1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_vcl.hxx" 26 27 #ifndef _BIGINT_HXX 28 #define _TOOLS_BIGINT 29 #include "tools/bigint.hxx" 30 #endif 31 32 #include "tools/debug.hxx" 33 34 #include "tools/rc.h" 35 #include "tools/resary.hxx" 36 37 #include "vcl/field.hxx" 38 #include "vcl/event.hxx" 39 #include "vcl/svapp.hxx" 40 #include "vcl/unohelp.hxx" 41 42 #include "svids.hrc" 43 #include "svdata.hxx" 44 45 #include "i18nutil/unicode.hxx" 46 47 #include "rtl/math.hxx" 48 49 50 #include <unotools/localedatawrapper.hxx> 51 52 using namespace ::com::sun::star; 53 54 // ----------------------------------------------------------------------- 55 56 #define FORMAT_NUMERIC 1 57 #define FORMAT_METRIC 2 58 #define FORMAT_CURRENCY 3 59 60 // ----------------------------------------------------------------------- 61 62 static sal_Int64 ImplPower10( sal_uInt16 n ) 63 { 64 sal_uInt16 i; 65 sal_Int64 nValue = 1; 66 67 for ( i=0; i < n; i++ ) 68 nValue *= 10; 69 70 return nValue; 71 } 72 73 // ----------------------------------------------------------------------- 74 75 static sal_Bool ImplNumericProcessKeyInput( Edit*, const KeyEvent& rKEvt, 76 sal_Bool bStrictFormat, sal_Bool bThousandSep, 77 const LocaleDataWrapper& rLocaleDataWrappper ) 78 { 79 if ( !bStrictFormat ) 80 return sal_False; 81 else 82 { 83 xub_Unicode cChar = rKEvt.GetCharCode(); 84 sal_uInt16 nGroup = rKEvt.GetKeyCode().GetGroup(); 85 86 if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) || 87 (nGroup == KEYGROUP_MISC) || 88 ((cChar >= '0') && (cChar <= '9')) || 89 (cChar == rLocaleDataWrappper.getNumDecimalSep() ) || 90 (bThousandSep && (cChar == rLocaleDataWrappper.getNumThousandSep())) || 91 (cChar == '-') ) 92 return sal_False; 93 else 94 return sal_True; 95 } 96 } 97 98 // ----------------------------------------------------------------------- 99 100 static sal_Bool ImplNumericGetValue( const XubString& rStr, double& rValue, 101 sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrappper, 102 sal_Bool bCurrency = sal_False ) 103 { 104 XubString aStr = rStr; 105 XubString aStr1; 106 XubString aStr2; 107 sal_Bool bNegative = sal_False; 108 xub_StrLen nDecPos; 109 xub_StrLen i; 110 111 // Reaktion auf leeren String 112 if ( !rStr.Len() ) 113 return sal_False; 114 115 // Fuehrende und nachfolgende Leerzeichen entfernen 116 aStr.EraseLeadingAndTrailingChars( ' ' ); 117 118 // Position des Dezimalpunktes suchen 119 nDecPos = aStr.Search( rLocaleDataWrappper.getNumDecimalSep() ); 120 if ( nDecPos != STRING_NOTFOUND ) 121 { 122 aStr1 = aStr.Copy( 0, nDecPos ); 123 aStr2 = aStr.Copy( nDecPos+1 ); 124 } 125 else 126 aStr1 = aStr; 127 128 // Negativ ? 129 if ( bCurrency ) 130 { 131 if ( (aStr.GetChar( 0 ) == '(') && (aStr.GetChar( aStr.Len()-1 ) == ')') ) 132 bNegative = sal_True; 133 if ( !bNegative ) 134 { 135 for ( i=0; i < aStr.Len(); i++ ) 136 { 137 if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') ) 138 break; 139 else if ( aStr.GetChar( i ) == '-' ) 140 { 141 bNegative = sal_True; 142 break; 143 } 144 } 145 } 146 if ( !bNegative && bCurrency && aStr.Len() ) 147 { 148 sal_uInt16 nFormat = rLocaleDataWrappper.getCurrNegativeFormat(); 149 if ( (nFormat == 3) || (nFormat == 6) || 150 (nFormat == 7) || (nFormat == 10) ) 151 { 152 for ( i = (xub_StrLen)(aStr.Len()-1); i > 0; i++ ) 153 { 154 if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') ) 155 break; 156 else if ( aStr.GetChar( i ) == '-' ) 157 { 158 bNegative = sal_True; 159 break; 160 } 161 } 162 } 163 } 164 } 165 else 166 { 167 if ( aStr1.GetChar( 0 ) == '-' ) 168 bNegative = sal_True; 169 } 170 171 // Alle unerwuenschten Zeichen rauswerfen 172 for ( i=0; i < aStr1.Len(); ) 173 { 174 if ( (aStr1.GetChar( i ) >= '0') && (aStr1.GetChar( i ) <= '9') ) 175 i++; 176 else 177 aStr1.Erase( i, 1 ); 178 } 179 for ( i=0; i < aStr2.Len(); ) 180 { 181 if ( (aStr2.GetChar( i ) >= '0') && (aStr2.GetChar( i ) <= '9') ) 182 i++; 183 else 184 aStr2.Erase( i, 1 ); 185 } 186 187 if ( !aStr1.Len() && !aStr2.Len() ) 188 return sal_False; 189 190 if ( !aStr1.Len() ) 191 aStr1.Insert( '0' ); 192 if ( bNegative ) 193 aStr1.Insert( '-', 0 ); 194 195 // Nachkommateil zurechtstutzen und dabei runden 196 sal_Bool bRound = sal_False; 197 if ( aStr2.Len() > nDecDigits ) 198 { 199 if ( aStr2.GetChar( nDecDigits ) >= '5' ) 200 bRound = sal_True; 201 aStr2.Erase( nDecDigits ); 202 } 203 if ( aStr2.Len() < nDecDigits ) 204 aStr2.Expand( nDecDigits, '0' ); 205 206 aStr = aStr1; 207 aStr += aStr2; 208 209 // Bereichsueberpruefung 210 double nValue = aStr.ToDouble(); 211 if ( bRound ) 212 { 213 if ( !bNegative ) 214 nValue++; 215 else 216 nValue--; 217 } 218 219 rValue = nValue; 220 221 return sal_True; 222 } 223 224 static void ImplUpdateSeparatorString( String& io_rText, 225 const String& rOldDecSep, const String& rNewDecSep, 226 const String& rOldThSep, const String& rNewThSep ) 227 { 228 rtl::OUStringBuffer aBuf( io_rText.Len() ); 229 xub_StrLen nIndexDec = 0, nIndexTh = 0, nIndex = 0; 230 231 const sal_Unicode* pBuffer = io_rText.GetBuffer(); 232 while( nIndex != STRING_NOTFOUND ) 233 { 234 nIndexDec = io_rText.Search( rOldDecSep, nIndex ); 235 nIndexTh = io_rText.Search( rOldThSep, nIndex ); 236 if( (nIndexTh != STRING_NOTFOUND && nIndexDec != STRING_NOTFOUND && nIndexTh < nIndexDec ) 237 || (nIndexTh != STRING_NOTFOUND && nIndexDec == STRING_NOTFOUND) 238 ) 239 { 240 aBuf.append( pBuffer + nIndex, nIndexTh - nIndex ); 241 aBuf.append( rNewThSep ); 242 nIndex = nIndexTh + rOldThSep.Len(); 243 } 244 else if( nIndexDec != STRING_NOTFOUND ) 245 { 246 aBuf.append( pBuffer + nIndex, nIndexDec - nIndex ); 247 aBuf.append( rNewDecSep ); 248 nIndex = nIndexDec + rOldDecSep.Len(); 249 } 250 else 251 { 252 aBuf.append( pBuffer + nIndex ); 253 nIndex = STRING_NOTFOUND; 254 } 255 } 256 257 io_rText = aBuf.makeStringAndClear(); 258 } 259 260 static void ImplUpdateSeparators( const String& rOldDecSep, const String& rNewDecSep, 261 const String& rOldThSep, const String& rNewThSep, 262 Edit* pEdit ) 263 { 264 bool bChangeDec = (rOldDecSep != rNewDecSep); 265 bool bChangeTh = (rOldThSep != rNewThSep ); 266 267 if( bChangeDec || bChangeTh ) 268 { 269 sal_Bool bUpdateMode = pEdit->IsUpdateMode(); 270 pEdit->SetUpdateMode( sal_False ); 271 String aText = pEdit->GetText(); 272 ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep ); 273 pEdit->SetText( aText ); 274 275 ComboBox* pCombo = dynamic_cast<ComboBox*>(pEdit); 276 if( pCombo ) 277 { 278 // update box entries 279 sal_uInt16 nEntryCount = pCombo->GetEntryCount(); 280 for ( sal_uInt16 i=0; i < nEntryCount; i++ ) 281 { 282 aText = pCombo->GetEntry( i ); 283 void* pEntryData = pCombo->GetEntryData( i ); 284 ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep ); 285 pCombo->RemoveEntry( i ); 286 pCombo->InsertEntry( aText, i ); 287 pCombo->SetEntryData( i, pEntryData ); 288 } 289 } 290 if( bUpdateMode ) 291 pEdit->SetUpdateMode( bUpdateMode ); 292 } 293 } 294 295 // ----------------------------------------------------------------------- 296 297 FormatterBase::FormatterBase( Edit* pField ) 298 { 299 mpField = pField; 300 mpLocaleDataWrapper = NULL; 301 mbReformat = sal_False; 302 mbStrictFormat = sal_False; 303 mbEmptyFieldValue = sal_False; 304 mbEmptyFieldValueEnabled = sal_False; 305 mbDefaultLocale = sal_True; 306 } 307 308 // ----------------------------------------------------------------------- 309 310 FormatterBase::~FormatterBase() 311 { 312 delete mpLocaleDataWrapper; 313 } 314 315 // ----------------------------------------------------------------------- 316 317 LocaleDataWrapper& FormatterBase::ImplGetLocaleDataWrapper() const 318 { 319 if ( !mpLocaleDataWrapper ) 320 { 321 ((FormatterBase*)this)->mpLocaleDataWrapper = new LocaleDataWrapper( vcl::unohelper::GetMultiServiceFactory(), GetLocale() ); 322 } 323 return *mpLocaleDataWrapper; 324 } 325 326 const LocaleDataWrapper& FormatterBase::GetLocaleDataWrapper() const 327 { 328 return ImplGetLocaleDataWrapper(); 329 } 330 331 // ----------------------------------------------------------------------- 332 333 void FormatterBase::Reformat() 334 { 335 } 336 337 // ----------------------------------------------------------------------- 338 339 void FormatterBase::ReformatAll() 340 { 341 Reformat(); 342 }; 343 344 // ----------------------------------------------------------------------- 345 346 void FormatterBase::SetStrictFormat( sal_Bool bStrict ) 347 { 348 if ( bStrict != mbStrictFormat ) 349 { 350 mbStrictFormat = bStrict; 351 if ( mbStrictFormat ) 352 ReformatAll(); 353 } 354 } 355 356 // ----------------------------------------------------------------------- 357 358 void FormatterBase::SetLocale( const lang::Locale& rLocale ) 359 { 360 ImplGetLocaleDataWrapper().setLocale( rLocale ); 361 mbDefaultLocale = sal_False; 362 ReformatAll(); 363 } 364 365 // ----------------------------------------------------------------------- 366 367 const lang::Locale& FormatterBase::GetLocale() const 368 { 369 if ( !mpLocaleDataWrapper || mbDefaultLocale ) 370 { 371 if ( mpField ) 372 return mpField->GetSettings().GetLocale(); 373 else 374 return Application::GetSettings().GetLocale(); 375 } 376 377 return mpLocaleDataWrapper->getLocale(); 378 } 379 380 // ----------------------------------------------------------------------- 381 382 const AllSettings& FormatterBase::GetFieldSettings() const 383 { 384 if ( mpField ) 385 return mpField->GetSettings(); 386 else 387 return Application::GetSettings(); 388 } 389 390 // ----------------------------------------------------------------------- 391 392 void FormatterBase::SetFieldText( const XubString& rText, sal_Bool bKeepSelection ) 393 { 394 if ( mpField ) 395 { 396 Selection aNewSelection( 0xFFFF, 0xFFFF ); 397 if ( bKeepSelection ) 398 aNewSelection = mpField->GetSelection(); 399 400 ImplSetText( rText, &aNewSelection ); 401 } 402 } 403 404 // ----------------------------------------------------------------------- 405 406 void FormatterBase::ImplSetText( const XubString& rText, Selection* pNewSelection ) 407 { 408 if ( mpField ) 409 { 410 if ( pNewSelection ) 411 mpField->SetText( rText, *pNewSelection ); 412 else 413 { 414 Selection aSel = mpField->GetSelection(); 415 aSel.Min() = aSel.Max(); 416 mpField->SetText( rText, aSel ); 417 } 418 419 MarkToBeReformatted( sal_False ); 420 } 421 } 422 423 // ----------------------------------------------------------------------- 424 425 void FormatterBase::SetEmptyFieldValue() 426 { 427 if ( mpField ) 428 mpField->SetText( ImplGetSVEmptyStr() ); 429 mbEmptyFieldValue = sal_True; 430 } 431 432 // ----------------------------------------------------------------------- 433 434 sal_Bool FormatterBase::IsEmptyFieldValue() const 435 { 436 return (!mpField || !mpField->GetText().Len()); 437 } 438 439 // ----------------------------------------------------------------------- 440 441 sal_Bool NumericFormatter::ImplNumericReformat( const XubString& rStr, double& rValue, 442 XubString& rOutStr ) 443 { 444 if ( !ImplNumericGetValue( rStr, rValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) ) 445 return sal_True; 446 else 447 { 448 double nTempVal = rValue; 449 // caution: precision loss in double cast 450 if ( nTempVal > mnMax ) 451 nTempVal = (double)mnMax; 452 else if ( nTempVal < mnMin ) 453 nTempVal = (double)mnMin; 454 455 if ( GetErrorHdl().IsSet() && (rValue != nTempVal) ) 456 { 457 mnCorrectedValue = (sal_Int64)nTempVal; 458 if ( !GetErrorHdl().Call( this ) ) 459 { 460 mnCorrectedValue = 0; 461 return sal_False; 462 } 463 else 464 mnCorrectedValue = 0; 465 } 466 467 rOutStr = CreateFieldText( (sal_Int64)nTempVal ); 468 return sal_True; 469 } 470 } 471 472 // ----------------------------------------------------------------------- 473 474 void NumericFormatter::ImplInit() 475 { 476 mnFieldValue = 0; 477 mnLastValue = 0; 478 mnMin = 0; 479 mnMax = 0x7FFFFFFFFFFFFFFFLL; 480 #ifdef OS2 // see i120312 for details. 481 mnMax = 0x00000000FFFFFFFFLL; 482 #endif 483 mnCorrectedValue = 0; 484 mnDecimalDigits = 2; 485 mnType = FORMAT_NUMERIC; 486 mbThousandSep = sal_True; 487 mbShowTrailingZeros = sal_True; 488 489 // for fields 490 mnSpinSize = 1; 491 mnFirst = mnMin; 492 mnLast = mnMax; 493 494 SetDecimalDigits( 0 ); 495 } 496 497 // ----------------------------------------------------------------------- 498 499 NumericFormatter::NumericFormatter() 500 { 501 ImplInit(); 502 } 503 504 // ----------------------------------------------------------------------- 505 506 void NumericFormatter::ImplLoadRes( const ResId& rResId ) 507 { 508 ResMgr* pMgr = rResId.GetResMgr(); 509 510 if( pMgr ) 511 { 512 sal_uLong nMask = pMgr->ReadLong(); 513 514 if ( NUMERICFORMATTER_MIN & nMask ) 515 mnMin = pMgr->ReadLong(); 516 517 if ( NUMERICFORMATTER_MAX & nMask ) 518 mnMax = pMgr->ReadLong(); 519 520 if ( NUMERICFORMATTER_STRICTFORMAT & nMask ) 521 SetStrictFormat( (sal_Bool)pMgr->ReadShort() ); 522 523 if ( NUMERICFORMATTER_DECIMALDIGITS & nMask ) 524 SetDecimalDigits( pMgr->ReadShort() ); 525 526 if ( NUMERICFORMATTER_VALUE & nMask ) 527 { 528 mnFieldValue = pMgr->ReadLong(); 529 if ( mnFieldValue > mnMax ) 530 mnFieldValue = mnMax; 531 else if ( mnFieldValue < mnMin ) 532 mnFieldValue = mnMin; 533 mnLastValue = mnFieldValue; 534 } 535 536 if ( NUMERICFORMATTER_NOTHOUSANDSEP & nMask ) 537 SetUseThousandSep( !(sal_Bool)pMgr->ReadShort() ); 538 } 539 } 540 541 // ----------------------------------------------------------------------- 542 543 NumericFormatter::~NumericFormatter() 544 { 545 } 546 547 // ----------------------------------------------------------------------- 548 549 void NumericFormatter::SetMin( sal_Int64 nNewMin ) 550 { 551 mnMin = nNewMin; 552 if ( !IsEmptyFieldValue() ) 553 ReformatAll(); 554 } 555 556 // ----------------------------------------------------------------------- 557 558 void NumericFormatter::SetMax( sal_Int64 nNewMax ) 559 { 560 mnMax = nNewMax; 561 if ( !IsEmptyFieldValue() ) 562 ReformatAll(); 563 } 564 565 // ----------------------------------------------------------------------- 566 567 void NumericFormatter::SetUseThousandSep( sal_Bool b ) 568 { 569 mbThousandSep = b; 570 ReformatAll(); 571 } 572 573 // ----------------------------------------------------------------------- 574 575 void NumericFormatter::SetDecimalDigits( sal_uInt16 nDigits ) 576 { 577 mnDecimalDigits = nDigits; 578 ReformatAll(); 579 } 580 581 // ----------------------------------------------------------------------- 582 583 void NumericFormatter::SetShowTrailingZeros( sal_Bool bShowTrailingZeros ) 584 { 585 if ( mbShowTrailingZeros != bShowTrailingZeros ) 586 { 587 mbShowTrailingZeros = bShowTrailingZeros; 588 ReformatAll(); 589 } 590 } 591 592 // ----------------------------------------------------------------------- 593 594 sal_uInt16 NumericFormatter::GetDecimalDigits() const 595 { 596 return mnDecimalDigits; 597 } 598 599 // ----------------------------------------------------------------------- 600 601 void NumericFormatter::SetValue( sal_Int64 nNewValue ) 602 { 603 SetUserValue( nNewValue ); 604 mnFieldValue = mnLastValue; 605 SetEmptyFieldValueData( sal_False ); 606 } 607 608 // ----------------------------------------------------------------------- 609 610 XubString NumericFormatter::CreateFieldText( sal_Int64 nValue ) const 611 { 612 return ImplGetLocaleDataWrapper().getNum( nValue, GetDecimalDigits(), IsUseThousandSep(), IsShowTrailingZeros() ); 613 } 614 615 // ----------------------------------------------------------------------- 616 617 void NumericFormatter::ImplSetUserValue( sal_Int64 nNewValue, Selection* pNewSelection ) 618 { 619 if ( nNewValue > mnMax ) 620 nNewValue = mnMax; 621 else if ( nNewValue < mnMin ) 622 nNewValue = mnMin; 623 mnLastValue = nNewValue; 624 625 if ( GetField() ) 626 ImplSetText( CreateFieldText( nNewValue ), pNewSelection ); 627 } 628 629 // ----------------------------------------------------------------------- 630 631 void NumericFormatter::SetUserValue( sal_Int64 nNewValue ) 632 { 633 ImplSetUserValue( nNewValue ); 634 } 635 636 // ----------------------------------------------------------------------- 637 638 sal_Int64 NumericFormatter::GetValue() const 639 { 640 if ( !GetField() ) 641 return 0; 642 643 double nTempValue; 644 645 if ( ImplNumericGetValue( GetField()->GetText(), nTempValue, 646 GetDecimalDigits(), ImplGetLocaleDataWrapper() ) ) 647 { 648 // caution: precision loss in double cast 649 if ( nTempValue > mnMax ) 650 nTempValue = (double)mnMax; 651 else if ( nTempValue < mnMin ) 652 nTempValue = (double)mnMin; 653 return (sal_Int64)nTempValue; 654 } 655 else 656 return mnLastValue; 657 } 658 659 // ----------------------------------------------------------------------- 660 661 sal_Bool NumericFormatter::IsValueModified() const 662 { 663 if ( ImplGetEmptyFieldValue() ) 664 return !IsEmptyFieldValue(); 665 else if ( GetValue() != mnFieldValue ) 666 return sal_True; 667 else 668 return sal_False; 669 } 670 671 // ----------------------------------------------------------------------- 672 673 Fraction NumericFormatter::ConvertToFraction( sal_Int64 nValue ) 674 { 675 // caution: precision loss in double cast (and in fraction anyhow) 676 return Fraction( (double)nValue/(double)ImplPower10( GetDecimalDigits() ) ); 677 } 678 679 // ----------------------------------------------------------------------- 680 681 sal_Int64 NumericFormatter::ConvertToLong( const Fraction& rValue ) 682 { 683 Fraction aFract = rValue; 684 aFract *= Fraction( (long)ImplPower10( GetDecimalDigits() ), 1 ); 685 return (sal_Int64)(double)aFract; 686 } 687 688 // ----------------------------------------------------------------------- 689 690 sal_Int64 NumericFormatter::Normalize( sal_Int64 nValue ) const 691 { 692 return (nValue * ImplPower10( GetDecimalDigits() ) ); 693 } 694 695 // ----------------------------------------------------------------------- 696 697 sal_Int64 NumericFormatter::Denormalize( sal_Int64 nValue ) const 698 { 699 sal_Int64 nFactor = ImplPower10( GetDecimalDigits() ); 700 701 if((nValue < ( SAL_MIN_INT64 + nFactor )) || 702 (nValue > ( SAL_MAX_INT64 - nFactor ))) 703 return ( nValue / nFactor ); 704 if( nValue < 0 ) 705 return ((nValue-(nFactor/2)) / nFactor ); 706 else 707 return ((nValue+(nFactor/2)) / nFactor ); 708 } 709 710 // ----------------------------------------------------------------------- 711 712 void NumericFormatter::Reformat() 713 { 714 if ( !GetField() ) 715 return; 716 717 if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() ) 718 return; 719 720 XubString aStr; 721 // caution: precision loss in double cast 722 double nTemp = (double)mnLastValue; 723 sal_Bool bOK = ImplNumericReformat( GetField()->GetText(), nTemp, aStr ); 724 mnLastValue = (sal_Int64)nTemp; 725 if ( !bOK ) 726 return; 727 728 if ( aStr.Len() ) 729 ImplSetText( aStr ); 730 else 731 SetValue( mnLastValue ); 732 } 733 734 // ----------------------------------------------------------------------- 735 736 void NumericFormatter::FieldUp() 737 { 738 sal_Int64 nValue = GetValue(); 739 nValue += mnSpinSize; 740 if ( nValue > mnMax ) 741 nValue = mnMax; 742 743 ImplNewFieldValue( nValue ); 744 } 745 746 // ----------------------------------------------------------------------- 747 748 void NumericFormatter::FieldDown() 749 { 750 sal_Int64 nValue = GetValue(); 751 nValue -= mnSpinSize; 752 if ( nValue < mnMin ) 753 nValue = mnMin; 754 755 ImplNewFieldValue( nValue ); 756 } 757 758 // ----------------------------------------------------------------------- 759 760 void NumericFormatter::FieldFirst() 761 { 762 ImplNewFieldValue( mnFirst ); 763 } 764 765 // ----------------------------------------------------------------------- 766 767 void NumericFormatter::FieldLast() 768 { 769 ImplNewFieldValue( mnLast ); 770 } 771 772 // ----------------------------------------------------------------------- 773 774 void NumericFormatter::ImplNewFieldValue( sal_Int64 nNewValue ) 775 { 776 if ( GetField() ) 777 { 778 // !!! TH-18.2.99: Wenn wir Zeit haben sollte mal geklaert werden, 779 // !!! warum nicht bei ImplSetUserValue() geprueft wird, ob 780 // !!! sich der Wert aendert. Denn auch hier muesste dieses 781 // !!! gemacht werden, da ansonsten der Modify-Aufruf 782 // !!! nicht gemacht werden duerfte. Jedenfalls sollten die 783 // !!! Wege von ImplNewFieldValue, ImplSetUserValue und 784 // !!! ImplSetText ueberprueft und klarer gestalltet (mit Kommentar) 785 // !!! werden, damit wir mal wissen, was dort ablaeuft!!! 786 787 Selection aSelection = GetField()->GetSelection(); 788 aSelection.Justify(); 789 XubString aText = GetField()->GetText(); 790 // Wenn bis ans Ende selektiert war, soll das auch so bleiben... 791 if ( (xub_StrLen)aSelection.Max() == aText.Len() ) 792 { 793 if ( !aSelection.Len() ) 794 aSelection.Min() = SELECTION_MAX; 795 aSelection.Max() = SELECTION_MAX; 796 } 797 798 sal_Int64 nOldLastValue = mnLastValue; 799 ImplSetUserValue( nNewValue, &aSelection ); 800 mnLastValue = nOldLastValue; 801 802 // Modify am Edit wird nur bei KeyInput gesetzt... 803 if ( GetField()->GetText() != aText ) 804 { 805 GetField()->SetModifyFlag(); 806 GetField()->Modify(); 807 } 808 } 809 } 810 811 // ----------------------------------------------------------------------- 812 813 NumericField::NumericField( Window* pParent, WinBits nWinStyle ) : 814 SpinField( pParent, nWinStyle ) 815 { 816 SetField( this ); 817 Reformat(); 818 } 819 820 // ----------------------------------------------------------------------- 821 822 NumericField::NumericField( Window* pParent, const ResId& rResId ) : 823 SpinField( WINDOW_NUMERICFIELD ) 824 { 825 rResId.SetRT( RSC_NUMERICFIELD ); 826 WinBits nStyle = ImplInitRes( rResId ) ; 827 SpinField::ImplInit( pParent, nStyle ); 828 SetField( this ); 829 ImplLoadRes( rResId ); 830 Reformat(); 831 832 if ( !(nStyle & WB_HIDE ) ) 833 Show(); 834 } 835 836 // ----------------------------------------------------------------------- 837 838 void NumericField::ImplLoadRes( const ResId& rResId ) 839 { 840 SpinField::ImplLoadRes( rResId ); 841 NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 842 843 sal_uLong nMask = ReadLongRes(); 844 845 if ( NUMERICFIELD_FIRST & nMask ) 846 mnFirst = ReadLongRes(); 847 848 if ( NUMERICFIELD_LAST & nMask ) 849 mnLast = ReadLongRes(); 850 851 if ( NUMERICFIELD_SPINSIZE & nMask ) 852 mnSpinSize = ReadLongRes(); 853 } 854 855 // ----------------------------------------------------------------------- 856 857 NumericField::~NumericField() 858 { 859 } 860 861 // ----------------------------------------------------------------------- 862 863 long NumericField::PreNotify( NotifyEvent& rNEvt ) 864 { 865 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 866 { 867 if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 868 return 1; 869 } 870 871 return SpinField::PreNotify( rNEvt ); 872 } 873 874 // ----------------------------------------------------------------------- 875 876 long NumericField::Notify( NotifyEvent& rNEvt ) 877 { 878 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 879 MarkToBeReformatted( sal_False ); 880 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 881 { 882 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 883 Reformat(); 884 } 885 886 return SpinField::Notify( rNEvt ); 887 } 888 889 // ----------------------------------------------------------------------- 890 891 void NumericField::DataChanged( const DataChangedEvent& rDCEvt ) 892 { 893 SpinField::DataChanged( rDCEvt ); 894 895 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 896 { 897 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 898 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 899 if ( IsDefaultLocale() ) 900 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 901 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 902 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 903 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 904 ReformatAll(); 905 } 906 } 907 908 // ----------------------------------------------------------------------- 909 910 void NumericField::Modify() 911 { 912 MarkToBeReformatted( sal_True ); 913 SpinField::Modify(); 914 } 915 916 // ----------------------------------------------------------------------- 917 918 void NumericField::Up() 919 { 920 FieldUp(); 921 SpinField::Up(); 922 } 923 924 // ----------------------------------------------------------------------- 925 926 void NumericField::Down() 927 { 928 FieldDown(); 929 SpinField::Down(); 930 } 931 932 // ----------------------------------------------------------------------- 933 934 void NumericField::First() 935 { 936 FieldFirst(); 937 SpinField::First(); 938 } 939 940 // ----------------------------------------------------------------------- 941 942 void NumericField::Last() 943 { 944 FieldLast(); 945 SpinField::Last(); 946 } 947 948 // ----------------------------------------------------------------------- 949 950 NumericBox::NumericBox( Window* pParent, WinBits nWinStyle ) : 951 ComboBox( pParent, nWinStyle ) 952 { 953 SetField( this ); 954 Reformat(); 955 } 956 957 // ----------------------------------------------------------------------- 958 959 NumericBox::NumericBox( Window* pParent, const ResId& rResId ) : 960 ComboBox( WINDOW_NUMERICBOX ) 961 { 962 rResId.SetRT( RSC_NUMERICBOX ); 963 WinBits nStyle = ImplInitRes( rResId ); 964 ComboBox::ImplInit( pParent, nStyle ); 965 SetField( this ); 966 ComboBox::ImplLoadRes( rResId ); 967 NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 968 Reformat(); 969 970 if ( !(nStyle & WB_HIDE ) ) 971 Show(); 972 } 973 974 // ----------------------------------------------------------------------- 975 976 NumericBox::~NumericBox() 977 { 978 } 979 980 // ----------------------------------------------------------------------- 981 982 long NumericBox::PreNotify( NotifyEvent& rNEvt ) 983 { 984 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 985 { 986 if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 987 return 1; 988 } 989 990 return ComboBox::PreNotify( rNEvt ); 991 } 992 993 // ----------------------------------------------------------------------- 994 995 long NumericBox::Notify( NotifyEvent& rNEvt ) 996 { 997 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 998 MarkToBeReformatted( sal_False ); 999 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 1000 { 1001 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 1002 Reformat(); 1003 } 1004 1005 return ComboBox::Notify( rNEvt ); 1006 } 1007 1008 // ----------------------------------------------------------------------- 1009 1010 void NumericBox::DataChanged( const DataChangedEvent& rDCEvt ) 1011 { 1012 ComboBox::DataChanged( rDCEvt ); 1013 1014 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 1015 { 1016 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1017 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1018 if ( IsDefaultLocale() ) 1019 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 1020 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1021 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1022 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 1023 ReformatAll(); 1024 } 1025 } 1026 1027 // ----------------------------------------------------------------------- 1028 1029 void NumericBox::Modify() 1030 { 1031 MarkToBeReformatted( sal_True ); 1032 ComboBox::Modify(); 1033 } 1034 1035 // ----------------------------------------------------------------------- 1036 1037 void NumericBox::ReformatAll() 1038 { 1039 double nValue; 1040 XubString aStr; 1041 SetUpdateMode( sal_False ); 1042 sal_uInt16 nEntryCount = GetEntryCount(); 1043 for ( sal_uInt16 i=0; i < nEntryCount; i++ ) 1044 { 1045 ImplNumericReformat( GetEntry( i ), nValue, aStr ); 1046 RemoveEntry( i ); 1047 InsertEntry( aStr, i ); 1048 } 1049 NumericFormatter::Reformat(); 1050 SetUpdateMode( sal_True ); 1051 } 1052 1053 // ----------------------------------------------------------------------- 1054 1055 void NumericBox::InsertValue( sal_Int64 nValue, sal_uInt16 nPos ) 1056 { 1057 ComboBox::InsertEntry( CreateFieldText( nValue ), nPos ); 1058 } 1059 1060 // ----------------------------------------------------------------------- 1061 1062 void NumericBox::RemoveValue( sal_Int64 nValue ) 1063 { 1064 ComboBox::RemoveEntry( CreateFieldText( nValue ) ); 1065 } 1066 1067 // ----------------------------------------------------------------------- 1068 1069 sal_Int64 NumericBox::GetValue( sal_uInt16 nPos ) const 1070 { 1071 double nValue = 0; 1072 ImplNumericGetValue( ComboBox::GetEntry( nPos ), nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ); 1073 return (sal_Int64)nValue; 1074 } 1075 1076 // ----------------------------------------------------------------------- 1077 1078 sal_uInt16 NumericBox::GetValuePos( sal_Int64 nValue ) const 1079 { 1080 return ComboBox::GetEntryPos( CreateFieldText( nValue ) ); 1081 } 1082 1083 // ----------------------------------------------------------------------- 1084 1085 static sal_Bool ImplMetricProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt, 1086 sal_Bool, sal_Bool bUseThousandSep, const LocaleDataWrapper& rWrapper ) 1087 { 1088 // Es gibt hier kein sinnvolles StrictFormat, also alle 1089 // Zeichen erlauben 1090 return ImplNumericProcessKeyInput( pEdit, rKEvt, sal_False, bUseThousandSep, rWrapper ); 1091 } 1092 1093 // ----------------------------------------------------------------------- 1094 1095 static XubString ImplMetricGetUnitText( const XubString& rStr ) 1096 { 1097 // Einheitentext holen 1098 XubString aStr; 1099 for ( short i = rStr.Len()-1; i >= 0; i-- ) 1100 { 1101 xub_Unicode c = rStr.GetChar( i ); 1102 if ( unicode::isAlpha( c ) || 1103 (c == '\'') || (c == '\"') || (c == '%' ) ) 1104 aStr.Insert( c, 0 ); 1105 else 1106 { 1107 if ( aStr.Len() ) 1108 break; 1109 } 1110 } 1111 return aStr; 1112 1113 /* 1114 // MT: #90545# Preparation for translated strings... 1115 String aMetricText; 1116 for ( sal_uInt16 n = rStr.Len(); n; ) 1117 { 1118 sal_Unicode c = rStr.GetChar( --n ); 1119 sal_Int32 nType = xCharClass->getStringType( rStr, n, 1, rLocale ); 1120 1121 if ( CharClass::isLetterType( nType ) ) 1122 { 1123 aMetricText.Insert( c, 0 ); 1124 } 1125 else 1126 { 1127 if ( aMetricText.Len() ) 1128 break; 1129 } 1130 } 1131 */ 1132 } 1133 1134 // ----------------------------------------------------------------------- 1135 1136 // #104355# support localized mesaurements 1137 1138 static const String& ImplMetricToString( FieldUnit rUnit ) 1139 { 1140 FieldUnitStringList* pList = ImplGetFieldUnits(); 1141 if( pList ) 1142 { 1143 // return unit's default string (ie, the first one ) 1144 for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it ) 1145 { 1146 if ( it->second == rUnit ) 1147 return it->first; 1148 } 1149 } 1150 1151 return String::EmptyString(); 1152 } 1153 1154 static FieldUnit ImplStringToMetric( const String &rMetricString ) 1155 { 1156 FieldUnitStringList* pList = ImplGetCleanedFieldUnits(); 1157 if( pList ) 1158 { 1159 // return FieldUnit 1160 String aStr( rMetricString ); 1161 aStr.ToLowerAscii(); 1162 aStr.EraseAllChars( sal_Unicode( ' ' ) ); 1163 for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it ) 1164 { 1165 if ( it->first.Equals( aStr ) ) 1166 return it->second; 1167 } 1168 } 1169 1170 return FUNIT_NONE; 1171 } 1172 1173 // ----------------------------------------------------------------------- 1174 1175 static FieldUnit ImplMetricGetUnit( const XubString& rStr ) 1176 { 1177 XubString aStr = ImplMetricGetUnitText( rStr ); 1178 return ImplStringToMetric( aStr ); 1179 } 1180 1181 #define K *1000L 1182 #define M *1000000L 1183 #define X *5280L 1184 1185 static const sal_Int64 aImplFactor[FUNIT_MILE+1][FUNIT_MILE+1] = 1186 { /* 1187 mm/100 mm cm m km twip point pica inch foot mile */ 1188 { 1, 100, 1 K, 100 K, 100 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X }, 1189 { 1, 1, 10, 1 K, 1 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X }, 1190 { 1, 1, 1, 100, 100 K, 254, 254, 254, 254, 254*12, 254*12 X }, 1191 { 1, 1, 1, 1, 1 K, 254, 254, 254, 254, 254*12, 254*12 X }, 1192 { 1, 1, 1, 1, 1, 0, 254, 254, 254, 254*12, 254*12 X }, 1193 { 1440,144 K,144 K,14400 K, 0, 1, 20, 240, 1440,1440*12,1440*12 X }, 1194 { 72, 7200, 7200, 720 K, 720 M, 1, 1, 12, 72, 72*12, 72*12 X }, 1195 { 6, 600, 600, 60 K, 60 M, 1, 1, 1, 6, 6*12, 6*12 X }, 1196 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 12, 12 X }, 1197 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 X }, 1198 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 } 1199 }; 1200 1201 #undef X 1202 #undef M 1203 #undef K 1204 // twip in km 254/14400 M 1205 1206 static FieldUnit eDefaultUnit = FUNIT_NONE; 1207 1208 FieldUnit MetricField::GetDefaultUnit() { return eDefaultUnit; } 1209 void MetricField::SetDefaultUnit( FieldUnit meUnit ) { eDefaultUnit = meUnit; } 1210 1211 static FieldUnit ImplMap2FieldUnit( MapUnit meUnit, long& nDecDigits ) 1212 { 1213 switch( meUnit ) 1214 { 1215 case MAP_100TH_MM : 1216 nDecDigits -= 2; 1217 return FUNIT_MM; 1218 case MAP_10TH_MM : 1219 nDecDigits -= 1; 1220 return FUNIT_MM; 1221 case MAP_MM : 1222 return FUNIT_MM; 1223 case MAP_CM : 1224 return FUNIT_CM; 1225 case MAP_1000TH_INCH : 1226 nDecDigits -= 3; 1227 return FUNIT_INCH; 1228 case MAP_100TH_INCH : 1229 nDecDigits -= 2; 1230 return FUNIT_INCH; 1231 case MAP_10TH_INCH : 1232 nDecDigits -= 1; 1233 return FUNIT_INCH; 1234 case MAP_INCH : 1235 return FUNIT_INCH; 1236 case MAP_POINT : 1237 return FUNIT_POINT; 1238 case MAP_TWIP : 1239 return FUNIT_TWIP; 1240 default: 1241 DBG_ERROR( "default eInUnit" ); 1242 break; 1243 } 1244 return FUNIT_NONE; 1245 } 1246 1247 // ----------------------------------------------------------------------- 1248 1249 static double nonValueDoubleToValueDouble( double nValue ) 1250 { 1251 return rtl::math::isFinite( nValue ) ? nValue : 0.0; 1252 } 1253 1254 sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits, 1255 FieldUnit eInUnit, FieldUnit eOutUnit ) 1256 { 1257 double nDouble = nonValueDoubleToValueDouble( ConvertDoubleValue( 1258 (double)nValue, mnBaseValue, nDecDigits, eInUnit, eOutUnit ) ); 1259 sal_Int64 nLong ; 1260 1261 // caution: precision loss in double cast 1262 if ( nDouble <= (double)SAL_MIN_INT64 ) 1263 nLong = SAL_MIN_INT64; 1264 else if ( nDouble >= (double)SAL_MAX_INT64 ) 1265 nLong = SAL_MAX_INT64; 1266 else 1267 nLong = static_cast<sal_Int64>( nDouble ); 1268 return ( nLong ); 1269 } 1270 1271 // ----------------------------------------------------------------------- 1272 1273 sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_uInt16 nDigits, 1274 MapUnit eInUnit, FieldUnit eOutUnit ) 1275 { 1276 return static_cast<sal_Int64>( 1277 nonValueDoubleToValueDouble( 1278 ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit ) ) ); 1279 } 1280 1281 // ----------------------------------------------------------------------- 1282 1283 sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_uInt16 nDigits, 1284 FieldUnit eInUnit, MapUnit eOutUnit ) 1285 { 1286 return static_cast<sal_Int64>( 1287 // #150733# cast double to sal_Int64 can throw a 1288 // EXCEPTION_FLT_INVALID_OPERATION on Windows 1289 nonValueDoubleToValueDouble( 1290 ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit ) ) ); 1291 } 1292 1293 // ----------------------------------------------------------------------- 1294 1295 double MetricField::ConvertDoubleValue( double nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits, 1296 FieldUnit eInUnit, FieldUnit eOutUnit ) 1297 { 1298 if ( eInUnit != eOutUnit ) 1299 { 1300 sal_Int64 nMult = 1, nDiv = 1; 1301 1302 if ( eInUnit == FUNIT_PERCENT ) 1303 { 1304 if ( (mnBaseValue <= 0) || (nValue <= 0) ) 1305 return nValue; 1306 nDiv = 100; 1307 for ( sal_uInt16 i=0; i < nDecDigits; i++ ) 1308 nDiv *= 10; 1309 1310 nMult = mnBaseValue; 1311 } 1312 else if ( eOutUnit == FUNIT_PERCENT || 1313 eOutUnit == FUNIT_CUSTOM || 1314 eOutUnit == FUNIT_NONE || 1315 eInUnit == FUNIT_CUSTOM || 1316 eInUnit == FUNIT_NONE ) 1317 return nValue; 1318 else 1319 { 1320 if ( eOutUnit == FUNIT_100TH_MM ) 1321 eOutUnit = FUNIT_NONE; 1322 if ( eInUnit == FUNIT_100TH_MM ) 1323 eInUnit = FUNIT_NONE; 1324 1325 nDiv = aImplFactor[eInUnit][eOutUnit]; 1326 nMult = aImplFactor[eOutUnit][eInUnit]; 1327 1328 DBG_ASSERT( nMult > 0, "illegal *" ); 1329 DBG_ASSERT( nDiv > 0, "illegal /" ); 1330 } 1331 1332 if ( nMult != 1 && nMult > 0 ) 1333 nValue *= nMult; 1334 if ( nDiv != 1 && nDiv > 0 ) 1335 { 1336 nValue += ( nValue < 0 ) ? (-nDiv/2) : (nDiv/2); 1337 nValue /= nDiv; 1338 } 1339 } 1340 1341 return nValue; 1342 } 1343 1344 // ----------------------------------------------------------------------- 1345 1346 double MetricField::ConvertDoubleValue( double nValue, sal_uInt16 nDigits, 1347 MapUnit eInUnit, FieldUnit eOutUnit ) 1348 { 1349 if ( eOutUnit == FUNIT_PERCENT || 1350 eOutUnit == FUNIT_CUSTOM || 1351 eOutUnit == FUNIT_NONE || 1352 eInUnit == MAP_PIXEL || 1353 eInUnit == MAP_SYSFONT || 1354 eInUnit == MAP_APPFONT || 1355 eInUnit == MAP_RELATIVE ) 1356 { 1357 DBG_ERROR( "invalid parameters" ); 1358 return nValue; 1359 } 1360 1361 long nDecDigits = nDigits; 1362 FieldUnit eFieldUnit = ImplMap2FieldUnit( eInUnit, nDecDigits ); 1363 1364 if ( nDecDigits < 0 ) 1365 { 1366 while ( nDecDigits ) 1367 { 1368 nValue += 5; 1369 nValue /= 10; 1370 nDecDigits++; 1371 } 1372 } 1373 else 1374 { 1375 while ( nDecDigits ) 1376 { 1377 nValue *= 10; 1378 nDecDigits--; 1379 } 1380 } 1381 1382 if ( eFieldUnit != eOutUnit ) 1383 { 1384 sal_Int64 nDiv = aImplFactor[eFieldUnit][eOutUnit]; 1385 sal_Int64 nMult = aImplFactor[eOutUnit][eFieldUnit]; 1386 1387 DBG_ASSERT( nMult > 0, "illegal *" ); 1388 DBG_ASSERT( nDiv > 0, "illegal /" ); 1389 1390 if ( nMult != 1 && nMult > 0) 1391 nValue *= nMult; 1392 if ( nDiv != 1 && nDiv > 0 ) 1393 { 1394 nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2); 1395 nValue /= nDiv; 1396 } 1397 } 1398 return nValue; 1399 } 1400 1401 // ----------------------------------------------------------------------- 1402 1403 double MetricField::ConvertDoubleValue( double nValue, sal_uInt16 nDigits, 1404 FieldUnit eInUnit, MapUnit eOutUnit ) 1405 { 1406 if ( eInUnit == FUNIT_PERCENT || 1407 eInUnit == FUNIT_CUSTOM || 1408 eInUnit == FUNIT_NONE || 1409 eOutUnit == MAP_PIXEL || 1410 eOutUnit == MAP_SYSFONT || 1411 eOutUnit == MAP_APPFONT || 1412 eOutUnit == MAP_RELATIVE ) 1413 { 1414 DBG_ERROR( "invalid parameters" ); 1415 return nValue; 1416 } 1417 1418 long nDecDigits = nDigits; 1419 FieldUnit eFieldUnit = ImplMap2FieldUnit( eOutUnit, nDecDigits ); 1420 1421 if ( nDecDigits < 0 ) 1422 { 1423 while ( nDecDigits ) 1424 { 1425 nValue *= 10; 1426 nDecDigits++; 1427 } 1428 } 1429 else 1430 { 1431 while ( nDecDigits ) 1432 { 1433 nValue += 5; 1434 nValue /= 10; 1435 nDecDigits--; 1436 } 1437 } 1438 1439 if ( eFieldUnit != eInUnit ) 1440 { 1441 sal_Int64 nDiv = aImplFactor[eInUnit][eFieldUnit]; 1442 sal_Int64 nMult = aImplFactor[eFieldUnit][eInUnit]; 1443 1444 DBG_ASSERT( nMult > 0, "illegal *" ); 1445 DBG_ASSERT( nDiv > 0, "illegal /" ); 1446 1447 if( nMult != 1 && nMult > 0 ) 1448 nValue *= nMult; 1449 if( nDiv != 1 && nDiv > 0 ) 1450 { 1451 nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2); 1452 nValue /= nDiv; 1453 } 1454 } 1455 return nValue; 1456 } 1457 1458 // ----------------------------------------------------------------------- 1459 1460 static sal_Bool ImplMetricGetValue( const XubString& rStr, double& rValue, sal_Int64 nBaseValue, 1461 sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrapper, FieldUnit eUnit ) 1462 { 1463 // Zahlenwert holen 1464 if ( !ImplNumericGetValue( rStr, rValue, nDecDigits, rLocaleDataWrapper ) ) 1465 return sal_False; 1466 1467 // Einheit rausfinden 1468 FieldUnit eEntryUnit = ImplMetricGetUnit( rStr ); 1469 1470 // Einheiten umrechnen 1471 rValue = MetricField::ConvertDoubleValue( rValue, nBaseValue, nDecDigits, eEntryUnit, eUnit ); 1472 1473 return sal_True; 1474 } 1475 1476 // ----------------------------------------------------------------------- 1477 1478 sal_Bool MetricFormatter::ImplMetricReformat( const XubString& rStr, double& rValue, XubString& rOutStr ) 1479 { 1480 if ( !ImplMetricGetValue( rStr, rValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) ) 1481 return sal_True; 1482 else 1483 { 1484 double nTempVal = rValue; 1485 // caution: precision loss in double cast 1486 if ( nTempVal > GetMax() ) 1487 nTempVal = (double)GetMax(); 1488 else if ( nTempVal < GetMin()) 1489 nTempVal = (double)GetMin(); 1490 1491 if ( GetErrorHdl().IsSet() && (rValue != nTempVal) ) 1492 { 1493 mnCorrectedValue = (sal_Int64)nTempVal; 1494 if ( !GetErrorHdl().Call( this ) ) 1495 { 1496 mnCorrectedValue = 0; 1497 return sal_False; 1498 } 1499 else 1500 mnCorrectedValue = 0; 1501 } 1502 1503 rOutStr = CreateFieldText( (sal_Int64)nTempVal ); 1504 return sal_True; 1505 } 1506 } 1507 1508 // ----------------------------------------------------------------------- 1509 1510 inline void MetricFormatter::ImplInit() 1511 { 1512 mnBaseValue = 0; 1513 meUnit = MetricField::GetDefaultUnit(); 1514 mnType = FORMAT_METRIC; 1515 } 1516 1517 // ----------------------------------------------------------------------- 1518 1519 MetricFormatter::MetricFormatter() 1520 { 1521 ImplInit(); 1522 } 1523 1524 // ----------------------------------------------------------------------- 1525 1526 void MetricFormatter::ImplLoadRes( const ResId& rResId ) 1527 { 1528 NumericFormatter::ImplLoadRes( rResId ); 1529 1530 ResMgr* pMgr = rResId.GetResMgr(); 1531 if( pMgr ) 1532 { 1533 sal_uLong nMask = pMgr->ReadLong(); 1534 1535 if ( METRICFORMATTER_UNIT & nMask ) 1536 meUnit = (FieldUnit)pMgr->ReadLong(); 1537 1538 if ( METRICFORMATTER_CUSTOMUNITTEXT & nMask ) 1539 maCustomUnitText = pMgr->ReadString(); 1540 } 1541 } 1542 1543 // ----------------------------------------------------------------------- 1544 1545 MetricFormatter::~MetricFormatter() 1546 { 1547 } 1548 1549 // ----------------------------------------------------------------------- 1550 1551 void MetricFormatter::SetUnit( FieldUnit eNewUnit ) 1552 { 1553 if ( eNewUnit == FUNIT_100TH_MM ) 1554 { 1555 SetDecimalDigits( GetDecimalDigits() + 2 ); 1556 meUnit = FUNIT_MM; 1557 } 1558 else 1559 meUnit = eNewUnit; 1560 ReformatAll(); 1561 } 1562 1563 // ----------------------------------------------------------------------- 1564 1565 void MetricFormatter::SetCustomUnitText( const XubString& rStr ) 1566 { 1567 maCustomUnitText = rStr; 1568 ReformatAll(); 1569 } 1570 1571 // ----------------------------------------------------------------------- 1572 1573 void MetricFormatter::SetValue( sal_Int64 nNewValue, FieldUnit eInUnit ) 1574 { 1575 SetUserValue( nNewValue, eInUnit ); 1576 mnFieldValue = mnLastValue; 1577 } 1578 1579 // ----------------------------------------------------------------------- 1580 1581 XubString MetricFormatter::CreateFieldText( sal_Int64 nValue ) const 1582 { 1583 XubString aStr = NumericFormatter::CreateFieldText( nValue ); 1584 1585 if( meUnit == FUNIT_CUSTOM ) 1586 aStr += maCustomUnitText; 1587 else 1588 { 1589 if ( meUnit != FUNIT_NONE && meUnit != FUNIT_PERCENT ) 1590 aStr += xub_Unicode( ' ' ); 1591 aStr += ImplMetricToString( meUnit ); 1592 } 1593 return aStr; 1594 } 1595 1596 // ----------------------------------------------------------------------- 1597 1598 void MetricFormatter::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit ) 1599 { 1600 // Umrechnen auf eingestellte Einheiten 1601 nNewValue = MetricField::ConvertValue( nNewValue, mnBaseValue, GetDecimalDigits(), eInUnit, meUnit ); 1602 NumericFormatter::SetUserValue( nNewValue ); 1603 } 1604 1605 // ----------------------------------------------------------------------- 1606 1607 sal_Int64 MetricFormatter::GetValue( FieldUnit eOutUnit ) const 1608 { 1609 if ( !GetField() ) 1610 return 0; 1611 1612 double nTempValue; 1613 // caution: precision loss in double cast 1614 if ( !ImplMetricGetValue( GetField()->GetText(), nTempValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) ) 1615 nTempValue = (double)mnLastValue; 1616 1617 // caution: precision loss in double cast 1618 if ( nTempValue > mnMax ) 1619 nTempValue = (double)mnMax; 1620 else if ( nTempValue < mnMin ) 1621 nTempValue = (double)mnMin; 1622 1623 // Umrechnen auf gewuenschte Einheiten 1624 return MetricField::ConvertValue( (sal_Int64)nTempValue, mnBaseValue, GetDecimalDigits(), meUnit, eOutUnit ); 1625 } 1626 1627 // ----------------------------------------------------------------------- 1628 1629 void MetricFormatter::SetValue( sal_Int64 nValue ) 1630 { 1631 // Implementation not inline, because it is a virtual Function 1632 SetValue( nValue, FUNIT_NONE ); 1633 } 1634 1635 // ----------------------------------------------------------------------- 1636 1637 sal_Int64 MetricFormatter::GetValue() const 1638 { 1639 // Implementation not inline, because it is a virtual Function 1640 return GetValue( FUNIT_NONE ); 1641 } 1642 1643 // ----------------------------------------------------------------------- 1644 1645 void MetricFormatter::SetMin( sal_Int64 nNewMin, FieldUnit eInUnit ) 1646 { 1647 // Umrechnen auf gewuenschte Einheiten 1648 NumericFormatter::SetMin( MetricField::ConvertValue( nNewMin, mnBaseValue, GetDecimalDigits(), 1649 eInUnit, meUnit ) ); 1650 } 1651 1652 // ----------------------------------------------------------------------- 1653 1654 sal_Int64 MetricFormatter::GetMin( FieldUnit eOutUnit ) const 1655 { 1656 // Umrechnen auf gewuenschte Einheiten 1657 return MetricField::ConvertValue( NumericFormatter::GetMin(), mnBaseValue, 1658 GetDecimalDigits(), meUnit, eOutUnit ); 1659 } 1660 1661 // ----------------------------------------------------------------------- 1662 1663 void MetricFormatter::SetMax( sal_Int64 nNewMax, FieldUnit eInUnit ) 1664 { 1665 // Umrechnen auf gewuenschte Einheiten 1666 NumericFormatter::SetMax( MetricField::ConvertValue( nNewMax, mnBaseValue, GetDecimalDigits(), 1667 eInUnit, meUnit ) ); 1668 } 1669 1670 // ----------------------------------------------------------------------- 1671 1672 sal_Int64 MetricFormatter::GetMax( FieldUnit eOutUnit ) const 1673 { 1674 // Umrechnen auf gewuenschte Einheiten 1675 return MetricField::ConvertValue( NumericFormatter::GetMax(), mnBaseValue, 1676 GetDecimalDigits(), meUnit, eOutUnit ); 1677 } 1678 1679 // ----------------------------------------------------------------------- 1680 1681 void MetricFormatter::SetBaseValue( sal_Int64 nNewBase, FieldUnit eInUnit ) 1682 { 1683 mnBaseValue = MetricField::ConvertValue( nNewBase, mnBaseValue, GetDecimalDigits(), 1684 eInUnit, meUnit ); 1685 } 1686 1687 // ----------------------------------------------------------------------- 1688 1689 sal_Int64 MetricFormatter::GetBaseValue( FieldUnit eOutUnit ) const 1690 { 1691 // Umrechnen auf gewuenschte Einheiten 1692 return MetricField::ConvertValue( mnBaseValue, mnBaseValue, GetDecimalDigits(), 1693 meUnit, eOutUnit ); 1694 } 1695 1696 // ----------------------------------------------------------------------- 1697 1698 void MetricFormatter::Reformat() 1699 { 1700 if ( !GetField() ) 1701 return; 1702 1703 XubString aText = GetField()->GetText(); 1704 if ( meUnit == FUNIT_CUSTOM ) 1705 maCurUnitText = ImplMetricGetUnitText( aText ); 1706 1707 XubString aStr; 1708 // caution: precision loss in double cast 1709 double nTemp = (double)mnLastValue; 1710 sal_Bool bOK = ImplMetricReformat( aText, nTemp, aStr ); 1711 mnLastValue = (sal_Int64)nTemp; 1712 1713 if ( !bOK ) 1714 return; 1715 1716 if ( aStr.Len() ) 1717 { 1718 ImplSetText( aStr ); 1719 if ( meUnit == FUNIT_CUSTOM ) 1720 CustomConvert(); 1721 } 1722 else 1723 SetValue( mnLastValue ); 1724 maCurUnitText.Erase(); 1725 } 1726 1727 // ----------------------------------------------------------------------- 1728 1729 sal_Int64 MetricFormatter::GetCorrectedValue( FieldUnit eOutUnit ) const 1730 { 1731 // Umrechnen auf gewuenschte Einheiten 1732 return MetricField::ConvertValue( mnCorrectedValue, mnBaseValue, GetDecimalDigits(), 1733 meUnit, eOutUnit ); 1734 } 1735 1736 // ----------------------------------------------------------------------- 1737 1738 MetricField::MetricField( Window* pParent, WinBits nWinStyle ) : 1739 SpinField( pParent, nWinStyle ) 1740 { 1741 SetField( this ); 1742 Reformat(); 1743 } 1744 1745 // ----------------------------------------------------------------------- 1746 1747 MetricField::MetricField( Window* pParent, const ResId& rResId ) : 1748 SpinField( WINDOW_METRICFIELD ) 1749 { 1750 rResId.SetRT( RSC_METRICFIELD ); 1751 WinBits nStyle = ImplInitRes( rResId ) ; 1752 SpinField::ImplInit( pParent, nStyle ); 1753 SetField( this ); 1754 ImplLoadRes( rResId ); 1755 1756 if ( !(nStyle & WB_HIDE ) ) 1757 Show(); 1758 } 1759 1760 // ----------------------------------------------------------------------- 1761 1762 void MetricField::ImplLoadRes( const ResId& rResId ) 1763 { 1764 SpinField::ImplLoadRes( rResId ); 1765 MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 1766 1767 sal_uLong nMask = ReadLongRes(); 1768 1769 if ( METRICFIELD_FIRST & nMask ) 1770 mnFirst = ReadLongRes(); 1771 1772 if ( METRICFIELD_LAST & nMask ) 1773 mnLast = ReadLongRes(); 1774 1775 if ( METRICFIELD_SPINSIZE & nMask ) 1776 mnSpinSize = ReadLongRes(); 1777 1778 Reformat(); 1779 } 1780 1781 // ----------------------------------------------------------------------- 1782 1783 MetricField::~MetricField() 1784 { 1785 } 1786 1787 // ----------------------------------------------------------------------- 1788 1789 void MetricField::SetFirst( sal_Int64 nNewFirst, FieldUnit eInUnit ) 1790 { 1791 // convert 1792 nNewFirst = MetricField::ConvertValue( nNewFirst, mnBaseValue, GetDecimalDigits(), 1793 eInUnit, meUnit ); 1794 mnFirst = nNewFirst; 1795 } 1796 1797 // ----------------------------------------------------------------------- 1798 1799 sal_Int64 MetricField::GetFirst( FieldUnit eOutUnit ) const 1800 { 1801 // convert 1802 return MetricField::ConvertValue( mnFirst, mnBaseValue, GetDecimalDigits(), 1803 meUnit, eOutUnit ); 1804 } 1805 1806 // ----------------------------------------------------------------------- 1807 1808 void MetricField::SetLast( sal_Int64 nNewLast, FieldUnit eInUnit ) 1809 { 1810 // Umrechnen 1811 nNewLast = MetricField::ConvertValue( nNewLast, mnBaseValue, GetDecimalDigits(), 1812 eInUnit, meUnit ); 1813 mnLast = nNewLast; 1814 } 1815 1816 // ----------------------------------------------------------------------- 1817 1818 sal_Int64 MetricField::GetLast( FieldUnit eOutUnit ) const 1819 { 1820 // Umrechnen 1821 return MetricField::ConvertValue( mnLast, mnBaseValue, GetDecimalDigits(), 1822 meUnit, eOutUnit ); 1823 } 1824 1825 // ----------------------------------------------------------------------- 1826 1827 long MetricField::PreNotify( NotifyEvent& rNEvt ) 1828 { 1829 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 1830 { 1831 if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 1832 return 1; 1833 } 1834 1835 return SpinField::PreNotify( rNEvt ); 1836 } 1837 1838 // ----------------------------------------------------------------------- 1839 1840 long MetricField::Notify( NotifyEvent& rNEvt ) 1841 { 1842 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 1843 MarkToBeReformatted( sal_False ); 1844 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 1845 { 1846 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 1847 Reformat(); 1848 } 1849 1850 return SpinField::Notify( rNEvt ); 1851 } 1852 1853 // ----------------------------------------------------------------------- 1854 1855 void MetricField::DataChanged( const DataChangedEvent& rDCEvt ) 1856 { 1857 SpinField::DataChanged( rDCEvt ); 1858 1859 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 1860 { 1861 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1862 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1863 if ( IsDefaultLocale() ) 1864 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 1865 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1866 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1867 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 1868 ReformatAll(); 1869 } 1870 } 1871 1872 // ----------------------------------------------------------------------- 1873 1874 void MetricField::Modify() 1875 { 1876 MarkToBeReformatted( sal_True ); 1877 SpinField::Modify(); 1878 } 1879 1880 // ----------------------------------------------------------------------- 1881 1882 void MetricField::Up() 1883 { 1884 FieldUp(); 1885 SpinField::Up(); 1886 } 1887 1888 // ----------------------------------------------------------------------- 1889 1890 void MetricField::Down() 1891 { 1892 FieldDown(); 1893 SpinField::Down(); 1894 } 1895 1896 // ----------------------------------------------------------------------- 1897 1898 void MetricField::First() 1899 { 1900 FieldFirst(); 1901 SpinField::First(); 1902 } 1903 1904 // ----------------------------------------------------------------------- 1905 1906 void MetricField::Last() 1907 { 1908 FieldLast(); 1909 SpinField::Last(); 1910 } 1911 1912 // ----------------------------------------------------------------------- 1913 1914 void MetricField::CustomConvert() 1915 { 1916 maCustomConvertLink.Call( this ); 1917 } 1918 1919 // ----------------------------------------------------------------------- 1920 1921 MetricBox::MetricBox( Window* pParent, WinBits nWinStyle ) : 1922 ComboBox( pParent, nWinStyle ) 1923 { 1924 SetField( this ); 1925 Reformat(); 1926 } 1927 1928 // ----------------------------------------------------------------------- 1929 1930 MetricBox::MetricBox( Window* pParent, const ResId& rResId ) : 1931 ComboBox( WINDOW_METRICBOX ) 1932 { 1933 rResId.SetRT( RSC_METRICBOX ); 1934 WinBits nStyle = ImplInitRes( rResId ); 1935 ComboBox::ImplInit( pParent, nStyle ); 1936 SetField( this ); 1937 Reformat(); 1938 ComboBox::ImplLoadRes( rResId ); 1939 MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 1940 1941 if ( !(nStyle & WB_HIDE ) ) 1942 Show(); 1943 } 1944 1945 // ----------------------------------------------------------------------- 1946 1947 MetricBox::~MetricBox() 1948 { 1949 } 1950 1951 // ----------------------------------------------------------------------- 1952 1953 long MetricBox::PreNotify( NotifyEvent& rNEvt ) 1954 { 1955 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 1956 { 1957 if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 1958 return 1; 1959 } 1960 1961 return ComboBox::PreNotify( rNEvt ); 1962 } 1963 1964 // ----------------------------------------------------------------------- 1965 1966 long MetricBox::Notify( NotifyEvent& rNEvt ) 1967 { 1968 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 1969 MarkToBeReformatted( sal_False ); 1970 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 1971 { 1972 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 1973 Reformat(); 1974 } 1975 1976 return ComboBox::Notify( rNEvt ); 1977 } 1978 1979 // ----------------------------------------------------------------------- 1980 1981 void MetricBox::DataChanged( const DataChangedEvent& rDCEvt ) 1982 { 1983 ComboBox::DataChanged( rDCEvt ); 1984 1985 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 1986 { 1987 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1988 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1989 if ( IsDefaultLocale() ) 1990 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 1991 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1992 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1993 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 1994 ReformatAll(); 1995 } 1996 } 1997 1998 // ----------------------------------------------------------------------- 1999 2000 void MetricBox::Modify() 2001 { 2002 MarkToBeReformatted( sal_True ); 2003 ComboBox::Modify(); 2004 } 2005 2006 // ----------------------------------------------------------------------- 2007 2008 void MetricBox::ReformatAll() 2009 { 2010 double nValue; 2011 XubString aStr; 2012 SetUpdateMode( sal_False ); 2013 sal_uInt16 nEntryCount = GetEntryCount(); 2014 for ( sal_uInt16 i=0; i < nEntryCount; i++ ) 2015 { 2016 ImplMetricReformat( GetEntry( i ), nValue, aStr ); 2017 RemoveEntry( i ); 2018 InsertEntry( aStr, i ); 2019 } 2020 MetricFormatter::Reformat(); 2021 SetUpdateMode( sal_True ); 2022 } 2023 2024 // ----------------------------------------------------------------------- 2025 2026 void MetricBox::CustomConvert() 2027 { 2028 maCustomConvertLink.Call( this ); 2029 } 2030 2031 // ----------------------------------------------------------------------- 2032 2033 void MetricBox::InsertValue( sal_Int64 nValue, FieldUnit eInUnit, sal_uInt16 nPos ) 2034 { 2035 // Umrechnen auf eingestellte Einheiten 2036 nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(), 2037 eInUnit, meUnit ); 2038 ComboBox::InsertEntry( CreateFieldText( nValue ), nPos ); 2039 } 2040 2041 // ----------------------------------------------------------------------- 2042 2043 void MetricBox::RemoveValue( sal_Int64 nValue, FieldUnit eInUnit ) 2044 { 2045 // Umrechnen auf eingestellte Einheiten 2046 nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(), 2047 eInUnit, meUnit ); 2048 ComboBox::RemoveEntry( CreateFieldText( nValue ) ); 2049 } 2050 2051 // ----------------------------------------------------------------------- 2052 2053 sal_Int64 MetricBox::GetValue( sal_uInt16 nPos, FieldUnit eOutUnit ) const 2054 { 2055 double nValue = 0; 2056 ImplMetricGetValue( ComboBox::GetEntry( nPos ), nValue, mnBaseValue, 2057 GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ); 2058 2059 // Umrechnen auf eingestellte Einheiten 2060 sal_Int64 nRetValue = MetricField::ConvertValue( (sal_Int64)nValue, mnBaseValue, GetDecimalDigits(), 2061 meUnit, eOutUnit ); 2062 2063 return nRetValue; 2064 } 2065 2066 // ----------------------------------------------------------------------- 2067 2068 sal_uInt16 MetricBox::GetValuePos( sal_Int64 nValue, FieldUnit eInUnit ) const 2069 { 2070 // Umrechnen auf eingestellte Einheiten 2071 nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(), 2072 eInUnit, meUnit ); 2073 return ComboBox::GetEntryPos( CreateFieldText( nValue ) ); 2074 } 2075 2076 // ----------------------------------------------------------------------- 2077 2078 sal_Int64 MetricBox::GetValue( FieldUnit eOutUnit ) const 2079 { 2080 // Implementation not inline, because it is a virtual Function 2081 return MetricFormatter::GetValue( eOutUnit ); 2082 } 2083 2084 // ----------------------------------------------------------------------- 2085 2086 sal_Int64 MetricBox::GetValue() const 2087 { 2088 // Implementation not inline, because it is a virtual Function 2089 return GetValue( FUNIT_NONE ); 2090 } 2091 2092 // ----------------------------------------------------------------------- 2093 2094 static sal_Bool ImplCurrencyProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt, 2095 sal_Bool, sal_Bool bUseThousandSep, const LocaleDataWrapper& rWrapper ) 2096 { 2097 // Es gibt hier kein sinnvolles StrictFormat, also alle 2098 // Zeichen erlauben 2099 return ImplNumericProcessKeyInput( pEdit, rKEvt, sal_False, bUseThousandSep, rWrapper ); 2100 } 2101 2102 // ----------------------------------------------------------------------- 2103 2104 inline sal_Bool ImplCurrencyGetValue( const XubString& rStr, double& rValue, 2105 sal_uInt16 nDecDigits, const LocaleDataWrapper& rWrapper ) 2106 { 2107 // Zahlenwert holen 2108 return ImplNumericGetValue( rStr, rValue, nDecDigits, rWrapper, sal_True ); 2109 } 2110 2111 // ----------------------------------------------------------------------- 2112 2113 sal_Bool CurrencyFormatter::ImplCurrencyReformat( const XubString& rStr, 2114 XubString& rOutStr ) 2115 { 2116 double nValue; 2117 if ( !ImplNumericGetValue( rStr, nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), sal_True ) ) 2118 return sal_True; 2119 else 2120 { 2121 double nTempVal = nValue; 2122 // caution: precision loss in double cast 2123 if ( nTempVal > GetMax() ) 2124 nTempVal = (double)GetMax(); 2125 else if ( nTempVal < GetMin()) 2126 nTempVal = (double)GetMin(); 2127 2128 if ( GetErrorHdl().IsSet() && (nValue != nTempVal) ) 2129 { 2130 mnCorrectedValue = (sal_Int64)nTempVal; 2131 if ( !GetErrorHdl().Call( this ) ) 2132 { 2133 mnCorrectedValue = 0; 2134 return sal_False; 2135 } 2136 else 2137 mnCorrectedValue = 0; 2138 } 2139 2140 rOutStr = CreateFieldText( (long)nTempVal ); 2141 return sal_True; 2142 } 2143 } 2144 2145 // ----------------------------------------------------------------------- 2146 2147 inline void CurrencyFormatter::ImplInit() 2148 { 2149 mnType = FORMAT_CURRENCY; 2150 } 2151 2152 // ----------------------------------------------------------------------- 2153 2154 CurrencyFormatter::CurrencyFormatter() 2155 { 2156 ImplInit(); 2157 } 2158 2159 // ----------------------------------------------------------------------- 2160 2161 CurrencyFormatter::~CurrencyFormatter() 2162 { 2163 } 2164 2165 // ----------------------------------------------------------------------- 2166 2167 void CurrencyFormatter::SetCurrencySymbol( const String& rStr ) 2168 { 2169 maCurrencySymbol= rStr; 2170 ReformatAll(); 2171 } 2172 2173 // ----------------------------------------------------------------------- 2174 2175 String CurrencyFormatter::GetCurrencySymbol() const 2176 { 2177 return maCurrencySymbol.Len() ? maCurrencySymbol : ImplGetLocaleDataWrapper().getCurrSymbol(); 2178 } 2179 2180 // ----------------------------------------------------------------------- 2181 2182 void CurrencyFormatter::SetValue( sal_Int64 nNewValue ) 2183 { 2184 SetUserValue( nNewValue ); 2185 mnFieldValue = mnLastValue; 2186 SetEmptyFieldValueData( sal_False ); 2187 } 2188 2189 // ----------------------------------------------------------------------- 2190 2191 XubString CurrencyFormatter::CreateFieldText( sal_Int64 nValue ) const 2192 { 2193 return ImplGetLocaleDataWrapper().getCurr( nValue, GetDecimalDigits(), GetCurrencySymbol(), IsUseThousandSep() ); 2194 } 2195 2196 // ----------------------------------------------------------------------- 2197 2198 sal_Int64 CurrencyFormatter::GetValue() const 2199 { 2200 if ( !GetField() ) 2201 return 0; 2202 2203 double nTempValue; 2204 if ( ImplCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) ) 2205 { 2206 // caution: precision loss in double cast 2207 if ( nTempValue > mnMax ) 2208 nTempValue = (double)mnMax; 2209 else if ( nTempValue < mnMin ) 2210 nTempValue = (double)mnMin; 2211 return (sal_Int64)nTempValue; 2212 } 2213 else 2214 return mnLastValue; 2215 } 2216 2217 // ----------------------------------------------------------------------- 2218 2219 void CurrencyFormatter::Reformat() 2220 { 2221 if ( !GetField() ) 2222 return; 2223 2224 XubString aStr; 2225 sal_Bool bOK = ImplCurrencyReformat( GetField()->GetText(), aStr ); 2226 if ( !bOK ) 2227 return; 2228 2229 if ( aStr.Len() ) 2230 { 2231 ImplSetText( aStr ); 2232 // caution: precision loss in double cast 2233 double nTemp = (double)mnLastValue; 2234 ImplCurrencyGetValue( aStr, nTemp, GetDecimalDigits(), ImplGetLocaleDataWrapper() ); 2235 mnLastValue = (sal_Int64)nTemp; 2236 } 2237 else 2238 SetValue( mnLastValue ); 2239 } 2240 2241 // ----------------------------------------------------------------------- 2242 2243 CurrencyField::CurrencyField( Window* pParent, WinBits nWinStyle ) : 2244 SpinField( pParent, nWinStyle ) 2245 { 2246 SetField( this ); 2247 Reformat(); 2248 } 2249 2250 // ----------------------------------------------------------------------- 2251 2252 CurrencyField::CurrencyField( Window* pParent, const ResId& rResId ) : 2253 SpinField( WINDOW_CURRENCYFIELD ) 2254 { 2255 rResId.SetRT( RSC_CURRENCYFIELD ); 2256 WinBits nStyle = ImplInitRes( rResId ); 2257 SpinField::ImplInit( pParent, nStyle); 2258 SetField( this ); 2259 ImplLoadRes( rResId ); 2260 2261 if ( !(nStyle & WB_HIDE ) ) 2262 Show(); 2263 } 2264 2265 // ----------------------------------------------------------------------- 2266 2267 void CurrencyField::ImplLoadRes( const ResId& rResId ) 2268 { 2269 SpinField::ImplLoadRes( rResId ); 2270 CurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 2271 2272 sal_uLong nMask = ReadLongRes(); 2273 2274 if ( CURRENCYFIELD_FIRST & nMask ) 2275 mnFirst = ReadLongRes(); 2276 2277 if ( CURRENCYFIELD_LAST & nMask ) 2278 mnLast = ReadLongRes(); 2279 2280 if ( CURRENCYFIELD_SPINSIZE & nMask ) 2281 mnSpinSize = ReadLongRes(); 2282 2283 Reformat(); 2284 } 2285 2286 // ----------------------------------------------------------------------- 2287 2288 CurrencyField::~CurrencyField() 2289 { 2290 } 2291 2292 // ----------------------------------------------------------------------- 2293 2294 long CurrencyField::PreNotify( NotifyEvent& rNEvt ) 2295 { 2296 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 2297 { 2298 if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 2299 return 1; 2300 } 2301 2302 return SpinField::PreNotify( rNEvt ); 2303 } 2304 2305 // ----------------------------------------------------------------------- 2306 2307 long CurrencyField::Notify( NotifyEvent& rNEvt ) 2308 { 2309 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 2310 MarkToBeReformatted( sal_False ); 2311 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 2312 { 2313 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 2314 Reformat(); 2315 } 2316 2317 return SpinField::Notify( rNEvt ); 2318 } 2319 2320 // ----------------------------------------------------------------------- 2321 2322 void CurrencyField::DataChanged( const DataChangedEvent& rDCEvt ) 2323 { 2324 SpinField::DataChanged( rDCEvt ); 2325 2326 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 2327 { 2328 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 2329 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 2330 if ( IsDefaultLocale() ) 2331 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 2332 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 2333 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 2334 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 2335 ReformatAll(); 2336 } 2337 } 2338 2339 // ----------------------------------------------------------------------- 2340 2341 void CurrencyField::Modify() 2342 { 2343 MarkToBeReformatted( sal_True ); 2344 SpinField::Modify(); 2345 } 2346 2347 // ----------------------------------------------------------------------- 2348 2349 void CurrencyField::Up() 2350 { 2351 FieldUp(); 2352 SpinField::Up(); 2353 } 2354 2355 // ----------------------------------------------------------------------- 2356 2357 void CurrencyField::Down() 2358 { 2359 FieldDown(); 2360 SpinField::Down(); 2361 } 2362 2363 // ----------------------------------------------------------------------- 2364 2365 void CurrencyField::First() 2366 { 2367 FieldFirst(); 2368 SpinField::First(); 2369 } 2370 2371 // ----------------------------------------------------------------------- 2372 2373 void CurrencyField::Last() 2374 { 2375 FieldLast(); 2376 SpinField::Last(); 2377 } 2378 2379 // ----------------------------------------------------------------------- 2380 2381 CurrencyBox::CurrencyBox( Window* pParent, WinBits nWinStyle ) : 2382 ComboBox( pParent, nWinStyle ) 2383 { 2384 SetField( this ); 2385 Reformat(); 2386 } 2387 2388 // ----------------------------------------------------------------------- 2389 2390 CurrencyBox::CurrencyBox( Window* pParent, const ResId& rResId ) : 2391 ComboBox( WINDOW_CURRENCYBOX ) 2392 { 2393 rResId.SetRT( RSC_CURRENCYBOX ); 2394 WinBits nStyle = ImplInitRes( rResId ); 2395 ComboBox::ImplInit( pParent, nStyle ); 2396 CurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 2397 SetField( this ); 2398 ComboBox::ImplLoadRes( rResId ); 2399 Reformat(); 2400 2401 if ( !(nStyle & WB_HIDE ) ) 2402 Show(); 2403 } 2404 2405 // ----------------------------------------------------------------------- 2406 2407 CurrencyBox::~CurrencyBox() 2408 { 2409 } 2410 2411 // ----------------------------------------------------------------------- 2412 2413 long CurrencyBox::PreNotify( NotifyEvent& rNEvt ) 2414 { 2415 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 2416 { 2417 if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 2418 return 1; 2419 } 2420 2421 return ComboBox::PreNotify( rNEvt ); 2422 } 2423 2424 // ----------------------------------------------------------------------- 2425 2426 long CurrencyBox::Notify( NotifyEvent& rNEvt ) 2427 { 2428 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 2429 MarkToBeReformatted( sal_False ); 2430 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 2431 { 2432 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 2433 Reformat(); 2434 } 2435 2436 return ComboBox::Notify( rNEvt ); 2437 } 2438 2439 // ----------------------------------------------------------------------- 2440 2441 void CurrencyBox::DataChanged( const DataChangedEvent& rDCEvt ) 2442 { 2443 ComboBox::DataChanged( rDCEvt ); 2444 2445 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 2446 { 2447 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 2448 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 2449 if ( IsDefaultLocale() ) 2450 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 2451 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 2452 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 2453 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 2454 ReformatAll(); 2455 } 2456 } 2457 2458 // ----------------------------------------------------------------------- 2459 2460 void CurrencyBox::Modify() 2461 { 2462 MarkToBeReformatted( sal_True ); 2463 ComboBox::Modify(); 2464 } 2465 2466 // ----------------------------------------------------------------------- 2467 2468 void CurrencyBox::ReformatAll() 2469 { 2470 XubString aStr; 2471 SetUpdateMode( sal_False ); 2472 sal_uInt16 nEntryCount = GetEntryCount(); 2473 for ( sal_uInt16 i=0; i < nEntryCount; i++ ) 2474 { 2475 ImplCurrencyReformat( GetEntry( i ), aStr ); 2476 RemoveEntry( i ); 2477 InsertEntry( aStr, i ); 2478 } 2479 CurrencyFormatter::Reformat(); 2480 SetUpdateMode( sal_True ); 2481 } 2482 2483 // ----------------------------------------------------------------------- 2484 2485 void CurrencyBox::InsertValue( sal_Int64 nValue, sal_uInt16 nPos ) 2486 { 2487 ComboBox::InsertEntry( CreateFieldText( nValue ), nPos ); 2488 } 2489 2490 // ----------------------------------------------------------------------- 2491 2492 void CurrencyBox::RemoveValue( sal_Int64 nValue ) 2493 { 2494 ComboBox::RemoveEntry( CreateFieldText( nValue ) ); 2495 } 2496 2497 // ----------------------------------------------------------------------- 2498 2499 sal_Int64 CurrencyBox::GetValue( sal_uInt16 nPos ) const 2500 { 2501 double nValue = 0; 2502 ImplCurrencyGetValue( ComboBox::GetEntry( nPos ), nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ); 2503 return (sal_Int64)nValue; 2504 } 2505 2506 // ----------------------------------------------------------------------- 2507 2508 sal_uInt16 CurrencyBox::GetValuePos( sal_Int64 nValue ) const 2509 { 2510 return ComboBox::GetEntryPos( CreateFieldText( nValue ) ); 2511 } 2512 2513 // ----------------------------------------------------------------------- 2514 2515 sal_Int64 CurrencyBox::GetValue() const 2516 { 2517 // Implementation not inline, because it is a virtual Function 2518 return CurrencyFormatter::GetValue(); 2519 } 2520