bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / items / numfmtsh.cxx
blobceb5dfbe6b44e2a13cda51edd950049501e95a2e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <tools/color.hxx>
22 #include <tools/debug.hxx>
23 #include <i18nlangtag/mslangid.hxx>
25 #include <svl/zforlist.hxx>
26 #include <svl/zformat.hxx>
27 #include <svl/currencytable.hxx>
29 #include <svtools/langtab.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/settings.hxx>
32 #include <comphelper/processfactory.hxx>
34 #include <svx/numfmtsh.hxx>
36 #include <limits>
38 const double SvxNumberFormatShell::DEFAULT_NUMVALUE = 1234.56789;
44 SvxNumberFormatShell* SvxNumberFormatShell::Create( SvNumberFormatter* pNumFormatter,
45 sal_uInt32 nFormatKey,
46 SvxNumberValueType eNumValType,
47 const OUString& rNumStr )
49 return new SvxNumberFormatShell(pNumFormatter,nFormatKey,
50 eNumValType,rNumStr );
53 SvxNumberFormatShell* SvxNumberFormatShell::Create( SvNumberFormatter* pNumFormatter,
54 sal_uInt32 nFormatKey,
55 SvxNumberValueType eNumValType,
56 double nNumVal,
57 const OUString* pNumStr )
59 return new SvxNumberFormatShell(pNumFormatter,nFormatKey,
60 eNumValType,nNumVal,pNumStr );
65 SvxNumberFormatShell::SvxNumberFormatShell( SvNumberFormatter* pNumFormatter,
66 sal_uInt32 nFormatKey,
67 SvxNumberValueType eNumValType,
68 const OUString& rNumStr )
69 : pFormatter ( pNumFormatter )
70 , pCurFmtTable ( NULL )
71 , eValType ( eNumValType )
72 , bUndoAddList ( true )
73 , nCurFormatKey ( nFormatKey )
74 , nCurCategory (css::util::NumberFormat::ALL)
75 , eCurLanguage (LANGUAGE_NONE)
76 , pCurCurrencyEntry(NULL)
77 , bBankingSymbol (false)
78 , nCurCurrencyEntryPos((sal_uInt16) SELPOS_NONE)
79 , bUseStarFormat (false)
81 nValNum = DEFAULT_NUMVALUE;
83 switch ( eValType )
85 case SVX_VALUE_TYPE_STRING:
86 aValStr = rNumStr;
87 break;
88 case SVX_VALUE_TYPE_NUMBER:
89 case SVX_VALUE_TYPE_UNDEFINED:
90 default:
91 aValStr.clear();
97 SvxNumberFormatShell::SvxNumberFormatShell( SvNumberFormatter* pNumFormatter,
98 sal_uInt32 nFormatKey,
99 SvxNumberValueType eNumValType,
100 double nNumVal,
101 const OUString* pNumStr )
102 : pFormatter ( pNumFormatter )
103 , pCurFmtTable ( NULL )
104 , eValType ( eNumValType )
105 , bUndoAddList ( true )
106 , nCurFormatKey ( nFormatKey )
107 , nCurCategory (css::util::NumberFormat::ALL)
108 , eCurLanguage (LANGUAGE_NONE)
109 , pCurCurrencyEntry(NULL)
110 , bBankingSymbol (false)
111 , nCurCurrencyEntryPos((sal_uInt16) SELPOS_NONE)
112 , bUseStarFormat (false)
114 // #50441# When used in Writer, the SvxNumberInfoItem contains the
115 // original string in addition to the value
117 if ( pNumStr )
118 aValStr = *pNumStr;
120 switch ( eValType )
122 case SVX_VALUE_TYPE_NUMBER:
123 nValNum = nNumVal;
124 break;
125 case SVX_VALUE_TYPE_STRING:
126 case SVX_VALUE_TYPE_UNDEFINED:
127 default:
128 nValNum = DEFAULT_NUMVALUE;
134 SvxNumberFormatShell::~SvxNumberFormatShell()
137 * An dieser Stelle wird abhaengig davon, ob die
138 * hinzugefuegten, benutzerdefinierten als gueltig
139 * erklaert wurden (ValidateNewEntries()), die
140 * Add-Liste wieder aus dem Zahlenformatierer entfernt.
142 * Loeschen von Formaten aus dem Formatierer passiert
143 * aus Undo-Gruenden nur in der aufrufenden Instanz.
146 if ( bUndoAddList )
148 // Added formats are invalid => remove them
150 for ( std::vector<sal_uInt32>::const_iterator it(aAddList.begin()); it != aAddList.end(); ++it )
151 pFormatter->DeleteEntry( *it );
157 size_t SvxNumberFormatShell::GetUpdateDataCount() const
159 return aDelList.size();
164 void SvxNumberFormatShell::GetUpdateData( sal_uInt32* pDelArray, const sal_uInt32 nSize )
166 const size_t nListSize = aDelList.size();
168 DBG_ASSERT( pDelArray && ( nSize == nListSize ), "Array not initialised!" );
170 if ( pDelArray && ( nSize == nListSize ) )
171 for (std::vector<sal_uInt32>::const_iterator it(aDelList.begin()); it != aDelList.end(); ++it )
172 *pDelArray++ = *it;
177 void SvxNumberFormatShell::CategoryChanged( sal_uInt16 nCatLbPos,
178 short& rFmtSelPos,
179 std::vector<OUString>& rFmtEntries )
181 short nOldCategory = nCurCategory;
182 PosToCategory_Impl( nCatLbPos, nCurCategory );
183 pCurFmtTable = &( pFormatter->GetEntryTable( nCurCategory,
184 nCurFormatKey,
185 eCurLanguage ) );
186 // reinitialize currency if category newly entered
187 if ( nCurCategory == css::util::NumberFormat::CURRENCY && nOldCategory != nCurCategory )
188 pCurCurrencyEntry = NULL;
189 rFmtSelPos = FillEntryList_Impl( rFmtEntries );
194 void SvxNumberFormatShell::LanguageChanged( LanguageType eLangType,
195 short& rFmtSelPos,
196 std::vector<OUString>& rFmtEntries )
198 eCurLanguage = eLangType;
199 pCurFmtTable = &(pFormatter->ChangeCL( nCurCategory,
200 nCurFormatKey,
201 eCurLanguage ) );
202 rFmtSelPos = FillEntryList_Impl( rFmtEntries );
207 void SvxNumberFormatShell::FormatChanged( sal_uInt16 nFmtLbPos,
208 OUString& rPreviewStr,
209 Color*& rpFontColor )
211 if( static_cast<size_t>(nFmtLbPos) < aCurEntryList.size() )
213 nCurFormatKey = aCurEntryList[nFmtLbPos];
215 if( nCurFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND )
217 GetPreviewString_Impl( rPreviewStr, rpFontColor );
219 else if( nCurCategory == css::util::NumberFormat::CURRENCY )
221 if( static_cast<size_t>(nFmtLbPos) < aCurrencyFormatList.size() )
223 MakePrevStringFromVal(aCurrencyFormatList[nFmtLbPos],
224 rPreviewStr,rpFontColor,nValNum);
231 bool SvxNumberFormatShell::AddFormat( OUString& rFormat, sal_Int32& rErrPos,
232 sal_uInt16& rCatLbSelPos, short& rFmtSelPos,
233 std::vector<OUString>& rFmtEntries )
235 bool bInserted = false;
236 sal_uInt32 nAddKey = pFormatter->GetEntryKey( rFormat, eCurLanguage );
238 if ( nAddKey != NUMBERFORMAT_ENTRY_NOT_FOUND ) // exists already?
240 ::std::vector<sal_uInt32>::iterator nAt = GetRemoved_Impl( nAddKey );
241 if ( nAt != aDelList.end() )
243 aDelList.erase( nAt );
244 bInserted = true;
246 else
248 OSL_FAIL( "duplicate format!" );
251 else // new format
253 sal_Int32 nPos;
254 bInserted = pFormatter->PutEntry( rFormat, nPos,
255 nCurCategory, nAddKey,
256 eCurLanguage );
257 rErrPos = (nPos >= 0) ? nPos : -1;
259 if (bInserted)
261 // May be sorted under a different locale if LCID was parsed.
262 const SvNumberformat* pEntry = pFormatter->GetEntry( nAddKey);
263 if (pEntry)
265 LanguageType nLang = pEntry->GetLanguage();
266 if (eCurLanguage != nLang)
268 // Current language's list would not show entry, adapt.
269 eCurLanguage = nLang;
275 if ( bInserted )
277 nCurFormatKey = nAddKey;
278 DBG_ASSERT( !IsAdded_Impl( nCurFormatKey ), "duplicate format!" );
279 aAddList.push_back( nCurFormatKey );
281 // get current table
282 pCurFmtTable = &(pFormatter->GetEntryTable( nCurCategory,
283 nCurFormatKey,
284 eCurLanguage ));
285 nCurCategory=pFormatter->GetType(nAddKey);
286 CategoryToPos_Impl( nCurCategory, rCatLbSelPos );
287 rFmtSelPos = FillEntryList_Impl( rFmtEntries );
289 else if ( rErrPos != 0 ) // syntax error
293 else // insert twice not possible
295 OSL_FAIL( "duplicate format!" );
298 return bInserted;
303 bool SvxNumberFormatShell::RemoveFormat( const OUString& rFormat,
304 sal_uInt16& rCatLbSelPos,
305 short& rFmtSelPos,
306 std::vector<OUString>& rFmtEntries )
308 sal_uInt32 nDelKey = pFormatter->GetEntryKey( rFormat, eCurLanguage );
310 DBG_ASSERT( nDelKey != NUMBERFORMAT_ENTRY_NOT_FOUND, "entry not found!" );
311 DBG_ASSERT( !IsRemoved_Impl( nDelKey ), "entry already removed!" );
313 if ( (nDelKey != NUMBERFORMAT_ENTRY_NOT_FOUND) && !IsRemoved_Impl( nDelKey ) )
315 aDelList.push_back( nDelKey );
317 ::std::vector<sal_uInt32>::iterator nAt = GetAdded_Impl( nDelKey );
318 if( nAt != aAddList.end() )
320 aAddList.erase( nAt );
323 nCurCategory=pFormatter->GetType(nDelKey);
324 pCurFmtTable = &(pFormatter->GetEntryTable( nCurCategory,
325 nCurFormatKey,
326 eCurLanguage ));
328 nCurFormatKey=pFormatter->GetStandardFormat(nCurCategory,
329 eCurLanguage );
331 CategoryToPos_Impl( nCurCategory, rCatLbSelPos );
332 rFmtSelPos = FillEntryList_Impl( rFmtEntries );
334 return true;
339 void SvxNumberFormatShell::MakeFormat( OUString& rFormat,
340 bool bThousand, bool bNegRed,
341 sal_uInt16 nPrecision, sal_uInt16 nLeadingZeroes,
342 sal_uInt16 nCurrencyPos)
344 if( aCurrencyFormatList.size() > static_cast<size_t>(nCurrencyPos) )
346 sal_Int32 rErrPos=0;
347 std::vector<OUString> aFmtEList;
349 sal_uInt32 nFound = pFormatter->TestNewString( aCurrencyFormatList[nCurrencyPos], eCurLanguage );
351 if ( nFound == NUMBERFORMAT_ENTRY_NOT_FOUND )
353 sal_uInt16 rCatLbSelPos =0;
354 short rFmtSelPos = 0;
355 AddFormat( aCurrencyFormatList[nCurrencyPos],rErrPos,rCatLbSelPos,
356 rFmtSelPos,aFmtEList);
359 if(rErrPos==0)
361 rFormat = pFormatter->GenerateFormat(nCurFormatKey,
362 eCurLanguage,
363 bThousand, bNegRed,
364 nPrecision, nLeadingZeroes);
367 else
369 rFormat = pFormatter->GenerateFormat(nCurFormatKey,
370 eCurLanguage,
371 bThousand, bNegRed,
372 nPrecision, nLeadingZeroes);
377 sal_uInt16 SvxNumberFormatShell::GetFormatIntegerDigits( const OUString& rFormat ) const
379 sal_uInt32 nFmtKey = pFormatter->GetEntryKey( rFormat, eCurLanguage );
381 return pFormatter->GetFormatIntegerDigits(nFmtKey);
385 void SvxNumberFormatShell::GetOptions( const OUString& rFormat,
386 bool& rThousand,
387 bool& rNegRed,
388 sal_uInt16& rPrecision,
389 sal_uInt16& rLeadingZeroes,
390 sal_uInt16& rCatLbPos )
393 sal_uInt32 nFmtKey = pFormatter->GetEntryKey( rFormat, eCurLanguage );
395 if(nFmtKey != NUMBERFORMAT_ENTRY_NOT_FOUND)
397 pFormatter->GetFormatSpecialInfo( nFmtKey,
398 rThousand, rNegRed,
399 rPrecision, rLeadingZeroes );
401 CategoryToPos_Impl( pFormatter->GetType( nFmtKey ), rCatLbPos );
403 else
405 bool bTestBanking = false;
406 sal_uInt16 nPos=FindCurrencyTableEntry(rFormat, bTestBanking );
408 if(IsInTable(nPos,bTestBanking,rFormat) &&
409 pFormatter->GetFormatSpecialInfo( rFormat,rThousand, rNegRed,
410 rPrecision, rLeadingZeroes,eCurLanguage)==0)
412 rCatLbPos = CAT_CURRENCY;
414 else
415 rCatLbPos = CAT_USERDEFINED;
422 void SvxNumberFormatShell::MakePreviewString( const OUString& rFormatStr,
423 OUString& rPreviewStr,
424 Color*& rpFontColor )
426 rpFontColor = NULL;
428 sal_uIntPtr nExistingFormat = pFormatter->GetEntryKey( rFormatStr, eCurLanguage );
429 if ( nExistingFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
431 // real preview - not implemented in NumberFormatter for text formats
432 pFormatter->GetPreviewString( rFormatStr, nValNum, rPreviewStr,
433 &rpFontColor, eCurLanguage, bUseStarFormat );
435 else
437 // format exists
439 // #50441# if a string was set in addition to the value, use it for text formats
440 bool bUseText = ( eValType == SVX_VALUE_TYPE_STRING ||
441 ( !aValStr.isEmpty() && ( pFormatter->GetType(nExistingFormat) & css::util::NumberFormat::TEXT ) ) );
442 if ( bUseText )
444 pFormatter->GetOutputString( aValStr, nExistingFormat,
445 rPreviewStr, &rpFontColor );
447 else
449 pFormatter->GetOutputString( nValNum, nExistingFormat,
450 rPreviewStr, &rpFontColor, bUseStarFormat );
457 bool SvxNumberFormatShell::IsUserDefined( const OUString& rFmtString )
459 sal_uInt32 nFound = pFormatter->GetEntryKey( rFmtString, eCurLanguage );
461 bool bFlag=false;
462 if ( nFound != NUMBERFORMAT_ENTRY_NOT_FOUND )
464 bFlag=pFormatter->IsUserDefined( rFmtString, eCurLanguage );
466 if(bFlag)
468 const SvNumberformat* pNumEntry = pFormatter->GetEntry(nFound);
470 if(pNumEntry!=NULL && pNumEntry->HasNewCurrency())
472 bool bTestBanking;
473 sal_uInt16 nPos=FindCurrencyTableEntry(rFmtString,bTestBanking);
474 bFlag=!IsInTable(nPos,bTestBanking,rFmtString);
478 return bFlag;
483 bool SvxNumberFormatShell::FindEntry( const OUString& rFmtString, sal_uInt32* pAt /* = NULL */ )
485 bool bRes=false;
486 sal_uInt32 nFound = pFormatter->TestNewString( rFmtString, eCurLanguage );
488 if ( nFound == NUMBERFORMAT_ENTRY_NOT_FOUND )
490 bool bTestBanking=false;
491 sal_uInt16 nPos=FindCurrencyTableEntry(rFmtString, bTestBanking );
493 if(IsInTable(nPos,bTestBanking,rFmtString))
495 nFound=NUMBERFORMAT_ENTRY_NEW_CURRENCY;
496 bRes=true;
499 else
501 bRes=!IsRemoved_Impl( nFound );
504 if ( pAt )
505 *pAt = nFound;
507 return bRes;
513 void SvxNumberFormatShell::GetInitSettings( sal_uInt16& nCatLbPos,
514 LanguageType& rLangType,
515 sal_uInt16& nFmtLbSelPos,
516 std::vector<OUString>& rFmtEntries,
517 OUString& rPrevString,
518 Color*& rpPrevColor )
521 // precondition: number formater found
522 DBG_ASSERT( pFormatter != NULL, "Zahlenformatierer nicht gefunden!" );
524 short nSelPos = SELPOS_NONE;
526 // Sonderbehandlung fuer undefiniertes Zahlenformat:
527 if ( (eValType == SVX_VALUE_TYPE_UNDEFINED) && (nCurFormatKey == 0) )
528 PosToCategory_Impl( CAT_ALL, nCurCategory ); // Kategorie = Alle
529 else
530 nCurCategory = css::util::NumberFormat::UNDEFINED; // Kategorie = Undefiniert
532 pCurFmtTable = &(pFormatter->GetFirstEntryTable( nCurCategory,
533 nCurFormatKey,
534 eCurLanguage ));
538 CategoryToPos_Impl( nCurCategory, nCatLbPos );
539 rLangType = eCurLanguage;
541 nSelPos = FillEntryList_Impl( rFmtEntries );
543 DBG_ASSERT( nSelPos != SELPOS_NONE, "Leere Formatliste!" );
545 nFmtLbSelPos = (nSelPos != SELPOS_NONE) ? (sal_uInt16)nSelPos : 0;
546 GetPreviewString_Impl( rPrevString, rpPrevColor );
551 short SvxNumberFormatShell::FillEntryList_Impl( std::vector<OUString>& rList )
553 /* Erstellen einer aktuellen Liste von Format-Eintraegen.
554 * Rueckgabewert ist die Listenposition des aktuellen Formates.
555 * Ist die Liste leer oder gibt es kein aktuelles Format,
556 * so wird SELPOS_NONE geliefert.
558 short nSelPos=0;
559 sal_uInt16 nPrivCat = CAT_CURRENCY;
560 nSelPos=SELPOS_NONE;
562 aCurEntryList.clear();
564 if(nCurCategory==css::util::NumberFormat::ALL)
566 FillEListWithStd_Impl(rList,CAT_NUMBER,nSelPos);
567 FillEListWithStd_Impl(rList,CAT_PERCENT,nSelPos);
568 FillEListWithStd_Impl(rList,CAT_CURRENCY,nSelPos);
569 FillEListWithStd_Impl(rList,CAT_DATE,nSelPos);
570 FillEListWithStd_Impl(rList,CAT_TIME,nSelPos);
571 FillEListWithStd_Impl(rList,CAT_SCIENTIFIC,nSelPos);
572 FillEListWithStd_Impl(rList,CAT_FRACTION,nSelPos);
573 FillEListWithStd_Impl(rList,CAT_BOOLEAN,nSelPos);
574 FillEListWithStd_Impl(rList,CAT_TEXT,nSelPos);
576 else
578 CategoryToPos_Impl(nCurCategory, nPrivCat);
579 FillEListWithStd_Impl(rList,nPrivCat,nSelPos);
582 if( nPrivCat!=CAT_CURRENCY)
583 nSelPos=FillEListWithUsD_Impl(rList,nPrivCat,nSelPos);
585 return nSelPos;
588 void SvxNumberFormatShell::FillEListWithStd_Impl( std::vector<OUString>& rList,
589 sal_uInt16 nPrivCat,short &nSelPos )
591 /* Erstellen einer aktuellen Liste von Format-Eintraegen.
592 * Rueckgabewert ist die Listenposition des aktuellen Formates.
593 * Ist die Liste leer oder gibt es kein aktuelles Format,
594 * so wird SELPOS_NONE geliefert.
596 DBG_ASSERT( pCurFmtTable != NULL, "Unbekanntes Zahlenformat!" );
598 aCurrencyFormatList.clear();
600 if(nPrivCat==CAT_CURRENCY)
602 nSelPos=FillEListWithCurrency_Impl(rList,nSelPos);
604 else
606 NfIndexTableOffset eOffsetStart;
607 NfIndexTableOffset eOffsetEnd;
609 switch(nPrivCat)
611 case CAT_NUMBER :eOffsetStart=NF_NUMBER_START;
612 eOffsetEnd=NF_NUMBER_END;
613 break;
614 case CAT_PERCENT :eOffsetStart=NF_PERCENT_START;
615 eOffsetEnd=NF_PERCENT_END;
616 break;
617 case CAT_CURRENCY :eOffsetStart=NF_CURRENCY_START;
618 eOffsetEnd=NF_CURRENCY_END;
619 break;
620 case CAT_DATE :eOffsetStart=NF_DATE_START;
621 eOffsetEnd=NF_DATE_END;
622 break;
623 case CAT_TIME :eOffsetStart=NF_TIME_START;
624 eOffsetEnd=NF_TIME_END;
625 break;
626 case CAT_SCIENTIFIC :eOffsetStart=NF_SCIENTIFIC_START;
627 eOffsetEnd=NF_SCIENTIFIC_END;
628 break;
629 case CAT_FRACTION :eOffsetStart=NF_FRACTION_START;
630 eOffsetEnd=NF_FRACTION_END;
631 break;
632 case CAT_BOOLEAN :eOffsetStart=NF_BOOLEAN;
633 eOffsetEnd=NF_BOOLEAN;
634 break;
635 case CAT_TEXT :eOffsetStart=NF_TEXT;
636 eOffsetEnd=NF_TEXT;
637 break;
638 default :return;
641 nSelPos=FillEListWithFormats_Impl(rList,nSelPos,eOffsetStart,eOffsetEnd);
643 if(nPrivCat==CAT_DATE || nPrivCat==CAT_TIME)
645 nSelPos=FillEListWithDateTime_Impl(rList,nSelPos);
650 short SvxNumberFormatShell::FillEListWithFormats_Impl( std::vector<OUString>& rList,
651 short nSelPos,
652 NfIndexTableOffset eOffsetStart,
653 NfIndexTableOffset eOffsetEnd)
655 /* Erstellen einer aktuellen Liste von Format-Eintraegen.
656 * Rueckgabewert ist die Listenposition des aktuellen Formates.
657 * Ist die Liste leer oder gibt es kein aktuelles Format,
658 * so wird SELPOS_NONE geliefert.
660 sal_uInt16 nMyType;
662 DBG_ASSERT( pCurFmtTable != NULL, "Unbekanntes Zahlenformat!" );
664 const SvNumberformat* pNumEntry = pCurFmtTable->empty() ? 0 : pCurFmtTable->begin()->second;
665 sal_uInt32 nNFEntry;
666 OUString aStrComment;
667 OUString aNewFormNInfo;
669 short nMyCat = SELPOS_NONE;
671 long nIndex;
673 for(nIndex=eOffsetStart;nIndex<=eOffsetEnd;nIndex++)
675 nNFEntry=pFormatter->GetFormatIndex((NfIndexTableOffset)nIndex,eCurLanguage);
677 pNumEntry = pFormatter->GetEntry(nNFEntry);
679 if(pNumEntry==NULL) continue;
681 nMyCat=pNumEntry->GetType() & ~css::util::NumberFormat::DEFINED;
682 aStrComment=pNumEntry->GetComment();
683 CategoryToPos_Impl(nMyCat,nMyType);
684 aNewFormNInfo= pNumEntry->GetFormatstring();
686 if ( nNFEntry == nCurFormatKey )
688 nSelPos = ( !IsRemoved_Impl( nNFEntry ) ) ? aCurEntryList.size() : SELPOS_NONE;
691 rList.push_back( aNewFormNInfo );
692 aCurEntryList.push_back( nNFEntry );
695 return nSelPos;
698 short SvxNumberFormatShell::FillEListWithDateTime_Impl( std::vector<OUString>& rList,
699 short nSelPos)
701 sal_uInt16 nMyType;
703 assert(pCurFmtTable && "Unknown number format!");
705 const SvNumberformat* pNumEntry = pCurFmtTable->empty() ? 0 : pCurFmtTable->begin()->second;
706 sal_uInt32 nNFEntry;
707 OUString aStrComment;
708 OUString aNewFormNInfo;
710 short nMyCat = SELPOS_NONE;
712 for (long nIndex = NF_DATETIME_START; nIndex <= NF_DATETIME_END; ++nIndex)
714 nNFEntry=pFormatter->GetFormatIndex((NfIndexTableOffset)nIndex,eCurLanguage);
716 pNumEntry = pFormatter->GetEntry(nNFEntry);
717 if(pNumEntry!=NULL)
719 nMyCat=pNumEntry->GetType() & ~css::util::NumberFormat::DEFINED;
720 aStrComment=pNumEntry->GetComment();
721 CategoryToPos_Impl(nMyCat,nMyType);
722 aNewFormNInfo= pNumEntry->GetFormatstring();
724 if ( nNFEntry == nCurFormatKey )
726 nSelPos = ( !IsRemoved_Impl( nNFEntry ) ) ? aCurEntryList.size() : SELPOS_NONE;
729 rList.push_back( aNewFormNInfo );
730 aCurEntryList.push_back( nNFEntry );
734 return nSelPos;
737 short SvxNumberFormatShell::FillEListWithCurrency_Impl( std::vector<OUString>& rList,
738 short nSelPos)
740 /* Erstellen einer aktuellen Liste von Format-Eintraegen.
741 * Rueckgabewert ist die Listenposition des aktuellen Formates.
742 * Ist die Liste leer oder gibt es kein aktuelles Format,
743 * so wird SELPOS_NONE geliefert.
745 DBG_ASSERT( pCurFmtTable != NULL, "Unbekanntes Zahlenformat!" );
747 const NfCurrencyEntry* pTmpCurrencyEntry;
748 bool bTmpBanking;
749 OUString rSymbol;
751 bool bFlag=pFormatter->GetNewCurrencySymbolString(nCurFormatKey,rSymbol,
752 &pTmpCurrencyEntry,&bTmpBanking);
754 if( (!bFlag && pCurCurrencyEntry==NULL) ||
755 (bFlag && pTmpCurrencyEntry==NULL && rSymbol.isEmpty()) ||
756 (nCurCategory==css::util::NumberFormat::ALL))
758 if ( nCurCategory == css::util::NumberFormat::ALL )
759 FillEListWithUserCurrencys(rList,nSelPos);
760 nSelPos=FillEListWithSysCurrencys(rList,nSelPos);
762 else
764 nSelPos=FillEListWithUserCurrencys(rList,nSelPos);
767 return nSelPos;
771 short SvxNumberFormatShell::FillEListWithSysCurrencys( std::vector<OUString>& rList,
772 short nSelPos)
774 /* Erstellen einer aktuellen Liste von Format-Eintraegen.
775 * Rueckgabewert ist die Listenposition des aktuellen Formates.
776 * Ist die Liste leer oder gibt es kein aktuelles Format,
777 * so wird SELPOS_NONE geliefert.
779 sal_uInt16 nMyType;
781 DBG_ASSERT( pCurFmtTable != NULL, "Unbekanntes Zahlenformat!" );
783 const SvNumberformat* pNumEntry = pCurFmtTable->empty() ? 0 : pCurFmtTable->begin()->second;
784 sal_uInt32 nNFEntry;
785 OUString aStrComment;
786 OUString aNewFormNInfo;
788 nCurCurrencyEntryPos=0;
790 short nMyCat = SELPOS_NONE;
792 NfIndexTableOffset eOffsetStart=NF_CURRENCY_START;
793 NfIndexTableOffset eOffsetEnd=NF_CURRENCY_END;
794 long nIndex;
796 for(nIndex=eOffsetStart;nIndex<=eOffsetEnd;nIndex++)
798 nNFEntry=pFormatter->GetFormatIndex((NfIndexTableOffset)nIndex,eCurLanguage);
800 pNumEntry = pFormatter->GetEntry(nNFEntry);
802 if(pNumEntry==NULL) continue;
804 nMyCat=pNumEntry->GetType() & ~css::util::NumberFormat::DEFINED;
805 aStrComment=pNumEntry->GetComment();
806 CategoryToPos_Impl(nMyCat,nMyType);
807 aNewFormNInfo= pNumEntry->GetFormatstring();
809 if ( nNFEntry == nCurFormatKey )
811 nSelPos = ( !IsRemoved_Impl( nNFEntry ) ) ? aCurEntryList.size() : SELPOS_NONE;
814 rList.push_back( aNewFormNInfo );
815 aCurEntryList.push_back( nNFEntry );
818 if(nCurCategory!=css::util::NumberFormat::ALL)
820 SvNumberFormatTable::iterator it = pCurFmtTable->begin();
822 while ( it != pCurFmtTable->end() )
824 sal_uInt32 nKey = it->first;
825 pNumEntry = it->second;
827 if ( !IsRemoved_Impl( nKey ))
829 bool bUserNewCurrency=false;
830 if(pNumEntry->HasNewCurrency())
832 const NfCurrencyEntry* pTmpCurrencyEntry;
833 bool bTmpBanking;
834 OUString rSymbol;
836 pFormatter->GetNewCurrencySymbolString(nKey,rSymbol,
837 &pTmpCurrencyEntry,
838 &bTmpBanking);
840 bUserNewCurrency=(pTmpCurrencyEntry!=NULL);
843 if(!bUserNewCurrency &&(pNumEntry->GetType() & css::util::NumberFormat::DEFINED))
845 nMyCat=pNumEntry->GetType() & ~css::util::NumberFormat::DEFINED;
846 aStrComment=pNumEntry->GetComment();
847 CategoryToPos_Impl(nMyCat,nMyType);
848 aNewFormNInfo= pNumEntry->GetFormatstring();
850 if ( nKey == nCurFormatKey ) nSelPos =aCurEntryList.size();
851 rList.push_back( aNewFormNInfo );
852 aCurEntryList.push_back( nKey );
855 ++it;
858 return nSelPos;
861 short SvxNumberFormatShell::FillEListWithUserCurrencys( std::vector<OUString>& rList,
862 short nSelPos)
864 /* Erstellen einer aktuellen Liste von Format-Eintraegen.
865 * Rueckgabewert ist die Listenposition des aktuellen Formates.
866 * Ist die Liste leer oder gibt es kein aktuelles Format,
867 * so wird SELPOS_NONE geliefert.
869 sal_uInt16 nMyType;
871 DBG_ASSERT( pCurFmtTable != NULL, "Unbekanntes Zahlenformat!" );
873 OUString aStrComment;
874 OUString aNewFormNInfo;
875 short nMyCat = SELPOS_NONE;
877 const NfCurrencyEntry* pTmpCurrencyEntry;
878 bool bTmpBanking, bAdaptSelPos;
879 OUString rSymbol;
880 OUString rBankSymbol;
882 std::vector<OUString> aList;
883 std::vector<sal_uInt32> aKeyList;
885 pFormatter->GetNewCurrencySymbolString(nCurFormatKey,rSymbol,
886 &pTmpCurrencyEntry,
887 &bTmpBanking);
889 OUString rShortSymbol;
891 if(pCurCurrencyEntry==NULL)
893 // #110398# If no currency format was previously selected (we're not
894 // about to add another currency), try to select the initial currency
895 // format (nCurFormatKey) that was set in FormatChanged() after
896 // matching the format string entered in the dialog.
897 bAdaptSelPos = true;
898 pCurCurrencyEntry = const_cast<NfCurrencyEntry*>(pTmpCurrencyEntry);
899 bBankingSymbol = bTmpBanking;
900 nCurCurrencyEntryPos = FindCurrencyFormat(pTmpCurrencyEntry,bTmpBanking);
902 else
904 if (pTmpCurrencyEntry == pCurCurrencyEntry)
905 bAdaptSelPos = true;
906 else
908 bAdaptSelPos = false;
909 pTmpCurrencyEntry = pCurCurrencyEntry;
911 bTmpBanking=bBankingSymbol;
914 if(pTmpCurrencyEntry!=NULL)
916 rSymbol = pTmpCurrencyEntry->BuildSymbolString(false);
917 rBankSymbol = pTmpCurrencyEntry->BuildSymbolString(true);
918 rShortSymbol = pTmpCurrencyEntry->BuildSymbolString(bTmpBanking,true);
921 SvNumberFormatTable::iterator it = pCurFmtTable->begin();
922 while ( it != pCurFmtTable->end() )
924 sal_uInt32 nKey = it->first;
925 const SvNumberformat* pNumEntry = it->second;
927 if ( !IsRemoved_Impl( nKey ) )
929 if( pNumEntry->GetType() & css::util::NumberFormat::DEFINED ||
930 pNumEntry->IsAdditionalBuiltin() )
932 nMyCat=pNumEntry->GetType() & ~css::util::NumberFormat::DEFINED;
933 aStrComment = pNumEntry->GetComment();
934 CategoryToPos_Impl(nMyCat,nMyType);
935 aNewFormNInfo = pNumEntry->GetFormatstring();
937 bool bInsFlag = false;
938 if ( pNumEntry->HasNewCurrency() )
940 bInsFlag = true; // merge locale formats into currency selection
942 else if( (!bTmpBanking && aNewFormNInfo.indexOf(rSymbol) >= 0) ||
943 (bTmpBanking && aNewFormNInfo.indexOf(rBankSymbol) >= 0) )
945 bInsFlag = true;
947 else if(aNewFormNInfo.indexOf(rShortSymbol) >= 0)
949 OUString rTstSymbol;
950 const NfCurrencyEntry* pTstCurrencyEntry;
951 bool bTstBanking;
953 pFormatter->GetNewCurrencySymbolString(nKey,rTstSymbol,
954 &pTstCurrencyEntry,
955 &bTstBanking);
957 if(pTmpCurrencyEntry == pTstCurrencyEntry &&
958 bTstBanking == bTmpBanking)
960 bInsFlag = true;
965 if(bInsFlag)
967 aList.push_back( aNewFormNInfo );
968 aKeyList.push_back( nKey );
972 ++it;
975 NfWSStringsDtor aWSStringsDtor;
976 sal_uInt16 nDefault;
977 if ( pTmpCurrencyEntry && nCurCategory != css::util::NumberFormat::ALL )
979 nDefault = pFormatter->GetCurrencyFormatStrings(
980 aWSStringsDtor, *pTmpCurrencyEntry, bTmpBanking );
981 if ( !bTmpBanking )
982 pFormatter->GetCurrencyFormatStrings(
983 aWSStringsDtor, *pTmpCurrencyEntry, true );
985 else
986 nDefault = 0;
987 if ( !bTmpBanking && nCurCategory != css::util::NumberFormat::ALL )
988 { // append formats for all currencies defined in the current I18N locale
989 const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable();
990 sal_uInt16 nCurrCount = rCurrencyTable.size();
991 LanguageType eLang = MsLangId::getRealLanguage( eCurLanguage );
992 for ( sal_uInt16 i=0; i < nCurrCount; ++i )
994 const NfCurrencyEntry* pCurr = &rCurrencyTable[i];
995 if ( pCurr->GetLanguage() == eLang && pTmpCurrencyEntry != pCurr )
997 pFormatter->GetCurrencyFormatStrings( aWSStringsDtor, *pCurr, false );
998 pFormatter->GetCurrencyFormatStrings( aWSStringsDtor, *pCurr, true );
1003 size_t nOldListCount = rList.size();
1004 for( size_t i = 0, nPos = nOldListCount; i < aWSStringsDtor.size(); ++i )
1006 bool bFlag = true;
1007 OUString aInsStr(aWSStringsDtor[i]);
1008 size_t j;
1009 for( j=0; j < aList.size(); ++j )
1011 if(aList[j]==aInsStr)
1013 bFlag = false;
1014 break;
1017 if(bFlag)
1019 rList.push_back( aInsStr );
1020 aCurEntryList.insert( aCurEntryList.begin() + (nPos++), NUMBERFORMAT_ENTRY_NOT_FOUND);
1022 else
1024 rList.push_back( aList[j] );
1025 aList.erase( aList.begin()+j );
1026 aCurEntryList.insert( aCurEntryList.begin() + (nPos++), aKeyList[j]);
1027 aKeyList.erase( aKeyList.begin()+j );
1031 for( size_t i = 0; i < aKeyList.size(); ++i )
1033 if( aKeyList[i] != NUMBERFORMAT_ENTRY_NOT_FOUND )
1035 rList.push_back( aList[i] );
1036 aCurEntryList.push_back( aKeyList[i] );
1040 for( size_t i = nOldListCount; i < rList.size(); ++i )
1042 aCurrencyFormatList.push_back( rList[i] );
1044 if ( nSelPos == SELPOS_NONE && bAdaptSelPos && aCurEntryList[i] == nCurFormatKey )
1045 nSelPos = i;
1048 if ( nSelPos == SELPOS_NONE && nCurCategory != css::util::NumberFormat::ALL )
1049 nSelPos = nDefault;
1051 return nSelPos;
1055 short SvxNumberFormatShell::FillEListWithUsD_Impl( std::vector<OUString>& rList,
1056 sal_uInt16 nPrivCat, short nSelPos )
1058 /* Erstellen einer aktuellen Liste von Format-Eintraegen.
1059 * Rueckgabewert ist die Listenposition des aktuellen Formates.
1060 * Ist die Liste leer oder gibt es kein aktuelles Format,
1061 * so wird SELPOS_NONE geliefert.
1063 sal_uInt16 nMyType;
1065 DBG_ASSERT( pCurFmtTable != NULL, "Unbekanntes Zahlenformat!" );
1067 OUString aStrComment;
1068 OUString aNewFormNInfo;
1070 short nMyCat = SELPOS_NONE;
1071 bool bAdditional = (nPrivCat != CAT_USERDEFINED &&
1072 nCurCategory != css::util::NumberFormat::ALL);
1074 SvNumberFormatTable::iterator it = pCurFmtTable->begin();
1075 while ( it != pCurFmtTable->end() )
1077 sal_uInt32 nKey = it->first;
1078 const SvNumberformat* pNumEntry = it->second;
1080 if ( !IsRemoved_Impl( nKey ) )
1082 if( (pNumEntry->GetType() & css::util::NumberFormat::DEFINED) ||
1083 (bAdditional && pNumEntry->IsAdditionalBuiltin()) )
1085 nMyCat=pNumEntry->GetType() & ~css::util::NumberFormat::DEFINED;
1086 aStrComment=pNumEntry->GetComment();
1087 CategoryToPos_Impl(nMyCat,nMyType);
1088 aNewFormNInfo= pNumEntry->GetFormatstring();
1090 bool bFlag=true;
1091 if(pNumEntry->HasNewCurrency())
1093 bool bTestBanking;
1094 sal_uInt16 nPos=FindCurrencyTableEntry(aNewFormNInfo,bTestBanking);
1095 bFlag=!IsInTable(nPos,bTestBanking,aNewFormNInfo);
1097 if(bFlag)
1099 if ( nKey == nCurFormatKey ) nSelPos = aCurEntryList.size();
1100 rList.push_back( aNewFormNInfo );
1101 aCurEntryList.push_back( nKey );
1105 ++it;
1107 return nSelPos;
1113 void SvxNumberFormatShell::GetPreviewString_Impl( OUString& rString, Color*& rpColor )
1115 rpColor = NULL;
1117 // #50441# if a string was set in addition to the value, use it for text formats
1118 bool bUseText = ( eValType == SVX_VALUE_TYPE_STRING ||
1119 ( !aValStr.isEmpty() && ( pFormatter->GetType(nCurFormatKey) & css::util::NumberFormat::TEXT ) ) );
1121 if ( bUseText )
1123 pFormatter->GetOutputString( aValStr, nCurFormatKey, rString, &rpColor );
1125 else
1127 pFormatter->GetOutputString( nValNum, nCurFormatKey, rString, &rpColor, bUseStarFormat );
1133 ::std::vector<sal_uInt32>::iterator SvxNumberFormatShell::GetRemoved_Impl( size_t nKey )
1135 return ::std::find(aDelList.begin(), aDelList.end(), nKey);
1140 bool SvxNumberFormatShell::IsRemoved_Impl( size_t nKey )
1142 return GetRemoved_Impl( nKey ) != aDelList.end();
1147 ::std::vector<sal_uInt32>::iterator SvxNumberFormatShell::GetAdded_Impl( size_t nKey )
1149 return ::std::find(aAddList.begin(), aAddList.end(), nKey);
1154 bool SvxNumberFormatShell::IsAdded_Impl( size_t nKey )
1156 return GetAdded_Impl( nKey ) != aAddList.end();
1159 // Konvertierungs-Routinen:
1160 void SvxNumberFormatShell::PosToCategory_Impl(sal_uInt16 nPos, short& rCategory) const
1162 // Kategorie ::com::sun::star::form-Positionen abbilden (->Resource)
1163 switch ( nPos )
1165 case CAT_USERDEFINED: rCategory = css::util::NumberFormat::DEFINED; break;
1166 case CAT_NUMBER: rCategory = css::util::NumberFormat::NUMBER; break;
1167 case CAT_PERCENT: rCategory = css::util::NumberFormat::PERCENT; break;
1168 case CAT_CURRENCY: rCategory = css::util::NumberFormat::CURRENCY; break;
1169 case CAT_DATE: rCategory = css::util::NumberFormat::DATE; break;
1170 case CAT_TIME: rCategory = css::util::NumberFormat::TIME; break;
1171 case CAT_SCIENTIFIC: rCategory = css::util::NumberFormat::SCIENTIFIC; break;
1172 case CAT_FRACTION: rCategory = css::util::NumberFormat::FRACTION; break;
1173 case CAT_BOOLEAN: rCategory = css::util::NumberFormat::LOGICAL; break;
1174 case CAT_TEXT: rCategory = css::util::NumberFormat::TEXT; break;
1175 case CAT_ALL:
1176 default: rCategory = css::util::NumberFormat::ALL; break;
1180 void SvxNumberFormatShell::CategoryToPos_Impl(short nCategory, sal_uInt16& rPos) const
1182 // Kategorie auf ::com::sun::star::form-Positionen abbilden (->Resource)
1183 switch ( nCategory )
1185 case css::util::NumberFormat::DEFINED: rPos = CAT_USERDEFINED; break;
1186 case css::util::NumberFormat::NUMBER: rPos = CAT_NUMBER; break;
1187 case css::util::NumberFormat::PERCENT: rPos = CAT_PERCENT; break;
1188 case css::util::NumberFormat::CURRENCY: rPos = CAT_CURRENCY; break;
1189 case css::util::NumberFormat::DATETIME:
1190 case css::util::NumberFormat::DATE: rPos = CAT_DATE; break;
1191 case css::util::NumberFormat::TIME: rPos = CAT_TIME; break;
1192 case css::util::NumberFormat::SCIENTIFIC: rPos = CAT_SCIENTIFIC; break;
1193 case css::util::NumberFormat::FRACTION: rPos = CAT_FRACTION; break;
1194 case css::util::NumberFormat::LOGICAL: rPos = CAT_BOOLEAN; break;
1195 case css::util::NumberFormat::TEXT: rPos = CAT_TEXT; break;
1196 case css::util::NumberFormat::ALL:
1197 default: rPos = CAT_ALL;
1202 * Funktion: Formatiert die Zahl nValue abhaengig von rFormatStr
1203 * und speichert das Ergebnis in rPreviewStr.
1204 * Input: FormatString, Farbe, zu formatierende Zahl
1205 * Output: Ausgabestring rPreviewStr
1207 void SvxNumberFormatShell::MakePrevStringFromVal(
1208 const OUString& rFormatStr,
1209 OUString& rPreviewStr,
1210 Color*& rpFontColor,
1211 double nValue)
1213 rpFontColor = NULL;
1214 pFormatter->GetPreviewString( rFormatStr, nValue, rPreviewStr, &rpFontColor, eCurLanguage );
1218 * Funktion: Liefert den Kommentar fuer einen gegebenen
1219 * Eintrag zurueck.
1220 * Input: Nummer des Eintrags
1221 * Output: Kommentar-String
1223 void SvxNumberFormatShell::SetComment4Entry(short nEntry, const OUString& aEntStr)
1225 SvNumberformat *pNumEntry;
1226 if(nEntry<0) return;
1227 sal_uInt32 nMyNfEntry=aCurEntryList[nEntry];
1228 pNumEntry = const_cast<SvNumberformat*>(pFormatter->GetEntry(nMyNfEntry));
1229 if(pNumEntry!=NULL) pNumEntry->SetComment(aEntStr);
1233 * Funktion: Liefert den Kommentar fuer einen gegebenen
1234 * Eintrag zurueck.
1235 * Input: Nummer des Eintrags
1236 * Output: Kommentar-String
1238 OUString SvxNumberFormatShell::GetComment4Entry(short nEntry)
1240 if(nEntry < 0)
1241 return OUString();
1243 if( static_cast<size_t>(nEntry) < aCurEntryList.size())
1245 sal_uInt32 nMyNfEntry=aCurEntryList[nEntry];
1246 const SvNumberformat *pNumEntry = pFormatter->GetEntry(nMyNfEntry);
1247 if(pNumEntry!=NULL)
1248 return pNumEntry->GetComment();
1251 return OUString();
1255 * Funktion: Liefert die Kategorie- Nummer fuer einen gegebenen
1256 * Eintrag zurueck.
1257 * Input: Nummer des Eintrags
1258 * Output: Kategorie- Nummer
1260 short SvxNumberFormatShell::GetCategory4Entry(short nEntry) const
1262 if(nEntry<0) return 0;
1263 if( static_cast<size_t>(nEntry) < aCurEntryList.size() )
1265 sal_uInt32 nMyNfEntry=aCurEntryList[nEntry];
1267 if(nMyNfEntry!=NUMBERFORMAT_ENTRY_NOT_FOUND)
1269 const SvNumberformat *pNumEntry = pFormatter->GetEntry(nMyNfEntry);
1270 sal_uInt16 nMyCat,nMyType;
1271 if(pNumEntry!=NULL)
1273 nMyCat=pNumEntry->GetType() & ~css::util::NumberFormat::DEFINED;
1274 CategoryToPos_Impl(nMyCat,nMyType);
1276 return (short) nMyType;
1278 return 0;
1280 else if( !aCurrencyFormatList.empty() )
1282 return CAT_CURRENCY;
1285 return 0;
1290 * Funktion: Liefert die Information, ob ein Eintrag
1291 * benutzerspezifisch ist zurueck.
1292 * Input: Nummer des Eintrags
1293 * Output: Benutzerspezifisch?
1295 bool SvxNumberFormatShell::GetUserDefined4Entry(short nEntry)
1297 if(nEntry<0) return false;
1298 if( static_cast<size_t>(nEntry) < aCurEntryList.size())
1300 sal_uInt32 nMyNfEntry=aCurEntryList[nEntry];
1301 const SvNumberformat *pNumEntry = pFormatter->GetEntry(nMyNfEntry);
1303 if(pNumEntry!=NULL)
1305 if((pNumEntry->GetType() & css::util::NumberFormat::DEFINED)>0)
1307 return true;
1311 return false;
1315 * Funktion: Liefert den Format- String fuer einen gegebenen
1316 * Eintrag zurueck.
1317 * Input: Nummer des Eintrags
1318 * Output: Format- String
1320 OUString SvxNumberFormatShell::GetFormat4Entry(short nEntry)
1322 if(nEntry < 0)
1323 return OUString();
1325 if( !aCurrencyFormatList.empty() )
1327 if( aCurrencyFormatList.size() > static_cast<size_t>(nEntry) )
1328 return aCurrencyFormatList[nEntry];
1330 else
1332 sal_uInt32 nMyNfEntry=aCurEntryList[nEntry];
1333 const SvNumberformat *pNumEntry = pFormatter->GetEntry(nMyNfEntry);
1335 if(pNumEntry!=NULL)
1336 return pNumEntry->GetFormatstring();
1338 return OUString();
1342 * Funktion: Liefert die Listen- Nummer fuer einen gegebenen
1343 * Formatindex zurueck.
1344 * Input: Nummer des Eintrags
1345 * Output: Kategorie- Nummer
1347 short SvxNumberFormatShell::GetListPos4Entry(sal_uInt32 nIdx)
1349 short nSelP=SELPOS_NONE;
1350 // Check list size against return type limit.
1351 if( aCurEntryList.size() <= static_cast<size_t>(::std::numeric_limits< short >::max()) )
1353 for(size_t i=0; i < aCurEntryList.size(); ++i)
1355 if(aCurEntryList[i]==nIdx)
1357 nSelP=i;
1358 break;
1362 else
1364 OSL_FAIL("svx::SvxNumberFormatShell::GetListPos4Entry(), list got too large!" );
1366 return nSelP;
1369 short SvxNumberFormatShell::GetListPos4Entry( const OUString& rFmtString )
1371 sal_uInt32 nAt=0;
1372 short nSelP=SELPOS_NONE;
1373 if(FindEntry(rFmtString, &nAt))
1375 if(NUMBERFORMAT_ENTRY_NOT_FOUND!=nAt && NUMBERFORMAT_ENTRY_NEW_CURRENCY!=nAt)
1377 nSelP=GetListPos4Entry(nAt);
1379 else
1381 for( size_t i=0; i<aCurrencyFormatList.size(); i++ )
1383 if (rFmtString==aCurrencyFormatList[i])
1385 nSelP = static_cast<short>(i);
1386 break;
1391 return nSelP;
1394 OUString SvxNumberFormatShell::GetStandardName() const
1396 return pFormatter->GetStandardName( eCurLanguage);
1399 void SvxNumberFormatShell::GetCurrencySymbols(std::vector<OUString>& rList, sal_uInt16* pPos)
1401 const NfCurrencyEntry* pTmpCurrencyEntry=SvNumberFormatter::MatchSystemCurrency();
1403 bool bFlag=(pTmpCurrencyEntry==NULL);
1405 GetCurrencySymbols(rList, bFlag);
1407 if(pPos!=NULL)
1409 const NfCurrencyTable& rCurrencyTable=SvNumberFormatter::GetTheCurrencyTable();
1410 sal_uInt16 nTableCount=rCurrencyTable.size();
1412 *pPos=0;
1413 size_t nCount=aCurCurrencyList.size();
1415 if(bFlag)
1417 *pPos=1;
1418 nCurCurrencyEntryPos=1;
1420 else
1422 for(size_t i=1;i<nCount;i++)
1424 const sal_uInt16 j = aCurCurrencyList[i];
1425 if (j != (sal_uInt16)-1 && j < nTableCount &&
1426 pTmpCurrencyEntry == &rCurrencyTable[j])
1428 *pPos=static_cast<sal_uInt16>(i);
1429 nCurCurrencyEntryPos=static_cast<sal_uInt16>(i);
1430 break;
1438 void SvxNumberFormatShell::GetCurrencySymbols(std::vector<OUString>& rList, bool bFlag)
1440 aCurCurrencyList.clear();
1442 const NfCurrencyTable& rCurrencyTable=SvNumberFormatter::GetTheCurrencyTable();
1443 sal_uInt16 nCount=rCurrencyTable.size();
1445 sal_uInt16 nStart=1;
1447 OUString aString( ApplyLreOrRleEmbedding( rCurrencyTable[0].GetSymbol()));
1448 aString += " ";
1449 aString += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString( rCurrencyTable[0].GetLanguage()));
1451 rList.push_back(aString);
1452 sal_uInt16 nAuto=(sal_uInt16)-1;
1453 aCurCurrencyList.push_back(nAuto);
1455 if(bFlag)
1457 rList.push_back(aString);
1458 aCurCurrencyList.push_back(0);
1459 ++nStart;
1462 CollatorWrapper aCollator( ::comphelper::getProcessComponentContext());
1463 aCollator.loadDefaultCollator( Application::GetSettings().GetLanguageTag().getLocale(), 0);
1465 const OUString aTwoSpace(" ");
1467 for(sal_uInt16 i = 1; i < nCount; ++i)
1469 OUString aStr( ApplyLreOrRleEmbedding( rCurrencyTable[i].GetBankSymbol()));
1470 aStr += aTwoSpace;
1471 aStr += ApplyLreOrRleEmbedding( rCurrencyTable[i].GetSymbol());
1472 aStr += aTwoSpace;
1473 aStr += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString( rCurrencyTable[i].GetLanguage()));
1475 sal_uInt16 j = nStart;
1476 for(; j < rList.size(); ++j)
1477 if (aCollator.compareString(aStr, rList[j]) < 0)
1478 break; // insert before first greater than
1480 rList.insert(rList.begin() + j, aStr);
1481 aCurCurrencyList.insert(aCurCurrencyList.begin() + j, i);
1484 // Append ISO codes to symbol list.
1485 // XXX If this is to be changed, various other places would had to be
1486 // adapted that assume this order!
1487 sal_uInt16 nCont = rList.size();
1489 for(sal_uInt16 i = 1; i < nCount; ++i)
1491 bool bInsert = true;
1492 OUString aStr(ApplyLreOrRleEmbedding(rCurrencyTable[i].GetBankSymbol()));
1494 sal_uInt16 j = nCont;
1495 for(; j < rList.size() && bInsert; ++j)
1497 if(rList[j] == aStr)
1498 bInsert = false;
1499 else if (aCollator.compareString(aStr, rList[j]) < 0)
1500 break; // insert before first greater than
1502 if(bInsert)
1504 rList.insert(rList.begin() + j, aStr);
1505 aCurCurrencyList.insert(aCurCurrencyList.begin()+j, i);
1510 void SvxNumberFormatShell::SetCurrencySymbol(sal_uInt32 nPos)
1512 const NfCurrencyTable& rCurrencyTable=SvNumberFormatter::GetTheCurrencyTable();
1513 sal_uInt16 nCount=rCurrencyTable.size();
1515 bBankingSymbol=(nPos>=nCount);
1517 if(nPos<aCurCurrencyList.size())
1519 sal_uInt16 nCurrencyPos=aCurCurrencyList[nPos];
1520 if(nCurrencyPos!=(sal_uInt16)-1)
1522 pCurCurrencyEntry=const_cast<NfCurrencyEntry*>(&rCurrencyTable[nCurrencyPos]);
1523 nCurCurrencyEntryPos=nPos;
1525 else
1527 pCurCurrencyEntry=NULL;
1528 nCurCurrencyEntryPos=0;
1529 nCurFormatKey=pFormatter->GetFormatIndex(
1530 NF_CURRENCY_1000DEC2_RED, eCurLanguage);
1536 void SvxNumberFormatShell::SetCurCurrencyEntry(NfCurrencyEntry* pCEntry)
1538 pCurCurrencyEntry=pCEntry;
1541 bool SvxNumberFormatShell::IsTmpCurrencyFormat( const OUString& rFmtString )
1543 sal_uInt32 nFound;
1544 FindEntry(rFmtString, &nFound);
1546 if(nFound==NUMBERFORMAT_ENTRY_NEW_CURRENCY)
1548 return true;
1550 return false;
1553 sal_uInt16 SvxNumberFormatShell::FindCurrencyFormat( const OUString& rFmtString )
1555 const NfCurrencyTable& rCurrencyTable=SvNumberFormatter::GetTheCurrencyTable();
1556 sal_uInt16 nCount=rCurrencyTable.size();
1558 bool bTestBanking=false;
1560 sal_uInt16 nPos=FindCurrencyTableEntry(rFmtString, bTestBanking);
1562 if(nPos!=(sal_uInt16)-1)
1564 sal_uInt16 nStart=0;
1565 if(bTestBanking && aCurCurrencyList.size()>nPos)
1567 nStart=nCount;
1569 for(sal_uInt16 j=nStart;j<aCurCurrencyList.size();j++)
1571 if(aCurCurrencyList[j]==nPos) return j;
1574 return (sal_uInt16) -1;
1577 sal_uInt16 SvxNumberFormatShell::FindCurrencyTableEntry( const OUString& rFmtString, bool &bTestBanking )
1579 sal_uInt16 nPos=(sal_uInt16) -1;
1581 const NfCurrencyTable& rCurrencyTable=SvNumberFormatter::GetTheCurrencyTable();
1582 sal_uInt16 nCount=rCurrencyTable.size();
1584 const SvNumberformat* pFormat;
1585 OUString aSymbol, aExtension;
1586 sal_uInt32 nFound = pFormatter->TestNewString( rFmtString, eCurLanguage );
1587 if ( nFound != NUMBERFORMAT_ENTRY_NOT_FOUND &&
1588 ((pFormat = pFormatter->GetEntry( nFound )) != 0) &&
1589 pFormat->GetNewCurrencySymbol( aSymbol, aExtension ) )
1590 { // eventually match with format locale
1591 const NfCurrencyEntry* pTmpCurrencyEntry =
1592 SvNumberFormatter::GetCurrencyEntry( bTestBanking, aSymbol, aExtension,
1593 pFormat->GetLanguage() );
1594 if ( pTmpCurrencyEntry )
1596 for(sal_uInt16 i=0;i<nCount;i++)
1598 if(pTmpCurrencyEntry==&rCurrencyTable[i])
1600 nPos=i;
1601 break;
1606 else
1607 { // search symbol string only
1608 for(sal_uInt16 i=0;i<nCount;i++)
1610 const NfCurrencyEntry* pTmpCurrencyEntry=&rCurrencyTable[i];
1611 OUString _aSymbol = pTmpCurrencyEntry->BuildSymbolString(false);
1612 OUString aBankSymbol = pTmpCurrencyEntry->BuildSymbolString(true);
1614 if(rFmtString.indexOf(_aSymbol) != -1)
1616 bTestBanking=false;
1617 nPos=i;
1618 break;
1620 else if(rFmtString.indexOf(aBankSymbol) != -1)
1622 bTestBanking=true;
1623 nPos=i;
1624 break;
1629 return nPos;
1632 sal_uInt16 SvxNumberFormatShell::FindCurrencyFormat(const NfCurrencyEntry* pTmpCurrencyEntry,bool bTmpBanking)
1634 const NfCurrencyTable& rCurrencyTable=SvNumberFormatter::GetTheCurrencyTable();
1635 sal_uInt16 nCount=rCurrencyTable.size();
1637 sal_uInt16 nPos=0;
1638 for(sal_uInt16 i=0;i<nCount;i++)
1640 if(pTmpCurrencyEntry==&rCurrencyTable[i])
1642 nPos=i;
1643 break;
1647 sal_uInt16 nStart=0;
1648 if(bTmpBanking && aCurCurrencyList.size()>nPos)
1650 nStart=nCount;
1652 for(sal_uInt16 j=nStart;j<aCurCurrencyList.size();j++)
1654 if(aCurCurrencyList[j]==nPos) return j;
1656 return (sal_uInt16) -1;
1659 bool SvxNumberFormatShell::IsInTable(sal_uInt16 const nPos,
1660 bool const bTmpBanking, OUString const& rFmtString)
1662 bool bFlag=false;
1664 if(nPos!=(sal_uInt16)-1)
1666 const NfCurrencyTable& rCurrencyTable=SvNumberFormatter::GetTheCurrencyTable();
1667 sal_uInt16 nCount=rCurrencyTable.size();
1669 if(nPos<nCount)
1671 NfWSStringsDtor aWSStringsDtor;
1673 const NfCurrencyEntry* pTmpCurrencyEntry=&rCurrencyTable[nPos];
1675 if ( pTmpCurrencyEntry!=NULL)
1677 pFormatter->GetCurrencyFormatStrings( aWSStringsDtor,
1678 *pTmpCurrencyEntry, bTmpBanking );
1680 for(sal_uInt16 i=0;i<aWSStringsDtor.size();i++)
1682 if (aWSStringsDtor[i] == rFmtString)
1684 bFlag=true;
1685 break;
1692 return bFlag;
1695 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */