1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
32 static OString
lcl_NormalizeFilename(const OString
& rFilename
)
34 return rFilename
.copy(
36 rFilename
.lastIndexOf( '\\' ),
37 rFilename
.lastIndexOf( '/' ))+1);
40 static bool lcl_ReadPoChecked(
41 PoEntry
& o_rPoEntry
, PoIfstream
& rPoFile
,
42 const OString
& rFileName
)
46 rPoFile
.readEntry( o_rPoEntry
);
48 catch( PoIfstream::Exception
& aException
)
50 if( aException
== PoIfstream::INVALIDENTRY
)
53 "Warning : %s contains invalid entry\n",
66 ResData::ResData( const OString
&rGId
)
68 nIdLevel( ID_LEVEL_NULL
),
70 bChildWithText( sal_False
),
72 bHelpText( sal_False
),
73 bQuickHelpText( sal_False
),
84 sGId
= sGId
.replaceAll("\r", OString());
87 ResData::ResData( const OString
&rGId
, const OString
&rFilename
)
89 nIdLevel( ID_LEVEL_NULL
),
91 bChildWithText( sal_False
),
93 bHelpText( sal_False
),
94 bQuickHelpText( sal_False
),
98 sFilename( rFilename
),
106 sGId
= sGId
.replaceAll("\r", OString());
113 // delete existing res. of type StringList
114 for ( size_t i
= 0; i
< pStringList
->size(); i
++ ) {
115 ExportListEntry
* test
= (*pStringList
)[ i
];
116 if( test
!= NULL
) delete test
;
121 // delete existing res. of type FilterList
122 for ( size_t i
= 0; i
< pFilterList
->size(); i
++ ) {
123 ExportListEntry
* test
= (*pFilterList
)[ i
];
129 // delete existing res. of type ItemList
130 for ( size_t i
= 0; i
< pItemList
->size(); i
++ ) {
131 ExportListEntry
* test
= (*pItemList
)[ i
];
137 // delete existing res. of type UIEntries
138 for ( size_t i
= 0; i
< pUIEntries
->size(); i
++ ) {
139 ExportListEntry
* test
= (*pUIEntries
)[ i
];
150 sal_Bool
MergeEntrys::GetText( OString
&rReturn
,
151 sal_uInt16 nTyp
, const OString
&nLangIndex
, sal_Bool bDel
)
154 sal_Bool bReturn
=sal_True
;
156 case STRING_TYP_TEXT
:
157 rReturn
= sText
[ nLangIndex
];
159 sText
[ nLangIndex
] = "";
160 bReturn
= bTextFirst
[ nLangIndex
];
161 bTextFirst
[ nLangIndex
] = sal_False
;
163 case STRING_TYP_QUICKHELPTEXT
:
164 rReturn
= sQuickHelpText
[ nLangIndex
];
166 sQuickHelpText
[ nLangIndex
] = "";
167 bReturn
= bQuickHelpTextFirst
[ nLangIndex
];
168 bQuickHelpTextFirst
[ nLangIndex
] = sal_False
;
170 case STRING_TYP_TITLE
:
171 rReturn
= sTitle
[ nLangIndex
];
173 sTitle
[ nLangIndex
] = "";
174 bReturn
= bTitleFirst
[ nLangIndex
];
175 bTitleFirst
[ nLangIndex
] = sal_False
;
182 OString
MergeEntrys::GetQTZText(const ResData
& rResData
, const OString
& rOrigText
)
184 const OString sFilename
= rResData
.sFilename
.copy(rResData
.sFilename
.lastIndexOf("/")+1);
186 PoEntry::genKeyId(sFilename
+ rResData
.sGId
+ rResData
.sId
+ rResData
.sResTyp
+ rOrigText
);
187 return sKey
+ "||" + rOrigText
;
191 // class MergeDataHashMap
194 std::pair
<MergeDataHashMap::iterator
,bool> MergeDataHashMap::insert(const OString
& rKey
, MergeData
* pMergeData
)
196 std::pair
<iterator
,bool> aTemp
= m_aHashMap
.insert(HashMap_t::value_type( rKey
, pMergeData
));
197 if( m_aHashMap
.size() == 1 )
199 // When first insert, set an iterator to the first element
200 aFirstInOrder
= aTemp
.first
;
204 // Define insertion order by setting an iterator to the next element.
205 aLastInsertion
->second
->m_aNextData
= aTemp
.first
;
207 aLastInsertion
= aTemp
.first
;
211 MergeDataHashMap::iterator
MergeDataHashMap::find(const OString
& rKey
)
213 iterator aHint
= m_aHashMap
.end();
216 if( bFirstSearch
&& !m_aHashMap
.empty() )
218 aHint
= aFirstInOrder
;
220 else if( aLastFound
== aLastInsertion
)
222 // Next to the last element is the first element
223 aHint
= aFirstInOrder
;
225 else if( aLastFound
!= m_aHashMap
.end() && aLastFound
!= aLastInsertion
)
227 aHint
= aLastFound
->second
->m_aNextData
;
230 // If hint works than no need for search
231 if( aHint
!= m_aHashMap
.end() && aHint
->first
== rKey
)
237 aLastFound
= m_aHashMap
.find(rKey
);
240 bFirstSearch
= false;
248 MergeData::MergeData(
249 const OString
&rTyp
, const OString
&rGID
,
250 const OString
&rLID
, const OString
&rFilename
)
254 sFilename( rFilename
),
255 pMergeEntrys( new MergeEntrys() )
259 MergeData::~MergeData()
264 MergeEntrys
* MergeData::GetMergeEntries()
269 sal_Bool
MergeData::operator==( ResData
*pData
)
271 return pData
->sId
== sLID
&& pData
->sGId
== sGID
272 && pData
->sResTyp
.equalsIgnoreAsciiCase(sTyp
);
276 // class MergeDataFile
279 MergeDataFile::MergeDataFile(
280 const OString
&rFileName
, const OString
&rFile
,
281 bool bCaseSensitive
, bool bWithQtz
)
283 std::ifstream
aInputStream( rFileName
.getStr() );
284 if ( !aInputStream
.is_open() )
286 printf("Warning : Can't open po path container file\n");
290 aInputStream
>> sPoFile
;
291 bool bFirstLang
= true;
292 while( !aInputStream
.eof() )
294 bool bSkipCurrentPOFile
= false;
295 const OString
sFileName( lcl_NormalizeFilename(rFile
) );
296 const bool bReadAll
= sFileName
.isEmpty();
297 const OString
sPoFileName(sPoFile
.data(), sPoFile
.length());
299 aPoInput
.open( sPoFileName
);
300 if ( !aPoInput
.isOpen() )
302 printf( "Warning : Can't open %s\n", sPoFileName
.getStr() );
307 //Get language id from path
309 const OString
sTransSource("translations/source/");
310 const sal_Int32 nStart
=
311 sPoFileName
.indexOf(sTransSource
)+sTransSource
.getLength();
312 const sal_Int32 nCount
=
313 sPoFileName
.indexOf("/",nStart
) - nStart
;
314 sLang
= sPoFileName
.copy(nStart
,nCount
);
316 aLanguageSet
.insert( sLang
);
320 if( !lcl_ReadPoChecked(aNextPo
, aPoInput
, sPoFileName
) )
322 bSkipCurrentPOFile
= true;
325 } while( !aPoInput
.eof() && aNextPo
.getSourceFile() != sFileName
&& !bReadAll
);
326 while( !aPoInput
.eof() && (aNextPo
.getSourceFile() == sFileName
|| bReadAll
) && !bSkipCurrentPOFile
)
328 PoEntry
aActPo( aNextPo
);
330 bool bInSameComp
= false;
341 OString sTemp
= aActPo
.getMsgStr();
342 if( aActPo
.isFuzzy() || sTemp
.isEmpty() )
343 sTemp
= aActPo
.getMsgId();
344 switch( aActPo
.getType() )
348 sExText
= aActPo
.getMsgId();
350 case PoEntry::TQUICKHELPTEXT
:
352 sExQHText
= aActPo
.getMsgId();
354 case PoEntry::TTITLE
:
356 sExTitle
= aActPo
.getMsgId();
359 if( !lcl_ReadPoChecked(aNextPo
, aPoInput
, sPoFileName
) )
361 bSkipCurrentPOFile
= true;
364 } while( !aPoInput
.eof() &&
365 ( bInSameComp
= PoEntry::IsInSameComp(aActPo
, aNextPo
) ) );
368 aActPo
.getResourceType(), aActPo
.getGroupId(),
369 aActPo
.getLocalId(), sLang
, sText
,
370 sQHText
, sTitle
, aActPo
.getSourceFile(),
371 bFirstLang
, bCaseSensitive
);
373 if( bFirstLang
&& bWithQtz
&&
374 ( strcmp(getenv("ENABLE_RELEASE_BUILD"),"TRUE") ) )
376 aLanguageSet
.insert("qtz");
378 aActPo
.getResourceType(), aActPo
.getGroupId(),
379 aActPo
.getLocalId(), "qtz",
381 sExTitle
, aActPo
.getSourceFile(),
382 false, bCaseSensitive
);
386 aInputStream
>> sPoFile
;
389 aInputStream
.close();
392 MergeDataFile::~MergeDataFile()
394 for (MergeDataHashMap::iterator aI
= aMap
.begin(), aEnd
= aMap
.end(); aI
!= aEnd
; ++aI
)
398 std::vector
<OString
> MergeDataFile::GetLanguages() const
400 return std::vector
<OString
>(aLanguageSet
.begin(),aLanguageSet
.end());
403 MergeData
*MergeDataFile::GetMergeData( ResData
*pResData
, bool bCaseSensitive
)
405 OString sOldG
= pResData
->sGId
;
406 OString sOldL
= pResData
->sId
;
407 OString sGID
= pResData
->sGId
;
410 sGID
= pResData
->sId
;
412 sLID
= pResData
->sId
;
413 pResData
->sGId
= sGID
;
414 pResData
->sId
= sLID
;
416 OString sKey
= CreateKey( pResData
->sResTyp
, pResData
->sGId
, pResData
->sId
, pResData
->sFilename
, bCaseSensitive
);
418 MergeDataHashMap::const_iterator mit
= aMap
.find( sKey
);
419 if(mit
!= aMap
.end())
421 pResData
->sGId
= sOldG
;
422 pResData
->sId
= sOldL
;
425 pResData
->sGId
= sOldG
;
426 pResData
->sId
= sOldL
;
430 MergeEntrys
*MergeDataFile::GetMergeEntrys( ResData
*pResData
)
432 // search for requested MergeEntrys
433 MergeData
*pData
= GetMergeData( pResData
);
435 return pData
->GetMergeEntries();
439 MergeEntrys
*MergeDataFile::GetMergeEntrysCaseSensitive( ResData
*pResData
)
441 // search for requested MergeEntrys
442 MergeData
*pData
= GetMergeData( pResData
, true );
444 return pData
->GetMergeEntries();
448 void MergeDataFile::InsertEntry(
449 const OString
&rTYP
, const OString
&rGID
,
450 const OString
&rLID
, const OString
&nLANG
,
451 const OString
&rTEXT
, const OString
&rQHTEXT
,
452 const OString
&rTITLE
, const OString
&rInFilename
,
453 bool bFirstLang
, bool bCaseSensitive
)
455 MergeData
*pData
= 0;
457 // search for MergeData
458 OString sKey
= CreateKey(rTYP
, rGID
, rLID
, rInFilename
, bCaseSensitive
);
462 MergeDataHashMap::const_iterator mit
= aMap
.find( sKey
);
463 if(mit
!= aMap
.end())
470 pData
= new MergeData( rTYP
, rGID
, rLID
, rInFilename
);
471 aMap
.insert( sKey
, pData
);
475 // insert the cur string
476 MergeEntrys
*pMergeEntrys
= pData
->GetMergeEntries();
479 const OString sTemp
= rInFilename
+ rGID
+ rLID
+ rTYP
;
480 pMergeEntrys
->InsertEntry(
482 rTEXT
.isEmpty()? rTEXT
: PoEntry::genKeyId(sTemp
+ rTEXT
) + "||" + rTEXT
,
483 rQHTEXT
.isEmpty()? rQHTEXT
: PoEntry::genKeyId(sTemp
+ rQHTEXT
) + "||" + rQHTEXT
,
484 rTITLE
.isEmpty()? rTITLE
: PoEntry::genKeyId(sTemp
+ rTITLE
) + "||" + rTITLE
);
488 pMergeEntrys
->InsertEntry( nLANG
, rTEXT
, rQHTEXT
, rTITLE
);
492 OString
MergeDataFile::CreateKey(const OString
& rTYP
, const OString
& rGID
,
493 const OString
& rLID
, const OString
& rFilename
, bool bCaseSensitive
)
495 static const OString
sStroke('-');
496 OString
sKey( rTYP
);
502 sKey
+= lcl_NormalizeFilename(rFilename
);
503 OSL_TRACE("created key: %s", sKey
.getStr());
505 return sKey
; // officecfg case sensitive identifier
506 return sKey
.toAsciiUpperCase();
509 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */