1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 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. 14 * 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). 20 * 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. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_l10ntools.hxx" 30 #include <stdio.h> 31 #include <tools/string.hxx> 32 #include <tools/fsys.hxx> 33 34 // local includes 35 #include "export.hxx" 36 #include "cfgmerge.hxx" 37 #include "tokens.h" 38 #include "utf8conv.hxx" 39 40 extern "C" { int yyerror( char * ); } 41 extern "C" { int YYWarning( char * ); } 42 43 // defines to parse command line 44 #define STATE_NON 0x0001 45 #define STATE_INPUT 0x0002 46 #define STATE_OUTPUT 0x0003 47 #define STATE_PRJ 0x0004 48 #define STATE_ROOT 0x0005 49 #define STATE_MERGESRC 0x0006 50 #define STATE_ERRORLOG 0x0007 51 #define STATE_UTF8 0x0008 52 #define STATE_LANGUAGES 0X0009 53 #define STATE_ISOCODE99 0x000A 54 #define STATE_FORCE 0x000B 55 56 // set of global variables 57 sal_Bool bEnableExport; 58 sal_Bool bMergeMode; 59 sal_Bool bErrorLog; 60 sal_Bool bForce; 61 sal_Bool bUTF8; 62 ByteString sPrj; 63 ByteString sPrjRoot; 64 ByteString sInputFileName; 65 ByteString sActFileName; 66 ByteString sFullEntry; 67 ByteString sOutputFile; 68 ByteString sMergeSrc; 69 String sUsedTempFile; 70 71 CfgParser *pParser; 72 73 extern "C" { 74 // the whole interface to lexer is in this extern "C" section 75 76 /*****************************************************************************/ 77 extern char *GetOutputFile( int argc, char* argv[]) 78 /*****************************************************************************/ 79 { 80 bEnableExport = sal_False; 81 bMergeMode = sal_False; 82 bErrorLog = sal_True; 83 bForce = sal_False; 84 bUTF8 = sal_True; 85 sPrj = ""; 86 sPrjRoot = ""; 87 sInputFileName = ""; 88 sActFileName = ""; 89 90 sal_uInt16 nState = STATE_NON; 91 sal_Bool bInput = sal_False; 92 93 // parse command line 94 for( int i = 1; i < argc; i++ ) { 95 ByteString sSwitch( argv[ i ] ); 96 sSwitch.ToUpperAscii(); 97 98 if ( sSwitch == "-I" ) { 99 nState = STATE_INPUT; // next token specifies source file 100 } 101 else if ( sSwitch == "-O" ) { 102 nState = STATE_OUTPUT; // next token specifies the dest file 103 } 104 else if ( sSwitch == "-P" ) { 105 nState = STATE_PRJ; // next token specifies the cur. project 106 } 107 else if ( sSwitch == "-R" ) { 108 nState = STATE_ROOT; // next token specifies path to project root 109 } 110 else if ( sSwitch == "-M" ) { 111 nState = STATE_MERGESRC; // next token specifies the merge database 112 } 113 else if ( sSwitch == "-E" ) { 114 nState = STATE_ERRORLOG; 115 bErrorLog = sal_False; 116 } 117 else if ( sSwitch == "-UTF8" ) { 118 nState = STATE_UTF8; 119 bUTF8 = sal_True; 120 } 121 else if ( sSwitch == "-NOUTF8" ) { 122 nState = STATE_UTF8; 123 bUTF8 = sal_False; 124 } 125 else if ( sSwitch == "-F" ) { 126 nState = STATE_FORCE; 127 bForce = sal_True; 128 } 129 else if ( sSwitch == "-L" ) { 130 nState = STATE_LANGUAGES; 131 } 132 else if ( sSwitch.ToUpperAscii() == "-ISO99" ) { 133 nState = STATE_ISOCODE99; 134 } 135 else { 136 switch ( nState ) { 137 case STATE_NON: { 138 return NULL; // no valid command line 139 } 140 case STATE_INPUT: { 141 sInputFileName = argv[ i ]; 142 bInput = sal_True; // source file found 143 } 144 break; 145 case STATE_OUTPUT: { 146 sOutputFile = argv[ i ]; // the dest. file 147 } 148 break; 149 case STATE_PRJ: { 150 sPrj = ByteString( argv[ i ]); 151 // sPrj.ToLowerAscii(); // the project 152 } 153 break; 154 case STATE_ROOT: { 155 sPrjRoot = ByteString( argv[ i ]); // path to project root 156 } 157 break; 158 case STATE_MERGESRC: { 159 sMergeSrc = ByteString( argv[ i ]); 160 bMergeMode = sal_True; // activate merge mode, cause merge database found 161 } 162 break; 163 case STATE_LANGUAGES: { 164 Export::sLanguages = ByteString( argv[ i ]); 165 } 166 break; 167 } 168 } 169 } 170 171 if ( bInput ) { 172 // command line is valid 173 bEnableExport = sal_True; 174 char *pReturn = new char[ sOutputFile.Len() + 1 ]; 175 strcpy( pReturn, sOutputFile.GetBuffer()); // #100211# - checked 176 return pReturn; 177 } 178 179 // command line is not valid 180 return NULL; 181 } 182 /*****************************************************************************/ 183 int InitCfgExport( char *pOutput , char* pFilename ) 184 /*****************************************************************************/ 185 { 186 // instanciate Export 187 ByteString sOutput( pOutput ); 188 ByteString sFilename( pFilename ); 189 Export::InitLanguages(); 190 191 if ( bMergeMode ) 192 pParser = new CfgMerge( sMergeSrc, sOutputFile, sFilename ); 193 else if ( sOutputFile.Len()) 194 pParser = new CfgExport( sOutputFile, sPrj, sActFileName ); 195 196 return 1; 197 } 198 199 /*****************************************************************************/ 200 int EndCfgExport() 201 /*****************************************************************************/ 202 { 203 delete pParser; 204 205 return 1; 206 } 207 208 void removeTempFile(){ 209 if( !sUsedTempFile.EqualsIgnoreCaseAscii( "" ) ){ 210 DirEntry aTempFile( sUsedTempFile ); 211 aTempFile.Kill(); 212 } 213 } 214 extern const char* getFilename() 215 { 216 return sInputFileName.GetBuffer(); 217 } 218 /*****************************************************************************/ 219 extern FILE *GetCfgFile() 220 /*****************************************************************************/ 221 { 222 FILE *pFile = 0; 223 // look for valid filename 224 if ( sInputFileName.Len()) { 225 if( Export::fileHasUTF8ByteOrderMarker( sInputFileName ) ){ 226 DirEntry aTempFile = Export::GetTempFile(); 227 DirEntry aSourceFile( String( sInputFileName , RTL_TEXTENCODING_ASCII_US ) ); 228 aSourceFile.CopyTo( aTempFile , FSYS_ACTION_COPYFILE ); 229 String sTempFile = aTempFile.GetFull(); 230 Export::RemoveUTF8ByteOrderMarkerFromFile( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ) ); 231 pFile = fopen( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ).GetBuffer(), "r" ); 232 sUsedTempFile = sTempFile; 233 }else{ 234 // able to open file? 235 pFile = fopen( sInputFileName.GetBuffer(), "r" ); 236 sUsedTempFile = String::CreateFromAscii(""); 237 } 238 if ( !pFile ){ 239 fprintf( stderr, "Error: Could not open file %s\n", 240 sInputFileName.GetBuffer()); 241 exit( -13 ); 242 } 243 else { 244 // this is a valid file which can be opened, so 245 // create path to project root 246 DirEntry aEntry( String( sInputFileName, RTL_TEXTENCODING_ASCII_US )); 247 aEntry.ToAbs(); 248 sFullEntry= ByteString( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US ); 249 aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US )); 250 aEntry += DirEntry( sPrjRoot ); 251 ByteString sPrjEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US ); 252 253 // create file name, beginnig with project root 254 // (e.g.: source\ui\src\menue.src) 255 // printf("sFullEntry = %s\n",sFullEntry.GetBuffer()); 256 sActFileName = sFullEntry.Copy( sPrjEntry.Len() + 1 ); 257 // printf("sActFileName = %s\n",sActFileName.GetBuffer()); 258 259 sActFileName.SearchAndReplaceAll( "/", "\\" ); 260 261 return pFile; 262 } 263 } 264 // this means the file could not be opened 265 return NULL; 266 } 267 268 /*****************************************************************************/ 269 int WorkOnTokenSet( int nTyp, char *pTokenText ) 270 /*****************************************************************************/ 271 { 272 pParser->Execute( nTyp, pTokenText ); 273 274 return 1; 275 } 276 277 278 /*****************************************************************************/ 279 int SetError() 280 /*****************************************************************************/ 281 { 282 return 1; 283 } 284 285 /*****************************************************************************/ 286 int GetError() 287 /*****************************************************************************/ 288 { 289 return 0; 290 } 291 } 292 293 // 294 // class CfgStackData 295 // 296 297 CfgStackData* CfgStack::Push( const ByteString &rTag, const ByteString &rId ) 298 { 299 CfgStackData *pD = new CfgStackData( rTag, rId ); 300 Insert( pD, LIST_APPEND ); 301 return pD; 302 } 303 304 // 305 // class CfgStack 306 // 307 308 /*****************************************************************************/ 309 CfgStack::~CfgStack() 310 /*****************************************************************************/ 311 { 312 for ( sal_uLong i = 0; i < Count(); i++ ) 313 delete GetObject( i ); 314 } 315 316 /*****************************************************************************/ 317 ByteString CfgStack::GetAccessPath( sal_uLong nPos ) 318 /*****************************************************************************/ 319 { 320 if ( nPos == LIST_APPEND ) 321 nPos = Count() - 1; 322 323 ByteString sReturn; 324 for ( sal_uLong i = 0; i <= nPos; i++ ) { 325 if ( i ) 326 sReturn += "."; 327 sReturn += GetStackData( i )->GetIdentifier(); 328 } 329 330 return sReturn; 331 } 332 333 /*****************************************************************************/ 334 CfgStackData *CfgStack::GetStackData( sal_uLong nPos ) 335 /*****************************************************************************/ 336 { 337 if ( nPos == LIST_APPEND ) 338 nPos = Count() - 1; 339 340 return GetObject( nPos ); 341 } 342 343 // 344 // class CfgParser 345 // 346 347 /*****************************************************************************/ 348 CfgParser::CfgParser() 349 /*****************************************************************************/ 350 : pStackData( NULL ), 351 bLocalize( sal_False ) 352 { 353 } 354 355 /*****************************************************************************/ 356 CfgParser::~CfgParser() 357 /*****************************************************************************/ 358 { 359 } 360 361 362 /*****************************************************************************/ 363 sal_Bool CfgParser::IsTokenClosed( const ByteString &rToken ) 364 /*****************************************************************************/ 365 { 366 return rToken.GetChar( rToken.Len() - 2 ) == '/'; 367 } 368 369 /*****************************************************************************/ 370 void CfgParser::AddText( 371 ByteString &rText, 372 const ByteString &rIsoLang, 373 const ByteString &rResTyp 374 ) 375 /*****************************************************************************/ 376 { 377 sal_uInt16 nTextLen = 0; 378 while ( rText.Len() != nTextLen ) { 379 nTextLen = rText.Len(); 380 rText.SearchAndReplaceAll( "\n", " " ); 381 rText.SearchAndReplaceAll( "\r", " " ); 382 rText.SearchAndReplaceAll( "\t", " " ); 383 rText.SearchAndReplaceAll( " ", " " ); 384 } 385 pStackData->sResTyp = rResTyp; 386 WorkOnText( rText, rIsoLang ); 387 388 pStackData->sText[ rIsoLang ] = rText; 389 } 390 391 392 /*****************************************************************************/ 393 void CfgParser::WorkOnRessourceEnd() 394 /*****************************************************************************/ 395 { 396 } 397 398 /*****************************************************************************/ 399 int CfgParser::ExecuteAnalyzedToken( int nToken, char *pToken ) 400 /*****************************************************************************/ 401 { 402 ByteString sToken( pToken ); 403 404 if ( sToken == " " || sToken == "\t" ) 405 sLastWhitespace += sToken; 406 407 ByteString sTokenName; 408 ByteString sTokenId; 409 410 sal_Bool bOutput = sal_True; 411 412 switch ( nToken ) { 413 case CFG_TOKEN_PACKAGE: 414 case CFG_TOKEN_COMPONENT: 415 case CFG_TOKEN_TEMPLATE: 416 case CFG_TOKEN_CONFIGNAME: 417 case CFG_TOKEN_OORNAME: 418 case CFG_TOKEN_OORVALUE: 419 case CFG_TAG: 420 case ANYTOKEN: 421 case CFG_TEXT_START: 422 { 423 sTokenName = sToken.GetToken( 1, '<' ).GetToken( 0, '>' ).GetToken( 0, ' ' ); 424 425 if ( !IsTokenClosed( sToken )) { 426 ByteString sSearch; 427 switch ( nToken ) { 428 case CFG_TOKEN_PACKAGE: 429 sSearch = "package-id="; 430 break; 431 case CFG_TOKEN_COMPONENT: 432 sSearch = "component-id="; 433 break; 434 case CFG_TOKEN_TEMPLATE: 435 sSearch = "template-id="; 436 break; 437 case CFG_TOKEN_CONFIGNAME: 438 sSearch = "cfg:name="; 439 break; 440 case CFG_TOKEN_OORNAME: 441 sSearch = "oor:name="; 442 bLocalize = sal_True; 443 break; 444 case CFG_TOKEN_OORVALUE: 445 sSearch = "oor:value="; 446 break; 447 case CFG_TEXT_START: { 448 if ( sCurrentResTyp != sTokenName ) { 449 WorkOnRessourceEnd(); 450 ByteString sCur; 451 for( unsigned int n = 0; n < aLanguages.size(); n++ ){ 452 sCur = aLanguages[ n ]; 453 pStackData->sText[ sCur ] = ByteString(""); 454 } 455 } 456 sCurrentResTyp = sTokenName; 457 458 ByteString sTemp = sToken.Copy( sToken.Search( "xml:lang=" )); 459 sCurrentIsoLang = sTemp.GetToken( 1, '\"' ).GetToken( 0, '\"' ); 460 461 if ( sCurrentIsoLang == NO_TRANSLATE_ISO ) 462 bLocalize = sal_False; 463 464 pStackData->sTextTag = sToken; 465 466 sCurrentText = ""; 467 } 468 break; 469 } 470 if ( sSearch.Len()) { 471 ByteString sTemp = sToken.Copy( sToken.Search( sSearch )); 472 sTokenId = sTemp.GetToken( 1, '\"' ).GetToken( 0, '\"' ); 473 } 474 pStackData = aStack.Push( sTokenName, sTokenId ); 475 476 if ( sSearch == "cfg:name=" ) { 477 ByteString sTemp( sToken ); 478 sTemp.ToUpperAscii(); 479 bLocalize = (( sTemp.Search( "CFG:TYPE=\"STRING\"" ) != STRING_NOTFOUND ) && 480 ( sTemp.Search( "CFG:LOCALIZED=\"sal_True\"" ) != STRING_NOTFOUND )); 481 } 482 } 483 else if ( sTokenName == "label" ) { 484 if ( sCurrentResTyp != sTokenName ) { 485 WorkOnRessourceEnd(); 486 ByteString sCur; 487 for( unsigned int n = 0; n < aLanguages.size(); n++ ){ 488 sCur = aLanguages[ n ]; 489 pStackData->sText[ sCur ] = ByteString(""); 490 } 491 } 492 sCurrentResTyp = sTokenName; 493 } 494 } 495 break; 496 case CFG_CLOSETAG: 497 sTokenName = sToken.GetToken( 1, '/' ).GetToken( 0, '>' ).GetToken( 0, ' ' ); 498 if ( aStack.GetStackData() && ( aStack.GetStackData()->GetTagType() == sTokenName )) { 499 if ( ! sCurrentText.Len()) 500 WorkOnRessourceEnd(); 501 aStack.Pop(); 502 pStackData = aStack.GetStackData(); 503 } 504 else { 505 ByteString sError( "Missplaced close tag: " ); 506 ByteString sInFile(" in file "); 507 sError += sToken; 508 sError += sInFile; 509 sError += sFullEntry; 510 Error( sError ); 511 exit ( 13 ); 512 } 513 break; 514 515 case CFG_TEXTCHAR: 516 sCurrentText += sToken; 517 bOutput = sal_False; 518 break; 519 520 case CFG_TOKEN_NO_TRANSLATE: 521 bLocalize = sal_False; 522 break; 523 } 524 525 if ( sCurrentText.Len() && nToken != CFG_TEXTCHAR ) { 526 AddText( sCurrentText, sCurrentIsoLang, sCurrentResTyp ); 527 Output( sCurrentText ); 528 sCurrentText = ""; 529 pStackData->sEndTextTag = sToken; 530 } 531 532 if ( bOutput ) 533 Output( sToken ); 534 535 if ( sToken != " " && sToken != "\t" ) 536 sLastWhitespace = ""; 537 538 return 1; 539 } 540 541 /*****************************************************************************/ 542 void CfgExport::Output( const ByteString& rOutput ) 543 /*****************************************************************************/ 544 { 545 // Dummy operation to suppress warnings caused by poor class design 546 ByteString a( rOutput ); 547 } 548 549 /*****************************************************************************/ 550 int CfgParser::Execute( int nToken, char * pToken ) 551 /*****************************************************************************/ 552 { 553 ByteString sToken( pToken ); 554 555 switch ( nToken ) { 556 case CFG_TAG: 557 if ( sToken.Search( "package-id=" ) != STRING_NOTFOUND ) 558 return ExecuteAnalyzedToken( CFG_TOKEN_PACKAGE, pToken ); 559 else if ( sToken.Search( "component-id=" ) != STRING_NOTFOUND ) 560 return ExecuteAnalyzedToken( CFG_TOKEN_COMPONENT, pToken ); 561 else if ( sToken.Search( "template-id=" ) != STRING_NOTFOUND ) 562 return ExecuteAnalyzedToken( CFG_TOKEN_TEMPLATE, pToken ); 563 else if ( sToken.Search( "cfg:name=" ) != STRING_NOTFOUND ) 564 return ExecuteAnalyzedToken( CFG_TOKEN_OORNAME, pToken ); 565 else if ( sToken.Search( "oor:name=" ) != STRING_NOTFOUND ) 566 return ExecuteAnalyzedToken( CFG_TOKEN_OORNAME, pToken ); 567 else if ( sToken.Search( "oor:value=" ) != STRING_NOTFOUND ) 568 return ExecuteAnalyzedToken( CFG_TOKEN_OORVALUE, pToken ); 569 break; 570 } 571 return ExecuteAnalyzedToken( nToken, pToken ); 572 } 573 574 575 /*****************************************************************************/ 576 void CfgParser::Error( const ByteString &rError ) 577 /*****************************************************************************/ 578 { 579 // ByteString sError( rError ); 580 // sError.Append("Error: In file "); 581 // sError.Append( sActFileName ); 582 yyerror(( char * ) rError.GetBuffer()); 583 } 584 585 586 // 587 // class CfgOutputParser 588 // 589 590 /*****************************************************************************/ 591 CfgOutputParser::CfgOutputParser( const ByteString &rOutputFile ) 592 /*****************************************************************************/ 593 { 594 pOutputStream = 595 new SvFileStream( 596 String( rOutputFile, RTL_TEXTENCODING_ASCII_US ), 597 STREAM_STD_WRITE | STREAM_TRUNC 598 ); 599 pOutputStream->SetStreamCharSet( RTL_TEXTENCODING_UTF8 ); 600 601 if ( !pOutputStream->IsOpen()) { 602 ByteString sError( "ERROR: Unable to open output file: " ); 603 sError += rOutputFile; 604 Error( sError ); 605 delete pOutputStream; 606 pOutputStream = NULL; 607 exit( -13 ); 608 } 609 } 610 611 /*****************************************************************************/ 612 CfgOutputParser::~CfgOutputParser() 613 /*****************************************************************************/ 614 { 615 if ( pOutputStream ) { 616 pOutputStream->Close(); 617 delete pOutputStream; 618 } 619 } 620 621 // 622 // class CfgExport 623 // 624 625 /*****************************************************************************/ 626 CfgExport::CfgExport( 627 const ByteString &rOutputFile, 628 const ByteString &rProject, 629 const ByteString &rFilePath 630 ) 631 /*****************************************************************************/ 632 : CfgOutputParser( rOutputFile ), 633 sPrj( rProject ), 634 sPath( rFilePath ) 635 { 636 Export::InitLanguages( false ); 637 aLanguages = Export::GetLanguages(); 638 } 639 640 /*****************************************************************************/ 641 CfgExport::~CfgExport() 642 /*****************************************************************************/ 643 { 644 } 645 646 /*****************************************************************************/ 647 void CfgExport::WorkOnRessourceEnd() 648 /*****************************************************************************/ 649 { 650 if ( pOutputStream && bLocalize ) { 651 if (( pStackData->sText[ ByteString("en-US") ].Len() 652 ) || 653 ( bForce && 654 ( pStackData->sText[ ByteString("de") ].Len() || 655 pStackData->sText[ ByteString("en-US") ].Len() ))) 656 { 657 ByteString sFallback = pStackData->sText[ ByteString("en-US") ]; 658 659 //if ( pStackData->sText[ ByteString("en-US") ].Len()) 660 // sFallback = pStackData->sText[ ByteString("en-US") ]; 661 662 ByteString sLocalId = pStackData->sIdentifier; 663 ByteString sGroupId; 664 if ( aStack.Count() == 1 ) { 665 sGroupId = sLocalId; 666 sLocalId = ""; 667 } 668 else { 669 sGroupId = aStack.GetAccessPath( aStack.Count() - 2 ); 670 } 671 672 ByteString sTimeStamp( Export::GetTimeStamp()); 673 674 ByteString sCur; 675 for( unsigned int n = 0; n < aLanguages.size(); n++ ){ 676 sCur = aLanguages[ n ]; 677 678 ByteString sText = pStackData->sText[ sCur ]; 679 if ( !sText.Len()) 680 sText = sFallback; 681 682 Export::UnquotHTML( sText ); 683 684 ByteString sOutput( sPrj ); sOutput += "\t"; 685 sOutput += sPath; 686 sOutput += "\t0\t"; 687 sOutput += pStackData->sResTyp; sOutput += "\t"; 688 sOutput += sGroupId; sOutput += "\t"; 689 sOutput += sLocalId; sOutput += "\t\t\t0\t"; 690 sOutput += sCur; 691 sOutput += "\t"; 692 693 sOutput += sText; sOutput += "\t\t\t\t"; 694 sOutput += sTimeStamp; 695 696 //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( sPrj ) ) ) 697 pOutputStream->WriteLine( sOutput ); 698 } 699 } 700 } 701 } 702 703 /*****************************************************************************/ 704 void CfgExport::WorkOnText( 705 ByteString &rText, 706 const ByteString &rIsoLang 707 ) 708 /*****************************************************************************/ 709 { 710 if( rIsoLang.Len() ) Export::UnquotHTML( rText ); 711 } 712 713 714 // 715 // class CfgMerge 716 // 717 718 /*****************************************************************************/ 719 CfgMerge::CfgMerge( 720 const ByteString &rMergeSource, const ByteString &rOutputFile, 721 ByteString &rFilename ) 722 /*****************************************************************************/ 723 : CfgOutputParser( rOutputFile ), 724 pMergeDataFile( NULL ), 725 pResData( NULL ), 726 bGerman( sal_False ), 727 sFilename( rFilename ), 728 bEnglish( sal_False ) 729 { 730 if ( rMergeSource.Len()){ 731 pMergeDataFile = new MergeDataFile( 732 rMergeSource, sInputFileName , bErrorLog, RTL_TEXTENCODING_MS_1252, true ); 733 if( Export::sLanguages.EqualsIgnoreCaseAscii("ALL") ){ 734 Export::SetLanguages( pMergeDataFile->GetLanguages() ); 735 aLanguages = pMergeDataFile->GetLanguages(); 736 } 737 else aLanguages = Export::GetLanguages(); 738 }else 739 aLanguages = Export::GetLanguages(); 740 } 741 742 /*****************************************************************************/ 743 CfgMerge::~CfgMerge() 744 /*****************************************************************************/ 745 { 746 delete pMergeDataFile; 747 delete pResData; 748 } 749 750 /*****************************************************************************/ 751 void CfgMerge::WorkOnText( 752 ByteString &rText, 753 const ByteString& nLangIndex 754 ) 755 /*****************************************************************************/ 756 { 757 758 if ( pMergeDataFile && bLocalize ) { 759 if ( !pResData ) { 760 ByteString sLocalId = pStackData->sIdentifier; 761 ByteString sGroupId; 762 if ( aStack.Count() == 1 ) { 763 sGroupId = sLocalId; 764 sLocalId = ""; 765 } 766 else { 767 sGroupId = aStack.GetAccessPath( aStack.Count() - 2 ); 768 } 769 770 ByteString sPlatform( "" ); 771 772 pResData = new ResData( sPlatform, sGroupId , sFilename ); 773 pResData->sId = sLocalId; 774 pResData->sResTyp = pStackData->sResTyp; 775 } 776 777 //if ( nLangIndex.EqualsIgnoreCaseAscii("de") ) 778 // bGerman = sal_True; 779 if (( nLangIndex.EqualsIgnoreCaseAscii("en-US") )) 780 bEnglish = sal_True; 781 782 PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrysCaseSensitive( pResData ); 783 if ( pEntrys ) { 784 ByteString sContent; 785 pEntrys->GetText( sContent, STRING_TYP_TEXT, nLangIndex ); 786 787 if ( Export::isAllowed( nLangIndex ) && 788 ( sContent != "-" ) && ( sContent.Len())) 789 { 790 #ifdef MERGE_SOURCE_LANGUAGES 791 if( nLangIndex.EqualsIgnoreCaseAscii("de") || nLangIndex.EqualsIgnoreCaseAscii("en-US") ) 792 rText = sContent; 793 #endif 794 Export::QuotHTML( rText ); 795 } 796 } 797 } 798 } 799 800 /*****************************************************************************/ 801 void CfgMerge::Output( const ByteString& rOutput ) 802 /*****************************************************************************/ 803 { 804 if ( pOutputStream ) 805 pOutputStream->Write( rOutput.GetBuffer(), rOutput.Len()); 806 } 807 808 sal_uLong CfgStack::Push( CfgStackData *pStackData ) 809 { 810 Insert( pStackData, LIST_APPEND ); 811 return Count() - 1; 812 } 813 814 /*****************************************************************************/ 815 void CfgMerge::WorkOnRessourceEnd() 816 /*****************************************************************************/ 817 { 818 819 if ( pMergeDataFile && pResData && bLocalize && (( bEnglish ) || bForce )) { 820 PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrysCaseSensitive( pResData ); 821 if ( pEntrys ) { 822 ByteString sCur; 823 824 for( unsigned int n = 0; n < aLanguages.size(); n++ ){ 825 sCur = aLanguages[ n ]; 826 827 ByteString sContent; 828 pEntrys->GetText( sContent, STRING_TYP_TEXT, sCur , sal_True ); 829 if ( 830 // (!sCur.EqualsIgnoreCaseAscii("de") ) && 831 ( !sCur.EqualsIgnoreCaseAscii("en-US") ) && 832 833 ( sContent != "-" ) && ( sContent.Len())) 834 { 835 836 ByteString sText = sContent; 837 Export::QuotHTML( sText ); 838 839 ByteString sAdditionalLine( "\t" ); 840 841 ByteString sTextTag = pStackData->sTextTag; 842 ByteString sTemp = sTextTag.Copy( sTextTag.Search( "xml:lang=" )); 843 844 ByteString sSearch = sTemp.GetToken( 0, '\"' ); 845 sSearch += "\""; 846 sSearch += sTemp.GetToken( 1, '\"' ); 847 sSearch += "\""; 848 849 ByteString sReplace = sTemp.GetToken( 0, '\"' ); 850 sReplace += "\""; 851 sReplace += sCur; 852 sReplace += "\""; 853 854 sTextTag.SearchAndReplace( sSearch, sReplace ); 855 856 sAdditionalLine += sTextTag; 857 sAdditionalLine += sText; 858 sAdditionalLine += pStackData->sEndTextTag; 859 860 sAdditionalLine += "\n"; 861 sAdditionalLine += sLastWhitespace; 862 863 Output( sAdditionalLine ); 864 } 865 } 866 } 867 } 868 delete pResData; 869 pResData = NULL; 870 bGerman = sal_False; 871 bEnglish = sal_False; 872 } 873