Files
libreoffice/vcl/source/control/field.cxx

2455 lines
71 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2000-09-18 16:07:07 +00:00
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2000-09-18 16:07:07 +00:00
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
2000-09-18 16:07:07 +00:00
*
* OpenOffice.org - a multi-platform office productivity suite
2000-09-18 16:07:07 +00:00
*
* This file is part of OpenOffice.org.
2000-09-18 16:07:07 +00:00
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
2000-09-18 16:07:07 +00:00
*
* OpenOffice.org 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 version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
2000-09-18 16:07:07 +00:00
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
2000-09-18 16:07:07 +00:00
*
************************************************************************/
#include "sal/config.h"
#include <comphelper/processfactory.hxx>
2011-11-18 21:03:31 +00:00
#include <comphelper/string.hxx>
#include "tools/debug.hxx"
2000-09-18 16:07:07 +00:00
#include "tools/rc.h"
#include "vcl/dialog.hxx"
#include "vcl/field.hxx"
#include "vcl/event.hxx"
#include "vcl/svapp.hxx"
#include "svids.hrc"
#include "svdata.hxx"
2008-10-01 13:31:44 +00:00
#include "i18nutil/unicode.hxx"
2000-09-18 16:07:07 +00:00
#include "rtl/math.hxx"
#include <unotools/localedatawrapper.hxx>
using namespace ::com::sun::star;
using namespace ::comphelper;
2001-07-06 15:16:57 +00:00
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
#define FORMAT_NUMERIC 1
#define FORMAT_METRIC 2
#define FORMAT_CURRENCY 3
// -----------------------------------------------------------------------
static sal_Int64 ImplPower10( sal_uInt16 n )
2000-09-18 16:07:07 +00:00
{
sal_uInt16 i;
sal_Int64 nValue = 1;
2000-09-18 16:07:07 +00:00
for ( i=0; i < n; i++ )
nValue *= 10;
return nValue;
}
// -----------------------------------------------------------------------
static sal_Bool ImplNumericProcessKeyInput( Edit*, const KeyEvent& rKEvt,
sal_Bool bStrictFormat, sal_Bool bThousandSep,
const LocaleDataWrapper& rLocaleDataWrappper )
2000-09-18 16:07:07 +00:00
{
if ( !bStrictFormat )
return sal_False;
2000-09-18 16:07:07 +00:00
else
{
sal_Unicode cChar = rKEvt.GetCharCode();
sal_uInt16 nGroup = rKEvt.GetKeyCode().GetGroup();
2000-09-18 16:07:07 +00:00
if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
(nGroup == KEYGROUP_MISC) ||
((cChar >= '0') && (cChar <= '9')) ||
string::equals(rLocaleDataWrappper.getNumDecimalSep(), cChar) ||
(bThousandSep && string::equals(rLocaleDataWrappper.getNumThousandSep(), cChar)) ||
2000-09-18 16:07:07 +00:00
(cChar == '-') )
return sal_False;
2000-09-18 16:07:07 +00:00
else
return sal_True;
2000-09-18 16:07:07 +00:00
}
}
// -----------------------------------------------------------------------
static sal_Bool ImplNumericGetValue( const XubString& rStr, double& rValue,
sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrappper,
sal_Bool bCurrency = sal_False )
2000-09-18 16:07:07 +00:00
{
XubString aStr = rStr;
XubString aStr1;
rtl::OUStringBuffer aStr2;
sal_Bool bNegative = sal_False;
2000-09-18 16:07:07 +00:00
xub_StrLen nDecPos;
// react on empty string
2000-09-18 16:07:07 +00:00
if ( !rStr.Len() )
return sal_False;
2000-09-18 16:07:07 +00:00
// remove leading and trailing spaces
aStr = string::strip(aStr, ' ');
2000-09-18 16:07:07 +00:00
// find position of decimal point
nDecPos = aStr.Search( rLocaleDataWrappper.getNumDecimalSep() );
2000-09-18 16:07:07 +00:00
if ( nDecPos != STRING_NOTFOUND )
{
aStr1 = aStr.Copy( 0, nDecPos );
aStr2.append(aStr.Copy(nDecPos+1));
2000-09-18 16:07:07 +00:00
}
else
aStr1 = aStr;
// negative?
2000-09-18 16:07:07 +00:00
if ( bCurrency )
{
if ( (aStr.GetChar( 0 ) == '(') && (aStr.GetChar( aStr.Len()-1 ) == ')') )
bNegative = sal_True;
2000-09-18 16:07:07 +00:00
if ( !bNegative )
{
for (xub_StrLen i=0; i < aStr.Len(); i++ )
2000-09-18 16:07:07 +00:00
{
if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
break;
else if ( aStr.GetChar( i ) == '-' )
{
bNegative = sal_True;
2000-09-18 16:07:07 +00:00
break;
}
}
}
if ( !bNegative && bCurrency && aStr.Len() )
{
sal_uInt16 nFormat = rLocaleDataWrappper.getCurrNegativeFormat();
2000-09-18 16:07:07 +00:00
if ( (nFormat == 3) || (nFormat == 6) ||
(nFormat == 7) || (nFormat == 10) )
{
for (xub_StrLen i = (xub_StrLen)(aStr.Len()-1); i > 0; i++ )
2000-09-18 16:07:07 +00:00
{
if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
break;
else if ( aStr.GetChar( i ) == '-' )
{
bNegative = sal_True;
2000-09-18 16:07:07 +00:00
break;
}
}
}
}
}
else
{
if ( aStr1.GetChar( 0 ) == '-' )
bNegative = sal_True;
2000-09-18 16:07:07 +00:00
}
// remove all unwanted charaters
for (xub_StrLen i=0; i < aStr1.Len(); )
2000-09-18 16:07:07 +00:00
{
if ( (aStr1.GetChar( i ) >= '0') && (aStr1.GetChar( i ) <= '9') )
i++;
else
aStr1.Erase( i, 1 );
}
for (sal_Int32 i=0; i < aStr2.getLength(); )
2000-09-18 16:07:07 +00:00
{
if ((aStr2[i] >= '0') && (aStr2[i] <= '9'))
++i;
2000-09-18 16:07:07 +00:00
else
aStr2.remove(i, 1);
2000-09-18 16:07:07 +00:00
}
if ( !aStr1.Len() && !aStr2.getLength() )
return sal_False;
2000-09-18 16:07:07 +00:00
if ( !aStr1.Len() )
aStr1.Insert( '0' );
if ( bNegative )
aStr1.Insert( '-', 0 );
// prune and round fraction
bool bRound = false;
if (aStr2.getLength() > nDecDigits)
2000-09-18 16:07:07 +00:00
{
if (aStr2[nDecDigits] >= '5')
bRound = true;
string::truncateToLength(aStr2, nDecDigits);
2000-09-18 16:07:07 +00:00
}
if (aStr2.getLength() < nDecDigits)
string::padToLength(aStr2, nDecDigits, '0');
2000-09-18 16:07:07 +00:00
aStr = aStr1;
aStr += aStr2.makeStringAndClear();
2000-09-18 16:07:07 +00:00
// check range
2012-03-20 11:37:07 +00:00
double nValue = rtl::OUString(aStr).toDouble();
if (bRound)
2000-09-18 16:07:07 +00:00
{
if ( !bNegative )
nValue++;
else
nValue--;
}
rValue = nValue;
return sal_True;
2000-09-18 16:07:07 +00:00
}
static void ImplUpdateSeparatorString( String& io_rText,
const String& rOldDecSep, const String& rNewDecSep,
const String& rOldThSep, const String& rNewThSep )
{
rtl::OUStringBuffer aBuf( io_rText.Len() );
xub_StrLen nIndexDec = 0, nIndexTh = 0, nIndex = 0;
const sal_Unicode* pBuffer = io_rText.GetBuffer();
while( nIndex != STRING_NOTFOUND )
{
nIndexDec = io_rText.Search( rOldDecSep, nIndex );
nIndexTh = io_rText.Search( rOldThSep, nIndex );
if( (nIndexTh != STRING_NOTFOUND && nIndexDec != STRING_NOTFOUND && nIndexTh < nIndexDec )
|| (nIndexTh != STRING_NOTFOUND && nIndexDec == STRING_NOTFOUND)
)
{
aBuf.append( pBuffer + nIndex, nIndexTh - nIndex );
aBuf.append( rNewThSep );
nIndex = nIndexTh + rOldThSep.Len();
}
else if( nIndexDec != STRING_NOTFOUND )
{
aBuf.append( pBuffer + nIndex, nIndexDec - nIndex );
aBuf.append( rNewDecSep );
nIndex = nIndexDec + rOldDecSep.Len();
}
else
{
aBuf.append( pBuffer + nIndex );
nIndex = STRING_NOTFOUND;
}
}
io_rText = aBuf.makeStringAndClear();
2000-09-18 16:07:07 +00:00
}
static void ImplUpdateSeparators( const String& rOldDecSep, const String& rNewDecSep,
const String& rOldThSep, const String& rNewThSep,
Edit* pEdit )
{
bool bChangeDec = (rOldDecSep != rNewDecSep);
bool bChangeTh = (rOldThSep != rNewThSep );
if( bChangeDec || bChangeTh )
{
sal_Bool bUpdateMode = pEdit->IsUpdateMode();
pEdit->SetUpdateMode( sal_False );
String aText = pEdit->GetText();
ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep );
pEdit->SetText( aText );
ComboBox* pCombo = dynamic_cast<ComboBox*>(pEdit);
if( pCombo )
{
// update box entries
sal_uInt16 nEntryCount = pCombo->GetEntryCount();
for ( sal_uInt16 i=0; i < nEntryCount; i++ )
{
aText = pCombo->GetEntry( i );
void* pEntryData = pCombo->GetEntryData( i );
ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep );
pCombo->RemoveEntry( i );
pCombo->InsertEntry( aText, i );
pCombo->SetEntryData( i, pEntryData );
}
}
if( bUpdateMode )
pEdit->SetUpdateMode( bUpdateMode );
}
}
2000-09-18 16:07:07 +00:00
// -----------------------------------------------------------------------
FormatterBase::FormatterBase( Edit* pField )
{
mpField = pField;
mpLocaleDataWrapper = NULL;
mbReformat = sal_False;
mbStrictFormat = sal_False;
mbEmptyFieldValue = sal_False;
mbEmptyFieldValueEnabled = sal_False;
mbDefaultLocale = sal_True;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
FormatterBase::~FormatterBase()
{
delete mpLocaleDataWrapper;
}
// -----------------------------------------------------------------------
2001-07-20 12:19:24 +00:00
LocaleDataWrapper& FormatterBase::ImplGetLocaleDataWrapper() const
{
if ( !mpLocaleDataWrapper )
{
((FormatterBase*)this)->mpLocaleDataWrapper = new LocaleDataWrapper( comphelper::getProcessServiceFactory(), GetLocale() );
}
return *mpLocaleDataWrapper;
2000-09-18 16:07:07 +00:00
}
2001-07-20 12:19:24 +00:00
const LocaleDataWrapper& FormatterBase::GetLocaleDataWrapper() const
{
return ImplGetLocaleDataWrapper();
}
2000-09-18 16:07:07 +00:00
// -----------------------------------------------------------------------
void FormatterBase::Reformat()
{
}
// -----------------------------------------------------------------------
void FormatterBase::ReformatAll()
{
Reformat();
};
// -----------------------------------------------------------------------
void FormatterBase::SetStrictFormat( sal_Bool bStrict )
2000-09-18 16:07:07 +00:00
{
if ( bStrict != mbStrictFormat )
{
mbStrictFormat = bStrict;
if ( mbStrictFormat )
ReformatAll();
}
}
// -----------------------------------------------------------------------
void FormatterBase::SetLocale( const lang::Locale& rLocale )
2000-09-18 16:07:07 +00:00
{
2001-07-20 12:19:24 +00:00
ImplGetLocaleDataWrapper().setLocale( rLocale );
mbDefaultLocale = sal_False;
ReformatAll();
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
const lang::Locale& FormatterBase::GetLocale() const
2000-09-18 16:07:07 +00:00
{
if ( !mpLocaleDataWrapper || mbDefaultLocale )
2000-09-18 16:07:07 +00:00
{
if ( mpField )
return mpField->GetSettings().GetLocale();
2000-09-18 16:07:07 +00:00
else
return Application::GetSettings().GetLocale();
2000-09-18 16:07:07 +00:00
}
return mpLocaleDataWrapper->getLocale();
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
const AllSettings& FormatterBase::GetFieldSettings() const
{
if ( mpField )
return mpField->GetSettings();
else
return Application::GetSettings();
}
// -----------------------------------------------------------------------
void FormatterBase::ImplSetText( const XubString& rText, Selection* pNewSelection )
{
if ( mpField )
{
if ( pNewSelection )
mpField->SetText( rText, *pNewSelection );
else
{
Selection aSel = mpField->GetSelection();
aSel.Min() = aSel.Max();
mpField->SetText( rText, aSel );
}
MarkToBeReformatted( sal_False );
2000-09-18 16:07:07 +00:00
}
}
// -----------------------------------------------------------------------
void FormatterBase::SetEmptyFieldValue()
{
if ( mpField )
mpField->SetText( ImplGetSVEmptyStr() );
mbEmptyFieldValue = sal_True;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
sal_Bool FormatterBase::IsEmptyFieldValue() const
2000-09-18 16:07:07 +00:00
{
return (!mpField || !mpField->GetText().Len());
}
// -----------------------------------------------------------------------
sal_Bool NumericFormatter::ImplNumericReformat( const XubString& rStr, double& rValue,
2000-09-18 16:07:07 +00:00
XubString& rOutStr )
{
2001-07-20 12:19:24 +00:00
if ( !ImplNumericGetValue( rStr, rValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
return sal_True;
2000-09-18 16:07:07 +00:00
else
{
double nTempVal = rValue;
// caution: precision loss in double cast
2000-09-18 16:07:07 +00:00
if ( nTempVal > mnMax )
nTempVal = (double)mnMax;
2000-09-18 16:07:07 +00:00
else if ( nTempVal < mnMin )
nTempVal = (double)mnMin;
2000-09-18 16:07:07 +00:00
if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
{
mnCorrectedValue = (sal_Int64)nTempVal;
2000-09-18 16:07:07 +00:00
if ( !GetErrorHdl().Call( this ) )
{
mnCorrectedValue = 0;
return sal_False;
2000-09-18 16:07:07 +00:00
}
else
mnCorrectedValue = 0;
}
rOutStr = CreateFieldText( (sal_Int64)nTempVal );
return sal_True;
2000-09-18 16:07:07 +00:00
}
}
// -----------------------------------------------------------------------
void NumericFormatter::ImplInit()
{
mnFieldValue = 0;
mnLastValue = 0;
mnMin = 0;
mnMax = 0x7FFFFFFFFFFFFFFFLL;
2000-09-18 16:07:07 +00:00
mnCorrectedValue = 0;
mnDecimalDigits = 2;
2000-09-18 16:07:07 +00:00
mnType = FORMAT_NUMERIC;
mbThousandSep = sal_True;
mbShowTrailingZeros = sal_True;
2000-09-18 16:07:07 +00:00
// for fields
2000-09-18 16:07:07 +00:00
mnSpinSize = 1;
mnFirst = mnMin;
mnLast = mnMax;
SetDecimalDigits( 0 );
}
// -----------------------------------------------------------------------
NumericFormatter::NumericFormatter()
{
ImplInit();
}
// -----------------------------------------------------------------------
void NumericFormatter::ImplLoadRes( const ResId& rResId )
2000-09-18 16:07:07 +00:00
{
ResMgr* pMgr = rResId.GetResMgr();
2000-09-18 16:07:07 +00:00
if( pMgr )
{
sal_uLong nMask = pMgr->ReadLong();
2000-09-18 16:07:07 +00:00
if ( NUMERICFORMATTER_MIN & nMask )
mnMin = pMgr->ReadLong();
2000-09-18 16:07:07 +00:00
if ( NUMERICFORMATTER_MAX & nMask )
mnMax = pMgr->ReadLong();
2000-09-18 16:07:07 +00:00
if ( NUMERICFORMATTER_STRICTFORMAT & nMask )
SetStrictFormat( (sal_Bool)pMgr->ReadShort() );
2000-09-18 16:07:07 +00:00
if ( NUMERICFORMATTER_DECIMALDIGITS & nMask )
SetDecimalDigits( pMgr->ReadShort() );
2000-09-18 16:07:07 +00:00
if ( NUMERICFORMATTER_VALUE & nMask )
{
mnFieldValue = pMgr->ReadLong();
if ( mnFieldValue > mnMax )
mnFieldValue = mnMax;
else if ( mnFieldValue < mnMin )
mnFieldValue = mnMin;
mnLastValue = mnFieldValue;
}
CWS-TOOLING: integrate CWS dba32g 2009-09-09 07:53:55 +0200 oj r275964 : replace strlen with rtl_str_getLength 2009-09-07 20:59:10 +0200 fs r275913 : disable the CopyTableWizard test until issue 104869 is fixed 2009-09-07 12:17:31 +0200 oj r275885 : #i104810# remove de as lang 2009-09-05 22:26:21 +0200 fs r275857 : protect StateChanged against re-entrance 2009-09-05 22:25:52 +0200 fs r275856 : don't attempt to classify the parent of a form as control 2009-09-05 22:25:29 +0200 fs r275855 : protect against re-entrance 2009-09-05 00:11:40 +0200 fs r275835 : #i10000# 2009-09-04 23:25:50 +0200 fs r275834 : #i10000# 2009-09-04 23:23:47 +0200 fs r275833 : #i10000# 2009-09-04 21:49:37 +0200 fs r275830 : #i10000# correct wrong conflict resolution 2009-09-04 20:59:51 +0200 fs r275829 : CWS-TOOLING: rebase CWS dba32g to trunk@275801 (milestone: DEV300:m57) 2009-09-04 11:08:32 +0200 oj r275791 : #i104780# new version 1.2.0 2009-09-03 22:29:21 +0200 fs r275775 : OSL_TRACE doesn't need \n anymore 2009-09-03 08:33:21 +0200 fs r275743 : CWS-TOOLING: rebase CWS dba32g to trunk@275331 (milestone: DEV300:m56) 2009-09-02 13:48:12 +0200 fs r275708 : removed useless include 2009-09-02 13:45:43 +0200 fs r275707 : more since tags, which are used across offapi/udkapi 2009-09-02 13:23:04 +0200 fs r275705 : should *not* have the dtor, copy ctor, and assignment operator compiler-generated, else we run into trouble as soon as the compiler creates different versions of our singleton member's static data in different libraries 2009-09-02 12:32:45 +0200 fs r275704 : AutoIncrementIsPrimaryKey is a driver setting, not a data source setting 2009-09-02 11:42:49 +0200 fs r275701 : URL meta data are meta data which are valid for all connections of this type, not per-data-source properties. Settings them as data source properties is a hack. 2009-09-02 08:43:34 +0200 fs r275696 : 3.x.x is not a valid 'since' tag 2009-09-01 16:05:24 +0200 fs r275665 : #i104686# don't treat controls bound to read-only columns as required 2009-09-01 13:10:22 +0200 fs r275657 : #i104574# use PageUp/Down to scroll through the complete page 2009-09-01 07:04:48 +0200 oj r275641 : #i104104# correct line ends 2009-08-31 15:52:34 +0200 fs r275612 : #i104410# 2009-08-31 12:29:05 +0200 fs r275596 : #i104364# 2009-08-31 12:28:56 +0200 fs r275595 : #i104364# 2009-08-31 11:43:09 +0200 fs r275593 : #i104649# JavaDriverClassPath is also a known JDBC-bridge setting 2009-08-31 11:41:37 +0200 fs r275592 : #i104649# 2009-08-28 21:48:27 +0200 fs r275552 : during #i96862#: renamed the configuration data which controls availability of certain DBA-related UI 2009-08-28 21:48:17 +0200 fs r275551 : #i96862# do not show the 'Create a new database' option when a) no embedded/dBase driver is installed or b) the configuration requests to hide the option 2009-08-28 21:47:19 +0200 fs r275550 : during #i96862#: renamed the configuration data which controls availability of certain DBA-related UI 2009-08-28 21:46:41 +0200 fs r275549 : #i96862# renamed and extended the configuration data which controls availability of certain DBA-related UI 2009-08-28 15:10:19 +0200 fs r275535 : #i96862# if no embedded driver is installed, use dBase for creating new DBs. If no dBase driver is installed, too, do not offer the 'Create new database' option 2009-08-28 14:03:04 +0200 fs r275532 : #i104454# allow multiple fields to display the same column 2009-08-28 13:14:00 +0200 fs r275528 : #i104584# driver meta data do not belong into a data source's settings 2009-08-28 13:09:57 +0200 fs r275527 : properly chech the MySQL type buttons (else next/back in the wizard leads to state with two buttons checked) 2009-08-28 13:09:17 +0200 fs r275526 : #i104584# driver meta data do not belong into a data source's settings 2009-08-28 13:07:18 +0200 fs r275525 : BooleanComparisonMode is a property, or a feature - but not a driver meta data 2009-08-28 11:00:31 +0200 fs r275521 : #i104580# 2009-08-28 10:40:05 +0200 fs r275519 : #i104577# correct assertion: If the template node type is ANY, then any value type is allowed 2009-08-28 10:09:30 +0200 fs r275518 : #i104575# implement Named Pipe UI 2009-08-28 10:09:07 +0200 fs r275517 : pass the trigger-event to IWindowOperator::operateOn / work with VclWindowEvents, not VclSimpleEvents 2009-08-27 14:27:36 +0200 fs r275484 : ImplPosTabPage: respect mbEmptyViewMargin for WINDOWALIGN_LEFT 2009-08-27 13:43:56 +0200 fs r275480 : merging latest changes from CWS dba32f herein 2009-08-27 13:23:07 +0200 fs r275475 : #i103882# 2009-08-27 11:56:55 +0200 fs r275466 : #i104544# SetState: Do not call Update at the window which we just set text for. It should (sic\!) not be needed, but causes trouble 2009-08-27 11:55:34 +0200 fs r275465 : #i104544# do not allow re-entrance for impl_ensureControl_nothrow Actually, this is part of the fix only. I also removed the code which triggered this re-entrance (from the grid control implementation), but to ensure it won't happen, again, I added some safety herein. 2009-08-27 10:14:11 +0200 fs r275459 : preparations for supporting a 'NamedPipe' parameter for the MySQL Connector/OOo 2009-08-27 10:13:21 +0200 fs r275458 : preparations for supporting a 'NamedPipe' setting for the MySQL Connector/OOo 2009-08-27 10:11:14 +0200 fs r275456 : outsourced the MySQLNative settings into a dedicated class, to not duplicate all the code in two tab page implementations 2009-08-26 14:18:13 +0200 fs r275422 : #i10000# 2009-08-26 13:26:36 +0200 fs r275419 : ignore output paths 2009-08-26 13:23:38 +0200 fs r275417 : support the LocalSocket property for the MySQL native driver 2009-08-26 13:17:05 +0200 fs r275416 : some re-factoring, to outsource the tab page for setting up the MySQLNative connection, into a dedicated class (needed later) 2009-08-26 13:15:15 +0200 fs r275415 : support a NoThousandSep property for NumericFormatters - I'm tired of correcting this at runtime, instead of controlling it in the resource 2009-08-26 11:45:08 +0200 fs r275410 : oops, 'flat' shouldn't have got lost 2009-08-26 09:38:57 +0200 fs r275398 : #i102631# when saving the document fails, ensure that the interaction handler really can handle/display the error 2009-08-26 09:37:05 +0200 fs r275397 : #i102631# don't let non-IO/RuntimeExceptions escape from DatabaseDocument::store*, wrap them into an IOException 2009-08-26 09:35:39 +0200 fs r275395 : let the default interaction handler implement XInteractionHandler2 2009-08-25 13:51:34 +0200 fs r275352 : #i102631# createTempFile: pass URL through FileHelper.getOOoCompatibleFileURL 2009-08-25 13:49:23 +0200 fs r275351 : #i102631# createTempFileURL: immediately delete the file implicitly created by createTempFile, we really only need the URL 2009-08-24 14:49:07 +0200 fs r275318 : #i10000# 2009-08-24 14:36:03 +0200 fs r275315 : properly terminate message with 0 character 2009-08-24 14:35:45 +0200 fs r275314 : trace method concepts in non-pro, if special flag is enabled 2009-08-24 14:24:17 +0200 fs r275312 : #i98973# filter some more events for grid control columns 2009-08-24 14:15:23 +0200 fs r275311 : #i98973# implement XComboBox for combo box cells 2009-08-24 13:39:24 +0200 fs r275308 : #i98973# do not display the 'actionPerformed' event for grid combo box columns 2009-08-24 12:52:03 +0200 fs r275303 : #i98973# implement XCheckBox and XButton for check box cells 2009-08-24 11:56:05 +0200 oj r275300 : #i104447# wrong default for orientation 2009-08-24 10:51:21 +0200 fs r275296 : in the script selector dialog, interpret a double click onto a function as OK 2009-08-24 10:50:56 +0200 fs r275295 : localize some to-be-displayed names, consolidate some code regarding form/control naming 2009-08-21 14:28:05 +0200 fs r275255 : #i98973# implement KeyListeners 2009-08-21 14:27:20 +0200 fs r275254 : #i98973# move the conversion VCL[Mouse|Key]Event->Awt[Mouse|Key]Event from vclxwindow.cxx to VCLUnoHelper 2009-08-21 14:08:50 +0200 fs r275248 : #i98973# implement Mouse- and MouseMotion-broadcasting 2009-08-21 13:31:08 +0200 fs r275244 : #i98973# implement text and change listeners at text cells 2009-08-21 12:47:38 +0200 fs r275234 : #i104399# some refactoring: If the MySQL Connector/OOo is installed, it registers for the sdbc:mysqlc: protocol (now known as DST_MYSQL_NATIVE_DIRECT). However, we do not want to display this in the UI, instead we display "MySQL" only, which collects DST_MYSQL_ODBC, DST_MYSQL_JDBC, and DST_MYSQL_NATIVE. 2009-08-21 12:45:18 +0200 fs r275232 : #i104399# also register for the sdbc:mysql:mysqlc protocol, decide at runtime (depending on the availability of sdbc:mysqlc:), whether it is really accepted. This prevents that the C/OOo extension needs to register *our* implementation name for the sdbc:mysql:mysqlc: protocol, which would be somewhat weird 2009-08-20 16:18:48 +0200 fs r275190 : merging the latest changes from CWS dba32f (which this CWS was created from) 2009-08-19 20:19:59 +0200 fs r275160 : add some spacing between the radios 2009-08-19 14:50:15 +0200 fs r275150 : #i98973# slightly refactoring the grid cell implementations, to prepare for proper events being fired. Implement focus events for the moment, more to come. 2009-08-19 10:53:38 +0200 fs r275142 : #i99936# initialize newly created models 2009-08-18 23:03:48 +0200 fs r275132 : merging latest changes from CWS dba32f 2009-08-18 15:14:08 +0200 fs r275110 : #i102819# SetColumnPos: SCROLL_CLIP is deadly here
2009-09-14 11:18:01 +00:00
if ( NUMERICFORMATTER_NOTHOUSANDSEP & nMask )
SetUseThousandSep( !(sal_Bool)pMgr->ReadShort() );
2000-09-18 16:07:07 +00:00
}
}
// -----------------------------------------------------------------------
NumericFormatter::~NumericFormatter()
{
}
// -----------------------------------------------------------------------
void NumericFormatter::SetMin( sal_Int64 nNewMin )
2000-09-18 16:07:07 +00:00
{
mnMin = nNewMin;
if ( !IsEmptyFieldValue() )
ReformatAll();
}
// -----------------------------------------------------------------------
void NumericFormatter::SetMax( sal_Int64 nNewMax )
2000-09-18 16:07:07 +00:00
{
mnMax = nNewMax;
if ( !IsEmptyFieldValue() )
ReformatAll();
}
// -----------------------------------------------------------------------
void NumericFormatter::SetUseThousandSep( sal_Bool b )
{
mbThousandSep = b;
ReformatAll();
}
// -----------------------------------------------------------------------
void NumericFormatter::SetDecimalDigits( sal_uInt16 nDigits )
2000-09-18 16:07:07 +00:00
{
mnDecimalDigits = nDigits;
ReformatAll();
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void NumericFormatter::SetShowTrailingZeros( sal_Bool bShowTrailingZeros )
2001-07-20 13:10:33 +00:00
{
if ( mbShowTrailingZeros != bShowTrailingZeros )
{
mbShowTrailingZeros = bShowTrailingZeros;
ReformatAll();
}
}
// -----------------------------------------------------------------------
sal_uInt16 NumericFormatter::GetDecimalDigits() const
2000-09-18 16:07:07 +00:00
{
return mnDecimalDigits;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void NumericFormatter::SetValue( sal_Int64 nNewValue )
2000-09-18 16:07:07 +00:00
{
SetUserValue( nNewValue );
mnFieldValue = mnLastValue;
SetEmptyFieldValueData( sal_False );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
XubString NumericFormatter::CreateFieldText( sal_Int64 nValue ) const
2000-09-18 16:07:07 +00:00
{
2001-07-20 13:10:33 +00:00
return ImplGetLocaleDataWrapper().getNum( nValue, GetDecimalDigits(), IsUseThousandSep(), IsShowTrailingZeros() );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void NumericFormatter::ImplSetUserValue( sal_Int64 nNewValue, Selection* pNewSelection )
2000-09-18 16:07:07 +00:00
{
if ( nNewValue > mnMax )
nNewValue = mnMax;
else if ( nNewValue < mnMin )
nNewValue = mnMin;
mnLastValue = nNewValue;
if ( GetField() )
ImplSetText( CreateFieldText( nNewValue ), pNewSelection );
}
// -----------------------------------------------------------------------
void NumericFormatter::SetUserValue( sal_Int64 nNewValue )
2000-09-18 16:07:07 +00:00
{
ImplSetUserValue( nNewValue );
}
// -----------------------------------------------------------------------
sal_Int64 NumericFormatter::GetValue() const
2000-09-18 16:07:07 +00:00
{
if ( !GetField() )
return 0;
double nTempValue;
if ( ImplNumericGetValue( GetField()->GetText(), nTempValue,
2001-07-20 12:19:24 +00:00
GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
2000-09-18 16:07:07 +00:00
{
// caution: precision loss in double cast
2000-09-18 16:07:07 +00:00
if ( nTempValue > mnMax )
nTempValue = (double)mnMax;
2000-09-18 16:07:07 +00:00
else if ( nTempValue < mnMin )
nTempValue = (double)mnMin;
return (sal_Int64)nTempValue;
2000-09-18 16:07:07 +00:00
}
else
return mnLastValue;
}
// -----------------------------------------------------------------------
sal_Bool NumericFormatter::IsValueModified() const
2000-09-18 16:07:07 +00:00
{
if ( ImplGetEmptyFieldValue() )
return !IsEmptyFieldValue();
else if ( GetValue() != mnFieldValue )
return sal_True;
2000-09-18 16:07:07 +00:00
else
return sal_False;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
sal_Int64 NumericFormatter::Normalize( sal_Int64 nValue ) const
2000-09-18 16:07:07 +00:00
{
return (nValue * ImplPower10( GetDecimalDigits() ) );
}
// -----------------------------------------------------------------------
sal_Int64 NumericFormatter::Denormalize( sal_Int64 nValue ) const
2000-09-18 16:07:07 +00:00
{
sal_Int64 nFactor = ImplPower10( GetDecimalDigits() );
2000-09-18 16:07:07 +00:00
if( nValue < 0 )
{
sal_Int64 nHalf = nValue < ( SAL_MIN_INT64 + nFactor )? 0 : nFactor/2;
return ((nValue-nHalf) / nFactor );
}
2000-09-18 16:07:07 +00:00
else
{
sal_Int64 nHalf = nValue > ( SAL_MAX_INT64 - nFactor )? 0 : nFactor/2;
return ((nValue+nHalf) / nFactor );
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void NumericFormatter::Reformat()
{
if ( !GetField() )
return;
if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() )
return;
XubString aStr;
// caution: precision loss in double cast
double nTemp = (double)mnLastValue;
sal_Bool bOK = ImplNumericReformat( GetField()->GetText(), nTemp, aStr );
mnLastValue = (sal_Int64)nTemp;
2000-09-18 16:07:07 +00:00
if ( !bOK )
return;
if ( aStr.Len() )
ImplSetText( aStr );
else
SetValue( mnLastValue );
}
// -----------------------------------------------------------------------
void NumericFormatter::FieldUp()
{
sal_Int64 nValue = GetValue();
2000-09-18 16:07:07 +00:00
nValue += mnSpinSize;
if ( nValue > mnMax )
nValue = mnMax;
ImplNewFieldValue( nValue );
}
// -----------------------------------------------------------------------
void NumericFormatter::FieldDown()
{
sal_Int64 nValue = GetValue();
2000-09-18 16:07:07 +00:00
nValue -= mnSpinSize;
if ( nValue < mnMin )
nValue = mnMin;
ImplNewFieldValue( nValue );
}
// -----------------------------------------------------------------------
void NumericFormatter::FieldFirst()
{
ImplNewFieldValue( mnFirst );
}
// -----------------------------------------------------------------------
void NumericFormatter::FieldLast()
{
ImplNewFieldValue( mnLast );
}
// -----------------------------------------------------------------------
void NumericFormatter::ImplNewFieldValue( sal_Int64 nNewValue )
2000-09-18 16:07:07 +00:00
{
if ( GetField() )
{
// !!! We should check why we do not validate in ImplSetUserValue() if the value was
// changed. This should be done there as well since otherwise the call to Modify would not
// be allowed. Anyway, the paths from ImplNewFieldValue, ImplSetUserValue, and ImplSetText
// should be checked and clearly traced (with comment) in order to find out what happens.
2000-09-18 16:07:07 +00:00
Selection aSelection = GetField()->GetSelection();
aSelection.Justify();
XubString aText = GetField()->GetText();
// leave it as is if selected until end
2000-09-18 16:07:07 +00:00
if ( (xub_StrLen)aSelection.Max() == aText.Len() )
{
if ( !aSelection.Len() )
aSelection.Min() = SELECTION_MAX;
aSelection.Max() = SELECTION_MAX;
}
sal_Int64 nOldLastValue = mnLastValue;
2000-09-18 16:07:07 +00:00
ImplSetUserValue( nNewValue, &aSelection );
mnLastValue = nOldLastValue;
// Modify during Edit is only set during KeyInput
2000-09-18 16:07:07 +00:00
if ( GetField()->GetText() != aText )
{
GetField()->SetModifyFlag();
GetField()->Modify();
}
}
}
2012-06-14 11:07:22 +01:00
void NumericFormatter::take_properties(NumericFormatter &rOther)
{
mnFieldValue = rOther.mnFieldValue;
mnLastValue = rOther.mnLastValue;
mnMin = rOther.mnMin;
mnMax = rOther.mnMax;
mnCorrectedValue = rOther.mnCorrectedValue;
mnType = rOther.mnType;
mnDecimalDigits = rOther.mnDecimalDigits;
mbThousandSep = rOther.mbThousandSep;
mbShowTrailingZeros = rOther.mbThousandSep;
mnSpinSize = rOther.mnSpinSize;
mnFirst = rOther.mnFirst;
mnLast = rOther.mnLast;
}
2000-09-18 16:07:07 +00:00
// -----------------------------------------------------------------------
NumericField::NumericField( Window* pParent, WinBits nWinStyle ) :
SpinField( pParent, nWinStyle )
{
SetField( this );
Reformat();
}
// -----------------------------------------------------------------------
NumericField::NumericField( Window* pParent, const ResId& rResId ) :
SpinField( WINDOW_NUMERICFIELD )
{
rResId.SetRT( RSC_NUMERICFIELD );
WinBits nStyle = ImplInitRes( rResId ) ;
if (VclBuilderContainer::replace_buildable(pParent, rResId, *this))
{
SetField( this );
return;
}
2000-09-18 16:07:07 +00:00
SpinField::ImplInit( pParent, nStyle );
SetField( this );
ImplLoadRes( rResId );
Reformat();
if ( !(nStyle & WB_HIDE ) )
Show();
}
bool NumericField::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
{
if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("digits")))
SetDecimalDigits(rValue.toInt32());
else
return SpinField::set_property(rKey, rValue);
return true;
}
2000-09-18 16:07:07 +00:00
// -----------------------------------------------------------------------
void NumericField::ImplLoadRes( const ResId& rResId )
{
SpinField::ImplLoadRes( rResId );
NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
2000-09-18 16:07:07 +00:00
sal_uLong nMask = ReadLongRes();
2000-09-18 16:07:07 +00:00
if ( NUMERICFIELD_FIRST & nMask )
mnFirst = ReadLongRes();
if ( NUMERICFIELD_LAST & nMask )
mnLast = ReadLongRes();
if ( NUMERICFIELD_SPINSIZE & nMask )
mnSpinSize = ReadLongRes();
}
// -----------------------------------------------------------------------
NumericField::~NumericField()
{
}
// -----------------------------------------------------------------------
long NumericField::PreNotify( NotifyEvent& rNEvt )
{
if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
2000-09-18 16:07:07 +00:00
{
2001-07-20 12:19:24 +00:00
if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
2000-09-18 16:07:07 +00:00
return 1;
}
return SpinField::PreNotify( rNEvt );
}
// -----------------------------------------------------------------------
long NumericField::Notify( NotifyEvent& rNEvt )
{
if ( rNEvt.GetType() == EVENT_GETFOCUS )
MarkToBeReformatted( sal_False );
2000-09-18 16:07:07 +00:00
else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
{
if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
Reformat();
}
return SpinField::Notify( rNEvt );
}
// -----------------------------------------------------------------------
void NumericField::DataChanged( const DataChangedEvent& rDCEvt )
{
SpinField::DataChanged( rDCEvt );
if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
{
String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
if ( IsDefaultLocale() )
2001-07-20 12:19:24 +00:00
ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
2000-09-18 16:07:07 +00:00
ReformatAll();
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void NumericField::Modify()
{
MarkToBeReformatted( sal_True );
2000-09-18 16:07:07 +00:00
SpinField::Modify();
}
// -----------------------------------------------------------------------
void NumericField::Up()
{
FieldUp();
SpinField::Up();
}
// -----------------------------------------------------------------------
void NumericField::Down()
{
FieldDown();
SpinField::Down();
}
// -----------------------------------------------------------------------
void NumericField::First()
{
FieldFirst();
SpinField::First();
}
// -----------------------------------------------------------------------
void NumericField::Last()
{
FieldLast();
SpinField::Last();
}
namespace
{
Size calcMinimumSize(const SpinField &rSpinField, const NumericFormatter &rFormatter)
{
rtl::OUStringBuffer aBuf;
sal_Int32 nTextLen;
nTextLen = rtl::OUString::valueOf(rFormatter.GetMin()).getLength();
string::padToLength(aBuf, nTextLen, '9');
Size aMinTextSize = rSpinField.CalcMinimumSizeForText(
rFormatter.CreateFieldText(aBuf.makeStringAndClear().toInt64()));
nTextLen = rtl::OUString::valueOf(rFormatter.GetMax()).getLength();
string::padToLength(aBuf, nTextLen, '9');
Size aMaxTextSize = rSpinField.CalcMinimumSizeForText(
rFormatter.CreateFieldText(aBuf.makeStringAndClear().toInt64()));
Size aRet(std::max(aMinTextSize.Width(), aMaxTextSize.Width()),
std::max(aMinTextSize.Height(), aMaxTextSize.Height()));
OUStringBuffer sBuf("999999999");
sal_uInt16 nDigits = rFormatter.GetDecimalDigits();
if (nDigits)
{
sBuf.append('.');
string::padToLength(aBuf, aBuf.getLength() + nDigits, '9');
}
aMaxTextSize = rSpinField.CalcMinimumSizeForText(sBuf.makeStringAndClear());
aRet.Width() = std::min(aRet.Width(), aMaxTextSize.Width());
return aRet;
}
}
Size NumericField::CalcMinimumSize() const
{
return calcMinimumSize(*this, *this);
}
2000-09-18 16:07:07 +00:00
// -----------------------------------------------------------------------
NumericBox::NumericBox( Window* pParent, WinBits nWinStyle ) :
ComboBox( pParent, nWinStyle )
{
SetField( this );
Reformat();
}
// -----------------------------------------------------------------------
NumericBox::NumericBox( Window* pParent, const ResId& rResId ) :
ComboBox( WINDOW_NUMERICBOX )
{
rResId.SetRT( RSC_NUMERICBOX );
WinBits nStyle = ImplInitRes( rResId );
ComboBox::ImplInit( pParent, nStyle );
SetField( this );
ComboBox::ImplLoadRes( rResId );
NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
2000-09-18 16:07:07 +00:00
Reformat();
if ( !(nStyle & WB_HIDE ) )
Show();
}
// -----------------------------------------------------------------------
NumericBox::~NumericBox()
{
}
// -----------------------------------------------------------------------
long NumericBox::PreNotify( NotifyEvent& rNEvt )
{
if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
2000-09-18 16:07:07 +00:00
{
2001-07-20 12:19:24 +00:00
if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
2000-09-18 16:07:07 +00:00
return 1;
}
return ComboBox::PreNotify( rNEvt );
}
// -----------------------------------------------------------------------
long NumericBox::Notify( NotifyEvent& rNEvt )
{
if ( rNEvt.GetType() == EVENT_GETFOCUS )
MarkToBeReformatted( sal_False );
2000-09-18 16:07:07 +00:00
else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
{
if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
Reformat();
}
return ComboBox::Notify( rNEvt );
}
// -----------------------------------------------------------------------
void NumericBox::DataChanged( const DataChangedEvent& rDCEvt )
{
ComboBox::DataChanged( rDCEvt );
if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
{
String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
if ( IsDefaultLocale() )
2001-07-20 12:19:24 +00:00
ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
2000-09-18 16:07:07 +00:00
ReformatAll();
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void NumericBox::Modify()
{
MarkToBeReformatted( sal_True );
2000-09-18 16:07:07 +00:00
ComboBox::Modify();
}
// -----------------------------------------------------------------------
void NumericBox::ReformatAll()
{
double nValue;
XubString aStr;
SetUpdateMode( sal_False );
sal_uInt16 nEntryCount = GetEntryCount();
for ( sal_uInt16 i=0; i < nEntryCount; i++ )
2000-09-18 16:07:07 +00:00
{
ImplNumericReformat( GetEntry( i ), nValue, aStr );
RemoveEntry( i );
InsertEntry( aStr, i );
}
NumericFormatter::Reformat();
SetUpdateMode( sal_True );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void NumericBox::InsertValue( sal_Int64 nValue, sal_uInt16 nPos )
2000-09-18 16:07:07 +00:00
{
ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
}
// -----------------------------------------------------------------------
static sal_Bool ImplMetricProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
sal_Bool, sal_Bool bUseThousandSep, const LocaleDataWrapper& rWrapper )
2000-09-18 16:07:07 +00:00
{
// no meaningfull strict format; therefore allow all characters
return ImplNumericProcessKeyInput( pEdit, rKEvt, sal_False, bUseThousandSep, rWrapper );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
2012-04-26 11:39:58 +01:00
static rtl::OUString ImplMetricGetUnitText(const rtl::OUString& rStr)
2000-09-18 16:07:07 +00:00
{
// fetch unit text
2012-04-26 11:39:58 +01:00
rtl::OUStringBuffer aStr;
for (sal_Int32 i = rStr.getLength()-1; i >= 0; --i)
2000-09-18 16:07:07 +00:00
{
sal_Unicode c = rStr[i];
if ( (c == '\'') || (c == '\"') || (c == '%' ) || unicode::isAlpha(c) || unicode::isControl(c) )
2012-04-26 11:39:58 +01:00
aStr.insert(0, c);
2000-09-18 16:07:07 +00:00
else
{
2012-04-26 11:39:58 +01:00
if (aStr.getLength())
2000-09-18 16:07:07 +00:00
break;
}
}
2012-04-26 11:39:58 +01:00
return aStr.makeStringAndClear();
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
// #104355# support localized mesaurements
static const String& ImplMetricToString( FieldUnit rUnit )
{
FieldUnitStringList* pList = ImplGetFieldUnits();
if( pList )
{
// return unit's default string (ie, the first one )
for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it )
{
if ( it->second == rUnit )
return it->first;
}
}
return String::EmptyString();
}
2012-04-26 11:39:58 +01:00
static FieldUnit ImplStringToMetric(const rtl::OUString &rMetricString)
{
FieldUnitStringList* pList = ImplGetCleanedFieldUnits();
if( pList )
{
// return FieldUnit
2012-04-26 11:39:58 +01:00
rtl::OUString aStr(rMetricString.toAsciiLowerCase());
aStr = string::remove(aStr, ' ');
for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it )
{
if ( it->first.Equals( aStr ) )
return it->second;
}
}
return FUNIT_NONE;
}
// -----------------------------------------------------------------------
2012-04-26 11:39:58 +01:00
static FieldUnit ImplMetricGetUnit(const rtl::OUString& rStr)
2000-09-18 16:07:07 +00:00
{
2012-04-26 11:39:58 +01:00
rtl::OUString aStr = ImplMetricGetUnitText( rStr );
return ImplStringToMetric( aStr );
2000-09-18 16:07:07 +00:00
}
#define K *1000L
#define M *1000000LL
2000-09-18 16:07:07 +00:00
#define X *5280L
// twip in km = 254 / 14 400 000 000
// expressions too big for default size 32 bit need LL to avoid overflow
static const sal_Int64 aImplFactor[FUNIT_LINE+1][FUNIT_LINE+1] =
2000-09-18 16:07:07 +00:00
{ /*
mm/100 mm cm m km twip point pica inch foot mile char line */
{ 1, 100, 1 K, 100 K, 100 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X , 53340, 396240},
{ 1, 1, 10, 1 K, 1 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X , 5334, 396240},
{ 1, 1, 1, 100, 100 K, 254, 254, 254, 254, 254*12, 254*12 X , 5334, 39624},
{ 1, 1, 1, 1, 1 K, 254, 254, 254, 254, 254*12, 254*12 X , 533400, 39624},
{ 1, 1, 1, 1, 1, 254, 254, 254, 254, 254*12, 254*12 X ,533400 K, 39624},
{ 1440,144 K,144 K,14400 K,14400LL M, 1, 20, 240, 1440,1440*12,1440*12 X , 210, 3120},
{ 72, 7200, 7200, 720 K, 720 M, 1, 1, 12, 72, 72*12, 72*12 X , 210, 156},
{ 6, 600, 600, 60 K, 60 M, 1, 1, 1, 6, 6*12, 6*12 X , 210, 10},
{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 12, 12 X , 210, 45},
{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 X , 210, 45},
{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 , 210, 45},
{ 144, 1440,14400, 14400, 14400, 1, 20, 240, 1440,1440*12, 1440*12 X, 1, 156 },
{ 720,72000,72000, 7200 K,7200LL M, 20, 10, 13, 11, 11*12, 11*12 X, 105, 1 }
2000-09-18 16:07:07 +00:00
};
#undef X
#undef M
#undef K
static FieldUnit eDefaultUnit = FUNIT_NONE;
FieldUnit MetricField::GetDefaultUnit() { return eDefaultUnit; }
void MetricField::SetDefaultUnit( FieldUnit meUnit ) { eDefaultUnit = meUnit; }
static FieldUnit ImplMap2FieldUnit( MapUnit meUnit, long& nDecDigits )
{
switch( meUnit )
{
case MAP_100TH_MM :
nDecDigits -= 2;
return FUNIT_MM;
case MAP_10TH_MM :
nDecDigits -= 1;
return FUNIT_MM;
case MAP_MM :
return FUNIT_MM;
case MAP_CM :
return FUNIT_CM;
case MAP_1000TH_INCH :
nDecDigits -= 3;
return FUNIT_INCH;
case MAP_100TH_INCH :
nDecDigits -= 2;
return FUNIT_INCH;
case MAP_10TH_INCH :
nDecDigits -= 1;
return FUNIT_INCH;
case MAP_INCH :
return FUNIT_INCH;
case MAP_POINT :
return FUNIT_POINT;
case MAP_TWIP :
return FUNIT_TWIP;
default:
2011-03-01 19:08:19 +01:00
OSL_FAIL( "default eInUnit" );
2000-09-18 16:07:07 +00:00
break;
}
return FUNIT_NONE;
}
// -----------------------------------------------------------------------
static double nonValueDoubleToValueDouble( double nValue )
{
return rtl::math::isFinite( nValue ) ? nValue : 0.0;
}
sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits,
FieldUnit eInUnit, FieldUnit eOutUnit )
2000-09-18 16:07:07 +00:00
{
double nDouble = nonValueDoubleToValueDouble( ConvertDoubleValue(
(double)nValue, mnBaseValue, nDecDigits, eInUnit, eOutUnit ) );
// caution: precision loss in double cast
sal_Int64 nLong = static_cast<sal_Int64>( nDouble );
if ( nDouble >= (double)SAL_MAX_INT64 )
nLong = SAL_MAX_INT64;
else if ( nDouble <= (double)SAL_MIN_INT64 )
nLong = SAL_MIN_INT64;
return nLong;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_uInt16 nDigits,
MapUnit eInUnit, FieldUnit eOutUnit )
2000-09-18 16:07:07 +00:00
{
return static_cast<sal_Int64>(
nonValueDoubleToValueDouble(
ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit ) ) );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
double MetricField::ConvertDoubleValue( double nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits,
2000-09-18 16:07:07 +00:00
FieldUnit eInUnit, FieldUnit eOutUnit )
{
if ( eInUnit != eOutUnit )
{
sal_Int64 nMult = 1, nDiv = 1;
2000-09-18 16:07:07 +00:00
if ( eInUnit == FUNIT_PERCENT )
{
if ( (mnBaseValue <= 0) || (nValue <= 0) )
return nValue;
nDiv = 100;
for ( sal_uInt16 i=0; i < nDecDigits; i++ )
2000-09-18 16:07:07 +00:00
nDiv *= 10;
nMult = mnBaseValue;
}
else if ( eOutUnit == FUNIT_PERCENT ||
eOutUnit == FUNIT_CUSTOM ||
eOutUnit == FUNIT_NONE ||
eInUnit == FUNIT_CUSTOM ||
eInUnit == FUNIT_NONE )
return nValue;
else
{
if ( eOutUnit == FUNIT_100TH_MM )
eOutUnit = FUNIT_NONE;
if ( eInUnit == FUNIT_100TH_MM )
eInUnit = FUNIT_NONE;
nDiv = aImplFactor[eInUnit][eOutUnit];
nMult = aImplFactor[eOutUnit][eInUnit];
DBG_ASSERT( nMult > 0, "illegal *" );
DBG_ASSERT( nDiv > 0, "illegal /" );
}
if ( nMult != 1 && nMult > 0 )
2000-09-18 16:07:07 +00:00
nValue *= nMult;
if ( nDiv != 1 && nDiv > 0 )
2000-09-18 16:07:07 +00:00
{
nValue += ( nValue < 0 ) ? (-nDiv/2) : (nDiv/2);
nValue /= nDiv;
}
}
return nValue;
}
// -----------------------------------------------------------------------
double MetricField::ConvertDoubleValue( double nValue, sal_uInt16 nDigits,
2000-09-18 16:07:07 +00:00
MapUnit eInUnit, FieldUnit eOutUnit )
{
if ( eOutUnit == FUNIT_PERCENT ||
eOutUnit == FUNIT_CUSTOM ||
eOutUnit == FUNIT_NONE ||
eInUnit == MAP_PIXEL ||
eInUnit == MAP_SYSFONT ||
eInUnit == MAP_APPFONT ||
eInUnit == MAP_RELATIVE )
{
2011-03-01 19:08:19 +01:00
OSL_FAIL( "invalid parameters" );
2000-09-18 16:07:07 +00:00
return nValue;
}
long nDecDigits = nDigits;
FieldUnit eFieldUnit = ImplMap2FieldUnit( eInUnit, nDecDigits );
if ( nDecDigits < 0 )
2000-09-18 16:07:07 +00:00
{
while ( nDecDigits )
{
nValue += 5;
nValue /= 10;
nDecDigits++;
}
}
else
{
while ( nDecDigits )
{
nValue *= 10;
nDecDigits--;
}
}
if ( eFieldUnit != eOutUnit )
{
sal_Int64 nDiv = aImplFactor[eFieldUnit][eOutUnit];
sal_Int64 nMult = aImplFactor[eOutUnit][eFieldUnit];
2000-09-18 16:07:07 +00:00
DBG_ASSERT( nMult > 0, "illegal *" );
DBG_ASSERT( nDiv > 0, "illegal /" );
if ( nMult != 1 && nMult > 0)
2000-09-18 16:07:07 +00:00
nValue *= nMult;
if ( nDiv != 1 && nDiv > 0 )
2000-09-18 16:07:07 +00:00
{
nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
nValue /= nDiv;
}
}
return nValue;
}
// -----------------------------------------------------------------------
double MetricField::ConvertDoubleValue( double nValue, sal_uInt16 nDigits,
2000-09-18 16:07:07 +00:00
FieldUnit eInUnit, MapUnit eOutUnit )
{
if ( eInUnit == FUNIT_PERCENT ||
eInUnit == FUNIT_CUSTOM ||
eInUnit == FUNIT_NONE ||
eOutUnit == MAP_PIXEL ||
eOutUnit == MAP_SYSFONT ||
eOutUnit == MAP_APPFONT ||
eOutUnit == MAP_RELATIVE )
{
2011-03-01 19:08:19 +01:00
OSL_FAIL( "invalid parameters" );
2000-09-18 16:07:07 +00:00
return nValue;
}
long nDecDigits = nDigits;
FieldUnit eFieldUnit = ImplMap2FieldUnit( eOutUnit, nDecDigits );
if ( nDecDigits < 0 )
2000-09-18 16:07:07 +00:00
{
while ( nDecDigits )
{
nValue *= 10;
nDecDigits++;
}
}
else
{
while ( nDecDigits )
{
nValue /= 10;
nDecDigits--;
}
}
if ( eFieldUnit != eInUnit )
{
sal_Int64 nDiv = aImplFactor[eInUnit][eFieldUnit];
sal_Int64 nMult = aImplFactor[eFieldUnit][eInUnit];
2000-09-18 16:07:07 +00:00
DBG_ASSERT( nMult > 0, "illegal *" );
DBG_ASSERT( nDiv > 0, "illegal /" );
if( nMult != 1 && nMult > 0 )
2000-09-18 16:07:07 +00:00
nValue *= nMult;
if( nDiv != 1 && nDiv > 0 )
2000-09-18 16:07:07 +00:00
{
nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
nValue /= nDiv;
}
}
return nValue;
}
// -----------------------------------------------------------------------
static sal_Bool ImplMetricGetValue( const XubString& rStr, double& rValue, sal_Int64 nBaseValue,
sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrapper, FieldUnit eUnit )
2000-09-18 16:07:07 +00:00
{
// Zahlenwert holen
if ( !ImplNumericGetValue( rStr, rValue, nDecDigits, rLocaleDataWrapper ) )
return sal_False;
2000-09-18 16:07:07 +00:00
// Einheit rausfinden
FieldUnit eEntryUnit = ImplMetricGetUnit( rStr );
// Einheiten umrechnen
rValue = MetricField::ConvertDoubleValue( rValue, nBaseValue, nDecDigits, eEntryUnit, eUnit );
return sal_True;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
sal_Bool MetricFormatter::ImplMetricReformat( const XubString& rStr, double& rValue, XubString& rOutStr )
2000-09-18 16:07:07 +00:00
{
2001-07-20 12:19:24 +00:00
if ( !ImplMetricGetValue( rStr, rValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) )
return sal_True;
2000-09-18 16:07:07 +00:00
else
{
double nTempVal = rValue;
// caution: precision loss in double cast
2000-09-18 16:07:07 +00:00
if ( nTempVal > GetMax() )
nTempVal = (double)GetMax();
2000-09-18 16:07:07 +00:00
else if ( nTempVal < GetMin())
nTempVal = (double)GetMin();
2000-09-18 16:07:07 +00:00
if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
{
mnCorrectedValue = (sal_Int64)nTempVal;
2000-09-18 16:07:07 +00:00
if ( !GetErrorHdl().Call( this ) )
{
mnCorrectedValue = 0;
return sal_False;
2000-09-18 16:07:07 +00:00
}
else
mnCorrectedValue = 0;
}
rOutStr = CreateFieldText( (sal_Int64)nTempVal );
return sal_True;
2000-09-18 16:07:07 +00:00
}
}
// -----------------------------------------------------------------------
inline void MetricFormatter::ImplInit()
{
mnBaseValue = 0;
meUnit = MetricField::GetDefaultUnit();
mnType = FORMAT_METRIC;
}
// -----------------------------------------------------------------------
MetricFormatter::MetricFormatter()
{
ImplInit();
}
// -----------------------------------------------------------------------
void MetricFormatter::ImplLoadRes( const ResId& rResId )
{
NumericFormatter::ImplLoadRes( rResId );
ResMgr* pMgr = rResId.GetResMgr();
if( pMgr )
{
sal_uLong nMask = pMgr->ReadLong();
2000-09-18 16:07:07 +00:00
if ( METRICFORMATTER_UNIT & nMask )
meUnit = (FieldUnit)pMgr->ReadLong();
2000-09-18 16:07:07 +00:00
if ( METRICFORMATTER_CUSTOMUNITTEXT & nMask )
maCustomUnitText = pMgr->ReadString();
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
MetricFormatter::~MetricFormatter()
{
}
// -----------------------------------------------------------------------
void MetricFormatter::SetUnit( FieldUnit eNewUnit )
{
if ( eNewUnit == FUNIT_100TH_MM )
{
SetDecimalDigits( GetDecimalDigits() + 2 );
meUnit = FUNIT_MM;
}
else
meUnit = eNewUnit;
ReformatAll();
}
// -----------------------------------------------------------------------
void MetricFormatter::SetCustomUnitText( const XubString& rStr )
{
maCustomUnitText = rStr;
ReformatAll();
}
// -----------------------------------------------------------------------
void MetricFormatter::SetValue( sal_Int64 nNewValue, FieldUnit eInUnit )
2000-09-18 16:07:07 +00:00
{
SetUserValue( nNewValue, eInUnit );
mnFieldValue = mnLastValue;
}
// -----------------------------------------------------------------------
XubString MetricFormatter::CreateFieldText( sal_Int64 nValue ) const
2000-09-18 16:07:07 +00:00
{
XubString aStr = NumericFormatter::CreateFieldText( nValue );
if( meUnit == FUNIT_CUSTOM )
aStr += maCustomUnitText;
else
aStr += ImplMetricToString( meUnit );
return aStr;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void MetricFormatter::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit )
2000-09-18 16:07:07 +00:00
{
// convert to previously configured units
2000-09-18 16:07:07 +00:00
nNewValue = MetricField::ConvertValue( nNewValue, mnBaseValue, GetDecimalDigits(), eInUnit, meUnit );
NumericFormatter::SetUserValue( nNewValue );
}
// -----------------------------------------------------------------------
sal_Int64 MetricFormatter::GetValue( FieldUnit eOutUnit ) const
2000-09-18 16:07:07 +00:00
{
if ( !GetField() )
return 0;
double nTempValue;
// caution: precision loss in double cast
2001-07-20 12:19:24 +00:00
if ( !ImplMetricGetValue( GetField()->GetText(), nTempValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) )
nTempValue = (double)mnLastValue;
2000-09-18 16:07:07 +00:00
// caution: precision loss in double cast
2000-09-18 16:07:07 +00:00
if ( nTempValue > mnMax )
nTempValue = (double)mnMax;
2000-09-18 16:07:07 +00:00
else if ( nTempValue < mnMin )
nTempValue = (double)mnMin;
2000-09-18 16:07:07 +00:00
// convert to requested units
return MetricField::ConvertValue( (sal_Int64)nTempValue, mnBaseValue, GetDecimalDigits(), meUnit, eOutUnit );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void MetricFormatter::SetValue( sal_Int64 nValue )
{
// Implementation not inline, because it is a virtual Function
SetValue( nValue, FUNIT_NONE );
}
// -----------------------------------------------------------------------
sal_Int64 MetricFormatter::GetValue() const
{
// Implementation not inline, because it is a virtual Function
return GetValue( FUNIT_NONE );
}
// -----------------------------------------------------------------------
void MetricFormatter::SetMin( sal_Int64 nNewMin, FieldUnit eInUnit )
2000-09-18 16:07:07 +00:00
{
// convert to requested units
2000-09-18 16:07:07 +00:00
NumericFormatter::SetMin( MetricField::ConvertValue( nNewMin, mnBaseValue, GetDecimalDigits(),
eInUnit, meUnit ) );
}
// -----------------------------------------------------------------------
sal_Int64 MetricFormatter::GetMin( FieldUnit eOutUnit ) const
2000-09-18 16:07:07 +00:00
{
// convert to requested units
2000-09-18 16:07:07 +00:00
return MetricField::ConvertValue( NumericFormatter::GetMin(), mnBaseValue,
GetDecimalDigits(), meUnit, eOutUnit );
}
// -----------------------------------------------------------------------
void MetricFormatter::SetMax( sal_Int64 nNewMax, FieldUnit eInUnit )
2000-09-18 16:07:07 +00:00
{
// convert to requested units
2000-09-18 16:07:07 +00:00
NumericFormatter::SetMax( MetricField::ConvertValue( nNewMax, mnBaseValue, GetDecimalDigits(),
eInUnit, meUnit ) );
}
// -----------------------------------------------------------------------
sal_Int64 MetricFormatter::GetMax( FieldUnit eOutUnit ) const
2000-09-18 16:07:07 +00:00
{
// convert to requested units
2000-09-18 16:07:07 +00:00
return MetricField::ConvertValue( NumericFormatter::GetMax(), mnBaseValue,
GetDecimalDigits(), meUnit, eOutUnit );
}
// -----------------------------------------------------------------------
void MetricFormatter::SetBaseValue( sal_Int64 nNewBase, FieldUnit eInUnit )
2000-09-18 16:07:07 +00:00
{
mnBaseValue = MetricField::ConvertValue( nNewBase, mnBaseValue, GetDecimalDigits(),
eInUnit, meUnit );
}
// -----------------------------------------------------------------------
sal_Int64 MetricFormatter::GetBaseValue( FieldUnit eOutUnit ) const
2000-09-18 16:07:07 +00:00
{
// convert to requested units
2000-09-18 16:07:07 +00:00
return MetricField::ConvertValue( mnBaseValue, mnBaseValue, GetDecimalDigits(),
meUnit, eOutUnit );
}
// -----------------------------------------------------------------------
void MetricFormatter::Reformat()
{
if ( !GetField() )
return;
XubString aText = GetField()->GetText();
if ( meUnit == FUNIT_CUSTOM )
maCurUnitText = ImplMetricGetUnitText( aText );
XubString aStr;
// caution: precision loss in double cast
double nTemp = (double)mnLastValue;
sal_Bool bOK = ImplMetricReformat( aText, nTemp, aStr );
mnLastValue = (sal_Int64)nTemp;
2000-09-18 16:07:07 +00:00
if ( !bOK )
return;
if ( aStr.Len() )
{
ImplSetText( aStr );
if ( meUnit == FUNIT_CUSTOM )
CustomConvert();
}
else
SetValue( mnLastValue );
maCurUnitText.Erase();
}
// -----------------------------------------------------------------------
sal_Int64 MetricFormatter::GetCorrectedValue( FieldUnit eOutUnit ) const
2000-09-18 16:07:07 +00:00
{
// convert to requested units
2000-09-18 16:07:07 +00:00
return MetricField::ConvertValue( mnCorrectedValue, mnBaseValue, GetDecimalDigits(),
meUnit, eOutUnit );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
MetricField::MetricField( Window* pParent, WinBits nWinStyle ) :
SpinField( pParent, nWinStyle )
{
SetField( this );
Reformat();
}
MetricField::MetricField( Window* pParent, const ResId& rResId ) :
SpinField( WINDOW_METRICFIELD )
{
rResId.SetRT( RSC_METRICFIELD );
WinBits nStyle = ImplInitRes( rResId ) ;
if (VclBuilderContainer::replace_buildable(pParent, rResId, *this))
return;
2000-09-18 16:07:07 +00:00
SpinField::ImplInit( pParent, nStyle );
SetField( this );
ImplLoadRes( rResId );
if ( !(nStyle & WB_HIDE ) )
Show();
}
Size MetricField::CalcMinimumSize() const
{
return calcMinimumSize(*this, *this);
}
2012-06-14 11:07:22 +01:00
void MetricFormatter::take_properties(MetricFormatter &rOtherField)
{
maCustomUnitText = rOtherField.maCustomUnitText;
maCurUnitText = rOtherField.maCurUnitText;
mnBaseValue = rOtherField.mnBaseValue;
meUnit = rOtherField.meUnit;
NumericFormatter::take_properties(rOtherField);
}
void MetricField::take_properties(Window &rOther)
{
if (!GetParent())
{
SpinField::ImplInit(rOther.GetParent(), rOther.GetStyle());
SetField( this );
}
SpinField::take_properties(rOther);
MetricField &rOtherField = static_cast<MetricField&>(rOther);
2012-06-14 11:07:22 +01:00
MetricFormatter::take_properties(rOtherField);
}
bool MetricField::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
{
if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("format")))
{
maCustomUnitText = rtl::OStringToOUString(rValue, RTL_TEXTENCODING_UTF8);
meUnit = FUNIT_CUSTOM;
}
2012-06-14 10:47:39 +01:00
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("digits")))
SetDecimalDigits(rValue.toInt32());
else
return SpinField::set_property(rKey, rValue);
return true;
}
2000-09-18 16:07:07 +00:00
void MetricField::ImplLoadRes( const ResId& rResId )
{
SpinField::ImplLoadRes( rResId );
MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
2000-09-18 16:07:07 +00:00
sal_uLong nMask = ReadLongRes();
2000-09-18 16:07:07 +00:00
if ( METRICFIELD_FIRST & nMask )
mnFirst = ReadLongRes();
if ( METRICFIELD_LAST & nMask )
mnLast = ReadLongRes();
if ( METRICFIELD_SPINSIZE & nMask )
mnSpinSize = ReadLongRes();
Reformat();
}
// -----------------------------------------------------------------------
MetricField::~MetricField()
{
}
void MetricField::SetUnit( FieldUnit nNewUnit )
{
sal_Int64 nRawMax = GetMax( nNewUnit );
sal_Int64 nMax = Denormalize( nRawMax );
sal_Int64 nMin = Denormalize( GetMin( nNewUnit ) );
sal_Int64 nFirst = Denormalize( GetFirst( nNewUnit ) );
sal_Int64 nLast = Denormalize( GetLast( nNewUnit ) );
MetricFormatter::SetUnit( nNewUnit );
SetMax( Normalize( nMax ), nNewUnit );
SetMin( Normalize( nMin ), nNewUnit );
SetFirst( Normalize( nFirst ), nNewUnit );
SetLast( Normalize( nLast ), nNewUnit );
}
2000-09-18 16:07:07 +00:00
// -----------------------------------------------------------------------
void MetricField::SetFirst( sal_Int64 nNewFirst, FieldUnit eInUnit )
2000-09-18 16:07:07 +00:00
{
// convert
2000-09-18 16:07:07 +00:00
nNewFirst = MetricField::ConvertValue( nNewFirst, mnBaseValue, GetDecimalDigits(),
eInUnit, meUnit );
mnFirst = nNewFirst;
}
// -----------------------------------------------------------------------
sal_Int64 MetricField::GetFirst( FieldUnit eOutUnit ) const
2000-09-18 16:07:07 +00:00
{
// convert
2000-09-18 16:07:07 +00:00
return MetricField::ConvertValue( mnFirst, mnBaseValue, GetDecimalDigits(),
meUnit, eOutUnit );
}
// -----------------------------------------------------------------------
void MetricField::SetLast( sal_Int64 nNewLast, FieldUnit eInUnit )
2000-09-18 16:07:07 +00:00
{
// convert
2000-09-18 16:07:07 +00:00
nNewLast = MetricField::ConvertValue( nNewLast, mnBaseValue, GetDecimalDigits(),
eInUnit, meUnit );
mnLast = nNewLast;
}
// -----------------------------------------------------------------------
sal_Int64 MetricField::GetLast( FieldUnit eOutUnit ) const
2000-09-18 16:07:07 +00:00
{
// conver
2000-09-18 16:07:07 +00:00
return MetricField::ConvertValue( mnLast, mnBaseValue, GetDecimalDigits(),
meUnit, eOutUnit );
}
// -----------------------------------------------------------------------
long MetricField::PreNotify( NotifyEvent& rNEvt )
{
if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
2000-09-18 16:07:07 +00:00
{
2001-07-20 12:19:24 +00:00
if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
2000-09-18 16:07:07 +00:00
return 1;
}
return SpinField::PreNotify( rNEvt );
}
// -----------------------------------------------------------------------
long MetricField::Notify( NotifyEvent& rNEvt )
{
if ( rNEvt.GetType() == EVENT_GETFOCUS )
MarkToBeReformatted( sal_False );
2000-09-18 16:07:07 +00:00
else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
{
if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
Reformat();
}
return SpinField::Notify( rNEvt );
}
// -----------------------------------------------------------------------
void MetricField::DataChanged( const DataChangedEvent& rDCEvt )
{
SpinField::DataChanged( rDCEvt );
if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
{
String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
if ( IsDefaultLocale() )
2001-07-20 12:19:24 +00:00
ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
2000-09-18 16:07:07 +00:00
ReformatAll();
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void MetricField::Modify()
{
MarkToBeReformatted( sal_True );
2000-09-18 16:07:07 +00:00
SpinField::Modify();
}
// -----------------------------------------------------------------------
void MetricField::Up()
{
FieldUp();
SpinField::Up();
}
// -----------------------------------------------------------------------
void MetricField::Down()
{
FieldDown();
SpinField::Down();
}
// -----------------------------------------------------------------------
void MetricField::First()
{
FieldFirst();
SpinField::First();
}
// -----------------------------------------------------------------------
void MetricField::Last()
{
FieldLast();
SpinField::Last();
}
// -----------------------------------------------------------------------
void MetricField::CustomConvert()
{
maCustomConvertLink.Call( this );
}
// -----------------------------------------------------------------------
MetricBox::MetricBox( Window* pParent, WinBits nWinStyle ) :
ComboBox( pParent, nWinStyle )
{
SetField( this );
Reformat();
}
// -----------------------------------------------------------------------
MetricBox::MetricBox( Window* pParent, const ResId& rResId ) :
ComboBox( WINDOW_METRICBOX )
{
rResId.SetRT( RSC_METRICBOX );
WinBits nStyle = ImplInitRes( rResId );
ComboBox::ImplInit( pParent, nStyle );
SetField( this );
Reformat();
ComboBox::ImplLoadRes( rResId );
MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
2000-09-18 16:07:07 +00:00
if ( !(nStyle & WB_HIDE ) )
Show();
}
// -----------------------------------------------------------------------
MetricBox::~MetricBox()
{
}
// -----------------------------------------------------------------------
long MetricBox::PreNotify( NotifyEvent& rNEvt )
{
if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
2000-09-18 16:07:07 +00:00
{
2001-07-20 12:19:24 +00:00
if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
2000-09-18 16:07:07 +00:00
return 1;
}
return ComboBox::PreNotify( rNEvt );
}
// -----------------------------------------------------------------------
long MetricBox::Notify( NotifyEvent& rNEvt )
{
if ( rNEvt.GetType() == EVENT_GETFOCUS )
MarkToBeReformatted( sal_False );
2000-09-18 16:07:07 +00:00
else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
{
if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
Reformat();
}
return ComboBox::Notify( rNEvt );
}
// -----------------------------------------------------------------------
void MetricBox::DataChanged( const DataChangedEvent& rDCEvt )
{
ComboBox::DataChanged( rDCEvt );
if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
{
String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
if ( IsDefaultLocale() )
2001-07-20 12:19:24 +00:00
ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
2000-09-18 16:07:07 +00:00
ReformatAll();
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void MetricBox::Modify()
{
MarkToBeReformatted( sal_True );
2000-09-18 16:07:07 +00:00
ComboBox::Modify();
}
// -----------------------------------------------------------------------
void MetricBox::ReformatAll()
{
double nValue;
XubString aStr;
SetUpdateMode( sal_False );
sal_uInt16 nEntryCount = GetEntryCount();
for ( sal_uInt16 i=0; i < nEntryCount; i++ )
2000-09-18 16:07:07 +00:00
{
ImplMetricReformat( GetEntry( i ), nValue, aStr );
RemoveEntry( i );
InsertEntry( aStr, i );
}
MetricFormatter::Reformat();
SetUpdateMode( sal_True );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void MetricBox::CustomConvert()
{
maCustomConvertLink.Call( this );
}
// -----------------------------------------------------------------------
void MetricBox::InsertValue( sal_Int64 nValue, FieldUnit eInUnit, sal_uInt16 nPos )
2000-09-18 16:07:07 +00:00
{
// convert to previously configured units
2000-09-18 16:07:07 +00:00
nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
eInUnit, meUnit );
ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
}
// -----------------------------------------------------------------------
sal_Int64 MetricBox::GetValue( sal_uInt16 nPos, FieldUnit eOutUnit ) const
2000-09-18 16:07:07 +00:00
{
double nValue = 0;
ImplMetricGetValue( ComboBox::GetEntry( nPos ), nValue, mnBaseValue,
2001-07-20 12:19:24 +00:00
GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit );
2000-09-18 16:07:07 +00:00
// convert to previously configured units
sal_Int64 nRetValue = MetricField::ConvertValue( (sal_Int64)nValue, mnBaseValue, GetDecimalDigits(),
meUnit, eOutUnit );
2000-09-18 16:07:07 +00:00
return nRetValue;
}
// -----------------------------------------------------------------------
sal_uInt16 MetricBox::GetValuePos( sal_Int64 nValue, FieldUnit eInUnit ) const
2000-09-18 16:07:07 +00:00
{
// convert to previously configured units
2000-09-18 16:07:07 +00:00
nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
eInUnit, meUnit );
return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
}
// -----------------------------------------------------------------------
sal_Int64 MetricBox::GetValue( FieldUnit eOutUnit ) const
{
// Implementation not inline, because it is a virtual Function
return MetricFormatter::GetValue( eOutUnit );
}
// -----------------------------------------------------------------------
sal_Int64 MetricBox::GetValue() const
{
// Implementation not inline, because it is a virtual Function
return GetValue( FUNIT_NONE );
}
// -----------------------------------------------------------------------
static sal_Bool ImplCurrencyProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
sal_Bool, sal_Bool bUseThousandSep, const LocaleDataWrapper& rWrapper )
2000-09-18 16:07:07 +00:00
{
// no strict format set; therefore allow all characters
return ImplNumericProcessKeyInput( pEdit, rKEvt, sal_False, bUseThousandSep, rWrapper );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
inline sal_Bool ImplCurrencyGetValue( const XubString& rStr, double& rValue,
sal_uInt16 nDecDigits, const LocaleDataWrapper& rWrapper )
2000-09-18 16:07:07 +00:00
{
// fetch number
return ImplNumericGetValue( rStr, rValue, nDecDigits, rWrapper, sal_True );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
sal_Bool CurrencyFormatter::ImplCurrencyReformat( const XubString& rStr,
2000-09-18 16:07:07 +00:00
XubString& rOutStr )
{
double nValue;
if ( !ImplNumericGetValue( rStr, nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), sal_True ) )
return sal_True;
2000-09-18 16:07:07 +00:00
else
{
double nTempVal = nValue;
// caution: precision loss in double cast
2000-09-18 16:07:07 +00:00
if ( nTempVal > GetMax() )
nTempVal = (double)GetMax();
2000-09-18 16:07:07 +00:00
else if ( nTempVal < GetMin())
nTempVal = (double)GetMin();
2000-09-18 16:07:07 +00:00
if ( GetErrorHdl().IsSet() && (nValue != nTempVal) )
{
mnCorrectedValue = (sal_Int64)nTempVal;
2000-09-18 16:07:07 +00:00
if ( !GetErrorHdl().Call( this ) )
{
mnCorrectedValue = 0;
return sal_False;
2000-09-18 16:07:07 +00:00
}
else
mnCorrectedValue = 0;
}
rOutStr = CreateFieldText( (long)nTempVal );
return sal_True;
2000-09-18 16:07:07 +00:00
}
}
// -----------------------------------------------------------------------
inline void CurrencyFormatter::ImplInit()
{
mnType = FORMAT_CURRENCY;
}
// -----------------------------------------------------------------------
CurrencyFormatter::CurrencyFormatter()
{
ImplInit();
}
// -----------------------------------------------------------------------
CurrencyFormatter::~CurrencyFormatter()
{
}
// -----------------------------------------------------------------------
String CurrencyFormatter::GetCurrencySymbol() const
{
2011-12-22 15:47:08 -05:00
return ImplGetLocaleDataWrapper().getCurrSymbol();
}
// -----------------------------------------------------------------------
void CurrencyFormatter::SetValue( sal_Int64 nNewValue )
2000-09-18 16:07:07 +00:00
{
SetUserValue( nNewValue );
mnFieldValue = mnLastValue;
SetEmptyFieldValueData( sal_False );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
XubString CurrencyFormatter::CreateFieldText( sal_Int64 nValue ) const
2000-09-18 16:07:07 +00:00
{
2001-07-20 12:19:24 +00:00
return ImplGetLocaleDataWrapper().getCurr( nValue, GetDecimalDigits(), GetCurrencySymbol(), IsUseThousandSep() );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
sal_Int64 CurrencyFormatter::GetValue() const
2000-09-18 16:07:07 +00:00
{
if ( !GetField() )
return 0;
double nTempValue;
2001-07-20 12:19:24 +00:00
if ( ImplCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
2000-09-18 16:07:07 +00:00
{
// caution: precision loss in double cast
2000-09-18 16:07:07 +00:00
if ( nTempValue > mnMax )
nTempValue = (double)mnMax;
2000-09-18 16:07:07 +00:00
else if ( nTempValue < mnMin )
nTempValue = (double)mnMin;
return (sal_Int64)nTempValue;
2000-09-18 16:07:07 +00:00
}
else
return mnLastValue;
}
// -----------------------------------------------------------------------
void CurrencyFormatter::Reformat()
{
if ( !GetField() )
return;
XubString aStr;
sal_Bool bOK = ImplCurrencyReformat( GetField()->GetText(), aStr );
2000-09-18 16:07:07 +00:00
if ( !bOK )
return;
if ( aStr.Len() )
{
ImplSetText( aStr );
// caution: precision loss in double cast
double nTemp = (double)mnLastValue;
2001-07-20 12:19:24 +00:00
ImplCurrencyGetValue( aStr, nTemp, GetDecimalDigits(), ImplGetLocaleDataWrapper() );
mnLastValue = (sal_Int64)nTemp;
2000-09-18 16:07:07 +00:00
}
else
SetValue( mnLastValue );
}
// -----------------------------------------------------------------------
CurrencyField::CurrencyField( Window* pParent, WinBits nWinStyle ) :
SpinField( pParent, nWinStyle )
{
SetField( this );
Reformat();
}
// -----------------------------------------------------------------------
CurrencyField::~CurrencyField()
{
}
// -----------------------------------------------------------------------
long CurrencyField::PreNotify( NotifyEvent& rNEvt )
{
if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
2000-09-18 16:07:07 +00:00
{
2001-07-20 12:19:24 +00:00
if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
2000-09-18 16:07:07 +00:00
return 1;
}
return SpinField::PreNotify( rNEvt );
}
// -----------------------------------------------------------------------
long CurrencyField::Notify( NotifyEvent& rNEvt )
{
if ( rNEvt.GetType() == EVENT_GETFOCUS )
MarkToBeReformatted( sal_False );
2000-09-18 16:07:07 +00:00
else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
{
if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
Reformat();
}
return SpinField::Notify( rNEvt );
}
// -----------------------------------------------------------------------
void CurrencyField::DataChanged( const DataChangedEvent& rDCEvt )
{
SpinField::DataChanged( rDCEvt );
if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
{
String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
if ( IsDefaultLocale() )
2001-07-20 12:19:24 +00:00
ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
2000-09-18 16:07:07 +00:00
ReformatAll();
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void CurrencyField::Modify()
{
MarkToBeReformatted( sal_True );
2000-09-18 16:07:07 +00:00
SpinField::Modify();
}
// -----------------------------------------------------------------------
void CurrencyField::Up()
{
FieldUp();
SpinField::Up();
}
// -----------------------------------------------------------------------
void CurrencyField::Down()
{
FieldDown();
SpinField::Down();
}
// -----------------------------------------------------------------------
void CurrencyField::First()
{
FieldFirst();
SpinField::First();
}
// -----------------------------------------------------------------------
void CurrencyField::Last()
{
FieldLast();
SpinField::Last();
}
// -----------------------------------------------------------------------
CurrencyBox::CurrencyBox( Window* pParent, WinBits nWinStyle ) :
ComboBox( pParent, nWinStyle )
{
SetField( this );
Reformat();
}
// -----------------------------------------------------------------------
CurrencyBox::~CurrencyBox()
{
}
// -----------------------------------------------------------------------
long CurrencyBox::PreNotify( NotifyEvent& rNEvt )
{
if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
2000-09-18 16:07:07 +00:00
{
2001-07-20 12:19:24 +00:00
if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
2000-09-18 16:07:07 +00:00
return 1;
}
return ComboBox::PreNotify( rNEvt );
}
// -----------------------------------------------------------------------
long CurrencyBox::Notify( NotifyEvent& rNEvt )
{
if ( rNEvt.GetType() == EVENT_GETFOCUS )
MarkToBeReformatted( sal_False );
2000-09-18 16:07:07 +00:00
else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
{
if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
Reformat();
}
return ComboBox::Notify( rNEvt );
}
// -----------------------------------------------------------------------
void CurrencyBox::DataChanged( const DataChangedEvent& rDCEvt )
{
ComboBox::DataChanged( rDCEvt );
if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
{
String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
if ( IsDefaultLocale() )
2001-07-20 12:19:24 +00:00
ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
2000-09-18 16:07:07 +00:00
ReformatAll();
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void CurrencyBox::Modify()
{
MarkToBeReformatted( sal_True );
2000-09-18 16:07:07 +00:00
ComboBox::Modify();
}
// -----------------------------------------------------------------------
void CurrencyBox::ReformatAll()
{
XubString aStr;
SetUpdateMode( sal_False );
sal_uInt16 nEntryCount = GetEntryCount();
for ( sal_uInt16 i=0; i < nEntryCount; i++ )
2000-09-18 16:07:07 +00:00
{
ImplCurrencyReformat( GetEntry( i ), aStr );
RemoveEntry( i );
InsertEntry( aStr, i );
}
CurrencyFormatter::Reformat();
SetUpdateMode( sal_True );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
sal_Int64 CurrencyBox::GetValue() const
{
// Implementation not inline, because it is a virtual Function
return CurrencyFormatter::GetValue();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */