merge the formfield patch from ooo-build
[ooovba.git] / transex3 / layout / tralay.cxx
blobb68d5ea0b02ad63726af6a468cacbd446ef230c0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tralay.cxx,v $
11 * $Revision: 1.4 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 #include <com/sun/star/xml/sax/SAXException.hpp>
33 #include <transex3/vosapp.hxx>
35 #include <osl/file.hxx>
37 #include "export.hxx"
38 #include "layoutparse.hxx"
39 #include "helpmerge.hxx"
40 #include "xmlparse.hxx"
42 // Convert a rtl::OUString to a byte string.
43 #define OUSTRING_CSTR( str ) \
44 rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr()
46 #define STRING( str ) String( str, RTL_TEXTENCODING_UTF8 )
47 #define BSTRING( str ) ByteString( str, RTL_TEXTENCODING_UTF8 )
49 using ::rtl::OUString;
51 using namespace ::osl;
52 using namespace ::com::sun::star;
53 using namespace ::com::sun::star::uno;
56 class TranslateLayout : public Application
58 ByteString mGid1;
59 ByteString mLanguage;
60 ByteString mLocalize;
61 ByteString mOutput;
62 ByteString mProject;
63 ByteString mRoot;
64 bool mMergeMode;
65 std::vector< ByteString > mLanguages;
66 std::list< ByteString > mFiles;
68 public:
69 TranslateLayout();
70 virtual ~TranslateLayout();
71 ByteString GetCommandLineParam( int i );
72 ByteString GetOptionArgument( int const i );
73 void ExceptionalMain();
74 void Main();
75 void Merge();
76 void MergeLanguage( ByteString const& language );
77 void ParseCommandLine();
78 void CreateSDF();
80 using Application::GetCommandLineParam;
83 static void usage()
85 fprintf( stderr, "Usage: tralay [OPTION]... XML-FILE\n" );
86 fprintf( stderr, "\nOptions:\n" );
87 fprintf( stderr, " -h,--help show this help\n" );
88 fprintf( stderr, " -l,--language=LANG process this language\n" );
89 fprintf( stderr, " -m,--merge=DATABASE.SDF translation database\n" );
90 fprintf( stderr, "\nExamples:\n" );
91 fprintf( stderr, " tralay -l en-US -o localize.sdf zoom.xml # Extract\n" );
92 fprintf( stderr, " tralay -m localize.sdf -l de -l nl -o out zoom.xml # Merge/translate\n" );
93 exit( 2 );
96 static ByteString ConvertSystemPath( const ByteString& rPath )
98 if( rPath.CompareTo( ".", 1 ) == 0 )
100 OUString sPath( rPath.GetBuffer(), rPath.Len(), RTL_TEXTENCODING_UTF8 );
102 ::rtl::OUString curDirPth, sURL;
103 osl_getProcessWorkingDir( &curDirPth.pData );
105 ::osl::FileBase::getAbsoluteFileURL( curDirPth, sPath, sURL );
106 ::osl::FileBase::getSystemPathFromFileURL( sURL, sPath );
108 return ByteString( rtl::OUStringToOString( sPath, RTL_TEXTENCODING_UTF8 ) );
110 else
112 return rPath;
116 ByteString TranslateLayout::GetCommandLineParam( int i )
118 return ByteString( OUSTRING_CSTR( Application::GetCommandLineParam( sal::static_int_cast< USHORT >( i ) ) ) );
121 ByteString TranslateLayout::GetOptionArgument( int const i )
123 if ( i >= GetCommandLineParamCount() )
124 usage();
125 ByteString arg = GetCommandLineParam( i );
126 if ( !arg.CompareTo( "-", 1 ) )
128 fprintf( stderr, "Option needs an argument: %s, found: %s\n",
129 GetCommandLineParam( i - 1 ).GetBuffer(),
130 arg.GetBuffer() );
131 usage();
133 return arg;
136 void TranslateLayout::ParseCommandLine()
138 for ( int i = 0; i < GetCommandLineParamCount(); i++ )
140 ByteString aParam = GetCommandLineParam( i );
141 if ( aParam.Equals( "-h" ) || aParam.Equals( "--help" ) )
142 usage();
143 else if ( aParam.Equals( "-l" ) || aParam.Equals( "--language" ) )
144 mLanguages.push_back ( GetOptionArgument( ++i ) );
145 else if ( aParam.Equals( "-m" ) || aParam.Equals( "--merge" ) )
147 mMergeMode = true;
148 mLocalize = GetOptionArgument( ++i );
150 else if ( aParam.Equals( "-o" ) || aParam.Equals( "--output" ) )
151 mOutput = ConvertSystemPath( GetOptionArgument( ++i ) );
152 else if ( !aParam.CompareTo( "-", 1 ) )
154 fprintf( stderr, "error: No such option: %s\n", aParam.GetBuffer() );
155 usage();
157 else
158 mFiles.push_back( ConvertSystemPath( aParam ) );
160 if ( !mFiles.size() )
162 fprintf( stderr, "error: No XML-FILE found\n" );
163 usage();
167 static XMLAttribute*
168 findAttribute( XMLAttributeList* lst, String const& name )
170 for ( ULONG i = 0; i < lst->Count(); i++ )
171 if ( lst->GetObject( i )->Equals( name ) )
172 return lst->GetObject( i );
173 return 0;
176 static XMLAttribute*
177 translateAttribute( XMLAttributeList* lst,
178 String const& name, String const& translation )
180 if ( XMLAttribute* a = findAttribute( lst, name ) )
181 return lst->Replace ( new XMLAttribute( name.Copy( 1 ), translation ), a );
182 return 0;
185 static void
186 translateElement( XMLElement* element, ByteString const& lang,
187 ResData* resData, MergeDataFile& mergeData )
189 XMLAttributeList* attributes = element->GetAttributeList();
190 std::vector<XMLAttribute*> interesting( interestingAttributes( attributes ) );
193 if( !interesting.empty() )
195 std::vector<XMLAttribute*>::iterator i( interesting.begin() );
196 ByteString id = BSTRING( (*i++)->GetValue() );
197 for ( ; i != interesting.end(); ++i )
199 ByteString attributeId = id;
200 attributeId += BSTRING ( **i );
201 resData->sGId = attributeId;
202 resData->sId = element->GetOldref();
204 if ( PFormEntrys* entry = mergeData.GetPFormEntrys( resData ) )
206 ByteString translation;
207 entry->GetText( translation, STRING_TYP_TEXT, lang, true );
208 // ByteString original = removeContent( element );
209 if ( !translation.Len() )
210 #if 0
211 translation = original;
212 #else
213 translation = BSTRING( ( *i )->GetValue() );
214 #endif
215 delete translateAttribute( attributes, **i , STRING( translation ) );
221 static bool is_dir( ByteString const& name )
223 DirectoryItem aItem;
224 OUString sFileURL( name.GetBuffer(), name.Len(), RTL_TEXTENCODING_UTF8 );
225 FileBase::getFileURLFromSystemPath( sFileURL, sFileURL );
226 if( DirectoryItem::get( sFileURL, aItem ) == FileBase::E_None )
228 FileStatus aStatus(FileStatusMask_Type);
229 if( aItem.getFileStatus( aStatus ) == FileBase::E_None )
231 if( aStatus.getFileType() == FileStatus::Directory )
232 return true;
235 return false;
238 static void make_directory( ByteString const& name )
240 OUString sFileURL( name.GetBuffer(), name.Len(), RTL_TEXTENCODING_UTF8 );
241 FileBase::getFileURLFromSystemPath( sFileURL, sFileURL );
242 Directory::create( sFileURL );
245 static void insertMarker( XMLParentNode *p, ByteString const& file )
247 if ( XMLChildNodeList* lst = p->GetChildList() )
248 if ( lst->Count() )
250 ULONG i = 1;
251 // Skip newline, if possible.
252 if ( lst->Count() > 1
253 && lst->GetObject( 2 )->GetNodeType() == XML_NODE_TYPE_DEFAULT )
254 i++;
255 OUString marker = OUString::createFromAscii( "\n NOTE: This file has been generated automagically by transex3/layout/tralay,\n from source template: " )
256 + STRING( file )
257 + OUString::createFromAscii( ".\n Do not edit, changes will be lost.\n" );
258 lst->Insert( new XMLComment( marker, 0 ), i );
262 void TranslateLayout::MergeLanguage( ByteString const& language )
264 ByteString xmlFile = mFiles.front();
266 MergeDataFile mergeData( mLocalize, xmlFile,
267 FALSE, RTL_TEXTENCODING_MS_1252 );
269 DirEntry aFile( xmlFile );
270 SimpleXMLParser aParser;
271 LayoutXMLFile* layoutXml = new LayoutXMLFile( mMergeMode );
272 if ( !aParser.Execute( aFile.GetFull() , STRING( xmlFile ), layoutXml ) )
274 fprintf(stderr, "error: parsing: %s\n", xmlFile.GetBuffer() );
275 return;
278 layoutXml->Extract();
279 insertMarker( layoutXml, xmlFile );
281 ResData resData( "", "", "" );
282 resData.sResTyp = mProject; /* mGid1 ?? */
283 resData.sFilename = xmlFile;
285 XMLHashMap* xmlStrings = layoutXml->GetStrings();
286 for ( XMLHashMap::iterator i = xmlStrings->begin(); i != xmlStrings->end();
287 ++i )
289 if ( LangHashMap* languageMap = i->second )
290 if ( XMLElement* element = ( *languageMap )[ "en-US" ] )
291 translateElement( element, language, &resData, mergeData );
294 #ifndef WNT
295 ByteString outFile = "/dev/stdout";
296 #else
297 ByteString outFile = "\\\\.\\CON";
298 #endif
299 if ( mOutput.Len() )
301 outFile = mOutput;
302 if ( is_dir( outFile ) )
304 ByteString outDir = mOutput;
305 outDir.Append( "/" ).Append( language );
306 if ( !is_dir( outDir ) )
307 make_directory( outDir );
308 outFile = outDir;
309 outFile.Append( "/" ).Append( xmlFile );
312 layoutXml->Write( outFile );
313 delete layoutXml;
316 void TranslateLayout::Merge()
318 if ( mLanguages.size() )
319 for ( std::vector<ByteString>::iterator i = mLanguages.begin();
320 i != mLanguages.end(); ++i)
321 MergeLanguage( *i );
322 else
323 MergeLanguage( mLanguage );
326 void TranslateLayout::CreateSDF()
328 ByteString xmlFile = mFiles.front();
329 #ifndef WNT
330 ByteString sdf = "/dev/stdout";
331 #else
332 ByteString sdf = "\\\\.\\CON";
333 #endif
334 if ( mOutput.Len() )
335 sdf = mOutput;
336 Export::SetLanguages( mLanguages );
337 HelpParser::CreateSDF( sdf, mProject, mRoot, xmlFile,
338 new LayoutXMLFile( mMergeMode ), mGid1 );
341 void TranslateLayout::ExceptionalMain()
343 ParseCommandLine();
344 if ( mLanguages.size() )
345 mLanguage = mLanguages.front();
346 if ( mMergeMode )
347 Merge();
348 else
349 CreateSDF();
352 void TranslateLayout::Main()
356 ExceptionalMain();
358 catch ( xml::sax::SAXException& rExc )
360 OString aStr( OUStringToOString( rExc.Message,
361 RTL_TEXTENCODING_ASCII_US ) );
362 uno::Exception exc;
363 if (rExc.WrappedException >>= exc)
365 aStr += OString( " >>> " );
366 aStr += OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US );
368 fprintf( stderr, "error: parsing: '%s'\n", aStr.getStr() );
369 OSL_ENSURE( 0, aStr.getStr() );
371 catch ( uno::Exception& rExc )
373 OString aStr( OUStringToOString( rExc.Message,
374 RTL_TEXTENCODING_ASCII_US ) );
375 fprintf( stderr, "error: UNO: '%s'\n", aStr.getStr() );
376 OSL_ENSURE( 0, aStr.getStr() );
380 TranslateLayout::TranslateLayout()
381 : Application()
382 , mGid1( "layout" )
383 , mLanguage( "en-US" )
384 , mLocalize( "localize.sdf" )
385 , mOutput()
386 , mProject( "layout" )
387 , mRoot()
388 , mMergeMode( false )
389 , mLanguages()
390 , mFiles()
394 TranslateLayout::~TranslateLayout()
398 SAL_IMPLEMENT_MAIN()
400 TranslateLayout t;
401 t.Main();
402 return 0;