merged tag ooo/OOO330_m14
[LibreOffice.git] / l10ntools / layout / tralay.cxx
blob72fd1a1d8c5ebbbd089b17cedc5b3dfb58f29e2d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #include <com/sun/star/xml/sax/SAXException.hpp>
29 #include <l10ntools/vosapp.hxx>
31 #include <osl/file.hxx>
33 #include "export.hxx"
34 #include "layoutparse.hxx"
35 #include "helpmerge.hxx"
36 #include "xmlparse.hxx"
38 // Convert a rtl::OUString to a byte string.
39 #define OUSTRING_CSTR( str ) \
40 rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr()
42 #define STRING( str ) String( str, RTL_TEXTENCODING_UTF8 )
43 #define BSTRING( str ) ByteString( str, RTL_TEXTENCODING_UTF8 )
45 using ::rtl::OUString;
47 using namespace ::osl;
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::uno;
52 class TranslateLayout : public Application
54 ByteString mGid1;
55 ByteString mLanguage;
56 ByteString mLocalize;
57 ByteString mOutput;
58 ByteString mProject;
59 ByteString mRoot;
60 bool mMergeMode;
61 std::vector< ByteString > mLanguages;
62 std::list< ByteString > mFiles;
64 public:
65 TranslateLayout();
66 virtual ~TranslateLayout();
67 ByteString GetCommandLineParam( int i );
68 ByteString GetOptionArgument( int const i );
69 void ExceptionalMain();
70 void Main();
71 void Merge();
72 void MergeLanguage( ByteString const& language );
73 void ParseCommandLine();
74 void CreateSDF();
76 using Application::GetCommandLineParam;
79 static void usage()
81 fprintf( stderr, "Usage: tralay [OPTION]... XML-FILE\n" );
82 fprintf( stderr, "\nOptions:\n" );
83 fprintf( stderr, " -h,--help show this help\n" );
84 fprintf( stderr, " -l,--language=LANG process this language\n" );
85 fprintf( stderr, " -m,--merge=DATABASE.SDF translation database\n" );
86 fprintf( stderr, "\nExamples:\n" );
87 fprintf( stderr, " tralay -l en-US -o localize.sdf zoom.xml # Extract\n" );
88 fprintf( stderr, " tralay -m localize.sdf -l de -l nl -o out zoom.xml # Merge/translate\n" );
89 exit( 2 );
92 static ByteString ConvertSystemPath( const ByteString& rPath )
94 if( rPath.CompareTo( ".", 1 ) == 0 )
96 OUString sPath( rPath.GetBuffer(), rPath.Len(), RTL_TEXTENCODING_UTF8 );
98 ::rtl::OUString curDirPth, sURL;
99 osl_getProcessWorkingDir( &curDirPth.pData );
101 ::osl::FileBase::getAbsoluteFileURL( curDirPth, sPath, sURL );
102 ::osl::FileBase::getSystemPathFromFileURL( sURL, sPath );
104 return ByteString( rtl::OUStringToOString( sPath, RTL_TEXTENCODING_UTF8 ) );
106 else
108 return rPath;
112 ByteString TranslateLayout::GetCommandLineParam( int i )
114 return ByteString( OUSTRING_CSTR( Application::GetCommandLineParam( sal::static_int_cast< USHORT >( i ) ) ) );
117 ByteString TranslateLayout::GetOptionArgument( int const i )
119 if ( i >= GetCommandLineParamCount() )
120 usage();
121 ByteString arg = GetCommandLineParam( i );
122 if ( !arg.CompareTo( "-", 1 ) )
124 fprintf( stderr, "Option needs an argument: %s, found: %s\n",
125 GetCommandLineParam( i - 1 ).GetBuffer(),
126 arg.GetBuffer() );
127 usage();
129 return arg;
132 void TranslateLayout::ParseCommandLine()
134 for ( int i = 0; i < GetCommandLineParamCount(); i++ )
136 ByteString aParam = GetCommandLineParam( i );
137 if ( aParam.Equals( "-h" ) || aParam.Equals( "--help" ) )
138 usage();
139 else if ( aParam.Equals( "-l" ) || aParam.Equals( "--language" ) )
140 mLanguages.push_back ( GetOptionArgument( ++i ) );
141 else if ( aParam.Equals( "-m" ) || aParam.Equals( "--merge" ) )
143 mMergeMode = true;
144 mLocalize = GetOptionArgument( ++i );
146 else if ( aParam.Equals( "-o" ) || aParam.Equals( "--output" ) )
147 mOutput = ConvertSystemPath( GetOptionArgument( ++i ) );
148 else if ( !aParam.CompareTo( "-", 1 ) )
150 fprintf( stderr, "error: No such option: %s\n", aParam.GetBuffer() );
151 usage();
153 else
154 mFiles.push_back( ConvertSystemPath( aParam ) );
156 if ( !mFiles.size() )
158 fprintf( stderr, "error: No XML-FILE found\n" );
159 usage();
163 static XMLAttribute*
164 findAttribute( XMLAttributeList* lst, String const& name )
166 for ( ULONG i = 0; i < lst->Count(); i++ )
167 if ( lst->GetObject( i )->Equals( name ) )
168 return lst->GetObject( i );
169 return 0;
172 static XMLAttribute*
173 translateAttribute( XMLAttributeList* lst,
174 String const& name, String const& translation )
176 if ( XMLAttribute* a = findAttribute( lst, name ) )
177 return lst->Replace ( new XMLAttribute( name.Copy( 1 ), translation ), a );
178 return 0;
181 static void
182 translateElement( XMLElement* element, ByteString const& lang,
183 ResData* resData, MergeDataFile& mergeData )
185 XMLAttributeList* attributes = element->GetAttributeList();
186 std::vector<XMLAttribute*> interesting( interestingAttributes( attributes ) );
189 if( !interesting.empty() )
191 std::vector<XMLAttribute*>::iterator i( interesting.begin() );
192 ByteString id = BSTRING( (*i++)->GetValue() );
193 for ( ; i != interesting.end(); ++i )
195 ByteString attributeId = id;
196 attributeId += BSTRING ( **i );
197 resData->sGId = attributeId;
198 resData->sId = element->GetOldref();
200 if ( PFormEntrys* entry = mergeData.GetPFormEntrys( resData ) )
202 ByteString translation;
203 entry->GetText( translation, STRING_TYP_TEXT, lang, true );
204 // ByteString original = removeContent( element );
205 if ( !translation.Len() )
206 #if 0
207 translation = original;
208 #else
209 translation = BSTRING( ( *i )->GetValue() );
210 #endif
211 delete translateAttribute( attributes, **i , STRING( translation ) );
217 static bool is_dir( ByteString const& name )
219 DirectoryItem aItem;
220 OUString sFileURL( name.GetBuffer(), name.Len(), RTL_TEXTENCODING_UTF8 );
221 FileBase::getFileURLFromSystemPath( sFileURL, sFileURL );
222 if( DirectoryItem::get( sFileURL, aItem ) == FileBase::E_None )
224 FileStatus aStatus(FileStatusMask_Type);
225 if( aItem.getFileStatus( aStatus ) == FileBase::E_None )
227 if( aStatus.getFileType() == FileStatus::Directory )
228 return true;
231 return false;
234 static void make_directory( ByteString const& name )
236 OUString sFileURL( name.GetBuffer(), name.Len(), RTL_TEXTENCODING_UTF8 );
237 FileBase::getFileURLFromSystemPath( sFileURL, sFileURL );
238 Directory::create( sFileURL );
241 static void insertMarker( XMLParentNode *p, ByteString const& file )
243 if ( XMLChildNodeList* lst = p->GetChildList() )
244 if ( lst->Count() )
246 ULONG i = 1;
247 // Skip newline, if possible.
248 if ( lst->Count() > 1
249 && lst->GetObject( 2 )->GetNodeType() == XML_NODE_TYPE_DEFAULT )
250 i++;
251 OUString marker = OUString::createFromAscii( "\n NOTE: This file has been generated automagically by transex3/layout/tralay,\n from source template: " )
252 + STRING( file )
253 + OUString::createFromAscii( ".\n Do not edit, changes will be lost.\n" );
254 lst->Insert( new XMLComment( marker, 0 ), i );
258 void TranslateLayout::MergeLanguage( ByteString const& language )
260 ByteString xmlFile = mFiles.front();
262 MergeDataFile mergeData( mLocalize, xmlFile,
263 FALSE, RTL_TEXTENCODING_MS_1252 );
265 DirEntry aFile( xmlFile );
266 SimpleXMLParser aParser;
267 LayoutXMLFile* layoutXml = new LayoutXMLFile( mMergeMode );
268 if ( !aParser.Execute( aFile.GetFull() , STRING( xmlFile ), layoutXml ) )
270 fprintf(stderr, "error: parsing: %s\n", xmlFile.GetBuffer() );
271 return;
274 layoutXml->Extract();
275 insertMarker( layoutXml, xmlFile );
277 ResData resData( "", "", "" );
278 resData.sResTyp = mProject; /* mGid1 ?? */
279 resData.sFilename = xmlFile;
281 XMLHashMap* xmlStrings = layoutXml->GetStrings();
282 for ( XMLHashMap::iterator i = xmlStrings->begin(); i != xmlStrings->end();
283 ++i )
285 if ( LangHashMap* languageMap = i->second )
286 if ( XMLElement* element = ( *languageMap )[ "en-US" ] )
287 translateElement( element, language, &resData, mergeData );
290 #ifndef WNT
291 ByteString outFile = "/dev/stdout";
292 #else
293 ByteString outFile = "\\\\.\\CON";
294 #endif
295 if ( mOutput.Len() )
297 outFile = mOutput;
298 if ( is_dir( outFile ) )
300 ByteString outDir = mOutput;
301 outDir.Append( "/" ).Append( language );
302 if ( !is_dir( outDir ) )
303 make_directory( outDir );
304 outFile = outDir;
305 outFile.Append( "/" ).Append( xmlFile );
308 layoutXml->Write( outFile );
309 delete layoutXml;
312 void TranslateLayout::Merge()
314 if ( mLanguages.size() )
315 for ( std::vector<ByteString>::iterator i = mLanguages.begin();
316 i != mLanguages.end(); ++i)
317 MergeLanguage( *i );
318 else
319 MergeLanguage( mLanguage );
322 void TranslateLayout::CreateSDF()
324 ByteString xmlFile = mFiles.front();
325 #ifndef WNT
326 ByteString sdf = "/dev/stdout";
327 #else
328 ByteString sdf = "\\\\.\\CON";
329 #endif
330 if ( mOutput.Len() )
331 sdf = mOutput;
332 Export::SetLanguages( mLanguages );
333 HelpParser::CreateSDF( sdf, mProject, mRoot, xmlFile,
334 new LayoutXMLFile( mMergeMode ), mGid1 );
337 void TranslateLayout::ExceptionalMain()
339 ParseCommandLine();
340 if ( mLanguages.size() )
341 mLanguage = mLanguages.front();
342 if ( mMergeMode )
343 Merge();
344 else
345 CreateSDF();
348 void TranslateLayout::Main()
352 ExceptionalMain();
354 catch ( xml::sax::SAXException& rExc )
356 OString aStr( OUStringToOString( rExc.Message,
357 RTL_TEXTENCODING_ASCII_US ) );
358 uno::Exception exc;
359 if (rExc.WrappedException >>= exc)
361 aStr += OString( " >>> " );
362 aStr += OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US );
364 fprintf( stderr, "error: parsing: '%s'\n", aStr.getStr() );
365 OSL_ENSURE( 0, aStr.getStr() );
367 catch ( uno::Exception& rExc )
369 OString aStr( OUStringToOString( rExc.Message,
370 RTL_TEXTENCODING_ASCII_US ) );
371 fprintf( stderr, "error: UNO: '%s'\n", aStr.getStr() );
372 OSL_ENSURE( 0, aStr.getStr() );
376 TranslateLayout::TranslateLayout()
377 : Application()
378 , mGid1( "layout" )
379 , mLanguage( "en-US" )
380 , mLocalize( "localize.sdf" )
381 , mOutput()
382 , mProject( "layout" )
383 , mRoot()
384 , mMergeMode( false )
385 , mLanguages()
386 , mFiles()
390 TranslateLayout::~TranslateLayout()
394 SAL_IMPLEMENT_MAIN()
396 TranslateLayout t;
397 t.Main();
398 return 0;