Compare commits
223 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f2ec22e95 | ||
|
|
65b2e506b1 | ||
|
|
8bc07b5286 | ||
|
|
fe0af63795 | ||
|
|
44ce7f4c67 | ||
|
|
252936134b | ||
|
|
e255b06945 | ||
|
|
d726568a23 | ||
|
|
66880a6de7 | ||
|
|
fda622a0c0 | ||
|
|
efa7d10f40 | ||
|
|
348a3fabab | ||
|
|
1bbaee605c | ||
|
|
22edf7a2b3 | ||
|
|
3ffcc29249 | ||
|
|
21f1fe52c0 | ||
|
|
99840c9e4f | ||
|
|
3194fe7d8e | ||
|
|
81df72b0cb | ||
|
|
57b056ac43 | ||
|
|
c5876d0d48 | ||
|
|
b5e65401b6 | ||
|
|
ebea5b48ea | ||
|
|
7d081e581a | ||
|
|
5e819cf04b | ||
|
|
fd9ab43681 | ||
|
|
4935cdc722 | ||
|
|
26a3c7ad6a | ||
|
|
c358216ad9 | ||
|
|
bb9302143c | ||
|
|
3a73553aac | ||
|
|
6447a17e3e | ||
|
|
4bd5c8ffb3 | ||
|
|
89f137b211 | ||
|
|
3425572c66 | ||
|
|
ad50875f9c | ||
|
|
34e5645dab | ||
|
|
e8ae91c230 | ||
|
|
44b83994fa | ||
|
|
201f585350 | ||
|
|
e4d2f1925e | ||
|
|
658c116eac | ||
|
|
dbbedee77f | ||
|
|
16ac9ea061 | ||
|
|
6afbc71b4a | ||
|
|
71263863ad | ||
|
|
05232065f8 | ||
|
|
f289ae4143 | ||
|
|
91703ecec4 | ||
|
|
6fb0858b87 | ||
|
|
f1c6620df9 | ||
|
|
08fed9a5ee | ||
|
|
eb28b3b05b | ||
|
|
f0c354b0c9 | ||
|
|
07d88e86a2 | ||
|
|
f41a3b9bb2 | ||
|
|
bfd9e76f40 | ||
|
|
38ce208a43 | ||
|
|
fcd148b8d5 | ||
|
|
fc6c3774b0 | ||
|
|
18023d2e18 | ||
|
|
467e834ad6 | ||
|
|
629d9e7ae0 | ||
|
|
4487d292e8 | ||
|
|
76711b9a66 | ||
|
|
b54c749e43 | ||
|
|
d82fd421ed | ||
|
|
abdcadb5fa | ||
|
|
fa3891e383 | ||
|
|
f1dc0f95c8 | ||
|
|
5c721d243a | ||
|
|
2770384f1f | ||
|
|
f4e5b83039 | ||
|
|
124681605b | ||
|
|
a217faae7c | ||
|
|
184c39bbb7 | ||
|
|
508e2a70bb | ||
|
|
5aac56fe96 | ||
|
|
dab7dad966 | ||
|
|
25e48d6cae | ||
|
|
9b743e55d1 | ||
|
|
dc1f9edfaf | ||
|
|
b6b68edf1e | ||
|
|
a2320b99ae | ||
|
|
be01e28068 | ||
|
|
d6084083a5 | ||
|
|
019bf5102c | ||
|
|
a1633224d1 | ||
|
|
e62bd26cb9 | ||
|
|
c29f517292 | ||
|
|
d80144f80c | ||
|
|
4733c84a86 | ||
|
|
23f3d2095b | ||
|
|
4f1f2b6fc6 | ||
|
|
1ea70b085f | ||
|
|
6c0b395f4a | ||
|
|
0ee67f186f | ||
|
|
d133addbaa | ||
|
|
683991b1c9 | ||
|
|
32ac02007b | ||
|
|
d716617ae0 | ||
|
|
26e1f015d2 | ||
|
|
1c94093a4b | ||
|
|
27eccd456a | ||
|
|
eed4447560 | ||
|
|
3c8d0ebd52 | ||
|
|
7ec0d2f2cc | ||
|
|
35da91a997 | ||
|
|
788747c071 | ||
|
|
36eb131289 | ||
|
|
f231f28818 | ||
|
|
aebdc89f77 | ||
|
|
4a3a379871 | ||
|
|
a7f27add2d | ||
|
|
cd1d4247cf | ||
|
|
6d618c4b78 | ||
|
|
ad469531ff | ||
|
|
cf9b4b1246 | ||
|
|
18a2692dc1 | ||
|
|
a2dad982f8 | ||
|
|
8f27b6a4c9 | ||
|
|
21c4022fca | ||
|
|
237933855a | ||
|
|
dff7068a03 | ||
|
|
8f28a85a6d | ||
|
|
2414eb2598 | ||
|
|
4851f6bffd | ||
|
|
948be36d3c | ||
|
|
edd088927d | ||
|
|
4cfe8dd95e | ||
|
|
e1ce81c5bf | ||
|
|
0f40b5f022 | ||
|
|
94c5ffa92e | ||
|
|
3c9bf56767 | ||
|
|
9024acb16e | ||
|
|
7732402122 | ||
|
|
2059bce6a7 | ||
|
|
499c86a8b8 | ||
|
|
ef084eb145 | ||
|
|
3f3ae7c38f | ||
|
|
83d762287f | ||
|
|
5af0acf147 | ||
|
|
907dfee6f7 | ||
|
|
d587d24603 | ||
|
|
c246b8f164 | ||
|
|
deecafa053 | ||
|
|
f8810106a2 | ||
|
|
8e35fbe532 | ||
|
|
b1fdccde6e | ||
|
|
6741f100a1 | ||
|
|
e05e9ea1b2 | ||
|
|
197341de5e | ||
|
|
2933482be3 | ||
|
|
c7ce23239f | ||
|
|
79115f7439 | ||
|
|
4457103672 | ||
|
|
d204875f72 | ||
|
|
c690e73b1a | ||
|
|
b5d39c5f21 | ||
|
|
7f8834cb04 | ||
|
|
0dab7e293c | ||
|
|
8f016880af | ||
|
|
f471462a84 | ||
|
|
58eec8df1e | ||
|
|
2655b8b43a | ||
|
|
ea86c043a4 | ||
|
|
c1faa616bc | ||
|
|
a68bf5a30d | ||
|
|
9568b8e0e5 | ||
|
|
b34321ef87 | ||
|
|
4971f1c5bf | ||
|
|
962b52bd5b | ||
|
|
9449bfa414 | ||
|
|
5b8e9066c6 | ||
|
|
8690be7fd2 | ||
|
|
497267016b | ||
|
|
0468f850c2 | ||
|
|
b9e7d4e30c | ||
|
|
0e7734b555 | ||
|
|
e81dcce5b3 | ||
|
|
38bd1f7e1c | ||
|
|
36ad9704a2 | ||
|
|
a6c05df362 | ||
|
|
f6b70fda71 | ||
|
|
8cb4e75f70 | ||
|
|
da1815ac2b | ||
|
|
f7357f2d10 | ||
|
|
d9c92c5ddd | ||
|
|
c82bdb6405 | ||
|
|
eec8ee5830 | ||
|
|
e67eb3c0d8 | ||
|
|
9c101759f6 | ||
|
|
a55ee92590 | ||
|
|
5ccfc97dab | ||
|
|
d6dd88ec3d | ||
|
|
8557d83599 | ||
|
|
94cf1f8698 | ||
|
|
9ada35c3a3 | ||
|
|
79b0c906fa | ||
|
|
a0688f1dba | ||
|
|
f91e8fecee | ||
|
|
1b363babe2 | ||
|
|
73843cb54d | ||
|
|
a2ccfc2116 | ||
|
|
fe104e2bad | ||
|
|
35e3e9f4ff | ||
|
|
b2a1cd9716 | ||
|
|
14f58eae4b | ||
|
|
5cec000618 | ||
|
|
4805a5287d | ||
|
|
4789dc5b30 | ||
|
|
5a35099043 | ||
|
|
4cd0128919 | ||
|
|
61e9b80f67 | ||
|
|
dcd881ba6c | ||
|
|
d40a67ce68 | ||
|
|
1c1e7ca62a | ||
|
|
d3831d511b | ||
|
|
0942e93144 | ||
|
|
98d3eba8e8 | ||
|
|
ff3db03696 | ||
|
|
3608c31d22 | ||
|
|
8d504d9cee |
3
.github/ISSUE_TEMPLATE.md
vendored
3
.github/ISSUE_TEMPLATE.md
vendored
@@ -7,7 +7,8 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
For technical issues, questions and feature suggestions/requests please use the forum on https://forum.strawberrymusicplayer.org/
|
||||
For technical issues, questions and discussion please use the forum on https://forum.strawberrymusicplayer.org/
|
||||
Any issues related to feature requests will be closed. See the README for more details.
|
||||
|
||||
Check the Changelog to see if the issue is already fixed:
|
||||
https://github.com/strawberrymusicplayer/strawberry/blob/master/Changelog
|
||||
|
||||
1661
.github/workflows/ccpp.yml
vendored
1661
.github/workflows/ccpp.yml
vendored
File diff suppressed because it is too large
Load Diff
1
.gitignore
vendored
1
.gitignore
vendored
@@ -105,7 +105,6 @@ Thumbs.db
|
||||
# Stuff in dist
|
||||
maketarball.sh
|
||||
changelog
|
||||
PKGBUILD
|
||||
|
||||
# Translations
|
||||
translations.pot
|
||||
|
||||
132
3rdparty/macdeployqt/shared.cpp
vendored
132
3rdparty/macdeployqt/shared.cpp
vendored
@@ -1214,28 +1214,42 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
|
||||
|
||||
// GIO modules
|
||||
{
|
||||
QString sourcePath = qgetenv("GIO_EXTRA_MODULES");
|
||||
if (sourcePath.isEmpty()) {
|
||||
if (QFileInfo::exists("/usr/local/lib/gio/modules/libgiognutls.so")) {
|
||||
sourcePath = "/usr/local/lib/gio/modules/libgiognutls.so";
|
||||
QString giomodule_path = qgetenv("GIO_EXTRA_MODULES");
|
||||
if (giomodule_path.isEmpty()) {
|
||||
if (QDir().exists("/usr/local/lib/gio/modules")) {
|
||||
giomodule_path = "/usr/local/lib/gio/modules";
|
||||
}
|
||||
else if (QFileInfo::exists("/opt/local/lib/gio/modules/libgiognutls.so")) {
|
||||
sourcePath = "/opt/local/lib/gio/modules/libgiognutls.so";
|
||||
else if (QDir().exists("/opt/local/lib/gio/modules")) {
|
||||
giomodule_path = "/opt/local/lib/gio/modules";
|
||||
}
|
||||
else {
|
||||
qFatal("Missing GIO_EXTRA_MODULES");
|
||||
}
|
||||
}
|
||||
else {
|
||||
sourcePath = sourcePath + "/libgiognutls.so";
|
||||
|
||||
const QStringList giomodules = QStringList() << "libgiognutls.so" << "libgioopenssl.so";
|
||||
bool have_giomodule = false;
|
||||
for (const QString &giomodule : giomodules) {
|
||||
const QString sourcePath = giomodule_path + "/" + giomodule;
|
||||
QFileInfo fileinfo(sourcePath);
|
||||
if (!fileinfo.exists()) {
|
||||
LogError() << "Missing GIO module" << fileinfo.baseName();
|
||||
continue;
|
||||
}
|
||||
have_giomodule = true;
|
||||
const QString destinationPath = appBundleInfo.path + "/Contents/PlugIns/gio-modules/" + giomodule;
|
||||
QDir dir;
|
||||
if (dir.mkpath(QFileInfo(destinationPath).path()) && copyFilePrintStatus(sourcePath, destinationPath)) {
|
||||
runStrip(destinationPath);
|
||||
QList<FrameworkInfo> frameworks = getQtFrameworks(destinationPath, appBundleInfo.path, deploymentInfo.rpathsUsed, useDebugLibs);
|
||||
deployQtFrameworks(frameworks, appBundleInfo.path, QStringList() << destinationPath, useDebugLibs, deploymentInfo.useLoaderPath);
|
||||
}
|
||||
}
|
||||
const QString destinationPath = appBundleInfo.path + "/Contents/PlugIns/gio-modules/libgiognutls.so";
|
||||
QDir dir;
|
||||
if (dir.mkpath(QFileInfo(destinationPath).path()) && copyFilePrintStatus(sourcePath, destinationPath)) {
|
||||
runStrip(destinationPath);
|
||||
QList<FrameworkInfo> frameworks = getQtFrameworks(destinationPath, appBundleInfo.path, deploymentInfo.rpathsUsed, useDebugLibs);
|
||||
deployQtFrameworks(frameworks, appBundleInfo.path, QStringList() << destinationPath, useDebugLibs, deploymentInfo.useLoaderPath);
|
||||
|
||||
if (!have_giomodule) {
|
||||
qFatal("Missing GIO modules.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// gst-plugin-scanner
|
||||
@@ -1262,8 +1276,13 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
|
||||
}
|
||||
|
||||
// GStreamer plugins.
|
||||
QStringList gstreamer_plugins = QStringList() << "libgstapetag.dylib"
|
||||
QStringList gstreamer_plugins = QStringList()
|
||||
<< "libgstaes.dylib"
|
||||
<< "libgstaiff.dylib"
|
||||
<< "libgstapetag.dylib"
|
||||
<< "libgstapp.dylib"
|
||||
<< "libgstasf.dylib"
|
||||
<< "libgstasfmux.dylib"
|
||||
<< "libgstaudioconvert.dylib"
|
||||
<< "libgstaudiofx.dylib"
|
||||
<< "libgstaudiomixer.dylib"
|
||||
@@ -1271,48 +1290,50 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
|
||||
<< "libgstaudiorate.dylib"
|
||||
<< "libgstaudioresample.dylib"
|
||||
<< "libgstaudiotestsrc.dylib"
|
||||
<< "libgstaudiovisualizers.dylib"
|
||||
<< "libgstauparse.dylib"
|
||||
<< "libgstautoconvert.dylib"
|
||||
<< "libgstautodetect.dylib"
|
||||
<< "libgstbs2b.dylib"
|
||||
<< "libgstcdio.dylib"
|
||||
<< "libgstcoreelements.dylib"
|
||||
<< "libgstdash.dylib"
|
||||
<< "libgstequalizer.dylib"
|
||||
<< "libgstfaac.dylib"
|
||||
<< "libgstfaad.dylib"
|
||||
<< "libgstfdkaac.dylib"
|
||||
<< "libgstflac.dylib"
|
||||
<< "libgstgio.dylib"
|
||||
<< "libgsthls.dylib"
|
||||
<< "libgsticydemux.dylib"
|
||||
<< "libgstid3demux.dylib"
|
||||
<< "libgstlevel.dylib"
|
||||
<< "libgstid3tag.dylib"
|
||||
<< "libgstisomp4.dylib"
|
||||
<< "libgstlame.dylib"
|
||||
<< "libgstlibav.dylib"
|
||||
<< "libgstmpg123.dylib"
|
||||
<< "libgstmusepack.dylib"
|
||||
<< "libgstogg.dylib"
|
||||
<< "libgstopenmpt.dylib"
|
||||
<< "libgstopus.dylib"
|
||||
<< "libgstopusparse.dylib"
|
||||
<< "libgstosxaudio.dylib"
|
||||
<< "libgstplayback.dylib"
|
||||
<< "libgstrawparse.dylib"
|
||||
<< "libgstreplaygain.dylib"
|
||||
<< "libgstsoup.dylib"
|
||||
<< "libgstspectrum.dylib"
|
||||
<< "libgsttypefindfunctions.dylib"
|
||||
<< "libgstvolume.dylib"
|
||||
<< "libgstxingmux.dylib"
|
||||
<< "libgsttcp.dylib"
|
||||
<< "libgstudp.dylib"
|
||||
<< "libgstpbtypes.dylib"
|
||||
<< "libgstplayback.dylib"
|
||||
<< "libgstreplaygain.dylib"
|
||||
<< "libgstrtp.dylib"
|
||||
<< "libgstrtsp.dylib"
|
||||
<< "libgstflac.dylib"
|
||||
<< "libgstwavparse.dylib"
|
||||
<< "libgstfaad.dylib"
|
||||
<< "libgstogg.dylib"
|
||||
<< "libgstopus.dylib"
|
||||
<< "libgstasf.dylib"
|
||||
<< "libgstsoup.dylib"
|
||||
<< "libgstspectrum.dylib"
|
||||
<< "libgstspeex.dylib"
|
||||
<< "libgsttaglib.dylib"
|
||||
<< "libgsttcp.dylib"
|
||||
<< "libgsttwolame.dylib"
|
||||
<< "libgsttypefindfunctions.dylib"
|
||||
<< "libgstudp.dylib"
|
||||
<< "libgstvolume.dylib"
|
||||
<< "libgstvorbis.dylib"
|
||||
<< "libgstisomp4.dylib"
|
||||
<< "libgstlibav.dylib"
|
||||
<< "libgstaiff.dylib"
|
||||
<< "libgstlame.dylib";
|
||||
|
||||
// macports does not have these.
|
||||
QStringList gstreamer_plugins_optional = QStringList() << "libgstopusparse.dylib"
|
||||
<< "libgstfaac.dylib"
|
||||
<< "libgstmusepack.dylib";
|
||||
<< "libgstwavenc.dylib"
|
||||
<< "libgstwavpack.dylib"
|
||||
<< "libgstwavparse.dylib"
|
||||
<< "libgstxingmux.dylib";
|
||||
|
||||
QString gstreamer_plugins_dir = qgetenv("GST_PLUGIN_PATH");
|
||||
if (gstreamer_plugins_dir.isEmpty()) {
|
||||
@@ -1327,13 +1348,16 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
|
||||
}
|
||||
}
|
||||
|
||||
QStringList missing_gst_plugins;
|
||||
|
||||
for (const QString &plugin : gstreamer_plugins) {
|
||||
QFileInfo info(gstreamer_plugins_dir + "/" + plugin);
|
||||
if (!info.exists()) {
|
||||
info.setFile(gstreamer_plugins_dir + "/" + info.baseName() + QString(".so"));
|
||||
if (!info.exists()) {
|
||||
LogError() << "Missing gstreamer plugin" << info.baseName();
|
||||
qFatal("Missing %s", info.baseName().toUtf8().constData());
|
||||
missing_gst_plugins << info.baseName();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const QString &sourcePath = info.filePath();
|
||||
@@ -1345,22 +1369,8 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
|
||||
}
|
||||
}
|
||||
|
||||
for (const QString &plugin : gstreamer_plugins_optional) {
|
||||
QFileInfo info(gstreamer_plugins_dir + "/" + plugin);
|
||||
if (!info.exists()) {
|
||||
info.setFile(gstreamer_plugins_dir + "/" + info.baseName() + QString(".so"));
|
||||
if (!info.exists()) {
|
||||
LogWarning() << "Skip missing gstreamer plugin" << info.baseName();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const QString &sourcePath = info.filePath();
|
||||
const QString destinationPath = appBundleInfo.path + "/Contents/PlugIns/gstreamer/" + info.fileName();
|
||||
if (QDir().mkpath(QFileInfo(destinationPath).path()) && copyFilePrintStatus(sourcePath, destinationPath)) {
|
||||
runStrip(destinationPath);
|
||||
QList<FrameworkInfo> frameworks = getQtFrameworks(destinationPath, appBundleInfo.path, deploymentInfo.rpathsUsed, useDebugLibs);
|
||||
deployQtFrameworks(frameworks, appBundleInfo.path, QStringList() << destinationPath, useDebugLibs, deploymentInfo.useLoaderPath);
|
||||
}
|
||||
if (!missing_gst_plugins.isEmpty()) {
|
||||
LogError() << "Missing gstreamer plugins" << missing_gst_plugins;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,14 +32,22 @@ endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
else()
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if(MSVC)
|
||||
list(APPEND COMPILE_OPTIONS /std:c++17 /MP)
|
||||
list(APPEND COMPILE_OPTIONS /MP)
|
||||
else()
|
||||
list(APPEND COMPILE_OPTIONS
|
||||
$<$<COMPILE_LANGUAGE:C>:-std=c99>
|
||||
$<$<COMPILE_LANGUAGE:C>:-std=c11>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-std=c++17>
|
||||
-Wall
|
||||
-Wextra
|
||||
@@ -58,8 +66,7 @@ else()
|
||||
-Wformat=2
|
||||
-Wdisabled-optimization
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Woverloaded-virtual>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Wno-old-style-cast>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fpermissive>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Wold-style-cast>
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -427,9 +434,9 @@ endif()
|
||||
|
||||
option(INSTALL_TRANSLATIONS "Install translations" OFF)
|
||||
|
||||
optional_component(SUBSONIC ON "Subsonic support")
|
||||
optional_component(TIDAL ON "Tidal support")
|
||||
optional_component(QOBUZ ON "Qobuz support")
|
||||
optional_component(SUBSONIC ON "Streaming: Subsonic")
|
||||
optional_component(TIDAL ON "Streaming: Tidal")
|
||||
optional_component(QOBUZ ON "Streaming: Qobuz")
|
||||
|
||||
optional_component(MOODBAR ON "Moodbar"
|
||||
DEPENDS "fftw3" FFTW3_FOUND
|
||||
@@ -490,12 +497,13 @@ endif()
|
||||
|
||||
# Set up definitions
|
||||
|
||||
add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS)
|
||||
add_definitions(${QT_DEFINITIONS})
|
||||
add_definitions(-DQT_STRICT_ITERATORS)
|
||||
add_definitions(-DQT_USE_QSTRINGBUILDER)
|
||||
add_definitions(-DQT_NO_URL_CAST_FROM_STRING)
|
||||
add_definitions(-DQT_NO_CAST_TO_ASCII)
|
||||
add_definitions(
|
||||
-DBOOST_BIND_NO_PLACEHOLDERS
|
||||
-DQT_STRICT_ITERATORS
|
||||
-DQT_USE_QSTRINGBUILDER
|
||||
-DQT_NO_URL_CAST_FROM_STRING
|
||||
-DQT_NO_CAST_TO_ASCII
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DUNICODE)
|
||||
@@ -518,6 +526,10 @@ if(GTest_FOUND AND GMOCK_LIBRARY AND QtTest_LIBRARIES)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if(LINUX AND LSB_RELEASE_EXEC AND DPKG_BUILDPACKAGE)
|
||||
add_subdirectory(debian)
|
||||
endif()
|
||||
|
||||
# Uninstall support
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
||||
|
||||
@@ -526,7 +538,7 @@ add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/c
|
||||
# Show a summary of what we have enabled
|
||||
summary_show()
|
||||
if(NOT HAVE_GSTREAMER AND NOT HAVE_VLC)
|
||||
message(FATAL_ERROR "You need to have either GStreamer or VLC to compile!")
|
||||
message(FATAL_ERROR "You need to have either GStreamer or libvlc to compile!")
|
||||
elseif(NOT HAVE_GSTREAMER)
|
||||
message(WARNING "GStreamer is the only engine that is fully implemented. Using other engines is possible but not recommended.")
|
||||
endif()
|
||||
|
||||
78
Changelog
78
Changelog
@@ -2,6 +2,84 @@ Strawberry Music Player
|
||||
=======================
|
||||
ChangeLog
|
||||
|
||||
Version 1.0.7 (2022.07.25)
|
||||
|
||||
Bugfixes:
|
||||
* Fixed checking file extension case-insensitive when loading and saving playlists.
|
||||
* Fixed reading and saving rating with TagParser.
|
||||
* (macOS/Windows) Fixed playlist column alignment. Applied patch for Qt bug QTBUG-103576 (#999).
|
||||
* (Windows|MinGW) Fixed HLS streaming.
|
||||
* (Windows|MSVC) Fixed MP3 encoding.
|
||||
|
||||
Enhancements
|
||||
* Added option for selecting file extension when saving all playlists.
|
||||
|
||||
Version 1.0.6 (2022.07.17)
|
||||
|
||||
Bugfixes:
|
||||
* Fixed certain albums not added to playlist in correct track order from search for Tidal and QObuz.
|
||||
* Fixed songs not added to playlist in numeric order when added from file view with right click (#977).
|
||||
* Fixed "Stop after this track" graying out next track in dynamic mode (#912).
|
||||
* Fixed a gstreamer caps leak when transcoding songs.
|
||||
* Fixed errors in translation files (#994).
|
||||
|
||||
Enhancements
|
||||
* Add songs to the collection even when they have invalid ctime or mtime.
|
||||
* Made ListenBrainz scrobbler respect "Prefer album artist" option (#989).
|
||||
* Send track duration, number, player name and version when scrobbling to ListenBrainz (#995).
|
||||
* (macOS) Added missing HLS streaming plugin.
|
||||
|
||||
Version 1.0.5 (2022.06.10)
|
||||
|
||||
Bugfixes:
|
||||
* Fixed smart playlist filetype search.
|
||||
* Fixed Radio Paradise URLs to use HTTPS instead of HTTP.
|
||||
* Fixed horizontal scrolling not affecting currently playing track (#952).
|
||||
* Fixed keep running in the background when window is closed with Wayland (#964).
|
||||
* Fixed percent-encoding of URLs when loading and saving XSPF playlists (#821).
|
||||
* Fixed fancy tabbar context menu showing on right clicks outside of tabbar when a song is playing.
|
||||
* Fixed possible duplicating songs in the database when moving songs to the collection using the organize feature.
|
||||
* (Windows|MSVC) Fixed moodbar fftw3 crash with (older) CPU's that does not support AVX2 (#944).
|
||||
* (Windows|MSVC) Fixed using libiconv for converting characters when organizing files like with MinGW.
|
||||
|
||||
Enhancements
|
||||
* Show more details in error dialog on GStreamer errors (#958).
|
||||
* Allow setting blur amount of playlist background image up to 100px (#939).
|
||||
* Include 128x128 icon sizes (#954).
|
||||
* Show right click copy context menu in context view on top text and lyrics (#965).
|
||||
* Improve fading between album covers in context view.
|
||||
* Added option for overwriting database playcounts in collection settings (#962).
|
||||
* Added option for disabling bar on currently playing track (#972).
|
||||
* (Debian) Added Qt 6 support to debian files and build with Qt 6 for Debian Bookworm, Ubuntu Jammy and newer.
|
||||
* (Windows|MSVC) Added libav/ffmpeg plugin.
|
||||
|
||||
Version 1.0.4 (2022.04.10)
|
||||
|
||||
Bugfixes:
|
||||
* Fixed use-after-free memory in ALSA PCM device finder.
|
||||
* Translate global shortcuts.
|
||||
* (Windows) Fixed registering 0-9 numpad keys in global shortcuts.
|
||||
|
||||
Enhancements
|
||||
* Added save all playlists action.
|
||||
* (Windows) Made updater support both MSVC and MinGW.
|
||||
* (Windows) Added HLS support.
|
||||
|
||||
Other:
|
||||
* Removed use of custom font in context.
|
||||
|
||||
Version 1.0.3 (2022.03.24)
|
||||
|
||||
Bugfixes:
|
||||
* Remove slash and backslash from filenames when saving album covers using album directory cover filenames (#903).
|
||||
* Remove playlist file-extensions from accepted audio file extensions (#909).
|
||||
* Fixed Qobuz requests only receiving the first 50 albums (#922).
|
||||
* (Windows|MinGW) Fixed streaming stopping at the end of each track. libsoup downgraded from 3.0 to 2.74.
|
||||
* (Windows|MSVC) Fixed initial database schema failure caused by CRLF line-endings in schema files.
|
||||
|
||||
New features
|
||||
* Added support for bs2b (Improved headphone listening of stereo audio records using Bauer stereophonic-to-binaural DSP) (#249).
|
||||
|
||||
Version 1.0.2 (2022.02.20)
|
||||
|
||||
Bugfixes:
|
||||
|
||||
26
README.md
26
README.md
@@ -11,6 +11,7 @@ Strawberry is a music player and music collection organizer. It is a fork of Cle
|
||||
Resources:
|
||||
|
||||
* Website: https://www.strawberrymusicplayer.org/
|
||||
* Wiki: https://wiki.strawberrymusicplayer.org/
|
||||
* Forum: https://forum.strawberrymusicplayer.org/
|
||||
* Github: https://github.com/strawberrymusicplayer/strawberry
|
||||
* Buildbot: https://buildbot.strawberrymusicplayer.org/
|
||||
@@ -23,7 +24,8 @@ Resources:
|
||||
### :bangbang: Opening an issue:
|
||||
|
||||
* Search for the issue to see if it is already solved, or if there is an open issue for it already. If there is an open issue already, you can comment on it if you have additional information that could be useful to us.
|
||||
* For technical problems, questions and feature requests please use our forum on https://forum.strawberrymusicplayer.org/ that is better suited for discussion. It also better allows answers from the community instead of just the developers on GitHub.
|
||||
* For technical problems, discussion, questions and feature suggestions use the forum (https://forum.strawberrymusicplayer.org/) instead. The forum is better suited for discussion.
|
||||
* We do not take feature requests from users on GitHub. Any issues related to feature requests will be closed. This does not necessarily mean that we won't add new features, but we don't have time to take feature requests or answer questions about new features from users. It is still possible to suggest or discuss new features on the forum (https://forum.strawberrymusicplayer.org/).
|
||||
|
||||
### :moneybag: Sponsoring:
|
||||
|
||||
@@ -66,15 +68,14 @@ It has so far been tested to work on Linux, OpenBSD, FreeBSD, macOS and Windows.
|
||||
To build Strawberry from source you need the following installed on your system with the additional development packages/headers:
|
||||
|
||||
* [CMake](https://cmake.org/)
|
||||
* [GNU Make](https://www.gnu.org/software/make/)
|
||||
* [GCC](https://gcc.gnu.org/) or [clang](https://clang.llvm.org/) compiler
|
||||
* [GCC](https://gcc.gnu.org/), [Clang](https://clang.llvm.org/) or [MSVC](https://visualstudio.microsoft.com/vs/features/cplusplus/) compiler
|
||||
* [Boost](https://www.boost.org/)
|
||||
* [GLib](https://developer.gnome.org/glib/)
|
||||
* [Protobuf](https://developers.google.com/protocol-buffers/)
|
||||
* [Qt 5.9 or higher (or Qt 6) with components Core, Gui, Widgets, Concurrent, Network and Sql](https://www.qt.io/)
|
||||
* [SQLite 3.9 or newer with FTS5](https://www.sqlite.org)
|
||||
* [ALSA (Linux required)](https://www.alsa-project.org/)
|
||||
* [D-Bus (Linux required)](https://www.freedesktop.org/wiki/Software/dbus/)
|
||||
* [Protobuf](https://developers.google.com/protocol-buffers/)
|
||||
* [ALSA (Required on Linux)](https://www.alsa-project.org/)
|
||||
* [D-Bus (Required on Linux)](https://www.freedesktop.org/wiki/Software/dbus/)
|
||||
* [GStreamer](https://gstreamer.freedesktop.org/) or [VLC](https://www.videolan.org)
|
||||
* [GnuTLS](https://www.gnutls.org/)
|
||||
* [TagLib 1.11.1 or higher](https://www.taglib.org/) or [TagParser](https://github.com/Martchus/tagparser)
|
||||
@@ -88,8 +89,7 @@ Optional dependencies:
|
||||
* MTP devices: [libmtp](http://libmtp.sourceforge.net/)
|
||||
* iPod Classic devices: [libgpod](http://www.gtkpod.org/libgpod/)
|
||||
|
||||
Either GStreamer or VLC engine is required, but only GStreamer is fully implemented, and works best, it is therefore recommended to use GStreamer.
|
||||
You should also install the gstreamer plugins base and good, and optionally bad, ugly and libav.
|
||||
You should also install the gstreamer plugins base and good, and optionally bad, ugly and libav to support all audio formats.
|
||||
|
||||
### :wrench: Compiling from source
|
||||
|
||||
@@ -101,15 +101,15 @@ You should also install the gstreamer plugins base and good, and optionally bad,
|
||||
|
||||
cd strawberry
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
cmake .. -DBUILD_WITH_QT6=ON
|
||||
make -j$(nproc)
|
||||
sudo make install
|
||||
|
||||
To compile with Qt 6 use:
|
||||
|
||||
cmake .. -DBUILD_WITH_QT6=ON
|
||||
Strawberry is backwards compatible with Qt 5, to compile with Qt 5 use:
|
||||
|
||||
cmake .. -DBUILD_WITH_QT5=ON
|
||||
|
||||
### :penguin: Packaging status
|
||||
|
||||
[](https://repology.org/metapackage/strawberry/versions)
|
||||
[](https://repology.org/metapackage/strawberry/versions)
|
||||
|
||||
|
||||
@@ -2,18 +2,5 @@ find_program(LSB_RELEASE_EXEC lsb_release)
|
||||
find_program(DPKG_BUILDPACKAGE dpkg-buildpackage)
|
||||
|
||||
if (LSB_RELEASE_EXEC AND DPKG_BUILDPACKAGE)
|
||||
execute_process(COMMAND env LC_ALL=C date "+%a, %-d %b %Y %H:%M:%S %z" OUTPUT_VARIABLE DEB_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(COMMAND /bin/sh "-c" "${LSB_RELEASE_EXEC} -cs"
|
||||
OUTPUT_VARIABLE DEB_CODENAME
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
if (DEB_CODENAME AND DEB_DATE)
|
||||
add_custom_target(deb
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMAND ${DPKG_BUILDPACKAGE} -b -d -uc -us
|
||||
)
|
||||
endif()
|
||||
|
||||
add_custom_target(deb WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${DPKG_BUILDPACKAGE} -b -d -uc -us)
|
||||
endif()
|
||||
|
||||
@@ -21,10 +21,7 @@ if(MACDEPLOYQT_EXECUTABLE)
|
||||
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/strawberry.app/Contents/{Frameworks,Resources}
|
||||
COMMAND cp -v ${CMAKE_SOURCE_DIR}/dist/macos/Info.plist ${CMAKE_BINARY_DIR}/strawberry.app/Contents/
|
||||
COMMAND cp -v ${CMAKE_SOURCE_DIR}/dist/macos/strawberry.icns ${CMAKE_BINARY_DIR}/strawberry.app/Contents/Resources/
|
||||
COMMAND ${MACDEPLOYQT_EXECUTABLE} strawberry.app -verbose=3
|
||||
-executable=${CMAKE_BINARY_DIR}/strawberry.app/Contents/PlugIns/strawberry-tagreader
|
||||
-executable=${CMAKE_BINARY_DIR}/strawberry.app/Contents/PlugIns/gio-modules/libgiognutls.so
|
||||
#-executable=${CMAKE_BINARY_DIR}/strawberry.app/Contents/PlugIns/gst-plugin-scanner
|
||||
COMMAND ${MACDEPLOYQT_EXECUTABLE} strawberry.app -verbose=3 -executable=${CMAKE_BINARY_DIR}/strawberry.app/Contents/PlugIns/strawberry-tagreader
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
DEPENDS strawberry strawberry-tagreader copy_gstreamer_plugins macdeployqt
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
set(STRAWBERRY_VERSION_MAJOR 1)
|
||||
set(STRAWBERRY_VERSION_MINOR 0)
|
||||
set(STRAWBERRY_VERSION_PATCH 2)
|
||||
set(STRAWBERRY_VERSION_PATCH 7)
|
||||
#set(STRAWBERRY_VERSION_PRERELEASE rc1)
|
||||
|
||||
set(INCLUDE_GIT_REVISION OFF)
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>schema/schema.sql</file>
|
||||
<file>schema/schema-1.sql</file>
|
||||
<file>schema/schema-2.sql</file>
|
||||
<file>schema/schema-3.sql</file>
|
||||
<file>schema/schema-4.sql</file>
|
||||
<file>schema/schema-5.sql</file>
|
||||
<file>schema/schema-6.sql</file>
|
||||
<file>schema/schema-7.sql</file>
|
||||
<file>schema/schema-8.sql</file>
|
||||
<file>schema/schema-9.sql</file>
|
||||
<file>schema/schema-10.sql</file>
|
||||
<file>schema/schema-11.sql</file>
|
||||
<file>schema/schema-12.sql</file>
|
||||
@@ -46,7 +37,6 @@
|
||||
<file>pictures/rainbowdash.png</file>
|
||||
<file>pictures/star-on.png</file>
|
||||
<file>pictures/star-off.png</file>
|
||||
<file>fonts/HumongousofEternitySt.ttf</file>
|
||||
<file>mood/sample.mood</file>
|
||||
<file>text/ghosts.txt</file>
|
||||
</qresource>
|
||||
|
||||
Binary file not shown.
@@ -24,6 +24,7 @@
|
||||
<file>icons/128x128/document-open-folder.png</file>
|
||||
<file>icons/128x128/document-open.png</file>
|
||||
<file>icons/128x128/document-save.png</file>
|
||||
<file>icons/128x128/document-save-all.png</file>
|
||||
<file>icons/128x128/document-search.png</file>
|
||||
<file>icons/128x128/download.png</file>
|
||||
<file>icons/128x128/edit-clear-list.png</file>
|
||||
@@ -120,6 +121,7 @@
|
||||
<file>icons/64x64/document-open-folder.png</file>
|
||||
<file>icons/64x64/document-open.png</file>
|
||||
<file>icons/64x64/document-save.png</file>
|
||||
<file>icons/64x64/document-save-all.png</file>
|
||||
<file>icons/64x64/document-search.png</file>
|
||||
<file>icons/64x64/download.png</file>
|
||||
<file>icons/64x64/edit-clear-list.png</file>
|
||||
@@ -218,6 +220,7 @@
|
||||
<file>icons/48x48/document-open-remote.png</file>
|
||||
<file>icons/48x48/document-open.png</file>
|
||||
<file>icons/48x48/document-save.png</file>
|
||||
<file>icons/48x48/document-save-all.png</file>
|
||||
<file>icons/48x48/document-search.png</file>
|
||||
<file>icons/48x48/download.png</file>
|
||||
<file>icons/48x48/edit-clear-list.png</file>
|
||||
@@ -319,6 +322,7 @@
|
||||
<file>icons/32x32/document-open-remote.png</file>
|
||||
<file>icons/32x32/document-open.png</file>
|
||||
<file>icons/32x32/document-save.png</file>
|
||||
<file>icons/32x32/document-save-all.png</file>
|
||||
<file>icons/32x32/document-search.png</file>
|
||||
<file>icons/32x32/download.png</file>
|
||||
<file>icons/32x32/edit-clear-list.png</file>
|
||||
@@ -420,6 +424,7 @@
|
||||
<file>icons/22x22/document-open-remote.png</file>
|
||||
<file>icons/22x22/document-open.png</file>
|
||||
<file>icons/22x22/document-save.png</file>
|
||||
<file>icons/22x22/document-save-all.png</file>
|
||||
<file>icons/22x22/document-search.png</file>
|
||||
<file>icons/22x22/download.png</file>
|
||||
<file>icons/22x22/edit-clear-list.png</file>
|
||||
|
||||
BIN
data/icons/128x128/document-save-all.png
Normal file
BIN
data/icons/128x128/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
BIN
data/icons/22x22/document-save-all.png
Normal file
BIN
data/icons/22x22/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 921 B |
BIN
data/icons/32x32/document-save-all.png
Normal file
BIN
data/icons/32x32/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
data/icons/48x48/document-save-all.png
Normal file
BIN
data/icons/48x48/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
BIN
data/icons/64x64/document-save-all.png
Normal file
BIN
data/icons/64x64/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
BIN
data/icons/full/document-save-all.png
Normal file
BIN
data/icons/full/document-save-all.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
@@ -1,35 +1,35 @@
|
||||
CREATE TABLE device_%deviceid_directories (
|
||||
path TEXT NOT NULL DEFAULT '',
|
||||
path TEXT NOT NULL,
|
||||
subdirs INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE device_%deviceid_subdirectories (
|
||||
directory_id INTEGER NOT NULL,
|
||||
path TEXT NOT NULL DEFAULT '',
|
||||
path TEXT NOT NULL,
|
||||
mtime INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE device_%deviceid_songs (
|
||||
|
||||
title TEXT DEFAULT '',
|
||||
album TEXT DEFAULT '',
|
||||
artist TEXT DEFAULT '',
|
||||
albumartist TEXT DEFAULT '',
|
||||
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 DEFAULT '',
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT DEFAULT '',
|
||||
performer TEXT DEFAULT '',
|
||||
grouping TEXT DEFAULT '',
|
||||
comment TEXT DEFAULT '',
|
||||
lyrics TEXT DEFAULT '',
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT DEFAULT '',
|
||||
album_id TEXT DEFAULT '',
|
||||
song_id TEXT DEFAULT '',
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -40,14 +40,14 @@ CREATE TABLE device_%deviceid_songs (
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL DEFAULT '',
|
||||
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,
|
||||
|
||||
fingerprint TEXT DEFAULT '',
|
||||
fingerprint TEXT,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -59,13 +59,13 @@ CREATE TABLE device_%deviceid_songs (
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT DEFAULT '',
|
||||
art_manual TEXT DEFAULT '',
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT DEFAULT '',
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT DEFAULT '',
|
||||
cue_path TEXT,
|
||||
|
||||
rating INTEGER DEFAULT -1
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
ALTER TABLE playlist_items ADD COLUMN internet_service TEXT;
|
||||
|
||||
UPDATE schema_version SET version=1;
|
||||
@@ -1,4 +1,4 @@
|
||||
ALTER TABLE %allsongstables ADD COLUMN fingerprint TEXT DEFAULT '';
|
||||
ALTER TABLE %allsongstables ADD COLUMN fingerprint TEXT;
|
||||
|
||||
ALTER TABLE %allsongstables ADD COLUMN lastseen INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS radio_channels (
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
name TEXT DEFAULT '',
|
||||
url TEXT DEFAULT '',
|
||||
thumbnail_url TEXT DEFAULT ''
|
||||
name TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
thumbnail_url TEXT
|
||||
);
|
||||
|
||||
UPDATE schema_version SET version=15;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
ALTER TABLE songs ADD COLUMN lyrics TEXT;
|
||||
|
||||
ALTER TABLE playlist_items ADD COLUMN lyrics TEXT;
|
||||
|
||||
UPDATE schema_version SET version=2;
|
||||
@@ -1,65 +0,0 @@
|
||||
ALTER TABLE songs ADD COLUMN source INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
UPDATE songs SET source = 2 WHERE source = 0;
|
||||
|
||||
DROP TABLE playlist_items;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS playlist_items (
|
||||
|
||||
playlist INTEGER NOT NULL,
|
||||
type INTEGER NOT NULL DEFAULT 0,
|
||||
collection_id INTEGER,
|
||||
url TEXT,
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT 0,
|
||||
samplerate INTEGER NOT NULL DEFAULT 0,
|
||||
bitdepth INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER,
|
||||
filename TEXT,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER,
|
||||
mtime INTEGER,
|
||||
ctime INTEGER,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
UPDATE schema_version SET version=3;
|
||||
@@ -1,205 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS tidal_artists_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT 0,
|
||||
samplerate INTEGER NOT NULL DEFAULT 0,
|
||||
bitdepth INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL,
|
||||
filename TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT 0,
|
||||
mtime INTEGER NOT NULL DEFAULT 0,
|
||||
ctime INTEGER NOT NULL DEFAULT 0,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
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 NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT 0,
|
||||
samplerate INTEGER NOT NULL DEFAULT 0,
|
||||
bitdepth INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL,
|
||||
filename TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT 0,
|
||||
mtime INTEGER NOT NULL DEFAULT 0,
|
||||
ctime INTEGER NOT NULL DEFAULT 0,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
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 NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT 0,
|
||||
samplerate INTEGER NOT NULL DEFAULT 0,
|
||||
bitdepth INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL,
|
||||
filename TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT 0,
|
||||
mtime INTEGER NOT NULL DEFAULT 0,
|
||||
ctime INTEGER NOT NULL DEFAULT 0,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
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 fts3(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize=unicode
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS tidal_albums_songs_fts USING fts3(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize=unicode
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS tidal_songs_fts USING fts3(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize=unicode
|
||||
|
||||
);
|
||||
|
||||
UPDATE schema_version SET version=4;
|
||||
@@ -1,31 +0,0 @@
|
||||
ALTER TABLE songs ADD COLUMN artist_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE songs ADD COLUMN album_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE songs ADD COLUMN song_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE tidal_artists_songs ADD COLUMN artist_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE tidal_artists_songs ADD COLUMN album_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE tidal_artists_songs ADD COLUMN song_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE tidal_albums_songs ADD COLUMN artist_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE tidal_albums_songs ADD COLUMN album_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE tidal_albums_songs ADD COLUMN song_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE tidal_songs ADD COLUMN artist_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE tidal_songs ADD COLUMN album_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE tidal_songs ADD COLUMN song_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE playlist_items ADD COLUMN artist_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE playlist_items ADD COLUMN album_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
ALTER TABLE playlist_items ADD COLUMN song_id INTEGER NOT NULL DEFAULT -1;
|
||||
|
||||
UPDATE schema_version SET version=5;
|
||||
@@ -1,73 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS subsonic_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id INTEGER NOT NULL DEFAULT -1,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT 0,
|
||||
samplerate INTEGER NOT NULL DEFAULT 0,
|
||||
bitdepth INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL,
|
||||
filename TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT 0,
|
||||
mtime INTEGER NOT NULL DEFAULT 0,
|
||||
ctime INTEGER NOT NULL DEFAULT 0,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
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 subsonic_songs_fts USING fts3(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize=unicode
|
||||
|
||||
);
|
||||
|
||||
UPDATE schema_version SET version=6;
|
||||
@@ -1,217 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS qobuz_artists_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id INTEGER NOT NULL DEFAULT -1,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT 0,
|
||||
samplerate INTEGER NOT NULL DEFAULT 0,
|
||||
bitdepth INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL,
|
||||
filename TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT 0,
|
||||
mtime INTEGER NOT NULL DEFAULT 0,
|
||||
ctime INTEGER NOT NULL DEFAULT 0,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS qobuz_albums_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id INTEGER NOT NULL DEFAULT -1,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT 0,
|
||||
samplerate INTEGER NOT NULL DEFAULT 0,
|
||||
bitdepth INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL,
|
||||
filename TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT 0,
|
||||
mtime INTEGER NOT NULL DEFAULT 0,
|
||||
ctime INTEGER NOT NULL DEFAULT 0,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS qobuz_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id INTEGER NOT NULL DEFAULT -1,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
bitrate INTEGER NOT NULL DEFAULT 0,
|
||||
samplerate INTEGER NOT NULL DEFAULT 0,
|
||||
bitdepth INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL,
|
||||
filename TEXT NOT NULL,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER NOT NULL DEFAULT 0,
|
||||
mtime INTEGER NOT NULL DEFAULT 0,
|
||||
ctime INTEGER NOT NULL DEFAULT 0,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
compilation_detected INTEGER DEFAULT 0,
|
||||
compilation_on INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
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 qobuz_artists_songs_fts USING fts3(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize=unicode
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS qobuz_albums_songs_fts USING fts3(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize=unicode
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS qobuz_songs_fts USING fts3(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize=unicode
|
||||
|
||||
);
|
||||
|
||||
UPDATE schema_version SET version=7;
|
||||
@@ -1,595 +0,0 @@
|
||||
ALTER TABLE songs RENAME TO songs_old;
|
||||
|
||||
ALTER TABLE playlist_items RENAME TO playlist_items_old;
|
||||
|
||||
ALTER TABLE tidal_artists_songs RENAME TO tidal_artists_songs_old;
|
||||
|
||||
ALTER TABLE tidal_albums_songs RENAME TO tidal_albums_songs_old;
|
||||
|
||||
ALTER TABLE tidal_songs RENAME TO tidal_songs_old;
|
||||
|
||||
ALTER TABLE qobuz_artists_songs RENAME TO qobuz_artists_songs_old;
|
||||
|
||||
ALTER TABLE qobuz_albums_songs RENAME TO qobuz_albums_songs_old;
|
||||
|
||||
ALTER TABLE qobuz_songs RENAME TO qobuz_songs_old;
|
||||
|
||||
ALTER TABLE subsonic_songs RENAME TO subsonic_songs_old;
|
||||
|
||||
DROP INDEX idx_filename;
|
||||
|
||||
CREATE TABLE songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
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 tidal_artists_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
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 tidal_albums_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
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 tidal_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
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 subsonic_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
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 qobuz_artists_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
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 qobuz_albums_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
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 qobuz_songs (
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
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 playlist_items (
|
||||
|
||||
playlist INTEGER NOT NULL,
|
||||
type INTEGER NOT NULL DEFAULT 0,
|
||||
collection_id INTEGER,
|
||||
playlist_url TEXT,
|
||||
|
||||
title TEXT NOT NULL,
|
||||
album TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
albumartist TEXT NOT NULL,
|
||||
track INTEGER NOT NULL DEFAULT -1,
|
||||
disc INTEGER NOT NULL DEFAULT -1,
|
||||
year INTEGER NOT NULL DEFAULT -1,
|
||||
originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
genre TEXT NOT NULL,
|
||||
compilation INTEGER NOT NULL DEFAULT -1,
|
||||
composer TEXT NOT NULL,
|
||||
performer TEXT NOT NULL,
|
||||
grouping TEXT NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
lyrics TEXT NOT NULL,
|
||||
|
||||
artist_id INTEGER NOT NULL DEFAULT -1,
|
||||
album_id TEXT NOT NULL,
|
||||
song_id INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
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,
|
||||
url TEXT,
|
||||
filetype INTEGER NOT NULL DEFAULT 0,
|
||||
filesize INTEGER,
|
||||
mtime INTEGER,
|
||||
ctime INTEGER,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
lastplayed INTEGER NOT NULL DEFAULT -1,
|
||||
|
||||
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 (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 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, filename, 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;
|
||||
|
||||
INSERT INTO tidal_artists_songs (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 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, filename, 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 tidal_artists_songs_old;
|
||||
|
||||
DROP TABLE tidal_artists_songs_old;
|
||||
|
||||
INSERT INTO tidal_albums_songs (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 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, filename, 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 tidal_albums_songs_old;
|
||||
|
||||
DROP TABLE tidal_albums_songs_old;
|
||||
|
||||
INSERT INTO tidal_songs (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 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, filename, 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 tidal_songs_old;
|
||||
|
||||
DROP TABLE tidal_songs_old;
|
||||
|
||||
INSERT INTO qobuz_artists_songs (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 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, filename, 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 qobuz_artists_songs_old;
|
||||
|
||||
DROP TABLE qobuz_artists_songs_old;
|
||||
|
||||
INSERT INTO qobuz_albums_songs (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 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, filename, 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 qobuz_albums_songs_old;
|
||||
|
||||
DROP TABLE qobuz_albums_songs_old;
|
||||
|
||||
INSERT INTO qobuz_songs (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 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, filename, 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 qobuz_songs_old;
|
||||
|
||||
DROP TABLE qobuz_songs_old;
|
||||
|
||||
INSERT INTO subsonic_songs (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 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, filename, 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;
|
||||
|
||||
INSERT INTO playlist_items (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 playlist, type, collection_id, 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, filename, 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;
|
||||
|
||||
CREATE INDEX idx_url ON songs (url);
|
||||
|
||||
UPDATE schema_version SET version=8;
|
||||
@@ -1,41 +0,0 @@
|
||||
DROP TABLE %allsongstables_fts;
|
||||
|
||||
DROP TABLE playlist_items_fts_;
|
||||
|
||||
CREATE VIRTUAL TABLE %allsongstables_fts USING fts5(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize = "unicode61 remove_diacritics 1"
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE playlist_items_fts_ USING fts5(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
ftsartist,
|
||||
ftsalbumartist,
|
||||
ftscomposer,
|
||||
ftsperformer,
|
||||
ftsgrouping,
|
||||
ftsgenre,
|
||||
ftscomment,
|
||||
tokenize = "unicode61 remove_diacritics 1"
|
||||
|
||||
);
|
||||
|
||||
INSERT INTO %allsongstables_fts (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment)
|
||||
SELECT ROWID, title, album, artist, albumartist, composer, performer, grouping, genre, comment FROM %allsongstables;
|
||||
|
||||
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=9;
|
||||
@@ -7,37 +7,37 @@ DELETE FROM schema_version;
|
||||
INSERT INTO schema_version (version) VALUES (15);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS directories (
|
||||
path TEXT NOT NULL DEFAULT '',
|
||||
path TEXT NOT NULL,
|
||||
subdirs INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS subdirectories (
|
||||
directory_id INTEGER NOT NULL,
|
||||
path TEXT NOT NULL DEFAULT '',
|
||||
path TEXT NOT NULL,
|
||||
mtime INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS songs (
|
||||
|
||||
title TEXT DEFAULT '',
|
||||
album TEXT DEFAULT '',
|
||||
artist TEXT DEFAULT '',
|
||||
albumartist TEXT DEFAULT '',
|
||||
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 -1,
|
||||
genre TEXT DEFAULT '',
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT DEFAULT '',
|
||||
performer TEXT DEFAULT '',
|
||||
grouping TEXT DEFAULT '',
|
||||
comment TEXT DEFAULT '',
|
||||
lyrics TEXT DEFAULT '',
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT DEFAULT '',
|
||||
album_id TEXT DEFAULT '',
|
||||
song_id TEXT DEFAULT '',
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -48,14 +48,14 @@ CREATE TABLE IF NOT EXISTS songs (
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL DEFAULT '',
|
||||
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,
|
||||
|
||||
fingerprint TEXT DEFAULT '',
|
||||
fingerprint TEXT,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -67,13 +67,13 @@ CREATE TABLE IF NOT EXISTS songs (
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT DEFAULT '',
|
||||
art_manual TEXT DEFAULT '',
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT DEFAULT '',
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT DEFAULT '',
|
||||
cue_path TEXT,
|
||||
|
||||
rating INTEGER DEFAULT -1
|
||||
|
||||
@@ -81,25 +81,25 @@ CREATE TABLE IF NOT EXISTS songs (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS subsonic_songs (
|
||||
|
||||
title TEXT DEFAULT '',
|
||||
album TEXT DEFAULT '',
|
||||
artist TEXT DEFAULT '',
|
||||
albumartist TEXT DEFAULT '',
|
||||
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 -1,
|
||||
genre TEXT DEFAULT '',
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT DEFAULT '',
|
||||
performer TEXT DEFAULT '',
|
||||
grouping TEXT DEFAULT '',
|
||||
comment TEXT DEFAULT '',
|
||||
lyrics TEXT DEFAULT '',
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT DEFAULT '',
|
||||
album_id TEXT DEFAULT '',
|
||||
song_id TEXT DEFAULT '',
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -110,14 +110,14 @@ CREATE TABLE IF NOT EXISTS subsonic_songs (
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL DEFAULT '',
|
||||
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,
|
||||
|
||||
fingerprint TEXT DEFAULT '',
|
||||
fingerprint TEXT,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -129,13 +129,13 @@ CREATE TABLE IF NOT EXISTS subsonic_songs (
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT DEFAULT '',
|
||||
art_manual TEXT DEFAULT '',
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT DEFAULT '',
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT DEFAULT '',
|
||||
cue_path TEXT,
|
||||
|
||||
rating INTEGER DEFAULT -1
|
||||
|
||||
@@ -143,25 +143,25 @@ CREATE TABLE IF NOT EXISTS subsonic_songs (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tidal_artists_songs (
|
||||
|
||||
title TEXT DEFAULT '',
|
||||
album TEXT DEFAULT '',
|
||||
artist TEXT DEFAULT '',
|
||||
albumartist TEXT DEFAULT '',
|
||||
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 -1,
|
||||
genre TEXT DEFAULT '',
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT DEFAULT '',
|
||||
performer TEXT DEFAULT '',
|
||||
grouping TEXT DEFAULT '',
|
||||
comment TEXT DEFAULT '',
|
||||
lyrics TEXT DEFAULT '',
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT DEFAULT '',
|
||||
album_id TEXT DEFAULT '',
|
||||
song_id TEXT DEFAULT '',
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -172,14 +172,14 @@ CREATE TABLE IF NOT EXISTS tidal_artists_songs (
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL DEFAULT '',
|
||||
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,
|
||||
|
||||
fingerprint TEXT DEFAULT '',
|
||||
fingerprint TEXT,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -191,13 +191,13 @@ CREATE TABLE IF NOT EXISTS tidal_artists_songs (
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT DEFAULT '',
|
||||
art_manual TEXT DEFAULT '',
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT DEFAULT '',
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT DEFAULT '',
|
||||
cue_path TEXT,
|
||||
|
||||
rating INTEGER DEFAULT -1
|
||||
|
||||
@@ -205,25 +205,25 @@ CREATE TABLE IF NOT EXISTS tidal_artists_songs (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tidal_albums_songs (
|
||||
|
||||
title TEXT DEFAULT '',
|
||||
album TEXT DEFAULT '',
|
||||
artist TEXT DEFAULT '',
|
||||
albumartist TEXT DEFAULT '',
|
||||
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 -1,
|
||||
genre TEXT DEFAULT '',
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT DEFAULT '',
|
||||
performer TEXT DEFAULT '',
|
||||
grouping TEXT DEFAULT '',
|
||||
comment TEXT DEFAULT '',
|
||||
lyrics TEXT DEFAULT '',
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT DEFAULT '',
|
||||
album_id TEXT DEFAULT '',
|
||||
song_id TEXT DEFAULT '',
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -234,14 +234,14 @@ CREATE TABLE IF NOT EXISTS tidal_albums_songs (
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL DEFAULT '',
|
||||
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,
|
||||
|
||||
fingerprint TEXT DEFAULT '',
|
||||
fingerprint TEXT,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -253,13 +253,13 @@ CREATE TABLE IF NOT EXISTS tidal_albums_songs (
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT DEFAULT '',
|
||||
art_manual TEXT DEFAULT '',
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT DEFAULT '',
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT DEFAULT '',
|
||||
cue_path TEXT,
|
||||
|
||||
rating INTEGER DEFAULT -1
|
||||
|
||||
@@ -267,25 +267,25 @@ CREATE TABLE IF NOT EXISTS tidal_albums_songs (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tidal_songs (
|
||||
|
||||
title TEXT DEFAULT '',
|
||||
album TEXT DEFAULT '',
|
||||
artist TEXT DEFAULT '',
|
||||
albumartist TEXT DEFAULT '',
|
||||
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 -1,
|
||||
genre TEXT DEFAULT '',
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT DEFAULT '',
|
||||
performer TEXT DEFAULT '',
|
||||
grouping TEXT DEFAULT '',
|
||||
comment TEXT DEFAULT '',
|
||||
lyrics TEXT DEFAULT '',
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT DEFAULT '',
|
||||
album_id TEXT DEFAULT '',
|
||||
song_id TEXT DEFAULT '',
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -296,14 +296,14 @@ CREATE TABLE IF NOT EXISTS tidal_songs (
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL DEFAULT '',
|
||||
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,
|
||||
|
||||
fingerprint TEXT DEFAULT '',
|
||||
fingerprint TEXT,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -315,13 +315,13 @@ CREATE TABLE IF NOT EXISTS tidal_songs (
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT DEFAULT '',
|
||||
art_manual TEXT DEFAULT '',
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT DEFAULT '',
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT DEFAULT '',
|
||||
cue_path TEXT,
|
||||
|
||||
rating INTEGER DEFAULT -1
|
||||
|
||||
@@ -329,25 +329,25 @@ CREATE TABLE IF NOT EXISTS tidal_songs (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS qobuz_artists_songs (
|
||||
|
||||
title TEXT DEFAULT '',
|
||||
album TEXT DEFAULT '',
|
||||
artist TEXT DEFAULT '',
|
||||
albumartist TEXT DEFAULT '',
|
||||
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 -1,
|
||||
genre TEXT DEFAULT '',
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT DEFAULT '',
|
||||
performer TEXT DEFAULT '',
|
||||
grouping TEXT DEFAULT '',
|
||||
comment TEXT DEFAULT '',
|
||||
lyrics TEXT DEFAULT '',
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT DEFAULT '',
|
||||
album_id TEXT DEFAULT '',
|
||||
song_id TEXT DEFAULT '',
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -358,14 +358,14 @@ CREATE TABLE IF NOT EXISTS qobuz_artists_songs (
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL DEFAULT '',
|
||||
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,
|
||||
|
||||
fingerprint TEXT DEFAULT '',
|
||||
fingerprint TEXT,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -377,13 +377,13 @@ CREATE TABLE IF NOT EXISTS qobuz_artists_songs (
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT DEFAULT '',
|
||||
art_manual TEXT DEFAULT '',
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT DEFAULT '',
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT DEFAULT '',
|
||||
cue_path TEXT,
|
||||
|
||||
rating INTEGER DEFAULT -1
|
||||
|
||||
@@ -391,25 +391,25 @@ CREATE TABLE IF NOT EXISTS qobuz_artists_songs (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS qobuz_albums_songs (
|
||||
|
||||
title TEXT DEFAULT '',
|
||||
album TEXT DEFAULT '',
|
||||
artist TEXT DEFAULT '',
|
||||
albumartist TEXT DEFAULT '',
|
||||
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 -1,
|
||||
genre TEXT DEFAULT '',
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT DEFAULT '',
|
||||
performer TEXT DEFAULT '',
|
||||
grouping TEXT DEFAULT '',
|
||||
comment TEXT DEFAULT '',
|
||||
lyrics TEXT DEFAULT '',
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT DEFAULT '',
|
||||
album_id TEXT DEFAULT '',
|
||||
song_id TEXT DEFAULT '',
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -420,14 +420,14 @@ CREATE TABLE IF NOT EXISTS qobuz_albums_songs (
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL DEFAULT '',
|
||||
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,
|
||||
|
||||
fingerprint TEXT DEFAULT '',
|
||||
fingerprint TEXT,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -439,13 +439,13 @@ CREATE TABLE IF NOT EXISTS qobuz_albums_songs (
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT DEFAULT '',
|
||||
art_manual TEXT DEFAULT '',
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT DEFAULT '',
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT DEFAULT '',
|
||||
cue_path TEXT,
|
||||
|
||||
rating INTEGER DEFAULT -1
|
||||
|
||||
@@ -453,25 +453,25 @@ CREATE TABLE IF NOT EXISTS qobuz_albums_songs (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS qobuz_songs (
|
||||
|
||||
title TEXT DEFAULT '',
|
||||
album TEXT DEFAULT '',
|
||||
artist TEXT DEFAULT '',
|
||||
albumartist TEXT DEFAULT '',
|
||||
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 -1,
|
||||
genre TEXT DEFAULT '',
|
||||
genre TEXT,
|
||||
compilation INTEGER NOT NULL DEFAULT 0,
|
||||
composer TEXT DEFAULT '',
|
||||
performer TEXT DEFAULT '',
|
||||
grouping TEXT DEFAULT '',
|
||||
comment TEXT DEFAULT '',
|
||||
lyrics TEXT DEFAULT '',
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT DEFAULT '',
|
||||
album_id TEXT DEFAULT '',
|
||||
song_id TEXT DEFAULT '',
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER NOT NULL DEFAULT 0,
|
||||
length INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -482,14 +482,14 @@ CREATE TABLE IF NOT EXISTS qobuz_songs (
|
||||
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
directory_id INTEGER NOT NULL DEFAULT -1,
|
||||
url TEXT NOT NULL DEFAULT '',
|
||||
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,
|
||||
|
||||
fingerprint TEXT DEFAULT '',
|
||||
fingerprint TEXT,
|
||||
|
||||
playcount INTEGER NOT NULL DEFAULT 0,
|
||||
skipcount INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -501,13 +501,13 @@ CREATE TABLE IF NOT EXISTS qobuz_songs (
|
||||
compilation_off INTEGER NOT NULL DEFAULT 0,
|
||||
compilation_effective INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
art_automatic TEXT DEFAULT '',
|
||||
art_manual TEXT DEFAULT '',
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT DEFAULT '',
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
cue_path TEXT DEFAULT '',
|
||||
cue_path TEXT,
|
||||
|
||||
rating INTEGER DEFAULT -1
|
||||
|
||||
@@ -515,15 +515,15 @@ CREATE TABLE IF NOT EXISTS qobuz_songs (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS playlists (
|
||||
|
||||
name TEXT NOT NULL DEFAULT '',
|
||||
name TEXT NOT NULL,
|
||||
last_played INTEGER NOT NULL DEFAULT -1,
|
||||
ui_order INTEGER NOT NULL DEFAULT 0,
|
||||
special_type TEXT DEFAULT '',
|
||||
ui_path TEXT DEFAULT '',
|
||||
special_type TEXT,
|
||||
ui_path TEXT,
|
||||
is_favorite INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
dynamic_playlist_type INTEGER,
|
||||
dynamic_playlist_backend TEXT DEFAULT '',
|
||||
dynamic_playlist_backend TEXT,
|
||||
dynamic_playlist_data BLOB
|
||||
|
||||
);
|
||||
@@ -533,27 +533,27 @@ CREATE TABLE IF NOT EXISTS playlist_items (
|
||||
playlist INTEGER NOT NULL,
|
||||
type INTEGER NOT NULL DEFAULT 0,
|
||||
collection_id INTEGER,
|
||||
playlist_url TEXT DEFAULT '',
|
||||
playlist_url TEXT,
|
||||
|
||||
title TEXT DEFAULT '',
|
||||
album TEXT DEFAULT '',
|
||||
artist TEXT DEFAULT '',
|
||||
albumartist TEXT DEFAULT '',
|
||||
title TEXT,
|
||||
album TEXT,
|
||||
artist TEXT,
|
||||
albumartist TEXT,
|
||||
track INTEGER,
|
||||
disc INTEGER,
|
||||
year INTEGER,
|
||||
originalyear INTEGER,
|
||||
genre TEXT DEFAULT '',
|
||||
genre TEXT,
|
||||
compilation INTEGER DEFAULT 0,
|
||||
composer TEXT DEFAULT '',
|
||||
performer TEXT DEFAULT '',
|
||||
grouping TEXT DEFAULT '',
|
||||
comment TEXT DEFAULT '',
|
||||
lyrics TEXT DEFAULT '',
|
||||
composer TEXT,
|
||||
performer TEXT,
|
||||
grouping TEXT,
|
||||
comment TEXT,
|
||||
lyrics TEXT,
|
||||
|
||||
artist_id TEXT DEFAULT '',
|
||||
album_id TEXT DEFAULT '',
|
||||
song_id TEXT DEFAULT '',
|
||||
artist_id TEXT,
|
||||
album_id TEXT,
|
||||
song_id TEXT,
|
||||
|
||||
beginning INTEGER,
|
||||
length INTEGER,
|
||||
@@ -564,14 +564,14 @@ CREATE TABLE IF NOT EXISTS playlist_items (
|
||||
|
||||
source INTEGER,
|
||||
directory_id INTEGER,
|
||||
url TEXT DEFAULT '',
|
||||
url TEXT NOT NULL,
|
||||
filetype INTEGER,
|
||||
filesize INTEGER,
|
||||
mtime INTEGER,
|
||||
ctime INTEGER,
|
||||
unavailable INTEGER DEFAULT 0,
|
||||
|
||||
fingerprint TEXT DEFAULT '',
|
||||
fingerprint TEXT,
|
||||
|
||||
playcount INTEGER DEFAULT 0,
|
||||
skipcount INTEGER DEFAULT 0,
|
||||
@@ -583,23 +583,23 @@ CREATE TABLE IF NOT EXISTS playlist_items (
|
||||
compilation_off INTEGER DEFAULT 0,
|
||||
compilation_effective INTEGER DEFAULT 0,
|
||||
|
||||
art_automatic TEXT DEFAULT '',
|
||||
art_manual TEXT DEFAULT '',
|
||||
art_automatic TEXT,
|
||||
art_manual TEXT,
|
||||
|
||||
effective_albumartist TEXT DEFAULT '',
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER,
|
||||
|
||||
cue_path TEXT DEFAULT '',
|
||||
cue_path TEXT,
|
||||
|
||||
rating INTEGER DEFAULT -1
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS devices (
|
||||
unique_id TEXT NOT NULL DEFAULT '',
|
||||
friendly_name TEXT DEFAULT '',
|
||||
unique_id TEXT NOT NULL,
|
||||
friendly_name TEXT,
|
||||
size INTEGER,
|
||||
icon TEXT DEFAULT '',
|
||||
icon TEXT,
|
||||
schema_version INTEGER NOT NULL DEFAULT 0,
|
||||
transcode_mode NOT NULL DEFAULT 3,
|
||||
transcode_format NOT NULL DEFAULT 5
|
||||
@@ -607,9 +607,9 @@ CREATE TABLE IF NOT EXISTS devices (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS radio_channels (
|
||||
source INTEGER NOT NULL DEFAULT 0,
|
||||
name TEXT DEFAULT '',
|
||||
url TEXT DEFAULT '',
|
||||
thumbnail_url TEXT DEFAULT ''
|
||||
name TEXT,
|
||||
url TEXT NOT NULL,
|
||||
thumbnail_url TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_url ON songs (url);
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
background-color: %palette-base;
|
||||
}
|
||||
|
||||
#context-scrollarea {
|
||||
background-color: %palette-base;
|
||||
}
|
||||
|
||||
QToolButton {
|
||||
border: 2px solid transparent;
|
||||
border-radius: 3px;
|
||||
|
||||
22
debian/CMakeLists.txt
vendored
Normal file
22
debian/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
if(LSB_RELEASE_EXEC AND DPKG_BUILDPACKAGE)
|
||||
|
||||
execute_process(COMMAND env LC_ALL=C date "+%a, %-d %b %Y %H:%M:%S %z" OUTPUT_VARIABLE DEB_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND /bin/sh "-c" "${LSB_RELEASE_EXEC} -cs" OUTPUT_VARIABLE DEB_CODENAME OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if(DEB_CODENAME AND DEB_DATE)
|
||||
|
||||
if(BUILD_WITH_QT5)
|
||||
set(DEBIAN_BUILD_DEPENDS_QT_PACKAGES qtbase5-dev,qtbase5-dev-tools,qttools5-dev,qttools5-dev-tools,libqt5x11extras5-dev)
|
||||
set(DEBIAN_DEPENDS_QT_PACKAGES libqt5sql5-sqlite)
|
||||
endif()
|
||||
if(BUILD_WITH_QT6)
|
||||
set(DEBIAN_BUILD_DEPENDS_QT_PACKAGES qt6-base-dev,qt6-base-dev-tools,qt6-tools-dev,qt6-tools-dev-tools,qt6-l10n-tools)
|
||||
set(DEBIAN_DEPENDS_QT_PACKAGES libqt6sql6-sqlite,qt6-qpa-plugins)
|
||||
endif()
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/control.in ${CMAKE_CURRENT_SOURCE_DIR}/control @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/changelog.in ${CMAKE_CURRENT_SOURCE_DIR}/changelog)
|
||||
|
||||
endif()
|
||||
|
||||
endif()
|
||||
19
debian/control → debian/control.in
vendored
19
debian/control → debian/control.in
vendored
@@ -6,6 +6,7 @@ Build-Depends: debhelper (>= 11),
|
||||
make,
|
||||
cmake,
|
||||
gcc,
|
||||
g++,
|
||||
protobuf-compiler,
|
||||
libglib2.0-dev,
|
||||
libdbus-1-dev,
|
||||
@@ -16,11 +17,7 @@ Build-Depends: debhelper (>= 11),
|
||||
libasound2-dev,
|
||||
libpulse-dev,
|
||||
libtag1-dev,
|
||||
qtbase5-dev,
|
||||
qtbase5-private-dev,
|
||||
qtbase5-dev-tools,
|
||||
qttools5-dev,
|
||||
libqt5x11extras5-dev,
|
||||
@DEBIAN_BUILD_DEPENDS_QT_PACKAGES@,
|
||||
libgstreamer1.0-dev,
|
||||
libgstreamer-plugins-base1.0-dev,
|
||||
libcdio-dev,
|
||||
@@ -28,20 +25,19 @@ Build-Depends: debhelper (>= 11),
|
||||
libmtp-dev,
|
||||
libchromaprint-dev,
|
||||
libfftw3-dev
|
||||
Standards-Version: 4.2.1
|
||||
Standards-Version: 4.6.1
|
||||
|
||||
Package: strawberry
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
libsqlite3-0,
|
||||
libqt5sql5-sqlite,
|
||||
@DEBIAN_DEPENDS_QT_PACKAGES@,
|
||||
gstreamer1.0-plugins-base,
|
||||
gstreamer1.0-plugins-good,
|
||||
gstreamer1.0-alsa,
|
||||
gstreamer1.0-pulseaudio
|
||||
Homepage: http://www.strawberrymusicplayer.org/
|
||||
Description: Audio player and music collection organizer
|
||||
Description: music player and music collection organizer
|
||||
Strawberry is a music player aimed at music collectors and audiophiles.
|
||||
.
|
||||
Features:
|
||||
@@ -49,14 +45,13 @@ Description: Audio player and music collection organizer
|
||||
- Supports WAV, FLAC, WavPack, Ogg Vorbis, Speex, MPC, TrueAudio, AIFF, MP4, MP3 and ASF
|
||||
- Audio CD playback
|
||||
- Native desktop notifications
|
||||
- Playlist management
|
||||
- Playlists in multiple formats
|
||||
- Playlist management and playlists in multiple formats
|
||||
- Smart and dynamic playlists
|
||||
- Advanced audio output and device configuration for bit-perfect playback on Linux
|
||||
- Edit tags on audio files
|
||||
- Automatically retrieve tags from MusicBrainz
|
||||
- Album cover art from Last.fm, Musicbrainz, Discogs, Musixmatch, Deezer, Tidal, Qobuz and Spotify
|
||||
- Song lyrics from AudD, Genius, Musixmatch, ChartLyrics, lyrics.ovh and lololyrics.com
|
||||
- Support for multiple backends
|
||||
- Audio analyzer
|
||||
- Audio equalizer
|
||||
- Transfer music to mass-storage USB players, MTP compatible devices and iPod Nano/Classic
|
||||
183
debian/copyright
vendored
183
debian/copyright
vendored
@@ -1,10 +1,11 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: strawberry
|
||||
Upstream-Contact: Jonas Kvinge <jonas@jkvinge.net>
|
||||
Source: https://www.strawberrymusicplayer.org/
|
||||
Source: https://github.com/strawberrymusicplayer/strawberry
|
||||
|
||||
Files: *
|
||||
Copyright: 2010-2015, David Sansome <me@davidsansome.com>
|
||||
2012-2014, 2017-2022 Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/core/timeconstants.h
|
||||
@@ -13,14 +14,13 @@ Files: src/core/timeconstants.h
|
||||
ext/libstrawberry-common/core/messagehandler.cpp
|
||||
ext/libstrawberry-common/core/messagehandler.h
|
||||
Copyright: 2011, 2012, David Sansome <me@davidsansome.com>
|
||||
2018-2022, Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: Apache-2.0
|
||||
|
||||
Files: src/core/main.h
|
||||
src/core/iconloader.cpp
|
||||
src/core/iconloader.h
|
||||
src/core/iconmapper.h
|
||||
src/config.h.in
|
||||
src/version.h.in
|
||||
src/context/contextview.cpp
|
||||
src/context/contextview.h
|
||||
src/context/contextalbum.cpp
|
||||
@@ -29,6 +29,8 @@ Files: src/core/main.h
|
||||
src/engine/enginetype.h
|
||||
src/engine/alsadevicefinder.cpp
|
||||
src/engine/alsadevicefinder.h
|
||||
src/engine/alsapcmdevicefinder.cpp
|
||||
src/engine/alsapcmdevicefinder.h
|
||||
src/engine/mmdevicefinder.cpp
|
||||
src/engine/mmdevicefinder.h
|
||||
src/engine/devicefinder.cpp
|
||||
@@ -69,11 +71,17 @@ Files: src/core/main.h
|
||||
src/covermanager/spotifycoverprovider.h
|
||||
src/covermanager/musixmatchcoverprovider.cpp
|
||||
src/covermanager/musixmatchcoverprovider.h
|
||||
src/globalshortcuts/globalshortcutsbackend-system.cpp
|
||||
src/globalshortcuts/globalshortcutsbackend-system.h
|
||||
src/globalshortcuts/globalshortcutsbackend-kde.cpp
|
||||
src/globalshortcuts/globalshortcutsbackend-kde.h
|
||||
src/globalshortcuts/globalshortcutsbackend-mate.cpp
|
||||
src/globalshortcuts/globalshortcutsbackend-mate.h
|
||||
src/globalshortcuts/globalshortcutsbackend-x11.cpp
|
||||
src/globalshortcuts/globalshortcutsbackend-x11.h
|
||||
src/globalshortcuts/globalshortcutsbackend-win.cpp
|
||||
src/globalshortcuts/globalshortcutsbackend-win.h
|
||||
src/globalshortcuts/globalshortcut.cpp
|
||||
src/globalshortcuts/globalshortcut.h
|
||||
src/globalshortcuts/globalshortcut-X11.cpp
|
||||
src/globalshortcuts/globalshortcut-x11.cpp
|
||||
src/globalshortcuts/globalshortcut-win.cpp
|
||||
src/globalshortcuts/keymapper_x11.h
|
||||
src/globalshortcuts/keymapper_win.h
|
||||
@@ -81,132 +89,21 @@ Files: src/core/main.h
|
||||
src/scrobbler/*
|
||||
src/subsonic/*
|
||||
src/tidal/*
|
||||
src/qobuz/*
|
||||
src/radios/*
|
||||
src/transcoder/transcoderoptionswavpack.cpp
|
||||
src/transcoder/transcoderoptionswavpack.h
|
||||
Copyright: 2012-2014, 2017-2020, Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/core/main.cpp
|
||||
src/core/mainwindow.cpp
|
||||
src/core/mainwindow.h
|
||||
src/core/player.cpp
|
||||
src/core/player.h
|
||||
src/core/song.cpp
|
||||
src/core/song.h
|
||||
src/core/songloader.cpp
|
||||
src/core/songloader.h
|
||||
src/core/urlhandler.cpp
|
||||
src/core/urlhandler.h
|
||||
src/core/utilities.cpp
|
||||
src/core/utilities.h
|
||||
src/core/networkaccessmanager.cpp
|
||||
src/core/networkaccessmanager.h
|
||||
src/core/threadsafenetworkdiskcache.cpp
|
||||
src/core/threadsafenetworkdiskcache.h
|
||||
src/core/filesystemmusicstorage.cpp
|
||||
src/core/filesystemmusicstorage.h
|
||||
src/core/stylesheetloader.cpp
|
||||
src/core/stylesheetloader.h
|
||||
src/engine/gstenginepipeline.cpp
|
||||
src/engine/gstenginepipeline.h
|
||||
src/engine/vlcengine.cpp
|
||||
src/engine/vlcengine.h
|
||||
src/collection/collectionwatcher.cpp
|
||||
src/collection/collectionwatcher.h
|
||||
src/collection/collectionbackend.cpp
|
||||
src/collection/collectionbackend.h
|
||||
src/collection/collectionmodel.cpp
|
||||
src/collection/collectionmodel.h
|
||||
src/context/contextalbumsmodel.cpp
|
||||
src/context/contextalbumsview.cpp
|
||||
src/context/contextalbumsmodel.h
|
||||
src/context/contextalbumsview.h
|
||||
src/widgets/playingwidget.cpp
|
||||
src/widgets/playingwidget.h
|
||||
src/osd/osdbase.cpp
|
||||
src/osd/osdbase.h
|
||||
src/osd/osdpretty.cpp
|
||||
src/osd/osdpretty.h
|
||||
src/osd/osddbus.cpp
|
||||
src/osd/osddbus.h
|
||||
src/osd/osdmac.cpp
|
||||
src/osd/osdmac.h
|
||||
src/dialogs/about.cpp
|
||||
src/dialogs/about.h
|
||||
src/playlist/playlist.cpp
|
||||
src/playlist/playlist.h
|
||||
src/playlist/playlistitem.cpp
|
||||
src/playlist/playlistitem.h
|
||||
src/playlist/playlistdelegates.cpp
|
||||
src/playlist/playlistdelegates.h
|
||||
src/playlist/playlistbackend.cpp
|
||||
src/playlist/playlistbackend.h
|
||||
src/playlist/playlistview.cpp
|
||||
src/playlist/playlistview.h
|
||||
src/playlist/songplaylistitem.cpp
|
||||
src/playlist/songplaylistitem.h
|
||||
src/internet/internetplaylistitem.cpp
|
||||
src/internet/internetsearch.cpp
|
||||
src/internet/internetsearch.h
|
||||
src/internet/internetsearchview.cpp
|
||||
src/internet/internetsearchview.h
|
||||
src/internet/internetservices.cpp
|
||||
src/internet/internetservices.h
|
||||
src/internet/internetsongsview.cpp
|
||||
src/internet/internetsongsview.h
|
||||
src/internet/internetcollectionview.cpp
|
||||
src/internet/internetcollectionview.h
|
||||
ext/libstrawberry-tagreader/tagreader.cpp
|
||||
ext/libstrawberry-tagreader/tagreader.h
|
||||
src/device/devicemanager.cpp
|
||||
src/device/devicemanager.h
|
||||
src/device/deviceinfo.cpp
|
||||
src/device/deviceinfo.h
|
||||
src/device/deviceproperties.cpp
|
||||
src/device/deviceproperties.h
|
||||
src/device/deviceview.cpp
|
||||
src/device/deviceview.h
|
||||
src/device/connecteddevice.cpp
|
||||
src/device/connecteddevice.h
|
||||
src/device/mtpconnection.cpp
|
||||
src/device/mtpconnection.h
|
||||
src/device/mtpdevice.cpp
|
||||
src/device/mtpdevice.h
|
||||
src/globalshortcuts/globalshortcutsmanager.cpp
|
||||
src/globalshortcuts/globalshortcutsmanager.h
|
||||
src/settings/shortcutssettingspage.cpp
|
||||
src/settings/shortcutssettingspage.h
|
||||
src/settings/appearancesettingspage.cpp
|
||||
src/settings/appearancesettingspage.h
|
||||
src/organize/organize.cpp
|
||||
src/organize/organize.h
|
||||
src/organize/organizedialog.cpp
|
||||
src/organize/organizedialog.h
|
||||
src/organize/organizeerrordialog.cpp
|
||||
src/organize/organizeerrordialog.h
|
||||
src/transcoder/transcoder.cpp
|
||||
src/transcoder/transcoder.h
|
||||
src/musicbrainz/musicbrainzclient.cpp
|
||||
src/musicbrainz/musicbrainzclient.h
|
||||
src/covermanager/albumcoverloader.cpp
|
||||
src/covermanager/albumcoverloader.h
|
||||
src/covermanager/currentalbumcoverloader.cpp
|
||||
src/covermanager/currentalbumcoverloader.h
|
||||
src/covermanager/albumcoverchoicecontroller.cpp
|
||||
src/covermanager/albumcoverchoicecontroller.h
|
||||
src/covermanager/albumcoverfetchersearch.cpp
|
||||
src/covermanager/albumcoverfetchersearch.h
|
||||
src/covermanager/coverproviders.cpp
|
||||
src/covermanager/coverproviders.h
|
||||
src/covermanager/coverprovider.cpp
|
||||
src/covermanager/coverprovider.h
|
||||
Copyright: 2010, 2012-2014 David Sansome <me@davidsansome.com>
|
||||
2012-2014, 2017-2020 Jonas Kvinge <jonas@jkvinge.net>
|
||||
ext/libstrawberry-tagreader/tagreadertagparser.cpp
|
||||
ext/libstrawberry-tagreader/tagreadertagparser.h
|
||||
ext/macdeploycheck/*
|
||||
src/widgets/resizabletextedit.cpp
|
||||
src/widgets/resizabletextedit.h
|
||||
Copyright: 2012-2014, 2017-2022, Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/engine/enginebase.cpp
|
||||
src/engine/enginebase.h
|
||||
Copyright: 2017, 2018, Jonas Kvinge <jonas@jkvinge.net>
|
||||
Copyright: 2017-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
2010, David Sansome <me@davidsansome.com>
|
||||
2004, 2005, Max Howell, <max.howell@methylblue.com>
|
||||
2003, Mark Kretschmann <markey@web.de>
|
||||
@@ -214,7 +111,7 @@ License: GPL-3+
|
||||
|
||||
Files: src/engine/gstengine.cpp
|
||||
src/engine/gstengine.h
|
||||
Copyright: 2017, 2018, Jonas Kvinge <jonas@jkvinge.net>
|
||||
Copyright: 2017-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
2006, Paul Cifarelli <paul@cifarelli.net>
|
||||
2005, Jakub Stachowski <qbast@go2.pl>
|
||||
2003-2005, Mark Kretschmann <markey@web.de>
|
||||
@@ -230,7 +127,7 @@ Files: src/core/application.cpp
|
||||
src/core/application.h
|
||||
Copyright: 2012, David Sansome <me@davidsansome.com>
|
||||
2012, 2014, John Maguire <john.maguire@gmail.com>
|
||||
2018, Jonas Kvinge <jonas@jkvinge.net>
|
||||
2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/core/appearance.cpp
|
||||
@@ -244,13 +141,7 @@ Copyright: 2012, Martin Björklund <mbj4668@gmail.com>
|
||||
2016, Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: ext/libstrawberry-common/core/arraysize.h
|
||||
ext/libstrawberry-common/core/scoped_nsautorelease_pool.h
|
||||
ext/libstrawberry-common/core/scoped_nsautorelease_pool.mm
|
||||
Copyright: 2010, 2011, 2014, The Chromium Authors.
|
||||
License: BSD-style
|
||||
|
||||
Files: ext/libstrawberry-common/core/lazy.h
|
||||
Files: src/core/lazy.h
|
||||
Copyright: 2016, John Maguire <john.maguire@gmail.com>
|
||||
License: GPL-3+
|
||||
|
||||
@@ -298,12 +189,16 @@ Copyright: 2011, Tyler Rhodes <tyler.s.rhodes@gmail.com>
|
||||
2015, Arun Narayanankutty <n.arun.lifescience@gmail.com>
|
||||
License: GPL-2+
|
||||
|
||||
Files: src/collection/savedgroupingmanager.h
|
||||
Files: src/collection/savedgroupingmanager.*
|
||||
Copyright: 2015, Nick Lanham <nick@afternight.org>
|
||||
2019-2021 Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/core/scoped_cftyperef.h
|
||||
Files: src/core/arraysize.h
|
||||
src/core/scoped_cftyperef.h
|
||||
src/core/scoped_nsobject.h
|
||||
src/core/scoped_nsautorelease_pool.h
|
||||
src/core/scoped_nsautorelease_pool.mm
|
||||
Copyright: 2010, 2011, 2014, The Chromium Authors.
|
||||
License: BSD-style
|
||||
|
||||
@@ -322,7 +217,7 @@ Files: src/internet/localredirectserver.cpp
|
||||
src/internet/localredirectserver.h
|
||||
Copyright: 2012, 2014, John Maguire <john.maguire@gmail.com>
|
||||
2014, Krzysztof Sobiecki <sobkas@gmail.com>
|
||||
2018-2019, Jonas Kvinge <jonas@jkvinge.net>
|
||||
2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/transcoder/transcoderoptionsopus.cpp
|
||||
@@ -337,12 +232,17 @@ Files: src/widgets/clickablelabel.cpp
|
||||
Copyright: 2010, 2011, Andrea Decorte <adecorte@gmail.com>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/widgets/sliderwidget.cpp
|
||||
src/widgets/sliderwidget.h
|
||||
Files: src/widgets/volumeslider.cpp
|
||||
src/widgets/volumeslider.h
|
||||
Copyright: 2005, Gábor Lehel
|
||||
2003, Mark Kretschmann <markey@web.de>
|
||||
License: GPL-2+
|
||||
|
||||
Files: src/scrobbler/subsonicscrobbler.*
|
||||
Copyright: 2018-2021 Jonas Kvinge <jonas@jkvinge.net>
|
||||
2020 Pascal Below <spezifisch@below.fr>
|
||||
License: GPL-3+
|
||||
|
||||
Files: src/core/stylehelper.cpp
|
||||
src/core/stylehelper.h
|
||||
Copyright: 2016 The Qt Company Ltd.
|
||||
@@ -358,6 +258,7 @@ License: GPL-2+
|
||||
Files: src/widgets/qsearchfield_nonmac.cpp
|
||||
src/widgets/qsearchfield_mac.mm
|
||||
src/widgets/qsearchfield.h
|
||||
src/widgets/qocoa_mac.h
|
||||
Copyright: 2011, Mike McQuaid <mike@mikemcquaid.com>
|
||||
License: Expat
|
||||
|
||||
@@ -367,7 +268,7 @@ Copyright: 2010, Spotify AB
|
||||
License: BSD-3-clause
|
||||
|
||||
Files: 3rdparty/singleapplication/*
|
||||
Copyright: 2015-2018, Itay Grudev
|
||||
Copyright: 2015-2022, Itay Grudev
|
||||
License: MIT
|
||||
|
||||
|
||||
|
||||
6
debian/copyright-scan-patterns.yml
vendored
6
debian/copyright-scan-patterns.yml
vendored
@@ -4,14 +4,14 @@ ignore:
|
||||
- Changelog
|
||||
- COPYING
|
||||
- CMakeLists.txt
|
||||
- Dockerfile
|
||||
- cmake_uninstall.cmake.in
|
||||
- .clang-format
|
||||
- .gitignore
|
||||
- .travis.yml
|
||||
- .github
|
||||
- /debian/
|
||||
- /cmake/
|
||||
- /data/
|
||||
- /dist/
|
||||
- /snap/
|
||||
|
||||
suffixes:
|
||||
- jpg
|
||||
|
||||
1
debian/rules
vendored
1
debian/rules
vendored
@@ -5,7 +5,6 @@
|
||||
|
||||
override_dh_auto_clean:
|
||||
rm -f dist/macos/Info.plist
|
||||
rm -f dist/unix/PKGBUILD
|
||||
rm -f dist/unix/strawberry.spec
|
||||
rm -f dist/scripts/maketarball.sh
|
||||
rm -f dist/windows/strawberry.nsi
|
||||
|
||||
4
dist/CMakeLists.txt
vendored
4
dist/CMakeLists.txt
vendored
@@ -2,10 +2,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/maketarball.sh.in ${CMAKE_CUR
|
||||
if(RPM_DISTRO AND RPM_DATE)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unix/strawberry.spec.in ${CMAKE_CURRENT_SOURCE_DIR}/unix/strawberry.spec @ONLY)
|
||||
endif(RPM_DISTRO AND RPM_DATE)
|
||||
if(DEB_CODENAME AND DEB_DATE)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/debian/changelog.in ${CMAKE_SOURCE_DIR}/debian/changelog)
|
||||
endif(DEB_CODENAME AND DEB_DATE)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unix/PKGBUILD.in ${CMAKE_CURRENT_SOURCE_DIR}/unix/PKGBUILD @ONLY)
|
||||
|
||||
if(APPLE)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist.in ${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist)
|
||||
|
||||
58
dist/macos/macgstcopy.sh
vendored
58
dist/macos/macgstcopy.sh
vendored
@@ -39,8 +39,12 @@ fi
|
||||
cp -v -f "${GST_PLUGIN_SCANNER}" "${bundledir}/Contents/PlugIns/" || exit 1
|
||||
|
||||
gst_plugins="
|
||||
libgstaes.dylib
|
||||
libgstaiff.dylib
|
||||
libgstapetag.dylib
|
||||
libgstapp.dylib
|
||||
libgstasf.dylib
|
||||
libgstasfmux.dylib
|
||||
libgstaudioconvert.dylib
|
||||
libgstaudiofx.dylib
|
||||
libgstaudiomixer.dylib
|
||||
@@ -48,46 +52,46 @@ libgstaudioparsers.dylib
|
||||
libgstaudiorate.dylib
|
||||
libgstaudioresample.dylib
|
||||
libgstaudiotestsrc.dylib
|
||||
libgstaudiovisualizers.dylib
|
||||
libgstauparse.dylib
|
||||
libgstautoconvert.dylib
|
||||
libgstautodetect.dylib
|
||||
libgstbs2b.dylib
|
||||
libgstcdio.dylib
|
||||
libgstcoreelements.dylib
|
||||
libgstdash.dylib
|
||||
libgstequalizer.dylib
|
||||
libgstflac.dylib
|
||||
libgstfaac.dylib
|
||||
libgstfaad.dylib
|
||||
libgstfdkaac.dylib
|
||||
libgstgio.dylib
|
||||
libgsticydemux.dylib
|
||||
libgstid3demux.dylib
|
||||
libgstlevel.dylib
|
||||
libgstisomp4.dylib
|
||||
libgstlame.dylib
|
||||
libgstlibav.dylib
|
||||
libgstmpg123.dylib
|
||||
libgstmusepack.dylib
|
||||
libgstogg.dylib
|
||||
libgstopenmpt.dylib
|
||||
libgstopus.dylib
|
||||
libgstopusparse.dylib
|
||||
libgstosxaudio.dylib
|
||||
libgstplayback.dylib
|
||||
libgstrawparse.dylib
|
||||
libgstreplaygain.dylib
|
||||
libgstsoup.dylib
|
||||
libgstspectrum.dylib
|
||||
libgsttypefindfunctions.dylib
|
||||
libgstvolume.dylib
|
||||
libgstxingmux.dylib
|
||||
libgsttcp.dylib
|
||||
libgstudp.dylib
|
||||
libgstpbtypes.dylib
|
||||
libgstplayback.dylib
|
||||
libgstreplaygain.dylib
|
||||
libgstrtp.dylib
|
||||
libgstrtsp.dylib
|
||||
libgstflac.dylib
|
||||
libgstwavparse.dylib
|
||||
libgstfaad.dylib
|
||||
libgstogg.dylib
|
||||
libgstopus.dylib
|
||||
libgstasf.dylib
|
||||
libgstsoup.dylib
|
||||
libgstspectrum.dylib
|
||||
libgstspeex.dylib
|
||||
libgsttaglib.dylib
|
||||
libgsttcp.dylib
|
||||
libgsttypefindfunctions.dylib
|
||||
libgstudp.dylib
|
||||
libgstvolume.dylib
|
||||
libgstvorbis.dylib
|
||||
libgstisomp4.dylib
|
||||
libgstlibav.dylib
|
||||
libgstaiff.dylib
|
||||
libgstlame.dylib
|
||||
libgstopusparse.dylib
|
||||
libgstfaac.dylib
|
||||
libgstmusepack.dylib
|
||||
libgstwavpack.dylib
|
||||
libgstwavparse.dylib
|
||||
libgstxingmux.dylib;
|
||||
"
|
||||
|
||||
gst_plugins=$(echo "$gst_plugins" | tr '\n' ' ' | sed -e 's/^ //g' | sed -e 's/ / /g')
|
||||
|
||||
1
dist/scripts/maketarball.sh.in
vendored
1
dist/scripts/maketarball.sh.in
vendored
@@ -60,7 +60,6 @@ ${TAR} -cJf $name-$version.tar.xz \
|
||||
--exclude="$root/.zanata-cache" \
|
||||
--exclude="$root/debian/changelog" \
|
||||
--exclude="$root/dist/scripts/maketarball.sh" \
|
||||
--exclude="$root/dist/unix/PKGBUILD" \
|
||||
--exclude="$root/dist/macos/Info.plist" \
|
||||
--exclude="$root/dist/windows/windres.rc" \
|
||||
--exclude="$root/src/translations/translations.pot" \
|
||||
|
||||
56
dist/unix/PKGBUILD.in
vendored
56
dist/unix/PKGBUILD.in
vendored
@@ -1,56 +0,0 @@
|
||||
# Maintainer: Jonas Kvinge <jonas@jkvinge.net>
|
||||
pkgname=strawberry
|
||||
pkgver=@STRAWBERRY_VERSION_PAC_V@
|
||||
pkgrel=@STRAWBERRY_VERSION_PAC_R@
|
||||
pkgdesc="A music player aimed at audio enthusiasts and music collectors"
|
||||
arch=(x86_64)
|
||||
url="https://www.strawberrymusicplayer.org/"
|
||||
license=(GPL3)
|
||||
makedepends=(git cmake make gcc boost gettext qt5-tools)
|
||||
depends=(
|
||||
desktop-file-utils
|
||||
hicolor-icon-theme
|
||||
gnutls
|
||||
udisks2
|
||||
protobuf
|
||||
qt5-base
|
||||
qt5-x11extras
|
||||
sqlite3
|
||||
alsa-lib
|
||||
libpulse
|
||||
dbus
|
||||
taglib
|
||||
gstreamer
|
||||
gst-plugins-base
|
||||
gst-plugins-good
|
||||
vlc
|
||||
chromaprint
|
||||
libgpod
|
||||
libcdio
|
||||
libmtp
|
||||
fftw
|
||||
)
|
||||
optdepends=(
|
||||
gst-plugins-bad
|
||||
gst-plugins-ugly
|
||||
gst-libav
|
||||
)
|
||||
provides=(strawberry)
|
||||
conflicts=(strawberry)
|
||||
source=("strawberry-@STRAWBERRY_VERSION_PACKAGE@.tar.xz")
|
||||
sha256sums=('SKIP')
|
||||
|
||||
prepare() {
|
||||
mkdir -p build
|
||||
}
|
||||
|
||||
build() {
|
||||
cd build
|
||||
cmake ../${pkgname}-@STRAWBERRY_VERSION_PACKAGE@ -DCMAKE_INSTALL_PREFIX=/usr
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd build
|
||||
make DESTDIR="${pkgdir}" install
|
||||
}
|
||||
@@ -12,15 +12,11 @@ Categories=AudioVideo;Player;Qt;Audio;
|
||||
StartupNotify=false
|
||||
MimeType=x-content/audio-player;application/ogg;application/x-ogg;application/x-ogm-audio;audio/flac;audio/ogg;audio/vorbis;audio/aac;audio/mp4;audio/mpeg;audio/mpegurl;audio/vnd.rn-realaudio;audio/x-flac;audio/x-oggflac;audio/x-vorbis;audio/x-vorbis+ogg;audio/x-speex;audio/x-wav;audio/x-wavpack;audio/x-ape;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-wma;audio/x-musepack;audio/x-pn-realaudio;audio/x-scpls;video/x-ms-asf;x-scheme-handler/tidal;
|
||||
StartupWMClass=strawberry
|
||||
Actions=Play;Pause;Stop;StopAfterCurrent;Previous;Next;
|
||||
Actions=Play-Pause;Stop;StopAfterCurrent;Previous;Next;
|
||||
|
||||
[Desktop Action Play]
|
||||
Name=Play
|
||||
Exec=strawberry --play
|
||||
|
||||
[Desktop Action Pause]
|
||||
Name=Pause
|
||||
Exec=strawberry --pause
|
||||
[Desktop Action Play-Pause]
|
||||
Name=Play/Pause
|
||||
Exec=strawberry --play-pause
|
||||
|
||||
[Desktop Action Stop]
|
||||
Name=Stop
|
||||
|
||||
2
dist/unix/strawberry.spec.in
vendored
2
dist/unix/strawberry.spec.in
vendored
@@ -1,6 +1,6 @@
|
||||
Name: strawberry
|
||||
Version: @STRAWBERRY_VERSION_RPM_V@
|
||||
%if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos}
|
||||
%if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos} || "%{?_vendor}" == "openmandriva"
|
||||
Release: @STRAWBERRY_VERSION_RPM_R@%{?dist}
|
||||
%else
|
||||
Release: @STRAWBERRY_VERSION_RPM_R@.@RPM_DISTRO@
|
||||
|
||||
186
dist/windows/Registry.nsh
vendored
Normal file
186
dist/windows/Registry.nsh
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
!define registry::Open `!insertmacro registry::Open`
|
||||
|
||||
!macro registry::Open _PATH _OPTIONS _HANDLE
|
||||
registry::_Open /NOUNLOAD `${_PATH}` `${_OPTIONS}`
|
||||
Pop ${_HANDLE}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::Find `!insertmacro registry::Find`
|
||||
|
||||
!macro registry::Find _HANDLE _PATH _VALUEORKEY _STRING _TYPE
|
||||
registry::_Find /NOUNLOAD `${_HANDLE}`
|
||||
Pop ${_PATH}
|
||||
Pop ${_VALUEORKEY}
|
||||
Pop ${_STRING}
|
||||
Pop ${_TYPE}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::Close `!insertmacro registry::Close`
|
||||
|
||||
!macro registry::Close _HANDLE
|
||||
registry::_Close /NOUNLOAD `${_HANDLE}`
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::KeyExists `!insertmacro registry::KeyExists`
|
||||
|
||||
!macro registry::KeyExists _PATH _ERR
|
||||
registry::_KeyExists /NOUNLOAD `${_PATH}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::Read `!insertmacro registry::Read`
|
||||
|
||||
!macro registry::Read _PATH _VALUE _STRING _TYPE
|
||||
registry::_Read /NOUNLOAD `${_PATH}` `${_VALUE}`
|
||||
Pop ${_STRING}
|
||||
Pop ${_TYPE}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::Write `!insertmacro registry::Write`
|
||||
|
||||
!macro registry::Write _PATH _VALUE _STRING _TYPE _ERR
|
||||
registry::_Write /NOUNLOAD `${_PATH}` `${_VALUE}` `${_STRING}` `${_TYPE}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::ReadExtra `!insertmacro registry::ReadExtra`
|
||||
|
||||
!macro registry::ReadExtra _PATH _VALUE _NUMBER _STRING _TYPE
|
||||
registry::_ReadExtra /NOUNLOAD `${_PATH}` `${_VALUE}` `${_NUMBER}`
|
||||
Pop ${_STRING}
|
||||
Pop ${_TYPE}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::WriteExtra `!insertmacro registry::WriteExtra`
|
||||
|
||||
!macro registry::WriteExtra _PATH _VALUE _STRING _ERR
|
||||
registry::_WriteExtra /NOUNLOAD `${_PATH}` `${_VALUE}` `${_STRING}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::CreateKey `!insertmacro registry::CreateKey`
|
||||
|
||||
!macro registry::CreateKey _PATH _ERR
|
||||
registry::_CreateKey /NOUNLOAD `${_PATH}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::DeleteValue `!insertmacro registry::DeleteValue`
|
||||
|
||||
!macro registry::DeleteValue _PATH _VALUE _ERR
|
||||
registry::_DeleteValue /NOUNLOAD `${_PATH}` `${_VALUE}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::DeleteKey `!insertmacro registry::DeleteKey`
|
||||
|
||||
!macro registry::DeleteKey _PATH _ERR
|
||||
registry::_DeleteKey /NOUNLOAD `${_PATH}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::DeleteKeyEmpty `!insertmacro registry::DeleteKeyEmpty`
|
||||
|
||||
!macro registry::DeleteKeyEmpty _PATH _ERR
|
||||
registry::_DeleteKeyEmpty /NOUNLOAD `${_PATH}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::CopyValue `!insertmacro registry::CopyValue`
|
||||
|
||||
!macro registry::CopyValue _PATH_SOURCE _VALUE_SOURCE _PATH_TARGET _VALUE_TARGET _ERR
|
||||
registry::_CopyValue /NOUNLOAD `${_PATH_SOURCE}` `${_VALUE_SOURCE}` `${_PATH_TARGET}` `${_VALUE_TARGET}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::MoveValue `!insertmacro registry::MoveValue`
|
||||
|
||||
!macro registry::MoveValue _PATH_SOURCE _VALUE_SOURCE _PATH_TARGET _VALUE_TARGET _ERR
|
||||
registry::_MoveValue /NOUNLOAD `${_PATH_SOURCE}` `${_VALUE_SOURCE}` `${_PATH_TARGET}` `${_VALUE_TARGET}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::CopyKey `!insertmacro registry::CopyKey`
|
||||
|
||||
!macro registry::CopyKey _PATH_SOURCE _PATH_TARGET _ERR
|
||||
registry::_CopyKey /NOUNLOAD `${_PATH_SOURCE}` `${_PATH_TARGET}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::MoveKey `!insertmacro registry::MoveKey`
|
||||
|
||||
!macro registry::MoveKey _PATH_SOURCE _PATH_TARGET _ERR
|
||||
registry::_MoveKey /NOUNLOAD `${_PATH_SOURCE}` `${_PATH_TARGET}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::SaveKey `!insertmacro registry::SaveKey`
|
||||
|
||||
!macro registry::SaveKey _PATH _FILE _OPTIONS _ERR
|
||||
registry::_SaveKey /NOUNLOAD `${_PATH}` `${_FILE}` `${_OPTIONS}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::RestoreKey `!insertmacro registry::RestoreKey`
|
||||
|
||||
!macro registry::RestoreKey _FILE _ERR
|
||||
registry::_RestoreKey /NOUNLOAD `${_FILE}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::StrToHex `!insertmacro registry::StrToHexA`
|
||||
!define registry::StrToHexA `!insertmacro registry::StrToHexA`
|
||||
|
||||
!macro registry::StrToHexA _STRING _HEX_STRING
|
||||
registry::_StrToHexA /NOUNLOAD `${_STRING}`
|
||||
Pop ${_HEX_STRING}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::StrToHexW `!insertmacro registry::StrToHexW`
|
||||
|
||||
!macro registry::StrToHexW _STRING _HEX_STRING
|
||||
registry::_StrToHexW /NOUNLOAD `${_STRING}`
|
||||
Pop ${_HEX_STRING}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::HexToStr `!insertmacro registry::HexToStrA`
|
||||
!define registry::HexToStrA `!insertmacro registry::HexToStrA`
|
||||
|
||||
!macro registry::HexToStrA _HEX_STRING _STRING
|
||||
registry::_HexToStrA /NOUNLOAD `${_HEX_STRING}`
|
||||
Pop ${_STRING}
|
||||
!macroend
|
||||
|
||||
!define registry::HexToStrW `!insertmacro registry::HexToStrW`
|
||||
|
||||
!macro registry::HexToStrW _HEX_STRING _STRING
|
||||
registry::_HexToStrW /NOUNLOAD `${_HEX_STRING}`
|
||||
Pop ${_STRING}
|
||||
!macroend
|
||||
|
||||
|
||||
!define registry::Unload `!insertmacro registry::Unload`
|
||||
|
||||
!macro registry::Unload
|
||||
registry::_Unload
|
||||
!macroend
|
||||
314
dist/windows/strawberry.nsi.in
vendored
314
dist/windows/strawberry.nsi.in
vendored
@@ -38,6 +38,10 @@
|
||||
!define compiler "msvc"
|
||||
!endif
|
||||
|
||||
!if "@CMAKE_BUILD_TYPE@" == "Release"
|
||||
!define release
|
||||
!endif
|
||||
|
||||
!if "@CMAKE_BUILD_TYPE@" == "Debug"
|
||||
!define debug
|
||||
!undef build_type
|
||||
@@ -96,6 +100,7 @@ SetCompressor /SOLID lzma
|
||||
!include "FileAssociation.nsh"
|
||||
!include "Capabilities.nsh"
|
||||
!include LogicLib.nsh
|
||||
!include Registry.nsh
|
||||
!include x64.nsh
|
||||
|
||||
!define MUI_ICON "strawberry.ico"
|
||||
@@ -105,11 +110,15 @@ SetCompressor /SOLID lzma
|
||||
!ifdef mingw
|
||||
ReserveFile "${NSISDIR}/Plugins/x86-unicode/LockedList.dll"
|
||||
ReserveFile "${NSISDIR}/Plugins/LockedList64.dll"
|
||||
ReserveFile "${NSISDIR}/Plugins/registry.dll"
|
||||
ReserveFile "${NSISDIR}/Plugins/x86-unicode/INetC.dll"
|
||||
!endif
|
||||
|
||||
!ifdef msvc
|
||||
ReserveFile "${NSISDIR}\Plugins\x86-unicode\LockedList.dll"
|
||||
ReserveFile "${NSISDIR}\Plugins\LockedList64.dll"
|
||||
ReserveFile "${NSISDIR}\Plugins\registry.dll"
|
||||
ReserveFile "${NSISDIR}\Plugins\x86-unicode\INetC.dll"
|
||||
!endif
|
||||
|
||||
!define LockedListPATH $InstallDir
|
||||
@@ -192,9 +201,7 @@ Section "Strawberry" Strawberry
|
||||
File "strawberry.exe"
|
||||
File "strawberry-tagreader.exe"
|
||||
File "strawberry.ico"
|
||||
!ifdef mingw
|
||||
File "sqlite3.exe"
|
||||
!endif
|
||||
File "gst-launch-1.0.exe"
|
||||
File "gst-discoverer-1.0.exe"
|
||||
|
||||
@@ -217,22 +224,27 @@ Section "Strawberry" Strawberry
|
||||
File "avfilter-8.dll"
|
||||
File "avformat-59.dll"
|
||||
File "avutil-57.dll"
|
||||
File "libFLAC-8.dll"
|
||||
File "libbrotlicommon.dll"
|
||||
File "libbrotlidec.dll"
|
||||
File "libbrotlienc.dll"
|
||||
File "libbs2b-0.dll"
|
||||
File "libbz2.dll"
|
||||
File "libcdio-19.dll"
|
||||
File "libchromaprint.dll"
|
||||
File "libdl.dll"
|
||||
File "libfaac-0.dll"
|
||||
File "libfaad-2.dll"
|
||||
File "libfdk-aac-2.dll"
|
||||
File "libffi-8.dll"
|
||||
File "libfreetype-6.dll"
|
||||
File "libgcrypt-20.dll"
|
||||
File "libgio-2.0-0.dll"
|
||||
File "libglib-2.0-0.dll"
|
||||
File "libgmodule-2.0-0.dll"
|
||||
File "libgmp-10.dll"
|
||||
File "libgnutls-30.dll"
|
||||
File "libgobject-2.0-0.dll"
|
||||
File "libgpg-error-0.dll"
|
||||
File "libgstadaptivedemux-1.0-0.dll"
|
||||
File "libgstapp-1.0-0.dll"
|
||||
File "libgstaudio-1.0-0.dll"
|
||||
@@ -252,30 +264,39 @@ Section "Strawberry" Strawberry
|
||||
File "libgstvideo-1.0-0.dll"
|
||||
File "libharfbuzz-0.dll"
|
||||
File "libhogweed-6.dll"
|
||||
File "libiconv-2.dll"
|
||||
File "libidn2-0.dll"
|
||||
File "libintl-8.dll"
|
||||
File "libjpeg-9.dll"
|
||||
File "liblzma-5.dll"
|
||||
File "libmp3lame-0.dll"
|
||||
File "libmpcdec.dll"
|
||||
File "libmpg123-0.dll"
|
||||
File "libnettle-8.dll"
|
||||
File "libnghttp2.dll"
|
||||
File "libogg-0.dll"
|
||||
File "libopenmpt-0.dll"
|
||||
File "libopus-0.dll"
|
||||
File "liborc-0.4-0.dll"
|
||||
File "libpcre-1.dll"
|
||||
File "libpcre2-16-0.dll"
|
||||
File "libpng16-16.dll"
|
||||
File "libprotobuf-30.dll"
|
||||
File "libprotobuf-32.dll"
|
||||
File "libpsl-5.dll"
|
||||
File "libqtsparkle-qt6.dll"
|
||||
File "libsoup-3.0-0.dll"
|
||||
File "libspeex-1.dll"
|
||||
File "libsqlite3-0.dll"
|
||||
File "libssp-0.dll"
|
||||
File "libstdc++-6.dll"
|
||||
File "libtag.dll"
|
||||
File "libtasn1-6.dll"
|
||||
File "libtwolame-0.dll"
|
||||
File "libunistring-2.dll"
|
||||
File "libvorbis-0.dll"
|
||||
File "libvorbisenc-2.dll"
|
||||
File "libvorbisfile-3.dll"
|
||||
File "libwavpack-1.dll"
|
||||
File "libwinpthread-1.dll"
|
||||
File "libxml2-2.dll"
|
||||
File "libzstd.dll"
|
||||
File "postproc-56.dll"
|
||||
File "swresample-4.dll"
|
||||
@@ -287,8 +308,13 @@ Section "Strawberry" Strawberry
|
||||
File "libexpat-1.dll"
|
||||
File "libmman.dll"
|
||||
File "libmpfr-6.dll"
|
||||
File "libpcre2-8d.dll"
|
||||
File "libpcre2-16d.dll"
|
||||
File "libreadline8.dll"
|
||||
File "libtermcap.dll"
|
||||
!else
|
||||
File "libpcre2-8.dll"
|
||||
File "libpcre2-16.dll"
|
||||
!endif
|
||||
|
||||
!endif ; MinGW
|
||||
@@ -298,20 +324,25 @@ Section "Strawberry" Strawberry
|
||||
!ifdef msvc
|
||||
|
||||
!ifdef arch_x86
|
||||
File "libcrypto-1_1.dll"
|
||||
File "libssl-1_1.dll"
|
||||
File "libcrypto-3.dll"
|
||||
File "libssl-3.dll"
|
||||
!endif
|
||||
!ifdef arch_x64
|
||||
File "libcrypto-1_1-x64.dll"
|
||||
File "libssl-1_1-x64.dll"
|
||||
File "libcrypto-3-x64.dll"
|
||||
File "libssl-3-x64.dll"
|
||||
!endif
|
||||
|
||||
File "FLAC.dll"
|
||||
File "avcodec-58.dll"
|
||||
File "avfilter-7.dll"
|
||||
File "avformat-58.dll"
|
||||
File "avresample-4.dll"
|
||||
File "avutil-56.dll"
|
||||
File "bz2.dll"
|
||||
File "brotlicommon.dll"
|
||||
File "brotlidec.dll"
|
||||
File "chromaprint.dll"
|
||||
File "faad.dll"
|
||||
File "fdk-aac.dll"
|
||||
File "ffi-7.dll"
|
||||
File "gio-2.0-0.dll"
|
||||
File "glib-2.0-0.dll"
|
||||
@@ -321,6 +352,7 @@ Section "Strawberry" Strawberry
|
||||
File "gstadaptivedemux-1.0-0.dll"
|
||||
File "gstapp-1.0-0.dll"
|
||||
File "gstaudio-1.0-0.dll"
|
||||
File "gstbadaudio-1.0-0.dll"
|
||||
File "gstbase-1.0-0.dll"
|
||||
File "gstfft-1.0-0.dll"
|
||||
File "gstisoff-1.0-0.dll"
|
||||
@@ -334,38 +366,70 @@ Section "Strawberry" Strawberry
|
||||
File "gsttag-1.0-0.dll"
|
||||
File "gsturidownloader-1.0-0.dll"
|
||||
File "gstvideo-1.0-0.dll"
|
||||
File "gstwinrt-1.0-0.dll"
|
||||
File "intl-8.dll"
|
||||
File "libprotobuf.dll"
|
||||
File "opus-0.dll"
|
||||
File "libbs2b.dll"
|
||||
File "libfaac_dll.dll"
|
||||
File "libiconv.dll"
|
||||
File "liblzma.dll"
|
||||
File "libmp3lame.dll"
|
||||
File "libopenmpt.dll"
|
||||
File "libspeex.dll"
|
||||
File "mpcdec.dll"
|
||||
File "mpg123.dll"
|
||||
File "ogg.dll"
|
||||
File "opus.dll"
|
||||
File "orc-0.4-0.dll"
|
||||
File "postproc-55.dll"
|
||||
File "psl-5.dll"
|
||||
File "qtsparkle-qt6.dll"
|
||||
File "soup-2.4-1.dll"
|
||||
File "sqlite3-0.dll"
|
||||
File "sqlite3.dll"
|
||||
File "swresample-3.dll"
|
||||
File "swscale-5.dll"
|
||||
File "tag.dll"
|
||||
File "z-1.dll"
|
||||
File "vorbis.dll"
|
||||
File "vorbisfile.dll"
|
||||
File "wavpackdll.dll"
|
||||
|
||||
!ifdef release
|
||||
File "libpng16.dll"
|
||||
File "libprotobuf.dll"
|
||||
File "libxml2.dll"
|
||||
File "pcre2-8.dll"
|
||||
File "pcre2-16.dll"
|
||||
File "twolame.dll"
|
||||
File "zlib.dll"
|
||||
!endif
|
||||
!ifdef debug
|
||||
File "libpng16d.dll"
|
||||
File "libprotobufd.dll"
|
||||
File "libxml2d.dll"
|
||||
File "pcre2-8d.dll"
|
||||
File "pcre2-16d.dll"
|
||||
File "twolamed.dll"
|
||||
File "zlibd.dll"
|
||||
!endif
|
||||
|
||||
!endif ; MSVC
|
||||
|
||||
; Common files
|
||||
|
||||
File "libfftw3-3.dll"
|
||||
File "libFLAC-8.dll"
|
||||
File "libiconv-2.dll"
|
||||
File "libmp3lame-0.dll"
|
||||
File "libogg-0.dll"
|
||||
File "libspeex-1.dll"
|
||||
File "libvorbis-0.dll"
|
||||
File "libvorbisenc-2.dll"
|
||||
File "libwinpthread-1.dll"
|
||||
File "libxml2-2.dll"
|
||||
!ifdef msvc && debug
|
||||
File "Qt6Concurrentd.dll"
|
||||
File "Qt6Cored.dll"
|
||||
File "Qt6Guid.dll"
|
||||
File "Qt6Networkd.dll"
|
||||
File "Qt6Sqld.dll"
|
||||
File "Qt6Widgetsd.dll"
|
||||
!else
|
||||
File "Qt6Concurrent.dll"
|
||||
File "Qt6Core.dll"
|
||||
File "Qt6Gui.dll"
|
||||
File "Qt6Network.dll"
|
||||
File "Qt6Sql.dll"
|
||||
File "Qt6Widgets.dll"
|
||||
!endif
|
||||
|
||||
; Register Strawberry with Default Programs
|
||||
Var /GLOBAL AppIcon
|
||||
@@ -403,43 +467,70 @@ Section "GIO modules" gio-modules
|
||||
SetOutPath "$INSTDIR\gio-modules"
|
||||
!ifdef mingw
|
||||
File "/oname=libgiognutls.dll" "gio-modules\libgiognutls.dll"
|
||||
File "/oname=libgioopenssl.dll" "gio-modules\libgioopenssl.dll"
|
||||
!endif
|
||||
!ifdef msvc
|
||||
File "/oname=giognutls.dll" "gio-modules\giognutls.dll"
|
||||
File "/oname=gioopenssl.dll" "gio-modules\gioopenssl.dll"
|
||||
!endif
|
||||
SectionEnd
|
||||
|
||||
Section "Qt Platform plugins" platforms
|
||||
SetOutPath "$INSTDIR\platforms"
|
||||
!ifdef msvc && debug
|
||||
File "/oname=qwindowsd.dll" "platforms\qwindowsd.dll"
|
||||
!else
|
||||
File "/oname=qwindows.dll" "platforms\qwindows.dll"
|
||||
!endif
|
||||
SectionEnd
|
||||
|
||||
Section "Qt styles" styles
|
||||
SetOutPath "$INSTDIR\styles"
|
||||
!ifdef msvc && debug
|
||||
File "/oname=qwindowsvistastyled.dll" "styles\qwindowsvistastyled.dll"
|
||||
!else
|
||||
File "/oname=qwindowsvistastyle.dll" "styles\qwindowsvistastyle.dll"
|
||||
!endif
|
||||
SectionEnd
|
||||
|
||||
Section "Qt TLS plugins" tls
|
||||
SetOutPath "$INSTDIR\tls"
|
||||
!ifdef msvc && debug
|
||||
File "/oname=qschannelbackendd.dll" "tls\qschannelbackendd.dll"
|
||||
File "/oname=qopensslbackendd.dll" "tls\qopensslbackendd.dll"
|
||||
!else
|
||||
File "/oname=qschannelbackend.dll" "tls\qschannelbackend.dll"
|
||||
File "/oname=qopensslbackend.dll" "tls\qopensslbackend.dll"
|
||||
!endif
|
||||
SectionEnd
|
||||
|
||||
Section "Qt SQL Drivers" sqldrivers
|
||||
SetOutPath "$INSTDIR\sqldrivers"
|
||||
!ifdef msvc && debug
|
||||
File "/oname=qsqlited.dll" "sqldrivers\qsqlited.dll"
|
||||
!else
|
||||
File "/oname=qsqlite.dll" "sqldrivers\qsqlite.dll"
|
||||
!endif
|
||||
SectionEnd
|
||||
|
||||
Section "Qt imageformats" imageformats
|
||||
SetOutPath "$INSTDIR\imageformats"
|
||||
!ifdef msvc && debug
|
||||
File "/oname=qgifd.dll" "imageformats\qgifd.dll"
|
||||
File "/oname=qicod.dll" "imageformats\qicod.dll"
|
||||
File "/oname=qjpegd.dll" "imageformats\qjpegd.dll"
|
||||
!else
|
||||
File "/oname=qgif.dll" "imageformats\qgif.dll"
|
||||
File "/oname=qico.dll" "imageformats\qico.dll"
|
||||
File "/oname=qjpeg.dll" "imageformats\qjpeg.dll"
|
||||
!endif
|
||||
SectionEnd
|
||||
|
||||
Section "Gstreamer plugins" gstreamer-plugins
|
||||
SetOutPath "$INSTDIR\gstreamer-plugins"
|
||||
|
||||
!ifdef mingw
|
||||
File "/oname=libgstaes.dll" "gstreamer-plugins\libgstaes.dll"
|
||||
File "/oname=libgstaiff.dll" "gstreamer-plugins\libgstaiff.dll"
|
||||
File "/oname=libgstapetag.dll" "gstreamer-plugins\libgstapetag.dll"
|
||||
File "/oname=libgstapp.dll" "gstreamer-plugins\libgstapp.dll"
|
||||
@@ -453,20 +544,25 @@ Section "Gstreamer plugins" gstreamer-plugins
|
||||
File "/oname=libgstaudioresample.dll" "gstreamer-plugins\libgstaudioresample.dll"
|
||||
File "/oname=libgstaudiotestsrc.dll" "gstreamer-plugins\libgstaudiotestsrc.dll"
|
||||
File "/oname=libgstautodetect.dll" "gstreamer-plugins\libgstautodetect.dll"
|
||||
File "/oname=libgstcdio.dll" "gstreamer-plugins\libgstcdio.dll"
|
||||
File "/oname=libgstbs2b.dll" "gstreamer-plugins\libgstbs2b.dll"
|
||||
File "/oname=libgstcoreelements.dll" "gstreamer-plugins\libgstcoreelements.dll"
|
||||
File "/oname=libgstdash.dll" "gstreamer-plugins\libgstdash.dll"
|
||||
File "/oname=libgstdirectsound.dll" "gstreamer-plugins\libgstdirectsound.dll"
|
||||
File "/oname=libgstequalizer.dll" "gstreamer-plugins\libgstequalizer.dll"
|
||||
File "/oname=libgstflac.dll" "gstreamer-plugins\libgstflac.dll"
|
||||
File "/oname=libgstfaac.dll" "gstreamer-plugins\libgstfaac.dll"
|
||||
File "/oname=libgstfaad.dll" "gstreamer-plugins\libgstfaad.dll"
|
||||
File "/oname=libgstfdkaac.dll" "gstreamer-plugins\libgstfdkaac.dll"
|
||||
File "/oname=libgstflac.dll" "gstreamer-plugins\libgstflac.dll"
|
||||
File "/oname=libgstgio.dll" "gstreamer-plugins\libgstgio.dll"
|
||||
File "/oname=libgsthls.dll" "gstreamer-plugins\libgsthls.dll"
|
||||
File "/oname=libgsticydemux.dll" "gstreamer-plugins\libgsticydemux.dll"
|
||||
File "/oname=libgstid3demux.dll" "gstreamer-plugins\libgstid3demux.dll"
|
||||
File "/oname=libgstid3tag.dll" "gstreamer-plugins\libgstid3tag.dll"
|
||||
File "/oname=libgstisomp4.dll" "gstreamer-plugins\libgstisomp4.dll"
|
||||
File "/oname=libgstlame.dll" "gstreamer-plugins\libgstlame.dll"
|
||||
File "/oname=libgstlibav.dll" "gstreamer-plugins\libgstlibav.dll"
|
||||
File "/oname=libgstmpg123.dll" "gstreamer-plugins\libgstmpg123.dll"
|
||||
File "/oname=libgstmusepack.dll" "gstreamer-plugins\libgstmusepack.dll"
|
||||
File "/oname=libgstogg.dll" "gstreamer-plugins\libgstogg.dll"
|
||||
File "/oname=libgstopenmpt.dll" "gstreamer-plugins\libgstopenmpt.dll"
|
||||
File "/oname=libgstopus.dll" "gstreamer-plugins\libgstopus.dll"
|
||||
@@ -481,17 +577,20 @@ Section "Gstreamer plugins" gstreamer-plugins
|
||||
File "/oname=libgstspeex.dll" "gstreamer-plugins\libgstspeex.dll"
|
||||
File "/oname=libgsttaglib.dll" "gstreamer-plugins\libgsttaglib.dll"
|
||||
File "/oname=libgsttcp.dll" "gstreamer-plugins\libgsttcp.dll"
|
||||
File "/oname=libgsttwolame.dll" "gstreamer-plugins\libgsttwolame.dll"
|
||||
File "/oname=libgsttypefindfunctions.dll" "gstreamer-plugins\libgsttypefindfunctions.dll"
|
||||
File "/oname=libgstudp.dll" "gstreamer-plugins\libgstudp.dll"
|
||||
File "/oname=libgstvolume.dll" "gstreamer-plugins\libgstvolume.dll"
|
||||
File "/oname=libgstvorbis.dll" "gstreamer-plugins\libgstvorbis.dll"
|
||||
File "/oname=libgstwasapi.dll" "gstreamer-plugins\libgstwasapi.dll"
|
||||
File "/oname=libgstwavenc.dll" "gstreamer-plugins\libgstwavenc.dll"
|
||||
File "/oname=libgstwavpack.dll" "gstreamer-plugins\libgstwavpack.dll"
|
||||
File "/oname=libgstwavparse.dll" "gstreamer-plugins\libgstwavparse.dll"
|
||||
File "/oname=libgstxingmux.dll" "gstreamer-plugins\libgstxingmux.dll"
|
||||
!endif ; MinGW
|
||||
|
||||
!ifdef msvc
|
||||
File "/oname=gstaes.dll" "gstreamer-plugins\gstaes.dll"
|
||||
File "/oname=gstaiff.dll" "gstreamer-plugins\gstaiff.dll"
|
||||
File "/oname=gstapetag.dll" "gstreamer-plugins\gstapetag.dll"
|
||||
File "/oname=gstapp.dll" "gstreamer-plugins\gstapp.dll"
|
||||
@@ -505,20 +604,30 @@ Section "Gstreamer plugins" gstreamer-plugins
|
||||
File "/oname=gstaudioresample.dll" "gstreamer-plugins\gstaudioresample.dll"
|
||||
File "/oname=gstaudiotestsrc.dll" "gstreamer-plugins\gstaudiotestsrc.dll"
|
||||
File "/oname=gstautodetect.dll" "gstreamer-plugins\gstautodetect.dll"
|
||||
File "/oname=gstbs2b.dll" "gstreamer-plugins\gstbs2b.dll"
|
||||
File "/oname=gstcoreelements.dll" "gstreamer-plugins\gstcoreelements.dll"
|
||||
File "/oname=gstdash.dll" "gstreamer-plugins\gstdash.dll"
|
||||
File "/oname=gstdirectsound.dll" "gstreamer-plugins\gstdirectsound.dll"
|
||||
File "/oname=gstequalizer.dll" "gstreamer-plugins\gstequalizer.dll"
|
||||
File "/oname=gstfaac.dll" "gstreamer-plugins\gstfaac.dll"
|
||||
File "/oname=gstfaad.dll" "gstreamer-plugins\gstfaad.dll"
|
||||
File "/oname=gstfdkaac.dll" "gstreamer-plugins\gstfdkaac.dll"
|
||||
File "/oname=gstflac.dll" "gstreamer-plugins\gstflac.dll"
|
||||
File "/oname=gstgio.dll" "gstreamer-plugins\gstgio.dll"
|
||||
File "/oname=gsthls.dll" "gstreamer-plugins\gsthls.dll"
|
||||
File "/oname=gsticydemux.dll" "gstreamer-plugins\gsticydemux.dll"
|
||||
File "/oname=gstid3demux.dll" "gstreamer-plugins\gstid3demux.dll"
|
||||
File "/oname=gstid3tag.dll" "gstreamer-plugins\gstid3tag.dll"
|
||||
File "/oname=gstisomp4.dll" "gstreamer-plugins\gstisomp4.dll"
|
||||
File "/oname=gstlame.dll" "gstreamer-plugins\gstlame.dll"
|
||||
File "/oname=gstlibav.dll" "gstreamer-plugins\gstlibav.dll"
|
||||
File "/oname=gstmpg123.dll" "gstreamer-plugins\gstmpg123.dll"
|
||||
File "/oname=gstmusepack.dll" "gstreamer-plugins\gstmusepack.dll"
|
||||
File "/oname=gstogg.dll" "gstreamer-plugins\gstogg.dll"
|
||||
File "/oname=gstopenmpt.dll" "gstreamer-plugins\gstopenmpt.dll"
|
||||
File "/oname=gstopus.dll" "gstreamer-plugins\gstopus.dll"
|
||||
File "/oname=gstopusparse.dll" "gstreamer-plugins\gstopusparse.dll"
|
||||
File "/oname=gstpbtypes.dll" "gstreamer-plugins\gstpbtypes.dll"
|
||||
File "/oname=gstplayback.dll" "gstreamer-plugins\gstplayback.dll"
|
||||
File "/oname=gstreplaygain.dll" "gstreamer-plugins\gstreplaygain.dll"
|
||||
File "/oname=gstrtp.dll" "gstreamer-plugins\gstrtp.dll"
|
||||
@@ -526,13 +635,15 @@ Section "Gstreamer plugins" gstreamer-plugins
|
||||
File "/oname=gstsoup.dll" "gstreamer-plugins\gstsoup.dll"
|
||||
File "/oname=gstspectrum.dll" "gstreamer-plugins\gstspectrum.dll"
|
||||
File "/oname=gstspeex.dll" "gstreamer-plugins\gstspeex.dll"
|
||||
File "/oname=gsttaglib.dll" "gstreamer-plugins\gsttaglib.dll"
|
||||
File "/oname=gsttcp.dll" "gstreamer-plugins\gsttcp.dll"
|
||||
File "/oname=gsttwolame.dll" "gstreamer-plugins\gsttwolame.dll"
|
||||
File "/oname=gsttypefindfunctions.dll" "gstreamer-plugins\gsttypefindfunctions.dll"
|
||||
File "/oname=gstudp.dll" "gstreamer-plugins\gstudp.dll"
|
||||
File "/oname=gstvolume.dll" "gstreamer-plugins\gstvolume.dll"
|
||||
File "/oname=gstvorbis.dll" "gstreamer-plugins\gstvorbis.dll"
|
||||
File "/oname=gstwasapi.dll" "gstreamer-plugins\gstwasapi.dll"
|
||||
File "/oname=gstwasapi2.dll" "gstreamer-plugins\gstwasapi2.dll"
|
||||
File "/oname=gstwavenc.dll" "gstreamer-plugins\gstwavenc.dll"
|
||||
File "/oname=gstwavpack.dll" "gstreamer-plugins\gstwavpack.dll"
|
||||
File "/oname=gstwavparse.dll" "gstreamer-plugins\gstwavparse.dll"
|
||||
File "/oname=gstxingmux.dll" "gstreamer-plugins\gstxingmux.dll"
|
||||
@@ -578,9 +689,7 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\strawberry.exe"
|
||||
Delete "$INSTDIR\strawberry-tagreader.exe"
|
||||
Delete "$INSTDIR\strawberry.ico"
|
||||
!ifdef mingw
|
||||
Delete "$INSTDIR\sqlite3.exe"
|
||||
!endif
|
||||
Delete "$INSTDIR\gst-launch-1.0.exe"
|
||||
Delete "$INSTDIR\gst-discoverer-1.0.exe"
|
||||
|
||||
@@ -604,22 +713,27 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\avfilter-8.dll"
|
||||
Delete "$INSTDIR\avformat-59.dll"
|
||||
Delete "$INSTDIR\avutil-57.dll"
|
||||
Delete "$INSTDIR\libFLAC-8.dll"
|
||||
Delete "$INSTDIR\libbrotlicommon.dll"
|
||||
Delete "$INSTDIR\libbrotlidec.dll"
|
||||
Delete "$INSTDIR\libbrotlienc.dll"
|
||||
Delete "$INSTDIR\libbs2b-0.dll"
|
||||
Delete "$INSTDIR\libbz2.dll"
|
||||
Delete "$INSTDIR\libcdio-19.dll"
|
||||
Delete "$INSTDIR\libchromaprint.dll"
|
||||
Delete "$INSTDIR\libdl.dll"
|
||||
Delete "$INSTDIR\libfaac-0.dll"
|
||||
Delete "$INSTDIR\libfaad-2.dll"
|
||||
Delete "$INSTDIR\libfdk-aac-2.dll"
|
||||
Delete "$INSTDIR\libffi-8.dll"
|
||||
Delete "$INSTDIR\libfreetype-6.dll"
|
||||
Delete "$INSTDIR\libgcrypt-20.dll"
|
||||
Delete "$INSTDIR\libgio-2.0-0.dll"
|
||||
Delete "$INSTDIR\libglib-2.0-0.dll"
|
||||
Delete "$INSTDIR\libgmodule-2.0-0.dll"
|
||||
Delete "$INSTDIR\libgmp-10.dll"
|
||||
Delete "$INSTDIR\libgnutls-30.dll"
|
||||
Delete "$INSTDIR\libgobject-2.0-0.dll"
|
||||
Delete "$INSTDIR\libgpg-error-0.dll"
|
||||
Delete "$INSTDIR\libgstadaptivedemux-1.0-0.dll"
|
||||
Delete "$INSTDIR\libgstapp-1.0-0.dll"
|
||||
Delete "$INSTDIR\libgstaudio-1.0-0.dll"
|
||||
@@ -639,30 +753,39 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\libgstvideo-1.0-0.dll"
|
||||
Delete "$INSTDIR\libharfbuzz-0.dll"
|
||||
Delete "$INSTDIR\libhogweed-6.dll"
|
||||
Delete "$INSTDIR\libiconv-2.dll"
|
||||
Delete "$INSTDIR\libidn2-0.dll"
|
||||
Delete "$INSTDIR\libintl-8.dll"
|
||||
Delete "$INSTDIR\libjpeg-9.dll"
|
||||
Delete "$INSTDIR\liblzma-5.dll"
|
||||
Delete "$INSTDIR\libmp3lame-0.dll"
|
||||
Delete "$INSTDIR\libmpcdec.dll"
|
||||
Delete "$INSTDIR\libmpg123-0.dll"
|
||||
Delete "$INSTDIR\libnettle-8.dll"
|
||||
Delete "$INSTDIR\libnghttp2.dll"
|
||||
Delete "$INSTDIR\libogg-0.dll"
|
||||
Delete "$INSTDIR\libopenmpt-0.dll"
|
||||
Delete "$INSTDIR\libopus-0.dll"
|
||||
Delete "$INSTDIR\liborc-0.4-0.dll"
|
||||
Delete "$INSTDIR\libpcre-1.dll"
|
||||
Delete "$INSTDIR\libpcre2-16-0.dll"
|
||||
Delete "$INSTDIR\libpng16-16.dll"
|
||||
Delete "$INSTDIR\libprotobuf-30.dll"
|
||||
Delete "$INSTDIR\libprotobuf-32.dll"
|
||||
Delete "$INSTDIR\libpsl-5.dll"
|
||||
Delete "$INSTDIR\libqtsparkle-qt6.dll"
|
||||
Delete "$INSTDIR\libsoup-3.0-0.dll"
|
||||
Delete "$INSTDIR\libspeex-1.dll"
|
||||
Delete "$INSTDIR\libsqlite3-0.dll"
|
||||
Delete "$INSTDIR\libssp-0.dll"
|
||||
Delete "$INSTDIR\libstdc++-6.dll"
|
||||
Delete "$INSTDIR\libtag.dll"
|
||||
Delete "$INSTDIR\libtasn1-6.dll"
|
||||
Delete "$INSTDIR\libtwolame-0.dll"
|
||||
Delete "$INSTDIR\libunistring-2.dll"
|
||||
Delete "$INSTDIR\libvorbis-0.dll"
|
||||
Delete "$INSTDIR\libvorbisenc-2.dll"
|
||||
Delete "$INSTDIR\libvorbisfile-3.dll"
|
||||
Delete "$INSTDIR\libwavpack-1.dll"
|
||||
Delete "$INSTDIR\libwinpthread-1.dll"
|
||||
Delete "$INSTDIR\libxml2-2.dll"
|
||||
Delete "$INSTDIR\libzstd.dll"
|
||||
Delete "$INSTDIR\postproc-56.dll"
|
||||
Delete "$INSTDIR\swresample-4.dll"
|
||||
@@ -674,8 +797,13 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\libexpat-1.dll"
|
||||
Delete "$INSTDIR\libmman.dll"
|
||||
Delete "$INSTDIR\libmpfr-6.dll"
|
||||
Delete "$INSTDIR\libpcre2-8d.dll"
|
||||
Delete "$INSTDIR\libpcre2-16d.dll"
|
||||
Delete "$INSTDIR\libreadline8.dll"
|
||||
Delete "$INSTDIR\libtermcap.dll"
|
||||
!else
|
||||
Delete "$INSTDIR\libpcre2-8.dll"
|
||||
Delete "$INSTDIR\libpcre2-16.dll"
|
||||
!endif
|
||||
|
||||
!endif ; MinGW
|
||||
@@ -685,20 +813,25 @@ Section "Uninstall"
|
||||
!ifdef msvc
|
||||
|
||||
!ifdef arch_x86
|
||||
Delete "$INSTDIR\libcrypto-1_1.dll"
|
||||
Delete "$INSTDIR\libssl-1_1.dll"
|
||||
Delete "$INSTDIR\libcrypto-3.dll"
|
||||
Delete "$INSTDIR\libssl-3.dll"
|
||||
!endif
|
||||
!ifdef arch_x64
|
||||
Delete "$INSTDIR\libcrypto-1_1-x64.dll"
|
||||
Delete "$INSTDIR\libssl-1_1-x64.dll"
|
||||
Delete "$INSTDIR\libcrypto-3-x64.dll"
|
||||
Delete "$INSTDIR\libssl-3-x64.dll"
|
||||
!endif
|
||||
|
||||
Delete "$INSTDIR\FLAC.dll"
|
||||
Delete "$INSTDIR\avcodec-58.dll"
|
||||
Delete "$INSTDIR\avfilter-7.dll"
|
||||
Delete "$INSTDIR\avformat-58.dll"
|
||||
Delete "$INSTDIR\avresample-4.dll"
|
||||
Delete "$INSTDIR\avutil-56.dll"
|
||||
Delete "$INSTDIR\bz2.dll"
|
||||
Delete "$INSTDIR\brotlicommon.dll"
|
||||
Delete "$INSTDIR\brotlidec.dll"
|
||||
Delete "$INSTDIR\chromaprint.dll"
|
||||
Delete "$INSTDIR\faad.dll"
|
||||
Delete "$INSTDIR\fdk-aac.dll"
|
||||
Delete "$INSTDIR\ffi-7.dll"
|
||||
Delete "$INSTDIR\gio-2.0-0.dll"
|
||||
Delete "$INSTDIR\glib-2.0-0.dll"
|
||||
@@ -708,6 +841,7 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\gstadaptivedemux-1.0-0.dll"
|
||||
Delete "$INSTDIR\gstapp-1.0-0.dll"
|
||||
Delete "$INSTDIR\gstaudio-1.0-0.dll"
|
||||
Delete "$INSTDIR\gstbadaudio-1.0-0.dll"
|
||||
Delete "$INSTDIR\gstbase-1.0-0.dll"
|
||||
Delete "$INSTDIR\gstfft-1.0-0.dll"
|
||||
Delete "$INSTDIR\gstisoff-1.0-0.dll"
|
||||
@@ -721,58 +855,104 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\gsttag-1.0-0.dll"
|
||||
Delete "$INSTDIR\gsturidownloader-1.0-0.dll"
|
||||
Delete "$INSTDIR\gstvideo-1.0-0.dll"
|
||||
Delete "$INSTDIR\gstwinrt-1.0-0.dll"
|
||||
Delete "$INSTDIR\intl-8.dll"
|
||||
Delete "$INSTDIR\libprotobuf.dll"
|
||||
Delete "$INSTDIR\opus-0.dll"
|
||||
Delete "$INSTDIR\libbs2b.dll"
|
||||
Delete "$INSTDIR\libfaac_dll.dll"
|
||||
Delete "$INSTDIR\libiconv.dll"
|
||||
Delete "$INSTDIR\liblzma.dll"
|
||||
Delete "$INSTDIR\libmp3lame.dll"
|
||||
Delete "$INSTDIR\libopenmpt.dll"
|
||||
Delete "$INSTDIR\libspeex.dll"
|
||||
Delete "$INSTDIR\mpcdec.dll"
|
||||
Delete "$INSTDIR\mpg123.dll"
|
||||
Delete "$INSTDIR\ogg.dll"
|
||||
Delete "$INSTDIR\opus.dll"
|
||||
Delete "$INSTDIR\orc-0.4-0.dll"
|
||||
Delete "$INSTDIR\postproc-55.dll"
|
||||
Delete "$INSTDIR\psl-5.dll"
|
||||
Delete "$INSTDIR\qtsparkle-qt6.dll"
|
||||
Delete "$INSTDIR\soup-2.4-1.dll"
|
||||
Delete "$INSTDIR\sqlite3-0.dll"
|
||||
Delete "$INSTDIR\sqlite3.dll"
|
||||
Delete "$INSTDIR\swresample-3.dll"
|
||||
Delete "$INSTDIR\swscale-5.dll"
|
||||
Delete "$INSTDIR\tag.dll"
|
||||
Delete "$INSTDIR\z-1.dll"
|
||||
Delete "$INSTDIR\vorbis.dll"
|
||||
Delete "$INSTDIR\vorbisfile.dll"
|
||||
Delete "$INSTDIR\wavpackdll.dll"
|
||||
|
||||
!ifdef release
|
||||
Delete "$INSTDIR\libpng16.dll"
|
||||
Delete "$INSTDIR\libprotobuf.dll"
|
||||
Delete "$INSTDIR\libxml2.dll"
|
||||
Delete "$INSTDIR\pcre2-8.dll"
|
||||
Delete "$INSTDIR\pcre2-16.dll"
|
||||
Delete "$INSTDIR\twolame.dll"
|
||||
Delete "$INSTDIR\zlib.dll"
|
||||
!endif
|
||||
!ifdef debug
|
||||
Delete "$INSTDIR\libpng16d.dll"
|
||||
Delete "$INSTDIR\libprotobufd.dll"
|
||||
Delete "$INSTDIR\libxml2d.dll"
|
||||
Delete "$INSTDIR\pcre2-8d.dll"
|
||||
Delete "$INSTDIR\pcre2-16d.dll"
|
||||
Delete "$INSTDIR\twolamed.dll"
|
||||
Delete "$INSTDIR\zlibd.dll"
|
||||
!endif
|
||||
|
||||
!endif ; MSVC
|
||||
|
||||
; Common files
|
||||
|
||||
Delete "$INSTDIR\libfftw3-3.dll"
|
||||
Delete "$INSTDIR\libFLAC-8.dll"
|
||||
Delete "$INSTDIR\libiconv-2.dll"
|
||||
Delete "$INSTDIR\libmp3lame-0.dll"
|
||||
Delete "$INSTDIR\libogg-0.dll"
|
||||
Delete "$INSTDIR\libspeex-1.dll"
|
||||
Delete "$INSTDIR\libvorbis-0.dll"
|
||||
Delete "$INSTDIR\libvorbisenc-2.dll"
|
||||
Delete "$INSTDIR\libwinpthread-1.dll"
|
||||
Delete "$INSTDIR\libxml2-2.dll"
|
||||
!ifdef msvc && debug
|
||||
Delete "$INSTDIR\Qt6Concurrentd.dll"
|
||||
Delete "$INSTDIR\Qt6Cored.dll"
|
||||
Delete "$INSTDIR\Qt6Guid.dll"
|
||||
Delete "$INSTDIR\Qt6Networkd.dll"
|
||||
Delete "$INSTDIR\Qt6Sqld.dll"
|
||||
Delete "$INSTDIR\Qt6Widgetsd.dll"
|
||||
!else
|
||||
Delete "$INSTDIR\Qt6Concurrent.dll"
|
||||
Delete "$INSTDIR\Qt6Core.dll"
|
||||
Delete "$INSTDIR\Qt6Gui.dll"
|
||||
Delete "$INSTDIR\Qt6Network.dll"
|
||||
Delete "$INSTDIR\Qt6Sql.dll"
|
||||
Delete "$INSTDIR\Qt6Widgets.dll"
|
||||
!endif
|
||||
|
||||
!ifdef mingw
|
||||
Delete "$INSTDIR\gio-modules\libgiognutls.dll"
|
||||
Delete "$INSTDIR\gio-modules\libgioopenssl.dll"
|
||||
!endif
|
||||
!ifdef msvc
|
||||
Delete "$INSTDIR\gio-modules\giognutls.dll"
|
||||
Delete "$INSTDIR\gio-modules\gioopenssl.dll"
|
||||
!endif
|
||||
|
||||
!ifdef msvc && debug
|
||||
Delete "$INSTDIR\platforms\qwindowsd.dll"
|
||||
Delete "$INSTDIR\styles\qwindowsvistastyled.dll"
|
||||
Delete "$INSTDIR\tls\qschannelbackendd.dll"
|
||||
Delete "$INSTDIR\tls\qopensslbackendd.dll"
|
||||
Delete "$INSTDIR\sqldrivers\qsqlited.dll"
|
||||
Delete "$INSTDIR\imageformats\qgifd.dll"
|
||||
Delete "$INSTDIR\imageformats\qicod.dll"
|
||||
Delete "$INSTDIR\imageformats\qjpegd.dll"
|
||||
!else
|
||||
Delete "$INSTDIR\platforms\qwindows.dll"
|
||||
Delete "$INSTDIR\styles\qwindowsvistastyle.dll"
|
||||
Delete "$INSTDIR\tls\qschannelbackend.dll"
|
||||
Delete "$INSTDIR\tls\qopensslbackend.dll"
|
||||
Delete "$INSTDIR\sqldrivers\qsqlite.dll"
|
||||
|
||||
Delete "$INSTDIR\imageformats\qgif.dll"
|
||||
Delete "$INSTDIR\imageformats\qico.dll"
|
||||
Delete "$INSTDIR\imageformats\qjpeg.dll"
|
||||
!endif
|
||||
|
||||
; MinGW GStreamer plugins
|
||||
|
||||
!ifdef mingw
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstaes.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstaiff.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstapetag.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstapp.dll"
|
||||
@@ -786,20 +966,25 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstaudioresample.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstaudiotestsrc.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstautodetect.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstcdio.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstbs2b.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstcoreelements.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstdash.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstdirectsound.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstequalizer.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstflac.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstfaac.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstfaad.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstfdkaac.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstflac.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstgio.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgsthls.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgsticydemux.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstid3demux.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstid3tag.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstisomp4.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstlame.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstlibav.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstmpg123.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstmusepack.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstogg.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstopenmpt.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstopus.dll"
|
||||
@@ -814,11 +999,13 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstspeex.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgsttaglib.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgsttcp.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgsttwolame.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgsttypefindfunctions.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstudp.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstvolume.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstvorbis.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstwasapi.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstwavenc.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstwavpack.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstwavparse.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\libgstxingmux.dll"
|
||||
@@ -827,6 +1014,7 @@ Section "Uninstall"
|
||||
; MSVC GStreamer plugins
|
||||
|
||||
!ifdef msvc
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstaes.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstaiff.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstapetag.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstapp.dll"
|
||||
@@ -840,20 +1028,30 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstaudioresample.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstaudiotestsrc.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstautodetect.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstbs2b.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstcoreelements.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstdash.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstdirectsound.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstequalizer.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstfaac.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstfaad.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstfdkaac.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstflac.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstgio.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gsthls.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gsticydemux.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstid3demux.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstid3tag.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstisomp4.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstlame.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstlibav.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstmpg123.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstmusepack.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstogg.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstopenmpt.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstopus.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstopusparse.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstpbtypes.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstplayback.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstreplaygain.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstrtp.dll"
|
||||
@@ -861,13 +1059,15 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstsoup.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstspectrum.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstspeex.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gsttaglib.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gsttcp.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gsttwolame.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gsttypefindfunctions.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstudp.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstvolume.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstvorbis.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstwasapi.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstwasapi2.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstwavenc.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstwavpack.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstwavparse.dll"
|
||||
Delete "$INSTDIR\gstreamer-plugins\gstxingmux.dll"
|
||||
|
||||
@@ -50,7 +50,10 @@ enum {
|
||||
} // namespace
|
||||
|
||||
#define gst_fastspectrum_parent_class parent_class
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
G_DEFINE_TYPE(GstFastSpectrum, gst_fastspectrum, GST_TYPE_AUDIO_FILTER)
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
static void gst_fastspectrum_finalize(GObject *object);
|
||||
static void gst_fastspectrum_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
|
||||
|
||||
@@ -61,7 +61,7 @@ static const char *kMessageHandlerMagic = "__logging_message__";
|
||||
static const size_t kMessageHandlerMagicLength = strlen(kMessageHandlerMagic);
|
||||
static QtMessageHandler sOriginalMessageHandler = nullptr;
|
||||
|
||||
template <class T>
|
||||
template<class T>
|
||||
static T CreateLogger(Level level, const QString &class_name, int line, const char *category);
|
||||
|
||||
void GLog(const char *domain, int level, const char *message, void*) {
|
||||
@@ -88,7 +88,7 @@ void GLog(const char *domain, int level, const char *message, void*) {
|
||||
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template<class T>
|
||||
class DebugBase : public QDebug {
|
||||
public:
|
||||
DebugBase() : QDebug(sNullDevice) {}
|
||||
@@ -314,11 +314,11 @@ QString LinuxDemangle(const QString &symbol) {
|
||||
QString DarwinDemangle(const QString &symbol);
|
||||
QString DarwinDemangle(const QString &symbol) {
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QStringList split = symbol.split(' ', Qt::SkipEmptyParts);
|
||||
#else
|
||||
# else
|
||||
QStringList split = symbol.split(' ', QString::SkipEmptyParts);
|
||||
#endif
|
||||
# endif
|
||||
QString mangled_function = split[3];
|
||||
return CXXDemangle(mangled_function);
|
||||
|
||||
@@ -379,7 +379,7 @@ QDebug CreateLoggerError(int line, const char *pretty_function, const char *cate
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
QString print_duration(T duration, const std::string &unit) {
|
||||
return QString("%1%2").arg(duration.count()).arg(unit.c_str());
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ void _MessageHandlerBase::DeviceReadyRead() {
|
||||
void _MessageHandlerBase::WriteMessage(const QByteArray &data) {
|
||||
|
||||
QDataStream s(device_);
|
||||
s << quint32(data.length());
|
||||
s << static_cast<quint32>(data.length());
|
||||
s.writeRawData(data.data(), static_cast<int>(data.length()));
|
||||
|
||||
// Sorry.
|
||||
|
||||
@@ -79,7 +79,7 @@ class _MessageHandlerBase : public QObject {
|
||||
|
||||
// Reads and writes uint32 length encoded MessageType messages to a socket.
|
||||
// You should subclass this and implement the MessageArrived(MessageType) method.
|
||||
template <typename MT>
|
||||
template<typename MT>
|
||||
class AbstractMessageHandler : public _MessageHandlerBase {
|
||||
public:
|
||||
AbstractMessageHandler(QIODevice *device, QObject *parent);
|
||||
@@ -115,11 +115,11 @@ class AbstractMessageHandler : public _MessageHandlerBase {
|
||||
QMap<int, ReplyType*> pending_replies_;
|
||||
};
|
||||
|
||||
template <typename MT>
|
||||
template<typename MT>
|
||||
AbstractMessageHandler<MT>::AbstractMessageHandler(QIODevice *device, QObject *parent)
|
||||
: _MessageHandlerBase(device, parent) {}
|
||||
|
||||
template <typename MT>
|
||||
template<typename MT>
|
||||
void AbstractMessageHandler<MT>::SendMessage(const MessageType &message) {
|
||||
Q_ASSERT(QThread::currentThread() == thread());
|
||||
|
||||
@@ -127,7 +127,7 @@ void AbstractMessageHandler<MT>::SendMessage(const MessageType &message) {
|
||||
WriteMessage(QByteArray(data.data(), data.size()));
|
||||
}
|
||||
|
||||
template <typename MT>
|
||||
template<typename MT>
|
||||
void AbstractMessageHandler<MT>::SendMessageAsync(const MessageType &message) {
|
||||
std::string data = message.SerializeAsString();
|
||||
QMetaObject::invokeMethod(this, "WriteMessage", Qt::QueuedConnection, Q_ARG(QByteArray, QByteArray(data.data(), data.size())));
|
||||
|
||||
@@ -56,7 +56,7 @@ class _MessageReplyBase : public QObject {
|
||||
};
|
||||
|
||||
// A reply future class that is returned immediately for requests that will occur in the background. Similar to QNetworkReply.
|
||||
template <typename MessageType>
|
||||
template<typename MessageType>
|
||||
class MessageReply : public _MessageReplyBase {
|
||||
public:
|
||||
explicit MessageReply(const MessageType &request_message, QObject *parent = nullptr);
|
||||
|
||||
@@ -70,7 +70,7 @@ class _WorkerPoolBase : public QObject {
|
||||
// A local socket server is started for each process, and the address is passed to the process as argv[1].
|
||||
// The process is expected to connect back to the socket server, and when it does a HandlerType is created for it.
|
||||
// Instances of HandlerType are created in the WorkerPool's thread.
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
class WorkerPool : public _WorkerPoolBase {
|
||||
public:
|
||||
explicit WorkerPool(QObject *parent = nullptr);
|
||||
@@ -121,9 +121,9 @@ class WorkerPool : public _WorkerPoolBase {
|
||||
// Must only ever be called on my thread.
|
||||
void StartOneWorker(Worker *worker);
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
Worker *FindWorker(T Worker::*member, T value) {
|
||||
for (typename QList<Worker>::iterator it = workers_.begin() ; it != workers_.end() ; ++it) {
|
||||
for (typename QList<Worker>::iterator it = workers_.begin(); it != workers_.end(); ++it) {
|
||||
if ((*it).*member == value) {
|
||||
return &(*it);
|
||||
}
|
||||
@@ -131,7 +131,7 @@ class WorkerPool : public _WorkerPoolBase {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
void DeleteQObjectPointerLater(T **p) {
|
||||
if (*p) {
|
||||
(*p)->deleteLater();
|
||||
@@ -158,15 +158,15 @@ class WorkerPool : public _WorkerPoolBase {
|
||||
QAtomicInt next_id_;
|
||||
|
||||
QMutex message_queue_mutex_;
|
||||
QQueue<ReplyType*> message_queue_;
|
||||
QQueue<ReplyType *> message_queue_;
|
||||
};
|
||||
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
WorkerPool<HandlerType>::WorkerPool(QObject *parent)
|
||||
: _WorkerPoolBase(parent),
|
||||
next_worker_(0),
|
||||
next_id_(0) {
|
||||
: _WorkerPoolBase(parent),
|
||||
next_worker_(0),
|
||||
next_id_(0) {
|
||||
|
||||
worker_count_ = qBound(1, QThread::idealThreadCount() / 2, 4);
|
||||
local_server_name_ = qApp->applicationName().toLower();
|
||||
@@ -177,7 +177,7 @@ WorkerPool<HandlerType>::WorkerPool(QObject *parent)
|
||||
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
WorkerPool<HandlerType>::~WorkerPool() {
|
||||
|
||||
for (const Worker &worker : workers_) {
|
||||
@@ -208,30 +208,30 @@ WorkerPool<HandlerType>::~WorkerPool() {
|
||||
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
void WorkerPool<HandlerType>::SetWorkerCount(const int count) {
|
||||
Q_ASSERT(workers_.isEmpty());
|
||||
worker_count_ = count;
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
void WorkerPool<HandlerType>::SetLocalServerName(const QString &local_server_name) {
|
||||
Q_ASSERT(workers_.isEmpty());
|
||||
local_server_name_ = local_server_name;
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
void WorkerPool<HandlerType>::SetExecutableName(const QString &executable_name) {
|
||||
Q_ASSERT(workers_.isEmpty());
|
||||
executable_name_ = executable_name;
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
void WorkerPool<HandlerType>::Start() {
|
||||
QMetaObject::invokeMethod(this, "DoStart");
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
void WorkerPool<HandlerType>::DoStart() {
|
||||
|
||||
Q_ASSERT(workers_.isEmpty());
|
||||
@@ -243,6 +243,10 @@ void WorkerPool<HandlerType>::DoStart() {
|
||||
|
||||
QStringList search_path;
|
||||
search_path << QCoreApplication::applicationDirPath();
|
||||
#if defined(Q_OS_UNIX)
|
||||
search_path << "/usr/libexec";
|
||||
search_path << "/usr/local/libexec";
|
||||
#endif
|
||||
#if defined(Q_OS_MACOS) && defined(USE_BUNDLE)
|
||||
search_path << QCoreApplication::applicationDirPath() + "/" + USE_BUNDLE_DIR;
|
||||
#endif
|
||||
@@ -270,7 +274,7 @@ void WorkerPool<HandlerType>::DoStart() {
|
||||
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
void WorkerPool<HandlerType>::StartOneWorker(Worker *worker) {
|
||||
|
||||
Q_ASSERT(QThread::currentThread() == thread());
|
||||
@@ -311,10 +315,9 @@ void WorkerPool<HandlerType>::StartOneWorker(Worker *worker) {
|
||||
#endif
|
||||
|
||||
worker->process_->start(executable_path_, QStringList() << worker->local_server_->fullServerName());
|
||||
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
void WorkerPool<HandlerType>::NewConnection() {
|
||||
|
||||
Q_ASSERT(QThread::currentThread() == thread());
|
||||
@@ -342,7 +345,7 @@ void WorkerPool<HandlerType>::NewConnection() {
|
||||
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
void WorkerPool<HandlerType>::ProcessError(QProcess::ProcessError error) {
|
||||
|
||||
Q_ASSERT(QThread::currentThread() == thread());
|
||||
@@ -370,7 +373,7 @@ void WorkerPool<HandlerType>::ProcessError(QProcess::ProcessError error) {
|
||||
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
void WorkerPool<HandlerType>::ProcessReadyReadStandardOutput() {
|
||||
|
||||
Q_ASSERT(QThread::currentThread() == thread());
|
||||
@@ -383,7 +386,7 @@ void WorkerPool<HandlerType>::ProcessReadyReadStandardOutput() {
|
||||
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
void WorkerPool<HandlerType>::ProcessReadyReadStandardError() {
|
||||
|
||||
Q_ASSERT(QThread::currentThread() == thread());
|
||||
@@ -426,7 +429,7 @@ WorkerPool<HandlerType>::SendMessageWithReply(MessageType *message) {
|
||||
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
void WorkerPool<HandlerType>::SendQueuedMessages() {
|
||||
|
||||
QMutexLocker l(&message_queue_mutex_);
|
||||
@@ -448,7 +451,7 @@ void WorkerPool<HandlerType>::SendQueuedMessages() {
|
||||
|
||||
}
|
||||
|
||||
template <typename HandlerType>
|
||||
template<typename HandlerType>
|
||||
HandlerType *WorkerPool<HandlerType>::NextHandler() const {
|
||||
|
||||
for (int i = 0; i < workers_.count(); ++i) {
|
||||
|
||||
@@ -25,3 +25,27 @@ const std::string TagReaderBase::kEmbeddedCover = "(embedded)";
|
||||
|
||||
TagReaderBase::TagReaderBase() = default;
|
||||
TagReaderBase::~TagReaderBase() = default;
|
||||
|
||||
float TagReaderBase::ConvertPOPMRating(const int POPM_rating) {
|
||||
|
||||
if (POPM_rating < 0x01) return 0.0F;
|
||||
else if (POPM_rating < 0x40) return 0.20F;
|
||||
else if (POPM_rating < 0x80) return 0.40F;
|
||||
else if (POPM_rating < 0xC0) return 0.60F;
|
||||
else if (POPM_rating < 0xFC) return 0.80F;
|
||||
|
||||
return 1.0F;
|
||||
|
||||
}
|
||||
|
||||
int TagReaderBase::ConvertToPOPMRating(const float rating) {
|
||||
|
||||
if (rating < 0.20) return 0x00;
|
||||
else if (rating < 0.40) return 0x01;
|
||||
else if (rating < 0.60) return 0x40;
|
||||
else if (rating < 0.80) return 0x80;
|
||||
else if (rating < 1.0) return 0xC0;
|
||||
|
||||
return 0xFF;
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,9 @@ class TagReaderBase {
|
||||
virtual bool SaveSongPlaycountToFile(const QString &filename, const spb::tagreader::SongMetadata &song) const = 0;
|
||||
virtual bool SaveSongRatingToFile(const QString &filename, const spb::tagreader::SongMetadata &song) const = 0;
|
||||
|
||||
static float ConvertPOPMRating(const int POPM_rating);
|
||||
static int ConvertToPOPMRating(const float rating);
|
||||
|
||||
protected:
|
||||
static const std::string kEmbeddedCover;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <taglib/taglib.h>
|
||||
@@ -113,6 +114,7 @@ class TagLibFileRefFactory : public FileRefFactory {
|
||||
return new TagLib::FileRef(QFile::encodeName(filename).constData());
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(TagLibFileRefFactory)
|
||||
};
|
||||
@@ -130,11 +132,11 @@ TagLib::String QStringToTaglibString(const QString &s) {
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
const char *kMP4_OriginalYear_ID = "----:com.apple.iTunes:ORIGINAL YEAR";
|
||||
const char *kMP4_OriginalYear_ID = "----:com.apple.iTunes:ORIGINAL YEAR";
|
||||
const char *kMP4_FMPS_Playcount_ID = "----:com.apple.iTunes:FMPS_Playcount";
|
||||
const char *kMP4_FMPS_Rating_ID = "----:com.apple.iTunes:FMPS_Rating";
|
||||
const char *kASF_OriginalDate_ID = "WM/OriginalReleaseTime";
|
||||
const char *kASF_OriginalYear_ID = "WM/OriginalReleaseYear";
|
||||
const char *kMP4_FMPS_Rating_ID = "----:com.apple.iTunes:FMPS_Rating";
|
||||
const char *kASF_OriginalDate_ID = "WM/OriginalReleaseTime";
|
||||
const char *kASF_OriginalYear_ID = "WM/OriginalReleaseYear";
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -194,12 +196,17 @@ void TagReaderTagLib::ReadFile(const QString &filename, spb::tagreader::SongMeta
|
||||
song->set_basefilename(DataCommaSizeFromQString(fileinfo.fileName()));
|
||||
song->set_url(url.constData(), url.size());
|
||||
song->set_filesize(fileinfo.size());
|
||||
song->set_mtime(fileinfo.lastModified().isValid() ? fileinfo.lastModified().toSecsSinceEpoch() : 0);
|
||||
song->set_mtime(fileinfo.lastModified().isValid() ? std::max(fileinfo.lastModified().toSecsSinceEpoch(), 0LL) : 0LL);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
song->set_ctime(fileinfo.birthTime().isValid() ? fileinfo.birthTime().toSecsSinceEpoch() : fileinfo.lastModified().isValid() ? fileinfo.lastModified().toSecsSinceEpoch() : 0);
|
||||
song->set_ctime(fileinfo.birthTime().isValid() ? std::max(fileinfo.birthTime().toSecsSinceEpoch(), 0LL) : fileinfo.lastModified().isValid() ? std::max(fileinfo.lastModified().toSecsSinceEpoch(), 0LL) : 0LL);
|
||||
#else
|
||||
song->set_ctime(fileinfo.created().isValid() ? fileinfo.created().toSecsSinceEpoch() : fileinfo.lastModified().isValid() ? fileinfo.lastModified().toSecsSinceEpoch() : 0);
|
||||
song->set_ctime(fileinfo.created().isValid() ? std::max(fileinfo.created().toSecsSinceEpoch(), 0LL) : fileinfo.lastModified().isValid() ? std::max(fileinfo.lastModified().toSecsSinceEpoch(), 0LL) : 0LL);
|
||||
#endif
|
||||
|
||||
if (song->ctime() <= 0) {
|
||||
song->set_ctime(song->mtime());
|
||||
}
|
||||
|
||||
song->set_lastseen(QDateTime::currentDateTime().toSecsSinceEpoch());
|
||||
|
||||
std::unique_ptr<TagLib::FileRef> fileref(factory_->GetFileRef(filename));
|
||||
@@ -265,7 +272,7 @@ void TagReaderTagLib::ReadFile(const QString &filename, spb::tagreader::SongMeta
|
||||
if (tag) Decode(tag->comment(), song->mutable_comment());
|
||||
}
|
||||
|
||||
else if (TagLib::WavPack::File *file_wavpack = 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_wavpack->audioProperties()->bitsPerSample());
|
||||
if (file_wavpack->APETag()) {
|
||||
ParseAPETag(file_wavpack->APETag()->itemListMap(), &disc, &compilation, song);
|
||||
@@ -306,7 +313,9 @@ void TagReaderTagLib::ReadFile(const QString &filename, spb::tagreader::SongMeta
|
||||
|
||||
if (!map["TCMP"].isEmpty()) compilation = TStringToQString(map["TCMP"].front()->toString()).trimmed();
|
||||
|
||||
if (!map["TDOR"].isEmpty()) { song->set_originalyear(map["TDOR"].front()->toString().substr(0, 4).toInt()); }
|
||||
if (!map["TDOR"].isEmpty()) {
|
||||
song->set_originalyear(map["TDOR"].front()->toString().substr(0, 4).toInt());
|
||||
}
|
||||
else if (!map["TORY"].isEmpty()) {
|
||||
song->set_originalyear(map["TORY"].front()->toString().substr(0, 4).toInt());
|
||||
}
|
||||
@@ -321,7 +330,7 @@ void TagReaderTagLib::ReadFile(const QString &filename, spb::tagreader::SongMeta
|
||||
if (!map["APIC"].isEmpty()) song->set_art_automatic(kEmbeddedCover);
|
||||
|
||||
// Find a suitable comment tag. For now we ignore iTunNORM comments.
|
||||
for (uint i = 0 ; i < map["COMM"].size() ; ++i) {
|
||||
for (uint i = 0; i < map["COMM"].size(); ++i) {
|
||||
const TagLib::ID3v2::CommentsFrame *frame = dynamic_cast<const TagLib::ID3v2::CommentsFrame*>(map["COMM"][i]);
|
||||
|
||||
if (frame && TStringToQString(frame->description()) != "iTunNORM") {
|
||||
@@ -450,7 +459,7 @@ void TagReaderTagLib::ReadFile(const QString &filename, spb::tagreader::SongMeta
|
||||
}
|
||||
|
||||
if (attributes_map.contains("FMPS/Rating")) {
|
||||
const TagLib::ASF::AttributeList& attributes = attributes_map["FMPS/Rating"];
|
||||
const TagLib::ASF::AttributeList &attributes = attributes_map["FMPS/Rating"];
|
||||
if (!attributes.isEmpty()) {
|
||||
float rating = TStringToQString(attributes.front().toString()).toFloat();
|
||||
if (song->rating() <= 0 && rating > 0) {
|
||||
@@ -679,7 +688,7 @@ bool TagReaderTagLib::SaveFile(const QString &filename, const spb::tagreader::So
|
||||
else if (TagLib::MP4::File *file_mp4 = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
|
||||
TagLib::MP4::Tag *tag = file_mp4->tag();
|
||||
if (!tag) return false;
|
||||
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(TagLib::String(song.composer(), TagLib::String::UTF8)));
|
||||
tag->setItem("\251grp", TagLib::StringList(TagLib::String(song.grouping(), TagLib::String::UTF8)));
|
||||
tag->setItem("\251lyr", TagLib::StringList(TagLib::String(song.lyrics(), TagLib::String::UTF8)));
|
||||
@@ -743,7 +752,7 @@ void TagReaderTagLib::SetTextFrame(const char *id, const std::string &value, Tag
|
||||
}
|
||||
|
||||
// Update and add the frames
|
||||
for (int i = 0 ; i < frames_buffer.size() ; ++i) {
|
||||
for (int i = 0; i < frames_buffer.size(); ++i) {
|
||||
TagLib::ID3v2::TextIdentificationFrame *frame = new TagLib::ID3v2::TextIdentificationFrame(frames_buffer.at(i));
|
||||
if (i == 0) {
|
||||
frame->setText(StdStringToTaglibString(value));
|
||||
@@ -799,7 +808,7 @@ void TagReaderTagLib::SetUnsyncLyricsFrame(const std::string &value, TagLib::ID3
|
||||
}
|
||||
|
||||
// Update and add the frames
|
||||
for (int i = 0 ; i < frames_buffer.size() ; ++i) {
|
||||
for (int i = 0; i < frames_buffer.size(); ++i) {
|
||||
TagLib::ID3v2::UnsynchronizedLyricsFrame *frame = new TagLib::ID3v2::UnsynchronizedLyricsFrame(frames_buffer.at(i));
|
||||
if (i == 0) {
|
||||
frame->setText(StdStringToTaglibString(value));
|
||||
@@ -983,7 +992,7 @@ bool TagReaderTagLib::SaveEmbeddedArt(const QString &filename, const QByteArray
|
||||
|
||||
// Remove existing covers
|
||||
TagLib::ID3v2::FrameList apiclist = tag->frameListMap()["APIC"];
|
||||
for (TagLib::ID3v2::FrameList::ConstIterator it = apiclist.begin() ; it != apiclist.end() ; ++it ) {
|
||||
for (TagLib::ID3v2::FrameList::ConstIterator it = apiclist.begin(); it != apiclist.end(); ++it) {
|
||||
TagLib::ID3v2::AttachedPictureFrame *frame = dynamic_cast<TagLib::ID3v2::AttachedPictureFrame*>(*it);
|
||||
tag->removeFrame(frame, false);
|
||||
}
|
||||
@@ -994,7 +1003,7 @@ bool TagReaderTagLib::SaveEmbeddedArt(const QString &filename, const QByteArray
|
||||
frontcover = new TagLib::ID3v2::AttachedPictureFrame("APIC");
|
||||
frontcover->setType(TagLib::ID3v2::AttachedPictureFrame::FrontCover);
|
||||
frontcover->setMimeType("image/jpeg");
|
||||
frontcover->setPicture(TagLib::ByteVector(data.constData(), data.count()));
|
||||
frontcover->setPicture(TagLib::ByteVector(data.constData(), data.size()));
|
||||
tag->addFrame(frontcover);
|
||||
}
|
||||
}
|
||||
@@ -1008,7 +1017,7 @@ bool TagReaderTagLib::SaveEmbeddedArt(const QString &filename, const QByteArray
|
||||
if (tag->contains("covr")) tag->removeItem("covr");
|
||||
}
|
||||
else {
|
||||
covers.append(TagLib::MP4::CoverArt(TagLib::MP4::CoverArt::JPEG, TagLib::ByteVector(data.constData(), data.count())));
|
||||
covers.append(TagLib::MP4::CoverArt(TagLib::MP4::CoverArt::JPEG, TagLib::ByteVector(data.constData(), data.size())));
|
||||
tag->setItem("covr", covers);
|
||||
}
|
||||
}
|
||||
@@ -1038,30 +1047,6 @@ TagLib::ID3v2::PopularimeterFrame *TagReaderTagLib::GetPOPMFrameFromTag(TagLib::
|
||||
|
||||
}
|
||||
|
||||
float TagReaderTagLib::ConvertPOPMRating(const int POPM_rating) {
|
||||
|
||||
if (POPM_rating < 0x01) return 0.0F;
|
||||
else if (POPM_rating < 0x40) return 0.20F;
|
||||
else if (POPM_rating < 0x80) return 0.40F;
|
||||
else if (POPM_rating < 0xC0) return 0.60F;
|
||||
else if (POPM_rating < 0xFC) return 0.80F;
|
||||
|
||||
return 1.0F;
|
||||
|
||||
}
|
||||
|
||||
int TagReaderTagLib::ConvertToPOPMRating(const float rating) {
|
||||
|
||||
if (rating < 0.20) return 0x00;
|
||||
else if (rating < 0.40) return 0x01;
|
||||
else if (rating < 0.60) return 0x40;
|
||||
else if (rating < 0.80) return 0x80;
|
||||
else if (rating < 1.0) return 0xC0;
|
||||
|
||||
return 0xFF;
|
||||
|
||||
}
|
||||
|
||||
bool TagReaderTagLib::SaveSongPlaycountToFile(const QString &filename, const spb::tagreader::SongMetadata &song) const {
|
||||
|
||||
if (filename.isEmpty()) return false;
|
||||
|
||||
@@ -75,13 +75,11 @@ class TagReaderTagLib : public TagReaderBase {
|
||||
void SetTextFrame(const char *id, const std::string &value, TagLib::ID3v2::Tag *tag) const;
|
||||
void SetUserTextFrame(const QString &description, const QString &value, TagLib::ID3v2::Tag *tag) const;
|
||||
void SetUserTextFrame(const std::string &description, const std::string &value, TagLib::ID3v2::Tag *tag) const;
|
||||
void SetUnsyncLyricsFrame(const std::string& value, TagLib::ID3v2::Tag* tag) const;
|
||||
void SetUnsyncLyricsFrame(const std::string &value, TagLib::ID3v2::Tag *tag) const;
|
||||
|
||||
QByteArray LoadEmbeddedAPEArt(const TagLib::APE::ItemListMap &map) const;
|
||||
|
||||
static float ConvertPOPMRating(const int POPM_rating);
|
||||
static int ConvertToPOPMRating(const float rating);
|
||||
static TagLib::ID3v2::PopularimeterFrame *GetPOPMFrameFromTag(TagLib::ID3v2::Tag* tag);
|
||||
static TagLib::ID3v2::PopularimeterFrame *GetPOPMFrameFromTag(TagLib::ID3v2::Tag *tag);
|
||||
|
||||
private:
|
||||
FileRefFactory *factory_;
|
||||
|
||||
@@ -106,12 +106,17 @@ void TagReaderTagParser::ReadFile(const QString &filename, spb::tagreader::SongM
|
||||
song->set_basefilename(DataCommaSizeFromQString(fileinfo.fileName()));
|
||||
song->set_url(url.constData(), url.size());
|
||||
song->set_filesize(fileinfo.size());
|
||||
song->set_mtime(fileinfo.lastModified().isValid() ? fileinfo.lastModified().toSecsSinceEpoch() : 0);
|
||||
song->set_mtime(fileinfo.lastModified().isValid() ? std::max(fileinfo.lastModified().toSecsSinceEpoch(), 0LL) : 0LL);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
song->set_ctime(fileinfo.birthTime().isValid() ? fileinfo.birthTime().toSecsSinceEpoch() : fileinfo.lastModified().isValid() ? fileinfo.lastModified().toSecsSinceEpoch() : 0);
|
||||
song->set_ctime(fileinfo.birthTime().isValid() ? std::max(fileinfo.birthTime().toSecsSinceEpoch(), 0LL) : fileinfo.lastModified().isValid() ? std::max(fileinfo.lastModified().toSecsSinceEpoch(), 0LL) : 0LL);
|
||||
#else
|
||||
song->set_ctime(fileinfo.created().isValid() ? fileinfo.created().toSecsSinceEpoch() : fileinfo.lastModified().isValid() ? fileinfo.lastModified().toSecsSinceEpoch() : 0);
|
||||
song->set_ctime(fileinfo.created().isValid() ? std::max(fileinfo.created().toSecsSinceEpoch(), 0LL) : fileinfo.lastModified().isValid() ? std::max(fileinfo.lastModified().toSecsSinceEpoch(), 0LL) : 0LL);
|
||||
#endif
|
||||
|
||||
if (song->ctime() <= 0) {
|
||||
song->set_ctime(song->mtime());
|
||||
}
|
||||
|
||||
song->set_lastseen(QDateTime::currentDateTime().toSecsSinceEpoch());
|
||||
|
||||
try {
|
||||
@@ -151,7 +156,7 @@ void TagReaderTagParser::ReadFile(const QString &filename, spb::tagreader::SongM
|
||||
|
||||
const auto tracks = taginfo.tracks();
|
||||
for (const auto track : tracks) {
|
||||
switch(track->format().general) {
|
||||
switch (track->format().general) {
|
||||
case TagParser::GeneralMediaFormat::Flac:
|
||||
song->set_filetype(spb::tagreader::SongMetadata_FileType::SongMetadata_FileType_FLAC);
|
||||
break;
|
||||
@@ -174,7 +179,7 @@ void TagReaderTagParser::ReadFile(const QString &filename, spb::tagreader::SongM
|
||||
song->set_filetype(spb::tagreader::SongMetadata_FileType::SongMetadata_FileType_OGGSPEEX);
|
||||
break;
|
||||
case TagParser::GeneralMediaFormat::Mpeg1Audio:
|
||||
switch(track->format().sub) {
|
||||
switch (track->format().sub) {
|
||||
case TagParser::SubFormats::Mpeg1Layer3:
|
||||
song->set_filetype(spb::tagreader::SongMetadata_FileType::SongMetadata_FileType_MPEG);
|
||||
break;
|
||||
@@ -222,6 +227,10 @@ void TagReaderTagParser::ReadFile(const QString &filename, spb::tagreader::SongM
|
||||
if (!tag->value(TagParser::KnownField::Cover).empty() && tag->value(TagParser::KnownField::Cover).dataSize() > 0) {
|
||||
song->set_art_automatic(kEmbeddedCover);
|
||||
}
|
||||
const float rating = ConvertPOPMRating(tag->value(TagParser::KnownField::Rating));
|
||||
if (song->rating() <= 0 && rating > 0.0 && rating <= 1.0) {
|
||||
song->set_rating(rating);
|
||||
}
|
||||
}
|
||||
|
||||
// Set integer fields to -1 if they're not valid
|
||||
@@ -464,7 +473,7 @@ bool TagReaderTagParser::SaveSongRatingToFile(const QString &filename, const spb
|
||||
}
|
||||
|
||||
for (const auto tag : taginfo.tags()) {
|
||||
tag->setValue(TagParser::KnownField::Rating, TagParser::TagValue(song.rating()));
|
||||
tag->setValue(TagParser::KnownField::Rating, TagParser::TagValue(ConvertToPOPMRating(song.rating())));
|
||||
}
|
||||
taginfo.applyChanges(diag, progress);
|
||||
taginfo.close();
|
||||
|
||||
@@ -99,7 +99,7 @@ int main(int argc, char **argv) {
|
||||
QRegularExpressionMatch match = regexp.match(output_line);
|
||||
if (match.hasMatch()) {
|
||||
QString library = match.captured(1);
|
||||
if (QFileInfo(library).fileName() == QFileInfo(filepath).fileName()) { // It's this.
|
||||
if (QFileInfo(library).fileName() == QFileInfo(filepath).fileName()) { // It's this.
|
||||
continue;
|
||||
}
|
||||
else if (library.startsWith("@executable_path")) {
|
||||
@@ -113,7 +113,7 @@ int main(int argc, char **argv) {
|
||||
else if (library.startsWith("@rpath")) {
|
||||
QString real_path = library;
|
||||
real_path = real_path.replace("@rpath", bundle_path + "/Contents/Frameworks");
|
||||
if (!QFile(real_path).exists() && !real_path.endsWith("QtSvg")) { // FIXME: Ignore broken svg image plugin.
|
||||
if (!QFile(real_path).exists() && !real_path.endsWith("QtSvg")) { // FIXME: Ignore broken svg image plugin.
|
||||
qLog(Error) << real_path << "does not exist for" << filepath;
|
||||
success = false;
|
||||
}
|
||||
@@ -127,7 +127,7 @@ int main(int argc, char **argv) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else if (library.startsWith("/System/Library/") || library.startsWith("/usr/lib/")) { // System library
|
||||
else if (library.startsWith("/System/Library/") || library.startsWith("/usr/lib/")) { // System library
|
||||
continue;
|
||||
}
|
||||
else if (library.endsWith("libgcc_s.1.dylib")) { // fftw points to it for some reason.
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <QtGlobal>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
#include <sys/time.h>
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "tagreaderworker.h"
|
||||
|
||||
TagReaderWorker::TagReaderWorker(QIODevice *socket, QObject *parent)
|
||||
: AbstractMessageHandler<spb::tagreader::Message>(socket, parent) {}
|
||||
: AbstractMessageHandler<spb::tagreader::Message>(socket, parent) {}
|
||||
|
||||
void TagReaderWorker::MessageArrived(const spb::tagreader::Message &message) {
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ set(SOURCES
|
||||
core/commandlineoptions.cpp
|
||||
core/database.cpp
|
||||
core/sqlquery.cpp
|
||||
core/sqlrow.cpp
|
||||
core/metatypes.cpp
|
||||
core/deletefiles.cpp
|
||||
core/filesystemmusicstorage.cpp
|
||||
@@ -59,8 +60,6 @@ set(SOURCES
|
||||
|
||||
context/contextview.cpp
|
||||
context/contextalbum.cpp
|
||||
context/contextalbumsmodel.cpp
|
||||
context/contextalbumsview.cpp
|
||||
|
||||
collection/collection.cpp
|
||||
collection/collectionmodel.cpp
|
||||
@@ -73,7 +72,6 @@ set(SOURCES
|
||||
collection/collectionfilterwidget.cpp
|
||||
collection/collectionplaylistitem.cpp
|
||||
collection/collectionquery.cpp
|
||||
collection/sqlrow.cpp
|
||||
collection/savedgroupingmanager.cpp
|
||||
collection/groupbydialog.cpp
|
||||
collection/collectiontask.cpp
|
||||
@@ -188,6 +186,7 @@ set(SOURCES
|
||||
dialogs/deleteconfirmationdialog.cpp
|
||||
dialogs/lastfmimportdialog.cpp
|
||||
dialogs/snapdialog.cpp
|
||||
dialogs/saveplaylistsdialog.cpp
|
||||
|
||||
widgets/autoexpandingtreeview.cpp
|
||||
widgets/busyindicator.cpp
|
||||
@@ -212,6 +211,7 @@ set(SOURCES
|
||||
widgets/tracksliderslider.cpp
|
||||
widgets/loginstatewidget.cpp
|
||||
widgets/ratingwidget.cpp
|
||||
widgets/resizabletextedit.cpp
|
||||
|
||||
osd/osdbase.cpp
|
||||
osd/osdpretty.cpp
|
||||
@@ -298,8 +298,6 @@ set(HEADERS
|
||||
|
||||
context/contextview.h
|
||||
context/contextalbum.h
|
||||
context/contextalbumsmodel.h
|
||||
context/contextalbumsview.h
|
||||
|
||||
collection/collection.h
|
||||
collection/collectionmodel.h
|
||||
@@ -420,6 +418,7 @@ set(HEADERS
|
||||
dialogs/deleteconfirmationdialog.h
|
||||
dialogs/lastfmimportdialog.h
|
||||
dialogs/snapdialog.h
|
||||
dialogs/saveplaylistsdialog.h
|
||||
|
||||
widgets/autoexpandingtreeview.h
|
||||
widgets/busyindicator.h
|
||||
@@ -445,6 +444,7 @@ set(HEADERS
|
||||
widgets/qsearchfield.h
|
||||
widgets/ratingwidget.h
|
||||
widgets/forcescrollperpixel.h
|
||||
widgets/resizabletextedit.h
|
||||
|
||||
osd/osdbase.h
|
||||
osd/osdpretty.h
|
||||
@@ -544,6 +544,7 @@ set(UI
|
||||
dialogs/userpassdialog.ui
|
||||
dialogs/lastfmimportdialog.ui
|
||||
dialogs/snapdialog.ui
|
||||
dialogs/saveplaylistsdialog.ui
|
||||
|
||||
widgets/trackslider.ui
|
||||
widgets/fileview.ui
|
||||
|
||||
@@ -32,10 +32,11 @@
|
||||
#include <QVector>
|
||||
#include <QPainter>
|
||||
#include <QPalette>
|
||||
#include <QBasicTimer>
|
||||
#include <QShowEvent>
|
||||
#include <QHideEvent>
|
||||
#include <QTimerEvent>
|
||||
#include <QtEvents>
|
||||
|
||||
#include "core/logging.h"
|
||||
#include "engine/enginebase.h"
|
||||
|
||||
// INSTRUCTIONS Base2D
|
||||
@@ -51,16 +52,34 @@
|
||||
|
||||
Analyzer::Base::Base(QWidget *parent, const uint scopeSize)
|
||||
: QWidget(parent),
|
||||
timeout_(40),
|
||||
fht_(new FHT(scopeSize)),
|
||||
engine_(nullptr),
|
||||
lastscope_(512),
|
||||
new_frame_(false),
|
||||
is_playing_(false) {}
|
||||
is_playing_(false),
|
||||
timeout_(40) {}
|
||||
|
||||
void Analyzer::Base::hideEvent(QHideEvent*) { timer_.stop(); }
|
||||
Analyzer::Base::~Base() {
|
||||
delete fht_;
|
||||
}
|
||||
|
||||
void Analyzer::Base::showEvent(QShowEvent*) { timer_.start(timeout(), this); }
|
||||
void Analyzer::Base::showEvent(QShowEvent*) {
|
||||
timer_.start(timeout(), this);
|
||||
}
|
||||
|
||||
void Analyzer::Base::hideEvent(QHideEvent*) {
|
||||
timer_.stop();
|
||||
}
|
||||
|
||||
void Analyzer::Base::ChangeTimeout(const int timeout) {
|
||||
|
||||
timeout_ = timeout;
|
||||
if (timer_.isActive()) {
|
||||
timer_.stop();
|
||||
timer_.start(timeout_, this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Analyzer::Base::transform(Scope &scope) {
|
||||
|
||||
@@ -154,7 +173,7 @@ int Analyzer::Base::resizeForBands(const int bands) {
|
||||
}
|
||||
else {
|
||||
exp = 9;
|
||||
}
|
||||
}
|
||||
|
||||
resizeExponent(exp);
|
||||
return fht_->size() / 2;
|
||||
@@ -186,10 +205,6 @@ void Analyzer::Base::demo(QPainter &p) {
|
||||
|
||||
}
|
||||
|
||||
void Analyzer::Base::polishEvent() {
|
||||
init();
|
||||
}
|
||||
|
||||
void Analyzer::interpolate(const Scope &inVec, Scope &outVec) {
|
||||
|
||||
double pos = 0.0;
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
|
||||
class QHideEvent;
|
||||
class QShowEvent;
|
||||
class QTimerEvent;
|
||||
class QPaintEvent;
|
||||
class QTimerEvent;
|
||||
|
||||
namespace Analyzer {
|
||||
|
||||
@@ -55,19 +55,13 @@ class Base : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
~Base() override { delete fht_; }
|
||||
~Base() override;
|
||||
|
||||
int timeout() const { return timeout_; }
|
||||
|
||||
void set_engine(EngineBase *engine) { engine_ = engine; }
|
||||
|
||||
void changeTimeout(int newTimeout) {
|
||||
timeout_ = newTimeout;
|
||||
if (timer_.isActive()) {
|
||||
timer_.stop();
|
||||
timer_.start(timeout_, this);
|
||||
}
|
||||
}
|
||||
void ChangeTimeout(const int timeout);
|
||||
|
||||
virtual void framerateChanged() {}
|
||||
|
||||
@@ -76,10 +70,8 @@ class Base : public QWidget {
|
||||
|
||||
void hideEvent(QHideEvent*) override;
|
||||
void showEvent(QShowEvent*) override;
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
void timerEvent(QTimerEvent*) override;
|
||||
|
||||
void polishEvent();
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void timerEvent(QTimerEvent *e) override;
|
||||
|
||||
int resizeExponent(int);
|
||||
int resizeForBands(const int);
|
||||
@@ -90,13 +82,13 @@ class Base : public QWidget {
|
||||
|
||||
protected:
|
||||
QBasicTimer timer_;
|
||||
int timeout_;
|
||||
FHT *fht_;
|
||||
EngineBase *engine_;
|
||||
Scope lastscope_;
|
||||
|
||||
bool new_frame_;
|
||||
bool is_playing_;
|
||||
int timeout_;
|
||||
};
|
||||
|
||||
void interpolate(const Scope&, Scope&);
|
||||
|
||||
@@ -153,7 +153,7 @@ void AnalyzerContainer::ChangeAnalyzer(const int id) {
|
||||
current_analyzer_->set_engine(engine_);
|
||||
// Even if it is not supposed to happen, I don't want to get a dbz error
|
||||
current_framerate_ = current_framerate_ == 0 ? kMediumFramerate : current_framerate_;
|
||||
current_analyzer_->changeTimeout(1000 / current_framerate_);
|
||||
current_analyzer_->ChangeTimeout(1000 / current_framerate_);
|
||||
|
||||
layout()->addWidget(current_analyzer_);
|
||||
|
||||
@@ -166,7 +166,7 @@ void AnalyzerContainer::ChangeFramerate(int new_framerate) {
|
||||
if (current_analyzer_) {
|
||||
// Even if it is not supposed to happen, I don't want to get a dbz error
|
||||
new_framerate = new_framerate == 0 ? kMediumFramerate : new_framerate;
|
||||
current_analyzer_->changeTimeout(1000 / new_framerate);
|
||||
current_analyzer_->ChangeTimeout(1000 / new_framerate);
|
||||
|
||||
// notify the current analyzer that the framerate has changed
|
||||
current_analyzer_->framerateChanged();
|
||||
|
||||
@@ -74,7 +74,7 @@ class AnalyzerContainer : public QWidget {
|
||||
void Load();
|
||||
void Save();
|
||||
void SaveFramerate(const int framerate);
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
void AddAnalyzerType();
|
||||
void AddFramerate(const QString &name, const int framerate);
|
||||
|
||||
@@ -96,10 +96,9 @@ class AnalyzerContainer : public QWidget {
|
||||
|
||||
Analyzer::Base *current_analyzer_;
|
||||
EngineBase *engine_;
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
void AnalyzerContainer::AddAnalyzerType() {
|
||||
|
||||
int id = analyzer_types_.count();
|
||||
|
||||
@@ -63,8 +63,7 @@ BlockAnalyzer::BlockAnalyzer(QWidget *parent)
|
||||
setMaximumWidth(kMaxColumns * (kWidth + 1) - 1);
|
||||
|
||||
// mxcl says null pixmaps cause crashes, so let's play it safe
|
||||
std::fill(fade_bars_.begin(), fade_bars_.end(), QPixmap(1, 1));
|
||||
|
||||
std::fill(fade_bars_.begin(), fade_bars_.end(), QPixmap(1, 1));
|
||||
}
|
||||
|
||||
void BlockAnalyzer::resizeEvent(QResizeEvent *e) {
|
||||
@@ -89,7 +88,7 @@ void BlockAnalyzer::resizeEvent(QResizeEvent *e) {
|
||||
if (rows_ != oldRows) {
|
||||
barpixmap_ = QPixmap(kWidth, rows_ * (kHeight + 1));
|
||||
|
||||
std::fill(fade_bars_.begin(), fade_bars_.end(), QPixmap(kWidth, rows_ * (kHeight + 1)));
|
||||
std::fill(fade_bars_.begin(), fade_bars_.end(), QPixmap(kWidth, rows_ * (kHeight + 1)));
|
||||
|
||||
yscale_.resize(rows_ + 1);
|
||||
|
||||
|
||||
@@ -65,14 +65,14 @@ class BlockAnalyzer : public Analyzer::Base {
|
||||
private:
|
||||
QPixmap *bar() { return &barpixmap_; }
|
||||
|
||||
int columns_, rows_; // number of rows and columns of blocks
|
||||
int y_; // y-offset from top of widget
|
||||
int columns_, rows_; // number of rows and columns of blocks
|
||||
int y_; // y-offset from top of widget
|
||||
QPixmap barpixmap_;
|
||||
QPixmap topbarpixmap_;
|
||||
QPixmap background_;
|
||||
QPixmap canvas_;
|
||||
Analyzer::Scope scope_; // so we don't create a vector every frame
|
||||
QVector<double> store_; // current bar heights
|
||||
Analyzer::Scope scope_; // so we don't create a vector every frame
|
||||
QVector<double> store_; // current bar heights
|
||||
QVector<double> yscale_;
|
||||
|
||||
QVector<QPixmap> fade_bars_;
|
||||
|
||||
@@ -43,12 +43,12 @@
|
||||
|
||||
using Analyzer::Scope;
|
||||
|
||||
const int Rainbow::RainbowAnalyzer::kHeight[] = {21, 33};
|
||||
const int Rainbow::RainbowAnalyzer::kWidth[] = {34, 53};
|
||||
const int Rainbow::RainbowAnalyzer::kFrameCount[] = {6, 16};
|
||||
const int Rainbow::RainbowAnalyzer::kRainbowHeight[] = {21, 16};
|
||||
const int Rainbow::RainbowAnalyzer::kRainbowOverlap[] = {13, 15};
|
||||
const int Rainbow::RainbowAnalyzer::kSleepingHeight[] = {24, 33};
|
||||
const int Rainbow::RainbowAnalyzer::kHeight[] = { 21, 33 };
|
||||
const int Rainbow::RainbowAnalyzer::kWidth[] = { 34, 53 };
|
||||
const int Rainbow::RainbowAnalyzer::kFrameCount[] = { 6, 16 };
|
||||
const int Rainbow::RainbowAnalyzer::kRainbowHeight[] = { 21, 16 };
|
||||
const int Rainbow::RainbowAnalyzer::kRainbowOverlap[] = { 13, 15 };
|
||||
const int Rainbow::RainbowAnalyzer::kSleepingHeight[] = { 24, 33 };
|
||||
|
||||
const char *Rainbow::NyanCatAnalyzer::kName = "Nyanalyzer Cat";
|
||||
const char *Rainbow::RainbowDashAnalyzer::kName = "Rainbow Dash";
|
||||
|
||||
@@ -93,7 +93,7 @@ class RainbowAnalyzer : public Analyzer::Base {
|
||||
|
||||
private:
|
||||
// "constants" that get initialized in the constructor
|
||||
float band_scale_[kRainbowBands]{};
|
||||
float band_scale_[kRainbowBands] {};
|
||||
QPen colors_[kRainbowBands];
|
||||
|
||||
// Rainbow Nyancat & Dash
|
||||
@@ -104,7 +104,7 @@ class RainbowAnalyzer : public Analyzer::Base {
|
||||
int frame_;
|
||||
|
||||
// The y positions of each point on the rainbow.
|
||||
float history_[kHistorySize * kRainbowBands]{};
|
||||
float history_[kHistorySize * kRainbowBands] {};
|
||||
|
||||
// A cache of the last frame's rainbow,
|
||||
// so it can be used in the next frame.
|
||||
@@ -142,6 +142,6 @@ class RainbowDashAnalyzer : public RainbowAnalyzer {
|
||||
|
||||
static const char *kName;
|
||||
};
|
||||
}
|
||||
} // namespace Rainbow
|
||||
|
||||
#endif // RAINBOWANALYZER_H
|
||||
|
||||
@@ -47,10 +47,10 @@
|
||||
#include "core/database.h"
|
||||
#include "core/scopedtransaction.h"
|
||||
#include "core/song.h"
|
||||
#include "core/sqlrow.h"
|
||||
#include "smartplaylists/smartplaylistsearch.h"
|
||||
|
||||
#include "directory.h"
|
||||
#include "sqlrow.h"
|
||||
#include "collectionbackend.h"
|
||||
#include "collectionquery.h"
|
||||
#include "collectiontask.h"
|
||||
@@ -335,8 +335,8 @@ void CollectionBackend::AddDirectory(const QString &path) {
|
||||
q.prepare(QString("INSERT INTO %1 (path, subdirs) VALUES (:path, 1)").arg(dirs_table_));
|
||||
q.BindValue(":path", db_path);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
return;
|
||||
db_->ReportErrors(q);
|
||||
return;
|
||||
}
|
||||
|
||||
Directory dir;
|
||||
@@ -634,15 +634,13 @@ void CollectionBackend::AddOrUpdateSongs(const SongList &songs) {
|
||||
added_songs << new_song;
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Create new song
|
||||
|
||||
int id = -1;
|
||||
{ // Insert the row and create a new ID
|
||||
{ // Insert the row and create a new ID
|
||||
SqlQuery q(db);
|
||||
q.prepare(QString("INSERT INTO %1 (" + Song::kColumnSpec + ") VALUES (" + Song::kBindSpec + ")").arg(songs_table_));
|
||||
song.BindToQuery(&q);
|
||||
@@ -656,7 +654,7 @@ void CollectionBackend::AddOrUpdateSongs(const SongList &songs) {
|
||||
|
||||
if (id == -1) return;
|
||||
|
||||
{ // Add to the FTS index
|
||||
{ // Add to the FTS index
|
||||
SqlQuery q(db);
|
||||
q.prepare(QString("INSERT INTO %1 (ROWID, " + Song::kFtsColumnSpec + ") VALUES (:id, " + Song::kFtsBindSpec + ")").arg(fts_table_));
|
||||
q.BindValue(":id", id);
|
||||
@@ -1345,7 +1343,7 @@ void CollectionBackend::CompilationsNeedUpdating() {
|
||||
if (album.isEmpty()) continue;
|
||||
|
||||
// Find the directory the song is in
|
||||
QString directory = url.toString(QUrl::PreferLocalFile|QUrl::RemoveFilename);
|
||||
QString directory = url.toString(QUrl::PreferLocalFile | QUrl::RemoveFilename);
|
||||
|
||||
CompilationInfo &info = compilation_info[directory + album];
|
||||
info.urls << url;
|
||||
@@ -1481,7 +1479,7 @@ CollectionBackend::AlbumList CollectionBackend::GetAlbums(const QString &artist,
|
||||
info.art_manual = QUrl::fromLocalFile(art_manual);
|
||||
}
|
||||
|
||||
info.filetype = Song::FileType(query.Value(6).toInt());
|
||||
info.filetype = static_cast<Song::FileType>(query.Value(6).toInt());
|
||||
QString filetype = Song::TextForFiletype(info.filetype);
|
||||
info.cue_path = query.Value(7).toString();
|
||||
|
||||
|
||||
@@ -68,24 +68,23 @@ CollectionFilterWidget::CollectionFilterWidget(QWidget *parent)
|
||||
QString available_fields = Song::kFtsColumns.join(", ").replace(QRegularExpression("\\bfts"), "");
|
||||
|
||||
ui_->search_field->setToolTip(
|
||||
QString("<html><head/><body><p>") +
|
||||
tr("Prefix a word with a field name to limit the search to that field, e.g.:") +
|
||||
QString(" ") +
|
||||
QString("<span style=\"font-weight:600;\">") +
|
||||
tr("artist") +
|
||||
QString(":") +
|
||||
QString("</span><span style=\"font-style:italic;\">Strawbs</span>") +
|
||||
QString(" ") +
|
||||
tr("searches the collection for all artists that contain the word") +
|
||||
QString(" Strawbs.") +
|
||||
QString("</p><p><span style=\"font-weight:600;\">") +
|
||||
tr("Available fields") +
|
||||
QString(": ") +
|
||||
"</span><span style=\"font-style:italic;\">" +
|
||||
available_fields +
|
||||
QString("</span>.") +
|
||||
QString("</p></body></html>")
|
||||
);
|
||||
QString("<html><head/><body><p>") +
|
||||
tr("Prefix a word with a field name to limit the search to that field, e.g.:") +
|
||||
QString(" ") +
|
||||
QString("<span style=\"font-weight:600;\">") +
|
||||
tr("artist") +
|
||||
QString(":") +
|
||||
QString("</span><span style=\"font-style:italic;\">Strawbs</span>") +
|
||||
QString(" ") +
|
||||
tr("searches the collection for all artists that contain the word") +
|
||||
QString(" Strawbs.") +
|
||||
QString("</p><p><span style=\"font-weight:600;\">") +
|
||||
tr("Available fields") +
|
||||
QString(": ") +
|
||||
"</span><span style=\"font-style:italic;\">" +
|
||||
available_fields +
|
||||
QString("</span>.") +
|
||||
QString("</p></body></html>"));
|
||||
|
||||
QObject::connect(ui_->search_field, &QSearchField::returnPressed, this, &CollectionFilterWidget::ReturnPressed);
|
||||
QObject::connect(filter_delay_, &QTimer::timeout, this, &CollectionFilterWidget::FilterDelayTimeout);
|
||||
@@ -177,16 +176,15 @@ void CollectionFilterWidget::Init(CollectionModel *model) {
|
||||
if (s.contains(group_by_version())) version = s.value(group_by_version(), 0).toInt();
|
||||
if (version == 1) {
|
||||
model_->SetGroupBy(CollectionModel::Grouping(
|
||||
CollectionModel::GroupBy(s.value(group_by(1), static_cast<int>(CollectionModel::GroupBy_AlbumArtist)).toInt()),
|
||||
CollectionModel::GroupBy(s.value(group_by(2), static_cast<int>(CollectionModel::GroupBy_AlbumDisc)).toInt()),
|
||||
CollectionModel::GroupBy(s.value(group_by(3), static_cast<int>(CollectionModel::GroupBy_None)).toInt())));
|
||||
CollectionModel::GroupBy(s.value(group_by(1), static_cast<int>(CollectionModel::GroupBy_AlbumArtist)).toInt()),
|
||||
CollectionModel::GroupBy(s.value(group_by(2), static_cast<int>(CollectionModel::GroupBy_AlbumDisc)).toInt()),
|
||||
CollectionModel::GroupBy(s.value(group_by(3), static_cast<int>(CollectionModel::GroupBy_None)).toInt())));
|
||||
}
|
||||
else {
|
||||
model_->SetGroupBy(CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_AlbumDisc, CollectionModel::GroupBy_None));
|
||||
}
|
||||
s.endGroup();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CollectionFilterWidget::ReloadSettings() {
|
||||
|
||||
@@ -100,7 +100,7 @@ void CollectionItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem
|
||||
// Draw the line under the item
|
||||
QColor line_color = opt.palette.color(QPalette::Text);
|
||||
QLinearGradient grad_color(opt.rect.bottomLeft(), opt.rect.bottomRight());
|
||||
const double fade_start_end = (opt.rect.width()/3.0)/opt.rect.width();
|
||||
const double fade_start_end = (opt.rect.width() / 3.0) / opt.rect.width();
|
||||
line_color.setAlphaF(0.0);
|
||||
grad_color.setColorAt(0, line_color);
|
||||
line_color.setAlphaF(0.5);
|
||||
|
||||
@@ -59,12 +59,12 @@
|
||||
#include "core/iconloader.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "core/sqlrow.h"
|
||||
#include "collectionquery.h"
|
||||
#include "collectionbackend.h"
|
||||
#include "collectiondirectorymodel.h"
|
||||
#include "collectionitem.h"
|
||||
#include "collectionmodel.h"
|
||||
#include "sqlrow.h"
|
||||
#include "playlist/playlistmanager.h"
|
||||
#include "playlist/songmimedata.h"
|
||||
#include "covermanager/albumcoverloader.h"
|
||||
@@ -325,26 +325,32 @@ QString CollectionModel::ContainerKey(const GroupBy type, const Song &song) {
|
||||
case GroupBy_Album:
|
||||
key = TextOrUnknown(song.album());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_AlbumDisc:
|
||||
key = PrettyAlbumDisc(song.album(), song.disc());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_YearAlbum:
|
||||
key = PrettyYearAlbum(song.year(), song.album());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_YearAlbumDisc:
|
||||
key = PrettyYearAlbumDisc(song.year(), song.album(), song.disc());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbum:
|
||||
key = PrettyYearAlbum(song.effective_originalyear(), song.album());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbumDisc:
|
||||
key = PrettyYearAlbumDisc(song.effective_originalyear(), song.album(), song.disc());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_Disc:
|
||||
key = PrettyDisc(song.disc());
|
||||
@@ -476,7 +482,7 @@ QString CollectionModel::DividerDisplayText(const GroupBy type, const QString &k
|
||||
case GroupBy_Genre:
|
||||
case GroupBy_FileType:
|
||||
case GroupBy_Format:
|
||||
if (key == "0") return "0-9";
|
||||
if (key == "0") return "0-9";
|
||||
return key.toUpper();
|
||||
|
||||
case GroupBy_YearAlbum:
|
||||
@@ -1008,22 +1014,22 @@ void CollectionModel::InitQuery(const GroupBy type, CollectionQuery *q) {
|
||||
q->SetColumnSpec("DISTINCT artist");
|
||||
break;
|
||||
case GroupBy_Album:
|
||||
q->SetColumnSpec("DISTINCT album, album_id");
|
||||
q->SetColumnSpec("DISTINCT album, album_id, grouping");
|
||||
break;
|
||||
case GroupBy_AlbumDisc:
|
||||
q->SetColumnSpec("DISTINCT album, album_id, disc");
|
||||
q->SetColumnSpec("DISTINCT album, album_id, disc, grouping");
|
||||
break;
|
||||
case GroupBy_YearAlbum:
|
||||
q->SetColumnSpec("DISTINCT year, album, album_id, grouping");
|
||||
break;
|
||||
case GroupBy_YearAlbumDisc:
|
||||
q->SetColumnSpec("DISTINCT year, album, album_id, disc");
|
||||
q->SetColumnSpec("DISTINCT year, album, album_id, disc, grouping");
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbum:
|
||||
q->SetColumnSpec("DISTINCT year, originalyear, album, album_id, grouping");
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbumDisc:
|
||||
q->SetColumnSpec("DISTINCT year, originalyear, album, album_id, disc");
|
||||
q->SetColumnSpec("DISTINCT year, originalyear, album, album_id, disc, grouping");
|
||||
break;
|
||||
case GroupBy_Disc:
|
||||
q->SetColumnSpec("DISTINCT disc");
|
||||
@@ -1097,11 +1103,13 @@ void CollectionModel::FilterQuery(const GroupBy type, CollectionItem *item, Coll
|
||||
case GroupBy_Album:
|
||||
q->AddWhere("album", item->metadata.album());
|
||||
q->AddWhere("album_id", item->metadata.album_id());
|
||||
q->AddWhere("grouping", item->metadata.grouping());
|
||||
break;
|
||||
case GroupBy_AlbumDisc:
|
||||
q->AddWhere("album", item->metadata.album());
|
||||
q->AddWhere("album_id", item->metadata.album_id());
|
||||
q->AddWhere("disc", item->metadata.disc());
|
||||
q->AddWhere("grouping", item->metadata.grouping());
|
||||
break;
|
||||
case GroupBy_YearAlbum:
|
||||
q->AddWhere("year", item->metadata.year());
|
||||
@@ -1114,6 +1122,7 @@ void CollectionModel::FilterQuery(const GroupBy type, CollectionItem *item, Coll
|
||||
q->AddWhere("album", item->metadata.album());
|
||||
q->AddWhere("album_id", item->metadata.album_id());
|
||||
q->AddWhere("disc", item->metadata.disc());
|
||||
q->AddWhere("grouping", item->metadata.grouping());
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbum:
|
||||
q->AddWhere("year", item->metadata.year());
|
||||
@@ -1128,6 +1137,7 @@ void CollectionModel::FilterQuery(const GroupBy type, CollectionItem *item, Coll
|
||||
q->AddWhere("album", item->metadata.album());
|
||||
q->AddWhere("album_id", item->metadata.album_id());
|
||||
q->AddWhere("disc", item->metadata.disc());
|
||||
q->AddWhere("grouping", item->metadata.grouping());
|
||||
break;
|
||||
case GroupBy_Disc:
|
||||
q->AddWhere("disc", item->metadata.disc());
|
||||
@@ -1216,6 +1226,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
case GroupBy_Album:{
|
||||
item->metadata.set_album(row.value(0).toString());
|
||||
item->metadata.set_album_id(row.value(1).toString());
|
||||
item->metadata.set_grouping(row.value(2).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->display_text = TextOrUnknown(item->metadata.album());
|
||||
item->sort_text = SortTextForArtist(item->metadata.album());
|
||||
@@ -1225,6 +1236,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
item->metadata.set_album(row.value(0).toString());
|
||||
item->metadata.set_album_id(row.value(1).toString());
|
||||
item->metadata.set_disc(row.value(2).toInt());
|
||||
item->metadata.set_grouping(row.value(3).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->display_text = PrettyAlbumDisc(item->metadata.album(), item->metadata.disc());
|
||||
item->sort_text = item->metadata.album() + SortTextForNumber(qMax(0, item->metadata.disc()));
|
||||
@@ -1245,6 +1257,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
item->metadata.set_album(row.value(1).toString());
|
||||
item->metadata.set_album_id(row.value(2).toString());
|
||||
item->metadata.set_disc(row.value(3).toInt());
|
||||
item->metadata.set_grouping(row.value(4).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->display_text = PrettyYearAlbumDisc(item->metadata.year(), item->metadata.album(), item->metadata.disc());
|
||||
item->sort_text = SortTextForNumber(qMax(0, item->metadata.year())) + item->metadata.album() + SortTextForNumber(qMax(0, item->metadata.disc()));
|
||||
@@ -1267,6 +1280,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
item->metadata.set_album(row.value(2).toString());
|
||||
item->metadata.set_album_id(row.value(3).toString());
|
||||
item->metadata.set_disc(row.value(4).toInt());
|
||||
item->metadata.set_grouping(row.value(5).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->display_text = PrettyYearAlbumDisc(item->metadata.effective_originalyear(), item->metadata.album(), item->metadata.disc());
|
||||
item->sort_text = SortTextForNumber(qMax(0, item->metadata.effective_originalyear())) + item->metadata.album() + SortTextForNumber(qMax(0, item->metadata.disc()));
|
||||
@@ -1325,14 +1339,14 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
break;
|
||||
}
|
||||
case GroupBy_FileType:{
|
||||
item->metadata.set_filetype(Song::FileType(row.value(0).toInt()));
|
||||
item->metadata.set_filetype(static_cast<Song::FileType>(row.value(0).toInt()));
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->display_text = item->metadata.TextForFiletype();
|
||||
item->sort_text = item->metadata.TextForFiletype();
|
||||
break;
|
||||
}
|
||||
case GroupBy_Format:{
|
||||
item->metadata.set_filetype(Song::FileType(row.value(0).toInt()));
|
||||
item->metadata.set_filetype(static_cast<Song::FileType>(row.value(0).toInt()));
|
||||
item->metadata.set_samplerate(row.value(1).toInt());
|
||||
item->metadata.set_bitdepth(row.value(2).toInt());
|
||||
QString key = ContainerKey(type, item->metadata);
|
||||
@@ -1411,6 +1425,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
case GroupBy_Album:{
|
||||
item->metadata.set_album(s.album());
|
||||
item->metadata.set_album_id(s.album_id());
|
||||
item->metadata.set_grouping(s.grouping());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->display_text = TextOrUnknown(s.album());
|
||||
item->sort_text = SortTextForArtist(s.album());
|
||||
@@ -1420,6 +1435,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
item->metadata.set_album(s.album());
|
||||
item->metadata.set_album_id(s.album_id());
|
||||
item->metadata.set_disc(s.disc());
|
||||
item->metadata.set_grouping(s.grouping());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->display_text = PrettyAlbumDisc(s.album(), s.disc());
|
||||
item->sort_text = s.album() + SortTextForNumber(qMax(0, s.disc()));
|
||||
@@ -1440,6 +1456,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
item->metadata.set_album(s.album());
|
||||
item->metadata.set_album_id(s.album_id());
|
||||
item->metadata.set_disc(s.disc());
|
||||
item->metadata.set_grouping(s.grouping());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->display_text = PrettyYearAlbumDisc(s.year(), s.album(), s.disc());
|
||||
item->sort_text = SortTextForNumber(qMax(0, s.year())) + s.album() + SortTextForNumber(qMax(0, s.disc()));
|
||||
@@ -1932,7 +1949,7 @@ void CollectionModel::ExpandAll(CollectionItem *item) const {
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &s, const CollectionModel::Grouping g) {
|
||||
s << quint32(g.first) << quint32(g.second) << quint32(g.third);
|
||||
s << static_cast<quint32>(g.first) << static_cast<quint32>(g.second) << static_cast<quint32>(g.third);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -1940,11 +1957,11 @@ QDataStream &operator>>(QDataStream &s, CollectionModel::Grouping &g) {
|
||||
|
||||
quint32 buf = 0;
|
||||
s >> buf;
|
||||
g.first = CollectionModel::GroupBy(buf);
|
||||
g.first = static_cast<CollectionModel::GroupBy>(buf);
|
||||
s >> buf;
|
||||
g.second = CollectionModel::GroupBy(buf);
|
||||
g.second = static_cast<CollectionModel::GroupBy>(buf);
|
||||
s >> buf;
|
||||
g.third = CollectionModel::GroupBy(buf);
|
||||
g.third = static_cast<CollectionModel::GroupBy>(buf);
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@
|
||||
|
||||
#include "core/simpletreemodel.h"
|
||||
#include "core/song.h"
|
||||
#include "core/sqlrow.h"
|
||||
#include "covermanager/albumcoverloader.h"
|
||||
#include "collectionquery.h"
|
||||
#include "collectionitem.h"
|
||||
#include "sqlrow.h"
|
||||
#include "covermanager/albumcoverloaderoptions.h"
|
||||
|
||||
class QSettings;
|
||||
|
||||
@@ -155,11 +155,11 @@ void CollectionQuery::AddWhere(const QString &column, const QVariant &value, con
|
||||
}
|
||||
else if (
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
value.metaType().id() == QMetaType::QString
|
||||
value.metaType().id() == QMetaType::QString
|
||||
#else
|
||||
value.type() == QVariant::String
|
||||
value.type() == QVariant::String
|
||||
#endif
|
||||
&& value.toString().isNull()) {
|
||||
&& value.toString().isNull()) {
|
||||
where_clauses_ << QString("%1 %2 ?").arg(column, op);
|
||||
bound_values_ << QString("");
|
||||
}
|
||||
|
||||
@@ -125,4 +125,4 @@ class CollectionQuery : public QSqlQuery {
|
||||
int limit_;
|
||||
};
|
||||
|
||||
#endif // COLLECTIONQUERY_H
|
||||
#endif // COLLECTIONQUERY_H
|
||||
|
||||
@@ -82,6 +82,7 @@ CollectionWatcher::CollectionWatcher(Song::Source source, QObject *parent)
|
||||
song_tracking_(false),
|
||||
mark_songs_unavailable_(source_ == Song::Source_Collection),
|
||||
expire_unavailable_songs_days_(60),
|
||||
overwrite_playcount_(false),
|
||||
overwrite_rating_(false),
|
||||
stop_requested_(false),
|
||||
abort_requested_(false),
|
||||
@@ -153,6 +154,7 @@ void CollectionWatcher::ReloadSettings() {
|
||||
mark_songs_unavailable_ = false;
|
||||
}
|
||||
expire_unavailable_songs_days_ = s.value("expire_unavailable_songs", 60).toInt();
|
||||
overwrite_playcount_ = s.value("overwrite_playcount", false).toBool();
|
||||
overwrite_rating_ = s.value("overwrite_rating", false).toBool();
|
||||
s.endGroup();
|
||||
|
||||
@@ -734,7 +736,7 @@ void CollectionWatcher::UpdateCueAssociatedSongs(const QString &file,
|
||||
const Song matching_cue_song = sections_map[new_cue_song.beginning_nanosec()];
|
||||
new_cue_song.set_id(matching_cue_song.id());
|
||||
if (!new_cue_song.has_embedded_cover()) new_cue_song.set_art_automatic(image);
|
||||
new_cue_song.MergeUserSetData(matching_cue_song, true);
|
||||
new_cue_song.MergeUserSetData(matching_cue_song, true, true);
|
||||
AddChangedSong(file, matching_cue_song, new_cue_song, t);
|
||||
used_ids.insert(matching_cue_song.id());
|
||||
}
|
||||
@@ -777,7 +779,7 @@ void CollectionWatcher::UpdateNonCueAssociatedSong(const QString &file,
|
||||
song_on_disk.set_id(matching_song.id());
|
||||
song_on_disk.set_fingerprint(fingerprint);
|
||||
if (!song_on_disk.has_embedded_cover()) song_on_disk.set_art_automatic(image);
|
||||
song_on_disk.MergeUserSetData(matching_song, !overwrite_rating_);
|
||||
song_on_disk.MergeUserSetData(matching_song, !overwrite_playcount_, !overwrite_rating_);
|
||||
AddChangedSong(file, matching_song, song_on_disk, t);
|
||||
}
|
||||
|
||||
|
||||
@@ -218,6 +218,7 @@ class CollectionWatcher : public QObject {
|
||||
bool song_tracking_;
|
||||
bool mark_songs_unavailable_;
|
||||
int expire_unavailable_songs_days_;
|
||||
bool overwrite_playcount_;
|
||||
bool overwrite_rating_;
|
||||
|
||||
bool stop_requested_;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2020-2022, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -43,7 +43,7 @@
|
||||
#include "contextview.h"
|
||||
#include "contextalbum.h"
|
||||
|
||||
const int ContextAlbum::kWidgetSpacing = 40;
|
||||
const int ContextAlbum::kFadeTimeLineMs = 1000;
|
||||
|
||||
ContextAlbum::ContextAlbum(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
@@ -51,23 +51,26 @@ ContextAlbum::ContextAlbum(QWidget *parent)
|
||||
context_view_(nullptr),
|
||||
album_cover_choice_controller_(nullptr),
|
||||
downloading_covers_(false),
|
||||
timeline_fade_(new QTimeLine(1000, this)),
|
||||
timeline_fade_(new QTimeLine(kFadeTimeLineMs, this)),
|
||||
image_strawberry_(":/pictures/strawberry.png"),
|
||||
image_original_(image_strawberry_),
|
||||
pixmap_previous_opacity_(0),
|
||||
prev_width_(width()) {
|
||||
pixmap_current_opacity_(1.0) {
|
||||
|
||||
setObjectName("context-widget-album");
|
||||
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
cover_loader_options_.desired_height_ = 600;
|
||||
cover_loader_options_.desired_height_ = width();
|
||||
cover_loader_options_.pad_output_image_ = true;
|
||||
cover_loader_options_.scale_output_image_ = true;
|
||||
QImage image = ImageUtils::ScaleAndPad(image_strawberry_, cover_loader_options_.scale_output_image_, cover_loader_options_.pad_output_image_, cover_loader_options_.desired_height_);
|
||||
if (!image.isNull()) pixmap_current_ = QPixmap::fromImage(image);
|
||||
if (!image.isNull()) {
|
||||
pixmap_current_ = QPixmap::fromImage(image);
|
||||
}
|
||||
|
||||
QObject::connect(timeline_fade_, &QTimeLine::valueChanged, this, &ContextAlbum::FadePreviousTrack);
|
||||
timeline_fade_->setDirection(QTimeLine::Backward); // 1.0 -> 0.0
|
||||
timeline_fade_->setDirection(QTimeLine::Forward);
|
||||
QObject::connect(timeline_fade_, &QTimeLine::valueChanged, this, &ContextAlbum::FadeCurrentCover);
|
||||
QObject::connect(timeline_fade_, &QTimeLine::finished, this, &ContextAlbum::FadeCurrentCoverFinished);
|
||||
|
||||
}
|
||||
|
||||
@@ -86,8 +89,21 @@ void ContextAlbum::Init(ContextView *context_view, AlbumCoverChoiceController *a
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::contextMenuEvent(QContextMenuEvent *e) {
|
||||
if (menu_ && image_original_ != image_strawberry_) menu_->popup(mapToGlobal(e->pos()));
|
||||
QSize ContextAlbum::sizeHint() const {
|
||||
|
||||
return QSize(pixmap_current_.width(), pixmap_current_.height());
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::paintEvent(QPaintEvent*) {
|
||||
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
DrawPreviousCovers(&p);
|
||||
DrawImage(&p, pixmap_current_, pixmap_current_opacity_);
|
||||
DrawSpinner(&p);
|
||||
p.end();
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::mouseDoubleClickEvent(QMouseEvent *e) {
|
||||
@@ -99,93 +115,146 @@ void ContextAlbum::mouseDoubleClickEvent(QMouseEvent *e) {
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::paintEvent(QPaintEvent*) {
|
||||
void ContextAlbum::contextMenuEvent(QContextMenuEvent *e) {
|
||||
|
||||
QPainter p(this);
|
||||
|
||||
DrawImage(&p);
|
||||
|
||||
// Draw the previous track's image if we're fading
|
||||
if (!pixmap_previous_.isNull()) {
|
||||
p.setOpacity(pixmap_previous_opacity_);
|
||||
p.drawPixmap(0, 0, pixmap_previous_);
|
||||
if (menu_ && image_original_ != image_strawberry_) {
|
||||
menu_->popup(mapToGlobal(e->pos()));
|
||||
}
|
||||
else {
|
||||
QWidget::contextMenuEvent(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::DrawImage(QPainter *p) {
|
||||
|
||||
p->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
void ContextAlbum::UpdateWidth(const int new_width) {
|
||||
|
||||
if (width() != prev_width_) {
|
||||
cover_loader_options_.desired_height_ = width() - kWidgetSpacing;
|
||||
QImage image = ImageUtils::ScaleAndPad(image_original_, cover_loader_options_.scale_output_image_, cover_loader_options_.pad_output_image_, cover_loader_options_.desired_height_);
|
||||
if (image.isNull()) pixmap_current_ = QPixmap();
|
||||
else pixmap_current_ = QPixmap::fromImage(image);
|
||||
prev_width_ = width();
|
||||
if (new_width != cover_loader_options_.desired_height_) {
|
||||
cover_loader_options_.desired_height_ = new_width;
|
||||
ScaleCover();
|
||||
ScalePreviousCovers();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
p->drawPixmap(0, 0, width() - kWidgetSpacing, width() - kWidgetSpacing, pixmap_current_);
|
||||
if (downloading_covers_ && spinner_animation_) {
|
||||
p->drawPixmap(50, 50, 16, 16, spinner_animation_->currentPixmap());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::FadePreviousTrack(const qreal value) {
|
||||
|
||||
pixmap_previous_opacity_ = value;
|
||||
if (qFuzzyCompare(pixmap_previous_opacity_, qreal(0.0))) {
|
||||
image_previous_ = QImage();
|
||||
pixmap_previous_ = QPixmap();
|
||||
}
|
||||
update();
|
||||
|
||||
if (value == 0 && image_original_ == image_strawberry_) {
|
||||
emit FadeStopFinished();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::ScaleCover() {
|
||||
|
||||
cover_loader_options_.desired_height_ = width() - kWidgetSpacing;
|
||||
QImage image = ImageUtils::ScaleAndPad(image_original_, cover_loader_options_.scale_output_image_, cover_loader_options_.pad_output_image_, cover_loader_options_.desired_height_);
|
||||
if (image.isNull()) pixmap_current_ = QPixmap();
|
||||
else pixmap_current_ = QPixmap::fromImage(image);
|
||||
prev_width_ = width();
|
||||
update();
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::SetImage(QImage image) {
|
||||
|
||||
if (image.isNull()) image = image_strawberry_;
|
||||
if (image.isNull()) {
|
||||
image = image_strawberry_;
|
||||
}
|
||||
|
||||
if (downloading_covers_) {
|
||||
downloading_covers_ = false;
|
||||
spinner_animation_.reset();
|
||||
}
|
||||
|
||||
// Cache the current pixmap so we can fade between them
|
||||
pixmap_previous_ = QPixmap(width() - kWidgetSpacing, width() - kWidgetSpacing);
|
||||
pixmap_previous_.fill(palette().window().color());
|
||||
pixmap_previous_opacity_ = 1.0;
|
||||
QImage image_previous = image_original_;
|
||||
QPixmap pixmap_previous = pixmap_current_;
|
||||
qreal opacity_previous = pixmap_current_opacity_;
|
||||
|
||||
QPainter p(&pixmap_previous_);
|
||||
DrawImage(&p);
|
||||
p.end();
|
||||
|
||||
image_previous_ = image_original_;
|
||||
image_original_ = image;
|
||||
|
||||
pixmap_current_opacity_ = 0.0;
|
||||
ScaleCover();
|
||||
|
||||
// Were we waiting for this cover to load before we started fading?
|
||||
if (!pixmap_previous_.isNull() && timeline_fade_) {
|
||||
if (!pixmap_previous.isNull()) {
|
||||
std::shared_ptr<PreviousCover> previous_cover = std::make_shared<PreviousCover>();
|
||||
previous_cover->image = image_previous;
|
||||
previous_cover->pixmap = pixmap_previous;
|
||||
previous_cover->opacity = opacity_previous;
|
||||
previous_cover->timeline.reset(new QTimeLine(kFadeTimeLineMs), [](QTimeLine *timeline) { timeline->deleteLater(); });
|
||||
previous_cover->timeline->setDirection(QTimeLine::Backward);
|
||||
previous_cover->timeline->setCurrentTime(timeline_fade_->state() == QTimeLine::Running ? timeline_fade_->currentTime() : kFadeTimeLineMs);
|
||||
QObject::connect(previous_cover->timeline.get(), &QTimeLine::valueChanged, this, [this, previous_cover]() { FadePreviousCover(previous_cover); });
|
||||
QObject::connect(previous_cover->timeline.get(), &QTimeLine::finished, this, [this, previous_cover]() { FadePreviousCoverFinished(previous_cover); });
|
||||
previous_covers_ << previous_cover;
|
||||
previous_cover->timeline->start();
|
||||
}
|
||||
|
||||
if (timeline_fade_->state() == QTimeLine::Running) {
|
||||
timeline_fade_->stop();
|
||||
timeline_fade_->setDirection(QTimeLine::Backward); // 1.0 -> 0.0
|
||||
timeline_fade_->start();
|
||||
}
|
||||
timeline_fade_->start();
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::DrawImage(QPainter *p, const QPixmap &pixmap, const qreal opacity) {
|
||||
|
||||
if (qFuzzyCompare(opacity, static_cast<qreal>(0.0))) return;
|
||||
|
||||
p->setOpacity(opacity);
|
||||
p->drawPixmap(0, 0, pixmap.width(), pixmap.height(), pixmap);
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::DrawSpinner(QPainter *p) {
|
||||
|
||||
if (downloading_covers_) {
|
||||
p->drawPixmap(50, 50, 16, 16, spinner_animation_->currentPixmap());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::DrawPreviousCovers(QPainter *p) {
|
||||
|
||||
for (std::shared_ptr<PreviousCover> previous_cover : previous_covers_) {
|
||||
DrawImage(p, previous_cover->pixmap, previous_cover->opacity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::FadeCurrentCover(const qreal value) {
|
||||
|
||||
if (value <= pixmap_current_opacity_) return;
|
||||
|
||||
pixmap_current_opacity_ = value;
|
||||
update();
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::FadeCurrentCoverFinished() {
|
||||
|
||||
if (image_original_ == image_strawberry_) {
|
||||
emit FadeStopFinished();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::FadePreviousCover(std::shared_ptr<PreviousCover> previous_cover) {
|
||||
|
||||
if (previous_cover->timeline->currentValue() >= previous_cover->opacity) return;
|
||||
|
||||
previous_cover->opacity = previous_cover->timeline->currentValue();
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::FadePreviousCoverFinished(std::shared_ptr<PreviousCover> previous_cover) {
|
||||
|
||||
previous_covers_.removeAll(previous_cover);
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::ScaleCover() {
|
||||
|
||||
QImage image = ImageUtils::ScaleAndPad(image_original_, cover_loader_options_.scale_output_image_, cover_loader_options_.pad_output_image_, cover_loader_options_.desired_height_);
|
||||
if (image.isNull()) {
|
||||
pixmap_current_ = QPixmap();
|
||||
}
|
||||
else {
|
||||
pixmap_current_ = QPixmap::fromImage(image);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbum::ScalePreviousCovers() {
|
||||
|
||||
for (std::shared_ptr<PreviousCover> previous_cover : previous_covers_) {
|
||||
QImage image = ImageUtils::ScaleAndPad(previous_cover->image, cover_loader_options_.scale_output_image_, cover_loader_options_.pad_output_image_, cover_loader_options_.desired_height_);
|
||||
if (image.isNull()) {
|
||||
previous_cover->pixmap = QPixmap();
|
||||
}
|
||||
else {
|
||||
previous_cover->pixmap = QPixmap::fromImage(image);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2020-2022, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <QtGlobal>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QImage>
|
||||
#include <QPixmap>
|
||||
@@ -50,15 +51,31 @@ class ContextAlbum : public QWidget {
|
||||
|
||||
void Init(ContextView *context_view, AlbumCoverChoiceController *album_cover_choice_controller);
|
||||
void SetImage(QImage image = QImage());
|
||||
void UpdateWidth(const int width);
|
||||
|
||||
protected:
|
||||
QSize sizeHint() const override;
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
void mouseDoubleClickEvent(QMouseEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
|
||||
private:
|
||||
void DrawImage(QPainter *p);
|
||||
|
||||
struct PreviousCover {
|
||||
PreviousCover() : opacity(0.0) {}
|
||||
QImage image;
|
||||
QPixmap pixmap;
|
||||
qreal opacity;
|
||||
std::shared_ptr<QTimeLine> timeline;
|
||||
};
|
||||
|
||||
QList<std::shared_ptr<PreviousCover>> previous_covers_;
|
||||
|
||||
void DrawImage(QPainter *p, const QPixmap &pixmap, const qreal opacity);
|
||||
void DrawSpinner(QPainter *p);
|
||||
void DrawPreviousCovers(QPainter *p);
|
||||
void ScaleCover();
|
||||
void ScalePreviousCovers();
|
||||
void GetCoverAutomatically();
|
||||
|
||||
signals:
|
||||
@@ -67,13 +84,16 @@ class ContextAlbum : public QWidget {
|
||||
private slots:
|
||||
void Update() { update(); }
|
||||
void AutomaticCoverSearchDone();
|
||||
void FadePreviousTrack(const qreal value);
|
||||
void FadeCurrentCover(const qreal value);
|
||||
void FadeCurrentCoverFinished();
|
||||
void FadePreviousCover(std::shared_ptr<PreviousCover> previouscover);
|
||||
void FadePreviousCoverFinished(std::shared_ptr<PreviousCover> previouscover);
|
||||
|
||||
public slots:
|
||||
void SearchCoverInProgress();
|
||||
|
||||
private:
|
||||
static const int kWidgetSpacing;
|
||||
static const int kFadeTimeLineMs;
|
||||
|
||||
private:
|
||||
QMenu *menu_;
|
||||
@@ -84,12 +104,9 @@ class ContextAlbum : public QWidget {
|
||||
QTimeLine *timeline_fade_;
|
||||
QImage image_strawberry_;
|
||||
QImage image_original_;
|
||||
QImage image_previous_;
|
||||
QPixmap pixmap_current_;
|
||||
QPixmap pixmap_previous_;
|
||||
qreal pixmap_previous_opacity_;
|
||||
qreal pixmap_current_opacity_;
|
||||
std::unique_ptr<QMovie> spinner_animation_;
|
||||
int prev_width_;
|
||||
};
|
||||
|
||||
#endif // CONTEXTALBUM_H
|
||||
|
||||
@@ -1,390 +0,0 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This code was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2013-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
|
||||
#include <QObject>
|
||||
#include <QtGlobal>
|
||||
#include <QMutex>
|
||||
#include <QMimeData>
|
||||
#include <QMetaType>
|
||||
#include <QVariant>
|
||||
#include <QList>
|
||||
#include <QSet>
|
||||
#include <QRegularExpression>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
#include <QImage>
|
||||
#include <QPixmapCache>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/database.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "collection/collectionquery.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
#include "collection/collectionmodel.h"
|
||||
#include "collection/collectionitem.h"
|
||||
#include "playlist/playlistmanager.h"
|
||||
#include "playlist/songmimedata.h"
|
||||
#include "covermanager/albumcoverloader.h"
|
||||
#include "covermanager/albumcoverloaderoptions.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
|
||||
#include "contextalbumsmodel.h"
|
||||
|
||||
const int ContextAlbumsModel::kPrettyCoverSize = 32;
|
||||
|
||||
ContextAlbumsModel::ContextAlbumsModel(CollectionBackend *backend, Application *app, QObject *parent)
|
||||
: SimpleTreeModel<CollectionItem>(new CollectionItem(this), parent),
|
||||
backend_(backend),
|
||||
app_(app),
|
||||
album_icon_(IconLoader::Load("cdcase")) {
|
||||
|
||||
root_->lazy_loaded = true;
|
||||
|
||||
cover_loader_options_.get_image_data_ = false;
|
||||
cover_loader_options_.scale_output_image_ = true;
|
||||
cover_loader_options_.pad_output_image_ = true;
|
||||
cover_loader_options_.desired_height_ = kPrettyCoverSize;
|
||||
|
||||
QObject::connect(app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &ContextAlbumsModel::AlbumCoverLoaded);
|
||||
|
||||
QIcon nocover = IconLoader::Load("cdcase");
|
||||
QList<QSize> nocover_sizes = nocover.availableSizes();
|
||||
no_cover_icon_ = nocover.pixmap(nocover_sizes.last()).scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
}
|
||||
|
||||
ContextAlbumsModel::~ContextAlbumsModel() { delete root_; }
|
||||
|
||||
void ContextAlbumsModel::AddSongs(const SongList &songs) {
|
||||
|
||||
for (const Song &song : songs) {
|
||||
if (song_nodes_.contains(song.id())) continue;
|
||||
QString key = CollectionModel::ContainerKey(CollectionModel::GroupBy_Album, song);
|
||||
CollectionItem *container = nullptr;
|
||||
if (container_nodes_.contains(key)) {
|
||||
container = container_nodes_[key];
|
||||
}
|
||||
else {
|
||||
container = ItemFromSong(CollectionItem::Type_Container, true, root_, song, 0);
|
||||
container_nodes_.insert(key, container);
|
||||
}
|
||||
song_nodes_[song.id()] = ItemFromSong(CollectionItem::Type_Song, true, container, song, -1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString ContextAlbumsModel::AlbumIconPixmapCacheKey(const QModelIndex &idx) {
|
||||
|
||||
QStringList path;
|
||||
QModelIndex index_copy(idx);
|
||||
while (index_copy.isValid()) {
|
||||
path.prepend(index_copy.data().toString());
|
||||
index_copy = index_copy.parent();
|
||||
}
|
||||
return "contextalbumsart:" + path.join("/");
|
||||
|
||||
}
|
||||
|
||||
QVariant ContextAlbumsModel::AlbumIcon(const QModelIndex &idx) {
|
||||
|
||||
CollectionItem *item = IndexToItem(idx);
|
||||
if (!item) return no_cover_icon_;
|
||||
|
||||
// Check the cache for a pixmap we already loaded.
|
||||
const QString cache_key = AlbumIconPixmapCacheKey(idx);
|
||||
|
||||
QPixmap cached_pixmap;
|
||||
if (QPixmapCache::find(cache_key, &cached_pixmap)) {
|
||||
return cached_pixmap;
|
||||
}
|
||||
|
||||
// Maybe we're loading a pixmap already?
|
||||
if (pending_cache_keys_.contains(cache_key)) {
|
||||
return no_cover_icon_;
|
||||
}
|
||||
|
||||
// No art is cached and we're not loading it already. Load art for the first song in the album.
|
||||
SongList songs = GetChildSongs(idx);
|
||||
if (!songs.isEmpty()) {
|
||||
const quint64 id = app_->album_cover_loader()->LoadImageAsync(cover_loader_options_, songs.first());
|
||||
pending_art_.insert(id, ItemAndCacheKey(item, cache_key));
|
||||
pending_cache_keys_.insert(cache_key);
|
||||
}
|
||||
|
||||
return no_cover_icon_;
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsModel::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result) {
|
||||
|
||||
if (!pending_art_.contains(id)) return;
|
||||
|
||||
ItemAndCacheKey item_and_cache_key = pending_art_.take(id);
|
||||
|
||||
CollectionItem *item = item_and_cache_key.first;
|
||||
if (!item) return;
|
||||
|
||||
const QString &cache_key = item_and_cache_key.second;
|
||||
if (pending_cache_keys_.contains(cache_key)) {
|
||||
pending_cache_keys_.remove(cache_key);
|
||||
}
|
||||
|
||||
// Insert this image in the cache.
|
||||
if (!result.success || result.image_scaled.isNull() || result.type == AlbumCoverLoaderResult::Type_ManuallyUnset) {
|
||||
// Set the no_cover image so we don't continually try to load art.
|
||||
QPixmapCache::insert(cache_key, no_cover_icon_);
|
||||
}
|
||||
else {
|
||||
QPixmap image_pixmap;
|
||||
image_pixmap = QPixmap::fromImage(result.image_scaled);
|
||||
QPixmapCache::insert(cache_key, image_pixmap);
|
||||
}
|
||||
|
||||
const QModelIndex idx = ItemToIndex(item);
|
||||
|
||||
emit dataChanged(idx, idx);
|
||||
|
||||
}
|
||||
|
||||
QVariant ContextAlbumsModel::data(const QModelIndex &idx, int role) const {
|
||||
|
||||
const CollectionItem *item = IndexToItem(idx);
|
||||
|
||||
if (role == Qt::DecorationRole && item->type == CollectionItem::Type_Container && item->container_level == 0) {
|
||||
return const_cast<ContextAlbumsModel*>(this)->AlbumIcon(idx);
|
||||
}
|
||||
|
||||
return data(item, role);
|
||||
|
||||
}
|
||||
|
||||
QVariant ContextAlbumsModel::data(const CollectionItem *item, int role) const {
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
case Qt::ToolTipRole:
|
||||
return item->DisplayText();
|
||||
|
||||
case Qt::DecorationRole:
|
||||
switch (item->type) {
|
||||
case CollectionItem::Type_Container:
|
||||
if (item->type == CollectionItem::Type_Container && item->container_level == 0) { return album_icon_; }
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case Role_Type:
|
||||
return item->type;
|
||||
|
||||
case Role_ContainerType:
|
||||
return item->type;
|
||||
|
||||
case Role_Key:
|
||||
return item->key;
|
||||
|
||||
case Role_Artist:
|
||||
return item->metadata.artist();
|
||||
|
||||
case Role_Editable:
|
||||
if (item->type == CollectionItem::Type_Container) {
|
||||
// if we have even one non editable item as a child, we ourselves are not available for edit
|
||||
if (!item->children.isEmpty()) {
|
||||
for (CollectionItem *child : item->children) {
|
||||
if (!data(child, role).toBool()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (item->type == CollectionItem::Type_Song) {
|
||||
return item->metadata.IsEditable();
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
case Role_SortText:
|
||||
return item->SortText();
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsModel::Reset() {
|
||||
|
||||
for (QMap<QString, CollectionItem*>::const_iterator it = container_nodes_.constBegin(); it != container_nodes_.constEnd(); ++it) {
|
||||
const QString cache_key = AlbumIconPixmapCacheKey(ItemToIndex(it.value()));
|
||||
QPixmapCache::remove(cache_key);
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
delete root_;
|
||||
song_nodes_.clear();
|
||||
container_nodes_.clear();
|
||||
pending_art_.clear();
|
||||
pending_cache_keys_.clear();
|
||||
|
||||
root_ = new CollectionItem(this);
|
||||
root_->lazy_loaded = true;
|
||||
endResetModel();
|
||||
|
||||
}
|
||||
|
||||
CollectionItem *ContextAlbumsModel::ItemFromSong(CollectionItem::Type item_type, const bool signal, CollectionItem *parent, const Song &s, const int container_level) {
|
||||
|
||||
if (signal) beginInsertRows(ItemToIndex(parent), static_cast<int>(parent->children.count()), static_cast<int>(parent->children.count()));
|
||||
|
||||
CollectionItem *item = new CollectionItem(item_type, parent);
|
||||
item->container_level = container_level;
|
||||
item->lazy_loaded = true;
|
||||
|
||||
if (item_type == CollectionItem::Type_Container) {
|
||||
item->key = CollectionModel::ContainerKey(CollectionModel::GroupBy_Album, s);
|
||||
item->display_text = CollectionModel::TextOrUnknown(s.album());
|
||||
item->sort_text = CollectionModel::SortTextForArtist(s.album());
|
||||
}
|
||||
else {
|
||||
item->key = s.album() + " " + s.title();
|
||||
item->display_text = CollectionModel::TextOrUnknown(s.title());
|
||||
item->sort_text = CollectionModel::SortTextForSong(s);
|
||||
item->metadata = s;
|
||||
}
|
||||
|
||||
if (signal) endInsertRows();
|
||||
|
||||
return item;
|
||||
|
||||
}
|
||||
|
||||
Qt::ItemFlags ContextAlbumsModel::flags(const QModelIndex &idx) const {
|
||||
|
||||
switch (IndexToItem(idx)->type) {
|
||||
case CollectionItem::Type_Song:
|
||||
case CollectionItem::Type_Container:
|
||||
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled;
|
||||
case CollectionItem::Type_Root:
|
||||
case CollectionItem::Type_LoadingIndicator:
|
||||
default:
|
||||
return Qt::ItemIsEnabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QStringList ContextAlbumsModel::mimeTypes() const {
|
||||
return QStringList() << "text/uri-list";
|
||||
}
|
||||
|
||||
QMimeData *ContextAlbumsModel::mimeData(const QModelIndexList &indexes) const {
|
||||
|
||||
if (indexes.isEmpty()) return nullptr;
|
||||
|
||||
SongMimeData *data = new SongMimeData;
|
||||
QList<QUrl> urls;
|
||||
QSet<int> song_ids;
|
||||
|
||||
data->backend = backend_;
|
||||
|
||||
for (const QModelIndex &idx : indexes) {
|
||||
GetChildSongs(IndexToItem(idx), &urls, &data->songs, &song_ids);
|
||||
}
|
||||
|
||||
data->setUrls(urls);
|
||||
data->name_for_new_playlist_ = PlaylistManager::GetNameForNewPlaylist(data->songs);
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
bool ContextAlbumsModel::CompareItems(const CollectionItem *a, const CollectionItem *b) const {
|
||||
|
||||
QVariant left(data(a, ContextAlbumsModel::Role_SortText));
|
||||
QVariant right(data(b, ContextAlbumsModel::Role_SortText));
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
if (left.metaType().id() == QMetaType::Int)
|
||||
#else
|
||||
if (left.type() == QVariant::Int)
|
||||
#endif
|
||||
return left.toInt() < right.toInt();
|
||||
else return left.toString() < right.toString();
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsModel::GetChildSongs(CollectionItem *item, QList<QUrl> *urls, SongList *songs, QSet<int> *song_ids) const {
|
||||
|
||||
switch (item->type) {
|
||||
case CollectionItem::Type_Container:{
|
||||
|
||||
QList<CollectionItem*> children = item->children;
|
||||
std::sort(children.begin(), children.end(), std::bind(&ContextAlbumsModel::CompareItems, this, std::placeholders::_1, std::placeholders::_2));
|
||||
|
||||
for (CollectionItem *child : children) {
|
||||
GetChildSongs(child, urls, songs, song_ids);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CollectionItem::Type_Song:
|
||||
urls->append(item->metadata.url());
|
||||
if (!song_ids->contains(item->metadata.id())) {
|
||||
songs->append(item->metadata);
|
||||
song_ids->insert(item->metadata.id());
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SongList ContextAlbumsModel::GetChildSongs(const QModelIndexList &indexes) const {
|
||||
|
||||
QList<QUrl> dontcare;
|
||||
SongList ret;
|
||||
QSet<int> song_ids;
|
||||
|
||||
for (const QModelIndex &idx : indexes) {
|
||||
GetChildSongs(IndexToItem(idx), &dontcare, &ret, &song_ids);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
SongList ContextAlbumsModel::GetChildSongs(const QModelIndex &idx) const {
|
||||
return GetChildSongs(QModelIndexList() << idx);
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This code was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2013-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CONTEXTALBUMSMODEL_H
|
||||
#define CONTEXTALBUMSMODEL_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QPair>
|
||||
#include <QSet>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
#include <QImage>
|
||||
#include <QPixmap>
|
||||
#include <QIcon>
|
||||
|
||||
#include "core/simpletreemodel.h"
|
||||
#include "core/song.h"
|
||||
#include "collection/collectionquery.h"
|
||||
#include "collection/collectionitem.h"
|
||||
#include "covermanager/albumcoverloaderoptions.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
|
||||
class QMimeData;
|
||||
|
||||
class Application;
|
||||
class CollectionBackend;
|
||||
class CollectionItem;
|
||||
|
||||
class ContextAlbumsModel : public SimpleTreeModel<CollectionItem> {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ContextAlbumsModel(CollectionBackend *backend, Application *app, QObject *parent = nullptr);
|
||||
~ContextAlbumsModel() override;
|
||||
|
||||
static const int kPrettyCoverSize;
|
||||
|
||||
enum Role {
|
||||
Role_Type = Qt::UserRole + 1,
|
||||
Role_ContainerType,
|
||||
Role_SortText,
|
||||
Role_Key,
|
||||
Role_Artist,
|
||||
Role_Editable,
|
||||
LastRole
|
||||
};
|
||||
|
||||
void GetChildSongs(CollectionItem *item, QList<QUrl> *urls, SongList *songs, QSet<int> *song_ids) const;
|
||||
SongList GetChildSongs(const QModelIndex &idx) const;
|
||||
SongList GetChildSongs(const QModelIndexList &indexes) const;
|
||||
|
||||
QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &idx) const override;
|
||||
QStringList mimeTypes() const override;
|
||||
QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
|
||||
void Reset();
|
||||
void AddSongs(const SongList &songs);
|
||||
|
||||
private slots:
|
||||
void AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result);
|
||||
|
||||
private:
|
||||
CollectionItem *ItemFromSong(CollectionItem::Type item_type, const bool signal, CollectionItem *parent, const Song &s, const int container_level);
|
||||
|
||||
static QString AlbumIconPixmapCacheKey(const QModelIndex &idx);
|
||||
QVariant AlbumIcon(const QModelIndex &idx);
|
||||
QVariant data(const CollectionItem *item, int role) const;
|
||||
bool CompareItems(const CollectionItem *a, const CollectionItem *b) const;
|
||||
|
||||
private:
|
||||
CollectionBackend *backend_;
|
||||
Application *app_;
|
||||
QueryOptions query_options_;
|
||||
QMap<QString, CollectionItem*> container_nodes_;
|
||||
QMap<int, CollectionItem*> song_nodes_;
|
||||
QIcon album_icon_;
|
||||
QPixmap no_cover_icon_;
|
||||
AlbumCoverLoaderOptions cover_loader_options_;
|
||||
typedef QPair<CollectionItem*, QString> ItemAndCacheKey;
|
||||
QMap<quint64, ItemAndCacheKey> pending_art_;
|
||||
QSet<QString> pending_cache_keys_;
|
||||
};
|
||||
|
||||
#endif // CONTEXTALBUMSMODEL_H
|
||||
@@ -1,434 +0,0 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This code was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2013-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <qcoreevent.h>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QTreeView>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QAbstractItemView>
|
||||
#include <QStyleOptionViewItem>
|
||||
#include <QAbstractScrollArea>
|
||||
#include <QMimeData>
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
#include <QLocale>
|
||||
#include <QMessageBox>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
#include <QRect>
|
||||
#include <QSize>
|
||||
#include <QToolTip>
|
||||
#include <QWhatsThis>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/mimedata.h"
|
||||
#include "core/utilities.h"
|
||||
#include "collection/collectiondirectorymodel.h"
|
||||
#include "collection/collectionmodel.h"
|
||||
#include "collection/collectionitem.h"
|
||||
#ifndef Q_OS_WIN
|
||||
# include "device/devicemanager.h"
|
||||
# include "device/devicestatefiltermodel.h"
|
||||
#endif
|
||||
#include "dialogs/edittagdialog.h"
|
||||
#include "organize/organizedialog.h"
|
||||
|
||||
#include "contextalbumsmodel.h"
|
||||
#include "contextalbumsview.h"
|
||||
|
||||
ContextItemDelegate::ContextItemDelegate(QObject *parent) : QStyledItemDelegate(parent) {}
|
||||
|
||||
bool ContextItemDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &idx) {
|
||||
|
||||
return true;
|
||||
|
||||
Q_UNUSED(option);
|
||||
|
||||
if (!event || !view) return false;
|
||||
|
||||
QString text = displayText(idx.data(), QLocale::system());
|
||||
|
||||
if (text.isEmpty() || !event) return false;
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::ToolTip: {
|
||||
|
||||
QSize real_text = sizeHint(option, idx);
|
||||
QRect displayed_text = view->visualRect(idx);
|
||||
bool is_elided = displayed_text.width() < real_text.width();
|
||||
|
||||
if (is_elided) {
|
||||
QToolTip::showText(event->globalPos(), text, view);
|
||||
}
|
||||
else if (idx.data(Qt::ToolTipRole).isValid()) {
|
||||
// If the item has a tooltip text, display it
|
||||
QString tooltip_text = idx.data(Qt::ToolTipRole).toString();
|
||||
QToolTip::showText(event->globalPos(), tooltip_text, view);
|
||||
}
|
||||
else {
|
||||
// in case that another text was previously displayed
|
||||
QToolTip::hideText();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
case QEvent::QueryWhatsThis:
|
||||
return true;
|
||||
|
||||
case QEvent::WhatsThis:
|
||||
QWhatsThis::showText(event->globalPos(), text, view);
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
ContextAlbumsView::ContextAlbumsView(QWidget *parent)
|
||||
: AutoExpandingTreeView(parent),
|
||||
app_(nullptr),
|
||||
context_menu_(nullptr),
|
||||
load_(nullptr),
|
||||
add_to_playlist_(nullptr),
|
||||
add_to_playlist_enqueue_(nullptr),
|
||||
open_in_new_playlist_(nullptr),
|
||||
organize_(nullptr),
|
||||
#ifndef Q_OS_WIN
|
||||
copy_to_device_(nullptr),
|
||||
#endif
|
||||
edit_track_(nullptr),
|
||||
edit_tracks_(nullptr),
|
||||
show_in_browser_(nullptr),
|
||||
is_in_keyboard_search_(false),
|
||||
model_(nullptr) {
|
||||
|
||||
setStyleSheet("border: none;");
|
||||
|
||||
setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
|
||||
setItemDelegate(new ContextItemDelegate(this));
|
||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
setHeaderHidden(true);
|
||||
setAllColumnsShowFocus(true);
|
||||
setDragEnabled(true);
|
||||
setDragDropMode(QAbstractItemView::DragOnly);
|
||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
SetAddOnDoubleClick(false);
|
||||
|
||||
}
|
||||
|
||||
ContextAlbumsView::~ContextAlbumsView() = default;
|
||||
|
||||
void ContextAlbumsView::SaveFocus() {
|
||||
|
||||
QModelIndex current = currentIndex();
|
||||
QVariant type = model()->data(current, ContextAlbumsModel::Role_Type);
|
||||
if (!type.isValid() || !(type.toInt() == CollectionItem::Type_Song || type.toInt() == CollectionItem::Type_Container || type.toInt() == CollectionItem::Type_Divider)) {
|
||||
return;
|
||||
}
|
||||
|
||||
last_selected_path_.clear();
|
||||
last_selected_song_ = Song();
|
||||
last_selected_container_ = QString();
|
||||
|
||||
switch (type.toInt()) {
|
||||
case CollectionItem::Type_Song: {
|
||||
QModelIndex index = current;
|
||||
SongList songs = model_->GetChildSongs(index);
|
||||
if (!songs.isEmpty()) {
|
||||
last_selected_song_ = songs.last();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CollectionItem::Type_Container:
|
||||
case CollectionItem::Type_Divider: {
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
SaveContainerPath(current);
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsView::SaveContainerPath(const QModelIndex &child) {
|
||||
|
||||
QModelIndex current = model()->parent(child);
|
||||
QVariant type = model()->data(current, ContextAlbumsModel::Role_Type);
|
||||
if (!type.isValid() || !(type.toInt() == CollectionItem::Type_Container || type.toInt() == CollectionItem::Type_Divider)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString text = model()->data(current, ContextAlbumsModel::Role_SortText).toString();
|
||||
last_selected_path_ << text;
|
||||
SaveContainerPath(current);
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsView::RestoreFocus() {
|
||||
|
||||
if (last_selected_container_.isEmpty() && last_selected_song_.url().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
RestoreLevelFocus();
|
||||
|
||||
}
|
||||
|
||||
bool ContextAlbumsView::RestoreLevelFocus(const QModelIndex &parent) {
|
||||
|
||||
if (model()->canFetchMore(parent)) {
|
||||
model()->fetchMore(parent);
|
||||
}
|
||||
int rows = model()->rowCount(parent);
|
||||
for (int i = 0; i < rows; i++) {
|
||||
QModelIndex current = model()->index(i, 0, parent);
|
||||
QVariant type = model()->data(current, ContextAlbumsModel::Role_Type);
|
||||
switch (type.toInt()) {
|
||||
case CollectionItem::Type_Song:
|
||||
if (!last_selected_song_.url().isEmpty()) {
|
||||
QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(current);
|
||||
const SongList songs = model_->GetChildSongs(index);
|
||||
if (std::any_of(songs.begin(), songs.end(), [this](const Song &song) { return song == last_selected_song_; })) {
|
||||
setCurrentIndex(current);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsView::Init(Application *app) {
|
||||
|
||||
app_ = app;
|
||||
|
||||
model_ = new ContextAlbumsModel(app_->collection_backend(), app_, this);
|
||||
model_->Reset();
|
||||
|
||||
setModel(model_);
|
||||
|
||||
QObject::connect(model_, &ContextAlbumsModel::modelAboutToBeReset, this, &ContextAlbumsView::SaveFocus);
|
||||
QObject::connect(model_, &ContextAlbumsModel::modelReset, this, &ContextAlbumsView::RestoreFocus);
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsView::paintEvent(QPaintEvent *event) {
|
||||
QTreeView::paintEvent(event);
|
||||
}
|
||||
|
||||
void ContextAlbumsView::mouseReleaseEvent(QMouseEvent *e) {
|
||||
QTreeView::mouseReleaseEvent(e);
|
||||
}
|
||||
|
||||
void ContextAlbumsView::contextMenuEvent(QContextMenuEvent *e) {
|
||||
|
||||
if (!context_menu_) {
|
||||
context_menu_ = new QMenu(this);
|
||||
|
||||
add_to_playlist_ = context_menu_->addAction(IconLoader::Load("media-playback-start"), tr("Append to current playlist"), this, &ContextAlbumsView::AddToPlaylist);
|
||||
load_ = context_menu_->addAction(IconLoader::Load("media-playback-start"), tr("Replace current playlist"), this, &ContextAlbumsView::Load);
|
||||
open_in_new_playlist_ = context_menu_->addAction(IconLoader::Load("document-new"), tr("Open in new playlist"), this, &ContextAlbumsView::OpenInNewPlaylist);
|
||||
|
||||
context_menu_->addSeparator();
|
||||
add_to_playlist_enqueue_ = context_menu_->addAction(IconLoader::Load("go-next"), tr("Queue track"), this, &ContextAlbumsView::AddToPlaylistEnqueue);
|
||||
|
||||
context_menu_->addSeparator();
|
||||
organize_ = context_menu_->addAction(IconLoader::Load("edit-copy"), tr("Organize files..."), this, &ContextAlbumsView::Organize);
|
||||
#ifndef Q_OS_WIN
|
||||
copy_to_device_ = context_menu_->addAction(IconLoader::Load("device"), tr("Copy to device..."), this, &ContextAlbumsView::CopyToDevice);
|
||||
#endif
|
||||
|
||||
context_menu_->addSeparator();
|
||||
edit_track_ = context_menu_->addAction(IconLoader::Load("edit-rename"), tr("Edit track information..."), this, &ContextAlbumsView::EditTracks);
|
||||
edit_tracks_ = context_menu_->addAction(IconLoader::Load("edit-rename"), tr("Edit tracks information..."), this, &ContextAlbumsView::EditTracks);
|
||||
show_in_browser_ = context_menu_->addAction(IconLoader::Load("document-open-folder"), tr("Show in file browser..."), this, &ContextAlbumsView::ShowInBrowser);
|
||||
|
||||
context_menu_->addSeparator();
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
copy_to_device_->setDisabled(app_->device_manager()->connected_devices_model()->rowCount() == 0);
|
||||
QObject::connect(app_->device_manager()->connected_devices_model(), &DeviceStateFilterModel::IsEmptyChanged, copy_to_device_, &QAction::setDisabled);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
context_menu_index_ = indexAt(e->pos());
|
||||
if (!context_menu_index_.isValid()) return;
|
||||
QModelIndexList selected_indexes = selectionModel()->selectedRows();
|
||||
|
||||
int regular_elements = 0;
|
||||
int regular_editable = 0;
|
||||
|
||||
for (const QModelIndex &idx : selected_indexes) {
|
||||
regular_elements++;
|
||||
if (model_->data(idx, ContextAlbumsModel::Role_Editable).toBool()) {
|
||||
regular_editable++;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check if custom plugin actions should be enabled / visible
|
||||
const int songs_selected = regular_elements;
|
||||
const bool regular_elements_only = songs_selected == regular_elements && regular_elements > 0;
|
||||
|
||||
// in all modes
|
||||
load_->setEnabled(songs_selected > 0);
|
||||
add_to_playlist_->setEnabled(songs_selected > 0);
|
||||
open_in_new_playlist_->setEnabled(songs_selected > 0);
|
||||
add_to_playlist_enqueue_->setEnabled(songs_selected > 0);
|
||||
|
||||
// if neither edit_track not edit_tracks are available, we show disabled edit_track element
|
||||
edit_track_->setVisible(regular_editable <= 1);
|
||||
edit_track_->setEnabled(regular_editable == 1);
|
||||
|
||||
organize_->setVisible(regular_elements_only);
|
||||
#ifndef Q_OS_WIN
|
||||
copy_to_device_->setVisible(regular_elements_only);
|
||||
#endif
|
||||
|
||||
// only when all selected items are editable
|
||||
organize_->setEnabled(regular_elements == regular_editable);
|
||||
#ifndef Q_OS_WIN
|
||||
copy_to_device_->setEnabled(regular_elements == regular_editable);
|
||||
#endif
|
||||
|
||||
context_menu_->popup(e->globalPos());
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsView::Load() {
|
||||
|
||||
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||
if (MimeData *mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||
mimedata->clear_first_ = true;
|
||||
}
|
||||
emit AddToPlaylistSignal(q_mimedata);
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsView::AddToPlaylist() {
|
||||
|
||||
emit AddToPlaylistSignal(model()->mimeData(selectedIndexes()));
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsView::AddToPlaylistEnqueue() {
|
||||
|
||||
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||
if (MimeData *mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||
mimedata->enqueue_now_ = true;
|
||||
}
|
||||
emit AddToPlaylistSignal(q_mimedata);
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsView::OpenInNewPlaylist() {
|
||||
|
||||
QMimeData *q_mimedata = model()->mimeData(selectedIndexes());
|
||||
if (MimeData *mimedata = qobject_cast<MimeData*>(q_mimedata)) {
|
||||
mimedata->open_in_new_playlist_ = true;
|
||||
}
|
||||
emit AddToPlaylistSignal(q_mimedata);
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsView::scrollTo(const QModelIndex &idx, ScrollHint hint) {
|
||||
|
||||
if (is_in_keyboard_search_) {
|
||||
QTreeView::scrollTo(idx, QAbstractItemView::PositionAtTop);
|
||||
}
|
||||
else {
|
||||
QTreeView::scrollTo(idx, hint);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SongList ContextAlbumsView::GetSelectedSongs() const {
|
||||
QModelIndexList selected_indexes = selectionModel()->selectedRows();
|
||||
return model_->GetChildSongs(selected_indexes);
|
||||
}
|
||||
|
||||
void ContextAlbumsView::Organize() {
|
||||
|
||||
if (!organize_dialog_) {
|
||||
organize_dialog_ = std::make_unique<OrganizeDialog>(app_->task_manager(), app_->collection_backend(), this);
|
||||
}
|
||||
|
||||
organize_dialog_->SetDestinationModel(app_->collection_model()->directory_model());
|
||||
organize_dialog_->SetCopy(false);
|
||||
if (organize_dialog_->SetSongs(GetSelectedSongs())) {
|
||||
organize_dialog_->show();
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this, tr("Error"), tr("None of the selected songs were suitable for copying to a device"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsView::EditTracks() {
|
||||
|
||||
if (!edit_tag_dialog_) {
|
||||
edit_tag_dialog_ = std::make_unique<EditTagDialog>(app_, this);
|
||||
}
|
||||
edit_tag_dialog_->SetSongs(GetSelectedSongs());
|
||||
edit_tag_dialog_->show();
|
||||
|
||||
}
|
||||
|
||||
void ContextAlbumsView::CopyToDevice() {
|
||||
#ifndef Q_OS_WIN
|
||||
if (!organize_dialog_) {
|
||||
organize_dialog_ = std::make_unique<OrganizeDialog>(app_->task_manager(), nullptr, this);
|
||||
}
|
||||
|
||||
organize_dialog_->SetDestinationModel(app_->device_manager()->connected_devices_model(), true);
|
||||
organize_dialog_->SetCopy(true);
|
||||
organize_dialog_->SetSongs(GetSelectedSongs());
|
||||
organize_dialog_->show();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ContextAlbumsView::ShowInBrowser() const {
|
||||
|
||||
const SongList songs = GetSelectedSongs();
|
||||
QList<QUrl> urls;
|
||||
urls.reserve(songs.count());
|
||||
for (const Song &song : songs) {
|
||||
urls << song.url();
|
||||
}
|
||||
|
||||
Utilities::OpenInFileBrowser(urls);
|
||||
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This code was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2013-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CONTEXTALBUMSVIEW_H
|
||||
#define CONTEXTALBUMSVIEW_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QAbstractItemView>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QStyleOption>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
|
||||
#include "core/song.h"
|
||||
#include "widgets/autoexpandingtreeview.h"
|
||||
|
||||
class QWidget;
|
||||
class QMenu;
|
||||
class QAction;
|
||||
class QContextMenuEvent;
|
||||
class QHelpEvent;
|
||||
class QMouseEvent;
|
||||
class QPaintEvent;
|
||||
|
||||
class Application;
|
||||
class ContextAlbumsModel;
|
||||
class EditTagDialog;
|
||||
class OrganizeDialog;
|
||||
|
||||
class ContextItemDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ContextItemDelegate(QObject *parent);
|
||||
|
||||
public slots:
|
||||
bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &idx) override;
|
||||
};
|
||||
|
||||
class ContextAlbumsView : public AutoExpandingTreeView {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ContextAlbumsView(QWidget *parent = nullptr);
|
||||
~ContextAlbumsView() override;
|
||||
|
||||
// Returns Songs currently selected in the collection view.
|
||||
// Please note that the selection is recursive meaning that if for example an album is selected this will return all of it's songs.
|
||||
SongList GetSelectedSongs() const;
|
||||
|
||||
void Init(Application *app);
|
||||
|
||||
// QTreeView
|
||||
void scrollTo(const QModelIndex &idx, ScrollHint hint = EnsureVisible) override;
|
||||
|
||||
ContextAlbumsModel *albums_model() { return model_; }
|
||||
|
||||
public slots:
|
||||
void SaveFocus();
|
||||
void RestoreFocus();
|
||||
|
||||
protected:
|
||||
// QWidget
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
|
||||
private slots:
|
||||
void Load();
|
||||
void AddToPlaylist();
|
||||
void AddToPlaylistEnqueue();
|
||||
void OpenInNewPlaylist();
|
||||
void Organize();
|
||||
void CopyToDevice();
|
||||
void EditTracks();
|
||||
void ShowInBrowser() const;
|
||||
|
||||
private:
|
||||
void RecheckIsEmpty();
|
||||
bool RestoreLevelFocus(const QModelIndex &parent = QModelIndex());
|
||||
void SaveContainerPath(const QModelIndex &child);
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
|
||||
QMenu *context_menu_;
|
||||
QModelIndex context_menu_index_;
|
||||
QAction *load_;
|
||||
QAction *add_to_playlist_;
|
||||
QAction *add_to_playlist_enqueue_;
|
||||
QAction *open_in_new_playlist_;
|
||||
QAction *organize_;
|
||||
#ifndef Q_OS_WIN
|
||||
QAction *copy_to_device_;
|
||||
#endif
|
||||
QAction *edit_track_;
|
||||
QAction *edit_tracks_;
|
||||
QAction *show_in_browser_;
|
||||
|
||||
std::unique_ptr<OrganizeDialog> organize_dialog_;
|
||||
std::unique_ptr<EditTagDialog> edit_tag_dialog_;
|
||||
|
||||
bool is_in_keyboard_search_;
|
||||
|
||||
// Save focus
|
||||
Song last_selected_song_;
|
||||
QString last_selected_container_;
|
||||
QSet<QString> last_selected_path_;
|
||||
|
||||
ContextAlbumsModel *model_;
|
||||
|
||||
};
|
||||
|
||||
#endif // CONTEXTALBUMSVIEW_H
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2013-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2013-2022, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <QScrollArea>
|
||||
#include <QSpacerItem>
|
||||
#include <QLabel>
|
||||
#include <QTextEdit>
|
||||
#include <QSettings>
|
||||
#include <QResizeEvent>
|
||||
#include <QContextMenuEvent>
|
||||
@@ -52,6 +53,7 @@
|
||||
#include "core/song.h"
|
||||
#include "core/utilities.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "widgets/resizabletextedit.h"
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/enginetype.h"
|
||||
@@ -66,8 +68,8 @@
|
||||
|
||||
#include "contextview.h"
|
||||
#include "contextalbum.h"
|
||||
#include "contextalbumsmodel.h"
|
||||
#include "contextalbumsview.h"
|
||||
|
||||
const int ContextView::kWidgetSpacing = 50;
|
||||
|
||||
ContextView::ContextView(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
@@ -75,18 +77,17 @@ ContextView::ContextView(QWidget *parent)
|
||||
collectionview_(nullptr),
|
||||
album_cover_choice_controller_(nullptr),
|
||||
lyrics_fetcher_(nullptr),
|
||||
menu_(new QMenu(this)),
|
||||
menu_options_(new QMenu(this)),
|
||||
action_show_album_(nullptr),
|
||||
action_show_data_(nullptr),
|
||||
action_show_output_(nullptr),
|
||||
action_show_albums_(nullptr),
|
||||
action_show_lyrics_(nullptr),
|
||||
action_search_lyrics_(nullptr),
|
||||
layout_container_(new QVBoxLayout()),
|
||||
widget_scrollarea_(new QWidget(this)),
|
||||
layout_scrollarea_(new QVBoxLayout()),
|
||||
scrollarea_(new QScrollArea(this)),
|
||||
label_top_(new QLabel(this)),
|
||||
textedit_top_(new ResizableTextEdit(this)),
|
||||
widget_album_(new ContextAlbum(this)),
|
||||
widget_stacked_(new QStackedWidget(this)),
|
||||
widget_stop_(new QWidget(this)),
|
||||
@@ -94,19 +95,13 @@ ContextView::ContextView(QWidget *parent)
|
||||
layout_stop_(new QVBoxLayout()),
|
||||
layout_play_(new QVBoxLayout()),
|
||||
label_stop_summary_(new QLabel(this)),
|
||||
spacer_stop_bottom_(new QSpacerItem(0, 20, QSizePolicy::Expanding, QSizePolicy::Expanding)),
|
||||
widget_play_data_(new QWidget(this)),
|
||||
widget_play_output_(new QWidget(this)),
|
||||
layout_play_data_(new QGridLayout()),
|
||||
layout_play_output_(new QGridLayout()),
|
||||
label_play_albums_(new QLabel(this)),
|
||||
label_play_lyrics_(new QLabel(this)),
|
||||
widget_albums_(new ContextAlbumsView(this)),
|
||||
//spacer_play_album_(new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Fixed)),
|
||||
textedit_play_lyrics_(new ResizableTextEdit(this)),
|
||||
spacer_play_output_(new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Fixed)),
|
||||
spacer_play_data_(new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Fixed)),
|
||||
spacer_play_albums_(new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Fixed)),
|
||||
spacer_play_bottom_(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding)),
|
||||
label_filetype_title_(new QLabel(this)),
|
||||
label_length_title_(new QLabel(this)),
|
||||
label_samplerate_title_(new QLabel(this)),
|
||||
@@ -125,12 +120,10 @@ ContextView::ContextView(QWidget *parent)
|
||||
label_engine_(new QLabel(this)),
|
||||
label_device_icon_(new QLabel(this)),
|
||||
label_engine_icon_(new QLabel(this)),
|
||||
spacer_bottom_(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding)),
|
||||
lyrics_tried_(false),
|
||||
lyrics_id_(-1),
|
||||
font_size_headline_(0),
|
||||
font_size_normal_(0),
|
||||
prev_width_(0) {
|
||||
font_size_normal_(0) {
|
||||
|
||||
setLayout(layout_container_);
|
||||
|
||||
@@ -143,23 +136,21 @@ ContextView::ContextView(QWidget *parent)
|
||||
scrollarea_->setWidget(widget_scrollarea_);
|
||||
scrollarea_->setContentsMargins(0, 0, 0, 0);
|
||||
scrollarea_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
scrollarea_->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
|
||||
widget_scrollarea_->setObjectName("context-widget-scrollarea");
|
||||
widget_scrollarea_->setLayout(layout_scrollarea_);
|
||||
widget_scrollarea_->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
label_top_->setAlignment(Qt::AlignTop|Qt::AlignLeft);
|
||||
label_top_->setWordWrap(true);
|
||||
label_top_->setMinimumHeight(50);
|
||||
label_top_->setContentsMargins(0, 0, 32, 0);
|
||||
label_top_->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
textedit_top_->setReadOnly(true);
|
||||
textedit_top_->setFrameShape(QFrame::NoFrame);
|
||||
|
||||
layout_scrollarea_->setObjectName("context-layout-scrollarea");
|
||||
layout_scrollarea_->setContentsMargins(15, 15, 15, 15);
|
||||
layout_scrollarea_->addWidget(label_top_);
|
||||
layout_scrollarea_->addWidget(textedit_top_);
|
||||
layout_scrollarea_->addWidget(widget_album_);
|
||||
layout_scrollarea_->addWidget(widget_stacked_);
|
||||
layout_scrollarea_->addSpacerItem(spacer_bottom_);
|
||||
layout_scrollarea_->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding));
|
||||
|
||||
widget_stacked_->setContentsMargins(0, 0, 0, 0);
|
||||
widget_stacked_->addWidget(widget_stop_);
|
||||
@@ -176,9 +167,10 @@ ContextView::ContextView(QWidget *parent)
|
||||
|
||||
// Stopped
|
||||
|
||||
layout_stop_->setContentsMargins(5, 0, 40, 0);
|
||||
label_stop_summary_->setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
|
||||
layout_stop_->setContentsMargins(0, 0, 0, 0);
|
||||
layout_stop_->addWidget(label_stop_summary_);
|
||||
layout_stop_->addSpacerItem(spacer_stop_bottom_);
|
||||
|
||||
// Playing
|
||||
|
||||
@@ -244,33 +236,25 @@ ContextView::ContextView(QWidget *parent)
|
||||
|
||||
widget_play_data_->setLayout(layout_play_data_);
|
||||
|
||||
label_play_lyrics_->setWordWrap(true);
|
||||
label_play_lyrics_->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
textedit_play_lyrics_->setReadOnly(true);
|
||||
textedit_play_lyrics_->setFrameShape(QFrame::NoFrame);
|
||||
textedit_play_lyrics_->hide();
|
||||
|
||||
widget_albums_->hide();
|
||||
label_play_albums_->setWordWrap(true);
|
||||
label_play_albums_->hide();
|
||||
|
||||
layout_play_->setContentsMargins(5, 0, 40, 0);
|
||||
layout_play_->setContentsMargins(0, 0, 0, 0);
|
||||
layout_play_->addWidget(widget_play_output_);
|
||||
layout_play_->addSpacerItem(spacer_play_output_);
|
||||
layout_play_->addWidget(widget_play_data_);
|
||||
layout_play_->addSpacerItem(spacer_play_data_);
|
||||
layout_play_->addWidget(label_play_albums_);
|
||||
layout_play_->addWidget(widget_albums_);
|
||||
layout_play_->addSpacerItem(spacer_play_albums_);
|
||||
layout_play_->addWidget(label_play_lyrics_);
|
||||
layout_play_->addSpacerItem(spacer_play_bottom_);
|
||||
layout_play_->addWidget(textedit_play_lyrics_);
|
||||
layout_play_->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding));
|
||||
|
||||
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_ << label_engine_title_
|
||||
<< label_device_title_
|
||||
<< label_filetype_title_
|
||||
<< label_length_title_
|
||||
<< label_samplerate_title_
|
||||
<< label_bitdepth_title_
|
||||
<< label_bitrate_title_;
|
||||
|
||||
labels_play_data_ << label_engine_icon_
|
||||
<< label_engine_
|
||||
@@ -280,27 +264,16 @@ ContextView::ContextView(QWidget *parent)
|
||||
<< label_length_
|
||||
<< label_samplerate_
|
||||
<< label_bitdepth_
|
||||
<< label_bitrate_
|
||||
<< label_play_albums_
|
||||
<< label_play_lyrics_;
|
||||
<< label_bitrate_;
|
||||
|
||||
labels_play_all_ = labels_play_ << labels_play_data_;
|
||||
|
||||
QFontDatabase::addApplicationFont(":/fonts/HumongousofEternitySt.ttf");
|
||||
textedit_play_ << textedit_play_lyrics_;
|
||||
|
||||
QObject::connect(widget_album_, &ContextAlbum::FadeStopFinished, this, &ContextView::FadeStopFinished);
|
||||
|
||||
}
|
||||
|
||||
void ContextView::resizeEvent(QResizeEvent*) {
|
||||
|
||||
if (width() != prev_width_) {
|
||||
widget_album_->setFixedSize(width() - 15, width());
|
||||
prev_width_ = width();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ContextView::Init(Application *app, CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller) {
|
||||
|
||||
app_ = app;
|
||||
@@ -308,7 +281,6 @@ void ContextView::Init(Application *app, CollectionView *collectionview, AlbumCo
|
||||
album_cover_choice_controller_ = album_cover_choice_controller;
|
||||
|
||||
widget_album_->Init(this, album_cover_choice_controller_);
|
||||
widget_albums_->Init(app_);
|
||||
lyrics_fetcher_ = new LyricsFetcher(app_->lyrics_providers(), this);
|
||||
|
||||
QObject::connect(collectionview_, &CollectionView::TotalSongCountUpdated_, this, &ContextView::UpdateNoSong);
|
||||
@@ -334,10 +306,6 @@ void ContextView::AddActions() {
|
||||
action_show_output_->setCheckable(true);
|
||||
action_show_output_->setChecked(true);
|
||||
|
||||
action_show_albums_ = new QAction(tr("Show albums by artist"), this);
|
||||
action_show_albums_->setCheckable(true);
|
||||
action_show_albums_->setChecked(false);
|
||||
|
||||
action_show_lyrics_ = new QAction(tr("Show song lyrics"), this);
|
||||
action_show_lyrics_->setCheckable(true);
|
||||
action_show_lyrics_->setChecked(true);
|
||||
@@ -346,20 +314,18 @@ void ContextView::AddActions() {
|
||||
action_search_lyrics_->setCheckable(true);
|
||||
action_search_lyrics_->setChecked(true);
|
||||
|
||||
menu_->addAction(action_show_album_);
|
||||
menu_->addAction(action_show_data_);
|
||||
menu_->addAction(action_show_output_);
|
||||
menu_->addAction(action_show_albums_);
|
||||
menu_->addAction(action_show_lyrics_);
|
||||
menu_->addAction(action_search_lyrics_);
|
||||
menu_->addSeparator();
|
||||
menu_options_->addAction(action_show_album_);
|
||||
menu_options_->addAction(action_show_data_);
|
||||
menu_options_->addAction(action_show_output_);
|
||||
menu_options_->addAction(action_show_lyrics_);
|
||||
menu_options_->addAction(action_search_lyrics_);
|
||||
menu_options_->addSeparator();
|
||||
|
||||
ReloadSettings();
|
||||
|
||||
QObject::connect(action_show_album_, &QAction::triggered, this, &ContextView::ActionShowAlbums);
|
||||
QObject::connect(action_show_album_, &QAction::triggered, this, &ContextView::ActionShowAlbum);
|
||||
QObject::connect(action_show_data_, &QAction::triggered, this, &ContextView::ActionShowData);
|
||||
QObject::connect(action_show_output_, &QAction::triggered, this, &ContextView::ActionShowOutput);
|
||||
QObject::connect(action_show_albums_, &QAction::triggered, this, &ContextView::ActionShowAlbums);
|
||||
QObject::connect(action_show_lyrics_, &QAction::triggered, this, &ContextView::ActionShowLyrics);
|
||||
QObject::connect(action_search_lyrics_, &QAction::triggered, this, &ContextView::ActionSearchLyrics);
|
||||
|
||||
@@ -374,12 +340,11 @@ void ContextView::ReloadSettings() {
|
||||
action_show_album_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::ALBUM], true).toBool());
|
||||
action_show_data_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::TECHNICAL_DATA], false).toBool());
|
||||
action_show_output_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::ENGINE_AND_DEVICE], 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_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_headline_ = s.value("font_size_headline", ContextSettingsPage::kDefaultFontSizeHeadline).toReal();
|
||||
font_size_normal_ = s.value("font_size_normal", font().pointSizeF()).toReal();
|
||||
s.endGroup();
|
||||
|
||||
@@ -394,6 +359,16 @@ void ContextView::ReloadSettings() {
|
||||
|
||||
}
|
||||
|
||||
void ContextView::resizeEvent(QResizeEvent *e) {
|
||||
|
||||
if (e->size().width() != e->oldSize().width()) {
|
||||
widget_album_->UpdateWidth(width() - kWidgetSpacing);
|
||||
}
|
||||
|
||||
QWidget::resizeEvent(e);
|
||||
|
||||
}
|
||||
|
||||
void ContextView::Playing() {}
|
||||
|
||||
void ContextView::Stopped() {
|
||||
@@ -441,6 +416,7 @@ void ContextView::FadeStopFinished() {
|
||||
widget_stacked_->setCurrentWidget(widget_stop_);
|
||||
NoSong();
|
||||
ResetSong();
|
||||
widget_stacked_->updateGeometry();
|
||||
|
||||
}
|
||||
|
||||
@@ -458,9 +434,8 @@ void ContextView::NoSong() {
|
||||
widget_album_->show();
|
||||
}
|
||||
|
||||
label_top_->setStyleSheet("font: 20pt \"Humongous of Eternity St\"; font-weight: Regular;");
|
||||
|
||||
label_top_->setText(tr("No song playing"));
|
||||
textedit_top_->setStyleSheet("font: 20pt 'Open Sans', 'FreeSans', 'FreeSerif', 'Liberation Serif'; font-weight: Regular;");
|
||||
textedit_top_->setText(tr("No song playing"));
|
||||
|
||||
QString html;
|
||||
if (collectionview_->TotalSongs() == 1) html += tr("%1 song").arg(collectionview_->TotalSongs());
|
||||
@@ -482,17 +457,20 @@ void ContextView::NoSong() {
|
||||
|
||||
void ContextView::UpdateFonts() {
|
||||
|
||||
QString font_style = QString("font: %2pt \"%1\"; font-weight: regular;").arg(font_normal_).arg(font_size_normal_);
|
||||
for (QLabel *l : labels_play_all_) {
|
||||
l->setStyleSheet(QString("font: %2pt \"%1\"; font-weight: regular;").arg(font_normal_).arg(font_size_normal_));
|
||||
l->setStyleSheet(font_style);
|
||||
}
|
||||
for (QTextEdit *e : textedit_play_) {
|
||||
e->setStyleSheet(font_style);
|
||||
}
|
||||
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() {
|
||||
|
||||
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 />", true), Utilities::ReplaceMessage(summary_fmt_, song_playing_, "<br />", true)));
|
||||
textedit_top_->setStyleSheet(QString("font: %2pt \"%1\"; font-weight: regular;").arg(font_headline_).arg(font_size_headline_));
|
||||
textedit_top_->setText(QString("<b>%1</b><br />%2").arg(Utilities::ReplaceMessage(title_fmt_, song_playing_, "<br />", true), Utilities::ReplaceMessage(summary_fmt_, song_playing_, "<br />", true)));
|
||||
|
||||
label_stop_summary_->clear();
|
||||
|
||||
@@ -605,51 +583,23 @@ void ContextView::SetSong() {
|
||||
spacer_play_output_->changeSize(0, 0, QSizePolicy::Fixed);
|
||||
}
|
||||
|
||||
if (action_show_albums_->isChecked() && song_prev_.artist() != song_playing_.artist()) {
|
||||
CollectionBackend::AlbumList albumlist;
|
||||
widget_albums_->albums_model()->Reset();
|
||||
albumlist = app_->collection_backend()->GetAlbumsByArtist(song_playing_.effective_albumartist());
|
||||
if (albumlist.count() > 1) {
|
||||
label_play_albums_->show();
|
||||
widget_albums_->show();
|
||||
label_play_albums_->setText("<b>" + tr("Albums by %1").arg(song_playing_.effective_albumartist().toHtmlEscaped()) + "</b>");
|
||||
for (const CollectionBackend::Album &album : albumlist) {
|
||||
SongList songs = app_->collection_backend()->GetAlbumSongs(song_playing_.effective_albumartist(), album.album);
|
||||
widget_albums_->albums_model()->AddSongs(songs);
|
||||
}
|
||||
spacer_play_albums_->changeSize(20, 10, QSizePolicy::Fixed);
|
||||
}
|
||||
else {
|
||||
label_play_albums_->hide();
|
||||
widget_albums_->hide();
|
||||
label_play_albums_->clear();
|
||||
spacer_play_albums_->changeSize(0, 0, QSizePolicy::Fixed);
|
||||
}
|
||||
}
|
||||
else if (!action_show_albums_->isChecked()) {
|
||||
label_play_albums_->hide();
|
||||
widget_albums_->hide();
|
||||
label_play_albums_->clear();
|
||||
widget_albums_->albums_model()->Reset();
|
||||
spacer_play_albums_->changeSize(0, 0, QSizePolicy::Fixed);
|
||||
}
|
||||
|
||||
if (action_show_lyrics_->isChecked()) {
|
||||
label_play_lyrics_->show();
|
||||
label_play_lyrics_->setText(lyrics_);
|
||||
if (action_show_lyrics_->isChecked() && !lyrics_.isEmpty()) {
|
||||
textedit_play_lyrics_->setText(lyrics_);
|
||||
textedit_play_lyrics_->show();
|
||||
}
|
||||
else {
|
||||
label_play_lyrics_->hide();
|
||||
label_play_lyrics_->clear();
|
||||
textedit_play_lyrics_->clear();
|
||||
textedit_play_lyrics_->hide();
|
||||
}
|
||||
|
||||
widget_stacked_->setCurrentWidget(widget_play_);
|
||||
widget_stacked_->updateGeometry();
|
||||
|
||||
}
|
||||
|
||||
void ContextView::UpdateSong(const Song &song) {
|
||||
|
||||
label_top_->setText(QString("<b>%1</b><br />%2").arg(Utilities::ReplaceMessage(title_fmt_, song, "<br />", true), Utilities::ReplaceMessage(summary_fmt_, song, "<br />", true)));
|
||||
textedit_top_->setText(QString("<b>%1</b><br />%2").arg(Utilities::ReplaceMessage(title_fmt_, song, "<br />", true), Utilities::ReplaceMessage(summary_fmt_, song, "<br />", true)));
|
||||
|
||||
if (action_show_data_->isChecked()) {
|
||||
if (song.filetype() != song_playing_.filetype()) label_filetype_->setText(song.TextForFiletype());
|
||||
@@ -713,22 +663,43 @@ void ContextView::ResetSong() {
|
||||
l->clear();
|
||||
}
|
||||
|
||||
for (QTextEdit *l : textedit_play_) {
|
||||
l->clear();
|
||||
}
|
||||
|
||||
widget_play_output_->hide();
|
||||
widget_play_data_->hide();
|
||||
textedit_play_lyrics_->hide();
|
||||
|
||||
}
|
||||
|
||||
void ContextView::UpdateLyrics(const quint64 id, const QString &provider, const QString &lyrics) {
|
||||
|
||||
if (static_cast<qint64>(id) != lyrics_id_) return;
|
||||
|
||||
lyrics_ = lyrics + "\n\n(Lyrics from " + provider + ")\n";
|
||||
lyrics_id_ = -1;
|
||||
if (action_show_lyrics_->isChecked()) {
|
||||
label_play_lyrics_->setText(lyrics_);
|
||||
|
||||
if (action_show_lyrics_->isChecked() && !lyrics_.isEmpty()) {
|
||||
textedit_play_lyrics_->setText(lyrics_);
|
||||
textedit_play_lyrics_->show();
|
||||
}
|
||||
else {
|
||||
textedit_play_lyrics_->clear();
|
||||
textedit_play_lyrics_->hide();
|
||||
}
|
||||
else label_play_lyrics_->clear();
|
||||
|
||||
}
|
||||
|
||||
void ContextView::contextMenuEvent(QContextMenuEvent *e) {
|
||||
if (menu_) menu_->popup(mapToGlobal(e->pos()));
|
||||
|
||||
if (menu_options_ && widget_stacked_->currentWidget() == widget_stop_) {
|
||||
menu_options_->popup(mapToGlobal(e->pos()));
|
||||
}
|
||||
else {
|
||||
QWidget::contextMenuEvent(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ContextView::dragEnterEvent(QDragEnterEvent *e) {
|
||||
@@ -790,17 +761,6 @@ void ContextView::ActionShowOutput() {
|
||||
|
||||
}
|
||||
|
||||
void ContextView::ActionShowAlbums() {
|
||||
|
||||
QSettings s;
|
||||
s.beginGroup(ContextSettingsPage::kSettingsGroup);
|
||||
s.setValue(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::ALBUMS_BY_ARTIST], action_show_albums_->isChecked());
|
||||
s.endGroup();
|
||||
song_prev_ = Song();
|
||||
if (song_playing_.is_valid()) SetSong();
|
||||
|
||||
}
|
||||
|
||||
void ContextView::ActionShowLyrics() {
|
||||
|
||||
QSettings s;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2013-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2013-2022, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -45,10 +45,10 @@ class QContextMenuEvent;
|
||||
class QDragEnterEvent;
|
||||
class QDropEvent;
|
||||
|
||||
class ResizableTextEdit;
|
||||
class Application;
|
||||
class CollectionView;
|
||||
class AlbumCoverChoiceController;
|
||||
class ContextAlbumsView;
|
||||
class LyricsFetcher;
|
||||
|
||||
class ContextView : public QWidget {
|
||||
@@ -60,12 +60,11 @@ class ContextView : public QWidget {
|
||||
void Init(Application *app, CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller);
|
||||
|
||||
ContextAlbum *album_widget() const { return widget_album_; }
|
||||
ContextAlbumsView *albums_widget() const { return widget_albums_; }
|
||||
bool album_enabled() const { return action_show_album_->isChecked(); }
|
||||
Song song_playing() const { return song_playing_; }
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent*) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent*) override;
|
||||
void dragEnterEvent(QDragEnterEvent*) override;
|
||||
void dropEvent(QDropEvent*) override;
|
||||
@@ -88,7 +87,6 @@ class ContextView : public QWidget {
|
||||
void ActionShowAlbum();
|
||||
void ActionShowData();
|
||||
void ActionShowOutput();
|
||||
void ActionShowAlbums();
|
||||
void ActionShowLyrics();
|
||||
void ActionSearchLyrics();
|
||||
void UpdateNoSong();
|
||||
@@ -104,16 +102,17 @@ class ContextView : public QWidget {
|
||||
void AlbumCoverLoaded(const Song &song, const QImage &image);
|
||||
|
||||
private:
|
||||
static const int kWidgetSpacing;
|
||||
|
||||
Application *app_;
|
||||
CollectionView *collectionview_;
|
||||
AlbumCoverChoiceController *album_cover_choice_controller_;
|
||||
LyricsFetcher *lyrics_fetcher_;
|
||||
|
||||
QMenu *menu_;
|
||||
QMenu *menu_options_;
|
||||
QAction *action_show_album_;
|
||||
QAction *action_show_data_;
|
||||
QAction *action_show_output_;
|
||||
QAction *action_show_albums_;
|
||||
QAction *action_show_lyrics_;
|
||||
QAction *action_search_lyrics_;
|
||||
|
||||
@@ -121,7 +120,7 @@ class ContextView : public QWidget {
|
||||
QWidget *widget_scrollarea_;
|
||||
QVBoxLayout *layout_scrollarea_;
|
||||
QScrollArea *scrollarea_;
|
||||
QLabel *label_top_;
|
||||
ResizableTextEdit *textedit_top_;
|
||||
ContextAlbum *widget_album_;
|
||||
QStackedWidget *widget_stacked_;
|
||||
QWidget *widget_stop_;
|
||||
@@ -129,20 +128,14 @@ class ContextView : public QWidget {
|
||||
QVBoxLayout *layout_stop_;
|
||||
QVBoxLayout *layout_play_;
|
||||
QLabel *label_stop_summary_;
|
||||
QSpacerItem *spacer_stop_bottom_;
|
||||
QWidget *widget_play_data_;
|
||||
QWidget *widget_play_output_;
|
||||
QGridLayout *layout_play_data_;
|
||||
QGridLayout *layout_play_output_;
|
||||
QLabel *label_play_albums_;
|
||||
QLabel *label_play_lyrics_;
|
||||
ContextAlbumsView *widget_albums_;
|
||||
ResizableTextEdit *textedit_play_lyrics_;
|
||||
|
||||
//QSpacerItem *spacer_play_album_;
|
||||
QSpacerItem *spacer_play_output_;
|
||||
QSpacerItem *spacer_play_data_;
|
||||
QSpacerItem *spacer_play_albums_;
|
||||
QSpacerItem *spacer_play_bottom_;
|
||||
|
||||
QLabel *label_filetype_title_;
|
||||
QLabel *label_length_title_;
|
||||
@@ -165,8 +158,6 @@ class ContextView : public QWidget {
|
||||
QLabel *label_device_icon_;
|
||||
QLabel *label_engine_icon_;
|
||||
|
||||
QSpacerItem *spacer_bottom_;
|
||||
|
||||
Song song_playing_;
|
||||
Song song_prev_;
|
||||
QImage image_original_;
|
||||
@@ -181,11 +172,10 @@ class ContextView : public QWidget {
|
||||
qreal font_size_normal_;
|
||||
|
||||
QList<QLabel*> labels_play_;
|
||||
QList<ResizableTextEdit*> textedit_play_;
|
||||
QList<QLabel*> labels_play_data_;
|
||||
QList<QLabel*> labels_play_all_;
|
||||
|
||||
int prev_width_;
|
||||
|
||||
};
|
||||
|
||||
#endif // CONTEXTVIEW_H
|
||||
|
||||
@@ -99,33 +99,33 @@ using namespace std::chrono_literals;
|
||||
class ApplicationImpl {
|
||||
public:
|
||||
explicit ApplicationImpl(Application *app) :
|
||||
tag_reader_client_([=]() {
|
||||
tag_reader_client_([app]() {
|
||||
TagReaderClient *client = new TagReaderClient(app);
|
||||
app->MoveToNewThread(client);
|
||||
client->Start();
|
||||
return client;
|
||||
}),
|
||||
database_([=]() {
|
||||
database_([app]() {
|
||||
Database *db = new Database(app, app);
|
||||
app->MoveToNewThread(db);
|
||||
QTimer::singleShot(30s, db, &Database::DoBackup);
|
||||
return db;
|
||||
}),
|
||||
appearance_([=]() { return new Appearance(app); }),
|
||||
task_manager_([=]() { return new TaskManager(app); }),
|
||||
player_([=]() { return new Player(app, app); }),
|
||||
device_finders_([=]() { return new DeviceFinders(app); }),
|
||||
appearance_([app]() { return new Appearance(app); }),
|
||||
task_manager_([app]() { return new TaskManager(app); }),
|
||||
player_([app]() { return new Player(app, app); }),
|
||||
device_finders_([app]() { return new DeviceFinders(app); }),
|
||||
#ifndef Q_OS_WIN
|
||||
device_manager_([=]() { return new DeviceManager(app, app); }),
|
||||
device_manager_([app]() { return new DeviceManager(app, app); }),
|
||||
#endif
|
||||
collection_([=]() { return new SCollection(app, app); }),
|
||||
playlist_backend_([=]() {
|
||||
collection_([app]() { return new SCollection(app, app); }),
|
||||
playlist_backend_([this, app]() {
|
||||
PlaylistBackend *backend = new PlaylistBackend(app, app);
|
||||
app->MoveToThread(backend, database_->thread());
|
||||
return backend;
|
||||
}),
|
||||
playlist_manager_([=]() { return new PlaylistManager(app); }),
|
||||
cover_providers_([=]() {
|
||||
playlist_manager_([app]() { return new PlaylistManager(app); }),
|
||||
cover_providers_([app]() {
|
||||
CoverProviders *cover_providers = new CoverProviders(app);
|
||||
// Initialize the repository of cover providers.
|
||||
cover_providers->AddProvider(new LastFmCoverProvider(app, cover_providers->network(), app));
|
||||
@@ -143,13 +143,13 @@ class ApplicationImpl {
|
||||
cover_providers->ReloadSettings();
|
||||
return cover_providers;
|
||||
}),
|
||||
album_cover_loader_([=]() {
|
||||
album_cover_loader_([app]() {
|
||||
AlbumCoverLoader *loader = new AlbumCoverLoader(app);
|
||||
app->MoveToNewThread(loader);
|
||||
return loader;
|
||||
}),
|
||||
current_albumcover_loader_([=]() { return new CurrentAlbumCoverLoader(app, app); }),
|
||||
lyrics_providers_([=]() {
|
||||
current_albumcover_loader_([app]() { return new CurrentAlbumCoverLoader(app, app); }),
|
||||
lyrics_providers_([app]() {
|
||||
LyricsProviders *lyrics_providers = new LyricsProviders(app);
|
||||
// Initialize the repository of lyrics providers.
|
||||
lyrics_providers->AddProvider(new AuddLyricsProvider(lyrics_providers->network(), app));
|
||||
@@ -161,7 +161,7 @@ class ApplicationImpl {
|
||||
lyrics_providers->ReloadSettings();
|
||||
return lyrics_providers;
|
||||
}),
|
||||
internet_services_([=]() {
|
||||
internet_services_([app]() {
|
||||
InternetServices *internet_services = new InternetServices(app);
|
||||
#ifdef HAVE_SUBSONIC
|
||||
internet_services->AddService(new SubsonicService(app, internet_services));
|
||||
@@ -174,13 +174,13 @@ class ApplicationImpl {
|
||||
#endif
|
||||
return internet_services;
|
||||
}),
|
||||
radio_services_([=]() { return new RadioServices(app, app); }),
|
||||
scrobbler_([=]() { return new AudioScrobbler(app, app); }),
|
||||
radio_services_([app]() { return new RadioServices(app, app); }),
|
||||
scrobbler_([app]() { return new AudioScrobbler(app, app); }),
|
||||
#ifdef HAVE_MOODBAR
|
||||
moodbar_loader_([=]() { return new MoodbarLoader(app, app); }),
|
||||
moodbar_controller_([=]() { return new MoodbarController(app, app); }),
|
||||
moodbar_loader_([app]() { return new MoodbarLoader(app, app); }),
|
||||
moodbar_controller_([app]() { return new MoodbarController(app, app); }),
|
||||
#endif
|
||||
lastfm_import_([=]() { return new LastFMImport(app); })
|
||||
lastfm_import_([app]() { return new LastFMImport(app); })
|
||||
{}
|
||||
|
||||
Lazy<TagReaderClient> tag_reader_client_;
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
// This template function declaration is used in defining arraysize.
|
||||
// Note that the function doesn't need an implementation, as we only
|
||||
// use its type.
|
||||
template <typename T, size_t N>
|
||||
template<typename T, size_t N>
|
||||
char (&ArraySizeHelper(T (&array)[N]))[N];
|
||||
|
||||
// That gcc wants both of these prototypes seems mysterious. VC, for
|
||||
// its part, can't decide which to use (another mystery). Matching of
|
||||
// template overloads: the final frontier.
|
||||
#ifndef _MSC_VER
|
||||
template <typename T, size_t N>
|
||||
template<typename T, size_t N>
|
||||
char (&ArraySizeHelper(const T (&array)[N]))[N];
|
||||
#endif
|
||||
|
||||
|
||||
@@ -369,8 +369,8 @@ QString CommandlineOptions::tr(const char *source_text) {
|
||||
|
||||
QDataStream &operator<<(QDataStream &s, const CommandlineOptions &a) {
|
||||
|
||||
s << qint32(a.player_action_)
|
||||
<< qint32(a.url_list_action_)
|
||||
s << static_cast<quint32>(a.player_action_)
|
||||
<< static_cast<quint32>(a.url_list_action_)
|
||||
<< a.set_volume_
|
||||
<< a.volume_modifier_
|
||||
<< a.seek_to_
|
||||
@@ -406,8 +406,8 @@ QDataStream &operator>>(QDataStream &s, CommandlineOptions &a) {
|
||||
>> a.playlist_name_
|
||||
>> a.window_size_;
|
||||
|
||||
a.player_action_ = CommandlineOptions::PlayerAction(player_action);
|
||||
a.url_list_action_ = CommandlineOptions::UrlListAction(url_list_action);
|
||||
a.player_action_ = static_cast<CommandlineOptions::PlayerAction>(player_action);
|
||||
a.url_list_action_ = static_cast<CommandlineOptions::UrlListAction>(url_list_action);
|
||||
|
||||
return s;
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
|
||||
const char *Database::kDatabaseFilename = "strawberry.db";
|
||||
const int Database::kSchemaVersion = 15;
|
||||
const int Database::kMinSupportedSchemaVersion = 10;
|
||||
const char *Database::kMagicAllSongsTables = "%allsongstables";
|
||||
|
||||
int Database::sNextConnectionId = 1;
|
||||
@@ -153,35 +154,8 @@ QSqlDatabase Database::Connect() {
|
||||
UpdateDatabaseSchema(0, db);
|
||||
}
|
||||
|
||||
if (SchemaVersion(&db) < 10) {
|
||||
// Register unicode from unicode61 tokenizer to drop old FTS3 tables.
|
||||
// We need it also to drop old devices later when loading devices.
|
||||
// And that's done in a different thread after schemas are upgraded, so register it anyway.
|
||||
#ifdef SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
|
||||
QVariant v = db.driver()->handle();
|
||||
if (v.isValid() && qstrcmp(v.typeName(), "sqlite3*") == 0) {
|
||||
sqlite3 *handle = *static_cast<sqlite3**>(v.data());
|
||||
if (handle) {
|
||||
(void)sqlite3_db_config(handle, SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, nullptr);
|
||||
}
|
||||
else qLog(Fatal) << "Unable to enable FTS3 tokenizer";
|
||||
}
|
||||
#endif
|
||||
SqlQuery get_fts_tokenizer(db);
|
||||
get_fts_tokenizer.prepare("SELECT fts3_tokenizer(:name)");
|
||||
get_fts_tokenizer.BindValue(":name", "unicode61");
|
||||
if (get_fts_tokenizer.exec() && get_fts_tokenizer.next()) {
|
||||
SqlQuery set_fts_tokenizer(db);
|
||||
set_fts_tokenizer.prepare("SELECT fts3_tokenizer(:name, :pointer)");
|
||||
set_fts_tokenizer.BindValue(":name", "unicode");
|
||||
set_fts_tokenizer.BindValue(":pointer", get_fts_tokenizer.value(0));
|
||||
if (!set_fts_tokenizer.exec()) {
|
||||
qLog(Warning) << "Couldn't register FTS3 tokenizer : " << set_fts_tokenizer.lastError();
|
||||
}
|
||||
}
|
||||
else {
|
||||
qLog(Warning) << "Couldn't get FTS3 tokenizer : " << get_fts_tokenizer.lastError();
|
||||
}
|
||||
if (SchemaVersion(&db) < kMinSupportedSchemaVersion) {
|
||||
qFatal("Database schema too old.");
|
||||
}
|
||||
|
||||
// Attach external databases
|
||||
@@ -401,15 +375,21 @@ void Database::ExecSchemaCommandsFromFile(QSqlDatabase &db, const QString &filen
|
||||
qFatal("Couldn't open schema file %s for reading: %s", filename.toUtf8().constData(), schema_file.errorString().toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
ExecSchemaCommands(db, QString::fromUtf8(schema_file.readAll()), schema_version, in_transaction);
|
||||
QByteArray data = schema_file.readAll();
|
||||
QString schema = QString::fromUtf8(data);
|
||||
if (schema.contains("\r\n")) {
|
||||
schema = schema.replace("\r\n", "\n");
|
||||
}
|
||||
schema_file.close();
|
||||
ExecSchemaCommands(db, schema, schema_version, in_transaction);
|
||||
|
||||
}
|
||||
|
||||
void Database::ExecSchemaCommands(QSqlDatabase &db, const QString &schema, int schema_version, bool in_transaction) {
|
||||
|
||||
// Run each command
|
||||
const QStringList commands(schema.split(QRegularExpression("; *\n\n")));
|
||||
QStringList commands;
|
||||
commands = schema.split(QRegularExpression("; *\n\n"));
|
||||
|
||||
// We don't want this list to reflect possible DB schema changes so we initialize it before executing any statements.
|
||||
// If no outer transaction is provided the song tables need to be queried before beginning an inner transaction! Otherwise
|
||||
|
||||
@@ -61,6 +61,7 @@ class Database : public QObject {
|
||||
};
|
||||
|
||||
static const int kSchemaVersion;
|
||||
static const int kMinSupportedSchemaVersion;
|
||||
static const char *kDatabaseFilename;
|
||||
static const char *kMagicAllSongsTables;
|
||||
|
||||
|
||||
@@ -109,12 +109,12 @@ bool FilesystemMusicStorage::DeleteFromStorage(const DeleteJob &job) {
|
||||
|
||||
if (job.use_trash_) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
if (fileInfo.isDir()) {
|
||||
return Utilities::MoveToTrashRecursive(path);
|
||||
}
|
||||
else {
|
||||
return QFile::moveToTrash(path);
|
||||
}
|
||||
if (fileInfo.isDir()) {
|
||||
return Utilities::MoveToTrashRecursive(path);
|
||||
}
|
||||
else {
|
||||
return QFile::moveToTrash(path);
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
||||
@@ -63,7 +63,7 @@ QIcon IconLoader::Load(const QString &name, const int fixed_size, const int min_
|
||||
|
||||
QList<int> sizes;
|
||||
if (fixed_size == 0) {
|
||||
sizes << 22 << 32 << 48 << 64;
|
||||
sizes << 22 << 32 << 48 << 64 << 128;
|
||||
}
|
||||
else {
|
||||
sizes << fixed_size;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
// Usage:
|
||||
// Lazy<Foo> my_lazy_object([]() { return new Foo; });
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
class Lazy {
|
||||
public:
|
||||
explicit Lazy(std::function<T*()> init) : init_(init) {}
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
QDebug operator<<(QDebug dbg, NSObject *object) {
|
||||
|
||||
QString ns_format = [ [NSString stringWithFormat:@"%@", object] UTF8String];
|
||||
QString ns_format = [[NSString stringWithFormat:@"%@", object] UTF8String];
|
||||
dbg.nospace() << ns_format;
|
||||
return dbg.space();
|
||||
|
||||
@@ -149,11 +149,12 @@ QDebug operator<<(QDebug dbg, NSObject *object) {
|
||||
|
||||
[[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
|
||||
|
||||
key_tap_ = [ [SPMediaKeyTap alloc] initWithDelegate:self];
|
||||
key_tap_ = [[SPMediaKeyTap alloc] initWithDelegate:self];
|
||||
if ([SPMediaKeyTap usesGlobalMediaKeyTap]) {
|
||||
if ([key_tap_ startWatchingMediaKeys]) {
|
||||
qLog(Debug) << "Media key monitoring started";
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
qLog(Warning) << "Failed to start media key monitoring";
|
||||
}
|
||||
}
|
||||
@@ -181,7 +182,7 @@ QDebug operator<<(QDebug dbg, NSObject *object) {
|
||||
|
||||
qLog(Debug) << "Wants to open:" << filenames;
|
||||
[filenames enumerateObjectsUsingBlock:^(id object, NSUInteger, BOOL*) {
|
||||
[self application:app openFile:(NSString*)object];
|
||||
[self application:app openFile:reinterpret_cast<NSString*>(object)];
|
||||
}];
|
||||
|
||||
}
|
||||
@@ -254,7 +255,7 @@ QDebug operator<<(QDebug dbg, NSObject *object) {
|
||||
|
||||
- (void)SetApplicationHandler:(PlatformInterface*)handler {
|
||||
|
||||
delegate_ = [ [AppDelegate alloc] initWithHandler:handler];
|
||||
delegate_ = [[AppDelegate alloc] initWithHandler:handler];
|
||||
// App-shortcut-handler set before delegate is set.
|
||||
// this makes sure the delegate's shortcut_handler is set
|
||||
[delegate_ setShortcutHandler:shortcut_handler_];
|
||||
@@ -263,7 +264,7 @@ QDebug operator<<(QDebug dbg, NSObject *object) {
|
||||
// FIXME
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
[ [NSUserNotificationCenter defaultUserNotificationCenter]setDelegate:delegate_];
|
||||
[[NSUserNotificationCenter defaultUserNotificationCenter]setDelegate:delegate_];
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
}
|
||||
@@ -402,7 +403,7 @@ QKeySequence KeySequenceFromNSEvent(NSEvent *event) {
|
||||
|
||||
void DumpDictionary(CFDictionaryRef dict) {
|
||||
|
||||
NSDictionary *d = (NSDictionary*)dict;
|
||||
NSDictionary *d = reinterpret_cast<NSDictionary*>(dict);
|
||||
NSLog(@"%@", d);
|
||||
|
||||
}
|
||||
|
||||
@@ -120,7 +120,6 @@
|
||||
#include "widgets/trackslider.h"
|
||||
#include "osd/osdbase.h"
|
||||
#include "context/contextview.h"
|
||||
#include "context/contextalbumsview.h"
|
||||
#include "collection/collection.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
#include "collection/collectiondirectorymodel.h"
|
||||
@@ -221,6 +220,18 @@ const int kTrackSliderUpdateTimeMs = 200;
|
||||
const int kTrackPositionUpdateTimeMs = 1000;
|
||||
} // namespace
|
||||
|
||||
#ifdef HAVE_QTSPARKLE
|
||||
# ifdef _MSC_VER
|
||||
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-msvc-x64";
|
||||
# else
|
||||
# ifdef __x86_64__
|
||||
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-mingw-x64";
|
||||
# else
|
||||
constexpr char QTSPARKLE_URL[] = "https://www.strawberrymusicplayer.org/sparkle-windows-mingw-x86";
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_icon, OSDBase *osd, const CommandlineOptions &options, QWidget *parent)
|
||||
: QMainWindow(parent),
|
||||
ui_(new Ui_MainWindow),
|
||||
@@ -230,7 +241,7 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
app_(app),
|
||||
tray_icon_(tray_icon),
|
||||
osd_(osd),
|
||||
console_([=]() {
|
||||
console_([app]() {
|
||||
Console *console = new Console(app);
|
||||
return console;
|
||||
}),
|
||||
@@ -248,7 +259,7 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
playlist_list_(new PlaylistListContainer(this)),
|
||||
queue_view_(new QueueView(this)),
|
||||
settings_dialog_(std::bind(&MainWindow::CreateSettingsDialog, this)),
|
||||
cover_manager_([=]() {
|
||||
cover_manager_([this, app]() {
|
||||
AlbumCoverManager *cover_manager = new AlbumCoverManager(app, app->collection_backend(), this);
|
||||
cover_manager->Init();
|
||||
|
||||
@@ -258,18 +269,18 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
return cover_manager;
|
||||
}),
|
||||
equalizer_(new Equalizer),
|
||||
organize_dialog_([=]() {
|
||||
organize_dialog_([this, app]() {
|
||||
OrganizeDialog *dialog = new OrganizeDialog(app->task_manager(), app->collection_backend(), this);
|
||||
dialog->SetDestinationModel(app->collection()->model()->directory_model());
|
||||
return dialog;
|
||||
}),
|
||||
#ifdef HAVE_GSTREAMER
|
||||
transcode_dialog_([=]() {
|
||||
transcode_dialog_([this]() {
|
||||
TranscodeDialog *dialog = new TranscodeDialog(this);
|
||||
return dialog;
|
||||
}),
|
||||
#endif
|
||||
add_stream_dialog_([=]() {
|
||||
add_stream_dialog_([this]() {
|
||||
AddStreamDialog *add_stream_dialog = new AddStreamDialog;
|
||||
QObject::connect(add_stream_dialog, &AddStreamDialog::accepted, this, &MainWindow::AddStreamAccepted);
|
||||
return add_stream_dialog;
|
||||
@@ -324,7 +335,8 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
hidden_(false),
|
||||
exit_(false),
|
||||
exit_count_(0),
|
||||
delete_files_(false) {
|
||||
delete_files_(false),
|
||||
ignore_close_(false) {
|
||||
|
||||
qLog(Debug) << "Starting";
|
||||
|
||||
@@ -334,6 +346,8 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
// Initialize the UI
|
||||
ui_->setupUi(this);
|
||||
|
||||
setWindowIcon(IconLoader::Load("strawberry"));
|
||||
|
||||
album_cover_choice_controller_->Init(app);
|
||||
|
||||
ui_->multi_loading_indicator->SetTaskManager(app_->task_manager());
|
||||
@@ -446,6 +460,7 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
ui_->action_remove_duplicates->setIcon(IconLoader::Load("list-remove"));
|
||||
ui_->action_remove_unavailable->setIcon(IconLoader::Load("list-remove"));
|
||||
ui_->action_remove_from_playlist->setIcon(IconLoader::Load("list-remove"));
|
||||
ui_->action_save_all_playlists->setIcon(IconLoader::Load("document-save-all"));
|
||||
|
||||
// Configure
|
||||
|
||||
@@ -476,9 +491,9 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
QObject::connect(file_view_, &FileView::CopyToCollection, this, &MainWindow::CopyFilesToCollection);
|
||||
QObject::connect(file_view_, &FileView::MoveToCollection, this, &MainWindow::MoveFilesToCollection);
|
||||
QObject::connect(file_view_, &FileView::EditTags, this, &MainWindow::EditFileTags);
|
||||
#ifndef Q_OS_WIN
|
||||
# ifndef Q_OS_WIN
|
||||
QObject::connect(file_view_, &FileView::CopyToDevice, this, &MainWindow::CopyFilesToDevice);
|
||||
#endif
|
||||
# endif
|
||||
#endif
|
||||
file_view_->SetTaskManager(app_->task_manager());
|
||||
|
||||
@@ -536,8 +551,8 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
QObject::connect(app_->scrobbler(), &AudioScrobbler::ErrorMessage, this, &MainWindow::ShowErrorDialog);
|
||||
|
||||
// Playlist view actions
|
||||
ui_->action_next_playlist->setShortcuts(QList<QKeySequence>() << QKeySequence::fromString("Ctrl+Tab")<< QKeySequence::fromString("Ctrl+PgDown"));
|
||||
ui_->action_previous_playlist->setShortcuts(QList<QKeySequence>() << QKeySequence::fromString("Ctrl+Shift+Tab")<< QKeySequence::fromString("Ctrl+PgUp"));
|
||||
ui_->action_next_playlist->setShortcuts(QList<QKeySequence>() << QKeySequence::fromString("Ctrl+Tab") << QKeySequence::fromString("Ctrl+PgDown"));
|
||||
ui_->action_previous_playlist->setShortcuts(QList<QKeySequence>() << QKeySequence::fromString("Ctrl+Shift+Tab") << QKeySequence::fromString("Ctrl+PgUp"));
|
||||
|
||||
// Actions for switching tabs will be global to the entire window, so adding them here
|
||||
addAction(ui_->action_next_playlist);
|
||||
@@ -551,8 +566,7 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
ui_->button_scrobble->setDefaultAction(ui_->action_toggle_scrobbling);
|
||||
ui_->button_love->setDefaultAction(ui_->action_love);
|
||||
|
||||
ui_->playlist->SetActions(ui_->action_new_playlist, ui_->action_load_playlist, ui_->action_save_playlist, ui_->action_clear_playlist, ui_->action_next_playlist, /* These two actions aren't associated */ ui_->action_previous_playlist /* to a button but to the main window */ );
|
||||
|
||||
ui_->playlist->SetActions(ui_->action_new_playlist, ui_->action_load_playlist, ui_->action_save_playlist, ui_->action_clear_playlist, ui_->action_next_playlist, /* These two actions aren't associated */ ui_->action_previous_playlist /* to a button but to the main window */, ui_->action_save_all_playlists);
|
||||
// Add the shuffle and repeat action groups to the menu
|
||||
ui_->action_shuffle_mode->setMenu(ui_->playlist_sequence->shuffle_menu());
|
||||
ui_->action_repeat_mode->setMenu(ui_->playlist_sequence->repeat_menu());
|
||||
@@ -680,7 +694,7 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
QObject::connect(tidal_view_->albums_collection_view(), &InternetCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist);
|
||||
QObject::connect(tidal_view_->songs_collection_view(), &InternetCollectionView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist);
|
||||
QObject::connect(tidal_view_->search_view(), &InternetSearchView::AddToPlaylist, this, &MainWindow::AddToPlaylist);
|
||||
if (TidalService *tidalservice = qobject_cast<TidalService*> (app_->internet_services()->ServiceBySource(Song::Source_Tidal))) {
|
||||
if (TidalService *tidalservice = qobject_cast<TidalService*>(app_->internet_services()->ServiceBySource(Song::Source_Tidal))) {
|
||||
QObject::connect(this, &MainWindow::AuthorizationUrlReceived, tidalservice, &TidalService::AuthorizationUrlReceived);
|
||||
}
|
||||
#endif
|
||||
@@ -818,7 +832,6 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
QObject::connect(this, &MainWindow::AlbumCoverReady, context_view_, &ContextView::AlbumCoverLoaded);
|
||||
QObject::connect(this, &MainWindow::SearchCoverInProgress, context_view_->album_widget(), &ContextAlbum::SearchCoverInProgress);
|
||||
QObject::connect(context_view_, &ContextView::AlbumEnabledChanged, this, &MainWindow::TabSwitched);
|
||||
QObject::connect(context_view_->albums_widget(), &ContextAlbumsView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist);
|
||||
|
||||
// Analyzer
|
||||
QObject::connect(ui_->analyzer, &AnalyzerContainer::WheelEvent, this, &MainWindow::VolumeWheelEvent);
|
||||
@@ -908,7 +921,7 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
ui_->tabs->setCurrentIndex(settings_.value("current_tab", 1).toInt());
|
||||
FancyTabWidget::Mode default_mode = FancyTabWidget::Mode_LargeSidebar;
|
||||
int tab_mode_int = settings_.value("tab_mode", default_mode).toInt();
|
||||
FancyTabWidget::Mode tab_mode = FancyTabWidget::Mode(tab_mode_int);
|
||||
FancyTabWidget::Mode tab_mode = static_cast<FancyTabWidget::Mode>(tab_mode_int);
|
||||
if (tab_mode == FancyTabWidget::Mode_None) tab_mode = default_mode;
|
||||
ui_->tabs->SetMode(tab_mode);
|
||||
|
||||
@@ -948,7 +961,6 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
break;
|
||||
case BehaviourSettingsPage::Startup_Hide:
|
||||
if (tray_icon_->IsSystemTrayAvailable() && tray_icon_->isVisible()) {
|
||||
hide();
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
@@ -968,7 +980,9 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
}
|
||||
else {
|
||||
hidden_ = settings_.value("hidden", false).toBool();
|
||||
setVisible(!hidden_);
|
||||
if (!hidden_) {
|
||||
show();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1000,12 +1014,7 @@ MainWindow::MainWindow(Application *app, std::shared_ptr<SystemTrayIcon> tray_ic
|
||||
}
|
||||
|
||||
#ifdef HAVE_QTSPARKLE
|
||||
QUrl sparkle_url;
|
||||
#if defined(Q_OS_MACOS)
|
||||
sparkle_url.setUrl("https://www.strawberrymusicplayer.org/sparkle-macos");
|
||||
#elif defined(Q_OS_WIN)
|
||||
sparkle_url.setUrl("https://www.strawberrymusicplayer.org/sparkle-windows");
|
||||
#endif
|
||||
QUrl sparkle_url(QTSPARKLE_URL);
|
||||
if (!sparkle_url.isEmpty()) {
|
||||
qLog(Debug) << "Creating Qt Sparkle updater";
|
||||
qtsparkle::Updater *updater = new qtsparkle::Updater(sparkle_url, this);
|
||||
@@ -1215,7 +1224,8 @@ void MainWindow::Exit() {
|
||||
QObject::connect(app_->player()->engine(), &EngineBase::FadeoutFinishedSignal, this, &MainWindow::DoExit);
|
||||
if (app_->player()->GetState() == Engine::Playing) {
|
||||
app_->player()->Stop();
|
||||
hide();
|
||||
ignore_close_ = true;
|
||||
close();
|
||||
if (tray_icon_->IsSystemTrayAvailable()) {
|
||||
tray_icon_->setVisible(false);
|
||||
}
|
||||
@@ -1543,16 +1553,13 @@ void MainWindow::VolumeWheelEvent(const int delta) {
|
||||
void MainWindow::ToggleShowHide() {
|
||||
|
||||
if (hidden_) {
|
||||
show();
|
||||
SetHiddenInTray(false);
|
||||
}
|
||||
else if (isActiveWindow()) {
|
||||
hide();
|
||||
setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
|
||||
SetHiddenInTray(true);
|
||||
}
|
||||
else if (isMinimized()) {
|
||||
hide();
|
||||
setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
|
||||
SetHiddenInTray(false);
|
||||
}
|
||||
@@ -1587,8 +1594,14 @@ void MainWindow::showEvent(QShowEvent *e) {
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *e) {
|
||||
|
||||
if (ignore_close_) {
|
||||
ignore_close_ = false;
|
||||
QMainWindow::closeEvent(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!exit_) {
|
||||
if (!hidden_ && keep_running_ && e->spontaneous() && tray_icon_->IsSystemTrayAvailable()) {
|
||||
if (!hidden_ && keep_running_ && tray_icon_->IsSystemTrayAvailable()) {
|
||||
SetHiddenInTray(true);
|
||||
}
|
||||
else {
|
||||
@@ -1609,7 +1622,8 @@ void MainWindow::SetHiddenInTray(const bool hidden) {
|
||||
if (hidden) {
|
||||
was_maximized_ = isMaximized();
|
||||
was_minimized_ = isMinimized();
|
||||
hide();
|
||||
ignore_close_ = true;
|
||||
close();
|
||||
}
|
||||
else {
|
||||
if (was_minimized_) {
|
||||
@@ -2165,7 +2179,7 @@ void MainWindow::EditValue() {
|
||||
if (column == -1) {
|
||||
for (int i = 0; i < ui_->playlist->view()->model()->columnCount(); ++i) {
|
||||
if (ui_->playlist->view()->isColumnHidden(i)) continue;
|
||||
if (!Playlist::column_is_editable(Playlist::Column(i))) continue;
|
||||
if (!Playlist::column_is_editable(static_cast<Playlist::Column>(i))) continue;
|
||||
column = i;
|
||||
break;
|
||||
}
|
||||
@@ -2183,7 +2197,7 @@ void MainWindow::AddFile() {
|
||||
PlaylistParser parser(app_->collection_backend());
|
||||
|
||||
// Show dialog
|
||||
QStringList file_names = QFileDialog::getOpenFileNames(this, tr("Add file"), directory, QString("%1 (%2);;%3;;%4").arg(tr("Music"), FileView::kFileFilter, parser.filters(), tr(kAllFilesFilterSpec)));
|
||||
QStringList file_names = QFileDialog::getOpenFileNames(this, tr("Add file"), directory, QString("%1 (%2);;%3;;%4").arg(tr("Music"), FileView::kFileFilter, parser.filters(PlaylistParser::Type_Load), tr(kAllFilesFilterSpec)));
|
||||
|
||||
if (file_names.isEmpty()) return;
|
||||
|
||||
@@ -2274,7 +2288,7 @@ void MainWindow::PlaylistRemoveCurrent() {
|
||||
void MainWindow::PlaylistClearCurrent() {
|
||||
|
||||
if (app_->playlist_manager()->current()->rowCount() > Playlist::kUndoItemLimit) {
|
||||
QMessageBox messagebox(QMessageBox::Warning, tr("Clear playlist"), tr("Playlist has %1 songs, too large to undo, are you sure you want to clear the playlist?").arg(app_->playlist_manager()->current()->rowCount()), QMessageBox::Ok|QMessageBox::Cancel);
|
||||
QMessageBox messagebox(QMessageBox::Warning, tr("Clear playlist"), tr("Playlist has %1 songs, too large to undo, are you sure you want to clear the playlist?").arg(app_->playlist_manager()->current()->rowCount()), QMessageBox::Ok | QMessageBox::Cancel);
|
||||
messagebox.setTextFormat(Qt::RichText);
|
||||
int result = messagebox.exec();
|
||||
switch (result) {
|
||||
@@ -2874,22 +2888,20 @@ void MainWindow::Raise() {
|
||||
show();
|
||||
activateWindow();
|
||||
hidden_ = false;
|
||||
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, qintptr *result) {
|
||||
#else
|
||||
# else
|
||||
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) {
|
||||
#endif
|
||||
# endif
|
||||
|
||||
if (exit_count_ == 0 && message) {
|
||||
MSG *msg = static_cast<MSG*>(message);
|
||||
thumbbar_->HandleWinEvent(msg);
|
||||
}
|
||||
return QMainWindow::nativeEvent(eventType, message, result);
|
||||
|
||||
}
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
|
||||
@@ -120,11 +120,11 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
||||
void closeEvent(QCloseEvent *e) override;
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
#ifdef Q_OS_WIN
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
|
||||
#else
|
||||
# else
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
|
||||
#endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// PlatformInterface
|
||||
@@ -395,6 +395,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
||||
bool exit_;
|
||||
int exit_count_;
|
||||
bool delete_files_;
|
||||
bool ignore_close_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../../data/icons.qrc">
|
||||
<normaloff>:/icons/64x64/strawberry.png</normaloff>:/icons/64x64/strawberry.png</iconset>
|
||||
<normaloff>:/icons/128x128/strawberry.png</normaloff>:/icons/128x128/strawberry.png</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QVBoxLayout" name="layout_centralWidget">
|
||||
@@ -448,7 +448,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1131</width>
|
||||
<height>26</height>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu_music">
|
||||
@@ -483,6 +483,7 @@
|
||||
<addaction name="action_new_playlist"/>
|
||||
<addaction name="action_save_playlist"/>
|
||||
<addaction name="action_load_playlist"/>
|
||||
<addaction name="action_save_all_playlists"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_jump"/>
|
||||
<addaction name="action_clear_playlist"/>
|
||||
@@ -747,6 +748,11 @@
|
||||
<string>Ctrl+Shift+O</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_save_all_playlists">
|
||||
<property name="text">
|
||||
<string>&Save all playlists...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_next_playlist">
|
||||
<property name="text">
|
||||
<string>Go to next playlist tab</string>
|
||||
@@ -897,7 +903,6 @@
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../data/data.qrc"/>
|
||||
<include location="../../data/icons.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
#include "radios/radiochannel.h"
|
||||
|
||||
#ifdef HAVE_LIBMTP
|
||||
#include "device/mtpconnection.h"
|
||||
# include "device/mtpconnection.h"
|
||||
#endif
|
||||
|
||||
void RegisterMetaTypes() {
|
||||
|
||||
@@ -113,7 +113,7 @@ Engine::EngineType Player::CreateEngine(Engine::EngineType enginetype) {
|
||||
Engine::EngineType use_enginetype(Engine::None);
|
||||
|
||||
for (int i = 0; use_enginetype == Engine::None; i++) {
|
||||
switch(enginetype) {
|
||||
switch (enginetype) {
|
||||
case Engine::None:
|
||||
#ifdef HAVE_GSTREAMER
|
||||
case Engine::GStreamer:{
|
||||
@@ -126,18 +126,20 @@ Engine::EngineType Player::CreateEngine(Engine::EngineType enginetype) {
|
||||
#endif
|
||||
#ifdef HAVE_VLC
|
||||
case Engine::VLC:
|
||||
use_enginetype=Engine::VLC;
|
||||
use_enginetype = Engine::VLC;
|
||||
engine_ = std::make_shared<VLCEngine>(app_->task_manager());
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (i > 0) { qFatal("No engine available!"); }
|
||||
if (i > 0) {
|
||||
qFatal("No engine available!");
|
||||
}
|
||||
enginetype = Engine::None;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (use_enginetype != enginetype) { // Engine was set to something else. Reset output and device.
|
||||
if (use_enginetype != enginetype) { // Engine was set to something else. Reset output and device.
|
||||
QSettings s;
|
||||
s.beginGroup(BackendSettingsPage::kSettingsGroup);
|
||||
s.setValue("engine", EngineName(use_enginetype));
|
||||
@@ -167,7 +169,9 @@ void Player::Init() {
|
||||
CreateEngine(enginetype);
|
||||
}
|
||||
|
||||
if (!engine_->Init()) { qFatal("Error initializing audio engine"); }
|
||||
if (!engine_->Init()) {
|
||||
qFatal("Error initializing audio engine");
|
||||
}
|
||||
|
||||
analyzer_->SetEngine(engine_.get());
|
||||
|
||||
@@ -426,7 +430,7 @@ void Player::PlayPlaylistInternal(const Engine::TrackChangeFlags change, const P
|
||||
if (playlist == nullptr) {
|
||||
qLog(Warning) << "Playlist '" << playlist_name << "' not found.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
app_->playlist_manager()->SetActivePlaylist(playlist->id());
|
||||
app_->playlist_manager()->SetCurrentPlaylist(playlist->id());
|
||||
@@ -515,7 +519,7 @@ void Player::UnPause() {
|
||||
const Song &song = current_item_->Metadata();
|
||||
if (url_handlers_.contains(song.url().scheme()) && song.stream_url_can_expire()) {
|
||||
const quint64 time = QDateTime::currentDateTime().toSecsSinceEpoch() - pause_time_.toSecsSinceEpoch();
|
||||
if (time >= 30) { // Stream URL might be expired.
|
||||
if (time >= 30) { // Stream URL might be expired.
|
||||
qLog(Debug) << "Re-requesting stream URL for" << song.url();
|
||||
play_offset_nanosec_ = engine_->position_nanosec();
|
||||
HandleLoadResult(url_handlers_[song.url().scheme()]->StartLoading(song.url()));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user