2010-10-14 08:27:31 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-11-15 17:28:16 +00:00
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
|
|
* with this work for additional information regarding copyright
|
|
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
|
|
* License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
|
|
|
|
*/
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <tools/debug.hxx>
|
2000-11-02 14:37:42 +00:00
|
|
|
#include <comphelper/processfactory.hxx>
|
2011-11-22 23:40:24 +00:00
|
|
|
#include <comphelper/string.hxx>
|
2000-11-09 14:15:19 +00:00
|
|
|
#include <unotools/localedatawrapper.hxx>
|
2000-09-18 16:07:07 +00:00
|
|
|
#include <vcl/svapp.hxx>
|
2013-11-20 06:40:17 -02:00
|
|
|
#include <vcl/builder.hxx>
|
2014-01-02 23:52:37 +01:00
|
|
|
#include <vcl/settings.hxx>
|
2009-10-16 00:05:16 +02:00
|
|
|
#include <svl/zformat.hxx>
|
2013-08-15 17:16:28 +02:00
|
|
|
#include <svtools/fmtfield.hxx>
|
2013-04-05 18:40:39 +02:00
|
|
|
#include <i18nlangtag/languagetag.hxx>
|
2000-11-09 14:15:19 +00:00
|
|
|
#include <com/sun/star/lang/Locale.hpp>
|
2001-06-12 05:29:37 +00:00
|
|
|
#include <com/sun/star/util/SearchOptions.hpp>
|
|
|
|
#include <com/sun/star/util/SearchAlgorithms.hpp>
|
|
|
|
#include <com/sun/star/util/SearchResult.hpp>
|
|
|
|
#include <com/sun/star/util/SearchFlags.hpp>
|
2009-10-16 00:05:16 +02:00
|
|
|
#include <unotools/syslocale.hxx>
|
2003-03-27 13:40:07 +00:00
|
|
|
#include <map>
|
2004-04-02 10:03:26 +00:00
|
|
|
#include <rtl/math.hxx>
|
2012-10-30 00:00:51 +00:00
|
|
|
#include <rtl/ustrbuf.hxx>
|
2004-04-02 10:03:26 +00:00
|
|
|
|
2000-11-09 14:15:19 +00:00
|
|
|
using namespace ::com::sun::star::lang;
|
2000-11-17 07:55:26 +00:00
|
|
|
using namespace ::com::sun::star::util;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2003-03-27 13:40:07 +00:00
|
|
|
// hmm. No support for regular expression. Well, I always (not really :) wanted to write a finite automat
|
|
|
|
// so here comes a finite automat ...
|
|
|
|
|
|
|
|
namespace validation
|
|
|
|
{
|
|
|
|
// the states of our automat.
|
|
|
|
enum State
|
|
|
|
{
|
|
|
|
START, // at the very start of the string
|
|
|
|
NUM_START, // the very start of the number
|
|
|
|
|
|
|
|
DIGIT_PRE_COMMA, // some pre-comma digits are read, perhaps including some thousand separators
|
|
|
|
|
|
|
|
DIGIT_POST_COMMA, // reading digits after the comma
|
|
|
|
EXPONENT_START, // at the very start of the exponent value
|
|
|
|
// (means: not including the "e" which denotes the exponent)
|
|
|
|
EXPONENT_DIGIT, // currently reading the digits of the exponent
|
|
|
|
|
|
|
|
END // reached the end of the string
|
|
|
|
};
|
|
|
|
|
|
|
|
// a row in the transition table (means the set of states to be reached from a given state)
|
|
|
|
typedef ::std::map< sal_Unicode, State > StateTransitions;
|
|
|
|
|
|
|
|
// a single transition
|
|
|
|
typedef StateTransitions::value_type Transition;
|
|
|
|
|
|
|
|
// the complete transition table
|
|
|
|
typedef ::std::map< State, StateTransitions > TransitionTable;
|
|
|
|
|
|
|
|
// the validator class
|
|
|
|
class NumberValidator
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
TransitionTable m_aTransitions;
|
|
|
|
const sal_Unicode m_cThSep;
|
|
|
|
const sal_Unicode m_cDecSep;
|
|
|
|
|
|
|
|
public:
|
|
|
|
NumberValidator( const sal_Unicode _cThSep, const sal_Unicode _cDecSep );
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
bool isValidNumericFragment( const OUString& _rText );
|
2003-03-27 13:40:07 +00:00
|
|
|
|
|
|
|
private:
|
2014-03-20 11:53:43 +02:00
|
|
|
bool implValidateNormalized( const OUString& _rText );
|
2003-03-27 13:40:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void lcl_insertStopTransition( StateTransitions& _rRow )
|
|
|
|
{
|
|
|
|
_rRow.insert( Transition( '_', END ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void lcl_insertStartExponentTransition( StateTransitions& _rRow )
|
|
|
|
{
|
|
|
|
_rRow.insert( Transition( 'e', EXPONENT_START ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void lcl_insertSignTransitions( StateTransitions& _rRow, const State eNextState )
|
|
|
|
{
|
|
|
|
_rRow.insert( Transition( '-', eNextState ) );
|
|
|
|
_rRow.insert( Transition( '+', eNextState ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void lcl_insertDigitTransitions( StateTransitions& _rRow, const State eNextState )
|
|
|
|
{
|
|
|
|
for ( sal_Unicode aChar = '0'; aChar <= '9'; ++aChar )
|
|
|
|
_rRow.insert( Transition( aChar, eNextState ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void lcl_insertCommonPreCommaTransitions( StateTransitions& _rRow, const sal_Unicode _cThSep, const sal_Unicode _cDecSep )
|
|
|
|
{
|
|
|
|
// digits are allowed
|
|
|
|
lcl_insertDigitTransitions( _rRow, DIGIT_PRE_COMMA );
|
|
|
|
|
|
|
|
// the thousand separator is allowed
|
|
|
|
_rRow.insert( Transition( _cThSep, DIGIT_PRE_COMMA ) );
|
|
|
|
|
|
|
|
// a comma is allowed
|
|
|
|
_rRow.insert( Transition( _cDecSep, DIGIT_POST_COMMA ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
NumberValidator::NumberValidator( const sal_Unicode _cThSep, const sal_Unicode _cDecSep )
|
|
|
|
:m_cThSep( _cThSep )
|
|
|
|
,m_cDecSep( _cDecSep )
|
|
|
|
{
|
|
|
|
// build up our transition table
|
|
|
|
|
|
|
|
// how to procede from START
|
|
|
|
{
|
|
|
|
StateTransitions& rRow = m_aTransitions[ START ];
|
|
|
|
rRow.insert( Transition( '_', NUM_START ) );
|
|
|
|
// if we encounter the normalizing character, we want to procede with the number
|
|
|
|
}
|
|
|
|
|
|
|
|
// how to procede from NUM_START
|
|
|
|
{
|
|
|
|
StateTransitions& rRow = m_aTransitions[ NUM_START ];
|
|
|
|
|
|
|
|
// a sign is allowed
|
|
|
|
lcl_insertSignTransitions( rRow, DIGIT_PRE_COMMA );
|
|
|
|
|
|
|
|
// common transitions for the two pre-comma states
|
|
|
|
lcl_insertCommonPreCommaTransitions( rRow, m_cThSep, m_cDecSep );
|
|
|
|
|
|
|
|
// the exponent may start here
|
|
|
|
// (this would mean string like "_+e10_", but this is a valid fragment, though no valid number)
|
|
|
|
lcl_insertStartExponentTransition( rRow );
|
|
|
|
}
|
|
|
|
|
|
|
|
// how to procede from DIGIT_PRE_COMMA
|
|
|
|
{
|
|
|
|
StateTransitions& rRow = m_aTransitions[ DIGIT_PRE_COMMA ];
|
|
|
|
|
|
|
|
// common transitions for the two pre-comma states
|
|
|
|
lcl_insertCommonPreCommaTransitions( rRow, m_cThSep, m_cDecSep );
|
|
|
|
|
|
|
|
// the exponent may start here
|
|
|
|
lcl_insertStartExponentTransition( rRow );
|
|
|
|
|
|
|
|
// the final transition indicating the end of the string
|
|
|
|
// (if there is no comma and no post-comma, then the string may end here)
|
|
|
|
lcl_insertStopTransition( rRow );
|
|
|
|
}
|
|
|
|
|
|
|
|
// how to procede from DIGIT_POST_COMMA
|
|
|
|
{
|
|
|
|
StateTransitions& rRow = m_aTransitions[ DIGIT_POST_COMMA ];
|
|
|
|
|
|
|
|
// there might be digits, which would keep the state at DIGIT_POST_COMMA
|
|
|
|
lcl_insertDigitTransitions( rRow, DIGIT_POST_COMMA );
|
|
|
|
|
|
|
|
// the exponent may start here
|
|
|
|
lcl_insertStartExponentTransition( rRow );
|
|
|
|
|
|
|
|
// the string may end here
|
|
|
|
lcl_insertStopTransition( rRow );
|
|
|
|
}
|
|
|
|
|
|
|
|
// how to procede from EXPONENT_START
|
|
|
|
{
|
|
|
|
StateTransitions& rRow = m_aTransitions[ EXPONENT_START ];
|
|
|
|
|
|
|
|
// there may be a sign
|
|
|
|
lcl_insertSignTransitions( rRow, EXPONENT_DIGIT );
|
|
|
|
|
|
|
|
// there may be digits
|
|
|
|
lcl_insertDigitTransitions( rRow, EXPONENT_DIGIT );
|
|
|
|
|
|
|
|
// the string may end here
|
|
|
|
lcl_insertStopTransition( rRow );
|
|
|
|
}
|
|
|
|
|
|
|
|
// how to procede from EXPONENT_DIGIT
|
|
|
|
{
|
|
|
|
StateTransitions& rRow = m_aTransitions[ EXPONENT_DIGIT ];
|
|
|
|
|
|
|
|
// there may be digits
|
|
|
|
lcl_insertDigitTransitions( rRow, EXPONENT_DIGIT );
|
|
|
|
|
|
|
|
// the string may end here
|
|
|
|
lcl_insertStopTransition( rRow );
|
|
|
|
}
|
|
|
|
|
|
|
|
// how to procede from END
|
|
|
|
{
|
2006-06-19 19:54:42 +00:00
|
|
|
/*StateTransitions& rRow =*/ m_aTransitions[ EXPONENT_DIGIT ];
|
2003-03-27 13:40:07 +00:00
|
|
|
// no valid transition to leave this state
|
|
|
|
// (note that we, for consistency, nevertheless want to have a row in the table)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
bool NumberValidator::implValidateNormalized( const OUString& _rText )
|
2003-03-27 13:40:07 +00:00
|
|
|
{
|
2013-08-21 11:13:04 +02:00
|
|
|
const sal_Unicode* pCheckPos = _rText.getStr();
|
2003-03-27 13:40:07 +00:00
|
|
|
State eCurrentState = START;
|
|
|
|
|
|
|
|
while ( END != eCurrentState )
|
|
|
|
{
|
|
|
|
// look up the transition row for the current state
|
|
|
|
TransitionTable::const_iterator aRow = m_aTransitions.find( eCurrentState );
|
|
|
|
DBG_ASSERT( m_aTransitions.end() != aRow,
|
|
|
|
"NumberValidator::implValidateNormalized: invalid transition table (row not found)!" );
|
|
|
|
|
|
|
|
if ( m_aTransitions.end() != aRow )
|
|
|
|
{
|
|
|
|
// look up the current character in this row
|
|
|
|
StateTransitions::const_iterator aTransition = aRow->second.find( *pCheckPos );
|
|
|
|
if ( aRow->second.end() != aTransition )
|
|
|
|
{
|
|
|
|
// there is a valid transition for this character
|
|
|
|
eCurrentState = aTransition->second;
|
|
|
|
++pCheckPos;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if we're here, there is no valid transition
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
DBG_ASSERT( ( END != eCurrentState ) || ( 0 == *pCheckPos ),
|
|
|
|
"NumberValidator::implValidateNormalized: inconsistency!" );
|
|
|
|
// if we're at END, then the string should be done, too - the string should be normalized, means ending
|
|
|
|
// a "_" and not containing any other "_" (except at the start), and "_" is the only possibility
|
|
|
|
// to reach the END state
|
|
|
|
|
|
|
|
// the string is valid if and only if we reached the final state
|
|
|
|
return ( END == eCurrentState );
|
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
bool NumberValidator::isValidNumericFragment( const OUString& _rText )
|
2003-03-27 13:40:07 +00:00
|
|
|
{
|
2013-08-21 11:13:04 +02:00
|
|
|
if ( _rText.isEmpty() )
|
2003-03-27 13:40:07 +00:00
|
|
|
// empty strings are always allowed
|
2014-03-20 11:53:43 +02:00
|
|
|
return true;
|
2003-03-27 13:40:07 +00:00
|
|
|
|
|
|
|
// normalize the string
|
2013-08-21 11:13:04 +02:00
|
|
|
OUString sNormalized( "_" );
|
|
|
|
sNormalized += _rText;
|
|
|
|
sNormalized += "_";
|
2003-03-27 13:40:07 +00:00
|
|
|
|
|
|
|
return implValidateNormalized( sNormalized );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
SvNumberFormatter* FormattedField::StaticFormatter::s_cFormatter = NULL;
|
2011-01-12 15:56:50 +01:00
|
|
|
sal_uLong FormattedField::StaticFormatter::s_nReferences = 0;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
SvNumberFormatter* FormattedField::StaticFormatter::GetFormatter()
|
|
|
|
{
|
|
|
|
if (!s_cFormatter)
|
2000-11-02 14:37:42 +00:00
|
|
|
{
|
2006-04-07 14:58:57 +00:00
|
|
|
// get the Office's locale and translate
|
2012-11-23 23:06:10 +01:00
|
|
|
LanguageType eSysLanguage = SvtSysLocale().GetLanguageTag().getLanguageType( false);
|
2000-11-02 14:37:42 +00:00
|
|
|
s_cFormatter = new SvNumberFormatter(
|
2013-01-10 16:40:27 +02:00
|
|
|
::comphelper::getProcessComponentContext(),
|
2002-09-26 10:19:37 +00:00
|
|
|
eSysLanguage);
|
2000-11-02 14:37:42 +00:00
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
return s_cFormatter;
|
|
|
|
}
|
|
|
|
|
|
|
|
FormattedField::StaticFormatter::StaticFormatter()
|
|
|
|
{
|
|
|
|
++s_nReferences;
|
|
|
|
}
|
|
|
|
|
|
|
|
FormattedField::StaticFormatter::~StaticFormatter()
|
|
|
|
{
|
|
|
|
if (--s_nReferences == 0)
|
|
|
|
{
|
|
|
|
delete s_cFormatter;
|
|
|
|
s_cFormatter = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-05 10:31:15 +08:00
|
|
|
FormattedField::FormattedField(Window* pParent, WinBits nStyle, SvNumberFormatter* pInitialFormatter, sal_Int32 nFormatKey)
|
2000-09-18 16:07:07 +00:00
|
|
|
:SpinField(pParent, nStyle)
|
2014-03-20 11:53:43 +02:00
|
|
|
,m_aLastSelection(0,0)
|
|
|
|
,m_dMinValue(0)
|
|
|
|
,m_dMaxValue(0)
|
|
|
|
,m_bHasMin(false)
|
|
|
|
,m_bHasMax(false)
|
|
|
|
,m_bStrictFormat(true)
|
|
|
|
,m_bValueDirty(true)
|
|
|
|
,m_bEnableEmptyField(true)
|
|
|
|
,m_bAutoColor(false)
|
|
|
|
,m_bEnableNaN(false)
|
|
|
|
,m_dCurrentValue(0)
|
|
|
|
,m_dDefaultValue(0)
|
|
|
|
,m_nFormatKey(0)
|
|
|
|
,m_pFormatter(NULL)
|
|
|
|
,m_dSpinSize(1)
|
|
|
|
,m_dSpinFirst(-1000000)
|
|
|
|
,m_dSpinLast(1000000)
|
|
|
|
,m_bTreatAsNumber(true)
|
|
|
|
,m_pLastOutputColor(NULL)
|
|
|
|
,m_bUseInputStringForFormatting(false)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
if (pInitialFormatter)
|
|
|
|
{
|
|
|
|
m_pFormatter = pInitialFormatter;
|
|
|
|
m_nFormatKey = nFormatKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-20 06:40:17 -02:00
|
|
|
extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeFormattedField(Window *pParent, VclBuilder::stringmap &)
|
|
|
|
{
|
|
|
|
WinBits nWinBits = WB_BORDER;
|
|
|
|
return new FormattedField(pParent, nWinBits);
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
FormattedField::~FormattedField()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-01-21 14:32:09 +01:00
|
|
|
void FormattedField::SetText(const OUString& rStr)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
SpinField::SetText(rStr);
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bValueDirty = true;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2013-01-21 14:32:09 +01:00
|
|
|
void FormattedField::SetText( const OUString& rStr, const Selection& rNewSelection )
|
2006-06-19 19:54:42 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
SpinField::SetText( rStr, rNewSelection );
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bValueDirty = true;
|
2006-06-19 19:54:42 +00:00
|
|
|
}
|
|
|
|
|
2012-09-12 23:24:07 +01:00
|
|
|
void FormattedField::SetTextFormatted(const OUString& rStr)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
|
2006-10-12 14:12:16 +00:00
|
|
|
#if defined DBG_UTIL
|
2000-09-18 16:07:07 +00:00
|
|
|
if (ImplGetFormatter()->IsTextFormat(m_nFormatKey))
|
|
|
|
DBG_WARNING("FormattedField::SetTextFormatted : valid only with text formats !");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
m_sCurrentTextValue = rStr;
|
|
|
|
|
2013-01-21 14:32:09 +01:00
|
|
|
OUString sFormatted;
|
2007-09-18 13:50:30 +00:00
|
|
|
double dNumber = 0.0;
|
|
|
|
// IsNumberFormat changes the format key parameter
|
|
|
|
sal_uInt32 nTempFormatKey = static_cast< sal_uInt32 >( m_nFormatKey );
|
|
|
|
if( IsUsingInputStringForFormatting() &&
|
|
|
|
ImplGetFormatter()->IsNumberFormat(m_sCurrentTextValue, nTempFormatKey, dNumber) )
|
2012-11-18 18:55:49 -06:00
|
|
|
{
|
2007-09-18 13:50:30 +00:00
|
|
|
ImplGetFormatter()->GetInputLineString(dNumber, m_nFormatKey, sFormatted);
|
2012-11-18 18:55:49 -06:00
|
|
|
}
|
2007-09-18 13:50:30 +00:00
|
|
|
else
|
2012-11-18 18:55:49 -06:00
|
|
|
{
|
2014-02-24 09:05:50 +01:00
|
|
|
ImplGetFormatter()->GetOutputString(m_sCurrentTextValue,
|
|
|
|
m_nFormatKey,
|
|
|
|
sFormatted,
|
|
|
|
&m_pLastOutputColor);
|
2012-11-18 18:55:49 -06:00
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// calculate the new selection
|
|
|
|
Selection aSel(GetSelection());
|
|
|
|
Selection aNewSel(aSel);
|
|
|
|
aNewSel.Justify();
|
2013-01-21 14:32:09 +01:00
|
|
|
sal_Int32 nNewLen = sFormatted.getLength();
|
|
|
|
sal_Int32 nCurrentLen = GetText().getLength();
|
2000-09-18 16:07:07 +00:00
|
|
|
if ((nNewLen > nCurrentLen) && (aNewSel.Max() == nCurrentLen))
|
|
|
|
{ // the new text is longer and the cursor was behind the last char (of the old text)
|
|
|
|
if (aNewSel.Min() == 0)
|
|
|
|
{ // the whole text was selected -> select the new text on the whole, too
|
|
|
|
aNewSel.Max() = nNewLen;
|
|
|
|
if (!nCurrentLen)
|
|
|
|
{ // there wasn't really a previous selection (as there was no previous text), we're setting a new one -> check the selection options
|
2011-01-12 15:56:50 +01:00
|
|
|
sal_uLong nSelOptions = GetSettings().GetStyleSettings().GetSelectionOptions();
|
2000-09-18 16:07:07 +00:00
|
|
|
if (nSelOptions & SELECTION_OPTION_SHOWFIRST)
|
|
|
|
{ // selection should be from right to left -> swap min and max
|
|
|
|
aNewSel.Min() = aNewSel.Max();
|
|
|
|
aNewSel.Max() = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (aNewSel.Max() == aNewSel.Min())
|
|
|
|
{ // there was no selection -> set the cursor behind the new last char
|
|
|
|
aNewSel.Max() = nNewLen;
|
|
|
|
aNewSel.Min() = nNewLen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (aNewSel.Max() > nNewLen)
|
|
|
|
aNewSel.Max() = nNewLen;
|
|
|
|
else
|
|
|
|
aNewSel = aSel; // don't use the justified version
|
|
|
|
SpinField::SetText(sFormatted, aNewSel);
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bValueDirty = false;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2013-08-19 13:06:37 +02:00
|
|
|
OUString FormattedField::GetTextValue() const
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
if (m_bValueDirty)
|
|
|
|
{
|
|
|
|
((FormattedField*)this)->m_sCurrentTextValue = GetText();
|
2014-03-20 11:53:43 +02:00
|
|
|
((FormattedField*)this)->m_bValueDirty = false;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
return m_sCurrentTextValue;
|
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
void FormattedField::EnableNotANumber( bool _bEnable )
|
2004-04-02 10:03:26 +00:00
|
|
|
{
|
|
|
|
if ( m_bEnableNaN == _bEnable )
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_bEnableNaN = _bEnable;
|
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
void FormattedField::SetAutoColor(bool _bAutomatic)
|
2001-05-17 10:14:15 +00:00
|
|
|
{
|
|
|
|
if (_bAutomatic == m_bAutoColor)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_bAutoColor = _bAutomatic;
|
|
|
|
if (m_bAutoColor)
|
|
|
|
{ // if auto color is switched on, adjust the current text color, too
|
|
|
|
if (m_pLastOutputColor)
|
|
|
|
SetControlForeground(*m_pLastOutputColor);
|
|
|
|
else
|
|
|
|
SetControlForeground();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-15 07:24:43 +02:00
|
|
|
void FormattedField::impl_Modify(bool makeValueDirty)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
if (!IsStrictFormat())
|
|
|
|
{
|
2013-05-15 07:24:43 +02:00
|
|
|
if(makeValueDirty)
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bValueDirty = true;
|
2000-09-18 16:07:07 +00:00
|
|
|
SpinField::Modify();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-08-21 11:13:04 +02:00
|
|
|
OUString sCheck = GetText();
|
2000-09-18 16:07:07 +00:00
|
|
|
if (CheckText(sCheck))
|
|
|
|
{
|
|
|
|
m_sLastValidText = sCheck;
|
|
|
|
m_aLastSelection = GetSelection();
|
2013-05-15 07:24:43 +02:00
|
|
|
if(makeValueDirty)
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bValueDirty = true;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-04-11 18:45:37 +00:00
|
|
|
ImplSetTextImpl(m_sLastValidText, &m_aLastSelection);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SpinField::Modify();
|
|
|
|
}
|
|
|
|
|
2013-05-15 07:24:43 +02:00
|
|
|
void FormattedField::Modify()
|
|
|
|
{
|
|
|
|
|
|
|
|
impl_Modify();
|
|
|
|
}
|
|
|
|
|
2013-01-21 14:32:09 +01:00
|
|
|
void FormattedField::ImplSetTextImpl(const OUString& rNew, Selection* pNewSel)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
|
2001-01-04 09:50:31 +00:00
|
|
|
if (m_bAutoColor)
|
|
|
|
{
|
|
|
|
if (m_pLastOutputColor)
|
|
|
|
SetControlForeground(*m_pLastOutputColor);
|
|
|
|
else
|
|
|
|
SetControlForeground();
|
|
|
|
}
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
if (pNewSel)
|
|
|
|
SpinField::SetText(rNew, *pNewSel);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Selection aSel(GetSelection());
|
|
|
|
aSel.Justify();
|
|
|
|
|
2013-01-21 14:32:09 +01:00
|
|
|
sal_Int32 nNewLen = rNew.getLength();
|
|
|
|
sal_Int32 nCurrentLen = GetText().getLength();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
if ((nNewLen > nCurrentLen) && (aSel.Max() == nCurrentLen))
|
|
|
|
{ // new new text is longer and the cursor is behind the last char
|
|
|
|
if (aSel.Min() == 0)
|
|
|
|
{ // the whole text was selected -> select the new text on the whole, too
|
|
|
|
aSel.Max() = nNewLen;
|
|
|
|
if (!nCurrentLen)
|
|
|
|
{ // there wasn't really a previous selection (as there was no previous text), we're setting a new one -> check the selection options
|
2011-01-12 15:56:50 +01:00
|
|
|
sal_uLong nSelOptions = GetSettings().GetStyleSettings().GetSelectionOptions();
|
2000-09-18 16:07:07 +00:00
|
|
|
if (nSelOptions & SELECTION_OPTION_SHOWFIRST)
|
|
|
|
{ // selection should be from right to left -> swap min and max
|
|
|
|
aSel.Min() = aSel.Max();
|
|
|
|
aSel.Max() = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (aSel.Max() == aSel.Min())
|
|
|
|
{ // there was no selection -> set the cursor behind the new last char
|
|
|
|
aSel.Max() = nNewLen;
|
|
|
|
aSel.Min() = nNewLen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (aSel.Max() > nNewLen)
|
|
|
|
aSel.Max() = nNewLen;
|
|
|
|
SpinField::SetText(rNew, aSel);
|
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bValueDirty = true; // not always necessary, but better re-evaluate for safety reasons
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2014-01-18 00:18:52 +01:00
|
|
|
bool FormattedField::PreNotify(NotifyEvent& rNEvt)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
if (rNEvt.GetType() == EVENT_KEYINPUT)
|
|
|
|
m_aLastSelection = GetSelection();
|
|
|
|
return SpinField::PreNotify(rNEvt);
|
|
|
|
}
|
|
|
|
|
2011-01-12 15:56:50 +01:00
|
|
|
void FormattedField::ImplSetFormatKey(sal_uLong nFormatKey)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
m_nFormatKey = nFormatKey;
|
2014-03-20 11:53:43 +02:00
|
|
|
bool bNeedFormatter = (m_pFormatter == NULL) && (nFormatKey != 0);
|
2000-09-18 16:07:07 +00:00
|
|
|
if (bNeedFormatter)
|
|
|
|
{
|
2013-08-31 22:37:30 +02:00
|
|
|
ImplGetFormatter(); // this creates a standard formatter
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2013-08-31 22:37:30 +02:00
|
|
|
// It might happen that the standard formatter makes no sense here, but it takes a default
|
|
|
|
// format. Thus, it is possible to set one of the other standard keys (which are spanning
|
|
|
|
// across multiple formatters).
|
2000-09-18 16:07:07 +00:00
|
|
|
m_nFormatKey = nFormatKey;
|
2013-08-31 22:37:30 +02:00
|
|
|
// When calling SetFormatKey without a formatter, the key must be one of the standard values
|
|
|
|
// that is available for all formatters (and, thus, also in this new one).
|
2000-09-18 16:07:07 +00:00
|
|
|
DBG_ASSERT(m_pFormatter->GetEntry(nFormatKey) != NULL, "FormattedField::ImplSetFormatKey : invalid format key !");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-12 15:56:50 +01:00
|
|
|
void FormattedField::SetFormatKey(sal_uLong nFormatKey)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2014-03-20 11:53:43 +02:00
|
|
|
bool bNoFormatter = (m_pFormatter == NULL);
|
2000-09-18 16:07:07 +00:00
|
|
|
ImplSetFormatKey(nFormatKey);
|
|
|
|
FormatChanged((bNoFormatter && (m_pFormatter != NULL)) ? FCT_FORMATTER : FCT_KEYONLY);
|
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
void FormattedField::SetFormatter(SvNumberFormatter* pFormatter, bool bResetFormat)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
if (bResetFormat)
|
|
|
|
{
|
|
|
|
m_pFormatter = pFormatter;
|
2001-08-24 05:44:51 +00:00
|
|
|
|
|
|
|
// calc the default format key from the Office's UI locale
|
|
|
|
if ( m_pFormatter )
|
|
|
|
{
|
2006-04-07 14:58:57 +00:00
|
|
|
// get the Office's locale and translate
|
2012-11-23 23:06:10 +01:00
|
|
|
LanguageType eSysLanguage = SvtSysLocale().GetLanguageTag().getLanguageType( false);
|
2001-08-24 05:44:51 +00:00
|
|
|
// get the standard numeric format for this language
|
|
|
|
m_nFormatKey = m_pFormatter->GetStandardFormat( NUMBERFORMAT_NUMBER, eSysLanguage );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_nFormatKey = 0;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LanguageType aOldLang;
|
2012-09-12 23:24:07 +01:00
|
|
|
OUString sOldFormat = GetFormat(aOldLang);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2005-12-14 14:00:52 +00:00
|
|
|
sal_uInt32 nDestKey = pFormatter->TestNewString(sOldFormat);
|
2000-09-18 16:07:07 +00:00
|
|
|
if (nDestKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
|
|
|
|
{
|
2013-08-31 22:37:30 +02:00
|
|
|
// language of the new formatter
|
2000-09-18 16:07:07 +00:00
|
|
|
const SvNumberformat* pDefaultEntry = pFormatter->GetEntry(0);
|
|
|
|
LanguageType aNewLang = pDefaultEntry ? pDefaultEntry->GetLanguage() : LANGUAGE_DONTKNOW;
|
|
|
|
|
2013-08-31 22:37:30 +02:00
|
|
|
// convert the old format string into the new language
|
2012-11-18 14:01:16 -06:00
|
|
|
sal_Int32 nCheckPos;
|
2000-09-18 16:07:07 +00:00
|
|
|
short nType;
|
|
|
|
pFormatter->PutandConvertEntry(sOldFormat, nCheckPos, nType, nDestKey, aOldLang, aNewLang);
|
|
|
|
m_nFormatKey = nDestKey;
|
|
|
|
}
|
|
|
|
m_pFormatter = pFormatter;
|
|
|
|
}
|
|
|
|
|
|
|
|
FormatChanged(FCT_FORMATTER);
|
|
|
|
}
|
|
|
|
|
2012-09-12 23:24:07 +01:00
|
|
|
OUString FormattedField::GetFormat(LanguageType& eLang) const
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey);
|
2003-03-27 13:40:07 +00:00
|
|
|
DBG_ASSERT(pFormatEntry != NULL, "FormattedField::GetFormat: no number format for the given format key.");
|
2012-09-12 23:24:07 +01:00
|
|
|
OUString sFormatString = pFormatEntry ? pFormatEntry->GetFormatstring() : OUString();
|
2000-09-18 16:07:07 +00:00
|
|
|
eLang = pFormatEntry ? pFormatEntry->GetLanguage() : LANGUAGE_DONTKNOW;
|
2012-09-12 23:24:07 +01:00
|
|
|
|
|
|
|
return sFormatString;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
bool FormattedField::SetFormat(const OUString& rFormatString, LanguageType eLang)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2005-12-14 14:00:52 +00:00
|
|
|
sal_uInt32 nNewKey = ImplGetFormatter()->TestNewString(rFormatString, eLang);
|
2000-09-18 16:07:07 +00:00
|
|
|
if (nNewKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
|
|
|
|
{
|
2012-11-27 22:58:50 -06:00
|
|
|
sal_Int32 nCheckPos;
|
2000-09-18 16:07:07 +00:00
|
|
|
short nType;
|
2012-11-27 22:58:50 -06:00
|
|
|
OUString rFormat(rFormatString);
|
2002-09-27 12:49:10 +00:00
|
|
|
if (!ImplGetFormatter()->PutEntry(rFormat, nCheckPos, nType, nNewKey, eLang))
|
2014-03-20 11:53:43 +02:00
|
|
|
return false;
|
2000-09-18 16:07:07 +00:00
|
|
|
DBG_ASSERT(nNewKey != NUMBERFORMAT_ENTRY_NOT_FOUND, "FormattedField::SetFormatString : PutEntry returned an invalid key !");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nNewKey != m_nFormatKey)
|
|
|
|
SetFormatKey(nNewKey);
|
2014-03-20 11:53:43 +02:00
|
|
|
return true;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
bool FormattedField::GetThousandsSep() const
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
|
2013-08-31 22:30:22 +02:00
|
|
|
"FormattedField::GetThousandsSep : Are you sure what you are doing when setting the precision of a text format?");
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2011-08-10 01:32:41 +02:00
|
|
|
bool bThousand, IsRed;
|
2010-11-05 10:31:15 +08:00
|
|
|
sal_uInt16 nPrecision, nAnzLeading;
|
2000-09-18 16:07:07 +00:00
|
|
|
ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
|
|
|
|
|
|
|
|
return bThousand;
|
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
void FormattedField::SetThousandsSep(bool _bUseSeparator)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
|
2013-08-31 22:30:22 +02:00
|
|
|
"FormattedField::SetThousandsSep : Are you sure what you are doing when setting the precision of a text format?");
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// get the current settings
|
2011-08-10 01:32:41 +02:00
|
|
|
bool bThousand, IsRed;
|
2010-11-05 10:31:15 +08:00
|
|
|
sal_uInt16 nPrecision, nAnzLeading;
|
2000-09-18 16:07:07 +00:00
|
|
|
ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
|
2011-10-05 17:37:50 +03:00
|
|
|
if (bThousand == (bool)_bUseSeparator)
|
2000-09-18 16:07:07 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// we need the language for the following
|
|
|
|
LanguageType eLang;
|
2012-10-02 10:19:18 +01:00
|
|
|
GetFormat(eLang);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// generate a new format ...
|
2012-10-02 10:19:18 +01:00
|
|
|
OUString sFmtDescription = ImplGetFormatter()->GenerateFormat(m_nFormatKey, eLang, _bUseSeparator, IsRed, nPrecision, nAnzLeading);
|
2000-09-18 16:07:07 +00:00
|
|
|
// ... and introduce it to the formatter
|
2012-11-21 21:11:17 +00:00
|
|
|
sal_Int32 nCheckPos = 0;
|
|
|
|
sal_uInt32 nNewKey;
|
2000-09-18 16:07:07 +00:00
|
|
|
short nType;
|
|
|
|
ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang);
|
|
|
|
|
|
|
|
// set the new key
|
|
|
|
ImplSetFormatKey(nNewKey);
|
|
|
|
FormatChanged(FCT_THOUSANDSSEP);
|
|
|
|
}
|
|
|
|
|
2010-11-05 10:31:15 +08:00
|
|
|
sal_uInt16 FormattedField::GetDecimalDigits() const
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
|
2013-08-31 22:30:22 +02:00
|
|
|
"FormattedField::GetDecimalDigits : Are you sure what you are doing when setting the precision of a text format?");
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2011-08-10 01:32:41 +02:00
|
|
|
bool bThousand, IsRed;
|
2010-11-05 10:31:15 +08:00
|
|
|
sal_uInt16 nPrecision, nAnzLeading;
|
2000-09-18 16:07:07 +00:00
|
|
|
ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
|
|
|
|
|
|
|
|
return nPrecision;
|
|
|
|
}
|
|
|
|
|
2010-11-05 10:31:15 +08:00
|
|
|
void FormattedField::SetDecimalDigits(sal_uInt16 _nPrecision)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
|
2013-08-31 22:30:22 +02:00
|
|
|
"FormattedField::SetDecimalDigits : Are you sure what you are doing when setting the precision of a text format?");
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// get the current settings
|
2011-08-10 01:32:41 +02:00
|
|
|
bool bThousand, IsRed;
|
2010-11-05 10:31:15 +08:00
|
|
|
sal_uInt16 nPrecision, nAnzLeading;
|
2000-09-18 16:07:07 +00:00
|
|
|
ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
|
|
|
|
if (nPrecision == _nPrecision)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// we need the language for the following
|
|
|
|
LanguageType eLang;
|
2012-10-02 10:19:18 +01:00
|
|
|
GetFormat(eLang);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// generate a new format ...
|
2012-10-02 10:19:18 +01:00
|
|
|
OUString sFmtDescription = ImplGetFormatter()->GenerateFormat(m_nFormatKey, eLang, bThousand, IsRed, _nPrecision, nAnzLeading);
|
2000-09-18 16:07:07 +00:00
|
|
|
// ... and introduce it to the formatter
|
2012-11-21 21:11:17 +00:00
|
|
|
sal_Int32 nCheckPos = 0;
|
2005-12-14 14:00:52 +00:00
|
|
|
sal_uInt32 nNewKey;
|
2000-09-18 16:07:07 +00:00
|
|
|
short nType;
|
|
|
|
ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang);
|
|
|
|
|
|
|
|
// set the new key
|
|
|
|
ImplSetFormatKey(nNewKey);
|
|
|
|
FormatChanged(FCT_PRECISION);
|
|
|
|
}
|
|
|
|
|
2002-04-03 09:10:05 +00:00
|
|
|
void FormattedField::FormatChanged( FORMAT_CHANGE_TYPE _nWhat )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
m_pLastOutputColor = NULL;
|
2002-04-03 09:10:05 +00:00
|
|
|
|
2002-10-18 14:15:29 +00:00
|
|
|
if ( ( 0 != ( _nWhat & FCT_FORMATTER ) ) && m_pFormatter )
|
2002-04-03 09:10:05 +00:00
|
|
|
m_pFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_INTL_FORMAT );
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
ReFormat();
|
|
|
|
}
|
|
|
|
|
2002-10-15 06:38:03 +00:00
|
|
|
void FormattedField::Commit()
|
|
|
|
{
|
|
|
|
// remember the old text
|
2013-01-21 14:32:09 +01:00
|
|
|
OUString sOld( GetText() );
|
2002-10-15 06:38:03 +00:00
|
|
|
|
|
|
|
// do the reformat
|
|
|
|
ReFormat();
|
|
|
|
|
|
|
|
// did the text change?
|
|
|
|
if ( GetText() != sOld )
|
2013-05-15 07:24:43 +02:00
|
|
|
{ // consider the field as modified,
|
|
|
|
// but we already have the most recent value;
|
|
|
|
// don't reparse it from the text
|
|
|
|
// (can lead to data loss when the format is lossy,
|
|
|
|
// as is e.g. our default date format: 2-digit year!)
|
|
|
|
impl_Modify(false);
|
2002-10-15 06:38:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
void FormattedField::ReFormat()
|
|
|
|
{
|
2013-01-21 14:32:09 +01:00
|
|
|
if (!IsEmptyFieldEnabled() || !GetText().isEmpty())
|
2008-12-11 07:05:03 +00:00
|
|
|
{
|
2000-09-18 16:07:07 +00:00
|
|
|
if (TreatingAsNumber())
|
2004-04-02 10:03:26 +00:00
|
|
|
{
|
|
|
|
double dValue = GetValue();
|
|
|
|
if ( m_bEnableNaN && ::rtl::math::isNan( dValue ) )
|
|
|
|
return;
|
2014-03-20 11:53:43 +02:00
|
|
|
ImplSetValue( dValue, true );
|
2004-04-02 10:03:26 +00:00
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
else
|
|
|
|
SetTextFormatted(GetTextValue());
|
2008-12-11 07:05:03 +00:00
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2014-01-17 16:40:50 +01:00
|
|
|
bool FormattedField::Notify(NotifyEvent& rNEvt)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
if ((rNEvt.GetType() == EVENT_KEYINPUT) && !IsReadOnly())
|
|
|
|
{
|
|
|
|
const KeyEvent& rKEvt = *rNEvt.GetKeyEvent();
|
2010-11-05 10:31:15 +08:00
|
|
|
sal_uInt16 nMod = rKEvt.GetKeyCode().GetModifier();
|
2000-09-18 16:07:07 +00:00
|
|
|
switch ( rKEvt.GetKeyCode().GetCode() )
|
|
|
|
{
|
|
|
|
case KEY_UP:
|
|
|
|
case KEY_DOWN:
|
|
|
|
case KEY_PAGEUP:
|
|
|
|
case KEY_PAGEDOWN:
|
|
|
|
if (!nMod && ImplGetFormatter()->IsTextFormat(m_nFormatKey))
|
|
|
|
{
|
|
|
|
// the base class would translate this into calls to Up/Down/First/Last,
|
|
|
|
// but we don't want this if we are text-formatted
|
2014-01-17 16:40:50 +01:00
|
|
|
return true;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((rNEvt.GetType() == EVENT_COMMAND) && !IsReadOnly())
|
|
|
|
{
|
|
|
|
const CommandEvent* pCommand = rNEvt.GetCommandEvent();
|
|
|
|
if (pCommand->GetCommand() == COMMAND_WHEEL)
|
|
|
|
{
|
|
|
|
const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
|
|
|
|
if ((pData->GetMode() == COMMAND_WHEEL_SCROLL) && ImplGetFormatter()->IsTextFormat(m_nFormatKey))
|
|
|
|
{
|
|
|
|
// same as above : prevent the base class from doing Up/Down-calls
|
|
|
|
// (normally I should put this test into the Up/Down methods itself, shouldn't I ?)
|
|
|
|
// FS - 71553 - 19.01.00
|
2014-01-17 16:40:50 +01:00
|
|
|
return true;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rNEvt.GetType() == EVENT_LOSEFOCUS)
|
|
|
|
{
|
|
|
|
// Sonderbehandlung fuer leere Texte
|
2013-01-21 14:32:09 +01:00
|
|
|
if (GetText().isEmpty())
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
if (!IsEmptyFieldEnabled())
|
|
|
|
{
|
|
|
|
if (TreatingAsNumber())
|
|
|
|
{
|
2014-03-20 11:53:43 +02:00
|
|
|
ImplSetValue(m_dCurrentValue, true);
|
2000-09-18 16:07:07 +00:00
|
|
|
Modify();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-08-21 11:13:04 +02:00
|
|
|
OUString sNew = GetTextValue();
|
|
|
|
if (!sNew.isEmpty())
|
2000-09-18 16:07:07 +00:00
|
|
|
SetTextFormatted(sNew);
|
|
|
|
else
|
|
|
|
SetTextFormatted(m_sDefaultText);
|
|
|
|
}
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bValueDirty = false;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-10-15 06:38:03 +00:00
|
|
|
Commit();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return SpinField::Notify( rNEvt );
|
|
|
|
}
|
|
|
|
|
|
|
|
void FormattedField::SetMinValue(double dMin)
|
|
|
|
{
|
|
|
|
DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMinValue : only to be used in numeric mode !");
|
|
|
|
|
|
|
|
m_dMinValue = dMin;
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bHasMin = true;
|
2013-08-31 22:37:30 +02:00
|
|
|
// for checking the current value at the new border -> ImplSetValue
|
2000-09-18 16:07:07 +00:00
|
|
|
ReFormat();
|
|
|
|
}
|
|
|
|
|
|
|
|
void FormattedField::SetMaxValue(double dMax)
|
|
|
|
{
|
|
|
|
DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMaxValue : only to be used in numeric mode !");
|
|
|
|
|
|
|
|
m_dMaxValue = dMax;
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bHasMax = true;
|
2013-08-31 22:37:30 +02:00
|
|
|
// for checking the current value at the new border -> ImplSetValue
|
2000-09-18 16:07:07 +00:00
|
|
|
ReFormat();
|
|
|
|
}
|
|
|
|
|
2012-09-12 23:24:07 +01:00
|
|
|
void FormattedField::SetTextValue(const OUString& rText)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
SetText(rText);
|
|
|
|
ReFormat();
|
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
void FormattedField::EnableEmptyField(bool bEnable)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
if (bEnable == m_bEnableEmptyField)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_bEnableEmptyField = bEnable;
|
2013-01-21 14:32:09 +01:00
|
|
|
if (!m_bEnableEmptyField && GetText().isEmpty())
|
2014-03-20 11:53:43 +02:00
|
|
|
ImplSetValue(m_dCurrentValue, true);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
void FormattedField::ImplSetValue(double dVal, bool bForce)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
if (m_bHasMin && (dVal<m_dMinValue))
|
|
|
|
dVal = m_dMinValue;
|
|
|
|
if (m_bHasMax && (dVal>m_dMaxValue))
|
|
|
|
dVal = m_dMaxValue;
|
|
|
|
if (!bForce && (dVal == GetValue()))
|
|
|
|
return;
|
|
|
|
|
|
|
|
DBG_ASSERT(ImplGetFormatter() != NULL, "FormattedField::ImplSetValue : can't set a value without a formatter !");
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bValueDirty = false;
|
2000-09-18 16:07:07 +00:00
|
|
|
m_dCurrentValue = dVal;
|
|
|
|
|
2013-07-05 16:25:03 -05:00
|
|
|
OUString sNewText;
|
2000-09-18 16:07:07 +00:00
|
|
|
if (ImplGetFormatter()->IsTextFormat(m_nFormatKey))
|
|
|
|
{
|
2013-08-31 22:37:30 +02:00
|
|
|
// first convert the number as string in standard format
|
2013-07-05 16:25:03 -05:00
|
|
|
OUString sTemp;
|
2000-09-18 16:07:07 +00:00
|
|
|
ImplGetFormatter()->GetOutputString(dVal, 0, sTemp, &m_pLastOutputColor);
|
2014-02-24 09:05:50 +01:00
|
|
|
// then encode the string in the corresponding text format
|
|
|
|
ImplGetFormatter()->GetOutputString(sTemp, m_nFormatKey, sNewText, &m_pLastOutputColor);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-09-18 13:50:30 +00:00
|
|
|
if( IsUsingInputStringForFormatting())
|
2012-11-18 18:55:49 -06:00
|
|
|
{
|
2007-09-18 13:50:30 +00:00
|
|
|
ImplGetFormatter()->GetInputLineString(dVal, m_nFormatKey, sNewText);
|
2012-11-18 18:55:49 -06:00
|
|
|
}
|
2007-09-18 13:50:30 +00:00
|
|
|
else
|
2012-11-18 18:55:49 -06:00
|
|
|
{
|
2007-09-18 13:50:30 +00:00
|
|
|
ImplGetFormatter()->GetOutputString(dVal, m_nFormatKey, sNewText, &m_pLastOutputColor);
|
2012-11-18 18:55:49 -06:00
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2007-04-11 18:45:37 +00:00
|
|
|
ImplSetTextImpl(sNewText, NULL);
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bValueDirty = false;
|
2000-09-18 16:07:07 +00:00
|
|
|
DBG_ASSERT(CheckText(sNewText), "FormattedField::ImplSetValue : formatted string doesn't match the criteria !");
|
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
bool FormattedField::ImplGetValue(double& dNewVal)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
dNewVal = m_dCurrentValue;
|
|
|
|
if (!m_bValueDirty)
|
2014-03-20 11:53:43 +02:00
|
|
|
return true;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
dNewVal = m_dDefaultValue;
|
2013-08-21 11:13:04 +02:00
|
|
|
OUString sText(GetText());
|
|
|
|
if (sText.isEmpty())
|
2014-03-20 11:53:43 +02:00
|
|
|
return true;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
DBG_ASSERT(ImplGetFormatter() != NULL, "FormattedField::ImplGetValue : can't give you a current value without a formatter !");
|
|
|
|
|
2013-08-31 22:37:30 +02:00
|
|
|
sal_uInt32 nFormatKey = m_nFormatKey; // IsNumberFormat changes the FormatKey!
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
if (ImplGetFormatter()->IsTextFormat(nFormatKey) && m_bTreatAsNumber)
|
2013-08-31 22:37:30 +02:00
|
|
|
// for detection of values like "1,1" in fields that are formated as text
|
2000-09-18 16:07:07 +00:00
|
|
|
nFormatKey = 0;
|
|
|
|
|
2013-08-31 22:37:30 +02:00
|
|
|
// special treatment for percentage formatting
|
2000-09-18 16:07:07 +00:00
|
|
|
if (ImplGetFormatter()->GetType(m_nFormatKey) == NUMBERFORMAT_PERCENT)
|
|
|
|
{
|
2001-02-05 11:36:37 +00:00
|
|
|
// the language of our format
|
|
|
|
LanguageType eLanguage = m_pFormatter->GetEntry(m_nFormatKey)->GetLanguage();
|
|
|
|
// the default number format for this language
|
2011-01-12 15:56:50 +01:00
|
|
|
sal_uLong nStandardNumericFormat = m_pFormatter->GetStandardFormat(NUMBERFORMAT_NUMBER, eLanguage);
|
2001-02-05 11:36:37 +00:00
|
|
|
|
2005-12-14 14:00:52 +00:00
|
|
|
sal_uInt32 nTempFormat = nStandardNumericFormat;
|
2000-09-18 16:07:07 +00:00
|
|
|
double dTemp;
|
|
|
|
if (m_pFormatter->IsNumberFormat(sText, nTempFormat, dTemp) &&
|
|
|
|
NUMBERFORMAT_NUMBER == m_pFormatter->GetType(nTempFormat))
|
2013-08-31 22:37:30 +02:00
|
|
|
// the string is equivalent to a number formatted one (has no % sign) -> append it
|
2013-08-21 11:13:04 +02:00
|
|
|
sText += "%";
|
2001-02-05 11:36:37 +00:00
|
|
|
// (with this, a input of '3' becomes '3%', which then by the formatter is translated
|
|
|
|
// into 0.03. Without this, the formatter would give us the double 3 for an input '3',
|
|
|
|
// which equals 300 percent.
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
if (!ImplGetFormatter()->IsNumberFormat(sText, nFormatKey, dNewVal))
|
2014-03-20 11:53:43 +02:00
|
|
|
return false;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
if (m_bHasMin && (dNewVal<m_dMinValue))
|
|
|
|
dNewVal = m_dMinValue;
|
|
|
|
if (m_bHasMax && (dNewVal>m_dMaxValue))
|
|
|
|
dNewVal = m_dMaxValue;
|
2014-03-20 11:53:43 +02:00
|
|
|
return true;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FormattedField::SetValue(double dVal)
|
|
|
|
{
|
|
|
|
ImplSetValue(dVal, m_bValueDirty);
|
|
|
|
}
|
|
|
|
|
|
|
|
double FormattedField::GetValue()
|
|
|
|
{
|
|
|
|
|
2004-04-02 10:03:26 +00:00
|
|
|
if ( !ImplGetValue( m_dCurrentValue ) )
|
2008-12-11 07:05:03 +00:00
|
|
|
{
|
2004-04-02 10:03:26 +00:00
|
|
|
if ( m_bEnableNaN )
|
|
|
|
::rtl::math::setNan( &m_dCurrentValue );
|
|
|
|
else
|
|
|
|
m_dCurrentValue = m_dDefaultValue;
|
2008-12-11 07:05:03 +00:00
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bValueDirty = false;
|
2000-09-18 16:07:07 +00:00
|
|
|
return m_dCurrentValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FormattedField::Up()
|
|
|
|
{
|
2013-08-31 22:37:30 +02:00
|
|
|
// setValue handles under- and overflows (min/max) automatically
|
2000-09-18 16:07:07 +00:00
|
|
|
SetValue(GetValue() + m_dSpinSize);
|
|
|
|
SetModifyFlag();
|
|
|
|
Modify();
|
2002-03-04 16:08:54 +00:00
|
|
|
|
|
|
|
SpinField::Up();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FormattedField::Down()
|
|
|
|
{
|
|
|
|
SetValue(GetValue() - m_dSpinSize);
|
|
|
|
SetModifyFlag();
|
|
|
|
Modify();
|
2002-03-04 16:08:54 +00:00
|
|
|
|
|
|
|
SpinField::Down();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FormattedField::First()
|
|
|
|
{
|
|
|
|
if (m_bHasMin)
|
|
|
|
{
|
|
|
|
SetValue(m_dMinValue);
|
|
|
|
SetModifyFlag();
|
|
|
|
Modify();
|
|
|
|
}
|
2002-03-04 16:08:54 +00:00
|
|
|
|
|
|
|
SpinField::First();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FormattedField::Last()
|
|
|
|
{
|
|
|
|
if (m_bHasMax)
|
|
|
|
{
|
|
|
|
SetValue(m_dMaxValue);
|
|
|
|
SetModifyFlag();
|
|
|
|
Modify();
|
|
|
|
}
|
2002-03-04 16:08:54 +00:00
|
|
|
|
|
|
|
SpinField::Last();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2007-09-18 13:50:30 +00:00
|
|
|
void FormattedField::UseInputStringForFormatting( bool bUseInputStr /* = true */ )
|
|
|
|
{
|
|
|
|
m_bUseInputStringForFormatting = bUseInputStr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
DoubleNumericField::~DoubleNumericField()
|
|
|
|
{
|
2003-03-27 13:40:07 +00:00
|
|
|
delete m_pNumberValidator;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DoubleNumericField::FormatChanged(FORMAT_CHANGE_TYPE nWhat)
|
|
|
|
{
|
|
|
|
ResetConformanceTester();
|
|
|
|
FormattedField::FormatChanged(nWhat);
|
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
bool DoubleNumericField::CheckText(const OUString& sText) const
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2003-03-27 13:40:07 +00:00
|
|
|
// We'd like to implement this using the NumberFormatter::IsNumberFormat, but unfortunately, this doesn't
|
|
|
|
// recognize fragments of numbers (like, for instance "1e", which happens during entering e.g. "1e10")
|
|
|
|
// Thus, the roundabout way via a regular expression
|
|
|
|
return m_pNumberValidator->isValidNumericFragment( sText );
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DoubleNumericField::ResetConformanceTester()
|
|
|
|
{
|
|
|
|
// the thousands and the decimal separator are language dependent
|
|
|
|
const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey);
|
|
|
|
|
2001-07-20 11:34:11 +00:00
|
|
|
sal_Unicode cSeparatorThousand = ',';
|
|
|
|
sal_Unicode cSeparatorDecimal = '.';
|
2000-11-09 14:15:19 +00:00
|
|
|
if (pFormatEntry)
|
|
|
|
{
|
2012-11-23 23:06:10 +01:00
|
|
|
LocaleDataWrapper aLocaleInfo( LanguageTag( pFormatEntry->GetLanguage()) );
|
2000-11-09 14:15:19 +00:00
|
|
|
|
2013-08-21 11:13:04 +02:00
|
|
|
OUString sSeparator = aLocaleInfo.getNumThousandSep();
|
|
|
|
if (!sSeparator.isEmpty())
|
|
|
|
cSeparatorThousand = sSeparator[0];
|
2000-11-09 14:15:19 +00:00
|
|
|
|
2000-11-14 07:47:26 +00:00
|
|
|
sSeparator = aLocaleInfo.getNumDecimalSep();
|
2013-08-21 11:13:04 +02:00
|
|
|
if (!sSeparator.isEmpty())
|
|
|
|
cSeparatorDecimal = sSeparator[0];
|
2000-11-09 14:15:19 +00:00
|
|
|
}
|
|
|
|
|
2003-03-27 13:40:07 +00:00
|
|
|
delete m_pNumberValidator;
|
|
|
|
m_pNumberValidator = new validation::NumberValidator( cSeparatorThousand, cSeparatorDecimal );
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DoubleCurrencyField::DoubleCurrencyField(Window* pParent, WinBits nStyle)
|
|
|
|
:FormattedField(pParent, nStyle)
|
2014-03-20 11:53:43 +02:00
|
|
|
,m_bChangingFormat(false)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bPrependCurrSym = false;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// initialize with a system currency format
|
2001-08-22 09:29:00 +00:00
|
|
|
m_sCurrencySymbol = SvtSysLocale().GetLocaleData().getCurrSymbol();
|
2000-09-18 16:07:07 +00:00
|
|
|
UpdateCurrencyFormat();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DoubleCurrencyField::FormatChanged(FORMAT_CHANGE_TYPE nWhat)
|
|
|
|
{
|
|
|
|
if (m_bChangingFormat)
|
|
|
|
{
|
|
|
|
FormattedField::FormatChanged(nWhat);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (nWhat)
|
|
|
|
{
|
|
|
|
case FCT_FORMATTER:
|
|
|
|
case FCT_PRECISION:
|
|
|
|
case FCT_THOUSANDSSEP:
|
|
|
|
// the aspects which changed don't take our currency settings into account (in fact, they most probably
|
|
|
|
// destroyed them)
|
|
|
|
UpdateCurrencyFormat();
|
|
|
|
break;
|
|
|
|
case FCT_KEYONLY:
|
2011-03-01 19:08:19 +01:00
|
|
|
OSL_FAIL("DoubleCurrencyField::FormatChanged : somebody modified my key !");
|
2000-09-18 16:07:07 +00:00
|
|
|
// We always build our own format from the settings we get via special methods (setCurrencySymbol etc.).
|
|
|
|
// Nobody but ourself should modifiy the format key directly !
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
FormattedField::FormatChanged(nWhat);
|
|
|
|
}
|
|
|
|
|
2013-03-12 10:41:57 +00:00
|
|
|
void DoubleCurrencyField::setCurrencySymbol(const OUString& rSymbol)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2013-03-12 10:41:57 +00:00
|
|
|
if (m_sCurrencySymbol == rSymbol)
|
2000-09-18 16:07:07 +00:00
|
|
|
return;
|
|
|
|
|
2013-03-12 10:41:57 +00:00
|
|
|
m_sCurrencySymbol = rSymbol;
|
2000-09-18 16:07:07 +00:00
|
|
|
UpdateCurrencyFormat();
|
|
|
|
FormatChanged(FCT_CURRENCY_SYMBOL);
|
|
|
|
}
|
|
|
|
|
2014-03-20 11:53:43 +02:00
|
|
|
void DoubleCurrencyField::setPrependCurrSym(bool _bPrepend)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
if (m_bPrependCurrSym == _bPrepend)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_bPrependCurrSym = _bPrepend;
|
|
|
|
UpdateCurrencyFormat();
|
|
|
|
FormatChanged(FCT_CURRSYM_POSITION);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DoubleCurrencyField::UpdateCurrencyFormat()
|
|
|
|
{
|
|
|
|
// the old settings
|
|
|
|
LanguageType eLanguage;
|
2012-09-12 23:24:07 +01:00
|
|
|
GetFormat(eLanguage);
|
2014-03-20 11:53:43 +02:00
|
|
|
bool bThSep = GetThousandsSep();
|
2010-11-05 10:31:15 +08:00
|
|
|
sal_uInt16 nDigits = GetDecimalDigits();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// build a new format string with the base class' and my own settings
|
2012-11-23 23:06:10 +01:00
|
|
|
|
|
|
|
/* Strangely with gcc 4.6.3 this needs a temporary LanguageTag, otherwise
|
|
|
|
* there's
|
2013-08-20 18:26:05 +01:00
|
|
|
* error: request for member 'getNumThousandSep' in 'aLocaleInfo', which is
|
|
|
|
* of non-class type 'LocaleDataWrapper(LanguageTag)' */
|
2012-11-23 23:06:10 +01:00
|
|
|
LanguageTag aLanguageTag( eLanguage);
|
|
|
|
LocaleDataWrapper aLocaleInfo( aLanguageTag );
|
2001-07-20 11:34:11 +00:00
|
|
|
|
2013-03-12 10:41:57 +00:00
|
|
|
OUStringBuffer sNewFormat;
|
2000-09-18 16:07:07 +00:00
|
|
|
if (bThSep)
|
|
|
|
{
|
2013-03-12 10:41:57 +00:00
|
|
|
sNewFormat.append('#');
|
|
|
|
sNewFormat.append(aLocaleInfo.getNumThousandSep());
|
|
|
|
sNewFormat.append("##0");
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
else
|
2013-03-12 10:41:57 +00:00
|
|
|
sNewFormat.append('0');
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
if (nDigits)
|
|
|
|
{
|
2013-03-12 10:41:57 +00:00
|
|
|
sNewFormat.append(aLocaleInfo.getNumDecimalSep());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
OUStringBuffer sTemp;
|
2012-10-30 00:00:51 +00:00
|
|
|
comphelper::string::padToLength(sTemp, nDigits, '0');
|
2013-03-12 10:41:57 +00:00
|
|
|
sNewFormat.append(sTemp);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (getPrependCurrSym())
|
|
|
|
{
|
2013-03-12 10:41:57 +00:00
|
|
|
OUString sSymbol = getCurrencySymbol();
|
2011-11-22 23:40:24 +00:00
|
|
|
sSymbol = comphelper::string::stripStart(sSymbol, ' ');
|
|
|
|
sSymbol = comphelper::string::stripEnd(sSymbol, ' ');
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2013-03-12 10:41:57 +00:00
|
|
|
OUStringBuffer sTemp("[$");
|
|
|
|
sTemp.append(sSymbol);
|
|
|
|
sTemp.append("] ");
|
|
|
|
sTemp.append(sNewFormat);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// for negative values : $ -0.00, not -$ 0.00 ...
|
|
|
|
// (the real solution would be a possibility to choose a "positive currency format" and a "negative currency format" ...
|
|
|
|
// But not now ... (and hey, you could take a formatted field for this ....))
|
|
|
|
// FS - 31.03.00 74642
|
2013-03-12 10:41:57 +00:00
|
|
|
sTemp.append(";[$");
|
|
|
|
sTemp.append(sSymbol);
|
|
|
|
sTemp.append("] -");
|
|
|
|
sTemp.append(sNewFormat);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
sNewFormat = sTemp;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-03-12 10:41:57 +00:00
|
|
|
OUString sTemp = getCurrencySymbol();
|
2011-11-22 23:40:24 +00:00
|
|
|
sTemp = comphelper::string::stripStart(sTemp, ' ');
|
|
|
|
sTemp = comphelper::string::stripEnd(sTemp, ' ');
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2013-03-12 10:41:57 +00:00
|
|
|
sNewFormat.append(" [$");
|
|
|
|
sNewFormat.append(sTemp);
|
|
|
|
sNewFormat.append(']');
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// set this new basic format
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bChangingFormat = true;
|
2013-03-12 10:41:57 +00:00
|
|
|
SetFormat(sNewFormat.makeStringAndClear(), eLanguage);
|
2014-03-20 11:53:43 +02:00
|
|
|
m_bChangingFormat = false;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2010-10-14 08:27:31 +02:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|