diff options
Diffstat (limited to 'l10ntools/layout/tralay.cxx')
-rw-r--r-- | l10ntools/layout/tralay.cxx | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/l10ntools/layout/tralay.cxx b/l10ntools/layout/tralay.cxx new file mode 100644 index 000000000000..13a7fdb0c5d9 --- /dev/null +++ b/l10ntools/layout/tralay.cxx @@ -0,0 +1,403 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tralay.cxx,v $ + * + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <com/sun/star/xml/sax/SAXException.hpp> +#include <l10ntools/vosapp.hxx> + +#include <osl/file.hxx> + +#include "export.hxx" +#include "layoutparse.hxx" +#include "helpmerge.hxx" +#include "xmlparse.hxx" + +// Convert a rtl::OUString to a byte string. +#define OUSTRING_CSTR( str ) \ + rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() + +#define STRING( str ) String( str, RTL_TEXTENCODING_UTF8 ) +#define BSTRING( str ) ByteString( str, RTL_TEXTENCODING_UTF8 ) + +using ::rtl::OUString; + +using namespace ::osl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + + +class TranslateLayout : public Application +{ + ByteString mGid1; + ByteString mLanguage; + ByteString mLocalize; + ByteString mOutput; + ByteString mProject; + ByteString mRoot; + bool mMergeMode; + std::vector< ByteString > mLanguages; + std::list< ByteString > mFiles; + +public: + TranslateLayout(); + virtual ~TranslateLayout(); + ByteString GetCommandLineParam( int i ); + ByteString GetOptionArgument( int const i ); + void ExceptionalMain(); + void Main(); + void Merge(); + void MergeLanguage( ByteString const& language ); + void ParseCommandLine(); + void CreateSDF(); + + using Application::GetCommandLineParam; +}; + +static void usage() +{ + fprintf( stderr, "Usage: tralay [OPTION]... XML-FILE\n" ); + fprintf( stderr, "\nOptions:\n" ); + fprintf( stderr, " -h,--help show this help\n" ); + fprintf( stderr, " -l,--language=LANG process this language\n" ); + fprintf( stderr, " -m,--merge=DATABASE.SDF translation database\n" ); + fprintf( stderr, "\nExamples:\n" ); + fprintf( stderr, " tralay -l en-US -o localize.sdf zoom.xml # Extract\n" ); + fprintf( stderr, " tralay -m localize.sdf -l de -l nl -o out zoom.xml # Merge/translate\n" ); + exit( 2 ); +} + +static ByteString ConvertSystemPath( const ByteString& rPath ) +{ + if( rPath.CompareTo( ".", 1 ) == 0 ) + { + OUString sPath( rPath.GetBuffer(), rPath.Len(), RTL_TEXTENCODING_UTF8 ); + + ::rtl::OUString curDirPth, sURL; + osl_getProcessWorkingDir( &curDirPth.pData ); + + ::osl::FileBase::getAbsoluteFileURL( curDirPth, sPath, sURL ); + ::osl::FileBase::getSystemPathFromFileURL( sURL, sPath ); + + return ByteString( rtl::OUStringToOString( sPath, RTL_TEXTENCODING_UTF8 ) ); + } + else + { + return rPath; + } +} + +ByteString TranslateLayout::GetCommandLineParam( int i ) +{ + return ByteString( OUSTRING_CSTR( Application::GetCommandLineParam( sal::static_int_cast< USHORT >( i ) ) ) ); +} + +ByteString TranslateLayout::GetOptionArgument( int const i ) +{ + if ( i >= GetCommandLineParamCount() ) + usage(); + ByteString arg = GetCommandLineParam( i ); + if ( !arg.CompareTo( "-", 1 ) ) + { + fprintf( stderr, "Option needs an argument: %s, found: %s\n", + GetCommandLineParam( i - 1 ).GetBuffer(), + arg.GetBuffer() ); + usage(); + } + return arg; + } + +void TranslateLayout::ParseCommandLine() +{ + for ( int i = 0; i < GetCommandLineParamCount(); i++ ) + { + ByteString aParam = GetCommandLineParam( i ); + if ( aParam.Equals( "-h" ) || aParam.Equals( "--help" ) ) + usage(); + else if ( aParam.Equals( "-l" ) || aParam.Equals( "--language" ) ) + mLanguages.push_back ( GetOptionArgument( ++i ) ); + else if ( aParam.Equals( "-m" ) || aParam.Equals( "--merge" ) ) + { + mMergeMode = true; + mLocalize = GetOptionArgument( ++i ); + } + else if ( aParam.Equals( "-o" ) || aParam.Equals( "--output" ) ) + mOutput = ConvertSystemPath( GetOptionArgument( ++i ) ); + else if ( !aParam.CompareTo( "-", 1 ) ) + { + fprintf( stderr, "error: No such option: %s\n", aParam.GetBuffer() ); + usage(); + } + else + mFiles.push_back( ConvertSystemPath( aParam ) ); + } + if ( !mFiles.size() ) + { + fprintf( stderr, "error: No XML-FILE found\n" ); + usage(); + } +} + +static XMLAttribute* +findAttribute( XMLAttributeList* lst, String const& name ) +{ + for ( ULONG i = 0; i < lst->Count(); i++ ) + if ( lst->GetObject( i )->Equals( name ) ) + return lst->GetObject( i ); + return 0; +} + +static XMLAttribute* +translateAttribute( XMLAttributeList* lst, + String const& name, String const& translation ) +{ + if ( XMLAttribute* a = findAttribute( lst, name ) ) + return lst->Replace ( new XMLAttribute( name.Copy( 1 ), translation ), a ); + return 0; +} + +static void +translateElement( XMLElement* element, ByteString const& lang, + ResData* resData, MergeDataFile& mergeData ) +{ + XMLAttributeList* attributes = element->GetAttributeList(); + std::vector<XMLAttribute*> interesting( interestingAttributes( attributes ) ); + + + if( !interesting.empty() ) + { + std::vector<XMLAttribute*>::iterator i( interesting.begin() ); + ByteString id = BSTRING( (*i++)->GetValue() ); + for ( ; i != interesting.end(); ++i ) + { + ByteString attributeId = id; + attributeId += BSTRING ( **i ); + resData->sGId = attributeId; + resData->sId = element->GetOldref(); + + if ( PFormEntrys* entry = mergeData.GetPFormEntrys( resData ) ) + { + ByteString translation; + entry->GetText( translation, STRING_TYP_TEXT, lang, true ); + // ByteString original = removeContent( element ); + if ( !translation.Len() ) +#if 0 + translation = original; +#else + translation = BSTRING( ( *i )->GetValue() ); +#endif + delete translateAttribute( attributes, **i , STRING( translation ) ); + } + } + } +} + +static bool is_dir( ByteString const& name ) +{ + DirectoryItem aItem; + OUString sFileURL( name.GetBuffer(), name.Len(), RTL_TEXTENCODING_UTF8 ); + FileBase::getFileURLFromSystemPath( sFileURL, sFileURL ); + if( DirectoryItem::get( sFileURL, aItem ) == FileBase::E_None ) + { + FileStatus aStatus(FileStatusMask_Type); + if( aItem.getFileStatus( aStatus ) == FileBase::E_None ) + { + if( aStatus.getFileType() == FileStatus::Directory ) + return true; + } + } + return false; +} + +static void make_directory( ByteString const& name ) +{ + OUString sFileURL( name.GetBuffer(), name.Len(), RTL_TEXTENCODING_UTF8 ); + FileBase::getFileURLFromSystemPath( sFileURL, sFileURL ); + Directory::create( sFileURL ); +} + +static void insertMarker( XMLParentNode *p, ByteString const& file ) +{ + if ( XMLChildNodeList* lst = p->GetChildList() ) + if ( lst->Count() ) + { + ULONG i = 1; + // Skip newline, if possible. + if ( lst->Count() > 1 + && lst->GetObject( 2 )->GetNodeType() == XML_NODE_TYPE_DEFAULT ) + i++; + OUString marker = OUString::createFromAscii( "\n NOTE: This file has been generated automagically by transex3/layout/tralay,\n from source template: " ) + + STRING( file ) + + OUString::createFromAscii( ".\n Do not edit, changes will be lost.\n" ); + lst->Insert( new XMLComment( marker, 0 ), i ); + } +} + +void TranslateLayout::MergeLanguage( ByteString const& language ) +{ + ByteString xmlFile = mFiles.front(); + + MergeDataFile mergeData( mLocalize, xmlFile, + FALSE, RTL_TEXTENCODING_MS_1252 ); + + DirEntry aFile( xmlFile ); + SimpleXMLParser aParser; + LayoutXMLFile* layoutXml = new LayoutXMLFile( mMergeMode ); + if ( !aParser.Execute( aFile.GetFull() , STRING( xmlFile ), layoutXml ) ) + { + fprintf(stderr, "error: parsing: %s\n", xmlFile.GetBuffer() ); + return; + } + + layoutXml->Extract(); + insertMarker( layoutXml, xmlFile ); + + ResData resData( "", "", "" ); + resData.sResTyp = mProject; /* mGid1 ?? */ + resData.sFilename = xmlFile; + + XMLHashMap* xmlStrings = layoutXml->GetStrings(); + for ( XMLHashMap::iterator i = xmlStrings->begin(); i != xmlStrings->end(); + ++i ) + { + if ( LangHashMap* languageMap = i->second ) + if ( XMLElement* element = ( *languageMap )[ "en-US" ] ) + translateElement( element, language, &resData, mergeData ); + } + +#ifndef WNT + ByteString outFile = "/dev/stdout"; +#else + ByteString outFile = "\\\\.\\CON"; +#endif + if ( mOutput.Len() ) + { + outFile = mOutput; + if ( is_dir( outFile ) ) + { + ByteString outDir = mOutput; + outDir.Append( "/" ).Append( language ); + if ( !is_dir( outDir ) ) + make_directory( outDir ); + outFile = outDir; + outFile.Append( "/" ).Append( xmlFile ); + } + } + layoutXml->Write( outFile ); + delete layoutXml; +} + +void TranslateLayout::Merge() +{ + if ( mLanguages.size() ) + for ( std::vector<ByteString>::iterator i = mLanguages.begin(); + i != mLanguages.end(); ++i) + MergeLanguage( *i ); + else + MergeLanguage( mLanguage ); +} + +void TranslateLayout::CreateSDF() +{ + ByteString xmlFile = mFiles.front(); +#ifndef WNT + ByteString sdf = "/dev/stdout"; +#else + ByteString sdf = "\\\\.\\CON"; +#endif + if ( mOutput.Len() ) + sdf = mOutput; + Export::SetLanguages( mLanguages ); + HelpParser::CreateSDF( sdf, mProject, mRoot, xmlFile, + new LayoutXMLFile( mMergeMode ), mGid1 ); +} + +void TranslateLayout::ExceptionalMain() +{ + ParseCommandLine(); + if ( mLanguages.size() ) + mLanguage = mLanguages.front(); + if ( mMergeMode ) + Merge(); + else + CreateSDF(); +} + +void TranslateLayout::Main() +{ + try + { + ExceptionalMain(); + } + catch ( xml::sax::SAXException& rExc ) + { + OString aStr( OUStringToOString( rExc.Message, + RTL_TEXTENCODING_ASCII_US ) ); + uno::Exception exc; + if (rExc.WrappedException >>= exc) + { + aStr += OString( " >>> " ); + aStr += OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ); + } + fprintf( stderr, "error: parsing: '%s'\n", aStr.getStr() ); + OSL_ENSURE( 0, aStr.getStr() ); + } + catch ( uno::Exception& rExc ) + { + OString aStr( OUStringToOString( rExc.Message, + RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "error: UNO: '%s'\n", aStr.getStr() ); + OSL_ENSURE( 0, aStr.getStr() ); + } +} + +TranslateLayout::TranslateLayout() + : Application() + , mGid1( "layout" ) + , mLanguage( "en-US" ) + , mLocalize( "localize.sdf" ) + , mOutput() + , mProject( "layout" ) + , mRoot() + , mMergeMode( false ) + , mLanguages() + , mFiles() +{ +} + +TranslateLayout::~TranslateLayout() +{ +} + +SAL_IMPLEMENT_MAIN() +{ + TranslateLayout t; + t.Main(); + return 0; +} |