Compare commits

..

No commits in common. "5406b3022a4af8b2ff2c6dcd814b8a986dc720ad" and "3c5b76f77a42cbefc4cdf39a4ceda3b4d0839fcf" have entirely different histories.

49 changed files with 405 additions and 215 deletions

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.25) # Debian 11 Ubuntu 24.04 Fedora 36
cmake_minimum_required(VERSION 3.25) # ubuntu 23.04 Fedora 36
option(WITH_FFMPEG_PLAYER "Enable support for FFMPEG player" ON)
option(WITH_EPWING_SUPPORT "Enable epwing support" ON)
@ -9,12 +9,20 @@ option(WITH_TTS "enable QTexttoSpeech support" OFF)
option(USE_SYSTEM_FMT "use system fmt instead of bundled one" OFF)
option(USE_SYSTEM_TOML "use system toml++ instead of bundled one" OFF)
## This should be avoided because of small regressions, as some scripts and icons themes assume the binary name and resources folder to be `goldendict`
option(USE_ALTERNATIVE_NAME "For Linux, change the binary name and resource folder to goldendict-ng to parallel install with the original GD" OFF)
option(WITH_VCPKG_BREAKPAD "build with Breakpad support for VCPKG build only" OFF)
## Change binary & resources folder to parallel install with original GD.
## This flag should be avoided because it leads to small regressions:
## 1. There are personal scripts assuming the binary name to be "goldendict" -> require everyone to change the name in their script
## 2. There are icon themes that assuming the icon name to be "goldendict" -> invalidate the GD icon when using a icon theme
## 3. There are dictionary packages that install files to "/usr/share/goldendict/content" -> nullify the auto dict discovery
option(USE_ALTERNATIVE_NAME "Force the name goldendict-ng " OFF)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}") # to put staff in the ./cmake folder
# vcpkg handling code, must be placed before project()
if (WIN32)
option(WITH_VCPKG_BREAKPAD "build with Breakpad support for VCPKG build only" OFF)
if (DEFINED CMAKE_TOOLCHAIN_FILE)
message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
else ()
@ -29,9 +37,11 @@ if (WIN32)
set(VCPKG_MANIFEST_MODE OFF CACHE BOOL "disable existing manifest mode caused by the existrance of vcpkg.json" FORCE)
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_BINARY_DIR}/_deps/vcpkg-export-src/scripts/buildsystems/vcpkg.cmake")
endif ()
if (WITH_VCPKG_BREAKPAD)
endif ()
if (WITH_VCPKG_BREAKPAD)
list(APPEND VCPKG_MANIFEST_FEATURES "breakpad")
endif ()
endif ()
include(FeatureSummary)
@ -50,12 +60,13 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(GOLDENDICT "goldendict") # binary/executable name
if (USE_ALTERNATIVE_NAME)
if (USE_ALTERNATIVE_NAME )
set(GOLDENDICT "goldendict-ng")
endif ()
if (APPLE)
set(GOLDENDICT "GoldenDict-ng")
endif ()
endif()
#### Qt
@ -67,10 +78,11 @@ endif ()
find_package(Qt6 REQUIRED COMPONENTS ${GD_QT_COMPONENTS})
qt_standard_project_setup()
qt_standard_project_setup() # availiable after find_package(Qt6 .... Core
set(CMAKE_AUTORCC ON) # not included in the qt_standard_project_setup
#### Things required during configuration
block() # generate version.txt
string(TIMESTAMP build_time UTC)
find_package(Git)
@ -151,8 +163,11 @@ target_link_libraries(${GOLDENDICT} PRIVATE
Qt6::WebEngineWidgets
Qt6::Widgets
Qt6::Svg
$<$<BOOL:${WITH_TTS}>:Qt6::TextToSpeech>
)
)
if (WITH_TTS)
target_link_libraries(${GOLDENDICT} PRIVATE Qt6::TextToSpeech)
endif ()
target_include_directories(${GOLDENDICT} PRIVATE
${PROJECT_SOURCE_DIR}/thirdparty/qtsingleapplication/src
@ -161,7 +176,11 @@ target_include_directories(${GOLDENDICT} PRIVATE
${PROJECT_SOURCE_DIR}/src/dict
${PROJECT_SOURCE_DIR}/src/dict/utils
${PROJECT_SOURCE_DIR}/src/ui
)
)
if (WIN32)
target_include_directories(${GOLDENDICT} PRIVATE ${PROJECT_SOURCE_DIR}/src/windows)
endif ()
if (NOT USE_SYSTEM_TOML)
target_include_directories(${GOLDENDICT} PRIVATE ${PROJECT_SOURCE_DIR}/thirdparty/tomlplusplus)
@ -180,22 +199,45 @@ target_compile_definitions(${GOLDENDICT} PRIVATE
)
target_compile_definitions(${GOLDENDICT} PUBLIC
CMAKE_USED_HACK # temporal hack to avoid breaking qmake build
MAKE_QTMULTIMEDIA_PLAYER
MAKE_CHINESE_CONVERSION_SUPPORT
$<$<BOOL:${WIN32}>:__WIN32>
$<$<BOOL:${WITH_FFMPEG_PLAYER}>:MAKE_FFMPEG_PLAYER>
$<$<BOOL:${WITH_TTS}>:TTS_SUPPORT>
$<$<BOOL:${WITH_EPWING_SUPPORT}>:EPWING_SUPPORT>
$<$<BOOL:${WITH_ZIM}>:MAKE_ZIM_SUPPORT>
$<$<BOOL:${WITH_VCPKG_BREAKPAD}>:USE_BREAKPAD>
)
)
if (WIN32)
target_compile_definitions(${GOLDENDICT} PUBLIC
__WIN32
INCLUDE_LIBRARY_PATH
)
endif ()
if (WITH_FFMPEG_PLAYER)
target_compile_definitions(${GOLDENDICT} PUBLIC MAKE_FFMPEG_PLAYER)
endif ()
if(NOT WITH_TTS)
target_compile_definitions(${GOLDENDICT} PUBLIC NO_TTS_SUPPORT)
endif()
if (NOT WITH_EPWING_SUPPORT)
target_compile_definitions(${GOLDENDICT} PUBLIC NO_EPWING_SUPPORT)
endif ()
if (WITH_ZIM)
target_compile_definitions(${GOLDENDICT} PUBLIC MAKE_ZIM_SUPPORT)
endif ()
if (WITH_VCPKG_BREAKPAD)
target_compile_definitions(${GOLDENDICT} PUBLIC USE_BREAKPAD)
endif ()
#### libraries linking && includes for Win or Unix
if (WIN32)
include(cmake/Deps_Vcpkg.cmake)
include(Deps_Vcpkg)
else ()
include(cmake/Deps_Unix.cmake)
include(Deps_Unix)
endif ()
#### add translations
@ -219,11 +261,156 @@ add_dependencies(${GOLDENDICT} "release_translations")
#### installation or assemble redistribution
if (APPLE)
include(cmake/Package_macOS.cmake)
elseif (LINUX OR BSD)
include(cmake/Package_Linux.cmake)
elseif (WIN32)
include(cmake/Package_Windows.cmake)
set(PLIST_FILE "${CMAKE_BINARY_DIR}/info_generated.plist")
configure_file("${CMAKE_SOURCE_DIR}/redist/mac_info_plist_template_cmake.plist" "${PLIST_FILE}" @ONLY)
set_target_properties(${GOLDENDICT} PROPERTIES
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_INFO_PLIST "${PLIST_FILE}"
)
set(Assembling_Dir "${CMAKE_BINARY_DIR}/redist")
set(App_Name "${GOLDENDICT}.app")
set(Redistributable_APP "${Assembling_Dir}/${App_Name}")
# if anything wrong, delete this and affect lines, and see what's Qt will generate by default.
set(QtConfPath "${Redistributable_APP}/Contents/Resources/qt.conf")
qt_generate_deploy_script(
TARGET ${GOLDENDICT}
OUTPUT_SCRIPT deploy_script
CONTENT "
set(QT_DEPLOY_PREFIX \"${Redistributable_APP}\")
set(QT_DEPLOY_TRANSLATIONS_DIR \"Contents/Resources/translations\")
qt_deploy_runtime_dependencies(
EXECUTABLE \"${Redistributable_APP}\"
ADDITIONAL_LIBRARIES ${BREW_ICU_ADDITIONAL_DYLIBS}
GENERATE_QT_CONF
NO_APP_STORE_COMPLIANCE)
qt_deploy_translations()
qt_deploy_qt_conf(\"${QtConfPath}\"
PLUGINS_DIR PlugIns
TRANSLATIONS_DIR Resources/translations)
"
)
install(TARGETS ${GOLDENDICT} BUNDLE DESTINATION "${Assembling_Dir}")
install(FILES ${qm_files} DESTINATION "${Redistributable_APP}/Contents/MacOS/locale")
if (IS_READABLE "/opt/homebrew/share/opencc/")
set(OPENCC_DATA_PATH "/opt/homebrew/share/opencc/" CACHE PATH "opencc's data path")
elseif (IS_READABLE "/usr/local/share/opencc/")
set(OPENCC_DATA_PATH "/usr/local/share/opencc/" CACHE PATH "opencc's data path")
else ()
message(FATAL_ERROR "Cannot find opencc's data folder!")
endif ()
file(REAL_PATH "${OPENCC_DATA_PATH}" OPENCC_DATA_PATH_FOR_REAL)
message(STATUS "OPENCC data is found -> ${OPENCC_DATA_PATH_FOR_REAL}")
install(DIRECTORY "${OPENCC_DATA_PATH_FOR_REAL}" DESTINATION "${Redistributable_APP}/Contents/MacOS")
install(SCRIPT ${deploy_script})
install(CODE "execute_process(COMMAND codesign --force --deep -s - ${Redistributable_APP})")
find_program(CREATE-DMG "create-dmg")
if (CREATE-DMG)
install(CODE "
execute_process(COMMAND ${CREATE-DMG} \
--skip-jenkins \
--format \"ULMO\"
--volname ${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-${CMAKE_SYSTEM_PROCESSOR} \
--volicon ${CMAKE_SOURCE_DIR}/icons/macicon.icns \
--icon \"${App_Name}\" 100 100
--app-drop-link 300 100 \
\"GoldenDict-ng-${CMAKE_PROJECT_VERSION}-Qt${Qt6_VERSION}-macOS-${CMAKE_SYSTEM_PROCESSOR}.dmg\" \
\"${Assembling_Dir}\")"
)
else ()
message(WARNING "create-dmg not found. No .dmg will be created")
endif ()
endif ()
if (LINUX OR BSD)
install(TARGETS ${GOLDENDICT})
install(FILES ${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop DESTINATION share/applications)
install(FILES ${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.metainfo.xml DESTINATION share/metainfo)
if (NOT USE_ALTERNATIVE_NAME)
# see: config.cc -> getProgramDataDir
add_compile_definitions(PROGRAM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/goldendict")
install(FILES ${CMAKE_SOURCE_DIR}/redist/icons/goldendict.png DESTINATION share/pixmaps)
install(FILES ${qm_files} DESTINATION share/goldendict/locale)
else ()
add_compile_definitions(PROGRAM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/goldendict-ng")
install(FILES ${CMAKE_SOURCE_DIR}/redist/icons/goldendict.png DESTINATION share/pixmaps
RENAME goldendict-ng.png)
install(FILES ${qm_files} DESTINATION share/goldendict-ng/locale)
block() # patch the desktop file to adapt the binary & icon file's name change
file(READ "${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop" DESKTOP_FILE_CONTENT)
string(REGEX REPLACE "\nIcon=goldendict\n" "\nIcon=goldendict-ng\n" DESKTOP_FILE_CONTENT "${DESKTOP_FILE_CONTENT}")
string(REGEX REPLACE "\nExec=goldendict %u\n" "\nExec=goldendict-ng %u\n" DESKTOP_FILE_CONTENT "${DESKTOP_FILE_CONTENT}")
file(WRITE "${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop" "${DESKTOP_FILE_CONTENT}")
endblock()
endif ()
endif ()
if (WIN32)
set_target_properties(${GOLDENDICT}
PROPERTIES
WIN32_EXECUTABLE TRUE
RUNTIME_OUTPUT_DIRECTORY "${GD_WIN_OUTPUT_DIR}"
LIBRARY_OUTPUT_DIRECTORY "${GD_WIN_OUTPUT_DIR}"
)
set(CMAKE_INSTALL_PREFIX "${GD_WIN_OUTPUT_DIR}" CACHE PATH "If you see this message, don't change this unless you want look into CMake build script. If you are an expert, yes, this is wrong. Help welcomed." FORCE)
qt_generate_deploy_script(
TARGET ${GOLDENDICT}
OUTPUT_SCRIPT deploy_script
CONTENT "qt_deploy_runtime_dependencies(
EXECUTABLE \"${CMAKE_INSTALL_PREFIX}/goldendict.exe\"
BIN_DIR .
LIB_DIR .
)"
)
install(SCRIPT ${deploy_script})
install(DIRECTORY "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/share/opencc" DESTINATION .)
# TODO: do we really need to carry a copy of openSSL?
install(FILES "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libssl-3-x64.dll" DESTINATION .)
install(FILES "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libcrypto-3-x64.dll" DESTINATION .)
# trick CPack to make the output folder as NSIS installer
install(DIRECTORY "${GD_WIN_OUTPUT_DIR}/"
DESTINATION .
FILES_MATCHING
PATTERN "*"
PATTERN "*.pdb" EXCLUDE
PATTERN "*.ilk" EXCLUDE)
set(CPACK_PACKAGE_FILE_NAME "GoldenDict-ng-${PROJECT_VERSION}-Qt${Qt6Widgets_VERSION}")
set(CPACK_GENERATOR "7Z;NSIS64")
# override the default install path, which is $PROGRAMFILES64\${project-name} ${project-version} in NSIS
set(CPACK_PACKAGE_INSTALL_DIRECTORY "GoldenDict-ng")
# NSIS specificS
set(CPACK_NSIS_MANIFEST_DPI_AWARE ON)
set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/icons/programicon.ico")
set(CPACK_NSIS_PACKAGE_NAME "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}")
set(CPACK_NSIS_DISPLAY_NAME "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}")
set(CPACK_NSIS_URL_INFO_ABOUT [=[https://xiaoyifang.github.io/goldendict-ng/]=])
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt")
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\GoldenDict-ng.lnk' '$INSTDIR\\\\${GOLDENDICT}.exe'")
set(CPACK_NSIS_DELETE_ICONS_EXTRA "Delete '$SMPROGRAMS\\\\$START_MENU\\\\GoldenDict-ng.lnk'")
include(CPack)
endif ()
feature_summary(WHAT ALL DESCRIPTION "Build configuration:")

View file

@ -1,4 +1,5 @@
#### Various workarounds
if (APPLE)
# old & new homebrew's include paths
target_include_directories(${GOLDENDICT} PRIVATE /usr/local/include /opt/homebrew/include)
@ -28,20 +29,25 @@ endif ()
##### Finding packages from package manager
find_package(PkgConfig REQUIRED)
find_package(ZLIB REQUIRED)
find_package(BZip2 REQUIRED)
# Import all PkgConfig dependencies as one
pkg_check_modules(DEPS REQUIRED IMPORTED_TARGET
# Consider all PkgConfig dependencies as one
pkg_check_modules(PKGCONFIG_DEPS IMPORTED_TARGET
hunspell
liblzma
lzo2
opencc
vorbis # .ogg
vorbisfile
liblzma
xapian-core
zlib
)
target_link_libraries(${GOLDENDICT} PRIVATE PkgConfig::DEPS BZip2::BZip2)
target_link_libraries(${GOLDENDICT} PRIVATE
PkgConfig::PKGCONFIG_DEPS
BZip2::BZip2
ZLIB::ZLIB
)
# On FreeBSD, there are two iconv, libc iconv & GNU libiconv.
# The system one is good enough, the following is a workaround to use libc iconv on freeBSD.
@ -82,7 +88,7 @@ if (WITH_ZIM)
COMMAND_ERROR_IS_FATAL ANY)
message(STATUS "Found correct homebrew icu path -> ${ICU_REQUIRED_BY_ZIM_PREFIX}")
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${ICU_REQUIRED_BY_ZIM_PREFIX}/lib/pkgconfig")
message(STATUS "Updated pkg_config_path -> $ENV{PKG_CONFIG_PATH}")
message(STATUS "Updated pkg_config_path -> $ENV{PKG_CONFIG_PATH}:${ICU_REQUIRED_BY_ZIM_PREFIX}/lib/pkgconfig")
# icu4c as transitive dependency of libzim may not be automatically copied into app bundle
# so we manually discover the icu4c from homebrew, then find the relevent dylibs

View file

@ -1,22 +0,0 @@
install(TARGETS ${GOLDENDICT})
install(FILES ${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop DESTINATION share/applications)
install(FILES ${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.metainfo.xml DESTINATION share/metainfo)
if (NOT USE_ALTERNATIVE_NAME)
# see: config.cc -> getProgramDataDir
add_compile_definitions(PROGRAM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/goldendict")
install(FILES ${CMAKE_SOURCE_DIR}/redist/icons/goldendict.png DESTINATION share/pixmaps)
install(FILES ${qm_files} DESTINATION share/goldendict/locale)
else ()
add_compile_definitions(PROGRAM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/goldendict-ng")
install(FILES ${CMAKE_SOURCE_DIR}/redist/icons/goldendict.png DESTINATION share/pixmaps
RENAME goldendict-ng.png)
install(FILES ${qm_files} DESTINATION share/goldendict-ng/locale)
block() # patch the desktop file to adapt the binary & icon file's name change
file(READ "${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop" DESKTOP_FILE_CONTENT)
string(REGEX REPLACE "\nIcon=goldendict\n" "\nIcon=goldendict-ng\n" DESKTOP_FILE_CONTENT "${DESKTOP_FILE_CONTENT}")
string(REGEX REPLACE "\nExec=goldendict %u\n" "\nExec=goldendict-ng %u\n" DESKTOP_FILE_CONTENT "${DESKTOP_FILE_CONTENT}")
file(WRITE "${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop" "${DESKTOP_FILE_CONTENT}")
endblock()
endif ()

View file

@ -1,55 +0,0 @@
set_target_properties(${GOLDENDICT}
PROPERTIES
WIN32_EXECUTABLE TRUE
RUNTIME_OUTPUT_DIRECTORY "${GD_WIN_OUTPUT_DIR}"
LIBRARY_OUTPUT_DIRECTORY "${GD_WIN_OUTPUT_DIR}"
)
# TODO: this breaks "Multi-Config" build systems like VisualStudio.
set(CMAKE_INSTALL_PREFIX "${GD_WIN_OUTPUT_DIR}" CACHE PATH "If you see this message, don't change this unless you want look into CMake build script. If you are an expert, yes, this is wrong. Help welcomed." FORCE)
qt_generate_deploy_script(
TARGET ${GOLDENDICT}
OUTPUT_SCRIPT deploy_script
CONTENT "qt_deploy_runtime_dependencies(
EXECUTABLE \"${CMAKE_INSTALL_PREFIX}/goldendict.exe\"
BIN_DIR .
LIB_DIR .
)"
)
install(SCRIPT ${deploy_script})
install(DIRECTORY "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/share/opencc" DESTINATION .)
# Note: This is runtime dependency that aren't copied automatically
# See Qt's network -> SSDL documentation https://doc.qt.io/qt-6/ssl.html#considerations-while-packaging-your-application
install(FILES "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libssl-3-x64.dll" DESTINATION .)
install(FILES "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libcrypto-3-x64.dll" DESTINATION .)
# trick CPack to make the output folder as NSIS installer
install(DIRECTORY "${GD_WIN_OUTPUT_DIR}/"
DESTINATION .
FILES_MATCHING
PATTERN "*"
PATTERN "*.pdb" EXCLUDE
PATTERN "*.ilk" EXCLUDE)
set(CPACK_PACKAGE_FILE_NAME "GoldenDict-ng-${PROJECT_VERSION}-Qt${Qt6Widgets_VERSION}")
set(CPACK_GENERATOR "7Z;NSIS64")
# override the default install path, which is $PROGRAMFILES64\${project-name} ${project-version} in NSIS
set(CPACK_PACKAGE_INSTALL_DIRECTORY "GoldenDict-ng")
# NSIS specificS
set(CPACK_NSIS_MANIFEST_DPI_AWARE ON)
set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/icons/programicon.ico")
set(CPACK_NSIS_PACKAGE_NAME "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}")
set(CPACK_NSIS_DISPLAY_NAME "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt")
# Copied from https://crascit.com/2015/08/07/cmake_cpack_nsis_shortcuts_with_parameters/
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\GoldenDict-ng.lnk' '$INSTDIR\\\\${GOLDENDICT}.exe'")
set(CPACK_NSIS_DELETE_ICONS_EXTRA "Delete '$SMPROGRAMS\\\\$START_MENU\\\\GoldenDict-ng.lnk'")
include(CPack)

View file

@ -1,69 +0,0 @@
set(PLIST_FILE "${CMAKE_BINARY_DIR}/info_generated.plist")
configure_file("${CMAKE_SOURCE_DIR}/redist/mac_info_plist_template_cmake.plist" "${PLIST_FILE}" @ONLY)
set_target_properties(${GOLDENDICT} PROPERTIES
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_INFO_PLIST "${PLIST_FILE}"
)
set(Assembling_Dir "${CMAKE_BINARY_DIR}/redist")
set(App_Name "${GOLDENDICT}.app")
set(Redistributable_APP "${Assembling_Dir}/${App_Name}")
# if anything wrong, delete this and affect lines, and see what's Qt will generate by default.
set(QtConfPath "${Redistributable_APP}/Contents/Resources/qt.conf")
qt_generate_deploy_script(
TARGET ${GOLDENDICT}
OUTPUT_SCRIPT deploy_script
CONTENT "
set(QT_DEPLOY_PREFIX \"${Redistributable_APP}\")
set(QT_DEPLOY_TRANSLATIONS_DIR \"Contents/Resources/translations\")
qt_deploy_runtime_dependencies(
EXECUTABLE \"${Redistributable_APP}\"
ADDITIONAL_LIBRARIES ${BREW_ICU_ADDITIONAL_DYLIBS}
GENERATE_QT_CONF
NO_APP_STORE_COMPLIANCE)
qt_deploy_translations()
qt_deploy_qt_conf(\"${QtConfPath}\"
PLUGINS_DIR PlugIns
TRANSLATIONS_DIR Resources/translations)
"
)
install(TARGETS ${GOLDENDICT} BUNDLE DESTINATION "${Assembling_Dir}")
install(FILES ${qm_files} DESTINATION "${Redistributable_APP}/Contents/MacOS/locale")
if (IS_READABLE "/opt/homebrew/share/opencc/")
set(OPENCC_DATA_PATH "/opt/homebrew/share/opencc/" CACHE PATH "opencc's data path")
elseif (IS_READABLE "/usr/local/share/opencc/")
set(OPENCC_DATA_PATH "/usr/local/share/opencc/" CACHE PATH "opencc's data path")
else ()
message(FATAL_ERROR "Cannot find opencc's data folder!")
endif ()
file(REAL_PATH "${OPENCC_DATA_PATH}" OPENCC_DATA_PATH_FOR_REAL)
message(STATUS "OPENCC data is found -> ${OPENCC_DATA_PATH_FOR_REAL}")
install(DIRECTORY "${OPENCC_DATA_PATH_FOR_REAL}" DESTINATION "${Redistributable_APP}/Contents/MacOS")
install(SCRIPT ${deploy_script})
install(CODE "execute_process(COMMAND codesign --force --deep -s - ${Redistributable_APP})")
find_program(CREATE-DMG "create-dmg")
if (CREATE-DMG)
install(CODE "
execute_process(COMMAND ${CREATE-DMG} \
--skip-jenkins \
--format \"ULMO\"
--volname ${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-${CMAKE_SYSTEM_PROCESSOR} \
--volicon ${CMAKE_SOURCE_DIR}/icons/macicon.icns \
--icon \"${App_Name}\" 100 100
--app-drop-link 300 100 \
\"GoldenDict-ng-${CMAKE_PROJECT_VERSION}-Qt${Qt6_VERSION}-macOS-${CMAKE_SYSTEM_PROCESSOR}.dmg\" \
\"${Assembling_Dir}\")"
)
else ()
message(WARNING "create-dmg not found. No .dmg will be created")
endif ()

View file

@ -800,7 +800,7 @@ Class load()
// Upgrading
c.dictServers = makeDefaultDictServers();
}
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
QDomNode ves = root.namedItem( "voiceEngines" );
if ( !ves.isNull() ) {
@ -1684,7 +1684,7 @@ void save( Class const & c )
p.setAttributeNode( icon );
}
}
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
{
QDomNode ves = dd.createElement( "voiceEngines" );
root.appendChild( ves );

View file

@ -725,7 +725,7 @@ struct Program
using Programs = QList< Program >;
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
struct VoiceEngine
{
bool enabled;
@ -818,7 +818,7 @@ struct Class
Lingua lingua;
Forvo forvo;
Programs programs;
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
VoiceEngines voiceEngines;
#endif

View file

@ -216,6 +216,11 @@ public:
~AardDictionary();
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.articleCount;

View file

@ -173,6 +173,11 @@ public:
BglDictionary( string const & id, string const & indexFile, string const & dictionaryFile );
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.articleCount;

View file

@ -91,6 +91,11 @@ public:
~DictdDictionary();
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.articleCount;

View file

@ -30,6 +30,13 @@ using std::string;
using gd::wstring;
using std::map;
enum Property {
Author,
Copyright,
Description,
Email
};
DEF_EX( Ex, "Dictionary error", std::exception )
DEF_EX( exIndexOutOfRange, "The supplied index is out of range", Ex )
DEF_EX( exSliceOutOfRange, "The requested data slice is out of range", Ex )
@ -373,6 +380,10 @@ public:
metadata_enable_fts = _enable_FTS;
}
/// Returns all the available properties, like the author's name, copyright,
/// description etc. All strings are in utf8.
virtual map< Property, string > getProperties() noexcept = 0;
/// Returns the features the dictionary possess. See the Feature enum for
/// their list.
virtual Features getFeatures() const noexcept

View file

@ -303,6 +303,10 @@ public:
disconnectFromServer( socket );
}
map< Property, string > getProperties() noexcept override
{
return {};
}
unsigned long getArticleCount() noexcept override
{

View file

@ -156,6 +156,11 @@ public:
~DslDictionary();
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.articleCount;

View file

@ -1,7 +1,7 @@
/* This file is (c) 2014 Abs62
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#include <QDir>
#ifdef EPWING_SUPPORT
#ifndef NO_EPWING_SUPPORT
#include "epwing_book.hh"
#include "epwing.hh"
@ -87,6 +87,12 @@ public:
~EpwingDictionary();
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.articleCount;

View file

@ -1,7 +1,7 @@
/* This file is (c) 2014 Abs62
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#ifdef EPWING_SUPPORT
#ifndef NO_EPWING_SUPPORT
#include "epwing_book.hh"

View file

@ -1,7 +1,7 @@
/* This file is (c) 2014 Abs62
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#ifdef EPWING_SUPPORT
#ifndef NO_EPWING_SUPPORT
#include "epwing_charmap.hh"

View file

@ -38,6 +38,11 @@ public:
}
map< Property, string > getProperties() noexcept override
{
return map< Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return 0;

View file

@ -349,6 +349,11 @@ public:
~GlsDictionary();
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.articleCount;

View file

@ -15,7 +15,12 @@
#include <set>
#include "utils.hh"
#include <QtConcurrentRun>
#include <hunspell/hunspell.hxx>
#ifndef INCLUDE_LIBRARY_PATH
#include <hunspell.hxx>
#else
#include <hunspell/hunspell.hxx>
#endif
namespace HunspellMorpho {
@ -50,6 +55,12 @@ public:
dictionaryName = name_;
}
map< Property, string > getProperties() noexcept override
{
return map< Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return 0;

View file

@ -165,6 +165,12 @@ WHERE {
}
}
map< Property, string > getProperties() noexcept override
{
return {};
}
unsigned long getArticleCount() noexcept override
{
return 0;

View file

@ -34,7 +34,7 @@
#include "dict/transliteration/romaji.hh"
#include "dict/transliteration/russian.hh"
#ifdef EPWING_SUPPORT
#ifndef NO_EPWING_SUPPORT
#include "dict/epwing.hh"
#endif
@ -83,7 +83,7 @@ LoadDictionaries::LoadDictionaries( Config::Class const & cfg ):
<< "*.zim"
<< "*.zimaa"
#endif
#ifdef EPWING_SUPPORT
#ifndef NO_EPWING_SUPPORT
<< "*catalogs"
#endif
;
@ -181,7 +181,7 @@ void LoadDictionaries::handlePath( Config::Path const & path )
#ifdef MAKE_ZIM_SUPPORT
addDicts( Zim::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this, maxHeadwordToExpand ) );
#endif
#ifdef EPWING_SUPPORT
#ifndef NO_EPWING_SUPPORT
addDicts( Epwing::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) );
#endif
}
@ -274,7 +274,7 @@ void loadDictionaries( QWidget * parent,
addDicts( Forvo::makeDictionaries( loadDicts, cfg.forvo, dictNetMgr ) );
addDicts( Lingua::makeDictionaries( loadDicts, cfg.lingua, dictNetMgr ) );
addDicts( Programs::makeDictionaries( cfg.programs ) );
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
addDicts( VoiceEngines::makeDictionaries( cfg.voiceEngines ) );
#endif
addDicts( DictServer::makeDictionaries( cfg.dictServers ) );

View file

@ -159,6 +159,11 @@ public:
string getName() noexcept override;
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.soundsCount;

View file

@ -212,6 +212,12 @@ public:
void deferredInit() override;
map< Dictionary::Property, string > getProperties() noexcept override
{
return {};
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.articleCount;

View file

@ -56,6 +56,11 @@ public:
return name;
}
map< Property, string > getProperties() noexcept override
{
return map< Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return 0;

View file

@ -36,6 +36,11 @@ public:
return prg.name.toUtf8().data();
}
map< Property, string > getProperties() noexcept override
{
return map< Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return 0;

View file

@ -113,6 +113,11 @@ public:
~SdictDictionary();
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.articleCount;

View file

@ -610,6 +610,12 @@ public:
~SlobDictionary();
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.articleCount;

View file

@ -75,6 +75,12 @@ public:
vector< string > const & dictionaryFiles,
QString const & iconFilename_ );
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.soundsCount;

View file

@ -16,7 +16,7 @@ Sources::Sources( QWidget * parent, Config::Class const & cfg ):
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
chineseConversion( new ChineseConversion( this, cfg.transliteration.chinese ) ),
#endif
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
textToSpeechSource( nullptr ),
#endif
itemDelegate( new QItemDelegate( this ) ),
@ -129,7 +129,7 @@ Sources::Sources( QWidget * parent, Config::Class const & cfg ):
ui.forvoLanguageCodes->setText( forvo.languageCodes );
// Text to speech
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
if ( !cfg.notts ) {
textToSpeechSource = new TextToSpeechSource( this, cfg.voiceEngines );
ui.tabWidget->addTab( textToSpeechSource, QIcon( ":/icons/text2speech.svg" ), tr( "Text to Speech" ) );
@ -325,7 +325,7 @@ void Sources::on_removeProgram_clicked()
}
}
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
Config::VoiceEngines Sources::getVoiceEngines() const
{
if ( !textToSpeechSource )

View file

@ -295,7 +295,7 @@ public:
{
return programsModel.getCurrentPrograms();
}
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
Config::VoiceEngines getVoiceEngines() const;
#endif
Config::Hunspell getHunspell() const;
@ -317,7 +317,7 @@ private:
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
ChineseConversion * chineseConversion;
#endif
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
TextToSpeechSource * textToSpeechSource;
#endif
QItemDelegate * itemDelegate;

View file

@ -134,6 +134,11 @@ public:
~StardictDictionary();
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.wordCount;

View file

@ -26,6 +26,11 @@ string BaseTransliterationDictionary::getName() noexcept
return name;
}
map< Dictionary::Property, string > BaseTransliterationDictionary::getProperties() noexcept
{
return map< Dictionary::Property, string >();
}
unsigned long BaseTransliterationDictionary::getArticleCount() noexcept
{
return 0;

View file

@ -28,6 +28,8 @@ public:
virtual string getName() noexcept;
virtual map< Dictionary::Property, string > getProperties() noexcept;
virtual unsigned long getArticleCount() noexcept;
virtual unsigned long getWordCount() noexcept;

View file

@ -1,6 +1,6 @@
/* This file is (c) 2013 Timon Wong <timon86.wang@gmail.com>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
#include "voiceengines.hh"
#include "audiolink.hh"
@ -47,6 +47,10 @@ public:
return voiceEngine.name.toUtf8().data();
}
map< Property, string > getProperties() noexcept override
{
return map< Property, string >();
}
unsigned long getArticleCount() noexcept override
{

View file

@ -1,7 +1,7 @@
/* This file is (c) 2013 Timon Wong <timon86.wang@gmail.com>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#pragma once
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
#include "dictionary.hh"
#include "config.hh"

View file

@ -52,6 +52,12 @@ public:
dictionaryDescription = urlTemplate_;
}
map< Property, string > getProperties() noexcept override
{
return map< Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return 0;

View file

@ -140,6 +140,12 @@ public:
~XdxfDictionary();
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.articleCount;

View file

@ -161,6 +161,11 @@ public:
~ZimDictionary() = default;
map< Dictionary::Property, string > getProperties() noexcept override
{
return {};
}
unsigned long getArticleCount() noexcept override
{
return idxHeader.articleCount;

View file

@ -107,6 +107,10 @@ public:
string getName() noexcept override;
map< Dictionary::Property, string > getProperties() noexcept override
{
return map< Dictionary::Property, string >();
}
unsigned long getArticleCount() noexcept override
{

View file

@ -510,7 +510,7 @@ int main( int argc, char ** argv )
if ( gdcl.notts ) {
cfg.notts = true;
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
cfg.voiceEngines.clear();
#endif
}

View file

@ -1,4 +1,4 @@
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
#include "speechclient.hh"

View file

@ -1,5 +1,5 @@
#pragma once
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
#include <QObject>
#include "config.hh"

View file

@ -1,6 +1,6 @@
/* This file is (c) 2013 Timon Wong <timon86.wang@gmail.com>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
#include "texttospeechsource.hh"
#include <QVariant>

View file

@ -3,7 +3,7 @@
#pragma once
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
#include "ui_texttospeechsource.h"
#include "config.hh"

View file

@ -1048,7 +1048,7 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref, QString const &
QMessageBox::critical( this, "GoldenDict", tr( "The referenced audio program doesn't exist." ) );
}
else if ( url.scheme() == "gdtts" ) {
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
// Text to speech
QString md5Id = Utils::Url::queryItemValue( url, "engine" );
QString text( url.path().mid( 1 ) );

View file

@ -173,7 +173,7 @@ bool EditDictionaries::isSourcesChanged() const
|| sources.getLingua() != cfg.lingua || sources.getForvo() != cfg.forvo || sources.getMediaWikis() != cfg.mediawikis
|| sources.getWebSites() != cfg.webSites || sources.getDictServers() != cfg.dictServers
|| sources.getPrograms() != cfg.programs
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
|| sources.getVoiceEngines() != cfg.voiceEngines
#endif
;
@ -197,7 +197,7 @@ void EditDictionaries::acceptChangedSources( bool rebuildGroups )
cfg.webSites = sources.getWebSites();
cfg.dictServers = sources.getDictServers();
cfg.programs = sources.getPrograms();
#ifdef TTS_SUPPORT
#ifndef NO_TTS_SUPPORT
cfg.voiceEngines = sources.getVoiceEngines();
#endif
setUpdatesEnabled( false );

View file

@ -3,7 +3,7 @@
#include <Qt>
#include <QScopeGuard>
#ifdef EPWING_SUPPORT
#ifndef NO_EPWING_SUPPORT
#include "dict/epwing_book.hh"
#endif
@ -209,7 +209,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
+ " GoldenDict/WebEngine" );
}
#ifdef EPWING_SUPPORT
#ifndef NO_EPWING_SUPPORT
Epwing::initialize();
#endif
@ -1173,7 +1173,7 @@ MainWindow::~MainWindow()
scanPopup = nullptr;
}
#ifdef EPWING_SUPPORT
#ifndef NO_EPWING_SUPPORT
Epwing::finalize();
#endif
}

View file

@ -390,7 +390,7 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ):
#ifndef MAKE_ZIM_SUPPORT
ui.allowZim->hide();
#endif
#ifndef EPWING_SUPPORT
#ifdef NO_EPWING_SUPPORT
ui.allowEpwing->hide();
#endif
ui.maxDictionarySize->setValue( p.fts.maxDictionarySize );

View file

@ -8,8 +8,8 @@ const QLatin1String flags = QLatin1String(
#ifdef MAKE_ZIM_SUPPORT
" MAKE_ZIM_SUPPORT"
#endif
#ifdef EPWING_SUPPORT
" EPWING_SUPPORT"
#ifdef NO_EPWING_SUPPORT
" NO_EPWING_SUPPORT"
#endif
#ifdef USE_ICONV
" USE_ICONV"
@ -17,8 +17,8 @@ const QLatin1String flags = QLatin1String(
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
" MAKE_CHINESE_CONVERSION_SUPPORT"
#endif
#ifdef TTS_SUPPORT
" TTS_SUPPORT"
#ifdef NO_TTS_SUPPORT
" NO_TTS_SUPPORT"
#endif
#ifndef MAKE_FFMPEG_PLAYER
" no_ffmpeg_player"