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 mnCorrectedValue = 0; 481 mnDecimalDigits = 2; 482 mnType = FORMAT_NUMERIC; 483 mbThousandSep = sal_True; 484 mbShowTrailingZeros = sal_True; 485 486 // for fields 487 mnSpinSize = 1; 488 mnFirst = mnMin; 489 mnLast = mnMax; 490 491 SetDecimalDigits( 0 ); 492 } 493 494 // ----------------------------------------------------------------------- 495 496 NumericFormatter::NumericFormatter() 497 { 498 ImplInit(); 499 } 500 501 // ----------------------------------------------------------------------- 502 503 void NumericFormatter::ImplLoadRes( const ResId& rResId ) 504 { 505 ResMgr* pMgr = rResId.GetResMgr(); 506 507 if( pMgr ) 508 { 509 sal_uLong nMask = pMgr->ReadLong(); 510 511 if ( NUMERICFORMATTER_MIN & nMask ) 512 mnMin = pMgr->ReadLong(); 513 514 if ( NUMERICFORMATTER_MAX & nMask ) 515 mnMax = pMgr->ReadLong(); 516 517 if ( NUMERICFORMATTER_STRICTFORMAT & nMask ) 518 SetStrictFormat( (sal_Bool)pMgr->ReadShort() ); 519 520 if ( NUMERICFORMATTER_DECIMALDIGITS & nMask ) 521 SetDecimalDigits( pMgr->ReadShort() ); 522 523 if ( NUMERICFORMATTER_VALUE & nMask ) 524 { 525 mnFieldValue = pMgr->ReadLong(); 526 if ( mnFieldValue > mnMax ) 527 mnFieldValue = mnMax; 528 else if ( mnFieldValue < mnMin ) 529 mnFieldValue = mnMin; 530 mnLastValue = mnFieldValue; 531 } 532 533 if ( NUMERICFORMATTER_NOTHOUSANDSEP & nMask ) 534 SetUseThousandSep( !(sal_Bool)pMgr->ReadShort() ); 535 } 536 } 537 538 // ----------------------------------------------------------------------- 539 540 NumericFormatter::~NumericFormatter() 541 { 542 } 543 544 // ----------------------------------------------------------------------- 545 546 void NumericFormatter::SetMin( sal_Int64 nNewMin ) 547 { 548 mnMin = nNewMin; 549 if ( !IsEmptyFieldValue() ) 550 ReformatAll(); 551 } 552 553 // ----------------------------------------------------------------------- 554 555 void NumericFormatter::SetMax( sal_Int64 nNewMax ) 556 { 557 mnMax = nNewMax; 558 if ( !IsEmptyFieldValue() ) 559 ReformatAll(); 560 } 561 562 // ----------------------------------------------------------------------- 563 564 void NumericFormatter::SetUseThousandSep( sal_Bool b ) 565 { 566 mbThousandSep = b; 567 ReformatAll(); 568 } 569 570 // ----------------------------------------------------------------------- 571 572 void NumericFormatter::SetDecimalDigits( sal_uInt16 nDigits ) 573 { 574 mnDecimalDigits = nDigits; 575 ReformatAll(); 576 } 577 578 // ----------------------------------------------------------------------- 579 580 void NumericFormatter::SetShowTrailingZeros( sal_Bool bShowTrailingZeros ) 581 { 582 if ( mbShowTrailingZeros != bShowTrailingZeros ) 583 { 584 mbShowTrailingZeros = bShowTrailingZeros; 585 ReformatAll(); 586 } 587 } 588 589 // ----------------------------------------------------------------------- 590 591 sal_uInt16 NumericFormatter::GetDecimalDigits() const 592 { 593 return mnDecimalDigits; 594 } 595 596 // ----------------------------------------------------------------------- 597 598 void NumericFormatter::SetValue( sal_Int64 nNewValue ) 599 { 600 SetUserValue( nNewValue ); 601 mnFieldValue = mnLastValue; 602 SetEmptyFieldValueData( sal_False ); 603 } 604 605 // ----------------------------------------------------------------------- 606 607 XubString NumericFormatter::CreateFieldText( sal_Int64 nValue ) const 608 { 609 return ImplGetLocaleDataWrapper().getNum( nValue, GetDecimalDigits(), IsUseThousandSep(), IsShowTrailingZeros() ); 610 } 611 612 // ----------------------------------------------------------------------- 613 614 void NumericFormatter::ImplSetUserValue( sal_Int64 nNewValue, Selection* pNewSelection ) 615 { 616 if ( nNewValue > mnMax ) 617 nNewValue = mnMax; 618 else if ( nNewValue < mnMin ) 619 nNewValue = mnMin; 620 mnLastValue = nNewValue; 621 622 if ( GetField() ) 623 ImplSetText( CreateFieldText( nNewValue ), pNewSelection ); 624 } 625 626 // ----------------------------------------------------------------------- 627 628 void NumericFormatter::SetUserValue( sal_Int64 nNewValue ) 629 { 630 ImplSetUserValue( nNewValue ); 631 } 632 633 // ----------------------------------------------------------------------- 634 635 sal_Int64 NumericFormatter::GetValue() const 636 { 637 if ( !GetField() ) 638 return 0; 639 640 double nTempValue; 641 642 if ( ImplNumericGetValue( GetField()->GetText(), nTempValue, 643 GetDecimalDigits(), ImplGetLocaleDataWrapper() ) ) 644 { 645 // caution: precision loss in double cast 646 if ( nTempValue > mnMax ) 647 nTempValue = (double)mnMax; 648 else if ( nTempValue < mnMin ) 649 nTempValue = (double)mnMin; 650 return (sal_Int64)nTempValue; 651 } 652 else 653 return mnLastValue; 654 } 655 656 // ----------------------------------------------------------------------- 657 658 sal_Bool NumericFormatter::IsValueModified() const 659 { 660 if ( ImplGetEmptyFieldValue() ) 661 return !IsEmptyFieldValue(); 662 else if ( GetValue() != mnFieldValue ) 663 return sal_True; 664 else 665 return sal_False; 666 } 667 668 // ----------------------------------------------------------------------- 669 670 Fraction NumericFormatter::ConvertToFraction( sal_Int64 nValue ) 671 { 672 // caution: precision loss in double cast (and in fraction anyhow) 673 return Fraction( (double)nValue/(double)ImplPower10( GetDecimalDigits() ) ); 674 } 675 676 // ----------------------------------------------------------------------- 677 678 sal_Int64 NumericFormatter::ConvertToLong( const Fraction& rValue ) 679 { 680 Fraction aFract = rValue; 681 aFract *= Fraction( (long)ImplPower10( GetDecimalDigits() ), 1 ); 682 return (sal_Int64)(double)aFract; 683 } 684 685 // ----------------------------------------------------------------------- 686 687 sal_Int64 NumericFormatter::Normalize( sal_Int64 nValue ) const 688 { 689 return (nValue * ImplPower10( GetDecimalDigits() ) ); 690 } 691 692 // ----------------------------------------------------------------------- 693 694 sal_Int64 NumericFormatter::Denormalize( sal_Int64 nValue ) const 695 { 696 sal_Int64 nFactor = ImplPower10( GetDecimalDigits() ); 697 698 if((nValue < ( SAL_MIN_INT64 + nFactor )) || 699 (nValue > ( SAL_MAX_INT64 - nFactor ))) 700 return ( nValue / nFactor ); 701 if( nValue < 0 ) 702 return ((nValue-(nFactor/2)) / nFactor ); 703 else 704 return ((nValue+(nFactor/2)) / nFactor ); 705 } 706 707 // ----------------------------------------------------------------------- 708 709 void NumericFormatter::Reformat() 710 { 711 if ( !GetField() ) 712 return; 713 714 if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() ) 715 return; 716 717 XubString aStr; 718 // caution: precision loss in double cast 719 double nTemp = (double)mnLastValue; 720 sal_Bool bOK = ImplNumericReformat( GetField()->GetText(), nTemp, aStr ); 721 mnLastValue = (sal_Int64)nTemp; 722 if ( !bOK ) 723 return; 724 725 if ( aStr.Len() ) 726 ImplSetText( aStr ); 727 else 728 SetValue( mnLastValue ); 729 } 730 731 // ----------------------------------------------------------------------- 732 733 void NumericFormatter::FieldUp() 734 { 735 sal_Int64 nValue = GetValue(); 736 nValue += mnSpinSize; 737 if ( nValue > mnMax ) 738 nValue = mnMax; 739 740 ImplNewFieldValue( nValue ); 741 } 742 743 // ----------------------------------------------------------------------- 744 745 void NumericFormatter::FieldDown() 746 { 747 sal_Int64 nValue = GetValue(); 748 nValue -= mnSpinSize; 749 if ( nValue < mnMin ) 750 nValue = mnMin; 751 752 ImplNewFieldValue( nValue ); 753 } 754 755 // ----------------------------------------------------------------------- 756 757 void NumericFormatter::FieldFirst() 758 { 759 ImplNewFieldValue( mnFirst ); 760 } 761 762 // ----------------------------------------------------------------------- 763 764 void NumericFormatter::FieldLast() 765 { 766 ImplNewFieldValue( mnLast ); 767 } 768 769 // ----------------------------------------------------------------------- 770 771 void NumericFormatter::ImplNewFieldValue( sal_Int64 nNewValue ) 772 { 773 if ( GetField() ) 774 { 775 // !!! TH-18.2.99: Wenn wir Zeit haben sollte mal geklaert werden, 776 // !!! warum nicht bei ImplSetUserValue() geprueft wird, ob 777 // !!! sich der Wert aendert. Denn auch hier muesste dieses 778 // !!! gemacht werden, da ansonsten der Modify-Aufruf 779 // !!! nicht gemacht werden duerfte. Jedenfalls sollten die 780 // !!! Wege von ImplNewFieldValue, ImplSetUserValue und 781 // !!! ImplSetText ueberprueft und klarer gestalltet (mit Kommentar) 782 // !!! werden, damit wir mal wissen, was dort ablaeuft!!! 783 784 Selection aSelection = GetField()->GetSelection(); 785 aSelection.Justify(); 786 XubString aText = GetField()->GetText(); 787 // Wenn bis ans Ende selektiert war, soll das auch so bleiben... 788 if ( (xub_StrLen)aSelection.Max() == aText.Len() ) 789 { 790 if ( !aSelection.Len() ) 791 aSelection.Min() = SELECTION_MAX; 792 aSelection.Max() = SELECTION_MAX; 793 } 794 795 sal_Int64 nOldLastValue = mnLastValue; 796 ImplSetUserValue( nNewValue, &aSelection ); 797 mnLastValue = nOldLastValue; 798 799 // Modify am Edit wird nur bei KeyInput gesetzt... 800 if ( GetField()->GetText() != aText ) 801 { 802 GetField()->SetModifyFlag(); 803 GetField()->Modify(); 804 } 805 } 806 } 807 808 // ----------------------------------------------------------------------- 809 810 NumericField::NumericField( Window* pParent, WinBits nWinStyle ) : 811 SpinField( pParent, nWinStyle ) 812 { 813 SetField( this ); 814 Reformat(); 815 } 816 817 // ----------------------------------------------------------------------- 818 819 NumericField::NumericField( Window* pParent, const ResId& rResId ) : 820 SpinField( WINDOW_NUMERICFIELD ) 821 { 822 rResId.SetRT( RSC_NUMERICFIELD ); 823 WinBits nStyle = ImplInitRes( rResId ) ; 824 SpinField::ImplInit( pParent, nStyle ); 825 SetField( this ); 826 ImplLoadRes( rResId ); 827 Reformat(); 828 829 if ( !(nStyle & WB_HIDE ) ) 830 Show(); 831 } 832 833 // ----------------------------------------------------------------------- 834 835 void NumericField::ImplLoadRes( const ResId& rResId ) 836 { 837 SpinField::ImplLoadRes( rResId ); 838 NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 839 840 sal_uLong nMask = ReadLongRes(); 841 842 if ( NUMERICFIELD_FIRST & nMask ) 843 mnFirst = ReadLongRes(); 844 845 if ( NUMERICFIELD_LAST & nMask ) 846 mnLast = ReadLongRes(); 847 848 if ( NUMERICFIELD_SPINSIZE & nMask ) 849 mnSpinSize = ReadLongRes(); 850 } 851 852 // ----------------------------------------------------------------------- 853 854 NumericField::~NumericField() 855 { 856 } 857 858 // ----------------------------------------------------------------------- 859 860 long NumericField::PreNotify( NotifyEvent& rNEvt ) 861 { 862 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 863 { 864 if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 865 return 1; 866 } 867 868 return SpinField::PreNotify( rNEvt ); 869 } 870 871 // ----------------------------------------------------------------------- 872 873 long NumericField::Notify( NotifyEvent& rNEvt ) 874 { 875 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 876 MarkToBeReformatted( sal_False ); 877 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 878 { 879 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 880 Reformat(); 881 } 882 883 return SpinField::Notify( rNEvt ); 884 } 885 886 // ----------------------------------------------------------------------- 887 888 void NumericField::DataChanged( const DataChangedEvent& rDCEvt ) 889 { 890 SpinField::DataChanged( rDCEvt ); 891 892 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 893 { 894 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 895 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 896 if ( IsDefaultLocale() ) 897 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 898 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 899 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 900 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 901 ReformatAll(); 902 } 903 } 904 905 // ----------------------------------------------------------------------- 906 907 void NumericField::Modify() 908 { 909 MarkToBeReformatted( sal_True ); 910 SpinField::Modify(); 911 } 912 913 // ----------------------------------------------------------------------- 914 915 void NumericField::Up() 916 { 917 FieldUp(); 918 SpinField::Up(); 919 } 920 921 // ----------------------------------------------------------------------- 922 923 void NumericField::Down() 924 { 925 FieldDown(); 926 SpinField::Down(); 927 } 928 929 // ----------------------------------------------------------------------- 930 931 void NumericField::First() 932 { 933 FieldFirst(); 934 SpinField::First(); 935 } 936 937 // ----------------------------------------------------------------------- 938 939 void NumericField::Last() 940 { 941 FieldLast(); 942 SpinField::Last(); 943 } 944 945 // ----------------------------------------------------------------------- 946 947 NumericBox::NumericBox( Window* pParent, WinBits nWinStyle ) : 948 ComboBox( pParent, nWinStyle ) 949 { 950 SetField( this ); 951 Reformat(); 952 } 953 954 // ----------------------------------------------------------------------- 955 956 NumericBox::NumericBox( Window* pParent, const ResId& rResId ) : 957 ComboBox( WINDOW_NUMERICBOX ) 958 { 959 rResId.SetRT( RSC_NUMERICBOX ); 960 WinBits nStyle = ImplInitRes( rResId ); 961 ComboBox::ImplInit( pParent, nStyle ); 962 SetField( this ); 963 ComboBox::ImplLoadRes( rResId ); 964 NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 965 Reformat(); 966 967 if ( !(nStyle & WB_HIDE ) ) 968 Show(); 969 } 970 971 // ----------------------------------------------------------------------- 972 973 NumericBox::~NumericBox() 974 { 975 } 976 977 // ----------------------------------------------------------------------- 978 979 long NumericBox::PreNotify( NotifyEvent& rNEvt ) 980 { 981 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 982 { 983 if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 984 return 1; 985 } 986 987 return ComboBox::PreNotify( rNEvt ); 988 } 989 990 // ----------------------------------------------------------------------- 991 992 long NumericBox::Notify( NotifyEvent& rNEvt ) 993 { 994 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 995 MarkToBeReformatted( sal_False ); 996 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 997 { 998 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 999 Reformat(); 1000 } 1001 1002 return ComboBox::Notify( rNEvt ); 1003 } 1004 1005 // ----------------------------------------------------------------------- 1006 1007 void NumericBox::DataChanged( const DataChangedEvent& rDCEvt ) 1008 { 1009 ComboBox::DataChanged( rDCEvt ); 1010 1011 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 1012 { 1013 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1014 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1015 if ( IsDefaultLocale() ) 1016 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 1017 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1018 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1019 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 1020 ReformatAll(); 1021 } 1022 } 1023 1024 // ----------------------------------------------------------------------- 1025 1026 void NumericBox::Modify() 1027 { 1028 MarkToBeReformatted( sal_True ); 1029 ComboBox::Modify(); 1030 } 1031 1032 // ----------------------------------------------------------------------- 1033 1034 void NumericBox::ReformatAll() 1035 { 1036 double nValue; 1037 XubString aStr; 1038 SetUpdateMode( sal_False ); 1039 sal_uInt16 nEntryCount = GetEntryCount(); 1040 for ( sal_uInt16 i=0; i < nEntryCount; i++ ) 1041 { 1042 ImplNumericReformat( GetEntry( i ), nValue, aStr ); 1043 RemoveEntry( i ); 1044 InsertEntry( aStr, i ); 1045 } 1046 NumericFormatter::Reformat(); 1047 SetUpdateMode( sal_True ); 1048 } 1049 1050 // ----------------------------------------------------------------------- 1051 1052 void NumericBox::InsertValue( sal_Int64 nValue, sal_uInt16 nPos ) 1053 { 1054 ComboBox::InsertEntry( CreateFieldText( nValue ), nPos ); 1055 } 1056 1057 // ----------------------------------------------------------------------- 1058 1059 void NumericBox::RemoveValue( sal_Int64 nValue ) 1060 { 1061 ComboBox::RemoveEntry( CreateFieldText( nValue ) ); 1062 } 1063 1064 // ----------------------------------------------------------------------- 1065 1066 sal_Int64 NumericBox::GetValue( sal_uInt16 nPos ) const 1067 { 1068 double nValue = 0; 1069 ImplNumericGetValue( ComboBox::GetEntry( nPos ), nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ); 1070 return (sal_Int64)nValue; 1071 } 1072 1073 // ----------------------------------------------------------------------- 1074 1075 sal_uInt16 NumericBox::GetValuePos( sal_Int64 nValue ) const 1076 { 1077 return ComboBox::GetEntryPos( CreateFieldText( nValue ) ); 1078 } 1079 1080 // ----------------------------------------------------------------------- 1081 1082 static sal_Bool ImplMetricProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt, 1083 sal_Bool, sal_Bool bUseThousandSep, const LocaleDataWrapper& rWrapper ) 1084 { 1085 // Es gibt hier kein sinnvolles StrictFormat, also alle 1086 // Zeichen erlauben 1087 return ImplNumericProcessKeyInput( pEdit, rKEvt, sal_False, bUseThousandSep, rWrapper ); 1088 } 1089 1090 // ----------------------------------------------------------------------- 1091 1092 static XubString ImplMetricGetUnitText( const XubString& rStr ) 1093 { 1094 // Einheitentext holen 1095 XubString aStr; 1096 for ( short i = rStr.Len()-1; i >= 0; i-- ) 1097 { 1098 xub_Unicode c = rStr.GetChar( i ); 1099 if ( unicode::isAlpha( c ) || 1100 (c == '\'') || (c == '\"') || (c == '%' ) ) 1101 aStr.Insert( c, 0 ); 1102 else 1103 { 1104 if ( aStr.Len() ) 1105 break; 1106 } 1107 } 1108 return aStr; 1109 1110 /* 1111 // MT: #90545# Preparation for translated strings... 1112 String aMetricText; 1113 for ( sal_uInt16 n = rStr.Len(); n; ) 1114 { 1115 sal_Unicode c = rStr.GetChar( --n ); 1116 sal_Int32 nType = xCharClass->getStringType( rStr, n, 1, rLocale ); 1117 1118 if ( CharClass::isLetterType( nType ) ) 1119 { 1120 aMetricText.Insert( c, 0 ); 1121 } 1122 else 1123 { 1124 if ( aMetricText.Len() ) 1125 break; 1126 } 1127 } 1128 */ 1129 } 1130 1131 // ----------------------------------------------------------------------- 1132 1133 // #104355# support localized mesaurements 1134 1135 static const String& ImplMetricToString( FieldUnit rUnit ) 1136 { 1137 FieldUnitStringList* pList = ImplGetFieldUnits(); 1138 if( pList ) 1139 { 1140 // return unit's default string (ie, the first one ) 1141 for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it ) 1142 { 1143 if ( it->second == rUnit ) 1144 return it->first; 1145 } 1146 } 1147 1148 return String::EmptyString(); 1149 } 1150 1151 static FieldUnit ImplStringToMetric( const String &rMetricString ) 1152 { 1153 FieldUnitStringList* pList = ImplGetCleanedFieldUnits(); 1154 if( pList ) 1155 { 1156 // return FieldUnit 1157 String aStr( rMetricString ); 1158 aStr.ToLowerAscii(); 1159 aStr.EraseAllChars( sal_Unicode( ' ' ) ); 1160 for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it ) 1161 { 1162 if ( it->first.Equals( aStr ) ) 1163 return it->second; 1164 } 1165 } 1166 1167 return FUNIT_NONE; 1168 } 1169 1170 // ----------------------------------------------------------------------- 1171 1172 static FieldUnit ImplMetricGetUnit( const XubString& rStr ) 1173 { 1174 XubString aStr = ImplMetricGetUnitText( rStr ); 1175 return ImplStringToMetric( aStr ); 1176 } 1177 1178 #define K *1000L 1179 #define M *1000000L 1180 #define X *5280L 1181 1182 static const sal_Int64 aImplFactor[FUNIT_MILE+1][FUNIT_MILE+1] = 1183 { /* 1184 mm/100 mm cm m km twip point pica inch foot mile */ 1185 { 1, 100, 1 K, 100 K, 100 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X }, 1186 { 1, 1, 10, 1 K, 1 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X }, 1187 { 1, 1, 1, 100, 100 K, 254, 254, 254, 254, 254*12, 254*12 X }, 1188 { 1, 1, 1, 1, 1 K, 254, 254, 254, 254, 254*12, 254*12 X }, 1189 { 1, 1, 1, 1, 1, 0, 254, 254, 254, 254*12, 254*12 X }, 1190 { 1440,144 K,144 K,14400 K, 0, 1, 20, 240, 1440,1440*12,1440*12 X }, 1191 { 72, 7200, 7200, 720 K, 720 M, 1, 1, 12, 72, 72*12, 72*12 X }, 1192 { 6, 600, 600, 60 K, 60 M, 1, 1, 1, 6, 6*12, 6*12 X }, 1193 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 12, 12 X }, 1194 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 X }, 1195 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 } 1196 }; 1197 1198 #undef X 1199 #undef M 1200 #undef K 1201 // twip in km 254/14400 M 1202 1203 static FieldUnit eDefaultUnit = FUNIT_NONE; 1204 1205 FieldUnit MetricField::GetDefaultUnit() { return eDefaultUnit; } 1206 void MetricField::SetDefaultUnit( FieldUnit meUnit ) { eDefaultUnit = meUnit; } 1207 1208 static FieldUnit ImplMap2FieldUnit( MapUnit meUnit, long& nDecDigits ) 1209 { 1210 switch( meUnit ) 1211 { 1212 case MAP_100TH_MM : 1213 nDecDigits -= 2; 1214 return FUNIT_MM; 1215 case MAP_10TH_MM : 1216 nDecDigits -= 1; 1217 return FUNIT_MM; 1218 case MAP_MM : 1219 return FUNIT_MM; 1220 case MAP_CM : 1221 return FUNIT_CM; 1222 case MAP_1000TH_INCH : 1223 nDecDigits -= 3; 1224 return FUNIT_INCH; 1225 case MAP_100TH_INCH : 1226 nDecDigits -= 2; 1227 return FUNIT_INCH; 1228 case MAP_10TH_INCH : 1229 nDecDigits -= 1; 1230 return FUNIT_INCH; 1231 case MAP_INCH : 1232 return FUNIT_INCH; 1233 case MAP_POINT : 1234 return FUNIT_POINT; 1235 case MAP_TWIP : 1236 return FUNIT_TWIP; 1237 default: 1238 DBG_ERROR( "default eInUnit" ); 1239 break; 1240 } 1241 return FUNIT_NONE; 1242 } 1243 1244 // ----------------------------------------------------------------------- 1245 1246 static double nonValueDoubleToValueDouble( double nValue ) 1247 { 1248 return rtl::math::isFinite( nValue ) ? nValue : 0.0; 1249 } 1250 1251 sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits, 1252 FieldUnit eInUnit, FieldUnit eOutUnit ) 1253 { 1254 double nDouble = nonValueDoubleToValueDouble( ConvertDoubleValue( 1255 (double)nValue, mnBaseValue, nDecDigits, eInUnit, eOutUnit ) ); 1256 sal_Int64 nLong ; 1257 1258 // caution: precision loss in double cast 1259 if ( nDouble <= (double)SAL_MIN_INT64 ) 1260 nLong = SAL_MIN_INT64; 1261 else if ( nDouble >= (double)SAL_MAX_INT64 ) 1262 nLong = SAL_MAX_INT64; 1263 else 1264 nLong = static_cast<sal_Int64>( nDouble ); 1265 return ( nLong ); 1266 } 1267 1268 // ----------------------------------------------------------------------- 1269 1270 sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_uInt16 nDigits, 1271 MapUnit eInUnit, FieldUnit eOutUnit ) 1272 { 1273 return static_cast<sal_Int64>( 1274 nonValueDoubleToValueDouble( 1275 ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit ) ) ); 1276 } 1277 1278 // ----------------------------------------------------------------------- 1279 1280 sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_uInt16 nDigits, 1281 FieldUnit eInUnit, MapUnit eOutUnit ) 1282 { 1283 return static_cast<sal_Int64>( 1284 // #150733# cast double to sal_Int64 can throw a 1285 // EXCEPTION_FLT_INVALID_OPERATION on Windows 1286 nonValueDoubleToValueDouble( 1287 ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit ) ) ); 1288 } 1289 1290 // ----------------------------------------------------------------------- 1291 1292 double MetricField::ConvertDoubleValue( double nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits, 1293 FieldUnit eInUnit, FieldUnit eOutUnit ) 1294 { 1295 if ( eInUnit != eOutUnit ) 1296 { 1297 sal_Int64 nMult = 1, nDiv = 1; 1298 1299 if ( eInUnit == FUNIT_PERCENT ) 1300 { 1301 if ( (mnBaseValue <= 0) || (nValue <= 0) ) 1302 return nValue; 1303 nDiv = 100; 1304 for ( sal_uInt16 i=0; i < nDecDigits; i++ ) 1305 nDiv *= 10; 1306 1307 nMult = mnBaseValue; 1308 } 1309 else if ( eOutUnit == FUNIT_PERCENT || 1310 eOutUnit == FUNIT_CUSTOM || 1311 eOutUnit == FUNIT_NONE || 1312 eInUnit == FUNIT_CUSTOM || 1313 eInUnit == FUNIT_NONE ) 1314 return nValue; 1315 else 1316 { 1317 if ( eOutUnit == FUNIT_100TH_MM ) 1318 eOutUnit = FUNIT_NONE; 1319 if ( eInUnit == FUNIT_100TH_MM ) 1320 eInUnit = FUNIT_NONE; 1321 1322 nDiv = aImplFactor[eInUnit][eOutUnit]; 1323 nMult = aImplFactor[eOutUnit][eInUnit]; 1324 1325 DBG_ASSERT( nMult > 0, "illegal *" ); 1326 DBG_ASSERT( nDiv > 0, "illegal /" ); 1327 } 1328 1329 if ( nMult != 1 && nMult > 0 ) 1330 nValue *= nMult; 1331 if ( nDiv != 1 && nDiv > 0 ) 1332 { 1333 nValue += ( nValue < 0 ) ? (-nDiv/2) : (nDiv/2); 1334 nValue /= nDiv; 1335 } 1336 } 1337 1338 return nValue; 1339 } 1340 1341 // ----------------------------------------------------------------------- 1342 1343 double MetricField::ConvertDoubleValue( double nValue, sal_uInt16 nDigits, 1344 MapUnit eInUnit, FieldUnit eOutUnit ) 1345 { 1346 if ( eOutUnit == FUNIT_PERCENT || 1347 eOutUnit == FUNIT_CUSTOM || 1348 eOutUnit == FUNIT_NONE || 1349 eInUnit == MAP_PIXEL || 1350 eInUnit == MAP_SYSFONT || 1351 eInUnit == MAP_APPFONT || 1352 eInUnit == MAP_RELATIVE ) 1353 { 1354 DBG_ERROR( "invalid parameters" ); 1355 return nValue; 1356 } 1357 1358 long nDecDigits = nDigits; 1359 FieldUnit eFieldUnit = ImplMap2FieldUnit( eInUnit, nDecDigits ); 1360 1361 if ( nDecDigits < 0 ) 1362 { 1363 while ( nDecDigits ) 1364 { 1365 nValue += 5; 1366 nValue /= 10; 1367 nDecDigits++; 1368 } 1369 } 1370 else 1371 { 1372 while ( nDecDigits ) 1373 { 1374 nValue *= 10; 1375 nDecDigits--; 1376 } 1377 } 1378 1379 if ( eFieldUnit != eOutUnit ) 1380 { 1381 sal_Int64 nDiv = aImplFactor[eFieldUnit][eOutUnit]; 1382 sal_Int64 nMult = aImplFactor[eOutUnit][eFieldUnit]; 1383 1384 DBG_ASSERT( nMult > 0, "illegal *" ); 1385 DBG_ASSERT( nDiv > 0, "illegal /" ); 1386 1387 if ( nMult != 1 && nMult > 0) 1388 nValue *= nMult; 1389 if ( nDiv != 1 && nDiv > 0 ) 1390 { 1391 nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2); 1392 nValue /= nDiv; 1393 } 1394 } 1395 return nValue; 1396 } 1397 1398 // ----------------------------------------------------------------------- 1399 1400 double MetricField::ConvertDoubleValue( double nValue, sal_uInt16 nDigits, 1401 FieldUnit eInUnit, MapUnit eOutUnit ) 1402 { 1403 if ( eInUnit == FUNIT_PERCENT || 1404 eInUnit == FUNIT_CUSTOM || 1405 eInUnit == FUNIT_NONE || 1406 eOutUnit == MAP_PIXEL || 1407 eOutUnit == MAP_SYSFONT || 1408 eOutUnit == MAP_APPFONT || 1409 eOutUnit == MAP_RELATIVE ) 1410 { 1411 DBG_ERROR( "invalid parameters" ); 1412 return nValue; 1413 } 1414 1415 long nDecDigits = nDigits; 1416 FieldUnit eFieldUnit = ImplMap2FieldUnit( eOutUnit, nDecDigits ); 1417 1418 if ( nDecDigits < 0 ) 1419 { 1420 while ( nDecDigits ) 1421 { 1422 nValue *= 10; 1423 nDecDigits++; 1424 } 1425 } 1426 else 1427 { 1428 while ( nDecDigits ) 1429 { 1430 nValue += 5; 1431 nValue /= 10; 1432 nDecDigits--; 1433 } 1434 } 1435 1436 if ( eFieldUnit != eInUnit ) 1437 { 1438 sal_Int64 nDiv = aImplFactor[eInUnit][eFieldUnit]; 1439 sal_Int64 nMult = aImplFactor[eFieldUnit][eInUnit]; 1440 1441 DBG_ASSERT( nMult > 0, "illegal *" ); 1442 DBG_ASSERT( nDiv > 0, "illegal /" ); 1443 1444 if( nMult != 1 && nMult > 0 ) 1445 nValue *= nMult; 1446 if( nDiv != 1 && nDiv > 0 ) 1447 { 1448 nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2); 1449 nValue /= nDiv; 1450 } 1451 } 1452 return nValue; 1453 } 1454 1455 // ----------------------------------------------------------------------- 1456 1457 static sal_Bool ImplMetricGetValue( const XubString& rStr, double& rValue, sal_Int64 nBaseValue, 1458 sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrapper, FieldUnit eUnit ) 1459 { 1460 // Zahlenwert holen 1461 if ( !ImplNumericGetValue( rStr, rValue, nDecDigits, rLocaleDataWrapper ) ) 1462 return sal_False; 1463 1464 // Einheit rausfinden 1465 FieldUnit eEntryUnit = ImplMetricGetUnit( rStr ); 1466 1467 // Einheiten umrechnen 1468 rValue = MetricField::ConvertDoubleValue( rValue, nBaseValue, nDecDigits, eEntryUnit, eUnit ); 1469 1470 return sal_True; 1471 } 1472 1473 // ----------------------------------------------------------------------- 1474 1475 sal_Bool MetricFormatter::ImplMetricReformat( const XubString& rStr, double& rValue, XubString& rOutStr ) 1476 { 1477 if ( !ImplMetricGetValue( rStr, rValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) ) 1478 return sal_True; 1479 else 1480 { 1481 double nTempVal = rValue; 1482 // caution: precision loss in double cast 1483 if ( nTempVal > GetMax() ) 1484 nTempVal = (double)GetMax(); 1485 else if ( nTempVal < GetMin()) 1486 nTempVal = (double)GetMin(); 1487 1488 if ( GetErrorHdl().IsSet() && (rValue != nTempVal) ) 1489 { 1490 mnCorrectedValue = (sal_Int64)nTempVal; 1491 if ( !GetErrorHdl().Call( this ) ) 1492 { 1493 mnCorrectedValue = 0; 1494 return sal_False; 1495 } 1496 else 1497 mnCorrectedValue = 0; 1498 } 1499 1500 rOutStr = CreateFieldText( (sal_Int64)nTempVal ); 1501 return sal_True; 1502 } 1503 } 1504 1505 // ----------------------------------------------------------------------- 1506 1507 inline void MetricFormatter::ImplInit() 1508 { 1509 mnBaseValue = 0; 1510 meUnit = MetricField::GetDefaultUnit(); 1511 mnType = FORMAT_METRIC; 1512 } 1513 1514 // ----------------------------------------------------------------------- 1515 1516 MetricFormatter::MetricFormatter() 1517 { 1518 ImplInit(); 1519 } 1520 1521 // ----------------------------------------------------------------------- 1522 1523 void MetricFormatter::ImplLoadRes( const ResId& rResId ) 1524 { 1525 NumericFormatter::ImplLoadRes( rResId ); 1526 1527 ResMgr* pMgr = rResId.GetResMgr(); 1528 if( pMgr ) 1529 { 1530 sal_uLong nMask = pMgr->ReadLong(); 1531 1532 if ( METRICFORMATTER_UNIT & nMask ) 1533 meUnit = (FieldUnit)pMgr->ReadLong(); 1534 1535 if ( METRICFORMATTER_CUSTOMUNITTEXT & nMask ) 1536 maCustomUnitText = pMgr->ReadString(); 1537 } 1538 } 1539 1540 // ----------------------------------------------------------------------- 1541 1542 MetricFormatter::~MetricFormatter() 1543 { 1544 } 1545 1546 // ----------------------------------------------------------------------- 1547 1548 void MetricFormatter::SetUnit( FieldUnit eNewUnit ) 1549 { 1550 if ( eNewUnit == FUNIT_100TH_MM ) 1551 { 1552 SetDecimalDigits( GetDecimalDigits() + 2 ); 1553 meUnit = FUNIT_MM; 1554 } 1555 else 1556 meUnit = eNewUnit; 1557 ReformatAll(); 1558 } 1559 1560 // ----------------------------------------------------------------------- 1561 1562 void MetricFormatter::SetCustomUnitText( const XubString& rStr ) 1563 { 1564 maCustomUnitText = rStr; 1565 ReformatAll(); 1566 } 1567 1568 // ----------------------------------------------------------------------- 1569 1570 void MetricFormatter::SetValue( sal_Int64 nNewValue, FieldUnit eInUnit ) 1571 { 1572 SetUserValue( nNewValue, eInUnit ); 1573 mnFieldValue = mnLastValue; 1574 } 1575 1576 // ----------------------------------------------------------------------- 1577 1578 XubString MetricFormatter::CreateFieldText( sal_Int64 nValue ) const 1579 { 1580 XubString aStr = NumericFormatter::CreateFieldText( nValue ); 1581 1582 if( meUnit == FUNIT_CUSTOM ) 1583 aStr += maCustomUnitText; 1584 else 1585 aStr += ImplMetricToString( meUnit ); 1586 1587 return aStr; 1588 } 1589 1590 // ----------------------------------------------------------------------- 1591 1592 void MetricFormatter::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit ) 1593 { 1594 // Umrechnen auf eingestellte Einheiten 1595 nNewValue = MetricField::ConvertValue( nNewValue, mnBaseValue, GetDecimalDigits(), eInUnit, meUnit ); 1596 NumericFormatter::SetUserValue( nNewValue ); 1597 } 1598 1599 // ----------------------------------------------------------------------- 1600 1601 sal_Int64 MetricFormatter::GetValue( FieldUnit eOutUnit ) const 1602 { 1603 if ( !GetField() ) 1604 return 0; 1605 1606 double nTempValue; 1607 // caution: precision loss in double cast 1608 if ( !ImplMetricGetValue( GetField()->GetText(), nTempValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) ) 1609 nTempValue = (double)mnLastValue; 1610 1611 // caution: precision loss in double cast 1612 if ( nTempValue > mnMax ) 1613 nTempValue = (double)mnMax; 1614 else if ( nTempValue < mnMin ) 1615 nTempValue = (double)mnMin; 1616 1617 // Umrechnen auf gewuenschte Einheiten 1618 return MetricField::ConvertValue( (sal_Int64)nTempValue, mnBaseValue, GetDecimalDigits(), meUnit, eOutUnit ); 1619 } 1620 1621 // ----------------------------------------------------------------------- 1622 1623 void MetricFormatter::SetValue( sal_Int64 nValue ) 1624 { 1625 // Implementation not inline, because it is a virtual Function 1626 SetValue( nValue, FUNIT_NONE ); 1627 } 1628 1629 // ----------------------------------------------------------------------- 1630 1631 sal_Int64 MetricFormatter::GetValue() const 1632 { 1633 // Implementation not inline, because it is a virtual Function 1634 return GetValue( FUNIT_NONE ); 1635 } 1636 1637 // ----------------------------------------------------------------------- 1638 1639 void MetricFormatter::SetMin( sal_Int64 nNewMin, FieldUnit eInUnit ) 1640 { 1641 // Umrechnen auf gewuenschte Einheiten 1642 NumericFormatter::SetMin( MetricField::ConvertValue( nNewMin, mnBaseValue, GetDecimalDigits(), 1643 eInUnit, meUnit ) ); 1644 } 1645 1646 // ----------------------------------------------------------------------- 1647 1648 sal_Int64 MetricFormatter::GetMin( FieldUnit eOutUnit ) const 1649 { 1650 // Umrechnen auf gewuenschte Einheiten 1651 return MetricField::ConvertValue( NumericFormatter::GetMin(), mnBaseValue, 1652 GetDecimalDigits(), meUnit, eOutUnit ); 1653 } 1654 1655 // ----------------------------------------------------------------------- 1656 1657 void MetricFormatter::SetMax( sal_Int64 nNewMax, FieldUnit eInUnit ) 1658 { 1659 // Umrechnen auf gewuenschte Einheiten 1660 NumericFormatter::SetMax( MetricField::ConvertValue( nNewMax, mnBaseValue, GetDecimalDigits(), 1661 eInUnit, meUnit ) ); 1662 } 1663 1664 // ----------------------------------------------------------------------- 1665 1666 sal_Int64 MetricFormatter::GetMax( FieldUnit eOutUnit ) const 1667 { 1668 // Umrechnen auf gewuenschte Einheiten 1669 return MetricField::ConvertValue( NumericFormatter::GetMax(), mnBaseValue, 1670 GetDecimalDigits(), meUnit, eOutUnit ); 1671 } 1672 1673 // ----------------------------------------------------------------------- 1674 1675 void MetricFormatter::SetBaseValue( sal_Int64 nNewBase, FieldUnit eInUnit ) 1676 { 1677 mnBaseValue = MetricField::ConvertValue( nNewBase, mnBaseValue, GetDecimalDigits(), 1678 eInUnit, meUnit ); 1679 } 1680 1681 // ----------------------------------------------------------------------- 1682 1683 sal_Int64 MetricFormatter::GetBaseValue( FieldUnit eOutUnit ) const 1684 { 1685 // Umrechnen auf gewuenschte Einheiten 1686 return MetricField::ConvertValue( mnBaseValue, mnBaseValue, GetDecimalDigits(), 1687 meUnit, eOutUnit ); 1688 } 1689 1690 // ----------------------------------------------------------------------- 1691 1692 void MetricFormatter::Reformat() 1693 { 1694 if ( !GetField() ) 1695 return; 1696 1697 XubString aText = GetField()->GetText(); 1698 if ( meUnit == FUNIT_CUSTOM ) 1699 maCurUnitText = ImplMetricGetUnitText( aText ); 1700 1701 XubString aStr; 1702 // caution: precision loss in double cast 1703 double nTemp = (double)mnLastValue; 1704 sal_Bool bOK = ImplMetricReformat( aText, nTemp, aStr ); 1705 mnLastValue = (sal_Int64)nTemp; 1706 1707 if ( !bOK ) 1708 return; 1709 1710 if ( aStr.Len() ) 1711 { 1712 ImplSetText( aStr ); 1713 if ( meUnit == FUNIT_CUSTOM ) 1714 CustomConvert(); 1715 } 1716 else 1717 SetValue( mnLastValue ); 1718 maCurUnitText.Erase(); 1719 } 1720 1721 // ----------------------------------------------------------------------- 1722 1723 sal_Int64 MetricFormatter::GetCorrectedValue( FieldUnit eOutUnit ) const 1724 { 1725 // Umrechnen auf gewuenschte Einheiten 1726 return MetricField::ConvertValue( mnCorrectedValue, mnBaseValue, GetDecimalDigits(), 1727 meUnit, eOutUnit ); 1728 } 1729 1730 // ----------------------------------------------------------------------- 1731 1732 MetricField::MetricField( Window* pParent, WinBits nWinStyle ) : 1733 SpinField( pParent, nWinStyle ) 1734 { 1735 SetField( this ); 1736 Reformat(); 1737 } 1738 1739 // ----------------------------------------------------------------------- 1740 1741 MetricField::MetricField( Window* pParent, const ResId& rResId ) : 1742 SpinField( WINDOW_METRICFIELD ) 1743 { 1744 rResId.SetRT( RSC_METRICFIELD ); 1745 WinBits nStyle = ImplInitRes( rResId ) ; 1746 SpinField::ImplInit( pParent, nStyle ); 1747 SetField( this ); 1748 ImplLoadRes( rResId ); 1749 1750 if ( !(nStyle & WB_HIDE ) ) 1751 Show(); 1752 } 1753 1754 // ----------------------------------------------------------------------- 1755 1756 void MetricField::ImplLoadRes( const ResId& rResId ) 1757 { 1758 SpinField::ImplLoadRes( rResId ); 1759 MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 1760 1761 sal_uLong nMask = ReadLongRes(); 1762 1763 if ( METRICFIELD_FIRST & nMask ) 1764 mnFirst = ReadLongRes(); 1765 1766 if ( METRICFIELD_LAST & nMask ) 1767 mnLast = ReadLongRes(); 1768 1769 if ( METRICFIELD_SPINSIZE & nMask ) 1770 mnSpinSize = ReadLongRes(); 1771 1772 Reformat(); 1773 } 1774 1775 // ----------------------------------------------------------------------- 1776 1777 MetricField::~MetricField() 1778 { 1779 } 1780 1781 // ----------------------------------------------------------------------- 1782 1783 void MetricField::SetFirst( sal_Int64 nNewFirst, FieldUnit eInUnit ) 1784 { 1785 // convert 1786 nNewFirst = MetricField::ConvertValue( nNewFirst, mnBaseValue, GetDecimalDigits(), 1787 eInUnit, meUnit ); 1788 mnFirst = nNewFirst; 1789 } 1790 1791 // ----------------------------------------------------------------------- 1792 1793 sal_Int64 MetricField::GetFirst( FieldUnit eOutUnit ) const 1794 { 1795 // convert 1796 return MetricField::ConvertValue( mnFirst, mnBaseValue, GetDecimalDigits(), 1797 meUnit, eOutUnit ); 1798 } 1799 1800 // ----------------------------------------------------------------------- 1801 1802 void MetricField::SetLast( sal_Int64 nNewLast, FieldUnit eInUnit ) 1803 { 1804 // Umrechnen 1805 nNewLast = MetricField::ConvertValue( nNewLast, mnBaseValue, GetDecimalDigits(), 1806 eInUnit, meUnit ); 1807 mnLast = nNewLast; 1808 } 1809 1810 // ----------------------------------------------------------------------- 1811 1812 sal_Int64 MetricField::GetLast( FieldUnit eOutUnit ) const 1813 { 1814 // Umrechnen 1815 return MetricField::ConvertValue( mnLast, mnBaseValue, GetDecimalDigits(), 1816 meUnit, eOutUnit ); 1817 } 1818 1819 // ----------------------------------------------------------------------- 1820 1821 long MetricField::PreNotify( NotifyEvent& rNEvt ) 1822 { 1823 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 1824 { 1825 if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 1826 return 1; 1827 } 1828 1829 return SpinField::PreNotify( rNEvt ); 1830 } 1831 1832 // ----------------------------------------------------------------------- 1833 1834 long MetricField::Notify( NotifyEvent& rNEvt ) 1835 { 1836 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 1837 MarkToBeReformatted( sal_False ); 1838 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 1839 { 1840 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 1841 Reformat(); 1842 } 1843 1844 return SpinField::Notify( rNEvt ); 1845 } 1846 1847 // ----------------------------------------------------------------------- 1848 1849 void MetricField::DataChanged( const DataChangedEvent& rDCEvt ) 1850 { 1851 SpinField::DataChanged( rDCEvt ); 1852 1853 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 1854 { 1855 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1856 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1857 if ( IsDefaultLocale() ) 1858 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 1859 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1860 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1861 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 1862 ReformatAll(); 1863 } 1864 } 1865 1866 // ----------------------------------------------------------------------- 1867 1868 void MetricField::Modify() 1869 { 1870 MarkToBeReformatted( sal_True ); 1871 SpinField::Modify(); 1872 } 1873 1874 // ----------------------------------------------------------------------- 1875 1876 void MetricField::Up() 1877 { 1878 FieldUp(); 1879 SpinField::Up(); 1880 } 1881 1882 // ----------------------------------------------------------------------- 1883 1884 void MetricField::Down() 1885 { 1886 FieldDown(); 1887 SpinField::Down(); 1888 } 1889 1890 // ----------------------------------------------------------------------- 1891 1892 void MetricField::First() 1893 { 1894 FieldFirst(); 1895 SpinField::First(); 1896 } 1897 1898 // ----------------------------------------------------------------------- 1899 1900 void MetricField::Last() 1901 { 1902 FieldLast(); 1903 SpinField::Last(); 1904 } 1905 1906 // ----------------------------------------------------------------------- 1907 1908 void MetricField::CustomConvert() 1909 { 1910 maCustomConvertLink.Call( this ); 1911 } 1912 1913 // ----------------------------------------------------------------------- 1914 1915 MetricBox::MetricBox( Window* pParent, WinBits nWinStyle ) : 1916 ComboBox( pParent, nWinStyle ) 1917 { 1918 SetField( this ); 1919 Reformat(); 1920 } 1921 1922 // ----------------------------------------------------------------------- 1923 1924 MetricBox::MetricBox( Window* pParent, const ResId& rResId ) : 1925 ComboBox( WINDOW_METRICBOX ) 1926 { 1927 rResId.SetRT( RSC_METRICBOX ); 1928 WinBits nStyle = ImplInitRes( rResId ); 1929 ComboBox::ImplInit( pParent, nStyle ); 1930 SetField( this ); 1931 Reformat(); 1932 ComboBox::ImplLoadRes( rResId ); 1933 MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 1934 1935 if ( !(nStyle & WB_HIDE ) ) 1936 Show(); 1937 } 1938 1939 // ----------------------------------------------------------------------- 1940 1941 MetricBox::~MetricBox() 1942 { 1943 } 1944 1945 // ----------------------------------------------------------------------- 1946 1947 long MetricBox::PreNotify( NotifyEvent& rNEvt ) 1948 { 1949 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 1950 { 1951 if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 1952 return 1; 1953 } 1954 1955 return ComboBox::PreNotify( rNEvt ); 1956 } 1957 1958 // ----------------------------------------------------------------------- 1959 1960 long MetricBox::Notify( NotifyEvent& rNEvt ) 1961 { 1962 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 1963 MarkToBeReformatted( sal_False ); 1964 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 1965 { 1966 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 1967 Reformat(); 1968 } 1969 1970 return ComboBox::Notify( rNEvt ); 1971 } 1972 1973 // ----------------------------------------------------------------------- 1974 1975 void MetricBox::DataChanged( const DataChangedEvent& rDCEvt ) 1976 { 1977 ComboBox::DataChanged( rDCEvt ); 1978 1979 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 1980 { 1981 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1982 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1983 if ( IsDefaultLocale() ) 1984 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 1985 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 1986 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 1987 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 1988 ReformatAll(); 1989 } 1990 } 1991 1992 // ----------------------------------------------------------------------- 1993 1994 void MetricBox::Modify() 1995 { 1996 MarkToBeReformatted( sal_True ); 1997 ComboBox::Modify(); 1998 } 1999 2000 // ----------------------------------------------------------------------- 2001 2002 void MetricBox::ReformatAll() 2003 { 2004 double nValue; 2005 XubString aStr; 2006 SetUpdateMode( sal_False ); 2007 sal_uInt16 nEntryCount = GetEntryCount(); 2008 for ( sal_uInt16 i=0; i < nEntryCount; i++ ) 2009 { 2010 ImplMetricReformat( GetEntry( i ), nValue, aStr ); 2011 RemoveEntry( i ); 2012 InsertEntry( aStr, i ); 2013 } 2014 MetricFormatter::Reformat(); 2015 SetUpdateMode( sal_True ); 2016 } 2017 2018 // ----------------------------------------------------------------------- 2019 2020 void MetricBox::CustomConvert() 2021 { 2022 maCustomConvertLink.Call( this ); 2023 } 2024 2025 // ----------------------------------------------------------------------- 2026 2027 void MetricBox::InsertValue( sal_Int64 nValue, FieldUnit eInUnit, sal_uInt16 nPos ) 2028 { 2029 // Umrechnen auf eingestellte Einheiten 2030 nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(), 2031 eInUnit, meUnit ); 2032 ComboBox::InsertEntry( CreateFieldText( nValue ), nPos ); 2033 } 2034 2035 // ----------------------------------------------------------------------- 2036 2037 void MetricBox::RemoveValue( sal_Int64 nValue, FieldUnit eInUnit ) 2038 { 2039 // Umrechnen auf eingestellte Einheiten 2040 nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(), 2041 eInUnit, meUnit ); 2042 ComboBox::RemoveEntry( CreateFieldText( nValue ) ); 2043 } 2044 2045 // ----------------------------------------------------------------------- 2046 2047 sal_Int64 MetricBox::GetValue( sal_uInt16 nPos, FieldUnit eOutUnit ) const 2048 { 2049 double nValue = 0; 2050 ImplMetricGetValue( ComboBox::GetEntry( nPos ), nValue, mnBaseValue, 2051 GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ); 2052 2053 // Umrechnen auf eingestellte Einheiten 2054 sal_Int64 nRetValue = MetricField::ConvertValue( (sal_Int64)nValue, mnBaseValue, GetDecimalDigits(), 2055 meUnit, eOutUnit ); 2056 2057 return nRetValue; 2058 } 2059 2060 // ----------------------------------------------------------------------- 2061 2062 sal_uInt16 MetricBox::GetValuePos( sal_Int64 nValue, FieldUnit eInUnit ) const 2063 { 2064 // Umrechnen auf eingestellte Einheiten 2065 nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(), 2066 eInUnit, meUnit ); 2067 return ComboBox::GetEntryPos( CreateFieldText( nValue ) ); 2068 } 2069 2070 // ----------------------------------------------------------------------- 2071 2072 sal_Int64 MetricBox::GetValue( FieldUnit eOutUnit ) const 2073 { 2074 // Implementation not inline, because it is a virtual Function 2075 return MetricFormatter::GetValue( eOutUnit ); 2076 } 2077 2078 // ----------------------------------------------------------------------- 2079 2080 sal_Int64 MetricBox::GetValue() const 2081 { 2082 // Implementation not inline, because it is a virtual Function 2083 return GetValue( FUNIT_NONE ); 2084 } 2085 2086 // ----------------------------------------------------------------------- 2087 2088 static sal_Bool ImplCurrencyProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt, 2089 sal_Bool, sal_Bool bUseThousandSep, const LocaleDataWrapper& rWrapper ) 2090 { 2091 // Es gibt hier kein sinnvolles StrictFormat, also alle 2092 // Zeichen erlauben 2093 return ImplNumericProcessKeyInput( pEdit, rKEvt, sal_False, bUseThousandSep, rWrapper ); 2094 } 2095 2096 // ----------------------------------------------------------------------- 2097 2098 inline sal_Bool ImplCurrencyGetValue( const XubString& rStr, double& rValue, 2099 sal_uInt16 nDecDigits, const LocaleDataWrapper& rWrapper ) 2100 { 2101 // Zahlenwert holen 2102 return ImplNumericGetValue( rStr, rValue, nDecDigits, rWrapper, sal_True ); 2103 } 2104 2105 // ----------------------------------------------------------------------- 2106 2107 sal_Bool CurrencyFormatter::ImplCurrencyReformat( const XubString& rStr, 2108 XubString& rOutStr ) 2109 { 2110 double nValue; 2111 if ( !ImplNumericGetValue( rStr, nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), sal_True ) ) 2112 return sal_True; 2113 else 2114 { 2115 double nTempVal = nValue; 2116 // caution: precision loss in double cast 2117 if ( nTempVal > GetMax() ) 2118 nTempVal = (double)GetMax(); 2119 else if ( nTempVal < GetMin()) 2120 nTempVal = (double)GetMin(); 2121 2122 if ( GetErrorHdl().IsSet() && (nValue != nTempVal) ) 2123 { 2124 mnCorrectedValue = (sal_Int64)nTempVal; 2125 if ( !GetErrorHdl().Call( this ) ) 2126 { 2127 mnCorrectedValue = 0; 2128 return sal_False; 2129 } 2130 else 2131 mnCorrectedValue = 0; 2132 } 2133 2134 rOutStr = CreateFieldText( (long)nTempVal ); 2135 return sal_True; 2136 } 2137 } 2138 2139 // ----------------------------------------------------------------------- 2140 2141 inline void CurrencyFormatter::ImplInit() 2142 { 2143 mnType = FORMAT_CURRENCY; 2144 } 2145 2146 // ----------------------------------------------------------------------- 2147 2148 CurrencyFormatter::CurrencyFormatter() 2149 { 2150 ImplInit(); 2151 } 2152 2153 // ----------------------------------------------------------------------- 2154 2155 CurrencyFormatter::~CurrencyFormatter() 2156 { 2157 } 2158 2159 // ----------------------------------------------------------------------- 2160 2161 void CurrencyFormatter::SetCurrencySymbol( const String& rStr ) 2162 { 2163 maCurrencySymbol= rStr; 2164 ReformatAll(); 2165 } 2166 2167 // ----------------------------------------------------------------------- 2168 2169 String CurrencyFormatter::GetCurrencySymbol() const 2170 { 2171 return maCurrencySymbol.Len() ? maCurrencySymbol : ImplGetLocaleDataWrapper().getCurrSymbol(); 2172 } 2173 2174 // ----------------------------------------------------------------------- 2175 2176 void CurrencyFormatter::SetValue( sal_Int64 nNewValue ) 2177 { 2178 SetUserValue( nNewValue ); 2179 mnFieldValue = mnLastValue; 2180 SetEmptyFieldValueData( sal_False ); 2181 } 2182 2183 // ----------------------------------------------------------------------- 2184 2185 XubString CurrencyFormatter::CreateFieldText( sal_Int64 nValue ) const 2186 { 2187 return ImplGetLocaleDataWrapper().getCurr( nValue, GetDecimalDigits(), GetCurrencySymbol(), IsUseThousandSep() ); 2188 } 2189 2190 // ----------------------------------------------------------------------- 2191 2192 sal_Int64 CurrencyFormatter::GetValue() const 2193 { 2194 if ( !GetField() ) 2195 return 0; 2196 2197 double nTempValue; 2198 if ( ImplCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) ) 2199 { 2200 // caution: precision loss in double cast 2201 if ( nTempValue > mnMax ) 2202 nTempValue = (double)mnMax; 2203 else if ( nTempValue < mnMin ) 2204 nTempValue = (double)mnMin; 2205 return (sal_Int64)nTempValue; 2206 } 2207 else 2208 return mnLastValue; 2209 } 2210 2211 // ----------------------------------------------------------------------- 2212 2213 void CurrencyFormatter::Reformat() 2214 { 2215 if ( !GetField() ) 2216 return; 2217 2218 XubString aStr; 2219 sal_Bool bOK = ImplCurrencyReformat( GetField()->GetText(), aStr ); 2220 if ( !bOK ) 2221 return; 2222 2223 if ( aStr.Len() ) 2224 { 2225 ImplSetText( aStr ); 2226 // caution: precision loss in double cast 2227 double nTemp = (double)mnLastValue; 2228 ImplCurrencyGetValue( aStr, nTemp, GetDecimalDigits(), ImplGetLocaleDataWrapper() ); 2229 mnLastValue = (sal_Int64)nTemp; 2230 } 2231 else 2232 SetValue( mnLastValue ); 2233 } 2234 2235 // ----------------------------------------------------------------------- 2236 2237 CurrencyField::CurrencyField( Window* pParent, WinBits nWinStyle ) : 2238 SpinField( pParent, nWinStyle ) 2239 { 2240 SetField( this ); 2241 Reformat(); 2242 } 2243 2244 // ----------------------------------------------------------------------- 2245 2246 CurrencyField::CurrencyField( Window* pParent, const ResId& rResId ) : 2247 SpinField( WINDOW_CURRENCYFIELD ) 2248 { 2249 rResId.SetRT( RSC_CURRENCYFIELD ); 2250 WinBits nStyle = ImplInitRes( rResId ); 2251 SpinField::ImplInit( pParent, nStyle); 2252 SetField( this ); 2253 ImplLoadRes( rResId ); 2254 2255 if ( !(nStyle & WB_HIDE ) ) 2256 Show(); 2257 } 2258 2259 // ----------------------------------------------------------------------- 2260 2261 void CurrencyField::ImplLoadRes( const ResId& rResId ) 2262 { 2263 SpinField::ImplLoadRes( rResId ); 2264 CurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 2265 2266 sal_uLong nMask = ReadLongRes(); 2267 2268 if ( CURRENCYFIELD_FIRST & nMask ) 2269 mnFirst = ReadLongRes(); 2270 2271 if ( CURRENCYFIELD_LAST & nMask ) 2272 mnLast = ReadLongRes(); 2273 2274 if ( CURRENCYFIELD_SPINSIZE & nMask ) 2275 mnSpinSize = ReadLongRes(); 2276 2277 Reformat(); 2278 } 2279 2280 // ----------------------------------------------------------------------- 2281 2282 CurrencyField::~CurrencyField() 2283 { 2284 } 2285 2286 // ----------------------------------------------------------------------- 2287 2288 long CurrencyField::PreNotify( NotifyEvent& rNEvt ) 2289 { 2290 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 2291 { 2292 if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 2293 return 1; 2294 } 2295 2296 return SpinField::PreNotify( rNEvt ); 2297 } 2298 2299 // ----------------------------------------------------------------------- 2300 2301 long CurrencyField::Notify( NotifyEvent& rNEvt ) 2302 { 2303 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 2304 MarkToBeReformatted( sal_False ); 2305 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 2306 { 2307 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 2308 Reformat(); 2309 } 2310 2311 return SpinField::Notify( rNEvt ); 2312 } 2313 2314 // ----------------------------------------------------------------------- 2315 2316 void CurrencyField::DataChanged( const DataChangedEvent& rDCEvt ) 2317 { 2318 SpinField::DataChanged( rDCEvt ); 2319 2320 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 2321 { 2322 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 2323 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 2324 if ( IsDefaultLocale() ) 2325 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 2326 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 2327 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 2328 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 2329 ReformatAll(); 2330 } 2331 } 2332 2333 // ----------------------------------------------------------------------- 2334 2335 void CurrencyField::Modify() 2336 { 2337 MarkToBeReformatted( sal_True ); 2338 SpinField::Modify(); 2339 } 2340 2341 // ----------------------------------------------------------------------- 2342 2343 void CurrencyField::Up() 2344 { 2345 FieldUp(); 2346 SpinField::Up(); 2347 } 2348 2349 // ----------------------------------------------------------------------- 2350 2351 void CurrencyField::Down() 2352 { 2353 FieldDown(); 2354 SpinField::Down(); 2355 } 2356 2357 // ----------------------------------------------------------------------- 2358 2359 void CurrencyField::First() 2360 { 2361 FieldFirst(); 2362 SpinField::First(); 2363 } 2364 2365 // ----------------------------------------------------------------------- 2366 2367 void CurrencyField::Last() 2368 { 2369 FieldLast(); 2370 SpinField::Last(); 2371 } 2372 2373 // ----------------------------------------------------------------------- 2374 2375 CurrencyBox::CurrencyBox( Window* pParent, WinBits nWinStyle ) : 2376 ComboBox( pParent, nWinStyle ) 2377 { 2378 SetField( this ); 2379 Reformat(); 2380 } 2381 2382 // ----------------------------------------------------------------------- 2383 2384 CurrencyBox::CurrencyBox( Window* pParent, const ResId& rResId ) : 2385 ComboBox( WINDOW_CURRENCYBOX ) 2386 { 2387 rResId.SetRT( RSC_CURRENCYBOX ); 2388 WinBits nStyle = ImplInitRes( rResId ); 2389 ComboBox::ImplInit( pParent, nStyle ); 2390 CurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 2391 SetField( this ); 2392 ComboBox::ImplLoadRes( rResId ); 2393 Reformat(); 2394 2395 if ( !(nStyle & WB_HIDE ) ) 2396 Show(); 2397 } 2398 2399 // ----------------------------------------------------------------------- 2400 2401 CurrencyBox::~CurrencyBox() 2402 { 2403 } 2404 2405 // ----------------------------------------------------------------------- 2406 2407 long CurrencyBox::PreNotify( NotifyEvent& rNEvt ) 2408 { 2409 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 2410 { 2411 if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) ) 2412 return 1; 2413 } 2414 2415 return ComboBox::PreNotify( rNEvt ); 2416 } 2417 2418 // ----------------------------------------------------------------------- 2419 2420 long CurrencyBox::Notify( NotifyEvent& rNEvt ) 2421 { 2422 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 2423 MarkToBeReformatted( sal_False ); 2424 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 2425 { 2426 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 2427 Reformat(); 2428 } 2429 2430 return ComboBox::Notify( rNEvt ); 2431 } 2432 2433 // ----------------------------------------------------------------------- 2434 2435 void CurrencyBox::DataChanged( const DataChangedEvent& rDCEvt ) 2436 { 2437 ComboBox::DataChanged( rDCEvt ); 2438 2439 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 2440 { 2441 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 2442 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 2443 if ( IsDefaultLocale() ) 2444 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 2445 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep(); 2446 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep(); 2447 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this ); 2448 ReformatAll(); 2449 } 2450 } 2451 2452 // ----------------------------------------------------------------------- 2453 2454 void CurrencyBox::Modify() 2455 { 2456 MarkToBeReformatted( sal_True ); 2457 ComboBox::Modify(); 2458 } 2459 2460 // ----------------------------------------------------------------------- 2461 2462 void CurrencyBox::ReformatAll() 2463 { 2464 XubString aStr; 2465 SetUpdateMode( sal_False ); 2466 sal_uInt16 nEntryCount = GetEntryCount(); 2467 for ( sal_uInt16 i=0; i < nEntryCount; i++ ) 2468 { 2469 ImplCurrencyReformat( GetEntry( i ), aStr ); 2470 RemoveEntry( i ); 2471 InsertEntry( aStr, i ); 2472 } 2473 CurrencyFormatter::Reformat(); 2474 SetUpdateMode( sal_True ); 2475 } 2476 2477 // ----------------------------------------------------------------------- 2478 2479 void CurrencyBox::InsertValue( sal_Int64 nValue, sal_uInt16 nPos ) 2480 { 2481 ComboBox::InsertEntry( CreateFieldText( nValue ), nPos ); 2482 } 2483 2484 // ----------------------------------------------------------------------- 2485 2486 void CurrencyBox::RemoveValue( sal_Int64 nValue ) 2487 { 2488 ComboBox::RemoveEntry( CreateFieldText( nValue ) ); 2489 } 2490 2491 // ----------------------------------------------------------------------- 2492 2493 sal_Int64 CurrencyBox::GetValue( sal_uInt16 nPos ) const 2494 { 2495 double nValue = 0; 2496 ImplCurrencyGetValue( ComboBox::GetEntry( nPos ), nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ); 2497 return (sal_Int64)nValue; 2498 } 2499 2500 // ----------------------------------------------------------------------- 2501 2502 sal_uInt16 CurrencyBox::GetValuePos( sal_Int64 nValue ) const 2503 { 2504 return ComboBox::GetEntryPos( CreateFieldText( nValue ) ); 2505 } 2506 2507 // ----------------------------------------------------------------------- 2508 2509 sal_Int64 CurrencyBox::GetValue() const 2510 { 2511 // Implementation not inline, because it is a virtual Function 2512 return CurrencyFormatter::GetValue(); 2513 } 2514