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/fsys.hxx> 32 #include "export.hxx" 33 #include "utf8conv.hxx" 34 #include <iostream> 35 36 using namespace std; 37 38 namespace 39 { 40 static ::rtl::OString lcl_NormalizeFilename(const ::rtl::OString& rFilename) 41 { 42 return rFilename.copy( 43 ::std::max( 44 rFilename.lastIndexOf( "\\" ), 45 rFilename.lastIndexOf( "/" ))+1); 46 }; 47 } 48 49 extern void ConvertHalfwitdhToFullwidth( String& rString ); 50 51 // 52 // class PFormEntrys 53 // 54 55 ByteString PFormEntrys::Dump() 56 { 57 ByteString sRet( "PFormEntrys\n" ); 58 ByteString a("sText"); 59 if(sText.size()) 60 Export::DumpMap(a , sText); 61 return sRet; 62 } 63 64 sal_Bool PFormEntrys::GetTransex3Text( ByteString &rReturn, 65 sal_uInt16 nTyp, const ByteString &nLangIndex, sal_Bool bDel ) 66 { 67 sal_Bool rc = GetText( rReturn , nTyp , nLangIndex , bDel ); 68 ByteString test( rReturn ); 69 for( sal_uInt16 idx = 0; idx < rReturn.Len(); idx++ ) 70 { 71 if( rReturn.GetChar( idx ) == '\"' && ( idx >= 1 ) && rReturn.GetChar( idx-1 ) == '\\' ) 72 { 73 rReturn.Erase( idx-1 , 1 ); 74 } 75 } 76 //if( !rReturn.Equals( test ) ) 77 // printf("*CHANGED******************\n%s\n%s\n",test.GetBuffer(),rReturn.GetBuffer()); 78 return rc; 79 } 80 /*****************************************************************************/ 81 sal_Bool PFormEntrys::GetText( ByteString &rReturn, 82 sal_uInt16 nTyp, const ByteString &nLangIndex, sal_Bool bDel ) 83 { 84 85 sal_Bool bReturn=sal_True; 86 switch ( nTyp ) { 87 case STRING_TYP_TEXT : 88 rReturn = sText[ nLangIndex ]; 89 if ( bDel ) 90 sText[ nLangIndex ] = ""; 91 bReturn = bTextFirst[ nLangIndex ]; 92 bTextFirst[ nLangIndex ] = sal_False; 93 break; 94 case STRING_TYP_HELPTEXT : 95 rReturn = sHelpText; 96 break; 97 case STRING_TYP_QUICKHELPTEXT : 98 rReturn = sQuickHelpText[ nLangIndex ]; 99 if ( bDel ) 100 sQuickHelpText[ nLangIndex ] = ""; 101 bReturn = bQuickHelpTextFirst[ nLangIndex ]; 102 bQuickHelpTextFirst[ nLangIndex ] = sal_False; 103 break; 104 case STRING_TYP_TITLE : 105 rReturn = sTitle[ nLangIndex ]; 106 if ( bDel ) 107 sTitle[ nLangIndex ] = ""; 108 bReturn = bTitleFirst[ nLangIndex ]; 109 bTitleFirst[ nLangIndex ] = sal_False; 110 break; 111 } 112 return bReturn; 113 } 114 115 116 // 117 // class MergeData 118 // 119 120 MergeData::~MergeData() 121 { 122 } 123 124 PFormEntrys* MergeData::GetPFormEntrys(ResData*) 125 { 126 if( aMap.find( ByteString("HACK") ) != aMap.end() ) 127 return aMap[ ByteString("HACK") ]; 128 return NULL; 129 } 130 131 void MergeData::Insert(const ByteString&, PFormEntrys* pfEntrys ) 132 { 133 aMap.insert( PFormEntrysHashMap::value_type( ByteString("HACK") , pfEntrys ) ); 134 } 135 136 ByteString MergeData::Dump(){ 137 ByteString sRet( "MergeData\n" ); 138 139 printf("MergeData sTyp = %s , sGid = %s , sLid =%s , sFilename = %s\n",sTyp.GetBuffer(),sGID.GetBuffer(),sLID.GetBuffer(), sFilename.GetBuffer() ); 140 141 PFormEntrysHashMap::const_iterator idbg; 142 for( idbg = aMap.begin() ; idbg != aMap.end(); ++idbg ) 143 { 144 printf("aMap[ %s ] = " ,idbg->first.GetBuffer()); 145 ( (PFormEntrys*)(idbg->second) )->Dump(); 146 printf("\n"); 147 } 148 printf("\n"); 149 return sRet; 150 } 151 152 PFormEntrys* MergeData::GetPFObject( const ByteString& rPFO ){ 153 if( aMap.find( ByteString("HACK") ) != aMap.end() ) 154 return aMap[ rPFO ]; 155 return NULL; 156 } 157 158 159 PFormEntrys *MergeData::InsertEntry( const ByteString &rPForm ) 160 { 161 PFormEntrys* pFEntrys = new PFormEntrys( rPForm ); 162 aMap.insert( PFormEntrysHashMap::value_type( rPForm , pFEntrys ) ); 163 return pFEntrys; 164 } 165 166 sal_Bool MergeData::operator==( ResData *pData ) 167 { 168 ByteString sResTyp_upper( pData->sResTyp ); 169 sResTyp_upper.ToUpperAscii(); 170 ByteString sTyp_upper( sTyp ); 171 sTyp_upper.ToUpperAscii(); 172 173 return (( pData->sId == sLID ) && 174 ( pData->sGId == sGID ) && 175 ( sResTyp_upper == sTyp_upper ) 176 ); 177 } 178 179 // 180 // class MergeDataFile 181 // 182 183 #define FFORMAT_UNKNOWN 0x0000 184 #define FFORMAT_NEW 0x0001 185 #define FFORMAT_OLD 0x0002 186 187 188 MergeDataFile::MergeDataFile( 189 const ByteString &rFileName, 190 const ByteString& sFile, 191 sal_Bool bErrLog, 192 CharSet aCharSet, 193 bool bCaseSensitive) 194 : bErrorLog( bErrLog ) 195 { 196 SvFileStream aInputStream( String( rFileName, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_READ ); 197 aInputStream.SetStreamCharSet( aCharSet ); 198 ByteString sLine; 199 const ByteString sHACK("HACK"); 200 const ::rtl::OString sFileNormalized(lcl_NormalizeFilename(sFile)); 201 const bool isFileEmpty = sFileNormalized.getLength(); 202 203 if( !aInputStream.IsOpen() ) 204 { 205 printf("Warning : Can't open %s\n", rFileName.GetBuffer()); 206 return; 207 } 208 while ( !aInputStream.IsEof()) 209 { 210 xub_StrLen nToks; 211 aInputStream.ReadLine( sLine ); 212 sLine = sLine.Convert( RTL_TEXTENCODING_MS_1252, aCharSet ); 213 214 nToks = sLine.GetTokenCount( '\t' ); 215 if ( nToks == 15 ) 216 { 217 // Skip all wrong filenames 218 const ::rtl::OString filename = lcl_NormalizeFilename(sLine.GetToken( 1 , '\t' )); 219 if(isFileEmpty || sFileNormalized.equals("") || (!isFileEmpty && filename.equals(sFileNormalized)) ) 220 { 221 xub_StrLen rIdx = 0; 222 const ByteString sTYP = sLine.GetToken( 3, '\t', rIdx ); 223 const ByteString sGID = sLine.GetToken( 0, '\t', rIdx ); // 4 224 const ByteString sLID = sLine.GetToken( 0, '\t', rIdx ); // 5 225 ByteString sPFO = sLine.GetToken( 1, '\t', rIdx ); // 7 226 sPFO = sHACK; 227 ByteString nLANG = sLine.GetToken( 1, '\t', rIdx ); // 9 228 nLANG.EraseLeadingAndTrailingChars(); 229 const ByteString sTEXT = sLine.GetToken( 0, '\t', rIdx ); // 10 230 const ByteString sQHTEXT = sLine.GetToken( 1, '\t', rIdx ); // 12 231 const ByteString sTITLE = sLine.GetToken( 0, '\t', rIdx ); // 13 232 233 234 #ifdef MERGE_SOURCE_LANGUAGES 235 if( true ) 236 #else 237 if( !nLANG.EqualsIgnoreCaseAscii("en-US") ) 238 #endif 239 { 240 aLanguageSet.insert(nLANG); 241 InsertEntry( sTYP, sGID, sLID, sPFO, nLANG, sTEXT, sQHTEXT, sTITLE, filename, bCaseSensitive ); 242 } 243 } 244 } 245 else if ( nToks == 10 ) 246 { 247 printf("ERROR: File format is obsolete and no longer supported!\n"); 248 } 249 } 250 aInputStream.Close(); 251 } 252 253 MergeDataFile::~MergeDataFile() 254 { 255 } 256 257 ByteString MergeDataFile::Dump(){ 258 ByteString sRet( "MergeDataFile\n" ); 259 260 printf("MergeDataFile\n"); 261 MergeDataHashMap::const_iterator idbg; 262 for( idbg = aMap.begin() ; idbg != aMap.end(); ++idbg ) 263 { 264 printf("aMap[ %s ] = ",idbg->first.GetBuffer()); 265 ((MergeData*) (idbg->second))->Dump(); 266 printf("\n"); 267 } 268 printf("\n"); 269 return sRet; 270 } 271 272 void MergeDataFile::WriteError( const ByteString &rLine ) 273 { 274 if ( bErrorLog ) 275 { 276 if ( !aErrLog.IsOpen()) 277 aErrLog.Open( String( sErrorLog, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_WRITE | STREAM_TRUNC ); 278 aErrLog.WriteLine( rLine ); 279 } 280 else 281 fprintf( stderr, "%s\n", rLine.GetBuffer()); 282 } 283 284 std::vector<ByteString> MergeDataFile::GetLanguages(){ 285 return std::vector<ByteString>(aLanguageSet.begin(),aLanguageSet.end()); 286 } 287 288 MergeData *MergeDataFile::GetMergeData( ResData *pResData , bool bCaseSensitive ) 289 { 290 ByteString sOldG = pResData->sGId; 291 ByteString sOldL = pResData->sId; 292 ByteString sGID = pResData->sGId; 293 ByteString sLID; 294 if(!sGID.Len()) 295 sGID = pResData->sId; 296 else 297 sLID = pResData->sId; 298 pResData->sGId = sGID; 299 pResData->sId = sLID; 300 301 ByteString sKey = CreateKey( pResData->sResTyp , pResData->sGId , pResData->sId , pResData->sFilename , bCaseSensitive ); 302 303 if(aMap.find( sKey ) != aMap.end()) 304 { 305 pResData->sGId = sOldG; 306 pResData->sId = sOldL; 307 return aMap[ sKey ]; 308 } 309 pResData->sGId = sOldG; 310 pResData->sId = sOldL; 311 return NULL; 312 } 313 314 315 PFormEntrys *MergeDataFile::GetPFormEntrys( ResData *pResData ) 316 { 317 // search for requested PFormEntrys 318 MergeData *pData = GetMergeData( pResData ); 319 if ( pData ) 320 return pData->GetPFormEntrys( pResData ); 321 return NULL; 322 } 323 324 PFormEntrys *MergeDataFile::GetPFormEntrysCaseSensitive( ResData *pResData ) 325 { 326 // search for requested PFormEntrys 327 MergeData *pData = GetMergeData( pResData , true ); 328 if ( pData ) 329 return pData->GetPFormEntrys( pResData ); 330 return NULL; 331 } 332 333 void MergeDataFile::InsertEntry( 334 const ByteString &rTYP, const ByteString &rGID, 335 const ByteString &rLID, const ByteString &rPFO, 336 const ByteString &nLANG, const ByteString &rTEXT, 337 const ByteString &rQHTEXT, const ByteString &rTITLE , 338 const ByteString &rInFilename , bool bCaseSensitive 339 ) 340 { 341 MergeData *pData; 342 343 // search for MergeData 344 ByteString sKey = CreateKey( rTYP , rGID , rLID , rInFilename , bCaseSensitive ); 345 MergeDataHashMap::const_iterator mit; 346 mit = aMap.find( sKey ); 347 if( mit != aMap.end() ) 348 { 349 pData = mit->second; 350 } 351 else 352 { 353 pData = new MergeData( rTYP, rGID, rLID, rInFilename ); 354 aMap.insert( MergeDataHashMap::value_type( sKey, pData ) ); 355 } 356 357 PFormEntrys *pFEntrys = 0; 358 359 // search for PFormEntrys 360 pFEntrys = pData->GetPFObject( rPFO ); 361 if( !pFEntrys ) 362 { 363 // create new PFormEntrys, cause no one exists with current properties 364 pFEntrys = new PFormEntrys( rPFO ); 365 pData->Insert( rPFO , pFEntrys ); 366 } 367 368 // finaly insert the cur string 369 pFEntrys->InsertEntry( nLANG , rTEXT, rQHTEXT, rTITLE ); 370 } 371 372 ByteString MergeDataFile::CreateKey( const ByteString& rTYP , const ByteString& rGID , const ByteString& rLID , const ByteString& rFilename , bool bCaseSensitive ) 373 { 374 static const ::rtl::OString sStroke('-'); 375 ::rtl::OString sKey( rTYP ); 376 sKey += sStroke; 377 sKey += rGID; 378 sKey += sStroke; 379 sKey += rLID; 380 sKey += sStroke; 381 sKey += lcl_NormalizeFilename(rFilename); 382 OSL_TRACE("created key: %s", sKey.getStr()); 383 if(bCaseSensitive) 384 return sKey; // officecfg case sensitive identifier 385 return sKey.toAsciiUpperCase(); 386 } 387