diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e83ee2d..6dde7ae 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -33,12 +33,16 @@ jobs: :: ------ dep ------ set CMAKE_PREFIX_PATH=%PWD%/dependencies_bin mkdir dependencies_src - :: ===== uchardet ===== - echo ::group::build uchardet - git clone -q https://gitlab.freedesktop.org/BLumia/uchardet.git --branch msvc dependencies_src/uchardet - cmake .\dependencies_src\uchardet -Bbuild_dependencies/uchardet -DBUILD_BINARY=OFF -DCMAKE_INSTALL_PREFIX="dependencies_bin" || goto :error - cmake --build build_dependencies/uchardet --config Release --target=install -j || goto :error - echo ::endgroup:: + :: ===== ECM ===== + git clone -q https://invent.kde.org/frameworks/extra-cmake-modules.git dependencies_src/extra-cmake-modules + cmake .\dependencies_src\extra-cmake-modules -Bbuild_dependencies/extra-cmake-modules -DCMAKE_INSTALL_PREFIX="dependencies_bin" -DBUILD_TESTING=OFF || goto :error + cmake --build build_dependencies/extra-cmake-modules --config Release --target=install || goto :error + :: ===== Gperf (required by KCodecs) ===== + choco install gperf + :: ===== KCodecs ===== + git clone -q https://invent.kde.org/frameworks/kcodecs.git dependencies_src/kcodecs + cmake .\dependencies_src\kcodecs -Bbuild_dependencies/kcodecs -DCMAKE_INSTALL_PREFIX="dependencies_bin" -DBUILD_TESTING=OFF || goto :error + cmake --build build_dependencies/kcodecs --config Release --target=install || goto :error :: ===== pkg-config ===== choco install pkgconfiglite set PKG_CONFIG_PATH=%PWD%/dependencies_bin/lib/pkgconfig diff --git a/CMakeLists.txt b/CMakeLists.txt index cb0cb53..87409cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 6.6 COMPONENTS Widgets Multimedia Network LinguistTools REQUIRED) -find_package(uchardet) +find_package(KF6Codecs 6.1.0) find_package(PkgConfig) if (PKG_CONFIG_FOUND) @@ -73,10 +73,10 @@ else () target_link_libraries(${EXE_NAME} PRIVATE PkgConfig::TagLib) endif () -if (NOT uchardet_FOUND) - target_compile_definitions(${EXE_NAME} PRIVATE NO_UCHARDET=1) +if (NOT TARGET KF6::Codecs) + target_compile_definitions(${EXE_NAME} PRIVATE NO_KCODECS=1) else () - target_link_libraries (${EXE_NAME} PRIVATE uchardet::libuchardet) + target_link_libraries (${EXE_NAME} PRIVATE KF6::Codecs) endif () target_link_libraries(${EXE_NAME} PRIVATE Qt::Widgets Qt::Multimedia Qt::Network) diff --git a/appveyor.yml b/appveyor.yml index 011999b..cf94d9d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,12 +22,20 @@ build_script: # prepare - mkdir 3rdparty - choco install ninja + - choco install gperf - choco install pkgconfiglite - cd 3rdparty -# build uchardet - - git clone -q https://gitlab.freedesktop.org/uchardet/uchardet.git - - cd uchardet - - cmake -G "Ninja" . -DCMAKE_INSTALL_PREFIX=%PACKAGE_INSTALL_ROOT% -DBUILD_BINARY=OFF +# install ECM + - git clone -q https://invent.kde.org/frameworks/extra-cmake-modules.git + - git rev-parse HEAD + - cd extra-cmake-modules + - cmake -G "Ninja" . -DCMAKE_INSTALL_PREFIX=%PACKAGE_INSTALL_ROOT% -DBUILD_TESTING=OFF + - cmake --build . --target install + - cd %APPVEYOR_BUILD_FOLDER% +# build kcodecs + - git clone -q https://invent.kde.org/frameworks/kcodecs.git + - cd kcodecs + - cmake -G "Ninja" . -DCMAKE_INSTALL_PREFIX=%PACKAGE_INSTALL_ROOT% -DBUILD_TESTING=OFF - cmake --build . --target install - cd %APPVEYOR_BUILD_FOLDER% # build taglib diff --git a/lyricsmanager.cpp b/lyricsmanager.cpp index 81054a6..31cf928 100644 --- a/lyricsmanager.cpp +++ b/lyricsmanager.cpp @@ -9,8 +9,10 @@ #include #include -#ifndef NO_UCHARDET -#include +#ifndef NO_KCODECS +#include +#include +#include #endif Q_LOGGING_CATEGORY(lcLyrics, "pmusic.lyrics") @@ -44,21 +46,23 @@ bool LyricsManager::loadLyrics(QString filepath) return false; } QByteArray fileContent(file.readAll()); -#ifndef NO_UCHARDET - uchardet_t handle = uchardet_new(); - uchardet_handle_data(handle, fileContent.data(), fileContent.length()); - uchardet_data_end(handle); - const char* encoding = uchardet_get_charset(handle); - qCDebug(lcLyrics) << "Detected encoding:" << (encoding == NULL ? "unknown" : encoding); +#ifndef NO_KCODECS + KEncodingProber prober(KEncodingProber::Universal); + prober.feed(fileContent); + QByteArray encoding(prober.encoding()); + qCDebug(lcLyrics) << "Detected encoding:" << QString(encoding) << "with confidence" << prober.confidence(); + auto toUtf16 = QStringDecoder(encoding); QStringList lines; - if (QStringConverter::availableCodecs().contains(QString(encoding))) { - auto toUtf16 = QStringDecoder(encoding); + // Don't use `QStringConverter::availableCodecs().contains(QString(encoding))` here, since the charset + // encoding name might not match, e.g. GB18030 (from availableCodecs) != gb18030 (from KEncodingProber) + if (toUtf16.isValid()) { QString decodedResult = toUtf16(fileContent); lines = decodedResult.split('\n'); } else { + qCDebug(lcLyrics) << "No codec for the detected encoding. Available codecs are:" << QStringConverter::availableCodecs(); + qCDebug(lcLyrics) << "KCodecs offers these encodings:" << KCharsets::charsets()->availableEncodingNames(); lines = QString(fileContent).split('\n'); } - uchardet_delete(handle); #else QStringList lines = QString(fileContent).split('\n'); #endif diff --git a/mainwindow.cpp b/mainwindow.cpp index 40b3239..6f7cb04 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -620,8 +620,8 @@ void MainWindow::on_actionHelp_triggered() #ifndef NO_TAGLIB QStringLiteral("- [TagLib](https://github.com/taglib/taglib)\n") % #endif // NO_TAGLIB -#ifndef NO_UCHARDET - QStringLiteral("- [uchardet](https://www.freedesktop.org/wiki/Software/uchardet/)\n") % +#ifndef NO_KCODECS + QStringLiteral("- [KCodecs](https://invent.kde.org/frameworks/kcodecs)\n") % #endif // NO_TAGLIB "\n" "[Source Code](https://github.com/BLumia/pineapple-music)\n"