mirror of
https://bitbucket.org/smil3y/katie.git
synced 2025-02-23 10:22:55 +00:00
use custom format for translations
the code for translating strings in kdelibs (see kdelibs/kdecore/localization/kcatalog.cpp) has finally made me roll my own - locking global mutex, saving and restoring environment variables on every string translation is not very good, is it? Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
ab43571cc1
commit
d0742df56c
25 changed files with 717 additions and 107 deletions
|
@ -120,7 +120,7 @@ set(KATIE_LIBRARIES_PATH "${CMAKE_INSTALL_FULL_LIBDIR}" CACHE PATH "Libraries in
|
|||
set(KATIE_BINARIES_PATH "${CMAKE_INSTALL_FULL_BINDIR}" CACHE PATH "Binaries installation path")
|
||||
set(KATIE_PLUGINS_PATH "${KATIE_LIBRARIES_PATH}/katie/plugins" CACHE PATH "Plugins installation path")
|
||||
set(KATIE_IMPORTS_PATH "${KATIE_LIBRARIES_PATH}/katie/imports" CACHE PATH "Declarative imports installation path")
|
||||
set(KATIE_TRANSLATIONS_PATH "${CMAKE_INSTALL_FULL_LOCALEDIR}" CACHE PATH "Translations installation path")
|
||||
set(KATIE_TRANSLATIONS_PATH "${CMAKE_INSTALL_FULL_DATADIR}/translations" CACHE PATH "Translations installation path")
|
||||
set(KATIE_CMAKE_PATH "${KATIE_LIBRARIES_PATH}/cmake/Katie" CACHE PATH "CMake aware modules installation path")
|
||||
set(KATIE_LDCONF_PATH "${CMAKE_INSTALL_FULL_SYSCONFDIR}/ld.so.conf.d" CACHE PATH "Run-time linker/loader configs installation path")
|
||||
set(KATIE_PROFILE_PATH "${CMAKE_INSTALL_FULL_SYSCONFDIR}/profile.d" CACHE PATH "Shell profile scripts installation path")
|
||||
|
@ -147,8 +147,8 @@ add_feature_info(dbus WITH_DBUS "build D-Bus support")
|
|||
option(WITH_FONTCONFIG "Build Fontconfig support" ON)
|
||||
add_feature_info(fontconfig WITH_FONTCONFIG "build Fontconfig support")
|
||||
|
||||
option(WITH_INTL "Build Intl support" ON)
|
||||
add_feature_info(intl WITH_INTL "build Intl support")
|
||||
option(WITH_GETTEXTPO "Build Gettext support" ON)
|
||||
add_feature_info(gettextpo WITH_GETTEXTPO "build Gettext support")
|
||||
|
||||
option(WITH_EXECINFO "Build ExecInfo support" OFF)
|
||||
add_feature_info(execinfo WITH_EXECINFO "build ExecInfo support")
|
||||
|
@ -256,10 +256,10 @@ set_package_properties(DBus PROPERTIES
|
|||
TYPE RECOMMENDED
|
||||
)
|
||||
|
||||
find_package(Intl)
|
||||
set_package_properties(Intl PROPERTIES
|
||||
find_package(GettextPO)
|
||||
set_package_properties(GettextPO PROPERTIES
|
||||
PURPOSE "Required for translations support"
|
||||
DESCRIPTION "GNU gettext runtime library"
|
||||
DESCRIPTION "GNU gettext PO files processsor"
|
||||
URL "https://www.gnu.org/software/gettext/gettext.html"
|
||||
TYPE RECOMMENDED
|
||||
)
|
||||
|
@ -400,8 +400,10 @@ if(NOT WITH_CUPS OR NOT CUPS_FOUND)
|
|||
katie_config(QT_NO_CUPS)
|
||||
endif()
|
||||
|
||||
if(NOT WITH_INTL OR NOT INTL_FOUND)
|
||||
if(NOT WITH_GETTEXTPO OR NOT GETTEXTPO_FOUND)
|
||||
katie_config(QT_NO_TRANSLATION)
|
||||
else()
|
||||
set(KATIE_TOOLS "${KATIE_TOOLS} trc")
|
||||
endif()
|
||||
|
||||
if(NOT WITH_EXECINFO OR NOT EXECINFO_FOUND)
|
||||
|
@ -464,7 +466,7 @@ add_subdirectory(src/uitools)
|
|||
|
||||
add_subdirectory(src/tools)
|
||||
|
||||
if(WITH_INTL AND INTL_FOUND)
|
||||
if(WITH_GETTEXTPO AND GETTEXTPO_FOUND)
|
||||
add_subdirectory(translations)
|
||||
endif()
|
||||
|
||||
|
|
1
README
1
README
|
@ -49,6 +49,7 @@ There are several things you should be aware before considering Katie:
|
|||
|
||||
- some additions have been made:
|
||||
- custom image format
|
||||
- custom translations format
|
||||
- custom hash algorithm
|
||||
- JSON document handler
|
||||
- standard directories handler
|
||||
|
|
31
cmake/modules/FindGettextPO.cmake
Normal file
31
cmake/modules/FindGettextPO.cmake
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Try to find gettextpo, once done this will define:
|
||||
#
|
||||
# GETTEXTPO_FOUND - system has gettextpo
|
||||
# GETTEXTPO_INCLUDES - the gettextpo include directory
|
||||
# GETTEXTPO_LIBRARIES - the libraries needed to use gettextpo
|
||||
#
|
||||
# Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
# gettextpo does not provide pkg-config files
|
||||
|
||||
find_path(GETTEXTPO_INCLUDES
|
||||
NAMES gettext-po.h
|
||||
HINTS $ENV{GETTEXTPODIR}/include
|
||||
)
|
||||
|
||||
find_library(GETTEXTPO_LIBRARIES
|
||||
NAMES gettextpo
|
||||
HINTS $ENV{GETTEXTPODIR}/lib
|
||||
)
|
||||
|
||||
find_package_handle_standard_args(GettextPO
|
||||
VERSION_VAR PC_GETTEXTPO_VERSION
|
||||
REQUIRED_VARS GETTEXTPO_LIBRARIES GETTEXTPO_INCLUDES
|
||||
)
|
||||
|
||||
mark_as_advanced(GETTEXTPO_INCLUDES GETTEXTPO_LIBRARIES)
|
|
@ -1,50 +0,0 @@
|
|||
# Try to find intl, once done this will define:
|
||||
#
|
||||
# INTL_FOUND - system has intl
|
||||
# INTL_INCLUDES - the intl include directory
|
||||
# INTL_LIBRARIES - the libraries needed to use intl
|
||||
# INTL_MSGFMT - the msgfmt binary
|
||||
#
|
||||
# Copyright (C) 2016 Ivailo Monev <xakepa10@gmail.com>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
|
||||
# intl does not provide pkg-config files
|
||||
|
||||
include(CMakePushCheckState)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
set(INTL_NAMES c intl)
|
||||
|
||||
find_path(INTL_INCLUDES
|
||||
NAMES libintl.h
|
||||
HINTS $ENV{INTLDIR}/include
|
||||
)
|
||||
|
||||
set(INTL_LIBRARIES)
|
||||
foreach(name ${INTL_NAMES})
|
||||
if(NOT INTL_LIBRARIES)
|
||||
unset(HAVE_bind_textdomain_codeset CACHE)
|
||||
cmake_reset_check_state()
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${name})
|
||||
katie_check_defined(bind_textdomain_codeset "libintl.h")
|
||||
cmake_reset_check_state()
|
||||
if(HAVE_bind_textdomain_codeset)
|
||||
find_library(INTL_LIBRARIES
|
||||
NAMES ${name}
|
||||
HINTS $ENV{INTLDIR}/lib
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
find_program(INTL_MSGFMT
|
||||
NAMES msgfmt
|
||||
HINTS $ENV{INTLDIR}/bin
|
||||
)
|
||||
|
||||
find_package_handle_standard_args(Intl
|
||||
REQUIRED_VARS INTL_LIBRARIES INTL_INCLUDES INTL_MSGFMT
|
||||
)
|
||||
|
||||
mark_as_advanced(INTL_INCLUDES INTL_LIBRARIES INTL_MSGFMT)
|
|
@ -5,7 +5,7 @@ Homepage: https://osdn.net/projects/kde/
|
|||
Vcs-Git: git://git.osdn.net/gitroot/kde/Katie.git
|
||||
Vcs-browser: https://osdn.net/projects/kde/scm/git/Katie/tree
|
||||
Standards-Version: 4.12.0
|
||||
Build-Depends: debhelper (>= 9~), libdeflate-dev,
|
||||
Build-Depends: debhelper (>= 9~), libdeflate-dev, libgettextpo-dev,
|
||||
libc6-dev, libjansson-dev, libpng-dev, libcups2-dev, libfreetype6-dev,
|
||||
libfontconfig1-dev, libdbus-1-dev, libicu-dev, cmake, git,
|
||||
xserver-xorg-dev, libxinerama-dev, libxrandr-dev, libxrender-dev,
|
||||
|
|
|
@ -16,6 +16,7 @@ WRKSRC = ${WRKDIR}/katie.git
|
|||
USES = compiler:c++11-lang pkgconfig cmake xorg desktop-file-utils
|
||||
USE_XORG = x11 xinerama xrandr xrender xfixes xcursor xext sm ice
|
||||
USE_LDCONFIG = yes
|
||||
USE_GETTEXT_TOOLS = build run
|
||||
RUN_DEPENDS = xdg-open:devel/xdg-utils \
|
||||
${LOCALBASE}/share/fonts/freefont-ttf/FreeSans.ttf:x11-fonts/freefont-ttf
|
||||
LIB_DEPENDS = libdeflate.so:archivers/libdeflate libicuuc.so:devel/icu \
|
||||
|
@ -28,9 +29,9 @@ CMAKE_ARGS = -DKATIE_TOOLS_SUFFIX="-katie" -Wno-dev
|
|||
OPTIONS_DEFINE = NLS
|
||||
OPTIONS_SUB = yes
|
||||
NLS_DESC = Build translator and translations
|
||||
NLS_USES = gettext
|
||||
NLS_CMAKE_ON = -DWITH_INTL=TRUE
|
||||
NLS_CMAKE_OFF = -DWITH_INTL=FALSE
|
||||
NLS_USES = gettext-tools
|
||||
NLS_CMAKE_ON = -DWITH_GETTEXTPO=TRUE
|
||||
NLS_CMAKE_OFF = -DWITH_GETTEXTPO=FALSE
|
||||
|
||||
do-extract:
|
||||
@rm -vrf ${WRKSRC}
|
||||
|
|
|
@ -319,14 +319,6 @@ foreach(lib dl rt)
|
|||
endif()
|
||||
endforeach()
|
||||
|
||||
if(WITH_INTL AND INTL_FOUND)
|
||||
set(EXTRA_CORE_LIBS
|
||||
${EXTRA_CORE_LIBS}
|
||||
${INTL_LIBRARIES}
|
||||
)
|
||||
include_directories(${INTL_INCLUDES})
|
||||
endif()
|
||||
|
||||
if(WITH_EXECINFO AND EXECINFO_FOUND)
|
||||
set(EXTRA_CORE_LIBS
|
||||
${EXTRA_CORE_LIBS}
|
||||
|
|
|
@ -24,22 +24,34 @@
|
|||
#ifndef QT_NO_TRANSLATION
|
||||
|
||||
#include "qcoreapplication.h"
|
||||
|
||||
#include <libintl.h>
|
||||
#include "qlibraryinfo.h"
|
||||
#include "qlocale.h"
|
||||
#include "qdir.h"
|
||||
#include "qtextcodec.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTranslatorPrivate
|
||||
{
|
||||
public:
|
||||
QTranslatorPrivate() { }
|
||||
QTranslatorPrivate();
|
||||
|
||||
QByteArray domain;
|
||||
mutable QByteArray data;
|
||||
mutable QTextConverter converter;
|
||||
quint32 offset;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QTranslatorPrivate);
|
||||
};
|
||||
|
||||
QTranslatorPrivate::QTranslatorPrivate()
|
||||
: offset(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\class QTranslator
|
||||
|
||||
|
@ -113,7 +125,6 @@ QTranslator::QTranslator()
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Destroys the object and frees any allocated resources.
|
||||
*/
|
||||
|
@ -126,58 +137,172 @@ QTranslator::~QTranslator()
|
|||
}
|
||||
|
||||
/*!
|
||||
|
||||
Loads \a filename (with ".mo" as suffix), which is file name relative
|
||||
to the translations installation directory. Returns true if the
|
||||
translation is successfully loaded; otherwise returns false.
|
||||
Loads translation for \a domain and \a locale, \a domain being
|
||||
filename relative to the translations installation directory
|
||||
without the suffix and \a locale being either empty or locale of
|
||||
choice; if empty the system locale will be used. Returns true if
|
||||
the translation is successfully loaded; otherwise returns false.
|
||||
|
||||
The previous contents of this translator object are discarded.
|
||||
|
||||
\sa QLibraryInfo
|
||||
*/
|
||||
bool QTranslator::load(const QString &domain)
|
||||
bool QTranslator::load(const QString &domain, const QString &locale)
|
||||
{
|
||||
Q_D(QTranslator);
|
||||
d->data.clear();
|
||||
d->converter = QTextConverter();
|
||||
d->offset = 0;
|
||||
if (domain.isEmpty()) {
|
||||
qWarning("QTranslator::load: Domain is empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
QString translationfilepath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
|
||||
translationfilepath.append(QDir::separator());
|
||||
if (locale.isEmpty()) {
|
||||
translationfilepath.append(QLocale::system().name());
|
||||
} else {
|
||||
translationfilepath.append(locale);
|
||||
}
|
||||
translationfilepath.append(QDir::separator());
|
||||
translationfilepath.append(domain);
|
||||
translationfilepath.append(QLatin1String(".tr"));
|
||||
// qDebug() << Q_FUNC_INFO << translationfilepath;
|
||||
|
||||
QFile translationfile(translationfilepath);
|
||||
if (!translationfile.open(QFile::ReadOnly)) {
|
||||
qWarning("QTranslator::load: %s", qPrintable(translationfile.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return loadFromData(translationfile.readAll());
|
||||
}
|
||||
|
||||
/*!
|
||||
Loads translation from \a data. Returns true if the translation
|
||||
is successfully loaded; otherwise returns false.
|
||||
|
||||
The previous contents of this translator object are discarded.
|
||||
|
||||
\sa QLibraryInfo
|
||||
*/
|
||||
bool QTranslator::loadFromData(const QByteArray &data)
|
||||
{
|
||||
Q_D(QTranslator);
|
||||
d->domain = domain.toLatin1();
|
||||
bind_textdomain_codeset(d->domain.constData(), "UTF-8");
|
||||
d->data = data;
|
||||
d->converter = QTextConverter();
|
||||
d->offset = 0;
|
||||
|
||||
if (data.isEmpty()) {
|
||||
qWarning("QTranslator::load: Empty data");
|
||||
d->data.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
QDataStream trheaderstream(&d->data, QIODevice::ReadOnly);
|
||||
QByteArray trmagic;
|
||||
QByteArray trcodec;
|
||||
trheaderstream >> trmagic;
|
||||
trheaderstream >> trcodec;
|
||||
|
||||
if (trmagic != "KATIE_TRANSLATION") {
|
||||
qWarning("QTranslator::load: Invalid magic");
|
||||
d->data.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
d->converter = QTextConverter(trcodec);
|
||||
d->offset = trheaderstream.device()->pos();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the translation for the key (\a context, \a sourceText).
|
||||
The text will be translated depending on the system locale.
|
||||
The text will be translated depending on either the locale specified
|
||||
when the translation was loaded or the system locale.
|
||||
|
||||
\sa load()
|
||||
*/
|
||||
QString QTranslator::translate(const char *context, const char *sourceText) const
|
||||
{
|
||||
Q_D(const QTranslator);
|
||||
if (context) {
|
||||
// for reference:
|
||||
// https://github.com/autotools-mirror/gettext/blob/master/gnulib-local/lib/gettext.h
|
||||
QByteArray msgwithctx(context);
|
||||
msgwithctx.append('\004');
|
||||
msgwithctx.append(sourceText);
|
||||
const char* result = dgettext(d->domain.constData(), msgwithctx.constData());
|
||||
if (result == msgwithctx.constData()) {
|
||||
QDataStream trdatastream(&d->data, QIODevice::ReadOnly);
|
||||
QIODevice* trdatadevice = trdatastream.device();
|
||||
trdatadevice->seek(d->offset);
|
||||
while (!trdatadevice->atEnd()) {
|
||||
QByteArray trmsgctxt;
|
||||
QByteArray trmsgid;
|
||||
QByteArray trmsgstr;
|
||||
QByteArray trmsgid_plural;
|
||||
QByteArray trmsgstr_plural;
|
||||
trdatastream >> trmsgctxt;
|
||||
trdatastream >> trmsgid;
|
||||
trdatastream >> trmsgstr;
|
||||
trdatastream >> trmsgid_plural;
|
||||
trdatastream >> trmsgstr_plural;
|
||||
|
||||
// this search method assumes plurals and regular messages are unique strings
|
||||
if ((!context || trmsgctxt == context) && trmsgid_plural == sourceText) {
|
||||
d->converter.reset();
|
||||
return d->converter.toUnicode(trmsgstr_plural.constData(), trmsgstr_plural.size());
|
||||
}
|
||||
|
||||
if ((!context || trmsgctxt == context) && trmsgid == sourceText) {
|
||||
d->converter.reset();
|
||||
return d->converter.toUnicode(trmsgstr.constData(), trmsgstr.size());
|
||||
}
|
||||
}
|
||||
return QString::fromUtf8(sourceText);
|
||||
}
|
||||
return QString::fromUtf8(result);
|
||||
|
||||
/*!
|
||||
Returns the translation for the key (\a context, \a sourceText).
|
||||
The text will be translated depending on either the locale specified
|
||||
when the translation was loaded or the system locale.
|
||||
|
||||
If no translation is found empty string is returned.
|
||||
|
||||
\sa load()
|
||||
*/
|
||||
QString QTranslator::translateStrict(const char *context, const char *sourceText) const
|
||||
{
|
||||
Q_D(const QTranslator);
|
||||
QDataStream trdatastream(&d->data, QIODevice::ReadOnly);
|
||||
QIODevice* trdatadevice = trdatastream.device();
|
||||
trdatadevice->seek(d->offset);
|
||||
while (!trdatadevice->atEnd()) {
|
||||
QByteArray trmsgctxt;
|
||||
QByteArray trmsgid;
|
||||
QByteArray trmsgstr;
|
||||
QByteArray trmsgid_plural;
|
||||
QByteArray trmsgstr_plural;
|
||||
trdatastream >> trmsgctxt;
|
||||
trdatastream >> trmsgid;
|
||||
trdatastream >> trmsgstr;
|
||||
trdatastream >> trmsgid_plural;
|
||||
trdatastream >> trmsgstr_plural;
|
||||
|
||||
if ((!context || trmsgctxt == context) && trmsgid_plural == sourceText) {
|
||||
d->converter.reset();
|
||||
return d->converter.toUnicode(trmsgstr_plural.constData(), trmsgstr_plural.size());
|
||||
}
|
||||
return QString::fromUtf8(dgettext(d->domain.constData(), sourceText));
|
||||
|
||||
if ((!context || trmsgctxt == context) && trmsgid == sourceText) {
|
||||
d->converter.reset();
|
||||
return d->converter.toUnicode(trmsgstr.constData(), trmsgstr.size());
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if this translator is empty, otherwise returns false.
|
||||
This function works with stripped and unstripped translation files.
|
||||
*/
|
||||
bool QTranslator::isEmpty() const
|
||||
{
|
||||
Q_D(const QTranslator);
|
||||
return d->domain.isEmpty();
|
||||
return d->data.isEmpty();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -37,10 +37,12 @@ public:
|
|||
virtual ~QTranslator();
|
||||
|
||||
virtual QString translate(const char *context, const char *sourceText) const;
|
||||
virtual QString translateStrict(const char *context, const char *sourceText) const;
|
||||
|
||||
virtual bool isEmpty() const;
|
||||
|
||||
bool load(const QString &domain);
|
||||
bool load(const QString &domain, const QString &locale = QString());
|
||||
bool loadFromData(const QByteArray &data);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QTranslator)
|
||||
|
|
|
@ -14,5 +14,8 @@ if(WITH_DBUS AND DBUS_FOUND)
|
|||
add_subdirectory(qdbus)
|
||||
add_subdirectory(qdbusviewer)
|
||||
endif()
|
||||
if(WITH_GETTEXTPO AND GETTEXTPO_FOUND)
|
||||
add_subdirectory(trc)
|
||||
endif()
|
||||
add_subdirectory(qscript)
|
||||
add_subdirectory(qtconfig)
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "MOC 1"
|
||||
.TH MOC 1 "2022-03-04" "Katie 4.12.0" "Katie Manual"
|
||||
.TH MOC 1 "2022-06-15" "Katie 4.12.0" "Katie Manual"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "QDBUS 1"
|
||||
.TH QDBUS 1 "2022-03-04" "Katie 4.12.0" "Katie Manual"
|
||||
.TH QDBUS 1 "2022-06-15" "Katie 4.12.0" "Katie Manual"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "QDBUSCPP2XML 1"
|
||||
.TH QDBUSCPP2XML 1 "2022-03-04" "Katie 4.12.0" "Katie Manual"
|
||||
.TH QDBUSCPP2XML 1 "2022-06-15" "Katie 4.12.0" "Katie Manual"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "QDBUSXML2CPP 1"
|
||||
.TH QDBUSXML2CPP 1 "2022-03-04" "Katie 4.12.0" "Katie Manual"
|
||||
.TH QDBUSXML2CPP 1 "2022-06-15" "Katie 4.12.0" "Katie Manual"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "QSCRIPT 1"
|
||||
.TH QSCRIPT 1 "2022-03-04" "Katie 4.12.0" "Katie Manual"
|
||||
.TH QSCRIPT 1 "2022-06-15" "Katie 4.12.0" "Katie Manual"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
|
|
40
src/tools/trc/CMakeLists.txt
Normal file
40
src/tools/trc/CMakeLists.txt
Normal file
|
@ -0,0 +1,40 @@
|
|||
set(EXTRA_TRC_LIBS
|
||||
KtCore
|
||||
${GETTEXTPO_LIBRARIES}
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_BINARY_DIR}/include
|
||||
${CMAKE_BINARY_DIR}/privateinclude
|
||||
${CMAKE_BINARY_DIR}/include/QtCore
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${GETTEXTPO_INCLUDES}
|
||||
)
|
||||
|
||||
set(TRC_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/trcmain.cpp
|
||||
)
|
||||
|
||||
katie_setup_target(trc ${TRC_SOURCES})
|
||||
|
||||
add_executable(trc ${trc_SOURCES})
|
||||
target_link_libraries(trc ${EXTRA_TRC_LIBS})
|
||||
|
||||
set_target_properties(trc PROPERTIES
|
||||
EXPORT_NAME trc
|
||||
OUTPUT_NAME trc${KATIE_TOOLS_SUFFIX}
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS trc
|
||||
EXPORT KatieTargets
|
||||
RUNTIME DESTINATION ${KATIE_BINARIES_PATH}
|
||||
COMPONENT Tools
|
||||
)
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_SOURCE_DIR}/trc.1
|
||||
DESTINATION ${KATIE_MAN_PATH}/man1
|
||||
RENAME trc${KATIE_TOOLS_SUFFIX}.1
|
||||
COMPONENT Doc
|
||||
)
|
109
src/tools/trc/trc.1
Normal file
109
src/tools/trc/trc.1
Normal file
|
@ -0,0 +1,109 @@
|
|||
.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40)
|
||||
.\"
|
||||
.\" Standard preamble:
|
||||
.\" ========================================================================
|
||||
.de Sp \" Vertical space (when we can't use .PP)
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
.de Vb \" Begin verbatim text
|
||||
.ft CW
|
||||
.nf
|
||||
.ne \\$1
|
||||
..
|
||||
.de Ve \" End verbatim text
|
||||
.ft R
|
||||
.fi
|
||||
..
|
||||
.\" Set up some character translations and predefined strings. \*(-- will
|
||||
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
||||
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
||||
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
||||
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
||||
.\" nothing in troff, for use with C<>.
|
||||
.tr \(*W-
|
||||
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
||||
.ie n \{\
|
||||
. ds -- \(*W-
|
||||
. ds PI pi
|
||||
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
||||
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
||||
. ds L" ""
|
||||
. ds R" ""
|
||||
. ds C` ""
|
||||
. ds C' ""
|
||||
'br\}
|
||||
.el\{\
|
||||
. ds -- \|\(em\|
|
||||
. ds PI \(*p
|
||||
. ds L" ``
|
||||
. ds R" ''
|
||||
. ds C`
|
||||
. ds C'
|
||||
'br\}
|
||||
.\"
|
||||
.\" Escape single quotes in literal strings from groff's Unicode transform.
|
||||
.ie \n(.g .ds Aq \(aq
|
||||
.el .ds Aq '
|
||||
.\"
|
||||
.\" If the F register is >0, we'll generate index entries on stderr for
|
||||
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
||||
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
||||
.\" output yourself in some meaningful fashion.
|
||||
.\"
|
||||
.\" Avoid warning from groff about undefined register 'F'.
|
||||
.de IX
|
||||
..
|
||||
.nr rF 0
|
||||
.if \n(.g .if rF .nr rF 1
|
||||
.if (\n(rF:(\n(.g==0)) \{\
|
||||
. if \nF \{\
|
||||
. de IX
|
||||
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||
..
|
||||
. if !\nF==2 \{\
|
||||
. nr % 0
|
||||
. nr F 2
|
||||
. \}
|
||||
. \}
|
||||
.\}
|
||||
.rr rF
|
||||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "TRC 1"
|
||||
.TH TRC 1 "2022-11-01" "Katie 4.12.0" "Katie Manual"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
.nh
|
||||
.SH "NAME"
|
||||
trc \- Katie Translation Compiler
|
||||
.SH "SYNOPSIS"
|
||||
.IX Header "SYNOPSIS"
|
||||
trc [options] <translation\-file>
|
||||
.SH "DESCRIPTION"
|
||||
.IX Header "DESCRIPTION"
|
||||
trc reads a user interface definition (.po) file and creates corresponding
|
||||
\&.tr file.
|
||||
.SH "OPTIONS"
|
||||
.IX Header "OPTIONS"
|
||||
.Vb 3
|
||||
\& \-h
|
||||
\& \-help
|
||||
\& Display this help and exit.
|
||||
\&
|
||||
\& \-v
|
||||
\& \-version
|
||||
\& Display version.
|
||||
\&
|
||||
\& \-o <file>
|
||||
\& Place the output into <file>.
|
||||
.Ve
|
||||
.SH "EXIT STATUS"
|
||||
.IX Header "EXIT STATUS"
|
||||
trc returns 0 on success and other on unexcepted failure.
|
||||
.SH "AUTHORS"
|
||||
.IX Header "AUTHORS"
|
||||
Copyright (C) 2022 Ivailo Monev
|
||||
.PP
|
||||
Licensed through \s-1GNU\s0 Lesser General Public License.
|
35
src/tools/trc/trc.pod
Normal file
35
src/tools/trc/trc.pod
Normal file
|
@ -0,0 +1,35 @@
|
|||
=head1 NAME
|
||||
|
||||
trc - Katie Translation Compiler
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
trc [options] <translation-file>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
trc reads a user interface definition (.po) file and creates corresponding
|
||||
.tr file.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
-h
|
||||
-help
|
||||
Display this help and exit.
|
||||
|
||||
-v
|
||||
-version
|
||||
Display version.
|
||||
|
||||
-o <file>
|
||||
Place the output into <file>.
|
||||
|
||||
=head1 EXIT STATUS
|
||||
|
||||
trc returns 0 on success and other on unexcepted failure.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Copyright (C) 2022 Ivailo Monev
|
||||
|
||||
Licensed through GNU Lesser General Public License.
|
222
src/tools/trc/trcmain.cpp
Normal file
222
src/tools/trc/trcmain.cpp
Normal file
|
@ -0,0 +1,222 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 Ivailo Monev
|
||||
**
|
||||
** This file is part of the tools applications of the Katie Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextCodec>
|
||||
#include <QDebug>
|
||||
|
||||
#include <gettext-po.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static void gettext_xerror(int severity,
|
||||
po_message_t message,
|
||||
const char *filename, size_t lineno, size_t column,
|
||||
int multiline_p, const char *message_text)
|
||||
{
|
||||
switch (severity) {
|
||||
case PO_SEVERITY_WARNING: {
|
||||
qWarning("%s", message_text);
|
||||
break;
|
||||
}
|
||||
case PO_SEVERITY_ERROR: {
|
||||
qCritical("%s", message_text);
|
||||
break;
|
||||
}
|
||||
case PO_SEVERITY_FATAL_ERROR: {
|
||||
qFatal("%s", message_text);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gettext_xerror2(int severity,
|
||||
po_message_t message1,
|
||||
const char *filename1, size_t lineno1, size_t column1,
|
||||
int multiline_p1, const char *message_text1,
|
||||
po_message_t message2,
|
||||
const char *filename2, size_t lineno2, size_t column2,
|
||||
int multiline_p2, const char *message_text2)
|
||||
{
|
||||
switch (severity) {
|
||||
case PO_SEVERITY_WARNING: {
|
||||
qWarning("%s, %s", message_text1, message_text2);
|
||||
break;
|
||||
}
|
||||
case PO_SEVERITY_ERROR: {
|
||||
qCritical("%s, %s", message_text1, message_text2);
|
||||
break;
|
||||
}
|
||||
case PO_SEVERITY_FATAL_ERROR: {
|
||||
qFatal("%s, %s", message_text1, message_text2);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct po_xerror_handler gettext_handler
|
||||
{
|
||||
gettext_xerror,
|
||||
gettext_xerror2
|
||||
};
|
||||
|
||||
void showHelp()
|
||||
{
|
||||
fprintf(stderr, "Usage:\n"
|
||||
" trc [options] <translation-file>\n\n"
|
||||
"Options:\n"
|
||||
" -h\n"
|
||||
" -help\n"
|
||||
" Display this help and exit.\n\n"
|
||||
" -v\n"
|
||||
" -version\n"
|
||||
" Display version.\n\n"
|
||||
" -o <file>\n"
|
||||
" Place the output into <file>.\n");
|
||||
}
|
||||
|
||||
int runTrc(int argc, char *argv[])
|
||||
{
|
||||
QByteArray inputfilepath;
|
||||
QString outputfilepath;
|
||||
|
||||
int arg = 1;
|
||||
while (arg < argc) {
|
||||
QString opt = QString::fromLocal8Bit(argv[arg]);
|
||||
if (opt == QLatin1String("-h") || opt == QLatin1String("-help")) {
|
||||
showHelp();
|
||||
return 0;
|
||||
} else if (opt == QLatin1String("-v") || opt == QLatin1String("-version")) {
|
||||
fprintf(stderr, "Katie Translation Compiler version %s\n", QT_VERSION_STR);
|
||||
return 0;
|
||||
} else if (opt == QLatin1String("-o") || opt == QLatin1String("-output")) {
|
||||
++arg;
|
||||
if (!argv[arg]) {
|
||||
showHelp();
|
||||
return 1;
|
||||
}
|
||||
outputfilepath = QFile::decodeName(argv[arg]);
|
||||
} else if (inputfilepath.isEmpty()) {
|
||||
inputfilepath = argv[arg];
|
||||
} else {
|
||||
showHelp();
|
||||
return 1;
|
||||
}
|
||||
|
||||
++arg;
|
||||
}
|
||||
|
||||
if (outputfilepath.isEmpty()) {
|
||||
outputfilepath = inputfilepath;
|
||||
if (outputfilepath.endsWith(QLatin1String(".po"))) {
|
||||
outputfilepath.chop(3);
|
||||
}
|
||||
outputfilepath.append(QLatin1String(".tr"));
|
||||
}
|
||||
|
||||
if (inputfilepath.isEmpty()) {
|
||||
showHelp();
|
||||
return 1;
|
||||
}
|
||||
|
||||
QFile outputfile(outputfilepath);
|
||||
if (!outputfile.open(QFile::WriteOnly)) {
|
||||
fprintf(stderr, "trc: Coult not open output %s\n", qPrintable(outputfilepath));
|
||||
return 1;
|
||||
}
|
||||
|
||||
po_file_t gettext_file = po_file_read(
|
||||
inputfilepath.constData(),
|
||||
&gettext_handler
|
||||
);
|
||||
if (gettext_file == NULL) {
|
||||
fprintf(stderr, "trc: Coult not open input %s\n", inputfilepath.constData());
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* gettext_domain_header = po_file_domain_header(gettext_file, NULL);
|
||||
|
||||
QByteArray trdata;
|
||||
QDataStream trdatastream(&trdata, QIODevice::WriteOnly);
|
||||
po_message_iterator_t gettext_iterator = po_message_iterator(gettext_file, NULL);
|
||||
po_message_t gettext_message = po_next_message(gettext_iterator);
|
||||
while (gettext_message != NULL) {
|
||||
if (po_message_is_obsolete(gettext_message) || po_message_is_fuzzy(gettext_message)) {
|
||||
gettext_message = po_next_message(gettext_iterator);
|
||||
continue;
|
||||
}
|
||||
|
||||
const QByteArray po_msgctxt = po_message_msgctxt(gettext_message);
|
||||
const QByteArray po_msgid = po_message_msgid(gettext_message);
|
||||
const QByteArray po_msgstr = po_message_msgstr(gettext_message);
|
||||
if (po_msgstr == gettext_domain_header) {
|
||||
gettext_message = po_next_message(gettext_iterator);
|
||||
continue;
|
||||
}
|
||||
const QByteArray po_msgid_plural = po_message_msgid_plural(gettext_message);
|
||||
const QByteArray po_msgstr_plural = po_message_msgstr_plural(gettext_message, 1);
|
||||
|
||||
trdatastream << po_msgctxt;
|
||||
trdatastream << po_msgid;
|
||||
trdatastream << po_msgstr;
|
||||
trdatastream << po_msgid_plural;
|
||||
trdatastream << po_msgstr_plural;
|
||||
|
||||
gettext_message = po_next_message(gettext_iterator);
|
||||
}
|
||||
po_message_iterator_free(gettext_iterator);
|
||||
|
||||
QByteArray trheaderdata;
|
||||
QDataStream trheaderstream(&trheaderdata, QIODevice::WriteOnly);
|
||||
trheaderstream << QByteArray("KATIE_TRANSLATION");
|
||||
// both Katie and Katana assume that the strings are UTF-8
|
||||
trheaderstream << QByteArray("UTF-8");
|
||||
|
||||
if (outputfile.write(trheaderdata.constData(), trheaderdata.size()) != trheaderdata.size()) {
|
||||
fprintf(stderr, "trc: Coult not write header %s\n", qPrintable(outputfile.errorString()));
|
||||
po_file_free(gettext_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (outputfile.write(trdata.constData(), trdata.size()) != trdata.size()) {
|
||||
fprintf(stderr, "trc: Coult not write data %s\n", qPrintable(outputfile.errorString()));
|
||||
po_file_free(gettext_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
po_file_free(gettext_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
return QT_PREPEND_NAMESPACE(runTrc)(argc, argv);
|
||||
}
|
|
@ -71,7 +71,7 @@
|
|||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "UIC 1"
|
||||
.TH UIC 1 "2022-03-04" "Katie 4.12.0" "Katie Manual"
|
||||
.TH UIC 1 "2022-06-15" "Katie 4.12.0" "Katie Manual"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
|
|
3
tests/auto/qtranslator/CMakeLists.txt
Normal file
3
tests/auto/qtranslator/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_qtranslator
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tst_qtranslator.cpp
|
||||
)
|
25
tests/auto/qtranslator/test.po
Normal file
25
tests/auto/qtranslator/test.po
Normal file
|
@ -0,0 +1,25 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-10-29 10:06+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: bg\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "foo"
|
||||
msgstr "фоо"
|
||||
|
||||
msgctxt "foo"
|
||||
msgid "bar"
|
||||
msgstr "фообар"
|
BIN
tests/auto/qtranslator/test.tr
Normal file
BIN
tests/auto/qtranslator/test.tr
Normal file
Binary file not shown.
68
tests/auto/qtranslator/tst_qtranslator.cpp
Normal file
68
tests/auto/qtranslator/tst_qtranslator.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 Ivailo Monev
|
||||
**
|
||||
** This file is part of the test suite of the Katie Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtCore/QtCore>
|
||||
|
||||
//TESTED_CLASS=QTranslator
|
||||
//TESTED_FILES=qtranslator.cpp,qtranslator.h
|
||||
|
||||
#ifndef QT_NO_TRANSLATION
|
||||
class tst_QTranslator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public slots:
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
private slots:
|
||||
void fromdata();
|
||||
};
|
||||
|
||||
void tst_QTranslator::init()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QTranslator::cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QTranslator::fromdata()
|
||||
{
|
||||
const QString trfilepath = QFile::encodeName(SRCDIR "/test.tr");
|
||||
QFile trfile(trfilepath);
|
||||
QVERIFY(trfile.open(QFile::ReadOnly));
|
||||
QTranslator translator;
|
||||
QVERIFY(translator.loadFromData(trfile.readAll()));
|
||||
QCOMPARE(translator.translate("", "foo"), QString::fromUtf8("фоо"));
|
||||
QCOMPARE(translator.translate("foo", "bar"), QString::fromUtf8("фообар"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QTranslator)
|
||||
|
||||
#include "moc_tst_qtranslator.cpp"
|
||||
|
||||
#else // QT_NO_TRANSLATION
|
||||
|
||||
QTEST_NOOP_MAIN
|
||||
|
||||
#endif // QT_NO_TRANSLATION
|
|
@ -4,7 +4,7 @@ foreach(tmpres ${TRANSLATIONS})
|
|||
get_filename_component(resource "${tmpres}" ABSOLUTE)
|
||||
get_filename_component(rscname "${resource}" NAME_WE)
|
||||
make_directory("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
set(rscout "${CMAKE_CURRENT_BINARY_DIR}/${rscname}.mo")
|
||||
set(rscout "${CMAKE_CURRENT_BINARY_DIR}/${rscname}.tr")
|
||||
if("${rscname}" MATCHES "qt_tools")
|
||||
set(rscbase "qt_tools")
|
||||
string(REPLACE "qt_tools_" "" rsclocale "${rscname}")
|
||||
|
@ -14,14 +14,15 @@ foreach(tmpres ${TRANSLATIONS})
|
|||
endif()
|
||||
add_custom_target(
|
||||
translations_${rscname} ALL
|
||||
COMMAND ${INTL_MSGFMT} -v "${resource}" -o "${rscout}"
|
||||
COMMENT "Generating ${rscname}.mo"
|
||||
COMMAND "${CMAKE_BINARY_DIR}/exec.sh" "${CMAKE_BINARY_DIR}/bin/trc${KATIE_TOOLS_SUFFIX}" "${resource}" -o "${rscout}"
|
||||
DEPENDS "trc"
|
||||
COMMENT "Generating ${rscname}.tr"
|
||||
)
|
||||
set_source_files_properties("${rscout}" PROPERTIES GENERATED TRUE)
|
||||
install(
|
||||
FILES "${rscout}"
|
||||
DESTINATION "${KATIE_TRANSLATIONS_PATH}/${rsclocale}/LC_MESSAGES"
|
||||
RENAME "${rscbase}.mo"
|
||||
DESTINATION "${KATIE_TRANSLATIONS_PATH}/${rsclocale}"
|
||||
RENAME "${rscbase}.tr"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
endforeach()
|
||||
|
|
Loading…
Add table
Reference in a new issue