diff --git a/CMakeLists.txt b/CMakeLists.txt index 34b8e4f1..df472676 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,14 +107,6 @@ if(X11_FOUND) endif(NOT HAVE_XSYNC AND NOT HAVE_XSCREENSAVER) endif(X11_FOUND) -kde4_optional_find_package(Libintl) -set_package_properties(Libintl PROPERTIES - DESCRIPTION "Support for multiple languages" - URL "http://www.gnu.org/software/gettext" - TYPE RECOMMENDED - PURPOSE "Enables KDE to be available in many different languages" -) - kde4_optional_find_package(DBusMenuQt) set_package_properties(DBusMenuQt PROPERTIES DESCRIPTION "Support for notification area menus via the DBusMenu protocol" diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index a9ed69bd..31e93f63 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -15,7 +15,6 @@ include(CMakePushCheckState) # definitions like _GNU_SOURCE that are needed on each platform. set(CMAKE_REQUIRED_DEFINITIONS ${_KDE4_PLATFORM_DEFINITIONS}) -kde4_bool_to_01(Libintl_FOUND HAVE_LIBINTL) # kdecore kde4_bool_to_01(DBUSMENUQT_FOUND HAVE_DBUSMENUQT) # kdeui kde4_bool_to_01(LibArchive_FOUND HAVE_LIBARCHIVE) # karchive kde4_bool_to_01(BZIP2_FOUND HAVE_BZIP2) # karchive diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt index c3a7662e..25af34e6 100644 --- a/cmake/modules/CMakeLists.txt +++ b/cmake/modules/CMakeLists.txt @@ -43,7 +43,6 @@ set(cmakeFiles FindLibATASmart.cmake FindLibDeflate.cmake FindLibDRM.cmake - FindLibintl.cmake FindLibKonq.cmake FindLibLZMA.cmake FindLibMms.cmake diff --git a/cmake/modules/FindKDE4Internal.cmake b/cmake/modules/FindKDE4Internal.cmake index 98988fbe..225846a1 100644 --- a/cmake/modules/FindKDE4Internal.cmake +++ b/cmake/modules/FindKDE4Internal.cmake @@ -302,7 +302,7 @@ if(_kdeBootStrapping) set(KDE4_DATA_INSTALL_DIR "${KDE4_SHARE_INSTALL_PREFIX}/apps" CACHE PATH "KDE data installation directory") set(KDE4_ICON_INSTALL_DIR "${KDE4_SHARE_INSTALL_PREFIX}/icons" CACHE PATH "KDE icon installation directory") set(KDE4_KCFG_INSTALL_DIR "${KDE4_SHARE_INSTALL_PREFIX}/config.kcfg" CACHE PATH "KDE kcfg installation directory") - set(KDE4_LOCALE_INSTALL_DIR "${CMAKE_INSTALL_FULL_LOCALEDIR}" CACHE PATH "KDE locale installation directory") + set(KDE4_LOCALE_INSTALL_DIR "${KATIE_TRANSLATIONS_PATH}/kde4" CACHE PATH "KDE locale installation directory") set(KDE4_SERVICES_INSTALL_DIR "${KDE4_SHARE_INSTALL_PREFIX}/kde4/services" CACHE PATH "KDE services installation directory") set(KDE4_SERVICETYPES_INSTALL_DIR "${KDE4_SHARE_INSTALL_PREFIX}/kde4/servicetypes" CACHE PATH "KDE service types installation directory") set(KDE4_SOUND_INSTALL_DIR "${KDE4_SHARE_INSTALL_PREFIX}/sounds" CACHE PATH "KDE sounds installation directory") diff --git a/cmake/modules/FindLibintl.cmake b/cmake/modules/FindLibintl.cmake deleted file mode 100644 index 2b8bce67..00000000 --- a/cmake/modules/FindLibintl.cmake +++ /dev/null @@ -1,45 +0,0 @@ -# Try to find Libintl functionality, once done this will define: -# -# LIBINTL_FOUND - system has Libintl -# LIBINTL_INCLUDE_DIR - Libintl include directory -# LIBINTL_LIBRARIES - Libraries needed to use Libintl -# -# TODO: This will enable translations only if Gettext functionality is -# present in libc. Must have more robust system for release, where Gettext -# functionality can also reside in standalone Gettext library, or the one -# embedded within kdelibs (cf. gettext.m4 from Gettext source). - -# Copyright (c) 2006, Chusslove Illich, -# Copyright (c) 2007, Alexander Neundorf, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -if(LIBINTL_INCLUDE_DIR AND LIBINTL_LIB_FOUND) - set(Libintl_FIND_QUIETLY TRUE) -endif(LIBINTL_INCLUDE_DIR AND LIBINTL_LIB_FOUND) - -find_path(LIBINTL_INCLUDE_DIR libintl.h) - -set(LIBINTL_LIB_FOUND FALSE) - -if(LIBINTL_INCLUDE_DIR) - include(CheckFunctionExists) - check_function_exists(dgettext LIBINTL_LIBC_HAS_DGETTEXT) - - if (LIBINTL_LIBC_HAS_DGETTEXT) - set(LIBINTL_LIBRARIES) - set(LIBINTL_LIB_FOUND TRUE) - else (LIBINTL_LIBC_HAS_DGETTEXT) - find_library(LIBINTL_LIBRARIES NAMES intl libintl ) - if(LIBINTL_LIBRARIES) - set(LIBINTL_LIB_FOUND TRUE) - endif(LIBINTL_LIBRARIES) - endif (LIBINTL_LIBC_HAS_DGETTEXT) - -endif(LIBINTL_INCLUDE_DIR) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Libintl DEFAULT_MSG LIBINTL_INCLUDE_DIR LIBINTL_LIB_FOUND) - -mark_as_advanced(LIBINTL_INCLUDE_DIR LIBINTL_LIBRARIES LIBINTL_LIBC_HAS_DGETTEXT LIBINTL_LIB_FOUND) diff --git a/cmake/modules/KDE4Macros.cmake b/cmake/modules/KDE4Macros.cmake index fca100ba..ac05541e 100644 --- a/cmake/modules/KDE4Macros.cmake +++ b/cmake/modules/KDE4Macros.cmake @@ -296,14 +296,37 @@ macro(KDE4_OPTIONAL_ADD_SUBDIRECTORY _dir) endif() endmacro(KDE4_OPTIONAL_ADD_SUBDIRECTORY) -# KDE4_OPTIONAL_FIND_PACKAGE( ... ) +# KDE4_OPTIONAL_FIND_PACKAGE( ...) # This macro is a combination of OPTION() and FIND_PACKAGE(), it works like # FIND_PACKAGE(), but additionally it automatically creates an option # WITH_, which can be disabled via the cmake GUI or via # -DWITH_=OFF -macro(KDE4_OPTIONAL_FIND_PACKAGE _name) - option(WITH_${_name} "Search for ${_name} package" ON) - if (WITH_${_name}) - find_package(${_name} ${ARGN}) +macro(KDE4_OPTIONAL_FIND_PACKAGE _PACKAGE) + option(WITH_${_PACKAGE} "Search for ${_PACKAGE} package" ON) + if (WITH_${_PACKAGE}) + find_package(${_PACKAGE} ${ARGN}) endif () endmacro(KDE4_OPTIONAL_FIND_PACKAGE) + +# KDE4_OPTIONAL_FIND_PACKAGE( FILE1.po ... FILEN.po) +# This macro is will create and install translation files +macro(KDE4_TRANSLATE _LANGUAGE) + foreach(_pofile ${ARGN}) + get_filename_component(_abspofile "${_pofile}" ABSOLUTE) + get_filename_component(_poname "${_abspofile}" NAME_WE) + make_directory("${CMAKE_CURRENT_BINARY_DIR}") + set(trout "${CMAKE_CURRENT_BINARY_DIR}/${_poname}.tr") + string(REPLACE "@" "_" _language ${_LANGUAGE}) + add_custom_target( + translations_${_language}_${_poname} ALL + COMMAND ${KATIE_TRC} "${_abspofile}" -o "${trout}" + COMMENT "Generating ${_poname}.tr" + ) + set_source_files_properties("${trout}" PROPERTIES GENERATED TRUE) + install( + FILES "${trout}" + DESTINATION "${KDE4_LOCALE_INSTALL_DIR}/${_LANGUAGE}" + RENAME "${_poname}.tr" + ) + endforeach() +endmacro(KDE4_TRANSLATE) diff --git a/config.h.cmake b/config.h.cmake index cc95bacc..f01ccc96 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -38,9 +38,6 @@ /* Define to 1 if you have the XSync extension */ #cmakedefine HAVE_XSYNC 1 -/* Define to 1 if you have libintl */ -#cmakedefine HAVE_LIBINTL 1 - /* Define to 1 if you have DBusMenuQt */ #cmakedefine HAVE_DBUSMENUQT 1 diff --git a/kdecore/CMakeLists.txt b/kdecore/CMakeLists.txt index 11bf8fdd..fafcbbf8 100644 --- a/kdecore/CMakeLists.txt +++ b/kdecore/CMakeLists.txt @@ -35,12 +35,6 @@ set(kdecore_OPTIONAL_LIBS) add_definitions(-DQT_NO_CAST_FROM_ASCII) -# compile Gettext support if available -if(LIBINTL_FOUND) - include_directories(${LIBINTL_INCLUDE_DIR}) - set(kdecore_OPTIONAL_LIBS ${kdecore_OPTIONAL_LIBS} ${LIBINTL_LIBRARIES}) -endif() - # compile Enchant if available if(ENCHANT_FOUND) include_directories( diff --git a/kdecore/localization/kcatalog.cpp b/kdecore/localization/kcatalog.cpp index c525641f..68899d14 100644 --- a/kdecore/localization/kcatalog.cpp +++ b/kdecore/localization/kcatalog.cpp @@ -19,159 +19,115 @@ #include "kcatalog_p.h" #include "kstandarddirs.h" - -#include - -#include -#include - #include -#include -#include +#include +#include -#ifdef HAVE_LIBINTL -# include -#endif - -// = "LANGUAGE=" + 32 chars for language code + terminating zero -static const int langenvMaxlen = 42; - -Q_GLOBAL_STATIC(QMutex, catalogLock) - -class KMsgCtx +static QByteArray translationData(const QByteArray &localeDir, const QByteArray &language, const QByteArray &name) { -public: - KMsgCtx(const char* const msgctxt, const char* const msgid); - ~KMsgCtx(); - - const char* const constData() const; - -private: - Q_DISABLE_COPY(KMsgCtx); - - bool m_freedata; - char* m_data; -}; - -KMsgCtx::KMsgCtx(const char* const msgctxt, const char* const msgid) - : m_freedata(false), - m_data(nullptr) -{ - const int msgidlen = qstrlen(msgid); - if (Q_UNLIKELY(msgidlen <= 0)) { - m_data = nullptr; - return; + QByteArray translationpath = localeDir; + translationpath.append('/'); + translationpath.append(language); + translationpath.append('/'); + translationpath.append(name); + translationpath.append(".tr"); + QFile translationfile(QFile::decodeName(translationpath)); + if (!translationfile.open(QFile::ReadOnly)) { + return QByteArray(); } - - const int msgctxtlen = qstrlen(msgctxt); - if (msgctxtlen <= 0) { - m_data = (char*)msgid; - return; - } - - // for reference: - // https://github.com/autotools-mirror/gettext/blob/master/gnulib-local/lib/gettext.h - const int totallen = (msgctxtlen + 1 + msgidlen + 1); - m_data = static_cast(::malloc(totallen * sizeof(char))); - ::memcpy(m_data, msgctxt, msgctxtlen * sizeof(char)); - m_data[msgctxtlen] = '\004'; - ::memcpy(m_data + msgctxtlen + 1, msgid, msgidlen * sizeof(char)); - m_data[totallen - 1] = '\0'; - m_freedata = true; - - // qDebug() << Q_FUNC_INFO << m_data; -} - -KMsgCtx::~KMsgCtx() -{ - if (m_freedata) { - ::free(m_data); - } -} - -const char* const KMsgCtx::constData() const -{ - return m_data; + return translationfile.readAll(); } class KCatalogPrivate { public: - QByteArray language; - QByteArray name; - QByteArray localeDir; + KCatalogPrivate(); + ~KCatalogPrivate(); -#ifdef HAVE_LIBINTL - QByteArray systemLanguage; + QByteArray language; + QByteArray name; + QByteArray localeDir; - void setupGettextEnv(); - void resetSystemLanguage(); +#ifndef QT_NO_TRANSLATION + QTranslator* translator; #endif }; +KCatalogPrivate::KCatalogPrivate() + : translator(nullptr) +{ +} + +KCatalogPrivate::~KCatalogPrivate() +{ + delete translator; +} + QDebug operator<<(QDebug debug, const KCatalog &c) { - return debug << c.d->language << " " << c.d->name << " " << c.d->localeDir; + return debug << c.d->language << " " << c.d->name << " " << c.d->localeDir; } KCatalog::KCatalog(const QString &name, const QString &language) - : d( new KCatalogPrivate() ) + : d(new KCatalogPrivate()) { - setlocale(LC_ALL, ""); + d->language = QFile::encodeName(language); + d->name = QFile::encodeName(name); + d->localeDir = QFile::encodeName(catalogLocaleDir(name, language)); - // Find locale directory for this catalog. - QString localeDir = catalogLocaleDir(name, language); - - d->language = QFile::encodeName(language); - d->name = QFile::encodeName(name); - d->localeDir = QFile::encodeName(localeDir); - -#ifdef HAVE_LIBINTL - // Point Gettext to current language, recording system value for recovery. - d->systemLanguage = qgetenv("LANGUAGE"); - - // Always get translations in UTF-8, regardless of user's environment. - bind_textdomain_codeset(d->name.constData(), "UTF-8"); - - //kDebug() << << name << language << localeDir; - bindtextdomain(d->name.constData(), d->localeDir.constData()); +#ifndef QT_NO_TRANSLATION + d->translator = new QTranslator(); + d->translator->loadFromData(translationData(d->localeDir, d->language, d->name)); + // kDebug() << << name << language << localeDir; #endif } -KCatalog::KCatalog(const KCatalog & rhs) - : d( new KCatalogPrivate(*rhs.d) ) +KCatalog::KCatalog(const KCatalog &rhs) + : d(new KCatalogPrivate()) { + d->language = rhs.d->language; + d->name = rhs.d->name; + d->localeDir = rhs.d->localeDir; + +#ifndef QT_NO_TRANSLATION + d->translator = new QTranslator(); + d->translator->loadFromData(translationData(d->localeDir, d->language, d->name)); +#endif } KCatalog & KCatalog::operator=(const KCatalog & rhs) { - *d = *rhs.d; + d->language = rhs.d->language; + d->name = rhs.d->name; + d->localeDir = rhs.d->localeDir; - return *this; +#ifndef QT_NO_TRANSLATION + d->translator->loadFromData(translationData(d->localeDir, d->language, d->name)); +#endif + return *this; } KCatalog::~KCatalog() { - delete d; + delete d; } -QString KCatalog::catalogLocaleDir( const QString &name, - const QString &language ) +QString KCatalog::catalogLocaleDir(const QString &name, + const QString &language) { - QString relpath = QString::fromLatin1( "%1/LC_MESSAGES/%2.mo" ) - .arg( language ).arg( name ); - return KGlobal::dirs()->findResourceDir( "locale", relpath ); + QString relpath = QString::fromLatin1("%1/%2.tr").arg(language).arg(name); + return KGlobal::dirs()->findResourceDir("locale", relpath); } QString KCatalog::name() const { - return QFile::decodeName(d->name); + return QFile::decodeName(d->name); } QString KCatalog::language() const { - return QFile::decodeName(d->language); + return QFile::decodeName(d->language); } QString KCatalog::localeDir() const @@ -179,156 +135,91 @@ QString KCatalog::localeDir() const return QFile::decodeName(d->localeDir); } -#ifdef HAVE_LIBINTL -void KCatalogPrivate::setupGettextEnv() -{ - if (language != systemLanguage) { - // it is enough to change the string set there. - char langenv[langenvMaxlen]; - ::memset(langenv, 0, langenvMaxlen * sizeof(char)); - snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", language.constData()); - putenv(strdup(langenv)); - } -} - -void KCatalogPrivate::resetSystemLanguage () -{ - if (language != systemLanguage) { - char langenv[langenvMaxlen]; - ::memset(langenv, 0, langenvMaxlen * sizeof(char)); - snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", systemLanguage.constData()); - putenv(strdup(langenv)); - } -} -#endif - QString KCatalog::translate(const char * msgid) const { -#ifdef HAVE_LIBINTL - QMutexLocker locker(catalogLock()); - d->setupGettextEnv(); - const char *msgstr = dgettext(d->name, msgid); - d->resetSystemLanguage(); - return QString::fromUtf8(msgstr); +#ifndef QT_NO_TRANSLATION + return d->translator->translate(nullptr, msgid); #else - return QString::fromUtf8(msgid); + return QString::fromUtf8(msgid); #endif } QString KCatalog::translate(const char * msgctxt, const char * msgid) const { -#ifdef HAVE_LIBINTL - QMutexLocker locker(catalogLock()); - d->setupGettextEnv(); - const KMsgCtx msgwithctx(msgctxt, msgid); - const char *msgstr = dgettext(d->name, msgwithctx.constData()); - const bool msgstrict = (msgstr != msgwithctx.constData()); - d->resetSystemLanguage(); - return msgstrict ? QString::fromUtf8(msgstr) : QString::fromUtf8(msgid); +#ifndef QT_NO_TRANSLATION + return d->translator->translate(msgctxt, msgid); #else - Q_UNUSED(msgctxt); - return QString::fromUtf8(msgid); + Q_UNUSED(msgctxt); + return QString::fromUtf8(msgid); #endif } QString KCatalog::translate(const char * msgid, const char * msgid_plural, unsigned long n) const { -#ifdef HAVE_LIBINTL - QMutexLocker locker(catalogLock()); - d->setupGettextEnv(); - const char *msgstr = dngettext(d->name, msgid, msgid_plural, n); - d->resetSystemLanguage(); - return QString::fromUtf8(msgstr); +#ifndef QT_NO_TRANSLATION + return (n == 1 ? d->translator->translate(nullptr, msgid) : d->translator->translate(nullptr, msgid_plural)); #else - return (n == 1 ? QString::fromUtf8(msgid) : QString::fromUtf8(msgid_plural)); + return (n == 1 ? QString::fromUtf8(msgid) : QString::fromUtf8(msgid_plural)); #endif } QString KCatalog::translate(const char * msgctxt, const char * msgid, const char * msgid_plural, unsigned long n) const { -#ifdef HAVE_LIBINTL - QMutexLocker locker(catalogLock()); - d->setupGettextEnv(); - const KMsgCtx msgwithctx(msgctxt, msgid); - const char *msgstr = dngettext(d->name, msgwithctx.constData(), msgid_plural, n); - const bool msgstrict = (msgstr != msgwithctx.constData()); - const bool msgstrict2 = (msgstr != msgid_plural); - d->resetSystemLanguage(); - return msgstrict && msgstrict2 ? QString::fromUtf8(msgstr) : (n == 1 ? QString::fromUtf8(msgid) : QString::fromUtf8(msgid_plural)); +#ifndef QT_NO_TRANSLATION + return (n == 1 ? d->translator->translate(msgctxt, msgid) : d->translator->translate(msgctxt, msgid_plural)); #else - Q_UNUSED(msgctxt); - return (n == 1 ? QString::fromUtf8(msgid) : QString::fromUtf8(msgid_plural)); + Q_UNUSED(msgctxt); + return (n == 1 ? QString::fromUtf8(msgid) : QString::fromUtf8(msgid_plural)); #endif } QString KCatalog::translateStrict(const char * msgid) const { -#ifdef HAVE_LIBINTL - QMutexLocker locker(catalogLock()); - d->setupGettextEnv(); - const char *msgstr = dgettext(d->name, msgid); - d->resetSystemLanguage(); - return msgstr != msgid ? QString::fromUtf8(msgstr) : QString(); +#ifndef QT_NO_TRANSLATION + return d->translator->translateStrict(nullptr, msgid); #else - Q_UNUSED(msgid); - return QString(); + Q_UNUSED(msgid); + return QString(); #endif } QString KCatalog::translateStrict(const char * msgctxt, const char * msgid) const { -#ifdef HAVE_LIBINTL - QMutexLocker locker(catalogLock()); - d->setupGettextEnv(); - const KMsgCtx msgwithctx(msgctxt, msgid); - const char *msgstr = dgettext(d->name, msgwithctx.constData()); - const bool msgstrict = (msgstr != msgwithctx.constData()); - d->resetSystemLanguage(); - return msgstrict ? QString::fromUtf8(msgstr) : QString(); +#ifndef QT_NO_TRANSLATION + return d->translator->translateStrict(msgctxt, msgid); #else - Q_UNUSED(msgctxt); - Q_UNUSED(msgid); - return QString(); + Q_UNUSED(msgctxt); + Q_UNUSED(msgid); + return QString(); #endif } QString KCatalog::translateStrict(const char * msgid, const char * msgid_plural, unsigned long n) const { -#ifdef HAVE_LIBINTL - QMutexLocker locker(catalogLock()); - d->setupGettextEnv(); - const char *msgstr = dngettext(d->name, msgid, msgid_plural, n); - d->resetSystemLanguage(); - return msgstr != msgid && msgstr != msgid_plural ? QString::fromUtf8(msgstr) : QString(); +#ifndef QT_NO_TRANSLATION + return (n == 1 ? d->translator->translateStrict(nullptr, msgid) : d->translator->translateStrict(nullptr, msgid_plural)); #else - Q_UNUSED(msgid); - Q_UNUSED(msgid_plural); - Q_UNUSED(n); - return QString(); + Q_UNUSED(msgid); + Q_UNUSED(msgid_plural); + Q_UNUSED(n); + return QString(); #endif } QString KCatalog::translateStrict(const char * msgctxt, const char * msgid, const char * msgid_plural, unsigned long n) const { -#ifdef HAVE_LIBINTL - QMutexLocker locker(catalogLock()); - d->setupGettextEnv(); - const KMsgCtx msgwithctx(msgctxt, msgid); - const char *msgstr = dngettext(d->name, msgwithctx.constData(), msgid_plural, n); - const bool msgstrict = (msgstr != msgwithctx.constData()); - const bool msgstrict2 = (msgstr != msgid_plural); - d->resetSystemLanguage(); - return msgstrict && msgstrict2 ? QString::fromUtf8(msgstr) : QString(); +#ifndef QT_NO_TRANSLATION + return (n == 1 ? d->translator->translateStrict(msgctxt, msgid) : d->translator->translateStrict(msgctxt, msgid_plural)); #else - Q_UNUSED(msgctxt); - Q_UNUSED(msgid); - Q_UNUSED(msgid_plural); - Q_UNUSED(n); - return QString(); + Q_UNUSED(msgctxt); + Q_UNUSED(msgid); + Q_UNUSED(msgid_plural); + Q_UNUSED(n); + return QString(); #endif }