Files
libreoffice/xmloff/source/style/xmlnumfe.cxx

1594 lines
55 KiB
C++
Raw Normal View History

2000-09-18 16:07:07 +00:00
/*************************************************************************
*
* $RCSfile: xmlnumfe.cxx,v $
*
* $Revision: 1.24 $
2000-09-18 16:07:07 +00:00
*
* last change: $Author: dvo $ $Date: 2001-10-19 18:43:58 $
2000-09-18 16:07:07 +00:00
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#define _SVSTDARR_ULONGS
#define _ZFORLIST_DECLARE_TABLE
#include <svtools/svstdarr.hxx>
#include <svtools/zforlist.hxx>
#include <svtools/zformat.hxx>
#include <svtools/numuno.hxx>
#include <tools/isolang.hxx>
#include <tools/debug.hxx>
#include <tools/solmath.hxx>
#include <unotools/calendarwrapper.hxx>
2000-10-24 09:41:04 +00:00
#include <unotools/charclass.hxx>
#include <com/sun/star/lang/Locale.hpp>
2000-09-18 16:07:07 +00:00
#include <rtl/ustrbuf.hxx>
2000-10-24 09:41:04 +00:00
#include <comphelper/processfactory.hxx>
2000-09-18 16:07:07 +00:00
#include "xmlnumfe.hxx"
#include "xmlnmspe.hxx"
#include "xmluconv.hxx"
#include "attrlist.hxx"
#include "nmspmap.hxx"
#include "families.hxx"
#include "xmlnumfi.hxx" // SvXMLNumFmtDefaults
2000-09-18 16:07:07 +00:00
#define _SVSTDARR_USHORTS
#include <svtools/svstdarr.hxx>
#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif
#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif
#include <set>
2000-09-18 16:07:07 +00:00
using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::xmloff::token;
2000-09-18 16:07:07 +00:00
//-------------------------------------------------------------------------
//! enum Sc_SymbolType is in source/numbers/zforscan.hxx
#define XMLNUM_SYMBOLTYPE_STRING (-1)
#define XMLNUM_SYMBOLTYPE_DEL (-2)
#define XMLNUM_SYMBOLTYPE_BLANK (-3)
#define XMLNUM_SYMBOLTYPE_STAR (-4)
#define XMLNUM_SYMBOLTYPE_DIGIT (-5)
#define XMLNUM_SYMBOLTYPE_DECSEP (-6)
#define XMLNUM_SYMBOLTYPE_THSEP (-7)
#define XMLNUM_SYMBOLTYPE_EXP (-8)
#define XMLNUM_SYMBOLTYPE_FRAC (-9)
#define XMLNUM_SYMBOLTYPE_EMPTY (-10)
#define XMLNUM_SYMBOLTYPE_FRACBLANK (-11)
#define XMLNUM_SYMBOLTYPE_COMMENT (-12)
#define XMLNUM_SYMBOLTYPE_CURRENCY (-13)
#define XMLNUM_SYMBOLTYPE_CURRDEL (-14)
#define XMLNUM_SYMBOLTYPE_CURREXT (-15)
#define XMLNUM_SYMBOLTYPE_CALENDAR (-16)
#define XMLNUM_SYMBOLTYPE_CALDEL (-17)
2000-09-18 16:07:07 +00:00
//-------------------------------------------------------------------------
// 4th condition for text formats doesn't work
//#define XMLNUM_MAX_PARTS 4
#define XMLNUM_MAX_PARTS 3
//-------------------------------------------------------------------------
struct LessuInt32
{
sal_Bool operator() (const sal_uInt32 rValue1, const sal_uInt32 rValue2) const
{
return rValue1 < rValue2;
}
};
typedef std::set< sal_uInt32, LessuInt32 > SvXMLuInt32Set;
2000-09-18 16:07:07 +00:00
class SvXMLNumUsedList_Impl
{
SvXMLuInt32Set aUsed;
SvXMLuInt32Set aWasUsed;
SvXMLuInt32Set::iterator aCurrentUsedPos;
sal_uInt32 nUsedCount;
sal_uInt32 nWasUsedCount;
2000-09-18 16:07:07 +00:00
public:
SvXMLNumUsedList_Impl();
~SvXMLNumUsedList_Impl();
void SetUsed( sal_uInt32 nKey );
sal_Bool IsUsed( sal_uInt32 nKey ) const;
sal_Bool IsWasUsed( sal_uInt32 nKey ) const;
void Export();
sal_Bool GetFirstUsed(sal_uInt32& nKey);
sal_Bool GetNextUsed(sal_uInt32& nKey);
void GetWasUsed(uno::Sequence<sal_Int32>& rWasUsed);
void SetWasUsed(const uno::Sequence<sal_Int32>& rWasUsed);
2000-09-18 16:07:07 +00:00
};
//-------------------------------------------------------------------------
//
//! SvXMLNumUsedList_Impl should be optimized!
//
SvXMLNumUsedList_Impl::SvXMLNumUsedList_Impl() :
nUsedCount(0),
nWasUsedCount(0)
2000-09-18 16:07:07 +00:00
{
}
SvXMLNumUsedList_Impl::~SvXMLNumUsedList_Impl()
{
}
void SvXMLNumUsedList_Impl::SetUsed( sal_uInt32 nKey )
{
if ( !IsWasUsed(nKey) )
{
std::pair<SvXMLuInt32Set::iterator, bool> aPair = aUsed.insert( nKey );
if (aPair.second)
nUsedCount++;
}
2000-09-18 16:07:07 +00:00
}
sal_Bool SvXMLNumUsedList_Impl::IsUsed( sal_uInt32 nKey ) const
{
SvXMLuInt32Set::iterator aItr = aUsed.find(nKey);
return (aItr != aUsed.end());
2000-09-18 16:07:07 +00:00
}
sal_Bool SvXMLNumUsedList_Impl::IsWasUsed( sal_uInt32 nKey ) const
{
SvXMLuInt32Set::iterator aItr = aWasUsed.find(nKey);
return (aItr != aWasUsed.end());
2000-09-18 16:07:07 +00:00
}
void SvXMLNumUsedList_Impl::Export()
{
SvXMLuInt32Set::iterator aItr = aUsed.begin();
while (aItr != aUsed.end())
{
std::pair<SvXMLuInt32Set::iterator, bool> aPair = aWasUsed.insert( *aItr );
if (aPair.second)
nWasUsedCount++;
aItr++;
}
aUsed.clear();
nUsedCount = 0;
}
sal_Bool SvXMLNumUsedList_Impl::GetFirstUsed(sal_uInt32& nKey)
{
sal_Bool bRet(sal_False);
aCurrentUsedPos = aUsed.begin();
if(nUsedCount)
{
DBG_ASSERT(aCurrentUsedPos != aUsed.end(), "something went wrong");
nKey = *aCurrentUsedPos;
bRet = sal_True;
}
return bRet;
}
sal_Bool SvXMLNumUsedList_Impl::GetNextUsed(sal_uInt32& nKey)
{
sal_Bool bRet(sal_False);
if (aCurrentUsedPos != aUsed.end())
{
aCurrentUsedPos++;
if (aCurrentUsedPos != aUsed.end())
{
nKey = *aCurrentUsedPos;
bRet = sal_True;
}
}
return bRet;
2000-09-18 16:07:07 +00:00
}
void SvXMLNumUsedList_Impl::GetWasUsed(uno::Sequence<sal_Int32>& rWasUsed)
{
rWasUsed.realloc(nWasUsedCount);
sal_Int32* pWasUsed = rWasUsed.getArray();
if (pWasUsed)
{
SvXMLuInt32Set::iterator aItr = aWasUsed.begin();
while (aItr != aWasUsed.end())
{
*pWasUsed = *aItr;
aItr++;
pWasUsed++;
}
}
}
void SvXMLNumUsedList_Impl::SetWasUsed(const uno::Sequence<sal_Int32>& rWasUsed)
{
DBG_ASSERT(nWasUsedCount == 0, "WasUsed should be empty");
sal_Int32 nCount(rWasUsed.getLength());
const sal_Int32* pWasUsed = rWasUsed.getConstArray();
for (sal_uInt16 i = 0; i < nCount; i++, pWasUsed++)
{
std::pair<SvXMLuInt32Set::iterator, bool> aPair = aWasUsed.insert( *pWasUsed );
if (aPair.second)
nWasUsedCount++;
}
}
2000-09-18 16:07:07 +00:00
//-------------------------------------------------------------------------
SvXMLNumFmtExport::SvXMLNumFmtExport(
SvXMLExport& rExp,
2000-09-18 16:07:07 +00:00
const uno::Reference< util::XNumberFormatsSupplier >& rSupp ) :
rExport( rExp ),
2000-09-18 16:07:07 +00:00
pFormatter( NULL ),
pCharClass( NULL ),
pLocaleData( NULL ),
sPrefix( OUString::createFromAscii( "N" ) )
{
// supplier must be SvNumberFormatsSupplierObj
SvNumberFormatsSupplierObj* pObj =
SvNumberFormatsSupplierObj::getImplementation( rSupp );
if (pObj)
pFormatter = pObj->GetNumberFormatter();
if ( pFormatter )
{
pCharClass = new CharClass( pFormatter->GetServiceManager(),
pFormatter->GetLocale() );
pLocaleData = new LocaleDataWrapper( pFormatter->GetServiceManager(),
pFormatter->GetLocale() );
}
else
{
lang::Locale aLocale( SvNumberFormatter::ConvertLanguageToLocale( ::GetSystemLanguage() ) );
pCharClass = new CharClass( ::comphelper::getProcessServiceFactory(), aLocale );
pLocaleData = new LocaleDataWrapper( ::comphelper::getProcessServiceFactory(), aLocale );
}
pUsedList = new SvXMLNumUsedList_Impl;
}
SvXMLNumFmtExport::SvXMLNumFmtExport(
SvXMLExport& rExp,
const ::com::sun::star::uno::Reference<
::com::sun::star::util::XNumberFormatsSupplier >& rSupp,
const rtl::OUString& rPrefix ) :
rExport( rExp ),
pFormatter( NULL ),
pCharClass( NULL ),
pLocaleData( NULL ),
sPrefix( rPrefix )
2000-09-18 16:07:07 +00:00
{
// supplier must be SvNumberFormatsSupplierObj
SvNumberFormatsSupplierObj* pObj =
SvNumberFormatsSupplierObj::getImplementation( rSupp );
if (pObj)
pFormatter = pObj->GetNumberFormatter();
if ( pFormatter )
{
pCharClass = new CharClass( pFormatter->GetServiceManager(),
pFormatter->GetLocale() );
pLocaleData = new LocaleDataWrapper( pFormatter->GetServiceManager(),
pFormatter->GetLocale() );
}
else
{
lang::Locale aLocale( SvNumberFormatter::ConvertLanguageToLocale( ::GetSystemLanguage() ) );
pCharClass = new CharClass( ::comphelper::getProcessServiceFactory(), aLocale );
pLocaleData = new LocaleDataWrapper( ::comphelper::getProcessServiceFactory(), aLocale );
}
2000-09-18 16:07:07 +00:00
pUsedList = new SvXMLNumUsedList_Impl;
}
SvXMLNumFmtExport::~SvXMLNumFmtExport()
{
delete pUsedList;
delete pLocaleData;
delete pCharClass;
2000-09-18 16:07:07 +00:00
}
//-------------------------------------------------------------------------
//
// helper methods
//
OUString lcl_CreateStyleName( sal_Int32 nKey, sal_Int32 nPart, sal_Bool bDefPart, const rtl::OUString& rPrefix )
2000-09-18 16:07:07 +00:00
{
OUStringBuffer aFmtName( 10L );
aFmtName.append( rPrefix );
2000-09-18 16:07:07 +00:00
aFmtName.append( nKey );
if (!bDefPart)
{
aFmtName.append( (sal_Unicode)'P' );
aFmtName.append( nPart );
}
return aFmtName.makeStringAndClear();
}
void SvXMLNumFmtExport::AddCalendarAttr_Impl( const OUString& rCalendar )
{
if ( rCalendar.getLength() )
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_CALENDAR, rCalendar );
}
}
2000-09-18 16:07:07 +00:00
void SvXMLNumFmtExport::AddTextualAttr_Impl( sal_Bool bText )
{
if ( bText ) // non-textual
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TEXTUAL, XML_TRUE );
2000-09-18 16:07:07 +00:00
}
}
void SvXMLNumFmtExport::AddStyleAttr_Impl( sal_Bool bLong )
{
if ( bLong ) // short is default
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_STYLE, XML_LONG );
2000-09-18 16:07:07 +00:00
}
}
void SvXMLNumFmtExport::AddLanguageAttr_Impl( sal_Int32 nLang )
{
if ( nLang != LANGUAGE_SYSTEM )
{
String aLangStr, aCountryStr;
ConvertLanguageToIsoNames( (LanguageType)nLang, aLangStr, aCountryStr );
2000-09-18 16:07:07 +00:00
OUString sAttrValue;
2000-09-18 16:07:07 +00:00
if (aLangStr.Len())
{
sAttrValue = aLangStr;
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_LANGUAGE, sAttrValue );
2000-09-18 16:07:07 +00:00
}
if (aCountryStr.Len())
{
sAttrValue = aCountryStr;
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_COUNTRY, sAttrValue );
2000-09-18 16:07:07 +00:00
}
}
}
//-------------------------------------------------------------------------
//
// methods to write individual elements within a format
//
void SvXMLNumFmtExport::AddToTextElement_Impl( const OUString& rString )
{
// append to sTextContent, write element in FinishTextElement_Impl
// to avoid several text elements following each other
sTextContent.append( rString );
}
void SvXMLNumFmtExport::FinishTextElement_Impl()
{
if ( sTextContent.getLength() )
{
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_TEXT,
sal_True, sal_False );
rExport.Characters( sTextContent.makeStringAndClear() );
}
}
2000-09-18 16:07:07 +00:00
void SvXMLNumFmtExport::WriteColorElement_Impl( const Color& rColor )
{
FinishTextElement_Impl();
2000-09-18 16:07:07 +00:00
OUStringBuffer aColStr( 7 );
SvXMLUnitConverter::convertColor( aColStr, rColor );
rExport.AddAttribute( XML_NAMESPACE_FO, XML_COLOR,
aColStr.makeStringAndClear() );
2000-09-18 16:07:07 +00:00
SvXMLElementExport aElem( rExport, XML_NAMESPACE_STYLE, XML_PROPERTIES,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteCurrencyElement_Impl( const OUString& rString,
const OUString& rExt )
{
FinishTextElement_Impl();
2000-09-18 16:07:07 +00:00
if ( rExt.getLength() )
{
sal_Int32 nLang = rExt.toInt32(16); // hex
if ( nLang < 0 ) // extension string may contain "-" separator
nLang = -nLang;
AddLanguageAttr_Impl( nLang ); // adds to pAttrList
}
SvXMLElementExport aElem( rExport,
XML_NAMESPACE_NUMBER, XML_CURRENCY_SYMBOL,
sal_True, sal_False );
rExport.Characters( rString );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteBooleanElement_Impl()
{
FinishTextElement_Impl();
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_BOOLEAN,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteTextContentElement_Impl()
{
FinishTextElement_Impl();
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_TEXT_CONTENT,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
// date elements
void SvXMLNumFmtExport::WriteDayElement_Impl( const OUString& rCalendar, sal_Bool bLong )
2000-09-18 16:07:07 +00:00
{
FinishTextElement_Impl();
AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
2000-09-18 16:07:07 +00:00
AddStyleAttr_Impl( bLong ); // adds to pAttrList
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_DAY,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteMonthElement_Impl( const OUString& rCalendar, sal_Bool bLong, sal_Bool bText )
2000-09-18 16:07:07 +00:00
{
FinishTextElement_Impl();
AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
2000-09-18 16:07:07 +00:00
AddStyleAttr_Impl( bLong ); // adds to pAttrList
AddTextualAttr_Impl( bText ); // adds to pAttrList
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_MONTH,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteYearElement_Impl( const OUString& rCalendar, sal_Bool bLong )
2000-09-18 16:07:07 +00:00
{
FinishTextElement_Impl();
AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
2000-09-18 16:07:07 +00:00
AddStyleAttr_Impl( bLong ); // adds to pAttrList
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_YEAR,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteEraElement_Impl( const OUString& rCalendar, sal_Bool bLong )
2000-11-29 19:37:27 +00:00
{
FinishTextElement_Impl();
AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
2000-11-29 19:37:27 +00:00
AddStyleAttr_Impl( bLong ); // adds to pAttrList
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_ERA,
sal_True, sal_False );
2000-11-29 19:37:27 +00:00
}
void SvXMLNumFmtExport::WriteDayOfWeekElement_Impl( const OUString& rCalendar, sal_Bool bLong )
2000-09-18 16:07:07 +00:00
{
FinishTextElement_Impl();
AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
2000-09-18 16:07:07 +00:00
AddStyleAttr_Impl( bLong ); // adds to pAttrList
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_DAY_OF_WEEK,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteWeekElement_Impl( const OUString& rCalendar )
2000-09-18 16:07:07 +00:00
{
FinishTextElement_Impl();
AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_WEEK_OF_YEAR,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteQuarterElement_Impl( const OUString& rCalendar, sal_Bool bLong )
2000-09-18 16:07:07 +00:00
{
FinishTextElement_Impl();
AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
2000-09-18 16:07:07 +00:00
AddStyleAttr_Impl( bLong ); // adds to pAttrList
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_QUARTER,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
// time elements
void SvXMLNumFmtExport::WriteHoursElement_Impl( sal_Bool bLong )
{
FinishTextElement_Impl();
2000-09-18 16:07:07 +00:00
AddStyleAttr_Impl( bLong ); // adds to pAttrList
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_HOURS,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteMinutesElement_Impl( sal_Bool bLong )
{
FinishTextElement_Impl();
2000-09-18 16:07:07 +00:00
AddStyleAttr_Impl( bLong ); // adds to pAttrList
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_MINUTES,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteSecondsElement_Impl( sal_Bool bLong, sal_uInt16 nDecimals )
{
FinishTextElement_Impl();
2000-09-18 16:07:07 +00:00
AddStyleAttr_Impl( bLong ); // adds to pAttrList
if ( nDecimals > 0 )
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DECIMAL_PLACES,
OUString::valueOf( (sal_Int32) nDecimals ) );
2000-09-18 16:07:07 +00:00
}
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_SECONDS,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteAMPMElement_Impl()
{
FinishTextElement_Impl();
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_AM_PM,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
// numbers
void SvXMLNumFmtExport::WriteNumberElement_Impl(
sal_Int32 nDecimals, sal_Int32 nInteger,
const OUString& rDashStr, sal_Bool bGrouping )
{
FinishTextElement_Impl();
2000-09-18 16:07:07 +00:00
// decimals
if ( nDecimals >= 0 ) // negative = automatic
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DECIMAL_PLACES,
OUString::valueOf( nDecimals ) );
2000-09-18 16:07:07 +00:00
}
// integer digits
if ( nInteger >= 0 ) // negative = automatic
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS,
OUString::valueOf( nInteger ) );
2000-09-18 16:07:07 +00:00
}
// decimal replacement (dashes)
if ( rDashStr.getLength() )
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DECIMAL_REPLACEMENT,
rDashStr );
2000-09-18 16:07:07 +00:00
}
// (automatic) grouping separator
if ( bGrouping )
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_GROUPING, XML_TRUE );
2000-09-18 16:07:07 +00:00
}
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_NUMBER,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteScientificElement_Impl(
sal_Int32 nDecimals, sal_Int32 nInteger,
sal_Bool bGrouping, sal_Int32 nExp )
{
FinishTextElement_Impl();
2000-09-18 16:07:07 +00:00
// decimals
if ( nDecimals >= 0 ) // negative = automatic
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DECIMAL_PLACES,
OUString::valueOf( nDecimals ) );
2000-09-18 16:07:07 +00:00
}
// integer digits
if ( nInteger >= 0 ) // negative = automatic
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS,
OUString::valueOf( nInteger ) );
2000-09-18 16:07:07 +00:00
}
// (automatic) grouping separator
if ( bGrouping )
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_GROUPING, XML_TRUE );
2000-09-18 16:07:07 +00:00
}
// exponent digits
if ( nExp >= 0 )
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_EXPONENT_DIGITS,
OUString::valueOf( nExp ) );
2000-09-18 16:07:07 +00:00
}
SvXMLElementExport aElem( rExport,
XML_NAMESPACE_NUMBER, XML_SCIENTIFIC_NUMBER,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::WriteFractionElement_Impl(
sal_Int32 nInteger, sal_Bool bGrouping,
sal_Int32 nNumerator, sal_Int32 nDenominator )
{
FinishTextElement_Impl();
2000-09-18 16:07:07 +00:00
// integer digits
if ( nInteger >= 0 ) // negative = default (no integer part)
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS,
OUString::valueOf( nInteger ) );
2000-09-18 16:07:07 +00:00
}
// (automatic) grouping separator
if ( bGrouping )
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_GROUPING, XML_TRUE );
2000-09-18 16:07:07 +00:00
}
// numerator digits
if ( nNumerator >= 0 )
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_NUMERATOR_DIGITS,
OUString::valueOf( nNumerator ) );
2000-09-18 16:07:07 +00:00
}
// denominator digits
if ( nDenominator >= 0 )
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_DENOMINATOR_DIGITS,
OUString::valueOf( nDenominator ) );
2000-09-18 16:07:07 +00:00
}
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_FRACTION,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
// mapping (condition)
void SvXMLNumFmtExport::WriteMapElement_Impl( sal_Int32 nOp, double fLimit,
sal_Int32 nKey, sal_Int32 nPart )
{
FinishTextElement_Impl();
2000-09-18 16:07:07 +00:00
if ( nOp != NUMBERFORMAT_OP_NO )
{
// style namespace
OUStringBuffer aCondStr( 20L );
aCondStr.appendAscii( "value()" ); //! define constant
switch ( nOp )
{
case NUMBERFORMAT_OP_EQ: aCondStr.append( (sal_Unicode) '=' ); break;
case NUMBERFORMAT_OP_NE: aCondStr.appendAscii( "<>" ); break;
case NUMBERFORMAT_OP_LT: aCondStr.append( (sal_Unicode) '<' ); break;
case NUMBERFORMAT_OP_LE: aCondStr.appendAscii( "<=" ); break;
case NUMBERFORMAT_OP_GT: aCondStr.append( (sal_Unicode) '>' ); break;
case NUMBERFORMAT_OP_GE: aCondStr.appendAscii( ">=" ); break;
default:
DBG_ERROR("unknown operator");
}
String aValStr;
SolarMath::DoubleToString( aValStr, fLimit, 'A', INT_MAX, '.', TRUE );
aCondStr.append( aValStr );
rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_CONDITION,
aCondStr.makeStringAndClear() );
2000-09-18 16:07:07 +00:00
rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_APPLY_STYLE_NAME,
lcl_CreateStyleName( nKey, nPart, sal_False,
sPrefix ) );
2000-09-18 16:07:07 +00:00
SvXMLElementExport aElem( rExport, XML_NAMESPACE_STYLE, XML_MAP,
sal_True, sal_False );
2000-09-18 16:07:07 +00:00
}
}
//-------------------------------------------------------------------------
// for old (automatic) currency formats: parse currency symbol from text
xub_StrLen lcl_FindSymbol( const String& sUpperStr, const String& sCurString )
{
// search for currency symbol
// Quoting as in ImpSvNumberformatScan::Symbol_Division
xub_StrLen nCPos = 0;
while (nCPos != STRING_NOTFOUND)
{
nCPos = sUpperStr.Search( sCurString, nCPos );
if (nCPos != STRING_NOTFOUND)
{
// in Quotes?
xub_StrLen nQ = SvNumberformat::GetQuoteEnd( sUpperStr, nCPos );
if ( nQ == STRING_NOTFOUND )
{
// dm can be escaped as "dm or \d
sal_Unicode c;
if ( nCPos == 0 ||
((c = sUpperStr.GetChar(xub_StrLen(nCPos-1))) != '"'
&& c != '\\') )
{
return nCPos; // found
}
else
nCPos++; // continue
}
else
nCPos = nQ + 1; // continue after quote end
}
}
return STRING_NOTFOUND; // not found
}
sal_Bool SvXMLNumFmtExport::WriteTextWithCurrency_Impl( const OUString& rString,
const ::com::sun::star::lang::Locale& rLocale )
2000-09-18 16:07:07 +00:00
{
// returns TRUE if currency element was written
sal_Bool bRet = sal_False;
// pLocaleData->setLocale( rLocale );
// String sCurString = pLocaleData->getCurrSymbol();
LanguageType nLang = ConvertIsoNamesToLanguage( rLocale.Language, rLocale.Country );
pFormatter->ChangeIntl( nLang );
String sCurString, sDummy;
pFormatter->GetCompatibilityCurrency( sCurString, sDummy );
pCharClass->setLocale( rLocale );
String sUpperStr = pCharClass->upper(rString);
2000-09-18 16:07:07 +00:00
xub_StrLen nPos = lcl_FindSymbol( sUpperStr, sCurString );
if ( nPos != STRING_NOTFOUND )
{
sal_Int32 nLength = rString.getLength();
sal_Int32 nCurLen = sCurString.Len();
sal_Int32 nCont = nPos + nCurLen;
// text before currency symbol
if ( nPos > 0 )
AddToTextElement_Impl( rString.copy( 0, nPos ) );
2000-09-18 16:07:07 +00:00
// currency symbol (empty string -> default)
OUString sEmpty;
WriteCurrencyElement_Impl( sEmpty, sEmpty );
bRet = sal_True;
2000-09-18 16:07:07 +00:00
// text after currency symbol
if ( nCont < nLength )
AddToTextElement_Impl( rString.copy( nCont, nLength-nCont ) );
2000-09-18 16:07:07 +00:00
}
else
AddToTextElement_Impl( rString ); // simple text
return bRet; // TRUE: currency element written
2000-09-18 16:07:07 +00:00
}
//-------------------------------------------------------------------------
// test if all date elements match the system settings
sal_Bool lcl_MatchesSystemDate( const SvNumberformat& rFormat, sal_uInt16 nPart, sal_Bool bLongSysDate )
{
sal_Bool bMatch = sal_True;
International aIntl( rFormat.GetLanguage() );
// loop through elements (only look for date elements that depend on style attribute)
sal_uInt16 nPos = 0;
sal_Bool bEnd = sal_False;
while ( bMatch && !bEnd )
{
short nElemType = rFormat.GetNumForType( nPart, nPos, sal_False );
switch ( nElemType )
{
case 0:
bEnd = sal_True; // end of format reached
break;
case NF_KEY_D: // short day
if ( SvXMLNumFmtDefaults::IsSystemLongDay( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
case NF_KEY_DD: // long day
if ( !SvXMLNumFmtDefaults::IsSystemLongDay( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
case NF_KEY_DDD: // short day of week
case NF_KEY_NN:
case NF_KEY_AAA:
if ( SvXMLNumFmtDefaults::IsSystemLongDayOfWeek( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
case NF_KEY_DDDD: // long day of week
case NF_KEY_NNN:
case NF_KEY_NNNN:
case NF_KEY_AAAA:
if ( !SvXMLNumFmtDefaults::IsSystemLongDayOfWeek( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
case NF_KEY_M: // short numerical month
if ( SvXMLNumFmtDefaults::IsSystemLongMonth( aIntl, bLongSysDate ) ||
SvXMLNumFmtDefaults::IsSystemTextualMonth( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
case NF_KEY_MM: // long numerical month
if ( !SvXMLNumFmtDefaults::IsSystemLongMonth( aIntl, bLongSysDate ) ||
SvXMLNumFmtDefaults::IsSystemTextualMonth( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
case NF_KEY_MMM: // short textual month
case NF_KEY_MMMMM: //! (first letter)
if ( SvXMLNumFmtDefaults::IsSystemLongMonth( aIntl, bLongSysDate ) ||
!SvXMLNumFmtDefaults::IsSystemTextualMonth( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
case NF_KEY_MMMM: // long textual month
if ( !SvXMLNumFmtDefaults::IsSystemLongMonth( aIntl, bLongSysDate ) ||
!SvXMLNumFmtDefaults::IsSystemTextualMonth( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
case NF_KEY_YY: // short year
case NF_KEY_EEC:
if ( SvXMLNumFmtDefaults::IsSystemLongYear( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
case NF_KEY_YYYY: // long year
case NF_KEY_EC:
case NF_KEY_R:
if ( !SvXMLNumFmtDefaults::IsSystemLongYear( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
case NF_KEY_G: // short era
case NF_KEY_GG:
if ( SvXMLNumFmtDefaults::IsSystemLongEra( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
case NF_KEY_GGG: // long era
case NF_KEY_RR:
if ( !SvXMLNumFmtDefaults::IsSystemLongEra( aIntl, bLongSysDate ) )
bMatch = sal_False;
break;
// quarter isn't changed by format-source
}
++nPos;
}
return bMatch;
}
//-------------------------------------------------------------------------
OUString lcl_GetDefaultCalendar( SvNumberFormatter* pFormatter, LanguageType nLang )
{
// get name of first non-gregorian calendar for the language
OUString aCalendar;
CalendarWrapper* pCalendar = pFormatter->GetCalendar();
if (pCalendar)
{
String sLangStr, sCountry;
ConvertLanguageToIsoNames( nLang, sLangStr, sCountry );
lang::Locale aLocale( sLangStr, sCountry, OUString() );
uno::Sequence<OUString> aCals = pCalendar->getAllCalendars( aLocale );
sal_Int32 nCnt = aCals.getLength();
sal_Bool bFound = sal_False;
for ( sal_Int32 j=0; j < nCnt && !bFound; j++ )
{
if ( !aCals[j].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("gregorian") ) )
{
aCalendar = aCals[j];
bFound = sal_True;
}
}
}
return aCalendar;
}
//-------------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
//
// export one part (condition)
//
void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt32 nKey,
2000-09-18 16:07:07 +00:00
sal_uInt16 nPart, sal_Bool bDefPart )
{
//! for the default part, pass the coditions from the other parts!
//
// element name
//
NfIndexTableOffset eBuiltIn = pFormatter->GetIndexTableOffset( nKey );
short nFmtType = 0;
sal_Bool bThousand = sal_False;
sal_uInt16 nPrecision = 0;
sal_uInt16 nLeading = 0;
rFormat.GetNumForInfo( nPart, nFmtType, bThousand, nPrecision, nLeading);
nFmtType &= ~NUMBERFORMAT_DEFINED;
// special treatment of builtin formats that aren't detected by normal parsing
// (the same formats that get the type set in SvNumberFormatter::ImpGenerateFormats)
if ( eBuiltIn == NF_NUMBER_STANDARD )
nFmtType = NUMBERFORMAT_NUMBER;
else if ( eBuiltIn == NF_BOOLEAN )
nFmtType = NUMBERFORMAT_LOGICAL;
else if ( eBuiltIn == NF_TEXT )
nFmtType = NUMBERFORMAT_TEXT;
XMLTokenEnum eType = XML_TOKEN_INVALID;
2000-09-18 16:07:07 +00:00
switch ( nFmtType )
{
// type is 0 if a format contains no recognized elements
// (like text only) - this is handled as a number-style.
case 0:
2000-09-18 16:07:07 +00:00
case NUMBERFORMAT_NUMBER:
case NUMBERFORMAT_SCIENTIFIC:
case NUMBERFORMAT_FRACTION:
eType = XML_NUMBER_STYLE;
2000-09-18 16:07:07 +00:00
break;
case NUMBERFORMAT_PERCENT:
eType = XML_PERCENTAGE_STYLE;
2000-09-18 16:07:07 +00:00
break;
case NUMBERFORMAT_CURRENCY:
eType = XML_CURRENCY_STYLE;
2000-09-18 16:07:07 +00:00
break;
case NUMBERFORMAT_DATE:
case NUMBERFORMAT_DATETIME:
eType = XML_DATE_STYLE;
2000-09-18 16:07:07 +00:00
break;
case NUMBERFORMAT_TIME:
eType = XML_TIME_STYLE;
2000-09-18 16:07:07 +00:00
break;
case NUMBERFORMAT_TEXT:
eType = XML_TEXT_STYLE;
2000-09-18 16:07:07 +00:00
break;
case NUMBERFORMAT_LOGICAL:
eType = XML_BOOLEAN_STYLE;
2000-09-18 16:07:07 +00:00
break;
}
DBG_ASSERT( eType != XML_TOKEN_INVALID, "unknown format type" );
OUString sAttrValue;
2000-09-18 16:07:07 +00:00
sal_Bool bUserDef = ( ( rFormat.GetType() & NUMBERFORMAT_DEFINED ) != 0 );
//
// common attributes for format
//
// format name (generated from key) - style namespace
rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_NAME,
lcl_CreateStyleName( nKey, nPart, bDefPart, sPrefix ) );
rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY,
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
XML_STYLE_FAMILY_DATA_STYLE_NAME)) );
2000-09-18 16:07:07 +00:00
// language / country
LanguageType nLang = rFormat.GetLanguage();
AddLanguageAttr_Impl( nLang ); // adds to pAttrList
// title (comment)
// titles for builtin formats are not written
sAttrValue = rFormat.GetComment();
if ( sAttrValue.getLength() && bUserDef && bDefPart )
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TITLE, sAttrValue );
2000-09-18 16:07:07 +00:00
}
// automatic ordering for currency and date formats
// only used for some built-in formats
BOOL bAutoOrder = ( eBuiltIn == NF_CURRENCY_1000INT || eBuiltIn == NF_CURRENCY_1000DEC2 ||
eBuiltIn == NF_CURRENCY_1000INT_RED || eBuiltIn == NF_CURRENCY_1000DEC2_RED ||
eBuiltIn == NF_CURRENCY_1000DEC2_DASHED ||
eBuiltIn == NF_DATE_SYSTEM_SHORT || eBuiltIn == NF_DATE_SYSTEM_LONG ||
eBuiltIn == NF_DATE_SYS_MMYY || eBuiltIn == NF_DATE_SYS_DDMMM ||
eBuiltIn == NF_DATE_SYS_DDMMYYYY || eBuiltIn == NF_DATE_SYS_DDMMYY ||
eBuiltIn == NF_DATE_SYS_DMMMYY || eBuiltIn == NF_DATE_SYS_DMMMYYYY ||
eBuiltIn == NF_DATE_SYS_DMMMMYYYY || eBuiltIn == NF_DATE_SYS_NNDMMMYY ||
eBuiltIn == NF_DATE_SYS_NNDMMMMYYYY || eBuiltIn == NF_DATE_SYS_NNNNDMMMMYYYY );
if ( bAutoOrder &&
( nFmtType == NUMBERFORMAT_CURRENCY || nFmtType == NUMBERFORMAT_DATE || nFmtType == NUMBERFORMAT_DATETIME ) )
2000-09-18 16:07:07 +00:00
{
// #85109# format type must be checked to avoid dtd errors if
// locale data contains other format types at the built-in positions
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_AUTOMATIC_ORDER,
XML_TRUE );
2000-09-18 16:07:07 +00:00
}
// format source (for date and time formats)
// only used for some built-in formats
BOOL bSystemDate = ( eBuiltIn == NF_DATE_SYSTEM_SHORT ||
eBuiltIn == NF_DATE_SYSTEM_LONG ||
2000-11-29 19:37:27 +00:00
eBuiltIn == NF_DATETIME_SYSTEM_SHORT_HHMM ) && rFormat.GetComment().Len();
BOOL bLongSysDate = ( eBuiltIn == NF_DATE_SYSTEM_LONG ) && rFormat.GetComment().Len();
// test if all date elements match the system settings
if ( bSystemDate && !lcl_MatchesSystemDate( rFormat, nPart, bLongSysDate ) )
bSystemDate = sal_False;
if ( bSystemDate &&
( nFmtType == NUMBERFORMAT_DATE || nFmtType == NUMBERFORMAT_DATETIME ) )
2000-09-18 16:07:07 +00:00
{
// #85109# format type must be checked to avoid dtd errors if
// locale data contains other format types at the built-in positions
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_FORMAT_SOURCE,
XML_LANGUAGE );
2000-09-18 16:07:07 +00:00
}
// overflow for time formats as in [hh]:mm
// controlled by bThousand from number format info
// default for truncate-on-overflow is true
if ( nFmtType == NUMBERFORMAT_TIME && bThousand )
{
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TRUNCATE_ON_OVERFLOW,
XML_FALSE );
2000-09-18 16:07:07 +00:00
}
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, eType,
sal_True, sal_True );
2000-09-18 16:07:07 +00:00
//
// color (properties element)
//
const Color* pCol = rFormat.GetColor( nPart );
if (pCol)
WriteColorElement_Impl(*pCol);
// detect if there is "real" content, excluding color and maps
//! move to implementation of Write... methods?
sal_Bool bAnyContent = sal_False;
2000-09-18 16:07:07 +00:00
//
// format elements
//
if ( eBuiltIn == NF_NUMBER_STANDARD )
{
// default number format contains just one number element
WriteNumberElement_Impl( -1, 1, OUString(), sal_False );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
}
else if ( eBuiltIn == NF_BOOLEAN )
{
// boolean format contains just one boolean element
WriteBooleanElement_Impl();
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
}
else
{
// first loop to collect attributes
sal_Bool bDecDashes = sal_False;
sal_Bool bExpFound = sal_False;
sal_Bool bCurrFound = sal_False;
sal_Int32 nExpDigits = 0;
OUString sCurrExt;
OUString aCalendar;
2000-09-18 16:07:07 +00:00
sal_uInt16 nPos = 0;
sal_Bool bEnd = sal_False;
while (!bEnd)
{
short nElemType = rFormat.GetNumForType( nPart, nPos, sal_False );
const XubString* pElemStr = rFormat.GetNumForString( nPart, nPos, sal_False );
switch ( nElemType )
{
case 0:
bEnd = sal_True; // end of format reached
break;
case XMLNUM_SYMBOLTYPE_DIGIT:
if ( bExpFound && pElemStr )
nExpDigits += pElemStr->Len();
else if ( !bDecDashes && pElemStr && pElemStr->GetChar(0) == '-' )
bDecDashes = TRUE;
break;
case XMLNUM_SYMBOLTYPE_EXP:
bExpFound = TRUE; // following digits are exponent digits
break;
case XMLNUM_SYMBOLTYPE_CURRENCY:
bCurrFound = TRUE;
break;
case XMLNUM_SYMBOLTYPE_CURREXT:
if (pElemStr)
sCurrExt = *pElemStr;
break;
// E, EE, R, RR: select non-gregorian calendar
// AAA, AAAA: calendar is switched at the position of the element
case NF_KEY_EC:
case NF_KEY_EEC:
case NF_KEY_R:
case NF_KEY_RR:
if (!aCalendar.getLength())
aCalendar = lcl_GetDefaultCalendar( pFormatter, nLang );
break;
2000-09-18 16:07:07 +00:00
}
++nPos;
}
// second loop to write elements
sal_Bool bNumWritten = sal_False;
sal_Bool bCurrencyWritten = sal_False;
2000-09-18 16:07:07 +00:00
short nPrevType = 0;
nPos = 0;
bEnd = sal_False;
while (!bEnd)
{
short nElemType = rFormat.GetNumForType( nPart, nPos, sal_False );
const XubString* pElemStr = rFormat.GetNumForString( nPart, nPos, sal_False );
switch ( nElemType )
{
case 0:
bEnd = sal_True; // end of format reached
break;
case XMLNUM_SYMBOLTYPE_STRING:
if (pElemStr)
{
if ( ( nPrevType == NF_KEY_S || nPrevType == NF_KEY_SS ) &&
( pElemStr->EqualsAscii( "," ) || pElemStr->EqualsAscii( "." ) ) &&
nPrecision > 0 )
{
// decimal separator after seconds is implied by
// "decimal-places" attribute and must not be written
// as text element
//! difference between '.' and ',' is lost here
}
else if ( nFmtType == NUMBERFORMAT_CURRENCY && !bCurrFound && !bCurrencyWritten )
2000-09-18 16:07:07 +00:00
{
// automatic currency symbol is implemented as part of
// normal text -> search for the symbol
bCurrencyWritten = WriteTextWithCurrency_Impl( *pElemStr,
SvNumberFormatter::ConvertLanguageToLocale( nLang ) );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
}
else
AddToTextElement_Impl( *pElemStr );
2000-09-18 16:07:07 +00:00
}
break;
case NF_KEY_GENERAL :
WriteNumberElement_Impl( -1, 1, OUString(), sal_False );
break;
2000-09-18 16:07:07 +00:00
case NF_KEY_CCC:
if (pElemStr)
{
if ( bCurrencyWritten )
AddToTextElement_Impl( *pElemStr ); // never more than one currency element
else
{
//! must be different from short automatic format
//! but should still be empty (meaning automatic)
// pElemStr is "CCC"
WriteCurrencyElement_Impl( *pElemStr, OUString() );
bAnyContent = sal_True;
bCurrencyWritten = sal_True;
}
}
2000-09-18 16:07:07 +00:00
break;
case XMLNUM_SYMBOLTYPE_CURRENCY:
if (pElemStr)
{
if ( bCurrencyWritten )
AddToTextElement_Impl( *pElemStr ); // never more than one currency element
else
{
WriteCurrencyElement_Impl( *pElemStr, sCurrExt );
bAnyContent = sal_True;
bCurrencyWritten = sal_True;
}
}
2000-09-18 16:07:07 +00:00
break;
case XMLNUM_SYMBOLTYPE_DIGIT:
if (!bNumWritten) // write number part
{
switch ( nFmtType )
{
// for type 0 (not recognized as a special type),
// write a "normal" number
case 0:
2000-09-18 16:07:07 +00:00
case NUMBERFORMAT_NUMBER:
case NUMBERFORMAT_CURRENCY:
case NUMBERFORMAT_PERCENT:
{
// decimals
// only some built-in formats have automatic decimals
sal_Int32 nDecimals = nPrecision; // from GetFormatSpecialInfo
if ( eBuiltIn == NF_NUMBER_STANDARD ||
eBuiltIn == NF_CURRENCY_1000DEC2 ||
eBuiltIn == NF_CURRENCY_1000DEC2_RED ||
eBuiltIn == NF_CURRENCY_1000DEC2_CCC ||
eBuiltIn == NF_CURRENCY_1000DEC2_DASHED )
nDecimals = -1;
// integer digits
// only one built-in format has automatic integer digits
sal_Int32 nInteger = nLeading;
if ( eBuiltIn == NF_NUMBER_SYSTEM )
nInteger = -1;
// string for decimal replacement
// has to be taken from nPrecision
// (positive number even for automatic decimals)
String sDashStr;
if ( bDecDashes && nPrecision > 0 )
sDashStr.Fill( nPrecision, '-' );
WriteNumberElement_Impl( nDecimals, nInteger, sDashStr, bThousand );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
}
break;
case NUMBERFORMAT_SCIENTIFIC:
WriteScientificElement_Impl( nPrecision, nLeading, bThousand, nExpDigits );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
break;
case NUMBERFORMAT_FRACTION:
WriteFractionElement_Impl( nLeading, bThousand, nPrecision, nPrecision );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
break;
}
bNumWritten = sal_True;
}
break;
case XMLNUM_SYMBOLTYPE_DEL:
if ( pElemStr && *pElemStr == XubString('@') )
{
2000-09-18 16:07:07 +00:00
WriteTextContentElement_Impl();
bAnyContent = sal_True;
}
2000-09-18 16:07:07 +00:00
break;
case XMLNUM_SYMBOLTYPE_CALENDAR:
if ( pElemStr )
aCalendar = *pElemStr;
break;
2000-09-18 16:07:07 +00:00
// date elements:
2000-11-24 18:41:01 +00:00
case NF_KEY_D:
case NF_KEY_DD:
2000-09-18 16:07:07 +00:00
{
2000-11-24 18:41:01 +00:00
sal_Bool bLong = ( nElemType == NF_KEY_DD );
WriteDayElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : bLong ) );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
}
break;
2000-11-24 18:41:01 +00:00
case NF_KEY_DDD:
case NF_KEY_DDDD:
2000-09-18 16:07:07 +00:00
case NF_KEY_NN:
case NF_KEY_NNN:
case NF_KEY_NNNN:
2000-11-29 19:37:27 +00:00
case NF_KEY_AAA:
case NF_KEY_AAAA:
2000-09-18 16:07:07 +00:00
{
OUString aCalAttr = aCalendar;
if ( nElemType == NF_KEY_AAA || nElemType == NF_KEY_AAAA )
{
// calendar attribute for AAA and AAAA is switched only for this element
if (!aCalAttr.getLength())
aCalAttr = lcl_GetDefaultCalendar( pFormatter, nLang );
}
2000-09-18 16:07:07 +00:00
sal_Bool bLong = ( nElemType == NF_KEY_NNN || nElemType == NF_KEY_NNNN ||
2000-11-29 19:37:27 +00:00
nElemType == NF_KEY_DDDD || nElemType == NF_KEY_AAAA );
WriteDayOfWeekElement_Impl( aCalAttr, ( bSystemDate ? bLongSysDate : bLong ) );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
if ( nElemType == NF_KEY_NNNN )
{
// write additional text element for separator
pLocaleData->setLocale( SvNumberFormatter::ConvertLanguageToLocale( nLang ) );
AddToTextElement_Impl( pLocaleData->getLongDateDayOfWeekSep() );
2000-09-18 16:07:07 +00:00
}
}
break;
case NF_KEY_M:
case NF_KEY_MM:
case NF_KEY_MMM:
case NF_KEY_MMMM:
case NF_KEY_MMMMM: //! first letter of month name, no attribute available
2000-09-18 16:07:07 +00:00
{
sal_Bool bLong = ( nElemType == NF_KEY_MM || nElemType == NF_KEY_MMMM );
sal_Bool bText = ( nElemType == NF_KEY_MMM || nElemType == NF_KEY_MMMM ||
nElemType == NF_KEY_MMMMM );
WriteMonthElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : bLong ), bText );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
}
break;
2000-11-24 18:41:01 +00:00
case NF_KEY_YY:
case NF_KEY_YYYY:
2000-11-29 19:37:27 +00:00
case NF_KEY_EC:
case NF_KEY_EEC:
case NF_KEY_R: //! R acts as EE, no attribute available
2000-09-18 16:07:07 +00:00
{
//! distinguish EE and R
// calendar attribute for E and EE and R is set in first loop
sal_Bool bLong = ( nElemType == NF_KEY_YYYY || nElemType == NF_KEY_EEC ||
nElemType == NF_KEY_R );
WriteYearElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : bLong ) );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
}
break;
2000-11-29 19:37:27 +00:00
case NF_KEY_G:
case NF_KEY_GG:
case NF_KEY_GGG:
case NF_KEY_RR: //! RR acts as GGGEE, no attribute available
2000-11-29 19:37:27 +00:00
{
//! distinguish GG and GGG and RR
sal_Bool bLong = ( nElemType == NF_KEY_GGG || nElemType == NF_KEY_RR );
WriteEraElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : bLong ) );
bAnyContent = sal_True;
if ( nElemType == NF_KEY_RR )
{
// calendar attribute for RR is set in first loop
WriteYearElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : sal_True ) );
}
2000-11-29 19:37:27 +00:00
}
break;
2000-09-18 16:07:07 +00:00
case NF_KEY_Q:
case NF_KEY_QQ:
{
sal_Bool bLong = ( nElemType == NF_KEY_QQ );
WriteQuarterElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : bLong ) );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
}
break;
case NF_KEY_WW:
WriteWeekElement_Impl( aCalendar );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
break;
// time elements (bSystemDate is not used):
case NF_KEY_H:
case NF_KEY_HH:
WriteHoursElement_Impl( nElemType == NF_KEY_HH );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
break;
case NF_KEY_MI:
case NF_KEY_MMI:
WriteMinutesElement_Impl( nElemType == NF_KEY_MMI );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
break;
case NF_KEY_S:
case NF_KEY_SS:
WriteSecondsElement_Impl( ( nElemType == NF_KEY_SS ), nPrecision );
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
break;
case NF_KEY_AMPM:
case NF_KEY_AP:
WriteAMPMElement_Impl(); // short/long?
bAnyContent = sal_True;
2000-09-18 16:07:07 +00:00
break;
}
nPrevType = nElemType;
++nPos;
}
}
if ( sTextContent.getLength() )
bAnyContent = sal_True; // element written in FinishTextElement_Impl
FinishTextElement_Impl(); // final text element - before maps
if ( !bAnyContent )
{
// for an empty format, write an empty text element
SvXMLElementExport aTElem( rExport, XML_NAMESPACE_NUMBER, XML_TEXT,
sal_True, sal_False );
}
2000-09-18 16:07:07 +00:00
//
// mapping (conditions) must be last elements
//
SvNumberformatLimitOps eOp1, eOp2;
double fLimit1, fLimit2;
rFormat.GetConditions( eOp1, fLimit1, eOp2, fLimit2 );
if (bDefPart)
{
WriteMapElement_Impl( eOp1, fLimit1, nKey, 0 );
WriteMapElement_Impl( eOp2, fLimit2, nKey, 1 );
}
}
//-------------------------------------------------------------------------
//
// export one format
//
void SvXMLNumFmtExport::ExportFormat_Impl( const SvNumberformat& rFormat, sal_uInt32 nKey )
2000-09-18 16:07:07 +00:00
{
sal_uInt16 nUsedParts = 0;
sal_uInt16 nPart;
for (nPart=0; nPart<XMLNUM_MAX_PARTS; nPart++)
if (rFormat.GetNumForType( nPart, 0, sal_False ) != 0)
nUsedParts = nPart+1;
for (nPart=0; nPart<nUsedParts; nPart++)
{
sal_Bool bDefault = ( nPart+1 == nUsedParts ); // last = default
ExportPart_Impl( rFormat, nKey, nPart, bDefault );
}
}
//-------------------------------------------------------------------------
//
// export method called by application
//
void SvXMLNumFmtExport::Export( sal_Bool bIsAutoStyle )
2000-09-18 16:07:07 +00:00
{
if ( !pFormatter )
return; // no formatter -> no entries
sal_uInt32 nKey;
const SvNumberformat* pFormat = NULL;
sal_Bool bNext(pUsedList->GetFirstUsed(nKey));
while(bNext)
2000-09-18 16:07:07 +00:00
{
pFormat = pFormatter->GetEntry(nKey);
if(pFormat)
ExportFormat_Impl( *pFormat, nKey );
bNext = pUsedList->GetNextUsed(nKey);
}
if (!bIsAutoStyle)
{
SvUShorts aLanguages;
pFormatter->GetUsedLanguages( aLanguages );
sal_uInt16 nLangCount = aLanguages.Count();
for (sal_uInt16 nLangPos=0; nLangPos<nLangCount; nLangPos++)
2000-09-18 16:07:07 +00:00
{
LanguageType nLang = aLanguages[nLangPos];
sal_uInt32 nStandard;
SvNumberFormatTable& rTable = pFormatter->GetEntryTable(
NUMBERFORMAT_DEFINED, nStandard, nLang );
SvNumberformat* pFormat = rTable.First();
while (pFormat)
2000-09-18 16:07:07 +00:00
{
sal_uInt32 nKey(rTable.GetCurKey());
if (!pUsedList->IsUsed(nKey))
{
DBG_ASSERT((pFormat->GetType() & NUMBERFORMAT_DEFINED) != 0, "a not user defined numberformat found");
// user-defined and used formats are exported
ExportFormat_Impl( *pFormat, nKey );
// if it is a user-defined Format it will be added else nothing will hapen
pUsedList->SetUsed(nKey);
}
2000-09-18 16:07:07 +00:00
pFormat = rTable.Next();
}
2000-09-18 16:07:07 +00:00
}
}
pUsedList->Export();
}
OUString SvXMLNumFmtExport::GetStyleName( sal_uInt32 nKey )
{
if(pUsedList->IsUsed(nKey) || pUsedList->IsWasUsed(nKey))
return lcl_CreateStyleName( nKey, 0, sal_True, sPrefix );
else
{
DBG_ERROR("There is no written Data-Style");
return rtl::OUString();
}
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::SetUsed( sal_uInt32 nKey )
{
if (pFormatter->GetEntry(nKey))
pUsedList->SetUsed( nKey );
else
DBG_ERROR("no existing Numberformat found with this key");
2000-09-18 16:07:07 +00:00
}
void SvXMLNumFmtExport::GetWasUsed(uno::Sequence<sal_Int32>& rWasUsed)
{
if (pUsedList)
pUsedList->GetWasUsed(rWasUsed);
}
void SvXMLNumFmtExport::SetWasUsed(const uno::Sequence<sal_Int32>& rWasUsed)
{
if (pUsedList)
pUsedList->SetWasUsed(rWasUsed);
}
2000-09-18 16:07:07 +00:00