summaryrefslogtreecommitdiff
path: root/l10ntools
diff options
context:
space:
mode:
authorAndras Timar <atimar@suse.com>2012-11-27 14:12:22 +0100
committerAndras Timar <atimar@suse.com>2012-11-27 14:35:53 +0100
commit869dab55c133a80096e516a5d2b0f0c4d573fab6 (patch)
tree472f9c3681ea705ecdcfaa1d31fd28568102cb10 /l10ntools
parenta511a4f2a9e911ba2a8cd8bc452e1fc80d9462d8 (diff)
add new tool "stringex" to extract/merge strings from/to android UI
Change-Id: I8210957cedf911418044da340642cf97396f3e14
Diffstat (limited to 'l10ntools')
-rw-r--r--l10ntools/Executable_stringex.mk37
-rw-r--r--l10ntools/Module_l10ntools.mk1
-rw-r--r--l10ntools/inc/stringmerge.hxx42
-rw-r--r--l10ntools/source/localize.cxx5
-rw-r--r--l10ntools/source/stringex.cxx59
-rw-r--r--l10ntools/source/stringmerge.cxx179
6 files changed, 322 insertions, 1 deletions
diff --git a/l10ntools/Executable_stringex.mk b/l10ntools/Executable_stringex.mk
new file mode 100644
index 000000000000..f42b36c79acf
--- /dev/null
+++ b/l10ntools/Executable_stringex.mk
@@ -0,0 +1,37 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+
+$(eval $(call gb_Executable_Executable,stringex))
+
+$(eval $(call gb_Executable_set_include,stringex,\
+ -I$(SRCDIR)/l10ntools/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Executable_use_libraries,stringex,\
+ sal \
+))
+
+$(eval $(call gb_Executable_use_static_libraries,stringex,\
+ transex \
+))
+
+$(eval $(call gb_Executable_add_exception_objects,stringex,\
+ l10ntools/source/stringmerge \
+ l10ntools/source/stringex \
+))
+
+$(eval $(call gb_Executable_use_externals,stringex,\
+ libxml2 \
+ icuuc \
+ $(if $(filter MSC,$(COM)),icuin,icui18n) \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/l10ntools/Module_l10ntools.mk b/l10ntools/Module_l10ntools.mk
index 4b2b0f6d970d..02b88dc276e1 100644
--- a/l10ntools/Module_l10ntools.mk
+++ b/l10ntools/Module_l10ntools.mk
@@ -39,6 +39,7 @@ $(eval $(call gb_Module_add_targets,l10ntools,\
Executable_renewpo \
Executable_propex \
Executable_treex \
+ Executable_stringex \
StaticLibrary_transex \
Package_inc \
Package_scripts \
diff --git a/l10ntools/inc/stringmerge.hxx b/l10ntools/inc/stringmerge.hxx
new file mode 100644
index 000000000000..01a7b9b719cd
--- /dev/null
+++ b/l10ntools/inc/stringmerge.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef _STRINGMERGE_INCLUDED
+#define _STRINGMERGE_INCLUDED
+
+#include <libxml/tree.h>
+#include <rtl/string.hxx>
+#include <vector>
+
+/** Class for Android strings.xml localization
+
+ Parse strings.xml files, extract translatable strings
+ and merge translated strings.
+*/
+class StringParser
+{
+private:
+ xmlDocPtr m_pSource;
+ OString m_sLang;
+ bool m_bIsInitialized;
+
+public:
+ StringParser(
+ const OString& rInputFile, const OString& rLang );
+ ~StringParser();
+
+ bool isInitialized() const { return m_bIsInitialized; }
+ void Extract(
+ const OString& rSDFFile, const OString& rPrj, const OString& rRoot );
+ void Merge(
+ const OString &rMergeSrc, const OString &rDestinationFile );
+};
+
+#endif //_STRINGMERGE_INCLUDED
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/l10ntools/source/localize.cxx b/l10ntools/source/localize.cxx
index eb284eaaa8d4..07a240ceb523 100644
--- a/l10ntools/source/localize.cxx
+++ b/l10ntools/source/localize.cxx
@@ -131,6 +131,7 @@ bool passesPositiveList(OUString const & url) {
{ RTL_CONSTASCII_STRINGPARAM(
"/dbaccess/source/ui/inc/toolbox_tmpl.hrc") },
{ RTL_CONSTASCII_STRINGPARAM("/description.xml") },
+ { RTL_CONSTASCII_STRINGPARAM("/android/sdremote/res/values/strings.xml") },
{ RTL_CONSTASCII_STRINGPARAM("/offmgr/inc/offmenu_tmpl.hrc") },
{ RTL_CONSTASCII_STRINGPARAM(
"/offmgr/source/offapp/intro/intro_tmpl.hrc") },
@@ -305,7 +306,8 @@ void handleFile(
{ RTL_CONSTASCII_STRINGPARAM(".ulf"), "ulfex", false },
{ RTL_CONSTASCII_STRINGPARAM(".xcu"), "cfgex", false },
{ RTL_CONSTASCII_STRINGPARAM(".xrm"), "xrmex", false },
- { RTL_CONSTASCII_STRINGPARAM(".xml"), "xrmex", true },
+ { RTL_CONSTASCII_STRINGPARAM("description.xml"), "xrmex", true },
+ { RTL_CONSTASCII_STRINGPARAM("strings.xml"), "stringex", true },
{ RTL_CONSTASCII_STRINGPARAM(".xhp"), "helpex", false },
{ RTL_CONSTASCII_STRINGPARAM(".properties"), "propex", false },
{ RTL_CONSTASCII_STRINGPARAM(".ui"), "uiex", false },
@@ -328,6 +330,7 @@ void handleFile(
bool includeProject(OString const & project) {
static OString projects[] = {
"accessibility",
+ "android",
"avmedia",
"basctl",
"basic",
diff --git a/l10ntools/source/stringex.cxx b/l10ntools/source/stringex.cxx
new file mode 100644
index 000000000000..ed2a935829c6
--- /dev/null
+++ b/l10ntools/source/stringex.cxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <iostream>
+#include "sal/main.h"
+
+#include "export.hxx"
+#include "stringmerge.hxx"
+
+void WriteUsage()
+{
+ std::cout
+ << "Syntax: stringex [-p Prj] [-r Root] -i FileIn -o FileOut"
+ << " [-m DataBase] [-l l1,l2,...]\n"
+ << " Prj: Project\n"
+ << " Root: Path to project root (../.. etc.)\n"
+ << " FileIn: Source files (strings.xml)\n"
+ << " FileOut: Destination file (*.*)\n"
+ << " DataBase: Mergedata (*.po)\n"
+ << " -l: Restrict the handled languages; l1, l2, ... are elements of"
+ << " (de, en-US, ...)\n";
+}
+
+
+SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
+{
+ HandledArgs aArgs;
+ if( !Export::handleArguments(argc, argv, aArgs) )
+ {
+ WriteUsage();
+ return 1;
+ }
+
+ StringParser aParser(aArgs.m_sInputFile, Export::sLanguages);
+ if( !aParser.isInitialized() )
+ {
+ return 1;
+ }
+
+ if( aArgs.m_bMergeMode || aArgs.m_sPrj.isEmpty() )
+ {
+ aParser.Merge(
+ aArgs.m_sMergeSrc, aArgs.m_sOutputFile );
+ }
+ else
+ {
+ aParser.Extract(
+ aArgs.m_sOutputFile, aArgs.m_sPrj, aArgs.m_sPrjRoot );
+ }
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/l10ntools/source/stringmerge.cxx b/l10ntools/source/stringmerge.cxx
new file mode 100644
index 000000000000..71909d9dbe72
--- /dev/null
+++ b/l10ntools/source/stringmerge.cxx
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <iostream>
+#include <fstream>
+#include <cassert>
+#include <cstring>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/xmlstring.h>
+
+#include "export.hxx"
+#include "common.hxx"
+#include "stringmerge.hxx"
+
+
+namespace
+{
+ //Write out an sdf line
+ static void lcl_WriteSDF(
+ std::ofstream &aSDFStream, const OString& rText, const OString& rPrj,
+ const OString& rActFileName, const OString& rID, const OString& rType )
+ {
+ OString sOutput( rPrj ); sOutput += "\t";
+ sOutput += rActFileName;
+ sOutput += "\t0\t";
+ sOutput += rType; sOutput += "\t";
+ sOutput += rID; sOutput += "\t\t\t\t0\ten-US\t";
+ sOutput += rText; sOutput += "\t\t\t\t";
+ aSDFStream << sOutput.getStr() << std::endl;
+ }
+
+ //Convert xmlChar* to OString
+ static OString lcl_xmlStrToOString( const xmlChar* pString )
+ {
+ xmlChar* pTemp = xmlStrdup( pString );
+ OString sResult =
+ static_cast<OString>(reinterpret_cast<sal_Char*>( pTemp ));
+ xmlFree( pTemp );
+ return sResult;
+ }
+}
+
+//Parse strings.xml file
+StringParser::StringParser(
+ const OString& rInputFile, const OString& rLang )
+ : m_pSource( 0 )
+ , m_sLang( rLang )
+ , m_bIsInitialized( false )
+{
+ m_pSource = xmlParseFile( rInputFile.getStr() );
+ if ( !m_pSource ) {
+ std::cerr
+ << "Stringx error: Cannot open source file: "
+ << rInputFile.getStr() << std::endl;
+ return;
+ }
+ if( !m_pSource->name )
+ {
+ m_pSource->name = new char[strlen(rInputFile.getStr())+1];
+ strcpy( m_pSource->name, rInputFile.getStr() );
+ }
+ m_bIsInitialized = true;
+}
+
+StringParser::~StringParser()
+{
+}
+
+//Extract strings form source file
+void StringParser::Extract(
+ const OString& rSDFFile, const OString& rPrj, const OString& rRoot )
+{
+ assert( m_bIsInitialized );
+ std::ofstream aSDFStream(
+ rSDFFile.getStr(), std::ios_base::out | std::ios_base::trunc );
+ if( !aSDFStream.is_open() )
+ {
+ std::cerr
+ << "stringex error: Cannot open sdffile for extract: "
+ << rSDFFile.getStr() << std::endl;
+ return;
+ }
+
+ xmlNodePtr pRootNode = xmlDocGetRootElement( m_pSource ); // <resource>
+ for( xmlNodePtr pCurrent = pRootNode->children->next;
+ pCurrent; pCurrent = pCurrent->next)
+ {
+ if (!xmlStrcmp(pCurrent->name, (const xmlChar*)("string")))
+ {
+ xmlChar* pID = xmlGetProp(pCurrent, (const xmlChar*)("name"));
+ xmlChar* pText = xmlNodeGetContent(pCurrent);
+ lcl_WriteSDF(
+ aSDFStream,
+ lcl_xmlStrToOString( pText ),
+ rPrj,
+ common::pathnameToken(
+ m_pSource->name, rRoot.getStr()),
+ lcl_xmlStrToOString( pID ),
+ OString( "string" ));
+
+ xmlFree( pID );
+ xmlFree( pText );
+ }
+ }
+
+ xmlFreeDoc( m_pSource );
+ xmlCleanupParser();
+ aSDFStream.close();
+ m_bIsInitialized = false;
+}
+
+//Merge strings to localized strings.xml file
+void StringParser::Merge(
+ const OString &rMergeSrc, const OString &rDestinationFile )
+{
+ assert( m_bIsInitialized );
+
+ if( (m_sLang == "en-US") || (m_sLang == "qtz") )
+ {
+ return;
+ }
+
+ MergeDataFile aMergeDataFile(
+ rMergeSrc, static_cast<OString>( m_pSource->name ), false );
+ const std::vector<OString> vLanguages = aMergeDataFile.GetLanguages();
+ if( vLanguages.size()>=2 && vLanguages[0] != m_sLang )
+ {
+ std::cerr
+ << "stringex error: given language conflicts with "
+ << "language of Mergedata file: "
+ << m_sLang.getStr() << " - "
+ << vLanguages[vLanguages[0]=="qtz" ? 0 : 1].getStr() << std::endl;
+ return;
+ }
+
+ xmlNodePtr pRootNode = xmlDocGetRootElement( m_pSource ); //<resource>
+
+ for( xmlNodePtr pCurrent = pRootNode->children;
+ pCurrent; pCurrent = pCurrent->next)
+ {
+ if (!xmlStrcmp(pCurrent->name, (const xmlChar*)("string")))
+ {
+ xmlChar* pID = xmlGetProp(pCurrent, (const xmlChar*)("name"));
+ ResData aResData(
+ "", lcl_xmlStrToOString( pID ),
+ static_cast<OString>(m_pSource->name) );
+ xmlFree( pID );
+ aResData.sResTyp = "string";
+ PFormEntrys* pEntrys =
+ (&aMergeDataFile)->GetPFormEntrys( &aResData );
+ if( pEntrys )
+ {
+ OString sNewText;
+ pEntrys->GetText( sNewText, STRING_TYP_TEXT, m_sLang );
+ xmlNodeSetContent(
+ pCurrent,
+ xmlEncodeSpecialChars( NULL,
+ reinterpret_cast<const xmlChar*>(
+ sNewText.getStr() )));
+ }
+ }
+ }
+
+ xmlSaveFile( rDestinationFile.getStr(), m_pSource );
+ xmlFreeDoc( m_pSource );
+ xmlCleanupParser();
+ m_bIsInitialized = false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */