Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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
|
working_directory: build
|
||||||
- run:
|
- run:
|
||||||
name: Build RPM
|
name: Build RPM
|
||||||
command: rpmbuild -ba ../dist/rpm/strawberry.spec
|
command: rpmbuild -ba ../dist/unix/strawberry.spec
|
||||||
working_directory: build
|
working_directory: build
|
||||||
|
|
||||||
|
|
||||||
@@ -59,14 +59,12 @@ commands:
|
|||||||
zypper --non-interactive --gpg-auto-import-keys install
|
zypper --non-interactive --gpg-auto-import-keys install
|
||||||
lsb-release
|
lsb-release
|
||||||
rpm-build
|
rpm-build
|
||||||
rpmdevtools
|
|
||||||
git
|
git
|
||||||
tar
|
tar
|
||||||
make
|
make
|
||||||
cmake
|
cmake
|
||||||
gcc
|
gcc
|
||||||
gcc-c++
|
gcc-c++
|
||||||
pkg-config
|
|
||||||
gettext-tools
|
gettext-tools
|
||||||
glibc-devel
|
glibc-devel
|
||||||
libboost_headers-devel
|
libboost_headers-devel
|
||||||
@@ -84,7 +82,6 @@ commands:
|
|||||||
gstreamer-plugins-base-devel
|
gstreamer-plugins-base-devel
|
||||||
libxine-devel
|
libxine-devel
|
||||||
vlc-devel
|
vlc-devel
|
||||||
taglib-devel
|
|
||||||
libQt5Core-devel
|
libQt5Core-devel
|
||||||
libQt5Gui-devel
|
libQt5Gui-devel
|
||||||
libQt5Widgets-devel
|
libQt5Widgets-devel
|
||||||
@@ -333,7 +330,7 @@ jobs:
|
|||||||
|
|
||||||
build_source:
|
build_source:
|
||||||
docker:
|
docker:
|
||||||
- image: opensuse/tumbleweed
|
- image: opensuse/leap:15.1
|
||||||
steps:
|
steps:
|
||||||
- install_opensuse_dependencies
|
- install_opensuse_dependencies
|
||||||
- checkout
|
- checkout
|
||||||
@@ -347,6 +344,12 @@ jobs:
|
|||||||
environment:
|
environment:
|
||||||
RPM_BUILD_NCPUS: "2"
|
RPM_BUILD_NCPUS: "2"
|
||||||
steps:
|
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
|
- install_opensuse_dependencies
|
||||||
- checkout
|
- checkout
|
||||||
- cmake
|
- cmake
|
||||||
|
|||||||
8
.github/workflows/ccpp.yml
vendored
@@ -6,13 +6,13 @@ jobs:
|
|||||||
build-linux:
|
build-linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: opensuse/tumbleweed
|
image: opensuse/leap:15.1
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: Update Packages
|
- name: Update Packages
|
||||||
run: zypper ref
|
run: zypper ref
|
||||||
- name: Install Packages
|
- 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
|
- name: Create Build Environment
|
||||||
run: mkdir -p build
|
run: mkdir -p build
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
@@ -31,7 +31,7 @@ jobs:
|
|||||||
- name: Unlink python
|
- name: Unlink python
|
||||||
run: brew unlink python@2
|
run: brew unlink python@2
|
||||||
- name: Install Packages
|
- 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
|
- name: Create Build Environment
|
||||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
run: cmake -E make_directory ${{runner.workspace}}/build
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
@@ -40,7 +40,7 @@ jobs:
|
|||||||
Qt5LinguistTools_DIR: /usr/local/opt/qt5/lib/cmake/Qt5LinguistTools
|
Qt5LinguistTools_DIR: /usr/local/opt/qt5/lib/cmake/Qt5LinguistTools
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
shell: bash
|
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
|
- name: Build
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ before_install:
|
|||||||
git fetch --unshallow || travis_terminate 1;
|
git fetch --unshallow || travis_terminate 1;
|
||||||
git pull || travis_terminate 1;
|
git pull || travis_terminate 1;
|
||||||
brew unlink python@2 || 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 gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav;
|
||||||
brew install libcdio libmtp libimobiledevice libplist;
|
brew install libcdio libmtp libimobiledevice libplist;
|
||||||
brew install create-dmg;
|
brew install create-dmg;
|
||||||
@@ -33,7 +33,7 @@ before_install:
|
|||||||
fi
|
fi
|
||||||
before_script:
|
before_script:
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker exec build cmake -Hstrawberry -Bbuild ; fi
|
- 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:
|
script:
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker exec build make -C build -j8 ; fi
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker exec build make -C build -j8 ; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
- 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(CheckIncludeFiles)
|
||||||
include(CheckFunctionExists)
|
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)
|
if(CMAKE_VERSION VERSION_GREATER 3.0)
|
||||||
check_function_exists(geteuid HAVE_GETEUID)
|
check_function_exists(geteuid HAVE_GETEUID)
|
||||||
check_function_exists(getpwuid HAVE_GETPWUID)
|
check_function_exists(getpwuid HAVE_GETPWUID)
|
||||||
@@ -19,14 +11,15 @@ endif()
|
|||||||
set(SINGLEAPP-SOURCES singleapplication.cpp singleapplication_p.cpp)
|
set(SINGLEAPP-SOURCES singleapplication.cpp singleapplication_p.cpp)
|
||||||
set(SINGLEAPP-MOC-HEADERS singleapplication.h singleapplication_p.h)
|
set(SINGLEAPP-MOC-HEADERS singleapplication.h singleapplication_p.h)
|
||||||
QT5_WRAP_CPP(SINGLEAPP-SOURCES-MOC ${SINGLEAPP-MOC-HEADERS})
|
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)
|
target_link_libraries(singleapplication Qt5::Core Qt5::Widgets Qt5::Network)
|
||||||
|
|
||||||
set(SINGLECOREAPP-SOURCES singlecoreapplication.cpp singlecoreapplication_p.cpp)
|
set(SINGLECOREAPP-SOURCES singlecoreapplication.cpp singlecoreapplication_p.cpp)
|
||||||
set(SINGLECOREAPP-MOC-HEADERS singlecoreapplication.h singlecoreapplication_p.h)
|
set(SINGLECOREAPP-MOC-HEADERS singlecoreapplication.h singlecoreapplication_p.h)
|
||||||
QT5_WRAP_CPP(SINGLECOREAPP-SOURCES-MOC ${SINGLECOREAPP-MOC-HEADERS})
|
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)
|
target_link_libraries(singlecoreapplication Qt5::Core Qt5::Widgets Qt5::Network)
|
||||||
|
|
||||||
configure_file(config.h.in "${CMAKE_CURRENT_BINARY_DIR}/config.h")
|
configure_file(config.h.in "${CMAKE_CURRENT_BINARY_DIR}/config.h")
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|||||||
@@ -61,8 +61,8 @@
|
|||||||
# include <lmcons.h>
|
# include <lmcons.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication *q_ptr)
|
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication *_q_ptr)
|
||||||
: q_ptr(q_ptr),
|
: q_ptr(_q_ptr),
|
||||||
memory(nullptr),
|
memory(nullptr),
|
||||||
socket(nullptr),
|
socket(nullptr),
|
||||||
server(nullptr),
|
server(nullptr),
|
||||||
@@ -186,7 +186,7 @@ void SingleApplicationPrivate::startPrimary() {
|
|||||||
|
|
||||||
void SingleApplicationPrivate::startSecondary() {}
|
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.
|
// Connect to the Local Server of the Primary Instance if not already connected.
|
||||||
if (socket == nullptr) {
|
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_Q(SingleApplication);
|
||||||
Q_EMIT q->receivedMessage(instanceId, dataSocket->readAll());
|
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)
|
if (closedSocket->bytesAvailable() > 0)
|
||||||
Q_EMIT slotDataAvailable(closedSocket, instanceId);
|
Q_EMIT slotDataAvailable(closedSocket, instanceId);
|
||||||
|
|||||||
@@ -74,14 +74,14 @@ class SingleApplicationPrivate : public QObject {
|
|||||||
};
|
};
|
||||||
Q_DECLARE_PUBLIC(SingleApplication)
|
Q_DECLARE_PUBLIC(SingleApplication)
|
||||||
|
|
||||||
SingleApplicationPrivate( SingleApplication *q_ptr );
|
SingleApplicationPrivate(SingleApplication *_q_ptr);
|
||||||
~SingleApplicationPrivate();
|
~SingleApplicationPrivate();
|
||||||
|
|
||||||
void genBlockServerName();
|
void genBlockServerName();
|
||||||
void initializeMemoryBlock();
|
void initializeMemoryBlock();
|
||||||
void startPrimary();
|
void startPrimary();
|
||||||
void startSecondary();
|
void startSecondary();
|
||||||
void connectToPrimary(int msecs, ConnectionType connectionType );
|
void connectToPrimary(const int msecs, const ConnectionType connectionType);
|
||||||
quint16 blockChecksum();
|
quint16 blockChecksum();
|
||||||
qint64 primaryPid();
|
qint64 primaryPid();
|
||||||
void readInitMessageHeader(QLocalSocket *socket);
|
void readInitMessageHeader(QLocalSocket *socket);
|
||||||
@@ -98,8 +98,8 @@ class SingleApplicationPrivate : public QObject {
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void slotConnectionEstablished();
|
void slotConnectionEstablished();
|
||||||
void slotDataAvailable(QLocalSocket*, quint32);
|
void slotDataAvailable(QLocalSocket*, const quint32);
|
||||||
void slotClientConnectionClosed(QLocalSocket*, quint32);
|
void slotClientConnectionClosed(QLocalSocket*, const quint32);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SINGLEAPPLICATION_P_H
|
#endif // SINGLEAPPLICATION_P_H
|
||||||
|
|||||||
@@ -61,8 +61,8 @@
|
|||||||
# include <lmcons.h>
|
# include <lmcons.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SingleCoreApplicationPrivate::SingleCoreApplicationPrivate(SingleCoreApplication *q_ptr)
|
SingleCoreApplicationPrivate::SingleCoreApplicationPrivate(SingleCoreApplication *_q_ptr)
|
||||||
: q_ptr(q_ptr),
|
: q_ptr(_q_ptr),
|
||||||
memory(nullptr),
|
memory(nullptr),
|
||||||
socket(nullptr),
|
socket(nullptr),
|
||||||
server(nullptr),
|
server(nullptr),
|
||||||
@@ -186,7 +186,7 @@ void SingleCoreApplicationPrivate::startPrimary() {
|
|||||||
|
|
||||||
void SingleCoreApplicationPrivate::startSecondary() {}
|
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.
|
// Connect to the Local Server of the Primary Instance if not already connected.
|
||||||
if (socket == nullptr) {
|
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_Q(SingleCoreApplication);
|
||||||
Q_EMIT q->receivedMessage(instanceId, dataSocket->readAll());
|
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)
|
if (closedSocket->bytesAvailable() > 0)
|
||||||
Q_EMIT slotDataAvailable(closedSocket, instanceId);
|
Q_EMIT slotDataAvailable(closedSocket, instanceId);
|
||||||
|
|||||||
@@ -74,14 +74,14 @@ class SingleCoreApplicationPrivate : public QObject {
|
|||||||
};
|
};
|
||||||
Q_DECLARE_PUBLIC(SingleCoreApplication)
|
Q_DECLARE_PUBLIC(SingleCoreApplication)
|
||||||
|
|
||||||
SingleCoreApplicationPrivate( SingleCoreApplication *q_ptr );
|
SingleCoreApplicationPrivate(SingleCoreApplication *_q_ptr);
|
||||||
~SingleCoreApplicationPrivate();
|
~SingleCoreApplicationPrivate();
|
||||||
|
|
||||||
void genBlockServerName();
|
void genBlockServerName();
|
||||||
void initializeMemoryBlock();
|
void initializeMemoryBlock();
|
||||||
void startPrimary();
|
void startPrimary();
|
||||||
void startSecondary();
|
void startSecondary();
|
||||||
void connectToPrimary(int msecs, ConnectionType connectionType );
|
void connectToPrimary(const int msecs, const ConnectionType connectionType);
|
||||||
quint16 blockChecksum();
|
quint16 blockChecksum();
|
||||||
qint64 primaryPid();
|
qint64 primaryPid();
|
||||||
void readInitMessageHeader(QLocalSocket *socket);
|
void readInitMessageHeader(QLocalSocket *socket);
|
||||||
@@ -98,8 +98,8 @@ class SingleCoreApplicationPrivate : public QObject {
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void slotConnectionEstablished();
|
void slotConnectionEstablished();
|
||||||
void slotDataAvailable(QLocalSocket*, quint32);
|
void slotDataAvailable(QLocalSocket*, const quint32);
|
||||||
void slotClientConnectionClosed(QLocalSocket*, quint32);
|
void slotClientConnectionClosed(QLocalSocket*, const quint32);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SINGLECOREAPPLICATION_P_H
|
#endif // SINGLECOREAPPLICATION_P_H
|
||||||
|
|||||||
6
3rdparty/taglib/CMakeLists.txt
vendored
@@ -1,8 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.11)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
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")
|
|
||||||
|
|
||||||
set(TAGLIB_SOVERSION_CURRENT 17)
|
set(TAGLIB_SOVERSION_CURRENT 17)
|
||||||
set(TAGLIB_SOVERSION_REVISION 0)
|
set(TAGLIB_SOVERSION_REVISION 0)
|
||||||
|
|||||||
2
3rdparty/taglib/ape/apefile.cpp
vendored
@@ -87,7 +87,7 @@ public:
|
|||||||
// static members
|
// 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.
|
// 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:
|
case BytesType:
|
||||||
if(d->pictureValue.isValid())
|
if(d->pictureValue.isValid())
|
||||||
return d->pictureValue.dataSize();
|
return d->pictureValue.dataSize();
|
||||||
|
break;
|
||||||
case GuidType:
|
case GuidType:
|
||||||
return d->byteVectorValue.size();
|
return d->byteVectorValue.size();
|
||||||
}
|
}
|
||||||
@@ -305,6 +306,7 @@ ByteVector ASF::Attribute::render(const String &name, int kind) const
|
|||||||
data.append(d->pictureValue.render());
|
data.append(d->pictureValue.render());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case GuidType:
|
case GuidType:
|
||||||
data.append(d->byteVectorValue);
|
data.append(d->byteVectorValue);
|
||||||
break;
|
break;
|
||||||
|
|||||||
8
3rdparty/taglib/dsdiff/dsdifffile.cpp
vendored
@@ -51,7 +51,7 @@ namespace
|
|||||||
|
|
||||||
int chunkIndex(const ChunkList &chunks, const ByteVector &id)
|
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)
|
if(chunks[i].name == id)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@@ -64,8 +64,8 @@ namespace
|
|||||||
if(name.size() != 4)
|
if(name.size() != 4)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for(int i = 0; i < 4; i++) {
|
for (int i = 0 ; i < 4 ; i++) {
|
||||||
if(name[i] < 32 || name[i] > 127)
|
if (name[i] < 32)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +227,7 @@ bool DSDIFF::File::save()
|
|||||||
return save(AllTags);
|
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()) {
|
if(readOnly()) {
|
||||||
debug("DSDIFF::File::save() -- File is read only.");
|
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
|
// 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
|
// 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);
|
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||||
if(ext == "OGA") {
|
if(ext == "OGA") {
|
||||||
/* .oga can be any audio in the Ogg container. First try FLAC, then Vorbis. */
|
/* .oga can be any audio in the Ogg container. First try FLAC, then Vorbis. */
|
||||||
File *file = new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
|
File *file_flac = new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||||
if(file->isValid())
|
if (file_flac->isValid())
|
||||||
return file;
|
return file_flac;
|
||||||
delete file;
|
delete file_flac;
|
||||||
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
|
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||||
}
|
}
|
||||||
if(ext == "FLAC")
|
if(ext == "FLAC")
|
||||||
|
|||||||
4
3rdparty/taglib/fileref.h
vendored
@@ -92,8 +92,8 @@ namespace TagLib {
|
|||||||
|
|
||||||
class TAGLIB_EXPORT FileTypeResolver
|
class TAGLIB_EXPORT FileTypeResolver
|
||||||
{
|
{
|
||||||
TAGLIB_IGNORE_MISSING_DESTRUCTOR
|
|
||||||
public:
|
public:
|
||||||
|
virtual ~FileTypeResolver();
|
||||||
/*!
|
/*!
|
||||||
* This method must be overridden to provide an additional file type
|
* This method must be overridden to provide an additional file type
|
||||||
* resolver. If the resolver is able to determine the file type it should
|
* resolver. If the resolver is able to determine the file type it should
|
||||||
@@ -286,4 +286,4 @@ namespace TagLib {
|
|||||||
}
|
}
|
||||||
} // namespace Strawberry_TagLib::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;
|
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);
|
writeBlock(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,11 +86,11 @@ void Mod::FileBase::writeU32B(unsigned long number)
|
|||||||
writeBlock(ByteVector::fromUInt(number, true));
|
writeBlock(ByteVector::fromUInt(number, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mod::FileBase::readByte(unsigned char &byte)
|
bool Mod::FileBase::readByte(unsigned char &_byte)
|
||||||
{
|
{
|
||||||
ByteVector data(readBlock(1));
|
ByteVector data(readBlock(1));
|
||||||
if(data.size() < 1) return false;
|
if(data.size() < 1) return false;
|
||||||
byte = data[0];
|
_byte = data[0];
|
||||||
return true;
|
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::AtomList
|
||||||
MP4::Atom::findall(const char *name, bool recursive)
|
MP4::Atom::findall(const char *_name, bool recursive)
|
||||||
{
|
{
|
||||||
MP4::AtomList result;
|
MP4::AtomList result;
|
||||||
for(AtomList::ConstIterator it = children.begin(); it != children.end(); ++it) {
|
for(AtomList::ConstIterator it = children.begin(); it != children.end(); ++it) {
|
||||||
if((*it)->name == name) {
|
if((*it)->name == _name) {
|
||||||
result.append(*it);
|
result.append(*it);
|
||||||
}
|
}
|
||||||
if(recursive) {
|
if(recursive) {
|
||||||
result.append((*it)->findall(name, recursive));
|
result.append((*it)->findall(_name, recursive));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
2
3rdparty/taglib/mp4/mp4atom.h
vendored
@@ -67,7 +67,7 @@ namespace TagLib {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AtomData {
|
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;
|
AtomDataType type;
|
||||||
int locale;
|
int locale;
|
||||||
ByteVector data;
|
ByteVector data;
|
||||||
|
|||||||
@@ -334,14 +334,14 @@ ByteVector TableOfContentsFrame::renderFields() const
|
|||||||
data.append(flags);
|
data.append(flags);
|
||||||
data.append((char)(entryCount()));
|
data.append((char)(entryCount()));
|
||||||
ByteVectorList::ConstIterator it = d->childElements.begin();
|
ByteVectorList::ConstIterator it = d->childElements.begin();
|
||||||
while(it != d->childElements.end()) {
|
while (it != d->childElements.end()) {
|
||||||
data.append(*it);
|
data.append(*it);
|
||||||
data.append('\0');
|
data.append('\0');
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
FrameList l = d->embeddedFrameList;
|
FrameList l = d->embeddedFrameList;
|
||||||
for(FrameList::ConstIterator it = l.begin(); it != l.end(); ++it)
|
for (FrameList::ConstIterator it2 = l.begin(); it2 != l.end(); ++it2)
|
||||||
data.append((*it)->render());
|
data.append((*it2)->render());
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
2
3rdparty/taglib/mpeg/id3v2/id3v2frame.cpp
vendored
@@ -417,7 +417,7 @@ namespace
|
|||||||
{"TYER", "TDRC"}, // 2.3 -> 2.4
|
{"TYER", "TDRC"}, // 2.3 -> 2.4
|
||||||
{"TIME", "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)
|
String Frame::frameIDToKey(const ByteVector &id)
|
||||||
|
|||||||
2
3rdparty/taglib/mpeg/mpegheader.cpp
vendored
@@ -69,7 +69,7 @@ public:
|
|||||||
// public members
|
// public members
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
MPEG::Header::Header(const ByteVector &data) :
|
MPEG::Header::Header(const ByteVector&) :
|
||||||
d(new HeaderPrivate())
|
d(new HeaderPrivate())
|
||||||
{
|
{
|
||||||
debug("MPEG::Header::Header() - This constructor is no longer used.");
|
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;
|
break;
|
||||||
|
|
||||||
page.setPageSequenceNumber(page.pageSequenceNumber() + numberOfNewPages);
|
page.setPageSequenceNumber(page.pageSequenceNumber() + numberOfNewPages);
|
||||||
const ByteVector data = page.render();
|
const ByteVector data2 = page.render();
|
||||||
|
|
||||||
seek(pageOffset + 18);
|
seek(pageOffset + 18);
|
||||||
writeBlock(data.mid(18, 8));
|
writeBlock(data2.mid(18, 8));
|
||||||
|
|
||||||
if(page.header()->lastPageOfStream())
|
if(page.header()->lastPageOfStream())
|
||||||
break;
|
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
|
// std::pair<String, StringList> where the first String is the field name and
|
||||||
// the StringList is the values associated with that field.
|
// the StringList is the values associated with that field.
|
||||||
|
|
||||||
FieldListMap::ConstIterator it = d->fieldListMap.begin();
|
for(FieldListMap::ConstIterator it = d->fieldListMap.begin() ; it != d->fieldListMap.end() ; ++it) {
|
||||||
for(; it != d->fieldListMap.end(); ++it) {
|
|
||||||
|
|
||||||
// And now iterate over the values of the current list.
|
// 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();
|
ByteVector picture = (*it)->render().toBase64();
|
||||||
data.append(ByteVector::fromUInt(picture.size() + 23, false));
|
data.append(ByteVector::fromUInt(picture.size() + 23, false));
|
||||||
data.append("METADATA_BLOCK_PICTURE=");
|
data.append("METADATA_BLOCK_PICTURE=");
|
||||||
|
|||||||
4
3rdparty/taglib/riff/rifffile.cpp
vendored
@@ -46,8 +46,8 @@ struct Chunk
|
|||||||
class RIFF::File::FilePrivate
|
class RIFF::File::FilePrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit FilePrivate(Endianness endianness) :
|
explicit FilePrivate(Endianness _endianness) :
|
||||||
endianness(endianness),
|
endianness(_endianness),
|
||||||
size(0),
|
size(0),
|
||||||
sizeOffset(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()
|
ByteVectorList::~ByteVectorList()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
7
3rdparty/taglib/toolkit/tbytevectorlist.h
vendored
@@ -53,13 +53,6 @@ namespace TagLib {
|
|||||||
*/
|
*/
|
||||||
virtual ~ByteVectorList();
|
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
|
* Convert the ByteVectorList to a ByteVector separated by \a separator. By
|
||||||
* default a space is used.
|
* default a space is used.
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ public:
|
|||||||
long position;
|
long position;
|
||||||
};
|
};
|
||||||
|
|
||||||
ByteVectorStream::ByteVectorStreamPrivate::ByteVectorStreamPrivate(const ByteVector &data) :
|
ByteVectorStream::ByteVectorStreamPrivate::ByteVectorStreamPrivate(const ByteVector &_data) :
|
||||||
data(data),
|
data(_data),
|
||||||
position(0)
|
position(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
6
3rdparty/taglib/toolkit/tfile.cpp
vendored
@@ -71,9 +71,9 @@ using namespace Strawberry_TagLib::TagLib;
|
|||||||
class File::FilePrivate
|
class File::FilePrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FilePrivate(IOStream *stream, bool owner) :
|
FilePrivate(IOStream *_stream, bool _owner) :
|
||||||
stream(stream),
|
stream(_stream),
|
||||||
streamOwner(owner),
|
streamOwner(_owner),
|
||||||
valid(true) {}
|
valid(true) {}
|
||||||
|
|
||||||
~FilePrivate()
|
~FilePrivate()
|
||||||
|
|||||||
2
3rdparty/taglib/toolkit/tfilestream.cpp
vendored
@@ -58,7 +58,7 @@ namespace
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
FileHandle openFile(const int fileDescriptor, bool readOnly)
|
FileHandle openFile(const int, bool)
|
||||||
{
|
{
|
||||||
return InvalidFileHandle;
|
return InvalidFileHandle;
|
||||||
}
|
}
|
||||||
|
|||||||
20
3rdparty/taglib/toolkit/tpropertymap.cpp
vendored
@@ -28,16 +28,10 @@
|
|||||||
using namespace Strawberry_TagLib::TagLib;
|
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){
|
for(SimplePropertyMap::ConstIterator it = m.begin(); it != m.end(); ++it){
|
||||||
String key = it->first.upper();
|
String key = it->first.upper();
|
||||||
if(!key.isEmpty())
|
if(!key.isEmpty())
|
||||||
@@ -45,14 +39,13 @@ PropertyMap::PropertyMap(const SimplePropertyMap &m)
|
|||||||
else
|
else
|
||||||
unsupported.append(it->first);
|
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();
|
String realKey = key.upper();
|
||||||
Iterator result = SimplePropertyMap::find(realKey);
|
Iterator result = SimplePropertyMap::find(realKey);
|
||||||
if(result == end())
|
if(result == end())
|
||||||
@@ -60,6 +53,7 @@ bool PropertyMap::insert(const String &key, const StringList &values)
|
|||||||
else
|
else
|
||||||
SimplePropertyMap::operator[](realKey).append(values);
|
SimplePropertyMap::operator[](realKey).append(values);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PropertyMap::replace(const String &key, const StringList &values)
|
bool PropertyMap::replace(const String &key, const StringList &values)
|
||||||
|
|||||||
2
3rdparty/taglib/toolkit/tpropertymap.h
vendored
@@ -115,8 +115,6 @@ namespace TagLib {
|
|||||||
|
|
||||||
PropertyMap();
|
PropertyMap();
|
||||||
|
|
||||||
PropertyMap(const PropertyMap &m);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Creates a PropertyMap initialized from a SimplePropertyMap. Copies all
|
* Creates a PropertyMap initialized from a SimplePropertyMap. Copies all
|
||||||
* entries from \a m that have valid keys.
|
* 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) :
|
StringList::StringList(const String &s) :
|
||||||
List<String>(),
|
List<String>(),
|
||||||
d(nullptr)
|
d(nullptr)
|
||||||
|
|||||||
2
3rdparty/taglib/toolkit/tstringlist.h
vendored
@@ -57,7 +57,7 @@ namespace TagLib {
|
|||||||
* implicitly shared, this method is lightweight and suitable for
|
* implicitly shared, this method is lightweight and suitable for
|
||||||
* pass-by-value usage.
|
* pass-by-value usage.
|
||||||
*/
|
*/
|
||||||
StringList(const StringList &l);
|
StringList(const StringList &l) = default;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Constructs a StringList with \a s as a member.
|
* 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.
|
// The last resort. May cause a buffer overflow.
|
||||||
|
|
||||||
length = vsprintf(buf, format, args);
|
length = vsprintf(buf, format, args);
|
||||||
if(length >= BufferSize) {
|
if(length >= (int)BufferSize) {
|
||||||
debug("Utils::formatString() - Buffer overflow! Returning an empty string.");
|
debug("Utils::formatString() - Buffer overflow! Returning an empty string.");
|
||||||
length = -1;
|
length = -1;
|
||||||
}
|
}
|
||||||
|
|||||||
44
3rdparty/taglib/xm/xmfile.cpp
vendored
@@ -110,7 +110,7 @@ template<typename T>
|
|||||||
class ValueReader : public Reader
|
class ValueReader : public Reader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ValueReader(T &value) : value(value)
|
explicit ValueReader(T &_value) : value(_value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ private:
|
|||||||
class ByteReader : public ValueReader<unsigned char>
|
class ByteReader : public ValueReader<unsigned char>
|
||||||
{
|
{
|
||||||
public:
|
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)
|
unsigned int read(Strawberry_TagLib::TagLib::File &file, unsigned int limit)
|
||||||
{
|
{
|
||||||
@@ -172,8 +172,8 @@ template<typename T>
|
|||||||
class NumberReader : public ValueReader<T>
|
class NumberReader : public ValueReader<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NumberReader(T &value, bool bigEndian) :
|
NumberReader(T &_value, bool _bigEndian) :
|
||||||
ValueReader<T>(value), bigEndian(bigEndian)
|
ValueReader<T>(_value), bigEndian(_bigEndian)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,8 +184,8 @@ protected:
|
|||||||
class U16Reader : public NumberReader<unsigned short>
|
class U16Reader : public NumberReader<unsigned short>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
U16Reader(unsigned short &value, bool bigEndian)
|
U16Reader(unsigned short &_value, bool _bigEndian)
|
||||||
: NumberReader<unsigned short>(value, bigEndian) {}
|
: NumberReader<unsigned short>(_value, _bigEndian) {}
|
||||||
|
|
||||||
unsigned int read(Strawberry_TagLib::TagLib::File &file, unsigned int limit)
|
unsigned int read(Strawberry_TagLib::TagLib::File &file, unsigned int limit)
|
||||||
{
|
{
|
||||||
@@ -203,8 +203,8 @@ public:
|
|||||||
class U32Reader : public NumberReader<unsigned long>
|
class U32Reader : public NumberReader<unsigned long>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
U32Reader(unsigned long &value, bool bigEndian = true) :
|
U32Reader(unsigned long &_value, bool _bigEndian = true) :
|
||||||
NumberReader<unsigned long>(value, bigEndian)
|
NumberReader<unsigned long>(_value, _bigEndian)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,11 +479,11 @@ bool XM::File::save()
|
|||||||
|
|
||||||
if(sampleHeaderSize > 18U) {
|
if(sampleHeaderSize > 18U) {
|
||||||
seek(pos + 18);
|
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())
|
if(sampleNameIndex >= lines.size())
|
||||||
writeString(String(), len);
|
writeString(String(), len2);
|
||||||
else
|
else
|
||||||
writeString(lines[sampleNameIndex ++], len);
|
writeString(lines[sampleNameIndex ++], len2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pos += sampleHeaderSize;
|
pos += sampleHeaderSize;
|
||||||
@@ -560,10 +560,10 @@ void XM::File::read(bool)
|
|||||||
StructReader pattern;
|
StructReader pattern;
|
||||||
pattern.byte(packingType).u16L(rowCount).u16L(dataSize);
|
pattern.byte(packingType).u16L(rowCount).u16L(dataSize);
|
||||||
|
|
||||||
unsigned int count = pattern.read(*this, patternHeaderLength - 4U);
|
unsigned int count2 = pattern.read(*this, patternHeaderLength - 4U);
|
||||||
READ_ASSERT(count == std::min(patternHeaderLength - 4U, (unsigned long)pattern.size()));
|
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;
|
StringList intrumentNames;
|
||||||
@@ -583,17 +583,17 @@ void XM::File::read(bool)
|
|||||||
instrument.string(instrumentName, 22).byte(instrumentType).u16L(sampleCount);
|
instrument.string(instrumentName, 22).byte(instrumentType).u16L(sampleCount);
|
||||||
|
|
||||||
// 4 for instrumentHeaderSize
|
// 4 for instrumentHeaderSize
|
||||||
unsigned int count = 4 + instrument.read(*this, instrumentHeaderSize - 4U);
|
unsigned int count2 = 4 + instrument.read(*this, instrumentHeaderSize - 4U);
|
||||||
READ_ASSERT(count == std::min(instrumentHeaderSize, (unsigned long)instrument.size() + 4));
|
READ_ASSERT(count2 == std::min(instrumentHeaderSize, (unsigned long)instrument.size() + 4));
|
||||||
|
|
||||||
long offset = 0;
|
long offset = 0;
|
||||||
if(sampleCount > 0) {
|
if(sampleCount > 0) {
|
||||||
unsigned long sampleHeaderSize = 0;
|
unsigned long sampleHeaderSize = 0;
|
||||||
sumSampleCount += sampleCount;
|
sumSampleCount += sampleCount;
|
||||||
// wouldn't know which header size to assume otherwise:
|
// 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:
|
// skip unhandled header proportion:
|
||||||
seek(instrumentHeaderSize - count - 4, Current);
|
seek(instrumentHeaderSize - count2 - 4, Current);
|
||||||
|
|
||||||
for(unsigned short j = 0; j < sampleCount; ++ j) {
|
for(unsigned short j = 0; j < sampleCount; ++ j) {
|
||||||
unsigned long sampleLength = 0;
|
unsigned long sampleLength = 0;
|
||||||
@@ -618,17 +618,17 @@ void XM::File::read(bool)
|
|||||||
.byte(compression)
|
.byte(compression)
|
||||||
.string(sampleName, 22);
|
.string(sampleName, 22);
|
||||||
|
|
||||||
unsigned int count = sample.read(*this, sampleHeaderSize);
|
unsigned int count3 = sample.read(*this, sampleHeaderSize);
|
||||||
READ_ASSERT(count == std::min(sampleHeaderSize, (unsigned long)sample.size()));
|
READ_ASSERT(count3 == std::min(sampleHeaderSize, (unsigned long)sample.size()));
|
||||||
// skip unhandled header proportion:
|
// skip unhandled header proportion:
|
||||||
seek(sampleHeaderSize - count, Current);
|
seek(sampleHeaderSize - count3, Current);
|
||||||
|
|
||||||
offset += sampleLength;
|
offset += sampleLength;
|
||||||
sampleNames.append(sampleName);
|
sampleNames.append(sampleName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
offset = instrumentHeaderSize - count;
|
offset = instrumentHeaderSize - count2;
|
||||||
}
|
}
|
||||||
intrumentNames.append(instrumentName);
|
intrumentNames.append(instrumentName);
|
||||||
seek(offset, Current);
|
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)
|
project(strawberry)
|
||||||
cmake_minimum_required(VERSION 2.8.11)
|
|
||||||
if(CMAKE_VERSION VERSION_GREATER 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
cmake_policy(SET CMP0054 NEW)
|
cmake_policy(SET CMP0054 NEW)
|
||||||
endif()
|
|
||||||
|
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
include(CheckCXXSourceRuns)
|
include(CheckCXXSourceRuns)
|
||||||
@@ -32,6 +15,8 @@ include(cmake/Rpm.cmake)
|
|||||||
include(cmake/Deb.cmake)
|
include(cmake/Deb.cmake)
|
||||||
include(cmake/Dmg.cmake)
|
include(cmake/Dmg.cmake)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||||
set(LINUX ON)
|
set(LINUX ON)
|
||||||
endif()
|
endif()
|
||||||
@@ -42,8 +27,46 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
|
|||||||
set(OPENBSD ON)
|
set(OPENBSD ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
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")
|
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
|
||||||
add_definitions(-DNDEBUG)
|
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(GSTREAMER_PBUTILS gstreamer-pbutils-1.0)
|
||||||
pkg_check_modules(LIBXINE libxine)
|
pkg_check_modules(LIBXINE libxine)
|
||||||
pkg_check_modules(LIBVLC libvlc)
|
pkg_check_modules(LIBVLC libvlc)
|
||||||
pkg_check_modules(PHONON phonon4qt5)
|
|
||||||
pkg_check_modules(SQLITE REQUIRED sqlite3>=3.9)
|
pkg_check_modules(SQLITE REQUIRED sqlite3>=3.9)
|
||||||
pkg_check_modules(LIBPULSE libpulse)
|
pkg_check_modules(LIBPULSE libpulse)
|
||||||
pkg_check_modules(CHROMAPRINT libchromaprint)
|
pkg_check_modules(CHROMAPRINT libchromaprint)
|
||||||
@@ -175,11 +197,10 @@ pkg_check_modules(TAGLIB taglib)
|
|||||||
# - Audio file detection by content.
|
# - Audio file detection by content.
|
||||||
# - DSF and DSDIFF support
|
# - DSF and DSDIFF support
|
||||||
#
|
#
|
||||||
if (TAGLIB_VERSION VERSION_GREATER 1.11.1)
|
# Some distros create their own version numbers for taglib so versions are not reliable anymore.
|
||||||
option(USE_SYSTEM_TAGLIB "Use system taglib" ON)
|
# Force to use our own copy of taglib unless USE_SYSTEM_TAGLIB is set.
|
||||||
else()
|
|
||||||
option(USE_SYSTEM_TAGLIB "Use system taglib" OFF)
|
option(USE_SYSTEM_TAGLIB "Use system taglib" OFF)
|
||||||
endif()
|
|
||||||
if (TAGLIB_FOUND AND USE_SYSTEM_TAGLIB)
|
if (TAGLIB_FOUND AND USE_SYSTEM_TAGLIB)
|
||||||
if (TAGLIB_VERSION VERSION_GREATER 1.11.1)
|
if (TAGLIB_VERSION VERSION_GREATER 1.11.1)
|
||||||
message(STATUS "Using system taglib library")
|
message(STATUS "Using system taglib library")
|
||||||
@@ -275,10 +296,6 @@ optional_component(VLC ON "Engine: VLC backend"
|
|||||||
DEPENDS "libvlc" LIBVLC_FOUND
|
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)"
|
optional_component(CHROMAPRINT ON "Chromaprint (Tag fetching from Musicbrainz)"
|
||||||
DEPENDS "chromaprint" CHROMAPRINT_FOUND
|
DEPENDS "chromaprint" CHROMAPRINT_FOUND
|
||||||
)
|
)
|
||||||
@@ -330,6 +347,7 @@ optional_component(TRANSLATIONS ON "Translations"
|
|||||||
)
|
)
|
||||||
|
|
||||||
optional_component(SUBSONIC ON "Subsonic support")
|
optional_component(SUBSONIC ON "Subsonic support")
|
||||||
|
optional_component(TIDAL ON "Tidal support")
|
||||||
|
|
||||||
optional_component(MOODBAR ON "Moodbar"
|
optional_component(MOODBAR ON "Moodbar"
|
||||||
DEPENDS "fftw3" FFTW3_FOUND
|
DEPENDS "fftw3" FFTW3_FOUND
|
||||||
@@ -387,17 +405,14 @@ if(HAVE_XINE)
|
|||||||
XINE_ANALYZER)
|
XINE_ANALYZER)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Set up definitions and paths
|
# Set up definitions
|
||||||
|
|
||||||
add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS)
|
add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS)
|
||||||
add_definitions(${QT_DEFINITIONS})
|
add_definitions(${QT_DEFINITIONS})
|
||||||
|
add_definitions(-DQT_STRICT_ITERATORS)
|
||||||
add_definitions(-DQT_USE_QSTRINGBUILDER)
|
add_definitions(-DQT_USE_QSTRINGBUILDER)
|
||||||
add_definitions(-DQT_NO_URL_CAST_FROM_STRING)
|
add_definitions(-DQT_NO_URL_CAST_FROM_STRING)
|
||||||
add_definitions(-DQT_NO_CAST_TO_ASCII -DQT_STRICT_ITERATORS)
|
add_definitions(-DQT_NO_CAST_TO_ASCII)
|
||||||
|
|
||||||
include_directories(${GLIB_INCLUDE_DIRS})
|
|
||||||
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
|
|
||||||
include_directories(${TAGLIB_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
# Subdirectories
|
# Subdirectories
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
@@ -421,8 +436,8 @@ add_custom_target(uninstall
|
|||||||
|
|
||||||
# Show a summary of what we have enabled
|
# Show a summary of what we have enabled
|
||||||
summary_show()
|
summary_show()
|
||||||
if(NOT HAVE_GSTREAMER AND NOT HAVE_XINE AND NOT HAVE_VLC AND NOT HAVE_PHONON)
|
if(NOT HAVE_GSTREAMER AND NOT HAVE_XINE AND NOT HAVE_VLC)
|
||||||
message(FATAL_ERROR "You need to have either GStreamer, Xine, VLC or Phonon to compile!")
|
message(FATAL_ERROR "You need to have either GStreamer, Xine or VLC to compile!")
|
||||||
elseif(NOT HAVE_GSTREAMER)
|
elseif(NOT HAVE_GSTREAMER)
|
||||||
message(WARNING "GStreamer is the only engine that is fully implemented. Using other engines is possible but not recommended.")
|
message(WARNING "GStreamer is the only engine that is fully implemented. Using other engines is possible but not recommended.")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
40
Changelog
@@ -2,6 +2,46 @@ Strawberry Music Player
|
|||||||
=======================
|
=======================
|
||||||
ChangeLog
|
ChangeLog
|
||||||
|
|
||||||
|
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:
|
Version 0.6.9:
|
||||||
|
|
||||||
BugFixes:
|
BugFixes:
|
||||||
|
|||||||
@@ -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/)
|
* [ALSA library (linux)](https://www.alsa-project.org/)
|
||||||
* [DBus (linux)](https://www.freedesktop.org/wiki/Software/dbus/)
|
* [DBus (linux)](https://www.freedesktop.org/wiki/Software/dbus/)
|
||||||
* [PulseAudio (linux optional)](https://www.freedesktop.org/wiki/Software/PulseAudio/?)
|
* [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/)
|
* [GnuTLS](https://www.gnutls.org/)
|
||||||
|
|
||||||
Optional dependencies:
|
Optional dependencies:
|
||||||
@@ -74,7 +74,7 @@ Optional dependencies:
|
|||||||
* iPhone, iPod Touch, iPad and Apple TV devices: [libimobiledevice, libplist and libusbmuxd](https://www.libimobiledevice.org/)
|
* iPhone, iPod Touch, iPad and Apple TV devices: [libimobiledevice, libplist and libusbmuxd](https://www.libimobiledevice.org/)
|
||||||
* Moodbar: [fftw3](http://www.fftw.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.
|
You should also install the gstreamer plugins base and good, and optionally bad and ugly.
|
||||||
|
|
||||||
### :wrench: Compiling from source
|
### :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")
|
set(RPM_DISTRO ${DIST_NAME} CACHE STRING "Suffix of the rpm file")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "RPM Suffix: ${RPM_DISTRO}")
|
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
|
add_custom_target(rpm
|
||||||
COMMAND ${CMAKE_SOURCE_DIR}/dist/scripts/maketarball.sh
|
COMMAND ${CMAKE_SOURCE_DIR}/dist/scripts/maketarball.sh
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy strawberry-${STRAWBERRY_VERSION_PACKAGE}.tar.xz ${RPMBUILD_DIR}/SOURCES/
|
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} -bs ${CMAKE_SOURCE_DIR}/dist/unix/strawberry.spec
|
||||||
COMMAND ${RPMBUILD_EXEC} -bb ${CMAKE_SOURCE_DIR}/dist/rpm/strawberry.spec
|
COMMAND ${RPMBUILD_EXEC} -bb ${CMAKE_SOURCE_DIR}/dist/unix/strawberry.spec
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
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_MAJOR 0)
|
||||||
set(STRAWBERRY_VERSION_MINOR 6)
|
set(STRAWBERRY_VERSION_MINOR 6)
|
||||||
set(STRAWBERRY_VERSION_PATCH 9)
|
set(STRAWBERRY_VERSION_PATCH 10)
|
||||||
#set(STRAWBERRY_VERSION_PRERELEASE rc1)
|
#set(STRAWBERRY_VERSION_PRERELEASE rc1)
|
||||||
|
|
||||||
set(INCLUDE_GIT_REVISION OFF)
|
set(INCLUDE_GIT_REVISION OFF)
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
<file>schema/schema-8.sql</file>
|
<file>schema/schema-8.sql</file>
|
||||||
<file>schema/schema-9.sql</file>
|
<file>schema/schema-9.sql</file>
|
||||||
<file>schema/schema-10.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>schema/device-schema.sql</file>
|
||||||
<file>style/strawberry.css</file>
|
<file>style/strawberry.css</file>
|
||||||
<file>html/playing-tooltip-plain.html</file>
|
<file>html/playing-tooltip-plain.html</file>
|
||||||
@@ -40,5 +42,6 @@
|
|||||||
<file>pictures/rainbowdash.png</file>
|
<file>pictures/rainbowdash.png</file>
|
||||||
<file>fonts/HumongousofEternitySt.ttf</file>
|
<file>fonts/HumongousofEternitySt.ttf</file>
|
||||||
<file>mood/sample.mood</file>
|
<file>mood/sample.mood</file>
|
||||||
|
<file>text/ghosts.txt</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@@ -89,6 +89,7 @@
|
|||||||
<file>icons/128x128/moodbar.png</file>
|
<file>icons/128x128/moodbar.png</file>
|
||||||
<file>icons/128x128/love.png</file>
|
<file>icons/128x128/love.png</file>
|
||||||
<file>icons/128x128/subsonic.png</file>
|
<file>icons/128x128/subsonic.png</file>
|
||||||
|
<file>icons/128x128/tidal.png</file>
|
||||||
<file>icons/64x64/albums.png</file>
|
<file>icons/64x64/albums.png</file>
|
||||||
<file>icons/64x64/alsa.png</file>
|
<file>icons/64x64/alsa.png</file>
|
||||||
<file>icons/64x64/application-exit.png</file>
|
<file>icons/64x64/application-exit.png</file>
|
||||||
@@ -179,6 +180,7 @@
|
|||||||
<file>icons/64x64/moodbar.png</file>
|
<file>icons/64x64/moodbar.png</file>
|
||||||
<file>icons/64x64/love.png</file>
|
<file>icons/64x64/love.png</file>
|
||||||
<file>icons/64x64/subsonic.png</file>
|
<file>icons/64x64/subsonic.png</file>
|
||||||
|
<file>icons/64x64/tidal.png</file>
|
||||||
<file>icons/48x48/albums.png</file>
|
<file>icons/48x48/albums.png</file>
|
||||||
<file>icons/48x48/alsa.png</file>
|
<file>icons/48x48/alsa.png</file>
|
||||||
<file>icons/48x48/application-exit.png</file>
|
<file>icons/48x48/application-exit.png</file>
|
||||||
@@ -201,6 +203,7 @@
|
|||||||
<file>icons/48x48/document-download.png</file>
|
<file>icons/48x48/document-download.png</file>
|
||||||
<file>icons/48x48/document-new.png</file>
|
<file>icons/48x48/document-new.png</file>
|
||||||
<file>icons/48x48/document-open-folder.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-open.png</file>
|
||||||
<file>icons/48x48/document-save.png</file>
|
<file>icons/48x48/document-save.png</file>
|
||||||
<file>icons/48x48/document-search.png</file>
|
<file>icons/48x48/document-search.png</file>
|
||||||
@@ -272,6 +275,7 @@
|
|||||||
<file>icons/48x48/moodbar.png</file>
|
<file>icons/48x48/moodbar.png</file>
|
||||||
<file>icons/48x48/love.png</file>
|
<file>icons/48x48/love.png</file>
|
||||||
<file>icons/48x48/subsonic.png</file>
|
<file>icons/48x48/subsonic.png</file>
|
||||||
|
<file>icons/48x48/tidal.png</file>
|
||||||
<file>icons/32x32/albums.png</file>
|
<file>icons/32x32/albums.png</file>
|
||||||
<file>icons/32x32/alsa.png</file>
|
<file>icons/32x32/alsa.png</file>
|
||||||
<file>icons/32x32/application-exit.png</file>
|
<file>icons/32x32/application-exit.png</file>
|
||||||
@@ -294,6 +298,7 @@
|
|||||||
<file>icons/32x32/document-download.png</file>
|
<file>icons/32x32/document-download.png</file>
|
||||||
<file>icons/32x32/document-new.png</file>
|
<file>icons/32x32/document-new.png</file>
|
||||||
<file>icons/32x32/document-open-folder.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-open.png</file>
|
||||||
<file>icons/32x32/document-save.png</file>
|
<file>icons/32x32/document-save.png</file>
|
||||||
<file>icons/32x32/document-search.png</file>
|
<file>icons/32x32/document-search.png</file>
|
||||||
@@ -365,6 +370,7 @@
|
|||||||
<file>icons/32x32/moodbar.png</file>
|
<file>icons/32x32/moodbar.png</file>
|
||||||
<file>icons/32x32/love.png</file>
|
<file>icons/32x32/love.png</file>
|
||||||
<file>icons/32x32/subsonic.png</file>
|
<file>icons/32x32/subsonic.png</file>
|
||||||
|
<file>icons/32x32/tidal.png</file>
|
||||||
<file>icons/22x22/albums.png</file>
|
<file>icons/22x22/albums.png</file>
|
||||||
<file>icons/22x22/alsa.png</file>
|
<file>icons/22x22/alsa.png</file>
|
||||||
<file>icons/22x22/application-exit.png</file>
|
<file>icons/22x22/application-exit.png</file>
|
||||||
@@ -387,6 +393,7 @@
|
|||||||
<file>icons/22x22/document-download.png</file>
|
<file>icons/22x22/document-download.png</file>
|
||||||
<file>icons/22x22/document-new.png</file>
|
<file>icons/22x22/document-new.png</file>
|
||||||
<file>icons/22x22/document-open-folder.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-open.png</file>
|
||||||
<file>icons/22x22/document-save.png</file>
|
<file>icons/22x22/document-save.png</file>
|
||||||
<file>icons/22x22/document-search.png</file>
|
<file>icons/22x22/document-search.png</file>
|
||||||
@@ -458,5 +465,6 @@
|
|||||||
<file>icons/22x22/moodbar.png</file>
|
<file>icons/22x22/moodbar.png</file>
|
||||||
<file>icons/22x22/love.png</file>
|
<file>icons/22x22/love.png</file>
|
||||||
<file>icons/22x22/subsonic.png</file>
|
<file>icons/22x22/subsonic.png</file>
|
||||||
|
<file>icons/22x22/tidal.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</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 (
|
CREATE TABLE device_%deviceid_songs (
|
||||||
|
|
||||||
title TEXT NOT NULL,
|
title TEXT,
|
||||||
album TEXT NOT NULL,
|
album TEXT,
|
||||||
artist TEXT NOT NULL,
|
artist TEXT,
|
||||||
albumartist TEXT NOT NULL,
|
albumartist TEXT,
|
||||||
track INTEGER NOT NULL DEFAULT -1,
|
track INTEGER NOT NULL DEFAULT -1,
|
||||||
disc INTEGER NOT NULL DEFAULT -1,
|
disc INTEGER NOT NULL DEFAULT -1,
|
||||||
year INTEGER NOT NULL DEFAULT -1,
|
year INTEGER NOT NULL DEFAULT -1,
|
||||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||||
genre TEXT NOT NULL,
|
genre TEXT,
|
||||||
compilation INTEGER NOT NULL DEFAULT -1,
|
compilation INTEGER NOT NULL DEFAULT 0,
|
||||||
composer TEXT NOT NULL,
|
composer TEXT,
|
||||||
performer TEXT NOT NULL,
|
performer TEXT,
|
||||||
grouping TEXT NOT NULL,
|
grouping TEXT,
|
||||||
comment TEXT NOT NULL,
|
comment TEXT,
|
||||||
lyrics TEXT NOT NULL,
|
lyrics TEXT,
|
||||||
|
|
||||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
artist_id TEXT,
|
||||||
album_id TEXT NOT NULL,
|
album_id TEXT,
|
||||||
song_id INTEGER NOT NULL DEFAULT -1,
|
song_id TEXT,
|
||||||
|
|
||||||
beginning INTEGER NOT NULL DEFAULT 0,
|
beginning INTEGER NOT NULL DEFAULT 0,
|
||||||
length 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;
|
DELETE FROM schema_version;
|
||||||
|
|
||||||
INSERT INTO schema_version (version) VALUES (10);
|
INSERT INTO schema_version (version) VALUES (12);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS directories (
|
CREATE TABLE IF NOT EXISTS directories (
|
||||||
path TEXT NOT NULL,
|
path TEXT NOT NULL,
|
||||||
@@ -19,25 +19,196 @@ CREATE TABLE IF NOT EXISTS subdirectories (
|
|||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS songs (
|
CREATE TABLE IF NOT EXISTS songs (
|
||||||
|
|
||||||
title TEXT NOT NULL,
|
title TEXT,
|
||||||
album TEXT NOT NULL,
|
album TEXT,
|
||||||
artist TEXT NOT NULL,
|
artist TEXT,
|
||||||
albumartist TEXT NOT NULL,
|
albumartist TEXT,
|
||||||
track INTEGER NOT NULL DEFAULT -1,
|
track INTEGER NOT NULL DEFAULT -1,
|
||||||
disc INTEGER NOT NULL DEFAULT -1,
|
disc INTEGER NOT NULL DEFAULT -1,
|
||||||
year INTEGER NOT NULL DEFAULT -1,
|
year INTEGER NOT NULL DEFAULT -1,
|
||||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||||
genre TEXT NOT NULL,
|
genre TEXT,
|
||||||
compilation INTEGER NOT NULL DEFAULT -1,
|
compilation INTEGER NOT NULL DEFAULT 0,
|
||||||
composer TEXT NOT NULL,
|
composer TEXT,
|
||||||
performer TEXT NOT NULL,
|
performer TEXT,
|
||||||
grouping TEXT NOT NULL,
|
grouping TEXT,
|
||||||
comment TEXT NOT NULL,
|
comment TEXT,
|
||||||
lyrics TEXT NOT NULL,
|
lyrics TEXT,
|
||||||
|
|
||||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
artist_id TEXT,
|
||||||
album_id TEXT NOT NULL,
|
album_id TEXT,
|
||||||
song_id INTEGER NOT NULL DEFAULT -1,
|
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,
|
beginning INTEGER NOT NULL DEFAULT 0,
|
||||||
length 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 (
|
CREATE TABLE IF NOT EXISTS subsonic_songs (
|
||||||
|
|
||||||
title TEXT NOT NULL,
|
title TEXT,
|
||||||
album TEXT NOT NULL,
|
album TEXT,
|
||||||
artist TEXT NOT NULL,
|
artist TEXT,
|
||||||
albumartist TEXT NOT NULL,
|
albumartist TEXT,
|
||||||
track INTEGER NOT NULL DEFAULT -1,
|
track INTEGER NOT NULL DEFAULT -1,
|
||||||
disc INTEGER NOT NULL DEFAULT -1,
|
disc INTEGER NOT NULL DEFAULT -1,
|
||||||
year INTEGER NOT NULL DEFAULT -1,
|
year INTEGER NOT NULL DEFAULT -1,
|
||||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||||
genre TEXT NOT NULL,
|
genre TEXT,
|
||||||
compilation INTEGER NOT NULL DEFAULT -1,
|
compilation INTEGER NOT NULL DEFAULT 0,
|
||||||
composer TEXT NOT NULL,
|
composer TEXT,
|
||||||
performer TEXT NOT NULL,
|
performer TEXT,
|
||||||
grouping TEXT NOT NULL,
|
grouping TEXT,
|
||||||
comment TEXT NOT NULL,
|
comment TEXT,
|
||||||
lyrics TEXT NOT NULL,
|
lyrics TEXT,
|
||||||
|
|
||||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
artist_id TEXT,
|
||||||
album_id TEXT NOT NULL,
|
album_id TEXT,
|
||||||
song_id INTEGER NOT NULL DEFAULT -1,
|
song_id TEXT,
|
||||||
|
|
||||||
beginning INTEGER NOT NULL DEFAULT 0,
|
beginning INTEGER NOT NULL DEFAULT 0,
|
||||||
length 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,
|
collection_id INTEGER,
|
||||||
playlist_url TEXT,
|
playlist_url TEXT,
|
||||||
|
|
||||||
title TEXT NOT NULL,
|
title TEXT,
|
||||||
album TEXT NOT NULL,
|
album TEXT,
|
||||||
artist TEXT NOT NULL,
|
artist TEXT,
|
||||||
albumartist TEXT NOT NULL,
|
albumartist TEXT,
|
||||||
track INTEGER NOT NULL DEFAULT -1,
|
track INTEGER,
|
||||||
disc INTEGER NOT NULL DEFAULT -1,
|
disc INTEGER,
|
||||||
year INTEGER NOT NULL DEFAULT -1,
|
year INTEGER,
|
||||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
originalyear INTEGER,
|
||||||
genre TEXT NOT NULL,
|
genre TEXT,
|
||||||
compilation INTEGER NOT NULL DEFAULT -1,
|
compilation INTEGER DEFAULT 0,
|
||||||
composer TEXT NOT NULL,
|
composer TEXT,
|
||||||
performer TEXT NOT NULL,
|
performer TEXT,
|
||||||
grouping TEXT NOT NULL,
|
grouping TEXT,
|
||||||
comment TEXT NOT NULL,
|
comment TEXT,
|
||||||
lyrics TEXT NOT NULL,
|
lyrics TEXT,
|
||||||
|
|
||||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
artist_id TEXT,
|
||||||
album_id TEXT NOT NULL,
|
album_id TEXT,
|
||||||
song_id INTEGER NOT NULL DEFAULT -1,
|
song_id TEXT,
|
||||||
|
|
||||||
beginning INTEGER NOT NULL DEFAULT 0,
|
beginning INTEGER,
|
||||||
length INTEGER NOT NULL DEFAULT 0,
|
length INTEGER,
|
||||||
|
|
||||||
bitrate INTEGER NOT NULL DEFAULT -1,
|
bitrate INTEGER,
|
||||||
samplerate INTEGER NOT NULL DEFAULT -1,
|
samplerate INTEGER,
|
||||||
bitdepth INTEGER NOT NULL DEFAULT -1,
|
bitdepth INTEGER,
|
||||||
|
|
||||||
source INTEGER NOT NULL DEFAULT 0,
|
source INTEGER,
|
||||||
directory_id INTEGER,
|
directory_id INTEGER,
|
||||||
url TEXT,
|
url TEXT,
|
||||||
filetype INTEGER NOT NULL DEFAULT 0,
|
filetype INTEGER,
|
||||||
filesize INTEGER,
|
filesize INTEGER,
|
||||||
mtime INTEGER,
|
mtime INTEGER,
|
||||||
ctime INTEGER,
|
ctime INTEGER,
|
||||||
unavailable INTEGER DEFAULT 0,
|
unavailable INTEGER DEFAULT 0,
|
||||||
|
|
||||||
playcount INTEGER NOT NULL DEFAULT 0,
|
playcount INTEGER DEFAULT 0,
|
||||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
skipcount INTEGER DEFAULT 0,
|
||||||
lastplayed INTEGER NOT NULL DEFAULT -1,
|
lastplayed INTEGER DEFAULT 0,
|
||||||
|
|
||||||
compilation_detected INTEGER DEFAULT 0,
|
compilation_detected INTEGER DEFAULT 0,
|
||||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
compilation_on INTEGER DEFAULT 0,
|
||||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
compilation_off INTEGER DEFAULT 0,
|
||||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
compilation_effective INTEGER DEFAULT 0,
|
||||||
|
|
||||||
art_automatic TEXT,
|
art_automatic TEXT,
|
||||||
art_manual TEXT,
|
art_manual TEXT,
|
||||||
|
|
||||||
effective_albumartist TEXT,
|
effective_albumartist TEXT,
|
||||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
effective_originalyear INTEGER,
|
||||||
|
|
||||||
cue_path TEXT
|
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(
|
CREATE VIRTUAL TABLE IF NOT EXISTS subsonic_songs_fts USING fts5(
|
||||||
|
|
||||||
ftstitle,
|
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)
|
||||||
2
debian/copyright
vendored
@@ -34,8 +34,6 @@ Files: src/core/main.h
|
|||||||
src/engine/devicefinder.h
|
src/engine/devicefinder.h
|
||||||
src/engine/enginedevice.cpp
|
src/engine/enginedevice.cpp
|
||||||
src/engine/enginedevice.h
|
src/engine/enginedevice.h
|
||||||
src/engine/phononengine.cpp
|
|
||||||
src/engine/phononengine.h
|
|
||||||
src/internet/internetservice.cpp
|
src/internet/internetservice.cpp
|
||||||
src/internet/internetservice.h
|
src/internet/internetservice.h
|
||||||
src/internet/internettabsview.cpp
|
src/internet/internettabsview.cpp
|
||||||
|
|||||||
4
debian/rules
vendored
@@ -6,8 +6,8 @@
|
|||||||
override_dh_auto_clean:
|
override_dh_auto_clean:
|
||||||
rm -f dist/macos/Info.plist
|
rm -f dist/macos/Info.plist
|
||||||
rm -f dist/macos/create-dmg.sh
|
rm -f dist/macos/create-dmg.sh
|
||||||
rm -f dist/pacman/PKGBUILD
|
rm -f dist/unix/PKGBUILD
|
||||||
rm -f dist/rpm/strawberry.spec
|
rm -f dist/unix/strawberry.spec
|
||||||
rm -f dist/scripts/maketarball.sh
|
rm -f dist/scripts/maketarball.sh
|
||||||
rm -f dist/windows/strawberry.nsi
|
rm -f dist/windows/strawberry.nsi
|
||||||
rm -f src/translations/translations.pot
|
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}/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)
|
if (APPLE)
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist.in ${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist)
|
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 ../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.desktop DESTINATION share/applications)
|
||||||
install(FILES unix/org.strawberrymusicplayer.strawberry.appdata.xml DESTINATION share/metainfo)
|
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)
|
endif (UNIX AND NOT APPLE)
|
||||||
|
|
||||||
if (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/.zanata-cache" \
|
||||||
--exclude="$root/debian/changelog" \
|
--exclude="$root/debian/changelog" \
|
||||||
--exclude="$root/dist/scripts/maketarball.sh" \
|
--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/create-dmg.sh" \
|
||||||
--exclude="$root/dist/macos/Info.plist" \
|
--exclude="$root/dist/macos/Info.plist" \
|
||||||
--exclude="$root/dist/windows/windres.rc" \
|
--exclude="$root/dist/windows/windres.rc" \
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ depends=(
|
|||||||
libusbmuxd
|
libusbmuxd
|
||||||
libplist
|
libplist
|
||||||
libimobiledevice
|
libimobiledevice
|
||||||
phonon-qt5
|
|
||||||
fftw
|
fftw
|
||||||
)
|
)
|
||||||
optdepends=(
|
optdepends=(
|
||||||
@@ -54,7 +53,6 @@ build() {
|
|||||||
cmake ../${pkgname}-@STRAWBERRY_VERSION_PACKAGE@ \
|
cmake ../${pkgname}-@STRAWBERRY_VERSION_PACKAGE@ \
|
||||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||||
-DUSE_SYSTEM_TAGLIB=ON \
|
-DUSE_SYSTEM_TAGLIB=ON \
|
||||||
-DENABLE_PHONON=ON \
|
|
||||||
-DENABLE_TRANSLATIONS=ON
|
-DENABLE_TRANSLATIONS=ON
|
||||||
make -j$(nproc)
|
make -j$(nproc)
|
||||||
}
|
}
|
||||||
@@ -10,5 +10,5 @@ Icon=strawberry
|
|||||||
Terminal=false
|
Terminal=false
|
||||||
Categories=AudioVideo;Player;Qt;Audio;
|
Categories=AudioVideo;Player;Qt;Audio;
|
||||||
StartupNotify=false
|
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
|
StartupWMClass=strawberry
|
||||||
|
|||||||
2
dist/windows/strawberry.nsi.in
vendored
@@ -201,7 +201,7 @@ Section "Strawberry" Strawberry
|
|||||||
File "libspeex-1.dll"
|
File "libspeex-1.dll"
|
||||||
File "libsqlite3-0.dll"
|
File "libsqlite3-0.dll"
|
||||||
File "libstdc++-6.dll"
|
File "libstdc++-6.dll"
|
||||||
;File "libtag.dll"
|
File "libtag.dll"
|
||||||
File "libunistring-2.dll"
|
File "libunistring-2.dll"
|
||||||
File "libvorbis-0.dll"
|
File "libvorbis-0.dll"
|
||||||
File "libvorbisenc-2.dll"
|
File "libvorbisenc-2.dll"
|
||||||
|
|||||||
@@ -1,15 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.11)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
include_directories(${GLIB_INCLUDE_DIRS})
|
include_directories(${GLIB_INCLUDE_DIRS})
|
||||||
include_directories(${GOBJECT_INCLUDE_DIRS})
|
include_directories(${GOBJECT_INCLUDE_DIRS})
|
||||||
include_directories(${GSTREAMER_INCLUDE_DIRS})
|
include_directories(${GSTREAMER_INCLUDE_DIRS})
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
cmake_minimum_required(VERSION 3.0)
|
||||||
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()
|
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR})
|
include_directories(${CMAKE_SOURCE_DIR})
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/src)
|
include_directories(${CMAKE_SOURCE_DIR}/src)
|
||||||
@@ -17,6 +11,8 @@ if (Backtrace_FOUND)
|
|||||||
include_directories(${Backtrace_INCLUDE_DIRS})
|
include_directories(${Backtrace_INCLUDE_DIRS})
|
||||||
endif(Backtrace_FOUND)
|
endif(Backtrace_FOUND)
|
||||||
|
|
||||||
|
include_directories(${GLIB_INCLUDE_DIRS})
|
||||||
|
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
|
||||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
@@ -41,18 +37,11 @@ endif(APPLE)
|
|||||||
|
|
||||||
qt5_wrap_cpp(MOC ${HEADERS})
|
qt5_wrap_cpp(MOC ${HEADERS})
|
||||||
|
|
||||||
add_library(libstrawberry-common STATIC
|
add_library(libstrawberry-common STATIC ${SOURCES} ${MOC})
|
||||||
${SOURCES}
|
|
||||||
${MOC}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (Backtrace_FOUND)
|
if(Backtrace_FOUND)
|
||||||
target_link_libraries(libstrawberry-common ${Backtrace_LIBRARIES})
|
target_link_libraries(libstrawberry-common ${Backtrace_LIBRARIES})
|
||||||
endif (Backtrace_FOUND)
|
endif(Backtrace_FOUND)
|
||||||
|
|
||||||
target_link_libraries(libstrawberry-common
|
|
||||||
${TAGLIB_LIBRARIES}
|
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
target_link_libraries(libstrawberry-common ${TAGLIB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||||
target_link_libraries(libstrawberry-common Qt5::Core Qt5::Network)
|
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();
|
return ret.space();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString CXXDemangle(const QString &mangled_function);
|
||||||
|
|
||||||
QString CXXDemangle(const QString &mangled_function) {
|
QString CXXDemangle(const QString &mangled_function) {
|
||||||
|
|
||||||
int status;
|
int status;
|
||||||
@@ -286,6 +288,8 @@ QString CXXDemangle(const QString &mangled_function) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString DarwinDemangle(const QString &symbol);
|
||||||
|
|
||||||
QString DarwinDemangle(const QString &symbol) {
|
QString DarwinDemangle(const QString &symbol) {
|
||||||
|
|
||||||
QStringList split = symbol.split(' ', QString::SkipEmptyParts);
|
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) {
|
QString LinuxDemangle(const QString &symbol) {
|
||||||
|
|
||||||
QRegExp regex("\\(([^+]+)");
|
QRegExp regex("\\(([^+]+)");
|
||||||
@@ -305,6 +311,8 @@ QString LinuxDemangle(const QString &symbol) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString DemangleSymbol(const QString &symbol);
|
||||||
|
|
||||||
QString DemangleSymbol(const QString &symbol) {
|
QString DemangleSymbol(const QString &symbol) {
|
||||||
#ifdef Q_OS_MACOS
|
#ifdef Q_OS_MACOS
|
||||||
return DarwinDemangle(symbol);
|
return DarwinDemangle(symbol);
|
||||||
|
|||||||
@@ -47,13 +47,13 @@ void _MessageHandlerBase::SetDevice(QIODevice *device) {
|
|||||||
connect(device, SIGNAL(readyRead()), SLOT(DeviceReadyRead()));
|
connect(device, SIGNAL(readyRead()), SLOT(DeviceReadyRead()));
|
||||||
|
|
||||||
// Yeah I know.
|
// Yeah I know.
|
||||||
if (QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(device)) {
|
if (QAbstractSocket *abstractsocket = qobject_cast<QAbstractSocket*>(device)) {
|
||||||
flush_abstract_socket_ = &QAbstractSocket::flush;
|
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;
|
flush_local_socket_ = &QLocalSocket::flush;
|
||||||
connect(socket, SIGNAL(disconnected()), SLOT(DeviceClosed()));
|
connect(localsocket, SIGNAL(disconnected()), SLOT(DeviceClosed()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qFatal("Unsupported device type passed to _MessageHandlerBase");
|
qFatal("Unsupported device type passed to _MessageHandlerBase");
|
||||||
|
|||||||
@@ -26,13 +26,16 @@ _MessageReplyBase::_MessageReplyBase(QObject *parent)
|
|||||||
: QObject(parent), finished_(false), success_(false) {}
|
: QObject(parent), finished_(false), success_(false) {}
|
||||||
|
|
||||||
bool _MessageReplyBase::WaitForFinished() {
|
bool _MessageReplyBase::WaitForFinished() {
|
||||||
|
|
||||||
qLog(Debug) << "Waiting on ID" << id();
|
qLog(Debug) << "Waiting on ID" << id();
|
||||||
semaphore_.acquire();
|
semaphore_.acquire();
|
||||||
qLog(Debug) << "Acquired ID" << id();
|
qLog(Debug) << "Acquired ID" << id();
|
||||||
return success_;
|
return success_;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _MessageReplyBase::Abort() {
|
void _MessageReplyBase::Abort() {
|
||||||
|
|
||||||
Q_ASSERT(!finished_);
|
Q_ASSERT(!finished_);
|
||||||
finished_ = true;
|
finished_ = true;
|
||||||
success_ = false;
|
success_ = false;
|
||||||
@@ -40,4 +43,5 @@ void _MessageReplyBase::Abort() {
|
|||||||
emit Finished(success_);
|
emit Finished(success_);
|
||||||
qLog(Debug) << "Releasing ID" << id() << "(aborted)";
|
qLog(Debug) << "Releasing ID" << id() << "(aborted)";
|
||||||
semaphore_.release();
|
semaphore_.release();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
cmake_minimum_required(VERSION 3.0)
|
||||||
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()
|
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_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_SOURCE_DIR}/src)
|
||||||
include_directories(${CMAKE_BINARY_DIR}/src)
|
include_directories(${CMAKE_BINARY_DIR}/src)
|
||||||
|
|
||||||
|
link_directories(${PROTOBUF_LIBRARY_DIRS})
|
||||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||||
|
|
||||||
set(MESSAGES
|
link_directories(${TAGLIB_LIBRARY_DIRS})
|
||||||
tagreadermessages.proto
|
include_directories(${TAGLIB_INCLUDE_DIRS})
|
||||||
)
|
|
||||||
|
|
||||||
set(SOURCES
|
set(MESSAGES tagreadermessages.proto)
|
||||||
fmpsparser.cpp
|
set(SOURCES fmpsparser.cpp tagreader.cpp)
|
||||||
tagreader.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(HEADERS
|
|
||||||
)
|
|
||||||
|
|
||||||
qt5_wrap_cpp(MOC ${HEADERS})
|
|
||||||
|
|
||||||
protobuf_generate_cpp(PROTO_SOURCES PROTO_HEADERS ${MESSAGES})
|
protobuf_generate_cpp(PROTO_SOURCES PROTO_HEADERS ${MESSAGES})
|
||||||
|
|
||||||
add_library(libstrawberry-tagreader STATIC
|
add_library(libstrawberry-tagreader STATIC ${PROTO_SOURCES} ${SOURCES})
|
||||||
${PROTO_SOURCES}
|
target_link_libraries(libstrawberry-tagreader ${PROTOBUF_LIBRARY} libstrawberry-common)
|
||||||
${SOURCES}
|
|
||||||
${MOC}
|
|
||||||
)
|
|
||||||
|
|
||||||
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;
|
// 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.
|
// 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())) {
|
if (TagLib::Ogg::XiphComment *tag_ogg = dynamic_cast<TagLib::Ogg::XiphComment*>(fileref->file()->tag())) {
|
||||||
ParseOggTag(tag->fieldListMap(), nullptr, &disc, &compilation, song);
|
ParseOggTag(tag_ogg->fieldListMap(), nullptr, &disc, &compilation, song);
|
||||||
if (!tag->pictureList().isEmpty()) {
|
if (!tag_ogg->pictureList().isEmpty()) {
|
||||||
song->set_art_automatic(kEmbeddedCover);
|
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()) {
|
if (file_flac->xiphComment()) {
|
||||||
ParseOggTag(file->xiphComment()->fieldListMap(), nullptr, &disc, &compilation, song);
|
ParseOggTag(file_flac->xiphComment()->fieldListMap(), nullptr, &disc, &compilation, song);
|
||||||
if (!file->pictureList().isEmpty()) {
|
if (!file_flac->pictureList().isEmpty()) {
|
||||||
song->set_art_automatic(kEmbeddedCover);
|
song->set_art_automatic(kEmbeddedCover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
|
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (TagLib::WavPack::File *file = dynamic_cast<TagLib::WavPack::File *>(fileref->file())) {
|
else if (TagLib::WavPack::File *file_wavpack = dynamic_cast<TagLib::WavPack::File *>(fileref->file())) {
|
||||||
song->set_bitdepth(file->audioProperties()->bitsPerSample());
|
song->set_bitdepth(file_wavpack->audioProperties()->bitsPerSample());
|
||||||
if (file->tag()) {
|
if (file_wavpack->tag()) {
|
||||||
ParseAPETag(file->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
|
ParseAPETag(file_wavpack->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
|
||||||
}
|
}
|
||||||
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
|
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (TagLib::APE::File *file = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
|
else if (TagLib::APE::File *file_ape = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
|
||||||
if (file->tag()) {
|
if (file_ape->tag()) {
|
||||||
ParseAPETag(file->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
|
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());
|
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()) {
|
if (file_mpeg->ID3v2Tag()) {
|
||||||
const TagLib::ID3v2::FrameListMap &map = file->ID3v2Tag()->frameListMap();
|
const TagLib::ID3v2::FrameListMap &map = file_mpeg->ID3v2Tag()->frameListMap();
|
||||||
|
|
||||||
if (!map["TPOS"].isEmpty()) disc = TStringToQString(map["TPOS"].front()->toString()).trimmed();
|
if (!map["TPOS"].isEmpty()) disc = TStringToQString(map["TPOS"].front()->toString()).trimmed();
|
||||||
if (!map["TCOM"].isEmpty()) Decode(map["TCOM"].front()->toString(), nullptr, song->mutable_composer());
|
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()) {
|
if (file_mp4->tag()) {
|
||||||
TagLib::MP4::Tag *mp4_tag = file->tag();
|
TagLib::MP4::Tag *mp4_tag = file_mp4->tag();
|
||||||
|
|
||||||
// Find album artists
|
// Find album artists
|
||||||
if (mp4_tag->item("aART").isValid()) {
|
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)) {
|
if (attributes_map.contains(kASF_OriginalDate_ID)) {
|
||||||
const TagLib::ASF::AttributeList &attributes = attributes_map[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())) {
|
else if (TagLib::MPC::File* file_mpc = dynamic_cast<TagLib::MPC::File*>(fileref->file())) {
|
||||||
if (file->tag()) {
|
if (file_mpc->tag()) {
|
||||||
ParseAPETag(file->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
|
ParseAPETag(file_mpc->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
|
||||||
}
|
}
|
||||||
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
|
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);
|
SetVorbisComments(tag, song);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (TagLib::WavPack::File *file = dynamic_cast<TagLib::WavPack::File*>(fileref->file())) {
|
else if (TagLib::WavPack::File *file_wavpack = dynamic_cast<TagLib::WavPack::File*>(fileref->file())) {
|
||||||
TagLib::APE::Tag *tag = file->APETag(true);
|
TagLib::APE::Tag *tag = file_wavpack->APETag(true);
|
||||||
if (!tag) return false;
|
if (!tag) return false;
|
||||||
SaveAPETag(tag, song);
|
SaveAPETag(tag, song);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (TagLib::APE::File *file = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
|
else if (TagLib::APE::File *file_ape = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
|
||||||
TagLib::APE::Tag *tag = file->APETag(true);
|
TagLib::APE::Tag *tag = file_ape->APETag(true);
|
||||||
if (!tag) return false;
|
if (!tag) return false;
|
||||||
SaveAPETag(tag, song);
|
SaveAPETag(tag, song);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (TagLib::MPC::File *file = dynamic_cast<TagLib::MPC::File*>(fileref->file())) {
|
else if (TagLib::MPC::File *file_mpc = dynamic_cast<TagLib::MPC::File*>(fileref->file())) {
|
||||||
TagLib::APE::Tag *tag = file->APETag(true);
|
TagLib::APE::Tag *tag = file_mpc->APETag(true);
|
||||||
if (!tag) return false;
|
if (!tag) return false;
|
||||||
SaveAPETag(tag, song);
|
SaveAPETag(tag, song);
|
||||||
}
|
}
|
||||||
|
|
||||||
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())) {
|
||||||
TagLib::ID3v2::Tag *tag = file->ID3v2Tag(true);
|
TagLib::ID3v2::Tag *tag = file_mpeg->ID3v2Tag(true);
|
||||||
if (!tag) return false;
|
if (!tag) return false;
|
||||||
SetTextFrame("TPOS", song.disc() <= 0 -1 ? QString() : QString::number(song.disc()), tag);
|
SetTextFrame("TPOS", song.disc() <= 0 -1 ? QString() : QString::number(song.disc()), tag);
|
||||||
SetTextFrame("TCOM", song.composer(), tag);
|
SetTextFrame("TCOM", song.composer(), tag);
|
||||||
@@ -609,8 +609,8 @@ bool TagReader::SaveFile(const QString &filename, const pb::tagreader::SongMetad
|
|||||||
SetUnsyncLyricsFrame(song.lyrics(), tag);
|
SetUnsyncLyricsFrame(song.lyrics(), tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
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())) {
|
||||||
TagLib::MP4::Tag *tag = file->tag();
|
TagLib::MP4::Tag *tag = file_mp4->tag();
|
||||||
tag->setItem("disk", TagLib::MP4::Item(song.disc() <= 0 -1 ? 0 : song.disc(), 0));
|
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("\251wrt", TagLib::StringList(song.composer().c_str()));
|
||||||
tag->setItem("\251grp", TagLib::StringList(song.grouping().c_str()));
|
tag->setItem("\251grp", TagLib::StringList(song.grouping().c_str()));
|
||||||
|
|||||||
@@ -26,28 +26,18 @@
|
|||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include <taglib/tstring.h>
|
||||||
|
#include <taglib/fileref.h>
|
||||||
#include <taglib/xiphcomment.h>
|
#include <taglib/xiphcomment.h>
|
||||||
#include <taglib/apetag.h>
|
#include <taglib/apetag.h>
|
||||||
#include <taglib/apefile.h>
|
#include <taglib/apefile.h>
|
||||||
|
#include <taglib/id3v2tag.h>
|
||||||
|
|
||||||
#include "tagreadermessages.pb.h"
|
#include "tagreadermessages.pb.h"
|
||||||
|
|
||||||
class QTextCodec;
|
class QTextCodec;
|
||||||
|
|
||||||
#ifndef USE_SYSTEM_TAGLIB
|
#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;
|
using namespace Strawberry_TagLib;
|
||||||
#endif
|
#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_SOURCE_DIR})
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/ext/libstrawberry-common)
|
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_SOURCE_DIR}/src)
|
||||||
include_directories(${CMAKE_BINARY_DIR}/src)
|
include_directories(${CMAKE_BINARY_DIR}/src)
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
link_directories(${PROTOBUF_LIBRARY_DIRS})
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -Wall -Wextra -Wpedantic -Woverloaded-virtual -fpermissive")
|
|
||||||
|
|
||||||
if(APPLE)
|
link_directories(${TAGLIB_LIBRARY_DIRS})
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")
|
include_directories(${TAGLIB_INCLUDE_DIRS})
|
||||||
endif()
|
|
||||||
|
|
||||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
|
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES main.cpp tagreaderworker.cpp)
|
||||||
main.cpp
|
|
||||||
tagreaderworker.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
qt5_wrap_cpp(MOC ${HEADERS})
|
qt5_wrap_cpp(MOC ${HEADERS})
|
||||||
qt5_add_resources(QRC data/data.qrc)
|
qt5_add_resources(QRC data/data.qrc)
|
||||||
|
|
||||||
add_executable(strawberry-tagreader
|
add_executable(strawberry-tagreader ${SOURCES} ${MOC} ${QRC})
|
||||||
${SOURCES}
|
|
||||||
${MOC}
|
|
||||||
${QRC}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(strawberry-tagreader
|
target_link_libraries(strawberry-tagreader
|
||||||
${TAGLIB_LIBRARIES}
|
${TAGLIB_LIBRARIES}
|
||||||
@@ -40,16 +32,11 @@ target_link_libraries(strawberry-tagreader
|
|||||||
)
|
)
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||||
target_link_libraries(strawberry-tagreader
|
target_link_libraries(strawberry-tagreader execinfo)
|
||||||
execinfo
|
|
||||||
)
|
|
||||||
endif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
endif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
target_link_libraries(strawberry-tagreader
|
target_link_libraries(strawberry-tagreader /System/Library/Frameworks/Foundation.framework)
|
||||||
/System/Library/Frameworks/Foundation.framework
|
|
||||||
)
|
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|
||||||
|
|
||||||
install(TARGETS strawberry-tagreader RUNTIME DESTINATION bin)
|
install(TARGETS strawberry-tagreader RUNTIME DESTINATION bin)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: strawberry
|
name: strawberry
|
||||||
version: '0.6.8+git'
|
version: '0.6.10+git'
|
||||||
summary: music player and collection organizer
|
summary: music player and collection organizer
|
||||||
description: |
|
description: |
|
||||||
Strawberry is a music player and collection organizer.
|
Strawberry is a music player and collection organizer.
|
||||||
|
|||||||
@@ -1,49 +1,16 @@
|
|||||||
# Strawberry Music Player
|
cmake_minimum_required(VERSION 3.0)
|
||||||
# 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)
|
|
||||||
|
|
||||||
if(HAVE_TRANSLATIONS)
|
if(HAVE_TRANSLATIONS)
|
||||||
include(../cmake/Translations.cmake)
|
include(../cmake/Translations.cmake)
|
||||||
endif(HAVE_TRANSLATIONS)
|
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(${Boost_INCLUDE_DIRS})
|
||||||
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
|
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
|
||||||
include_directories(${GLIB_INCLUDE_DIRS})
|
include_directories(${GLIB_INCLUDE_DIRS})
|
||||||
@@ -69,10 +36,6 @@ if(HAVE_GSTREAMER)
|
|||||||
include_directories(${GSTREAMER_PBUTILS_INCLUDE_DIRS})
|
include_directories(${GSTREAMER_PBUTILS_INCLUDE_DIRS})
|
||||||
endif(HAVE_GSTREAMER)
|
endif(HAVE_GSTREAMER)
|
||||||
|
|
||||||
if(HAVE_PHONON)
|
|
||||||
include_directories(${PHONON_INCLUDE_DIRS})
|
|
||||||
endif(HAVE_PHONON)
|
|
||||||
|
|
||||||
if(HAVE_CHROMAPRINT)
|
if(HAVE_CHROMAPRINT)
|
||||||
link_directories(${CHROMAPRINT_LIBRARY_DIRS})
|
link_directories(${CHROMAPRINT_LIBRARY_DIRS})
|
||||||
include_directories(${CHROMAPRINT_INCLUDE_DIRS})
|
include_directories(${CHROMAPRINT_INCLUDE_DIRS})
|
||||||
@@ -96,10 +59,6 @@ if(HAVE_LIBMTP)
|
|||||||
include_directories(${LIBMTP_INCLUDE_DIRS})
|
include_directories(${LIBMTP_INCLUDE_DIRS})
|
||||||
endif(HAVE_LIBMTP)
|
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
|
set(SOURCES
|
||||||
core/mainwindow.cpp
|
core/mainwindow.cpp
|
||||||
core/application.cpp
|
core/application.cpp
|
||||||
@@ -227,6 +186,7 @@ set(SOURCES
|
|||||||
covermanager/musicbrainzcoverprovider.cpp
|
covermanager/musicbrainzcoverprovider.cpp
|
||||||
covermanager/discogscoverprovider.cpp
|
covermanager/discogscoverprovider.cpp
|
||||||
covermanager/deezercoverprovider.cpp
|
covermanager/deezercoverprovider.cpp
|
||||||
|
covermanager/qobuzcoverprovider.cpp
|
||||||
|
|
||||||
lyrics/lyricsproviders.cpp
|
lyrics/lyricsproviders.cpp
|
||||||
lyrics/lyricsprovider.cpp
|
lyrics/lyricsprovider.cpp
|
||||||
@@ -254,6 +214,7 @@ set(SOURCES
|
|||||||
dialogs/errordialog.cpp
|
dialogs/errordialog.cpp
|
||||||
dialogs/edittagdialog.cpp
|
dialogs/edittagdialog.cpp
|
||||||
dialogs/trackselectiondialog.cpp
|
dialogs/trackselectiondialog.cpp
|
||||||
|
dialogs/addstreamdialog.cpp
|
||||||
|
|
||||||
widgets/autoexpandingtreeview.cpp
|
widgets/autoexpandingtreeview.cpp
|
||||||
widgets/busyindicator.cpp
|
widgets/busyindicator.cpp
|
||||||
@@ -286,7 +247,6 @@ set(SOURCES
|
|||||||
internet/internetservices.cpp
|
internet/internetservices.cpp
|
||||||
internet/internetservice.cpp
|
internet/internetservice.cpp
|
||||||
internet/internetplaylistitem.cpp
|
internet/internetplaylistitem.cpp
|
||||||
internet/internetsearch.cpp
|
|
||||||
internet/internetsearchview.cpp
|
internet/internetsearchview.cpp
|
||||||
internet/internetsearchmodel.cpp
|
internet/internetsearchmodel.cpp
|
||||||
internet/internetsearchsortmodel.cpp
|
internet/internetsearchsortmodel.cpp
|
||||||
@@ -413,6 +373,7 @@ set(HEADERS
|
|||||||
covermanager/musicbrainzcoverprovider.h
|
covermanager/musicbrainzcoverprovider.h
|
||||||
covermanager/discogscoverprovider.h
|
covermanager/discogscoverprovider.h
|
||||||
covermanager/deezercoverprovider.h
|
covermanager/deezercoverprovider.h
|
||||||
|
covermanager/qobuzcoverprovider.h
|
||||||
|
|
||||||
lyrics/lyricsproviders.h
|
lyrics/lyricsproviders.h
|
||||||
lyrics/lyricsprovider.h
|
lyrics/lyricsprovider.h
|
||||||
@@ -440,6 +401,7 @@ set(HEADERS
|
|||||||
dialogs/console.h
|
dialogs/console.h
|
||||||
dialogs/edittagdialog.h
|
dialogs/edittagdialog.h
|
||||||
dialogs/trackselectiondialog.h
|
dialogs/trackselectiondialog.h
|
||||||
|
dialogs/addstreamdialog.h
|
||||||
|
|
||||||
widgets/autoexpandingtreeview.h
|
widgets/autoexpandingtreeview.h
|
||||||
widgets/busyindicator.h
|
widgets/busyindicator.h
|
||||||
@@ -472,7 +434,6 @@ set(HEADERS
|
|||||||
internet/internetservices.h
|
internet/internetservices.h
|
||||||
internet/internetservice.h
|
internet/internetservice.h
|
||||||
internet/internetsongmimedata.h
|
internet/internetsongmimedata.h
|
||||||
internet/internetsearch.h
|
|
||||||
internet/internetsearchview.h
|
internet/internetsearchview.h
|
||||||
internet/internetsearchmodel.h
|
internet/internetsearchmodel.h
|
||||||
internet/localredirectserver.h
|
internet/localredirectserver.h
|
||||||
@@ -539,6 +500,7 @@ set(UI
|
|||||||
dialogs/console.ui
|
dialogs/console.ui
|
||||||
dialogs/edittagdialog.ui
|
dialogs/edittagdialog.ui
|
||||||
dialogs/trackselectiondialog.ui
|
dialogs/trackselectiondialog.ui
|
||||||
|
dialogs/addstreamdialog.ui
|
||||||
|
|
||||||
widgets/trackslider.ui
|
widgets/trackslider.ui
|
||||||
widgets/osdpretty.ui
|
widgets/osdpretty.ui
|
||||||
@@ -622,12 +584,6 @@ optional_source(HAVE_VLC
|
|||||||
HEADERS engine/vlcengine.h
|
HEADERS engine/vlcengine.h
|
||||||
)
|
)
|
||||||
|
|
||||||
# Phonon
|
|
||||||
optional_source(HAVE_PHONON
|
|
||||||
SOURCES engine/phononengine.cpp
|
|
||||||
HEADERS engine/phononengine.h
|
|
||||||
)
|
|
||||||
|
|
||||||
# DBUS and MPRIS - Unix specific
|
# DBUS and MPRIS - Unix specific
|
||||||
if(UNIX AND HAVE_DBUS)
|
if(UNIX AND HAVE_DBUS)
|
||||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/dbus)
|
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/dbus)
|
||||||
@@ -923,6 +879,29 @@ optional_source(HAVE_SUBSONIC
|
|||||||
settings/subsonicsettingspage.ui
|
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
|
# Moodbar
|
||||||
optional_source(HAVE_MOODBAR
|
optional_source(HAVE_MOODBAR
|
||||||
SOURCES
|
SOURCES
|
||||||
@@ -1034,10 +1013,6 @@ if(HAVE_VLC)
|
|||||||
target_link_libraries(strawberry_lib ${LIBVLC_LIBRARIES})
|
target_link_libraries(strawberry_lib ${LIBVLC_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(HAVE_PHONON)
|
|
||||||
target_link_libraries(strawberry_lib ${PHONON_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(HAVE_LIBGPOD)
|
if(HAVE_LIBGPOD)
|
||||||
target_link_libraries(strawberry_lib ${LIBGPOD_LIBRARIES})
|
target_link_libraries(strawberry_lib ${LIBGPOD_LIBRARIES})
|
||||||
endif(HAVE_LIBGPOD)
|
endif(HAVE_LIBGPOD)
|
||||||
@@ -1051,11 +1026,7 @@ if(HAVE_AUDIOCD)
|
|||||||
endif(HAVE_AUDIOCD)
|
endif(HAVE_AUDIOCD)
|
||||||
|
|
||||||
if(HAVE_IMOBILEDEVICE)
|
if(HAVE_IMOBILEDEVICE)
|
||||||
target_link_libraries(strawberry_lib
|
target_link_libraries(strawberry_lib ${LIBIMOBILEDEVICE_LIBRARIES} ${LIBPLIST_LIBRARIES} ${LIBUSBMUXD_LIBRARIES})
|
||||||
${LIBIMOBILEDEVICE_LIBRARIES}
|
|
||||||
${LIBPLIST_LIBRARIES}
|
|
||||||
${LIBUSBMUXD_LIBRARIES}
|
|
||||||
)
|
|
||||||
link_directories(${LIBIMOBILEDEVICE_LIBRARY_DIRS})
|
link_directories(${LIBIMOBILEDEVICE_LIBRARY_DIRS})
|
||||||
link_directories(${LIBUSBMUXD_LIBRARY_DIRS})
|
link_directories(${LIBUSBMUXD_LIBRARY_DIRS})
|
||||||
endif(HAVE_IMOBILEDEVICE)
|
endif(HAVE_IMOBILEDEVICE)
|
||||||
@@ -1083,7 +1054,6 @@ if (APPLE)
|
|||||||
"-framework ScriptingBridge"
|
"-framework ScriptingBridge"
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(strawberry_lib ${SPMEDIAKEYTAP_LIBRARIES})
|
|
||||||
if (HAVE_SPARKLE)
|
if (HAVE_SPARKLE)
|
||||||
include_directories(${SPARKLE}/Headers)
|
include_directories(${SPARKLE}/Headers)
|
||||||
target_link_libraries(strawberry_lib ${SPARKLE})
|
target_link_libraries(strawberry_lib ${SPARKLE})
|
||||||
@@ -1106,9 +1076,9 @@ if (UNIX AND NOT APPLE)
|
|||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if(NOT USE_SYSTEM_SINGLEAPPLICATION)
|
if (NOT USE_SYSTEM_SINGLEAPPLICATION)
|
||||||
add_dependencies(strawberry_lib ${SINGLEAPPLICATION_LIBRARIES} ${SINGLECOREAPPLICATION_LIBRARIES})
|
add_dependencies(strawberry_lib ${SINGLEAPPLICATION_LIBRARIES} ${SINGLECOREAPPLICATION_LIBRARIES})
|
||||||
endif()
|
endif ()
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
@@ -1136,9 +1106,7 @@ if(FREEBSD)
|
|||||||
target_link_libraries(strawberry execinfo)
|
target_link_libraries(strawberry execinfo)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(strawberry
|
target_link_libraries(strawberry strawberry_lib)
|
||||||
strawberry_lib
|
|
||||||
)
|
|
||||||
|
|
||||||
# macdeploy.py relies on the blob being built first.
|
# macdeploy.py relies on the blob being built first.
|
||||||
add_dependencies(strawberry strawberry-tagreader)
|
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) {
|
if (fade_intensity_[x] > 0) {
|
||||||
const uint offset = --fade_intensity_[x];
|
const uint offset = --fade_intensity_[x];
|
||||||
const uint y = y_ + (fade_pos_[x] * (kHeight + 1));
|
const uint y2 = y_ + (fade_pos_[x] * (kHeight + 1));
|
||||||
canvas_painter.drawPixmap(x * (kWidth + 1), y, fade_bars_[offset], 0, 0, kWidth, height() - y);
|
canvas_painter.drawPixmap(x * (kWidth + 1), y2, fade_bars_[offset], 0, 0, kWidth, height() - y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fade_intensity_[x] == 0) fade_pos_[x] = rows_;
|
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
|
* It won't modify the hue of fg unless absolutely necessary
|
||||||
* @return the adjusted form of fg
|
* @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 {
|
class OutputOnExit {
|
||||||
public:
|
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)));
|
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
|
// make a complimentary fadebar colour
|
||||||
// TODO dark is not always correct, dumbo!
|
// TODO dark is not always correct, dumbo!
|
||||||
int h, s, v;
|
int h, s, v;
|
||||||
palette().color(QPalette::Background).darker(150).getHsv(&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 dr2 = fg2.red() - bg2.red();
|
||||||
const double dg = fg.green() - bg.green();
|
const double dg2 = fg2.green() - bg2.green();
|
||||||
const double db = fg.blue() - bg.blue();
|
const double db2 = fg2.blue() - bg2.blue();
|
||||||
const int r = bg.red(), g = bg.green(), b = bg.blue();
|
const int r2 = bg2.red(), g2 = bg2.green(), b2 = bg2.blue();
|
||||||
|
|
||||||
// Precalculate all fade-bar pixmaps
|
// Precalculate all fade-bar pixmaps
|
||||||
for (uint y = 0; y < kFadeSize; ++y) {
|
for (uint y = 0; y < kFadeSize; ++y) {
|
||||||
@@ -363,7 +364,7 @@ void BlockAnalyzer::paletteChange(const QPalette&) {
|
|||||||
QPainter f(&fade_bars_[y]);
|
QPainter f(&fade_bars_[y]);
|
||||||
for (int z = 0; static_cast<uint>(z) < rows_; ++z) {
|
for (int z = 0; static_cast<uint>(z) < rows_; ++z) {
|
||||||
const double Y = 1.0 - (log10(kFadeSize - y) / log10(kFadeSize));
|
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;
|
static RainbowType rainbowtype;
|
||||||
|
|
||||||
inline QRect SourceRect(RainbowType rainbowtype) const {
|
inline QRect SourceRect(RainbowType _rainbowtype) const {
|
||||||
return QRect(0, kHeight[rainbowtype] * frame_, kWidth[rainbowtype], kHeight[rainbowtype]);
|
return QRect(0, kHeight[_rainbowtype] * frame_, kWidth[_rainbowtype], kHeight[_rainbowtype]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QRect SleepingSourceRect(RainbowType rainbowtype) const {
|
inline QRect SleepingSourceRect(RainbowType _rainbowtype) const {
|
||||||
return QRect(0, kHeight[rainbowtype] * kFrameCount[rainbowtype], kWidth[rainbowtype], kSleepingHeight[rainbowtype]);
|
return QRect(0, kHeight[_rainbowtype] * kFrameCount[_rainbowtype], kWidth[_rainbowtype], kSleepingHeight[_rainbowtype]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QRect DestRect(RainbowType rainbowtype) const {
|
inline QRect DestRect(RainbowType _rainbowtype) const {
|
||||||
return QRect(width() - kWidth[rainbowtype], (height() - kHeight[rainbowtype]) / 2, kWidth[rainbowtype], kHeight[rainbowtype]);
|
return QRect(width() - kWidth[_rainbowtype], (height() - kHeight[_rainbowtype]) / 2, kWidth[_rainbowtype], kHeight[_rainbowtype]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QRect SleepingDestRect(RainbowType rainbowtype) const {
|
inline QRect SleepingDestRect(RainbowType _rainbowtype) const {
|
||||||
return QRect(width() - kWidth[rainbowtype], (height() - kSleepingHeight[rainbowtype]) / 2, kWidth[rainbowtype], kSleepingHeight[rainbowtype]);
|
return QRect(width() - kWidth[_rainbowtype], (height() - kSleepingHeight[_rainbowtype]) / 2, kWidth[_rainbowtype], kSleepingHeight[_rainbowtype]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -467,7 +467,7 @@ void CollectionBackend::AddOrUpdateSongs(const SongList &songs) {
|
|||||||
continue;
|
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
|
// Get the previous song data first
|
||||||
Song old_song(GetSongBySongId(song.song_id()));
|
Song old_song(GetSongBySongId(song.song_id()));
|
||||||
@@ -822,35 +822,29 @@ SongList CollectionBackend::GetSongsByUrl(const QUrl &url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Song CollectionBackend::GetSongBySongId(int song_id) {
|
Song CollectionBackend::GetSongBySongId(const QString &song_id) {
|
||||||
|
|
||||||
QMutexLocker l(db_->Mutex());
|
QMutexLocker l(db_->Mutex());
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
return GetSongBySongId(song_id, db);
|
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) {
|
SongList CollectionBackend::GetSongsBySongId(const QStringList &song_ids) {
|
||||||
|
|
||||||
QMutexLocker l(db_->Mutex());
|
QMutexLocker l(db_->Mutex());
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
return GetSongsBySongId(song_ids, db);
|
return GetSongsBySongId(song_ids, db);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Song CollectionBackend::GetSongBySongId(int song_id, QSqlDatabase &db) {
|
Song CollectionBackend::GetSongBySongId(const QString &song_id, QSqlDatabase &db) {
|
||||||
SongList list = GetSongsBySongId(QStringList() << QString::number(song_id), db);
|
|
||||||
|
SongList list = GetSongsBySongId(QStringList() << song_id, db);
|
||||||
if (list.isEmpty()) return Song();
|
if (list.isEmpty()) return Song();
|
||||||
return list.first();
|
return list.first();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SongList CollectionBackend::GetSongsBySongId(const QStringList &song_ids, QSqlDatabase &db) {
|
SongList CollectionBackend::GetSongsBySongId(const QStringList &song_ids, QSqlDatabase &db) {
|
||||||
@@ -1001,7 +995,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;
|
AlbumList ret;
|
||||||
|
|
||||||
@@ -1009,7 +1003,7 @@ CollectionBackend::AlbumList CollectionBackend::GetAlbums(const QString &artist,
|
|||||||
query.SetColumnSpec("album, artist, albumartist, compilation, compilation_detected, art_automatic, art_manual, url");
|
query.SetColumnSpec("album, artist, albumartist, compilation, compilation_detected, art_automatic, art_manual, url");
|
||||||
query.SetOrderBy("album");
|
query.SetOrderBy("album");
|
||||||
|
|
||||||
if (compilation) {
|
if (compilation_required) {
|
||||||
query.AddCompilationRequirement(true);
|
query.AddCompilationRequirement(true);
|
||||||
}
|
}
|
||||||
else if (!artist.isEmpty()) {
|
else if (!artist.isEmpty()) {
|
||||||
@@ -1026,11 +1020,11 @@ CollectionBackend::AlbumList CollectionBackend::GetAlbums(const QString &artist,
|
|||||||
QString last_artist;
|
QString last_artist;
|
||||||
QString last_album_artist;
|
QString last_album_artist;
|
||||||
while (query.Next()) {
|
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;
|
Album info;
|
||||||
info.artist = compilation ? QString() : query.Value(1).toString();
|
info.artist = is_compilation ? QString() : query.Value(1).toString();
|
||||||
info.album_artist = compilation ? QString() : query.Value(2).toString();
|
info.album_artist = is_compilation ? QString() : query.Value(2).toString();
|
||||||
info.album_name = query.Value(0).toString();
|
info.album_name = query.Value(0).toString();
|
||||||
info.first_url = QUrl::fromEncoded(query.Value(7).toByteArray());
|
info.first_url = QUrl::fromEncoded(query.Value(7).toByteArray());
|
||||||
|
|
||||||
|
|||||||
@@ -141,10 +141,10 @@ class CollectionBackend : public CollectionBackendInterface {
|
|||||||
void UpdateTotalArtistCountAsync();
|
void UpdateTotalArtistCountAsync();
|
||||||
void UpdateTotalAlbumCountAsync();
|
void UpdateTotalAlbumCountAsync();
|
||||||
|
|
||||||
SongList FindSongsInDirectory(int id);
|
SongList FindSongsInDirectory(const int id);
|
||||||
SubdirectoryList SubdirsInDirectory(int id);
|
SubdirectoryList SubdirsInDirectory(const int id);
|
||||||
DirectoryList GetAllDirectories();
|
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 GetAll(const QString &column, const QueryOptions &opt = QueryOptions());
|
||||||
QStringList GetAllArtists(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);
|
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);
|
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 QList<int> &ids);
|
||||||
SongList GetSongsById(const QStringList &ids);
|
SongList GetSongsById(const QStringList &ids);
|
||||||
SongList GetSongsByForeignId(const QStringList &ids, const QString &table, const QString &column);
|
SongList GetSongsByForeignId(const QStringList &ids, const QString &table, const QString &column);
|
||||||
@@ -175,14 +175,13 @@ class CollectionBackend : public CollectionBackendInterface {
|
|||||||
bool ExecQuery(CollectionQuery *q);
|
bool ExecQuery(CollectionQuery *q);
|
||||||
SongList ExecCollectionQuery(CollectionQuery *query);
|
SongList ExecCollectionQuery(CollectionQuery *query);
|
||||||
|
|
||||||
void IncrementPlayCountAsync(int id);
|
void IncrementPlayCountAsync(const int id);
|
||||||
void IncrementSkipCountAsync(int id, float progress);
|
void IncrementSkipCountAsync(const int id, const float progress);
|
||||||
void ResetStatisticsAsync(int id);
|
void ResetStatisticsAsync(const int id);
|
||||||
|
|
||||||
void DeleteAll();
|
void DeleteAll();
|
||||||
|
|
||||||
Song GetSongBySongId(int song_id);
|
Song GetSongBySongId(const QString &song_id);
|
||||||
SongList GetSongsBySongId(const QList<int> &song_ids);
|
|
||||||
SongList GetSongsBySongId(const QStringList &song_ids);
|
SongList GetSongsBySongId(const QStringList &song_ids);
|
||||||
|
|
||||||
Song::Source Source() const;
|
Song::Source Source() const;
|
||||||
@@ -200,10 +199,10 @@ class CollectionBackend : public CollectionBackendInterface {
|
|||||||
void AddOrUpdateSubdirs(const SubdirectoryList &subdirs);
|
void AddOrUpdateSubdirs(const SubdirectoryList &subdirs);
|
||||||
void UpdateCompilations();
|
void UpdateCompilations();
|
||||||
void UpdateManualAlbumArt(const QString &artist, const QString &albumartist, const QString &album, const QUrl &cover_url);
|
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 ForceCompilation(const QString &album, const QList<QString> &artists, const bool on);
|
||||||
void IncrementPlayCount(int id);
|
void IncrementPlayCount(const int id);
|
||||||
void IncrementSkipCount(int id, float progress);
|
void IncrementSkipCount(const int id, const float progress);
|
||||||
void ResetStatistics(int id);
|
void ResetStatistics(const int id);
|
||||||
void SongPathChanged(const Song &song, const QFileInfo &new_file);
|
void SongPathChanged(const Song &song, const QFileInfo &new_file);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@@ -216,9 +215,9 @@ class CollectionBackend : public CollectionBackendInterface {
|
|||||||
|
|
||||||
void DatabaseReset();
|
void DatabaseReset();
|
||||||
|
|
||||||
void TotalSongCountUpdated(int total);
|
void TotalSongCountUpdated(const int total);
|
||||||
void TotalArtistCountUpdated(int total);
|
void TotalArtistCountUpdated(const int total);
|
||||||
void TotalAlbumCountUpdated(int total);
|
void TotalAlbumCountUpdated(const int total);
|
||||||
|
|
||||||
void ExitFinished();
|
void ExitFinished();
|
||||||
|
|
||||||
@@ -234,14 +233,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);
|
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, const QString &album_artist, const bool compilation_required = false, const QueryOptions &opt = QueryOptions());
|
||||||
AlbumList GetAlbums(const QString &artist, bool compilation, const QueryOptions &opt = QueryOptions());
|
AlbumList GetAlbums(const QString &artist, const bool compilation_required, const QueryOptions &opt = QueryOptions());
|
||||||
SubdirectoryList SubdirsInDirectory(int id, QSqlDatabase &db);
|
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);
|
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);
|
SongList GetSongsBySongId(const QStringList &song_ids, QSqlDatabase &db);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -34,8 +34,6 @@
|
|||||||
#include "collectionbackend.h"
|
#include "collectionbackend.h"
|
||||||
#include "collectiondirectorymodel.h"
|
#include "collectiondirectorymodel.h"
|
||||||
|
|
||||||
using std::shared_ptr;
|
|
||||||
|
|
||||||
CollectionDirectoryModel::CollectionDirectoryModel(CollectionBackend *backend, QObject *parent)
|
CollectionDirectoryModel::CollectionDirectoryModel(CollectionBackend *backend, QObject *parent)
|
||||||
: QStandardItemModel(parent),
|
: QStandardItemModel(parent),
|
||||||
dir_icon_(IconLoader::Load("document-open-folder")),
|
dir_icon_(IconLoader::Load("document-open-folder")),
|
||||||
|
|||||||
@@ -297,6 +297,7 @@ void CollectionFilterWidget::SetCollectionModel(CollectionModel *model) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CollectionFilterWidget::GroupByClicked(QAction *action) {
|
void CollectionFilterWidget::GroupByClicked(QAction *action) {
|
||||||
|
|
||||||
if (action->property("group_by").isNull()) {
|
if (action->property("group_by").isNull()) {
|
||||||
group_by_dialog_->show();
|
group_by_dialog_->show();
|
||||||
return;
|
return;
|
||||||
@@ -304,6 +305,7 @@ void CollectionFilterWidget::GroupByClicked(QAction *action) {
|
|||||||
|
|
||||||
CollectionModel::Grouping g = action->property("group_by").value<CollectionModel::Grouping>();
|
CollectionModel::Grouping g = action->property("group_by").value<CollectionModel::Grouping>();
|
||||||
model_->SetGroupBy(g);
|
model_->SetGroupBy(g);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollectionFilterWidget::GroupingChanged(const CollectionModel::Grouping &g) {
|
void CollectionFilterWidget::GroupingChanged(const CollectionModel::Grouping &g) {
|
||||||
|
|||||||
@@ -37,13 +37,13 @@ class CollectionItem : public SimpleTreeItem<CollectionItem> {
|
|||||||
Type_LoadingIndicator,
|
Type_LoadingIndicator,
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit CollectionItem(SimpleTreeModel<CollectionItem> *model)
|
explicit CollectionItem(SimpleTreeModel<CollectionItem> *_model)
|
||||||
: SimpleTreeItem<CollectionItem>(Type_Root, model),
|
: SimpleTreeItem<CollectionItem>(Type_Root, _model),
|
||||||
container_level(-1),
|
container_level(-1),
|
||||||
compilation_artist_node_(nullptr) {}
|
compilation_artist_node_(nullptr) {}
|
||||||
|
|
||||||
explicit CollectionItem(Type type, CollectionItem *parent = nullptr)
|
explicit CollectionItem(Type _type, CollectionItem *_parent = nullptr)
|
||||||
: SimpleTreeItem<CollectionItem>(type, parent),
|
: SimpleTreeItem<CollectionItem>(_type, _parent),
|
||||||
container_level(-1),
|
container_level(-1),
|
||||||
compilation_artist_node_(nullptr) {}
|
compilation_artist_node_(nullptr) {}
|
||||||
|
|
||||||
|
|||||||
@@ -66,16 +66,15 @@
|
|||||||
#include "playlist/playlistmanager.h"
|
#include "playlist/playlistmanager.h"
|
||||||
#include "playlist/songmimedata.h"
|
#include "playlist/songmimedata.h"
|
||||||
#include "covermanager/albumcoverloader.h"
|
#include "covermanager/albumcoverloader.h"
|
||||||
|
#include "covermanager/albumcoverloaderresult.h"
|
||||||
#include "settings/collectionsettingspage.h"
|
#include "settings/collectionsettingspage.h"
|
||||||
|
|
||||||
using std::bind;
|
|
||||||
using std::sort;
|
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
using std::placeholders::_2;
|
using std::placeholders::_2;
|
||||||
|
|
||||||
const char *CollectionModel::kSavedGroupingsSettingsGroup = "SavedGroupings";
|
const char *CollectionModel::kSavedGroupingsSettingsGroup = "SavedGroupings";
|
||||||
const int CollectionModel::kPrettyCoverSize = 32;
|
const int CollectionModel::kPrettyCoverSize = 32;
|
||||||
const char *CollectionModel::kPixmapDiskCacheDir = "/pixmapcache";
|
const char *CollectionModel::kPixmapDiskCacheDir = "pixmapcache";
|
||||||
|
|
||||||
QNetworkDiskCache *CollectionModel::sIconCache = nullptr;
|
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_.pad_output_image_ = true;
|
||||||
cover_loader_options_.scale_output_image_ = true;
|
cover_loader_options_.scale_output_image_ = true;
|
||||||
|
|
||||||
if (app_)
|
if (app_) {
|
||||||
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");
|
QIcon nocover = IconLoader::Load("cdcase");
|
||||||
no_cover_icon_ = nocover.pixmap(nocover.availableSizes().last()).scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
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);
|
//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 (sIconCache == nullptr) {
|
||||||
// If this ever changes, these two lines might need to be protected by a mutex.
|
|
||||||
if (sIconCache == nullptr)
|
|
||||||
sIconCache = new QNetworkDiskCache(this);
|
sIconCache = new QNetworkDiskCache(this);
|
||||||
|
sIconCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/" + kPixmapDiskCacheDir);
|
||||||
|
}
|
||||||
|
|
||||||
connect(backend_, SIGNAL(SongsDiscovered(SongList)), SLOT(SongsDiscovered(SongList)));
|
connect(backend_, SIGNAL(SongsDiscovered(SongList)), SLOT(SongsDiscovered(SongList)));
|
||||||
connect(backend_, SIGNAL(SongsDeleted(SongList)), SLOT(SongsDeleted(SongList)));
|
connect(backend_, SIGNAL(SongsDeleted(SongList)), SLOT(SongsDeleted(SongList)));
|
||||||
@@ -187,16 +187,16 @@ void CollectionModel::ReloadSettings() {
|
|||||||
|
|
||||||
use_disk_cache_ = s.value(CollectionSettingsPage::kSettingsDiskCacheEnable, false).toBool();
|
use_disk_cache_ = s.value(CollectionSettingsPage::kSettingsDiskCacheEnable, false).toBool();
|
||||||
|
|
||||||
if (!use_disk_cache_) {
|
QPixmapCache::setCacheLimit(MaximumCacheSize(&s, CollectionSettingsPage::kSettingsCacheSize, CollectionSettingsPage::kSettingsCacheSizeUnit, CollectionSettingsPage::kSettingsCacheSizeDefault) / 1024);
|
||||||
sIconCache->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
sIconCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + kPixmapDiskCacheDir);
|
sIconCache->setMaximumCacheSize(MaximumCacheSize(&s, CollectionSettingsPage::kSettingsDiskCacheSize, CollectionSettingsPage::kSettingsDiskCacheSizeUnit, CollectionSettingsPage::kSettingsDiskCacheSizeDefault));
|
||||||
sIconCache->setMaximumCacheSize(MaximumCacheSize(&s, CollectionSettingsPage::kSettingsDiskCacheSize, CollectionSettingsPage::kSettingsDiskCacheSizeUnit));
|
|
||||||
|
|
||||||
QPixmapCache::setCacheLimit(MaximumCacheSize(&s, CollectionSettingsPage::kSettingsCacheSize, CollectionSettingsPage::kSettingsCacheSizeUnit) / 1024);
|
|
||||||
|
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
|
if (!use_disk_cache_) {
|
||||||
|
ClearDiskCache();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollectionModel::Init(bool async) {
|
void CollectionModel::Init(bool async) {
|
||||||
@@ -588,10 +588,10 @@ QVariant CollectionModel::AlbumIcon(const QModelIndex &idx) {
|
|||||||
if (use_disk_cache_) {
|
if (use_disk_cache_) {
|
||||||
std::unique_ptr<QIODevice> cache(sIconCache->data(QUrl(cache_key)));
|
std::unique_ptr<QIODevice> cache(sIconCache->data(QUrl(cache_key)));
|
||||||
if (cache) {
|
if (cache) {
|
||||||
QImage cached_pixmap;
|
QImage cached_image;
|
||||||
if (cached_pixmap.load(cache.get(), "XPM")) {
|
if (cached_image.load(cache.get(), "XPM")) {
|
||||||
QPixmapCache::insert(cache_key, QPixmap::fromImage(cached_pixmap));
|
QPixmapCache::insert(cache_key, QPixmap::fromImage(cached_image));
|
||||||
return QPixmap::fromImage(cached_pixmap);
|
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) {
|
void CollectionModel::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result) {
|
||||||
|
|
||||||
Q_UNUSED(cover_url);
|
|
||||||
|
|
||||||
if (!pending_art_.contains(id)) return;
|
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);
|
pending_cache_keys_.remove(cache_key);
|
||||||
|
|
||||||
// Insert this image in the cache.
|
// 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.
|
// Set the no_cover image so we don't continually try to load art.
|
||||||
QPixmapCache::insert(cache_key, no_cover_icon_);
|
QPixmapCache::insert(cache_key, no_cover_icon_);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
QPixmap image_pixmap;
|
QPixmap image_pixmap;
|
||||||
image_pixmap = QPixmap::fromImage(image);
|
image_pixmap = QPixmap::fromImage(result.image_scaled);
|
||||||
QPixmapCache::insert(cache_key, image_pixmap);
|
QPixmapCache::insert(cache_key, image_pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a valid cover not already in the disk cache
|
// If we have a valid cover not already in the disk cache
|
||||||
if (use_disk_cache_) {
|
if (use_disk_cache_) {
|
||||||
std::unique_ptr<QIODevice> cached_img(sIconCache->data(QUrl(cache_key)));
|
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;
|
QNetworkCacheMetaData item_metadata;
|
||||||
item_metadata.setSaveToDisk(true);
|
item_metadata.setSaveToDisk(true);
|
||||||
item_metadata.setUrl(QUrl(cache_key));
|
item_metadata.setUrl(QUrl(cache_key));
|
||||||
QIODevice* cache = sIconCache->prepare(item_metadata);
|
QIODevice *cache = sIconCache->prepare(item_metadata);
|
||||||
if (cache) {
|
if (cache) {
|
||||||
image.save(cache, "XPM");
|
result.image_scaled.save(cache, "XPM");
|
||||||
sIconCache->insert(cache);
|
sIconCache->insert(cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1541,9 +1539,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;
|
int unit = s->value(size_unit_id, CollectionSettingsPage::CacheSizeUnit::CacheSizeUnit_MB).toInt() + 1;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -41,16 +41,17 @@
|
|||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
#include <QNetworkDiskCache>
|
||||||
|
|
||||||
#include "core/simpletreemodel.h"
|
#include "core/simpletreemodel.h"
|
||||||
#include "core/song.h"
|
#include "core/song.h"
|
||||||
|
#include "covermanager/albumcoverloader.h"
|
||||||
#include "collectionquery.h"
|
#include "collectionquery.h"
|
||||||
#include "collectionitem.h"
|
#include "collectionitem.h"
|
||||||
#include "sqlrow.h"
|
#include "sqlrow.h"
|
||||||
#include "covermanager/albumcoverloaderoptions.h"
|
#include "covermanager/albumcoverloaderoptions.h"
|
||||||
|
|
||||||
class QSettings;
|
class QSettings;
|
||||||
class QNetworkDiskCache;
|
|
||||||
|
|
||||||
class Application;
|
class Application;
|
||||||
class CollectionBackend;
|
class CollectionBackend;
|
||||||
@@ -176,7 +177,9 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
|||||||
static QString SortTextForYear(int year);
|
static QString SortTextForYear(int year);
|
||||||
static QString SortTextForBitrate(int bitrate);
|
static QString SortTextForBitrate(int bitrate);
|
||||||
|
|
||||||
signals:
|
quint64 icon_cache_disk_size() { return sIconCache->cacheSize(); }
|
||||||
|
|
||||||
|
signals:
|
||||||
void TotalSongCountUpdated(int count);
|
void TotalSongCountUpdated(int count);
|
||||||
void TotalArtistCountUpdated(int count);
|
void TotalArtistCountUpdated(int count);
|
||||||
void TotalAlbumCountUpdated(int count);
|
void TotalAlbumCountUpdated(int count);
|
||||||
@@ -210,7 +213,7 @@ signals:
|
|||||||
// Called after ResetAsync
|
// Called after ResetAsync
|
||||||
void ResetAsyncQueryFinished(QFuture<CollectionModel::QueryResult> future);
|
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:
|
private:
|
||||||
// Provides some optimisations for loading the list of items in the root.
|
// Provides some optimisations for loading the list of items in the root.
|
||||||
@@ -247,7 +250,7 @@ signals:
|
|||||||
QVariant AlbumIcon(const QModelIndex &idx);
|
QVariant AlbumIcon(const QModelIndex &idx);
|
||||||
QVariant data(const CollectionItem *item, int role) const;
|
QVariant data(const CollectionItem *item, int role) const;
|
||||||
bool CompareItems(const CollectionItem *a, const CollectionItem *b) 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:
|
private:
|
||||||
CollectionBackend *backend_;
|
CollectionBackend *backend_;
|
||||||
|
|||||||
@@ -43,20 +43,33 @@ void CollectionPlaylistItem::Reload() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CollectionPlaylistItem::InitFromQuery(const SqlRow &query) {
|
bool CollectionPlaylistItem::InitFromQuery(const SqlRow &query) {
|
||||||
|
|
||||||
// Rows from the songs tables come first
|
// Rows from the songs tables come first
|
||||||
song_.InitFromQuery(query, true);
|
song_.InitFromQuery(query, true);
|
||||||
song_.set_source(Song::Source_Collection);
|
song_.set_source(Song::Source_Collection);
|
||||||
return song_.is_valid();
|
return song_.is_valid();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant CollectionPlaylistItem::DatabaseValue(DatabaseColumn column) const {
|
QVariant CollectionPlaylistItem::DatabaseValue(DatabaseColumn column) const {
|
||||||
|
|
||||||
switch (column) {
|
switch (column) {
|
||||||
case Column_CollectionId: return song_.id();
|
case Column_CollectionId: return song_.id();
|
||||||
default: return PlaylistItem::DatabaseValue(column);
|
default: return PlaylistItem::DatabaseValue(column);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Song CollectionPlaylistItem::Metadata() const {
|
Song CollectionPlaylistItem::Metadata() const {
|
||||||
|
|
||||||
if (HasTemporaryMetadata()) return temp_metadata_;
|
if (HasTemporaryMetadata()) return temp_metadata_;
|
||||||
return song_;
|
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; }
|
bool IsLocalCollectionItem() const { return true; }
|
||||||
|
|
||||||
|
void SetArtManual(const QUrl &cover_url);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QVariant DatabaseValue(DatabaseColumn column) const;
|
QVariant DatabaseValue(DatabaseColumn column) const;
|
||||||
Song DatabaseSongMetadata() const { return Song(Song::Source_Collection); }
|
Song DatabaseSongMetadata() const { return Song(Song::Source_Collection); }
|
||||||
|
|||||||
@@ -64,8 +64,6 @@
|
|||||||
#include "organise/organisedialog.h"
|
#include "organise/organisedialog.h"
|
||||||
#include "settings/collectionsettingspage.h"
|
#include "settings/collectionsettingspage.h"
|
||||||
|
|
||||||
using std::unique_ptr;
|
|
||||||
|
|
||||||
CollectionView::CollectionView(QWidget *parent)
|
CollectionView::CollectionView(QWidget *parent)
|
||||||
: AutoExpandingTreeView(parent),
|
: AutoExpandingTreeView(parent),
|
||||||
app_(nullptr),
|
app_(nullptr),
|
||||||
@@ -463,11 +461,11 @@ void CollectionView::ShowInVarious(bool on) {
|
|||||||
|
|
||||||
void CollectionView::Load() {
|
void CollectionView::Load() {
|
||||||
|
|
||||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||||
if (MimeData *mime_data = qobject_cast<MimeData*>(data)) {
|
if (MimeData *mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||||
mime_data->clear_first_ = true;
|
mimedata->clear_first_ = true;
|
||||||
}
|
}
|
||||||
emit AddToPlaylistSignal(data);
|
emit AddToPlaylistSignal(q_mimedata);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,31 +477,31 @@ void CollectionView::AddToPlaylist() {
|
|||||||
|
|
||||||
void CollectionView::AddToPlaylistEnqueue() {
|
void CollectionView::AddToPlaylistEnqueue() {
|
||||||
|
|
||||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||||
if (MimeData* mime_data = qobject_cast<MimeData*>(data)) {
|
if (MimeData* mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||||
mime_data->enqueue_now_ = true;
|
mimedata->enqueue_now_ = true;
|
||||||
}
|
}
|
||||||
emit AddToPlaylistSignal(data);
|
emit AddToPlaylistSignal(q_mimedata);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollectionView::AddToPlaylistEnqueueNext() {
|
void CollectionView::AddToPlaylistEnqueueNext() {
|
||||||
|
|
||||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||||
if (MimeData *mime_data = qobject_cast<MimeData*>(data)) {
|
if (MimeData *mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||||
mime_data->enqueue_next_now_ = true;
|
mimedata->enqueue_next_now_ = true;
|
||||||
}
|
}
|
||||||
emit AddToPlaylistSignal(data);
|
emit AddToPlaylistSignal(q_mimedata);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollectionView::OpenInNewPlaylist() {
|
void CollectionView::OpenInNewPlaylist() {
|
||||||
|
|
||||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||||
if (MimeData* mime_data = qobject_cast<MimeData*>(data)) {
|
if (MimeData* mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||||
mime_data->open_in_new_playlist_ = true;
|
mimedata->open_in_new_playlist_ = true;
|
||||||
}
|
}
|
||||||
emit AddToPlaylistSignal(data);
|
emit AddToPlaylistSignal(q_mimedata);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,8 +47,6 @@ class CollectionFilterWidget;
|
|||||||
class EditTagDialog;
|
class EditTagDialog;
|
||||||
class OrganiseDialog;
|
class OrganiseDialog;
|
||||||
|
|
||||||
using std::unique_ptr;
|
|
||||||
|
|
||||||
class CollectionView : public AutoExpandingTreeView {
|
class CollectionView : public AutoExpandingTreeView {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|||||||
@@ -650,7 +650,7 @@ void CollectionWatcher::AddWatch(const Directory &dir, const QString &path) {
|
|||||||
|
|
||||||
if (!QFile::exists(path)) return;
|
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);
|
fs_watcher_->AddPath(path);
|
||||||
subdir_mapping_[path] = dir;
|
subdir_mapping_[path] = dir;
|
||||||
|
|
||||||
|
|||||||
@@ -45,10 +45,10 @@
|
|||||||
#cmakedefine HAVE_GSTREAMER
|
#cmakedefine HAVE_GSTREAMER
|
||||||
#cmakedefine HAVE_VLC
|
#cmakedefine HAVE_VLC
|
||||||
#cmakedefine HAVE_XINE
|
#cmakedefine HAVE_XINE
|
||||||
#cmakedefine HAVE_PHONON
|
|
||||||
#cmakedefine XINE_ANALYZER
|
#cmakedefine XINE_ANALYZER
|
||||||
|
|
||||||
#cmakedefine HAVE_SUBSONIC
|
#cmakedefine HAVE_SUBSONIC
|
||||||
|
#cmakedefine HAVE_TIDAL
|
||||||
|
|
||||||
#cmakedefine HAVE_MOODBAR
|
#cmakedefine HAVE_MOODBAR
|
||||||
|
|
||||||
|
|||||||
@@ -33,17 +33,22 @@
|
|||||||
#include <QTimeLine>
|
#include <QTimeLine>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QSizePolicy>
|
#include <QSizePolicy>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QContextMenuEvent>
|
||||||
#include <QPaintEvent>
|
#include <QPaintEvent>
|
||||||
|
|
||||||
#include "covermanager/albumcoverchoicecontroller.h"
|
#include "covermanager/albumcoverchoicecontroller.h"
|
||||||
#include "covermanager/albumcoverloader.h"
|
#include "covermanager/albumcoverloader.h"
|
||||||
|
|
||||||
|
#include "contextview.h"
|
||||||
#include "contextalbum.h"
|
#include "contextalbum.h"
|
||||||
|
|
||||||
const int ContextAlbum::kWidgetSpacing = 40;
|
const int ContextAlbum::kWidgetSpacing = 40;
|
||||||
|
|
||||||
ContextAlbum::ContextAlbum(QWidget *parent) :
|
ContextAlbum::ContextAlbum(QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
|
menu_(new QMenu(this)),
|
||||||
|
context_view_(nullptr),
|
||||||
album_cover_choice_controller_(nullptr),
|
album_cover_choice_controller_(nullptr),
|
||||||
downloading_covers_(false),
|
downloading_covers_(false),
|
||||||
timeline_fade_(new QTimeLine(1000, this)),
|
timeline_fade_(new QTimeLine(1000, this)),
|
||||||
@@ -57,18 +62,39 @@ ContextAlbum::ContextAlbum(QWidget *parent) :
|
|||||||
cover_loader_options_.desired_height_ = 600;
|
cover_loader_options_.desired_height_ = 600;
|
||||||
cover_loader_options_.pad_output_image_ = true;
|
cover_loader_options_.pad_output_image_ = true;
|
||||||
cover_loader_options_.scale_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)));
|
connect(timeline_fade_, SIGNAL(valueChanged(qreal)), SLOT(FadePreviousTrack(qreal)));
|
||||||
timeline_fade_->setDirection(QTimeLine::Backward); // 1.0 -> 0.0
|
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;
|
album_cover_choice_controller_ = album_cover_choice_controller;
|
||||||
connect(album_cover_choice_controller_, SIGNAL(AutomaticCoverSearchDone()), this, SLOT(AutomaticCoverSearchDone()));
|
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*) {
|
void ContextAlbum::paintEvent(QPaintEvent*) {
|
||||||
@@ -89,7 +115,7 @@ void ContextAlbum::DrawImage(QPainter *p) {
|
|||||||
|
|
||||||
if (width() != prev_width_) {
|
if (width() != prev_width_) {
|
||||||
cover_loader_options_.desired_height_ = width() - kWidgetSpacing;
|
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();
|
prev_width_ = width();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +144,7 @@ void ContextAlbum::FadePreviousTrack(const qreal value) {
|
|||||||
void ContextAlbum::ScaleCover() {
|
void ContextAlbum::ScaleCover() {
|
||||||
|
|
||||||
cover_loader_options_.desired_height_ = width() - kWidgetSpacing;
|
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();
|
prev_width_ = width();
|
||||||
update();
|
update();
|
||||||
|
|
||||||
@@ -162,7 +188,7 @@ void ContextAlbum::SearchCoverInProgress() {
|
|||||||
|
|
||||||
// Show a spinner animation
|
// Show a spinner animation
|
||||||
spinner_animation_.reset(new QMovie(":/pictures/spinner.gif", QByteArray(), this));
|
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();
|
spinner_animation_->start();
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
|||||||
@@ -34,10 +34,12 @@
|
|||||||
|
|
||||||
#include "covermanager/albumcoverloaderoptions.h"
|
#include "covermanager/albumcoverloaderoptions.h"
|
||||||
|
|
||||||
|
class QMenu;
|
||||||
class QTimeLine;
|
class QTimeLine;
|
||||||
class QPainter;
|
class QPainter;
|
||||||
class QPaintEvent;
|
class QPaintEvent;
|
||||||
|
|
||||||
|
class ContextView;
|
||||||
class AlbumCoverChoiceController;
|
class AlbumCoverChoiceController;
|
||||||
|
|
||||||
class ContextAlbum : public QWidget {
|
class ContextAlbum : public QWidget {
|
||||||
@@ -46,11 +48,13 @@ class ContextAlbum : public QWidget {
|
|||||||
public:
|
public:
|
||||||
explicit ContextAlbum(QWidget *parent = nullptr);
|
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());
|
void SetImage(QImage image = QImage());
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent*);
|
void paintEvent(QPaintEvent*);
|
||||||
|
void contextMenuEvent(QContextMenuEvent *e);
|
||||||
|
void mouseDoubleClickEvent(QMouseEvent *e);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DrawImage(QPainter *p);
|
void DrawImage(QPainter *p);
|
||||||
@@ -67,6 +71,10 @@ class ContextAlbum : public QWidget {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static const int kWidgetSpacing;
|
static const int kWidgetSpacing;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMenu *menu_;
|
||||||
|
ContextView *context_view_;
|
||||||
AlbumCoverChoiceController *album_cover_choice_controller_;
|
AlbumCoverChoiceController *album_cover_choice_controller_;
|
||||||
AlbumCoverLoaderOptions cover_loader_options_;
|
AlbumCoverLoaderOptions cover_loader_options_;
|
||||||
bool downloading_covers_;
|
bool downloading_covers_;
|
||||||
|
|||||||
@@ -48,11 +48,11 @@
|
|||||||
#include "playlist/playlistmanager.h"
|
#include "playlist/playlistmanager.h"
|
||||||
#include "playlist/songmimedata.h"
|
#include "playlist/songmimedata.h"
|
||||||
#include "covermanager/albumcoverloader.h"
|
#include "covermanager/albumcoverloader.h"
|
||||||
|
#include "covermanager/albumcoverloaderoptions.h"
|
||||||
|
#include "covermanager/albumcoverloaderresult.h"
|
||||||
|
|
||||||
#include "contextalbumsmodel.h"
|
#include "contextalbumsmodel.h"
|
||||||
|
|
||||||
using std::bind;
|
|
||||||
using std::sort;
|
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
using std::placeholders::_2;
|
using std::placeholders::_2;
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ ContextAlbumsModel::ContextAlbumsModel(CollectionBackend *backend, Application *
|
|||||||
cover_loader_options_.pad_output_image_ = true;
|
cover_loader_options_.pad_output_image_ = true;
|
||||||
cover_loader_options_.scale_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");
|
QIcon nocover = IconLoader::Load("cdcase");
|
||||||
no_cover_icon_ = nocover.pixmap(nocover.availableSizes().last()).scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
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) {
|
void ContextAlbumsModel::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result) {
|
||||||
|
|
||||||
Q_UNUSED(cover_url);
|
|
||||||
|
|
||||||
if (!pending_art_.contains(id)) return;
|
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);
|
pending_cache_keys_.remove(cache_key);
|
||||||
|
|
||||||
// Insert this image in the cache.
|
// 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.
|
// Set the no_cover image so we don't continually try to load art.
|
||||||
QPixmapCache::insert(cache_key, no_cover_icon_);
|
QPixmapCache::insert(cache_key, no_cover_icon_);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
QPixmap image_pixmap;
|
QPixmap image_pixmap;
|
||||||
image_pixmap = QPixmap::fromImage(image);
|
image_pixmap = QPixmap::fromImage(result.image_scaled);
|
||||||
QPixmapCache::insert(cache_key, image_pixmap);
|
QPixmapCache::insert(cache_key, image_pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#include "collection/collectionitem.h"
|
#include "collection/collectionitem.h"
|
||||||
#include "collection/sqlrow.h"
|
#include "collection/sqlrow.h"
|
||||||
#include "covermanager/albumcoverloaderoptions.h"
|
#include "covermanager/albumcoverloaderoptions.h"
|
||||||
|
#include "covermanager/albumcoverloaderresult.h"
|
||||||
|
|
||||||
class QMimeData;
|
class QMimeData;
|
||||||
|
|
||||||
@@ -99,7 +100,7 @@ class ContextAlbumsModel : public SimpleTreeModel<CollectionItem> {
|
|||||||
void LazyPopulate(CollectionItem *item, bool signal);
|
void LazyPopulate(CollectionItem *item, bool signal);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void AlbumCoverLoaded(const quint64 id, const QUrl &cover_url, const QImage &image);
|
void AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QueryResult RunQuery(CollectionItem *parent);
|
QueryResult RunQuery(CollectionItem *parent);
|
||||||
|
|||||||
@@ -321,11 +321,11 @@ void ContextAlbumsView::contextMenuEvent(QContextMenuEvent *e) {
|
|||||||
|
|
||||||
void ContextAlbumsView::Load() {
|
void ContextAlbumsView::Load() {
|
||||||
|
|
||||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||||
if (MimeData *mime_data = qobject_cast<MimeData*>(data)) {
|
if (MimeData *mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||||
mime_data->clear_first_ = true;
|
mimedata->clear_first_ = true;
|
||||||
}
|
}
|
||||||
emit AddToPlaylistSignal(data);
|
emit AddToPlaylistSignal(q_mimedata);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,21 +337,21 @@ void ContextAlbumsView::AddToPlaylist() {
|
|||||||
|
|
||||||
void ContextAlbumsView::AddToPlaylistEnqueue() {
|
void ContextAlbumsView::AddToPlaylistEnqueue() {
|
||||||
|
|
||||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||||
if (MimeData* mime_data = qobject_cast<MimeData*>(data)) {
|
if (MimeData *mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||||
mime_data->enqueue_now_ = true;
|
mimedata->enqueue_now_ = true;
|
||||||
}
|
}
|
||||||
emit AddToPlaylistSignal(data);
|
emit AddToPlaylistSignal(q_mimedata);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContextAlbumsView::OpenInNewPlaylist() {
|
void ContextAlbumsView::OpenInNewPlaylist() {
|
||||||
|
|
||||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||||
if (MimeData* mime_data = qobject_cast<MimeData*>(data)) {
|
if (MimeData *mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||||
mime_data->open_in_new_playlist_ = true;
|
mimedata->open_in_new_playlist_ = true;
|
||||||
}
|
}
|
||||||
emit AddToPlaylistSignal(data);
|
emit AddToPlaylistSignal(q_mimedata);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
#include <QFont>
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QSizePolicy>
|
#include <QSizePolicy>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
@@ -80,6 +81,7 @@ ContextView::ContextView(QWidget *parent) :
|
|||||||
action_show_output_(nullptr),
|
action_show_output_(nullptr),
|
||||||
action_show_albums_(nullptr),
|
action_show_albums_(nullptr),
|
||||||
action_show_lyrics_(nullptr),
|
action_show_lyrics_(nullptr),
|
||||||
|
action_search_lyrics_(nullptr),
|
||||||
layout_container_(new QVBoxLayout()),
|
layout_container_(new QVBoxLayout()),
|
||||||
widget_scrollarea_(new QWidget(this)),
|
widget_scrollarea_(new QWidget(this)),
|
||||||
layout_scrollarea_(new QVBoxLayout()),
|
layout_scrollarea_(new QVBoxLayout()),
|
||||||
@@ -124,6 +126,7 @@ ContextView::ContextView(QWidget *parent) :
|
|||||||
label_device_icon_(new QLabel(this)),
|
label_device_icon_(new QLabel(this)),
|
||||||
label_engine_icon_(new QLabel(this)),
|
label_engine_icon_(new QLabel(this)),
|
||||||
spacer_bottom_(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding)),
|
spacer_bottom_(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding)),
|
||||||
|
lyrics_tried_(false),
|
||||||
lyrics_id_(-1),
|
lyrics_id_(-1),
|
||||||
prev_width_(0)
|
prev_width_(0)
|
||||||
{
|
{
|
||||||
@@ -144,9 +147,10 @@ ContextView::ContextView(QWidget *parent) :
|
|||||||
widget_scrollarea_->setLayout(layout_scrollarea_);
|
widget_scrollarea_->setLayout(layout_scrollarea_);
|
||||||
widget_scrollarea_->setContentsMargins(0, 0, 0, 0);
|
widget_scrollarea_->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
label_top_->setWordWrap(true);
|
|
||||||
label_top_->setAlignment(Qt::AlignTop|Qt::AlignLeft);
|
label_top_->setAlignment(Qt::AlignTop|Qt::AlignLeft);
|
||||||
|
label_top_->setWordWrap(true);
|
||||||
label_top_->setMinimumHeight(50);
|
label_top_->setMinimumHeight(50);
|
||||||
|
label_top_->setContentsMargins(0, 0, 32, 0);
|
||||||
|
|
||||||
layout_scrollarea_->setObjectName("context-layout-scrollarea");
|
layout_scrollarea_->setObjectName("context-layout-scrollarea");
|
||||||
layout_scrollarea_->setContentsMargins(15, 15, 15, 15);
|
layout_scrollarea_->setContentsMargins(15, 15, 15, 15);
|
||||||
@@ -241,6 +245,8 @@ ContextView::ContextView(QWidget *parent) :
|
|||||||
label_play_lyrics_->setWordWrap(true);
|
label_play_lyrics_->setWordWrap(true);
|
||||||
label_play_lyrics_->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
label_play_lyrics_->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||||
|
|
||||||
|
label_play_albums_->setWordWrap(true);
|
||||||
|
|
||||||
layout_play_->setContentsMargins(5, 0, 40, 0);
|
layout_play_->setContentsMargins(5, 0, 40, 0);
|
||||||
layout_play_->addWidget(widget_play_output_);
|
layout_play_->addWidget(widget_play_output_);
|
||||||
layout_play_->addSpacerItem(spacer_play_output_);
|
layout_play_->addSpacerItem(spacer_play_output_);
|
||||||
@@ -252,6 +258,30 @@ ContextView::ContextView(QWidget *parent) :
|
|||||||
layout_play_->addWidget(label_play_lyrics_);
|
layout_play_->addWidget(label_play_lyrics_);
|
||||||
layout_play_->addSpacerItem(spacer_play_bottom_);
|
layout_play_->addSpacerItem(spacer_play_bottom_);
|
||||||
|
|
||||||
|
labels_play_ << label_engine_title_
|
||||||
|
<< label_device_title_
|
||||||
|
<< label_filetype_title_
|
||||||
|
<< label_length_title_
|
||||||
|
<< label_samplerate_title_
|
||||||
|
<< label_bitdepth_title_
|
||||||
|
<< label_bitrate_title_
|
||||||
|
<< label_play_albums_
|
||||||
|
<< label_play_lyrics_;
|
||||||
|
|
||||||
|
labels_play_data_ << label_engine_icon_
|
||||||
|
<< label_engine_
|
||||||
|
<< label_device_
|
||||||
|
<< label_device_icon_
|
||||||
|
<< label_filetype_
|
||||||
|
<< label_length_
|
||||||
|
<< label_samplerate_
|
||||||
|
<< label_bitdepth_
|
||||||
|
<< label_bitrate_
|
||||||
|
<< label_play_albums_
|
||||||
|
<< label_play_lyrics_;
|
||||||
|
|
||||||
|
labels_play_all_ = labels_play_ << labels_play_data_;
|
||||||
|
|
||||||
QFontDatabase::addApplicationFont(":/fonts/HumongousofEternitySt.ttf");
|
QFontDatabase::addApplicationFont(":/fonts/HumongousofEternitySt.ttf");
|
||||||
|
|
||||||
connect(widget_album_, SIGNAL(FadeStopFinished()), SLOT(FadeStopFinished()));
|
connect(widget_album_, SIGNAL(FadeStopFinished()), SLOT(FadeStopFinished()));
|
||||||
@@ -270,14 +300,14 @@ void ContextView::Init(Application *app, CollectionView *collectionview, AlbumCo
|
|||||||
collectionview_ = collectionview;
|
collectionview_ = collectionview;
|
||||||
album_cover_choice_controller_ = album_cover_choice_controller;
|
album_cover_choice_controller_ = album_cover_choice_controller;
|
||||||
|
|
||||||
widget_album_->Init(album_cover_choice_controller_);
|
widget_album_->Init(this, album_cover_choice_controller_);
|
||||||
widget_albums_->Init(app_);
|
widget_albums_->Init(app_);
|
||||||
lyrics_fetcher_ = new LyricsFetcher(app_->lyrics_providers(), this);
|
lyrics_fetcher_ = new LyricsFetcher(app_->lyrics_providers(), this);
|
||||||
|
|
||||||
connect(collectionview_, SIGNAL(TotalSongCountUpdated_()), this, SLOT(UpdateNoSong()));
|
connect(collectionview_, SIGNAL(TotalSongCountUpdated_()), this, SLOT(UpdateNoSong()));
|
||||||
connect(collectionview_, SIGNAL(TotalArtistCountUpdated_()), this, SLOT(UpdateNoSong()));
|
connect(collectionview_, SIGNAL(TotalArtistCountUpdated_()), this, SLOT(UpdateNoSong()));
|
||||||
connect(collectionview_, SIGNAL(TotalAlbumCountUpdated_()), this, SLOT(UpdateNoSong()));
|
connect(collectionview_, SIGNAL(TotalAlbumCountUpdated_()), this, SLOT(UpdateNoSong()));
|
||||||
connect(lyrics_fetcher_, SIGNAL(LyricsFetched(const quint64, const QString&, const QString&)), this, SLOT(UpdateLyrics(const quint64, const QString&, const QString&)));
|
connect(lyrics_fetcher_, SIGNAL(LyricsFetched(quint64, QString, QString)), this, SLOT(UpdateLyrics(quint64, QString, QString)));
|
||||||
|
|
||||||
AddActions();
|
AddActions();
|
||||||
|
|
||||||
@@ -299,22 +329,22 @@ void ContextView::AddActions() {
|
|||||||
|
|
||||||
action_show_albums_ = new QAction(tr("Show albums by artist"), this);
|
action_show_albums_ = new QAction(tr("Show albums by artist"), this);
|
||||||
action_show_albums_->setCheckable(true);
|
action_show_albums_->setCheckable(true);
|
||||||
action_show_albums_->setChecked(true);
|
action_show_albums_->setChecked(false);
|
||||||
|
|
||||||
action_show_lyrics_ = new QAction(tr("Show song lyrics"), this);
|
action_show_lyrics_ = new QAction(tr("Show song lyrics"), this);
|
||||||
action_show_lyrics_->setCheckable(true);
|
action_show_lyrics_->setCheckable(true);
|
||||||
action_show_lyrics_->setChecked(false);
|
action_show_lyrics_->setChecked(true);
|
||||||
|
|
||||||
|
action_search_lyrics_ = new QAction(tr("Automatically search for song lyrics"), this);
|
||||||
|
action_search_lyrics_->setCheckable(true);
|
||||||
|
action_search_lyrics_->setChecked(true);
|
||||||
|
|
||||||
menu_->addAction(action_show_album_);
|
menu_->addAction(action_show_album_);
|
||||||
menu_->addAction(action_show_data_);
|
menu_->addAction(action_show_data_);
|
||||||
menu_->addAction(action_show_output_);
|
menu_->addAction(action_show_output_);
|
||||||
menu_->addAction(action_show_albums_);
|
menu_->addAction(action_show_albums_);
|
||||||
menu_->addAction(action_show_lyrics_);
|
menu_->addAction(action_show_lyrics_);
|
||||||
menu_->addSeparator();
|
menu_->addAction(action_search_lyrics_);
|
||||||
|
|
||||||
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();
|
menu_->addSeparator();
|
||||||
|
|
||||||
ReloadSettings();
|
ReloadSettings();
|
||||||
@@ -324,6 +354,7 @@ void ContextView::AddActions() {
|
|||||||
connect(action_show_output_, SIGNAL(triggered()), this, SLOT(ActionShowOutput()));
|
connect(action_show_output_, SIGNAL(triggered()), this, SLOT(ActionShowOutput()));
|
||||||
connect(action_show_albums_, SIGNAL(triggered()), this, SLOT(ActionShowAlbums()));
|
connect(action_show_albums_, SIGNAL(triggered()), this, SLOT(ActionShowAlbums()));
|
||||||
connect(action_show_lyrics_, SIGNAL(triggered()), this, SLOT(ActionShowLyrics()));
|
connect(action_show_lyrics_, SIGNAL(triggered()), this, SLOT(ActionShowLyrics()));
|
||||||
|
connect(action_search_lyrics_, SIGNAL(triggered()), this, SLOT(ActionSearchLyrics()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,8 +369,15 @@ void ContextView::ReloadSettings() {
|
|||||||
action_show_output_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::ENGINE_AND_DEVICE], true).toBool());
|
action_show_output_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::ENGINE_AND_DEVICE], true).toBool());
|
||||||
action_show_albums_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::ALBUMS_BY_ARTIST], false).toBool());
|
action_show_albums_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::ALBUMS_BY_ARTIST], false).toBool());
|
||||||
action_show_lyrics_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::SONG_LYRICS], true).toBool());
|
action_show_lyrics_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::SONG_LYRICS], true).toBool());
|
||||||
|
action_search_lyrics_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::SEARCH_LYRICS], true).toBool());
|
||||||
|
font_headline_ = s.value("font_headline", font().family()).toString();
|
||||||
|
font_normal_ = s.value("font_normal", font().family()).toString();
|
||||||
|
font_size_headline_ = s.value("font_size_headline", ContextSettingsPage::kDefaultFontSizeHeadline).toReal();
|
||||||
|
font_size_normal_ = s.value("font_size_normal", font().pointSizeF()).toReal();
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
|
UpdateFonts();
|
||||||
|
|
||||||
if (widget_stacked_->currentWidget() == widget_stop_) {
|
if (widget_stacked_->currentWidget() == widget_stop_) {
|
||||||
NoSong();
|
NoSong();
|
||||||
}
|
}
|
||||||
@@ -355,7 +393,7 @@ void ContextView::Stopped() {
|
|||||||
|
|
||||||
song_playing_ = Song();
|
song_playing_ = Song();
|
||||||
song_prev_ = Song();
|
song_prev_ = Song();
|
||||||
lyrics_ = QString();
|
lyrics_.clear();
|
||||||
image_original_ = QImage();
|
image_original_ = QImage();
|
||||||
widget_album_->SetImage();
|
widget_album_->SetImage();
|
||||||
|
|
||||||
@@ -365,19 +403,28 @@ void ContextView::Error() {}
|
|||||||
|
|
||||||
void ContextView::SongChanged(const Song &song) {
|
void ContextView::SongChanged(const Song &song) {
|
||||||
|
|
||||||
if (widget_stacked_->currentWidget() == widget_play_ && song_playing_.is_valid() && song == song_playing_) {
|
if (widget_stacked_->currentWidget() == widget_play_ && song_playing_.is_valid() && song == song_playing_ && song.title() == song_playing_.title() && song.album() == song_playing_.album() && song.artist() == song_playing_.artist()) {
|
||||||
UpdateSong(song);
|
UpdateSong(song);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
song_prev_ = song_playing_;
|
song_prev_ = song_playing_;
|
||||||
|
song_playing_ = song;
|
||||||
lyrics_ = song.lyrics();
|
lyrics_ = song.lyrics();
|
||||||
lyrics_id_ = -1;
|
lyrics_id_ = -1;
|
||||||
song_playing_ = song;
|
lyrics_tried_ = false;
|
||||||
SetSong();
|
SetSong();
|
||||||
if (lyrics_.isEmpty() && action_show_lyrics_->isChecked() && !song.artist().isEmpty() && !song.title().isEmpty()) {
|
}
|
||||||
lyrics_fetcher_->Clear();
|
|
||||||
lyrics_id_ = lyrics_fetcher_->Search(song.effective_albumartist(), song.album(), song.title());
|
SearchLyrics();
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContextView::SearchLyrics() {
|
||||||
|
|
||||||
|
if (lyrics_.isEmpty() && action_show_lyrics_->isChecked() && action_search_lyrics_->isChecked() && !song_playing_.artist().isEmpty() && !song_playing_.title().isEmpty() && !lyrics_tried_ && lyrics_id_ == -1) {
|
||||||
|
lyrics_fetcher_->Clear();
|
||||||
|
lyrics_tried_ = true;
|
||||||
|
lyrics_id_ = lyrics_fetcher_->Search(song_playing_.effective_albumartist(), song_playing_.album(), song_playing_.title());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -421,14 +468,23 @@ void ContextView::NoSong() {
|
|||||||
else html += tr("%1 albums").arg(collectionview_->TotalAlbums());
|
else html += tr("%1 albums").arg(collectionview_->TotalAlbums());
|
||||||
html += "<br />";
|
html += "<br />";
|
||||||
|
|
||||||
label_stop_summary_->setStyleSheet("font: 12pt; font-weight: regular;");
|
label_stop_summary_->setStyleSheet(QString("font: %1pt \"%2\"; font-weight: regular;").arg(font_size_normal_).arg(font_normal_));
|
||||||
label_stop_summary_->setText(html);
|
label_stop_summary_->setText(html);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContextView::UpdateFonts() {
|
||||||
|
|
||||||
|
for (QLabel *l: labels_play_all_) {
|
||||||
|
l->setStyleSheet(QString("font: %2pt \"%1\"; font-weight: regular;").arg(font_normal_).arg(font_size_normal_));
|
||||||
|
}
|
||||||
|
label_play_albums_->setStyleSheet(QString("background-color: #3DADE8; color: rgb(255, 255, 255); font: %1pt \"%2\"; font-weight: regular;").arg(font_size_normal_).arg(font_normal_));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void ContextView::SetSong() {
|
void ContextView::SetSong() {
|
||||||
|
|
||||||
label_top_->setStyleSheet("font: 11pt; font-weight: regular;");
|
label_top_->setStyleSheet(QString("font: %2pt \"%1\"; font-weight: regular;").arg(font_headline_).arg(font_size_headline_));
|
||||||
label_top_->setText(QString("<b>%1</b><br/>%2").arg(Utilities::ReplaceMessage(title_fmt_, song_playing_, "<br/>"), Utilities::ReplaceMessage(summary_fmt_, song_playing_, "<br/>")));
|
label_top_->setText(QString("<b>%1</b><br/>%2").arg(Utilities::ReplaceMessage(title_fmt_, song_playing_, "<br/>"), Utilities::ReplaceMessage(summary_fmt_, song_playing_, "<br/>")));
|
||||||
|
|
||||||
label_stop_summary_->clear();
|
label_stop_summary_->clear();
|
||||||
@@ -447,7 +503,16 @@ void ContextView::SetSong() {
|
|||||||
if (action_show_data_->isChecked()) {
|
if (action_show_data_->isChecked()) {
|
||||||
widget_play_data_->show();
|
widget_play_data_->show();
|
||||||
label_filetype_->setText(song_playing_.TextForFiletype());
|
label_filetype_->setText(song_playing_.TextForFiletype());
|
||||||
label_length_->setText(Utilities::PrettyTimeNanosec(song_playing_.length_nanosec()));
|
if (song_playing_.length_nanosec() <= 0) {
|
||||||
|
label_length_title_->hide();
|
||||||
|
label_length_->hide();
|
||||||
|
label_length_->clear();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
label_length_title_->show();
|
||||||
|
label_length_->show();
|
||||||
|
label_length_->setText(Utilities::PrettyTimeNanosec(song_playing_.length_nanosec()));
|
||||||
|
}
|
||||||
if (song_playing_.samplerate() <= 0) {
|
if (song_playing_.samplerate() <= 0) {
|
||||||
label_samplerate_title_->hide();
|
label_samplerate_title_->hide();
|
||||||
label_samplerate_->hide();
|
label_samplerate_->hide();
|
||||||
@@ -496,7 +561,7 @@ void ContextView::SetSong() {
|
|||||||
if (app_->player()->engine()) enginetype = app_->player()->engine()->type();
|
if (app_->player()->engine()) enginetype = app_->player()->engine()->type();
|
||||||
QIcon icon_engine = IconLoader::Load(EngineName(enginetype), 32);
|
QIcon icon_engine = IconLoader::Load(EngineName(enginetype), 32);
|
||||||
|
|
||||||
label_engine_icon_->setPixmap(icon_engine.pixmap(icon_engine.availableSizes().last()));
|
label_engine_icon_->setPixmap(icon_engine.pixmap(QSize(32, 32)));
|
||||||
label_engine_->setText(EngineDescription(enginetype));
|
label_engine_->setText(EngineDescription(enginetype));
|
||||||
spacer_play_output_->changeSize(20, 20, QSizePolicy::Fixed);
|
spacer_play_output_->changeSize(20, 20, QSizePolicy::Fixed);
|
||||||
|
|
||||||
@@ -513,7 +578,7 @@ void ContextView::SetSong() {
|
|||||||
label_device_icon_->show();
|
label_device_icon_->show();
|
||||||
label_device_->show();
|
label_device_->show();
|
||||||
QIcon icon_device = IconLoader::Load(device.iconname, 32);
|
QIcon icon_device = IconLoader::Load(device.iconname, 32);
|
||||||
label_device_icon_->setPixmap(icon_device.pixmap(icon_device.availableSizes().last()));
|
label_device_icon_->setPixmap(icon_device.pixmap(QSize(32, 32)));
|
||||||
label_device_->setText(device.description);
|
label_device_->setText(device.description);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -542,7 +607,6 @@ void ContextView::SetSong() {
|
|||||||
label_play_albums_->show();
|
label_play_albums_->show();
|
||||||
widget_albums_->show();
|
widget_albums_->show();
|
||||||
label_play_albums_->setText("<b>" + tr("Albums by %1").arg( song_playing_.artist().toHtmlEscaped()) + "</b>");
|
label_play_albums_->setText("<b>" + tr("Albums by %1").arg( song_playing_.artist().toHtmlEscaped()) + "</b>");
|
||||||
label_play_albums_->setStyleSheet("background-color: #3DADE8; color: rgb(255, 255, 255); font: 11pt;");
|
|
||||||
for (CollectionBackend::Album album : albumlist) {
|
for (CollectionBackend::Album album : albumlist) {
|
||||||
SongList songs = app_->collection_backend()->GetSongs(song_playing_.artist(), album.album_name, opt);
|
SongList songs = app_->collection_backend()->GetSongs(song_playing_.artist(), album.album_name, opt);
|
||||||
widget_albums_->albums_model()->AddSongs(songs);
|
widget_albums_->albums_model()->AddSongs(songs);
|
||||||
@@ -583,7 +647,18 @@ void ContextView::UpdateSong(const Song &song) {
|
|||||||
|
|
||||||
if (action_show_data_->isChecked()) {
|
if (action_show_data_->isChecked()) {
|
||||||
if (song.filetype() != song_playing_.filetype()) label_filetype_->setText(song.TextForFiletype());
|
if (song.filetype() != song_playing_.filetype()) label_filetype_->setText(song.TextForFiletype());
|
||||||
if (song.length_nanosec() != song_playing_.length_nanosec()) label_length_->setText(Utilities::PrettyTimeNanosec(song.length_nanosec()));
|
if (song.length_nanosec() != song_playing_.length_nanosec()){
|
||||||
|
if (song.length_nanosec() <= 0) {
|
||||||
|
label_length_title_->hide();
|
||||||
|
label_length_->hide();
|
||||||
|
label_length_->clear();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
label_length_title_->show();
|
||||||
|
label_length_->show();
|
||||||
|
label_length_->setText(Utilities::PrettyTimeNanosec(song.length_nanosec()));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (song.samplerate() != song_playing_.samplerate()) {
|
if (song.samplerate() != song_playing_.samplerate()) {
|
||||||
if (song.samplerate() <= 0) {
|
if (song.samplerate() <= 0) {
|
||||||
label_samplerate_title_->hide();
|
label_samplerate_title_->hide();
|
||||||
@@ -628,21 +703,7 @@ void ContextView::UpdateSong(const Song &song) {
|
|||||||
|
|
||||||
void ContextView::ResetSong() {
|
void ContextView::ResetSong() {
|
||||||
|
|
||||||
QList <QLabel *> labels_play_data;
|
for (QLabel *l: labels_play_data_) {
|
||||||
|
|
||||||
labels_play_data << label_engine_icon_
|
|
||||||
<< label_engine_
|
|
||||||
<< label_device_
|
|
||||||
<< label_device_icon_
|
|
||||||
<< label_filetype_
|
|
||||||
<< label_length_
|
|
||||||
<< label_samplerate_
|
|
||||||
<< label_bitdepth_
|
|
||||||
<< label_bitrate_
|
|
||||||
<< label_play_albums_
|
|
||||||
<< label_play_lyrics_;
|
|
||||||
|
|
||||||
for (QLabel *l: labels_play_data) {
|
|
||||||
l->clear();
|
l->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,7 +722,7 @@ void ContextView::UpdateLyrics(const quint64 id, const QString &provider, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ContextView::contextMenuEvent(QContextMenuEvent *e) {
|
void ContextView::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
if (menu_ && widget_stacked_->currentWidget() == widget_play_) menu_->popup(mapToGlobal(e->pos()));
|
if (menu_) menu_->popup(mapToGlobal(e->pos()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContextView::dragEnterEvent(QDragEnterEvent *e) {
|
void ContextView::dragEnterEvent(QDragEnterEvent *e) {
|
||||||
@@ -684,9 +745,7 @@ void ContextView::dropEvent(QDropEvent *e) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContextView::AlbumCoverLoaded(const Song &song, const QUrl &cover_url, const QImage &image) {
|
void ContextView::AlbumCoverLoaded(const Song &song, const QImage &image) {
|
||||||
|
|
||||||
Q_UNUSED(cover_url);
|
|
||||||
|
|
||||||
if (song != song_playing_ || image == image_original_) return;
|
if (song != song_playing_ || image == image_original_) return;
|
||||||
|
|
||||||
@@ -742,11 +801,22 @@ void ContextView::ActionShowLyrics() {
|
|||||||
s.beginGroup(ContextSettingsPage::kSettingsGroup);
|
s.beginGroup(ContextSettingsPage::kSettingsGroup);
|
||||||
s.setValue(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::SONG_LYRICS], action_show_lyrics_->isChecked());
|
s.setValue(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::SONG_LYRICS], action_show_lyrics_->isChecked());
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
if (song_playing_.is_valid()) SetSong();
|
if (song_playing_.is_valid()) SetSong();
|
||||||
|
|
||||||
if (lyrics_.isEmpty() && action_show_lyrics_->isChecked() && !song_playing_.artist().isEmpty() && !song_playing_.title().isEmpty()) {
|
SearchLyrics();
|
||||||
lyrics_fetcher_->Clear();
|
|
||||||
lyrics_id_ = lyrics_fetcher_->Search(song_playing_.artist(), song_playing_.album(), song_playing_.title());
|
}
|
||||||
}
|
|
||||||
|
void ContextView::ActionSearchLyrics() {
|
||||||
|
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(ContextSettingsPage::kSettingsGroup);
|
||||||
|
s.setValue(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::SEARCH_LYRICS], action_search_lyrics_->isChecked());
|
||||||
|
s.endGroup();
|
||||||
|
|
||||||
|
if (song_playing_.is_valid()) SetSong();
|
||||||
|
|
||||||
|
SearchLyrics();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||