1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 #include <tools/debug.hxx> 31 32 #include <tools/rc.h> 33 34 #include <vcl/svapp.hxx> 35 #include <vcl/sound.hxx> 36 #include <vcl/event.hxx> 37 #include <vcl/field.hxx> 38 #include <vcl/unohelp.hxx> 39 40 #include <svdata.hxx> 41 42 #include <i18npool/mslangid.hxx> 43 44 #include <com/sun/star/lang/Locale.hpp> 45 #include <com/sun/star/i18n/XCharacterClassification.hpp> 46 #include <com/sun/star/i18n/KCharacterType.hpp> 47 48 49 #include <unotools/localedatawrapper.hxx> 50 #include <unotools/calendarwrapper.hxx> 51 #include <unotools/charclass.hxx> 52 #include <unotools/misccfg.hxx> 53 54 using namespace ::com::sun::star; 55 56 // ======================================================================= 57 58 #define EDITMASK_LITERAL 'L' 59 #define EDITMASK_ALPHA 'a' 60 #define EDITMASK_UPPERALPHA 'A' 61 #define EDITMASK_ALPHANUM 'c' 62 #define EDITMASK_UPPERALPHANUM 'C' 63 #define EDITMASK_NUM 'N' 64 #define EDITMASK_NUMSPACE 'n' 65 #define EDITMASK_ALLCHAR 'x' 66 #define EDITMASK_UPPERALLCHAR 'X' 67 68 uno::Reference< i18n::XCharacterClassification > ImplGetCharClass() 69 { 70 static uno::Reference< i18n::XCharacterClassification > xCharClass; 71 if ( !xCharClass.is() ) 72 xCharClass = vcl::unohelper::CreateCharacterClassification(); 73 74 return xCharClass; 75 } 76 77 // ----------------------------------------------------------------------- 78 79 static sal_Unicode* ImplAddString( sal_Unicode* pBuf, const String& rStr ) 80 { 81 if ( rStr.Len() == 1 ) 82 *pBuf++ = rStr.GetChar(0); 83 else if ( rStr.Len() == 0 ) 84 ; 85 else 86 { 87 memcpy( pBuf, rStr.GetBuffer(), rStr.Len() * sizeof(sal_Unicode) ); 88 pBuf += rStr.Len(); 89 } 90 return pBuf; 91 } 92 93 // ----------------------------------------------------------------------- 94 95 static sal_Unicode* ImplAddNum( sal_Unicode* pBuf, sal_uLong nNumber, int nMinLen ) 96 { 97 // fill temp buffer with digits 98 sal_Unicode aTempBuf[30]; 99 sal_Unicode* pTempBuf = aTempBuf; 100 do 101 { 102 *pTempBuf = (sal_Unicode)(nNumber % 10) + '0'; 103 pTempBuf++; 104 nNumber /= 10; 105 if ( nMinLen ) 106 nMinLen--; 107 } 108 while ( nNumber ); 109 110 // fill with zeros up to the minimal length 111 while ( nMinLen > 0 ) 112 { 113 *pBuf = '0'; 114 pBuf++; 115 nMinLen--; 116 } 117 118 // copy temp buffer to real buffer 119 do 120 { 121 pTempBuf--; 122 *pBuf = *pTempBuf; 123 pBuf++; 124 } 125 while ( pTempBuf != aTempBuf ); 126 127 return pBuf; 128 } 129 130 // ----------------------------------------------------------------------- 131 132 static sal_uInt16 ImplGetNum( const sal_Unicode*& rpBuf, sal_Bool& rbError ) 133 { 134 if ( !*rpBuf ) 135 { 136 rbError = sal_True; 137 return 0; 138 } 139 140 sal_uInt16 nNumber = 0; 141 while( ( *rpBuf >= '0' ) && ( *rpBuf <= '9' ) ) 142 { 143 nNumber *= 10; 144 nNumber += *rpBuf - '0'; 145 rpBuf++; 146 } 147 148 return nNumber; 149 } 150 151 // ----------------------------------------------------------------------- 152 153 static void ImplSkipDelimiters( const sal_Unicode*& rpBuf ) 154 { 155 while( ( *rpBuf == ',' ) || ( *rpBuf == '.' ) || ( *rpBuf == ';' ) || 156 ( *rpBuf == ':' ) || ( *rpBuf == '-' ) || ( *rpBuf == '/' ) ) 157 { 158 rpBuf++; 159 } 160 } 161 162 // ----------------------------------------------------------------------- 163 164 static int ImplIsPatternChar( xub_Unicode cChar, sal_Char cEditMask ) 165 { 166 sal_Int32 nType = 0; 167 168 try 169 { 170 String aCharStr( cChar ); 171 nType = ImplGetCharClass()->getStringType( aCharStr, 0, aCharStr.Len(), Application::GetSettings().GetLocale() ); 172 } 173 catch ( ::com::sun::star::uno::Exception& ) 174 { 175 DBG_ERRORFILE( "ImplIsPatternChar: Exception caught!" ); 176 return sal_False; 177 } 178 179 if ( (cEditMask == EDITMASK_ALPHA) || (cEditMask == EDITMASK_UPPERALPHA) ) 180 { 181 if( !CharClass::isLetterType( nType ) ) 182 return sal_False; 183 } 184 else if ( cEditMask == EDITMASK_NUM ) 185 { 186 if( !CharClass::isNumericType( nType ) ) 187 return sal_False; 188 } 189 else if ( (cEditMask == EDITMASK_ALPHANUM) || (cEditMask == EDITMASK_UPPERALPHANUM) ) 190 { 191 if( !CharClass::isLetterNumericType( nType ) ) 192 return sal_False; 193 } 194 else if ( (cEditMask == EDITMASK_ALLCHAR) || (cEditMask == EDITMASK_UPPERALLCHAR) ) 195 { 196 if ( cChar < 32 ) 197 return sal_False; 198 } 199 else if ( cEditMask == EDITMASK_NUMSPACE ) 200 { 201 if ( !CharClass::isNumericType( nType ) && ( cChar != ' ' ) ) 202 return sal_False; 203 } 204 else 205 return sal_False; 206 207 return sal_True; 208 } 209 210 // ----------------------------------------------------------------------- 211 212 static xub_Unicode ImplPatternChar( xub_Unicode cChar, sal_Char cEditMask ) 213 { 214 if ( ImplIsPatternChar( cChar, cEditMask ) ) 215 { 216 if ( (cEditMask == EDITMASK_UPPERALPHA) || 217 (cEditMask == EDITMASK_UPPERALPHANUM) || 218 ( cEditMask == EDITMASK_UPPERALLCHAR ) ) 219 { 220 cChar = ImplGetCharClass()->toUpper( String(cChar),0,1,Application::GetSettings().GetLocale() )[0]; 221 } 222 return cChar; 223 } 224 else 225 return 0; 226 } 227 228 // ----------------------------------------------------------------------- 229 230 static int ImplKommaPointCharEqual( xub_Unicode c1, xub_Unicode c2 ) 231 { 232 if ( c1 == c2 ) 233 return sal_True; 234 else if ( ((c1 == '.') || (c1 == ',')) && 235 ((c2 == '.') || (c2 == ',')) ) 236 return sal_True; 237 else 238 return sal_False; 239 } 240 241 // ----------------------------------------------------------------------- 242 243 static XubString ImplPatternReformat( const XubString& rStr, 244 const ByteString& rEditMask, 245 const XubString& rLiteralMask, 246 sal_uInt16 nFormatFlags ) 247 { 248 if ( !rEditMask.Len() ) 249 return rStr; 250 251 XubString aStr = rStr; 252 XubString aOutStr = rLiteralMask; 253 xub_Unicode cTempChar; 254 xub_Unicode cChar; 255 xub_Unicode cLiteral; 256 sal_Char cMask; 257 xub_StrLen nStrIndex = 0; 258 xub_StrLen i = 0; 259 xub_StrLen n; 260 261 while ( i < rEditMask.Len() ) 262 { 263 if ( nStrIndex >= aStr.Len() ) 264 break; 265 266 cChar = aStr.GetChar(nStrIndex); 267 cLiteral = rLiteralMask.GetChar(i); 268 cMask = rEditMask.GetChar(i); 269 270 // Aktuelle Position ein Literal 271 if ( cMask == EDITMASK_LITERAL ) 272 { 273 // Wenn es das Literal-Zeichen ist, uebernehmen, ansonsten 274 // ignorieren, da es das naechste gueltige Zeichen vom String 275 // sein kann 276 if ( ImplKommaPointCharEqual( cChar, cLiteral ) ) 277 nStrIndex++; 278 else 279 { 280 // Ansonsten testen wir, ob es ein ungueltiges Zeichen ist. 281 // Dies ist dann der Fall, wenn es nicht in das Muster 282 // des naechsten nicht Literal-Zeichens passt 283 n = i+1; 284 while ( n < rEditMask.Len() ) 285 { 286 if ( rEditMask.GetChar(n) != EDITMASK_LITERAL ) 287 { 288 if ( !ImplIsPatternChar( cChar, rEditMask.GetChar(n) ) ) 289 nStrIndex++; 290 break; 291 } 292 293 n++; 294 } 295 } 296 } 297 else 298 { 299 // Gueltiges Zeichen an der Stelle 300 cTempChar = ImplPatternChar( cChar, cMask ); 301 if ( cTempChar ) 302 { 303 // dann Zeichen uebernehmen 304 aOutStr.SetChar( i, cTempChar ); 305 nStrIndex++; 306 } 307 else 308 { 309 // Wenn es das Literalzeichen ist, uebernehmen 310 if ( cLiteral == cChar ) 311 nStrIndex++; 312 else 313 { 314 // Wenn das ungueltige Zeichen das naechste Literalzeichen 315 // sein kann, dann springen wir bis dahin vor, ansonten 316 // das Zeichen ignorieren 317 // Nur machen, wenn leere Literale erlaubt sind 318 if ( nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS ) 319 { 320 n = i; 321 while ( n < rEditMask.Len() ) 322 { 323 if ( rEditMask.GetChar( n ) == EDITMASK_LITERAL ) 324 { 325 if ( ImplKommaPointCharEqual( cChar, rLiteralMask.GetChar( n ) ) ) 326 i = n+1; 327 328 break; 329 } 330 331 n++; 332 } 333 } 334 335 nStrIndex++; 336 continue; 337 } 338 } 339 } 340 341 i++; 342 } 343 344 return aOutStr; 345 } 346 347 // ----------------------------------------------------------------------- 348 349 static void ImplPatternMaxPos( const XubString rStr, const ByteString& rEditMask, 350 sal_uInt16 nFormatFlags, sal_Bool bSameMask, 351 sal_uInt16 nCursorPos, sal_uInt16& rPos ) 352 { 353 354 // Letzte Position darf nicht groesser als der enthaltene String sein 355 xub_StrLen nMaxPos = rStr.Len(); 356 357 // Wenn keine leeren Literale erlaubt sind, auch Leerzeichen 358 // am Ende ignorieren 359 if ( bSameMask && !(nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS) ) 360 { 361 while ( nMaxPos ) 362 { 363 if ( (rEditMask.GetChar(nMaxPos-1) != EDITMASK_LITERAL) && 364 (rStr.GetChar(nMaxPos-1) != ' ') ) 365 break; 366 nMaxPos--; 367 } 368 369 // Wenn wir vor einem Literal stehen, dann solange weitersuchen, 370 // bis erste Stelle nach Literal 371 xub_StrLen nTempPos = nMaxPos; 372 while ( nTempPos < rEditMask.Len() ) 373 { 374 if ( rEditMask.GetChar(nTempPos) != EDITMASK_LITERAL ) 375 { 376 nMaxPos = nTempPos; 377 break; 378 } 379 nTempPos++; 380 } 381 } 382 383 if ( rPos > nMaxPos ) 384 rPos = nMaxPos; 385 // Zeichen sollte nicht nach links wandern 386 if ( rPos < nCursorPos ) 387 rPos = nCursorPos; 388 } 389 390 // ----------------------------------------------------------------------- 391 392 static void ImplPatternProcessStrictModify( Edit* pEdit, 393 const ByteString& rEditMask, 394 const XubString& rLiteralMask, 395 sal_uInt16 nFormatFlags, sal_Bool bSameMask ) 396 { 397 XubString aText = pEdit->GetText(); 398 399 // Leerzeichen am Anfang entfernen 400 if ( bSameMask && !(nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS) ) 401 { 402 xub_StrLen i = 0; 403 xub_StrLen nMaxLen = aText.Len(); 404 while ( i < nMaxLen ) 405 { 406 if ( (rEditMask.GetChar( i ) != EDITMASK_LITERAL) && 407 (aText.GetChar( i ) != ' ') ) 408 break; 409 410 i++; 411 } 412 // Alle Literalzeichen beibehalten 413 while ( i && (rEditMask.GetChar( i ) == EDITMASK_LITERAL) ) 414 i--; 415 aText.Erase( 0, i ); 416 } 417 418 XubString aNewText = ImplPatternReformat( aText, rEditMask, rLiteralMask, nFormatFlags ); 419 if ( aNewText != aText ) 420 { 421 // Selection so anpassen, das diese wenn sie vorher am Ende 422 // stand, immer noch am Ende steht 423 Selection aSel = pEdit->GetSelection(); 424 sal_uLong nMaxSel = Max( aSel.Min(), aSel.Max() ); 425 if ( nMaxSel >= aText.Len() ) 426 { 427 xub_StrLen nMaxPos = aNewText.Len(); 428 ImplPatternMaxPos( aNewText, rEditMask, nFormatFlags, bSameMask, (xub_StrLen)nMaxSel, nMaxPos ); 429 if ( aSel.Min() == aSel.Max() ) 430 { 431 aSel.Min() = nMaxPos; 432 aSel.Max() = aSel.Min(); 433 } 434 else if ( aSel.Min() > aSel.Max() ) 435 aSel.Min() = nMaxPos; 436 else 437 aSel.Max() = nMaxPos; 438 } 439 pEdit->SetText( aNewText, aSel ); 440 } 441 } 442 443 // ----------------------------------------------------------------------- 444 445 static xub_StrLen ImplPatternLeftPos( const ByteString& rEditMask, xub_StrLen nCursorPos ) 446 { 447 // Vorheriges Zeichen suchen, was kein Literal ist 448 xub_StrLen nNewPos = nCursorPos; 449 xub_StrLen nTempPos = nNewPos; 450 while ( nTempPos ) 451 { 452 if ( rEditMask.GetChar(nTempPos-1) != EDITMASK_LITERAL ) 453 { 454 nNewPos = nTempPos-1; 455 break; 456 } 457 nTempPos--; 458 } 459 return nNewPos; 460 } 461 462 // ----------------------------------------------------------------------- 463 464 static xub_StrLen ImplPatternRightPos( const XubString& rStr, const ByteString& rEditMask, 465 sal_uInt16 nFormatFlags, sal_Bool bSameMask, 466 xub_StrLen nCursorPos ) 467 { 468 // Naechstes Zeichen suchen, was kein Literal ist 469 xub_StrLen nNewPos = nCursorPos; 470 xub_StrLen nTempPos = nNewPos; 471 while ( nTempPos < rEditMask.Len() ) 472 { 473 if ( rEditMask.GetChar(nTempPos+1) != EDITMASK_LITERAL ) 474 { 475 nNewPos = nTempPos+1; 476 break; 477 } 478 nTempPos++; 479 } 480 ImplPatternMaxPos( rStr, rEditMask, nFormatFlags, bSameMask, nCursorPos, nNewPos ); 481 return nNewPos; 482 } 483 484 // ----------------------------------------------------------------------- 485 486 static sal_Bool ImplPatternProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt, 487 const ByteString& rEditMask, 488 const XubString& rLiteralMask, 489 sal_Bool bStrictFormat, 490 sal_uInt16 nFormatFlags, 491 sal_Bool bSameMask, 492 sal_Bool& rbInKeyInput ) 493 { 494 if ( !rEditMask.Len() || !bStrictFormat ) 495 return sal_False; 496 497 Selection aOldSel = pEdit->GetSelection(); 498 KeyCode aCode = rKEvt.GetKeyCode(); 499 xub_Unicode cChar = rKEvt.GetCharCode(); 500 sal_uInt16 nKeyCode = aCode.GetCode(); 501 sal_Bool bShift = aCode.IsShift(); 502 xub_StrLen nCursorPos = (xub_StrLen)aOldSel.Max(); 503 xub_StrLen nNewPos; 504 xub_StrLen nTempPos; 505 506 if ( nKeyCode && !aCode.IsMod1() && !aCode.IsMod2() ) 507 { 508 if ( nKeyCode == KEY_LEFT ) 509 { 510 Selection aSel( ImplPatternLeftPos( rEditMask, nCursorPos ) ); 511 if ( bShift ) 512 aSel.Min() = aOldSel.Min(); 513 pEdit->SetSelection( aSel ); 514 return sal_True; 515 } 516 else if ( nKeyCode == KEY_RIGHT ) 517 { 518 // Hier nehmen wir Selectionsanfang als minimum, da falls durch 519 // Focus alles selektiert ist, ist eine kleine Position schon 520 // erlaubt. 521 Selection aSel( aOldSel ); 522 aSel.Justify(); 523 nCursorPos = (xub_StrLen)aSel.Min(); 524 aSel.Max() = ImplPatternRightPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nCursorPos ); 525 if ( bShift ) 526 aSel.Min() = aOldSel.Min(); 527 else 528 aSel.Min() = aSel.Max(); 529 pEdit->SetSelection( aSel ); 530 return sal_True; 531 } 532 else if ( nKeyCode == KEY_HOME ) 533 { 534 // Home ist Position des ersten nicht literalen Zeichens 535 nNewPos = 0; 536 while ( (nNewPos < rEditMask.Len()) && 537 (rEditMask.GetChar(nNewPos) == EDITMASK_LITERAL) ) 538 nNewPos++; 539 // Home sollte nicht nach rechts wandern 540 if ( nCursorPos < nNewPos ) 541 nNewPos = nCursorPos; 542 Selection aSel( nNewPos ); 543 if ( bShift ) 544 aSel.Min() = aOldSel.Min(); 545 pEdit->SetSelection( aSel ); 546 return sal_True; 547 } 548 else if ( nKeyCode == KEY_END ) 549 { 550 // End ist die Position des letzten nicht literalen Zeichens 551 nNewPos = rEditMask.Len(); 552 while ( nNewPos && 553 (rEditMask.GetChar(nNewPos-1) == EDITMASK_LITERAL) ) 554 nNewPos--; 555 // Hier nehmen wir Selectionsanfang als minimum, da falls durch 556 // Focus alles selektiert ist, ist eine kleine Position schon 557 // erlaubt. 558 Selection aSel( aOldSel ); 559 aSel.Justify(); 560 nCursorPos = (xub_StrLen)aSel.Min(); 561 ImplPatternMaxPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nCursorPos, nNewPos ); 562 aSel.Max() = nNewPos; 563 if ( bShift ) 564 aSel.Min() = aOldSel.Min(); 565 else 566 aSel.Min() = aSel.Max(); 567 pEdit->SetSelection( aSel ); 568 return sal_True; 569 } 570 else if ( (nKeyCode == KEY_BACKSPACE) || (nKeyCode == KEY_DELETE) ) 571 { 572 XubString aStr( pEdit->GetText() ); 573 XubString aOldStr = aStr; 574 Selection aSel = aOldSel; 575 576 aSel.Justify(); 577 nNewPos = (xub_StrLen)aSel.Min(); 578 579 // Wenn Selection, dann diese Loeschen 580 if ( aSel.Len() ) 581 { 582 if ( bSameMask ) 583 aStr.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() ); 584 else 585 { 586 XubString aRep = rLiteralMask.Copy( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() ); 587 aStr.Replace( (xub_StrLen)aSel.Min(), aRep.Len(), aRep ); 588 } 589 } 590 else 591 { 592 if ( nKeyCode == KEY_BACKSPACE ) 593 { 594 nTempPos = nNewPos; 595 nNewPos = ImplPatternLeftPos( rEditMask, nTempPos ); 596 } 597 else 598 nTempPos = ImplPatternRightPos( aStr, rEditMask, nFormatFlags, bSameMask, nNewPos ); 599 600 if ( nNewPos != nTempPos ) 601 { 602 if ( bSameMask ) 603 { 604 if ( rEditMask.GetChar( nNewPos ) != EDITMASK_LITERAL ) 605 aStr.Erase( nNewPos, 1 ); 606 } 607 else 608 { 609 XubString aTempStr = rLiteralMask.Copy( nNewPos, 1 ); 610 aStr.Replace( nNewPos, aTempStr.Len(), aTempStr ); 611 } 612 } 613 } 614 615 if ( aOldStr != aStr ) 616 { 617 if ( bSameMask ) 618 aStr = ImplPatternReformat( aStr, rEditMask, rLiteralMask, nFormatFlags ); 619 rbInKeyInput = sal_True; 620 pEdit->SetText( aStr, Selection( nNewPos ) ); 621 pEdit->SetModifyFlag(); 622 pEdit->Modify(); 623 rbInKeyInput = sal_False; 624 } 625 else 626 pEdit->SetSelection( Selection( nNewPos ) ); 627 628 return sal_True; 629 } 630 else if ( nKeyCode == KEY_INSERT ) 631 { 632 // InsertModus kann man beim PatternField nur einstellen, 633 // wenn Maske an jeder Eingabeposition die gleiche 634 // ist 635 if ( !bSameMask ) 636 { 637 Sound::Beep(); 638 return sal_True; 639 } 640 } 641 } 642 643 if ( rKEvt.GetKeyCode().IsMod2() || (cChar < 32) || (cChar == 127) ) 644 return sal_False; 645 646 Selection aSel = aOldSel; 647 aSel.Justify(); 648 nNewPos = (xub_StrLen)aSel.Min(); 649 650 if ( nNewPos < rEditMask.Len() ) 651 { 652 xub_Unicode cPattChar = ImplPatternChar( cChar, rEditMask.GetChar(nNewPos) ); 653 if ( cPattChar ) 654 cChar = cPattChar; 655 else 656 { 657 // Wenn kein gueltiges Zeichen, dann testen wir, ob der 658 // Anwender zum naechsten Literal springen wollte. Dies machen 659 // wir nur, wenn er hinter einem Zeichen steht, damit 660 // eingebene Literale die automatisch uebersprungenen wurden 661 // nicht dazu fuehren, das der Anwender dann da steht, wo 662 // er nicht stehen wollte. 663 if ( nNewPos && 664 (rEditMask.GetChar(nNewPos-1) != EDITMASK_LITERAL) && 665 !aSel.Len() ) 666 { 667 // Naechstes Zeichen suchen, was kein Literal ist 668 nTempPos = nNewPos; 669 while ( nTempPos < rEditMask.Len() ) 670 { 671 if ( rEditMask.GetChar(nTempPos) == EDITMASK_LITERAL ) 672 { 673 // Gilt nur, wenn ein Literalzeichen vorhanden 674 if ( (rEditMask.GetChar(nTempPos+1) != EDITMASK_LITERAL ) && 675 ImplKommaPointCharEqual( cChar, rLiteralMask.GetChar(nTempPos) ) ) 676 { 677 nTempPos++; 678 ImplPatternMaxPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nNewPos, nTempPos ); 679 if ( nTempPos > nNewPos ) 680 { 681 pEdit->SetSelection( Selection( nTempPos ) ); 682 return sal_True; 683 } 684 } 685 break; 686 } 687 nTempPos++; 688 } 689 } 690 691 cChar = 0; 692 } 693 } 694 else 695 cChar = 0; 696 if ( cChar ) 697 { 698 XubString aStr = pEdit->GetText(); 699 sal_Bool bError = sal_False; 700 if ( bSameMask && pEdit->IsInsertMode() ) 701 { 702 // Text um Spacezeichen und Literale am Ende kuerzen, bis zur 703 // aktuellen Position 704 xub_StrLen n = aStr.Len(); 705 while ( n && (n > nNewPos) ) 706 { 707 if ( (aStr.GetChar( n-1 ) != ' ') && 708 ((n > rEditMask.Len()) || (rEditMask.GetChar(n-1) != EDITMASK_LITERAL)) ) 709 break; 710 711 n--; 712 } 713 aStr.Erase( n ); 714 715 if ( aSel.Len() ) 716 aStr.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() ); 717 718 if ( aStr.Len() < rEditMask.Len() ) 719 { 720 // String evtl. noch bis Cursor-Position erweitern 721 if ( aStr.Len() < nNewPos ) 722 aStr += rLiteralMask.Copy( aStr.Len(), nNewPos-aStr.Len() ); 723 if ( nNewPos < aStr.Len() ) 724 aStr.Insert( cChar, nNewPos ); 725 else if ( nNewPos < rEditMask.Len() ) 726 aStr += cChar; 727 aStr = ImplPatternReformat( aStr, rEditMask, rLiteralMask, nFormatFlags ); 728 } 729 else 730 bError = sal_True; 731 } 732 else 733 { 734 if ( aSel.Len() ) 735 { 736 // Selection loeschen 737 XubString aRep = rLiteralMask.Copy( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() ); 738 aStr.Replace( (xub_StrLen)aSel.Min(), aRep.Len(), aRep ); 739 } 740 741 if ( nNewPos < aStr.Len() ) 742 aStr.SetChar( nNewPos, cChar ); 743 else if ( nNewPos < rEditMask.Len() ) 744 aStr += cChar; 745 } 746 747 if ( bError ) 748 Sound::Beep(); 749 else 750 { 751 rbInKeyInput = sal_True; 752 Selection aNewSel( ImplPatternRightPos( aStr, rEditMask, nFormatFlags, bSameMask, nNewPos ) ); 753 pEdit->SetText( aStr, aNewSel ); 754 pEdit->SetModifyFlag(); 755 pEdit->Modify(); 756 rbInKeyInput = sal_False; 757 } 758 } 759 else 760 Sound::Beep(); 761 762 return sal_True; 763 } 764 765 // ----------------------------------------------------------------------- 766 767 void PatternFormatter::ImplSetMask( const ByteString& rEditMask, 768 const XubString& rLiteralMask ) 769 { 770 maEditMask = rEditMask; 771 maLiteralMask = rLiteralMask; 772 mbSameMask = sal_True; 773 774 if ( maEditMask.Len() != maLiteralMask.Len() ) 775 { 776 if ( maEditMask.Len() < maLiteralMask.Len() ) 777 maLiteralMask.Erase( maEditMask.Len() ); 778 else 779 maLiteralMask.Expand( maEditMask.Len(), ' ' ); 780 } 781 782 // StrictModus erlaubt nur Input-Mode, wenn als Maske nur 783 // gleiche Zeichen zugelassen werden und als Vorgabe nur 784 // Spacezeichen vorgegeben werden, die durch die Maske 785 // nicht zugelassen sind 786 xub_StrLen i = 0; 787 sal_Char c = 0; 788 while ( i < rEditMask.Len() ) 789 { 790 sal_Char cTemp = rEditMask.GetChar( i ); 791 if ( cTemp != EDITMASK_LITERAL ) 792 { 793 if ( (cTemp == EDITMASK_ALLCHAR) || 794 (cTemp == EDITMASK_UPPERALLCHAR) || 795 (cTemp == EDITMASK_NUMSPACE) ) 796 { 797 mbSameMask = sal_False; 798 break; 799 } 800 if ( i < rLiteralMask.Len() ) 801 { 802 if ( rLiteralMask.GetChar( i ) != ' ' ) 803 { 804 mbSameMask = sal_False; 805 break; 806 } 807 } 808 if ( !c ) 809 c = cTemp; 810 if ( cTemp != c ) 811 { 812 mbSameMask = sal_False; 813 break; 814 } 815 } 816 i++; 817 } 818 } 819 820 // ----------------------------------------------------------------------- 821 822 PatternFormatter::PatternFormatter() 823 { 824 mnFormatFlags = 0; 825 mbSameMask = sal_True; 826 mbInPattKeyInput = sal_False; 827 } 828 829 // ----------------------------------------------------------------------- 830 831 void PatternFormatter::ImplLoadRes( const ResId& rResId ) 832 { 833 ByteString aEditMask; 834 XubString aLiteralMask; 835 ResMgr* pMgr = rResId.GetResMgr(); 836 if( pMgr ) 837 { 838 sal_uLong nMask = pMgr->ReadLong(); 839 840 if ( PATTERNFORMATTER_STRICTFORMAT & nMask ) 841 SetStrictFormat( (sal_Bool)pMgr->ReadShort() ); 842 843 if ( PATTERNFORMATTER_EDITMASK & nMask ) 844 aEditMask = ByteString( pMgr->ReadString(), RTL_TEXTENCODING_ASCII_US ); 845 846 if ( PATTERNFORMATTER_LITTERALMASK & nMask ) 847 aLiteralMask = pMgr->ReadString(); 848 849 if ( (PATTERNFORMATTER_EDITMASK | PATTERNFORMATTER_LITTERALMASK) & nMask ) 850 ImplSetMask( aEditMask, aLiteralMask ); 851 } 852 } 853 854 // ----------------------------------------------------------------------- 855 856 PatternFormatter::~PatternFormatter() 857 { 858 } 859 860 // ----------------------------------------------------------------------- 861 862 void PatternFormatter::SetMask( const ByteString& rEditMask, 863 const XubString& rLiteralMask ) 864 { 865 ImplSetMask( rEditMask, rLiteralMask ); 866 ReformatAll(); 867 } 868 869 // ----------------------------------------------------------------------- 870 871 void PatternFormatter::SetString( const XubString& rStr ) 872 { 873 maFieldString = rStr; 874 if ( GetField() ) 875 { 876 GetField()->SetText( rStr ); 877 MarkToBeReformatted( sal_False ); 878 } 879 } 880 881 // ----------------------------------------------------------------------- 882 883 XubString PatternFormatter::GetString() const 884 { 885 if ( !GetField() ) 886 return ImplGetSVEmptyStr(); 887 else 888 return ImplPatternReformat( GetField()->GetText(), maEditMask, maLiteralMask, mnFormatFlags ); 889 } 890 891 // ----------------------------------------------------------------------- 892 893 void PatternFormatter::Reformat() 894 { 895 if ( GetField() ) 896 { 897 ImplSetText( ImplPatternReformat( GetField()->GetText(), maEditMask, maLiteralMask, mnFormatFlags ) ); 898 if ( !mbSameMask && IsStrictFormat() && !GetField()->IsReadOnly() ) 899 GetField()->SetInsertMode( sal_False ); 900 } 901 } 902 903 // ----------------------------------------------------------------------- 904 905 void PatternFormatter::SelectFixedFont() 906 { 907 if ( GetField() ) 908 { 909 Font aFont = OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, Application::GetSettings().GetLanguage(), 0 ); 910 Font aControlFont; 911 aControlFont.SetName( aFont.GetName() ); 912 aControlFont.SetFamily( aFont.GetFamily() ); 913 aControlFont.SetPitch( aFont.GetPitch() ); 914 GetField()->SetControlFont( aControlFont ); 915 } 916 } 917 918 // ----------------------------------------------------------------------- 919 920 PatternField::PatternField( Window* pParent, WinBits nWinStyle ) : 921 SpinField( pParent, nWinStyle ) 922 { 923 SetField( this ); 924 Reformat(); 925 } 926 927 // ----------------------------------------------------------------------- 928 929 PatternField::PatternField( Window* pParent, const ResId& rResId ) : 930 SpinField( WINDOW_PATTERNFIELD ) 931 { 932 rResId.SetRT( RSC_PATTERNFIELD ); 933 WinBits nStyle = ImplInitRes( rResId ); 934 ImplInit( pParent, nStyle ); 935 SetField( this ); 936 SpinField::ImplLoadRes( rResId ); 937 PatternFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 938 Reformat(); 939 940 if ( !(nStyle & WB_HIDE ) ) 941 Show(); 942 } 943 944 // ----------------------------------------------------------------------- 945 946 PatternField::~PatternField() 947 { 948 } 949 950 // ----------------------------------------------------------------------- 951 952 long PatternField::PreNotify( NotifyEvent& rNEvt ) 953 { 954 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 955 { 956 if ( ImplPatternProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetEditMask(), GetLiteralMask(), 957 IsStrictFormat(), GetFormatFlags(), 958 ImplIsSameMask(), ImplGetInPattKeyInput() ) ) 959 return 1; 960 } 961 962 return SpinField::PreNotify( rNEvt ); 963 } 964 965 // ----------------------------------------------------------------------- 966 967 long PatternField::Notify( NotifyEvent& rNEvt ) 968 { 969 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 970 MarkToBeReformatted( sal_False ); 971 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 972 { 973 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 974 Reformat(); 975 } 976 977 return SpinField::Notify( rNEvt ); 978 } 979 980 // ----------------------------------------------------------------------- 981 982 void PatternField::Modify() 983 { 984 if ( !ImplGetInPattKeyInput() ) 985 { 986 if ( IsStrictFormat() ) 987 ImplPatternProcessStrictModify( GetField(), GetEditMask(), GetLiteralMask(), GetFormatFlags(), ImplIsSameMask() ); 988 else 989 MarkToBeReformatted( sal_True ); 990 } 991 992 SpinField::Modify(); 993 } 994 995 // ----------------------------------------------------------------------- 996 997 PatternBox::PatternBox( Window* pParent, WinBits nWinStyle ) : 998 ComboBox( pParent, nWinStyle ) 999 { 1000 SetField( this ); 1001 Reformat(); 1002 } 1003 1004 // ----------------------------------------------------------------------- 1005 1006 PatternBox::PatternBox( Window* pParent, const ResId& rResId ) : 1007 ComboBox( WINDOW_PATTERNBOX ) 1008 { 1009 rResId.SetRT( RSC_PATTERNBOX ); 1010 WinBits nStyle = ImplInitRes( rResId ); 1011 ImplInit( pParent, nStyle ); 1012 1013 SetField( this ); 1014 ComboBox::ImplLoadRes( rResId ); 1015 PatternFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); 1016 Reformat(); 1017 1018 if ( !(nStyle & WB_HIDE ) ) 1019 Show(); 1020 } 1021 1022 // ----------------------------------------------------------------------- 1023 1024 PatternBox::~PatternBox() 1025 { 1026 } 1027 1028 // ----------------------------------------------------------------------- 1029 1030 long PatternBox::PreNotify( NotifyEvent& rNEvt ) 1031 { 1032 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 1033 { 1034 if ( ImplPatternProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetEditMask(), GetLiteralMask(), 1035 IsStrictFormat(), GetFormatFlags(), 1036 ImplIsSameMask(), ImplGetInPattKeyInput() ) ) 1037 return 1; 1038 } 1039 1040 return ComboBox::PreNotify( rNEvt ); 1041 } 1042 1043 // ----------------------------------------------------------------------- 1044 1045 long PatternBox::Notify( NotifyEvent& rNEvt ) 1046 { 1047 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 1048 MarkToBeReformatted( sal_False ); 1049 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 1050 { 1051 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 1052 Reformat(); 1053 } 1054 1055 return ComboBox::Notify( rNEvt ); 1056 } 1057 1058 // ----------------------------------------------------------------------- 1059 1060 void PatternBox::Modify() 1061 { 1062 if ( !ImplGetInPattKeyInput() ) 1063 { 1064 if ( IsStrictFormat() ) 1065 ImplPatternProcessStrictModify( GetField(), GetEditMask(), GetLiteralMask(), GetFormatFlags(), ImplIsSameMask() ); 1066 else 1067 MarkToBeReformatted( sal_True ); 1068 } 1069 1070 ComboBox::Modify(); 1071 } 1072 1073 // ----------------------------------------------------------------------- 1074 1075 void PatternBox::ReformatAll() 1076 { 1077 XubString aStr; 1078 SetUpdateMode( sal_False ); 1079 sal_uInt16 nEntryCount = GetEntryCount(); 1080 for ( sal_uInt16 i=0; i < nEntryCount; i++ ) 1081 { 1082 aStr = ImplPatternReformat( GetEntry( i ), GetEditMask(), GetLiteralMask(), GetFormatFlags() ); 1083 RemoveEntry( i ); 1084 InsertEntry( aStr, i ); 1085 } 1086 PatternFormatter::Reformat(); 1087 SetUpdateMode( sal_True ); 1088 } 1089 1090 // ----------------------------------------------------------------------- 1091 1092 void PatternBox::InsertString( const XubString& rStr, sal_uInt16 nPos ) 1093 { 1094 ComboBox::InsertEntry( ImplPatternReformat( rStr, GetEditMask(), GetLiteralMask(), GetFormatFlags() ), nPos ); 1095 } 1096 1097 // ----------------------------------------------------------------------- 1098 1099 void PatternBox::RemoveString( const XubString& rStr ) 1100 { 1101 ComboBox::RemoveEntry( ImplPatternReformat( rStr, GetEditMask(), GetLiteralMask(), GetFormatFlags() ) ); 1102 } 1103 1104 // ----------------------------------------------------------------------- 1105 1106 XubString PatternBox::GetString( sal_uInt16 nPos ) const 1107 { 1108 return ImplPatternReformat( ComboBox::GetEntry( nPos ), GetEditMask(), GetLiteralMask(), GetFormatFlags() ); 1109 } 1110 1111 // ----------------------------------------------------------------------- 1112 1113 sal_uInt16 PatternBox::GetStringPos( const XubString& rStr ) const 1114 { 1115 return ComboBox::GetEntryPos( ImplPatternReformat( rStr, GetEditMask(), GetLiteralMask(), GetFormatFlags() ) ); 1116 } 1117 1118 // ======================================================================= 1119 1120 static ExtDateFieldFormat ImplGetExtFormat( DateFormat eOld ) 1121 { 1122 switch( eOld ) 1123 { 1124 case DMY: return XTDATEF_SHORT_DDMMYY; 1125 case MDY: return XTDATEF_SHORT_MMDDYY; 1126 default: return XTDATEF_SHORT_YYMMDD; 1127 } 1128 } 1129 1130 // ----------------------------------------------------------------------- 1131 1132 static sal_uInt16 ImplCutNumberFromString( XubString& rStr ) 1133 { 1134 // Nach Zahl suchen 1135 while ( rStr.Len() && !(rStr.GetChar( 0 ) >= '0' && rStr.GetChar( 0 ) <= '9') ) 1136 rStr.Erase( 0, 1 ); 1137 if ( !rStr.Len() ) 1138 return 0; 1139 XubString aNumStr; 1140 while ( rStr.Len() && (rStr.GetChar( 0 ) >= '0' && rStr.GetChar( 0 ) <= '9') ) 1141 { 1142 aNumStr.Insert( rStr.GetChar( 0 ) ); 1143 rStr.Erase( 0, 1 ); 1144 } 1145 return (sal_uInt16)aNumStr.ToInt32(); 1146 } 1147 1148 // ----------------------------------------------------------------------- 1149 1150 static sal_Bool ImplCutMonthName( XubString& rStr, const XubString& _rLookupMonthName ) 1151 { 1152 sal_uInt16 nPos = rStr.Search( _rLookupMonthName ); 1153 if ( nPos != STRING_NOTFOUND ) 1154 { 1155 rStr.Erase( 0, nPos + _rLookupMonthName.Len() ); 1156 return sal_True; 1157 } 1158 return sal_False; 1159 } 1160 1161 // ----------------------------------------------------------------------- 1162 1163 static sal_uInt16 ImplCutMonthFromString( XubString& rStr, const CalendarWrapper& rCalendarWrapper ) 1164 { 1165 // search for a month' name 1166 for ( sal_uInt16 i=1; i <= 12; i++ ) 1167 { 1168 String aMonthName = rCalendarWrapper.getMonths()[i-1].FullName; 1169 // long month name? 1170 if ( ImplCutMonthName( rStr, aMonthName ) ) 1171 return i; 1172 1173 // short month name? 1174 String aAbbrevMonthName = rCalendarWrapper.getMonths()[i-1].AbbrevName; 1175 if ( ImplCutMonthName( rStr, aAbbrevMonthName ) ) 1176 return i; 1177 } 1178 1179 return ImplCutNumberFromString( rStr ); 1180 } 1181 1182 // ----------------------------------------------------------------------- 1183 1184 static String ImplGetDateSep( const LocaleDataWrapper& rLocaleDataWrapper, ExtDateFieldFormat eFormat ) 1185 { 1186 String aDateSep = rLocaleDataWrapper.getDateSep(); 1187 1188 if ( ( eFormat == XTDATEF_SHORT_YYMMDD_DIN5008 ) || ( eFormat == XTDATEF_SHORT_YYYYMMDD_DIN5008 ) ) 1189 aDateSep = String( RTL_CONSTASCII_USTRINGPARAM( "-" ) ); 1190 1191 return aDateSep; 1192 } 1193 1194 static sal_Bool ImplDateProcessKeyInput( Edit*, const KeyEvent& rKEvt, ExtDateFieldFormat eFormat, 1195 const LocaleDataWrapper& rLocaleDataWrapper ) 1196 { 1197 xub_Unicode cChar = rKEvt.GetCharCode(); 1198 sal_uInt16 nGroup = rKEvt.GetKeyCode().GetGroup(); 1199 if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) || 1200 (nGroup == KEYGROUP_MISC)|| 1201 ((cChar >= '0') && (cChar <= '9')) || 1202 (cChar == ImplGetDateSep( rLocaleDataWrapper, eFormat ).GetChar(0) ) ) 1203 return sal_False; 1204 else 1205 return sal_True; 1206 } 1207 1208 // ----------------------------------------------------------------------- 1209 1210 static sal_Bool ImplDateGetValue( const XubString& rStr, Date& rDate, ExtDateFieldFormat eDateFormat, 1211 const LocaleDataWrapper& rLocaleDataWrapper, const CalendarWrapper& rCalendarWrapper, 1212 const AllSettings& ) 1213 { 1214 sal_uInt16 nDay = 0; 1215 sal_uInt16 nMonth = 0; 1216 sal_uInt16 nYear = 0; 1217 sal_Bool bYear = sal_True; 1218 sal_Bool bError = sal_False; 1219 String aStr( rStr ); 1220 1221 if ( eDateFormat == XTDATEF_SYSTEM_LONG ) 1222 { 1223 DateFormat eFormat = rLocaleDataWrapper.getLongDateFormat(); 1224 switch( eFormat ) 1225 { 1226 case MDY: 1227 nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper ); 1228 nDay = ImplCutNumberFromString( aStr ); 1229 nYear = ImplCutNumberFromString( aStr ); 1230 break; 1231 case DMY: 1232 nDay = ImplCutNumberFromString( aStr ); 1233 nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper ); 1234 nYear = ImplCutNumberFromString( aStr ); 1235 break; 1236 case YMD: 1237 default: 1238 nYear = ImplCutNumberFromString( aStr ); 1239 nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper ); 1240 nDay = ImplCutNumberFromString( aStr ); 1241 break; 1242 } 1243 } 1244 else 1245 { 1246 // Check if year is present: 1247 String aDateSep = ImplGetDateSep( rLocaleDataWrapper, eDateFormat ); 1248 sal_uInt16 nSepPos = aStr.Search( aDateSep ); 1249 if ( nSepPos == STRING_NOTFOUND ) 1250 return sal_False; 1251 nSepPos = aStr.Search( aDateSep, nSepPos+1 ); 1252 if ( ( nSepPos == STRING_NOTFOUND ) || ( nSepPos == (aStr.Len()-1) ) ) 1253 { 1254 bYear = sal_False; 1255 nYear = Date().GetYear(); 1256 } 1257 1258 const sal_Unicode* pBuf = aStr.GetBuffer(); 1259 ImplSkipDelimiters( pBuf ); 1260 1261 switch ( eDateFormat ) 1262 { 1263 case XTDATEF_SHORT_DDMMYY: 1264 case XTDATEF_SHORT_DDMMYYYY: 1265 { 1266 nDay = ImplGetNum( pBuf, bError ); 1267 ImplSkipDelimiters( pBuf ); 1268 nMonth = ImplGetNum( pBuf, bError ); 1269 ImplSkipDelimiters( pBuf ); 1270 if ( bYear ) 1271 nYear = ImplGetNum( pBuf, bError ); 1272 } 1273 break; 1274 case XTDATEF_SHORT_MMDDYY: 1275 case XTDATEF_SHORT_MMDDYYYY: 1276 { 1277 nMonth = ImplGetNum( pBuf, bError ); 1278 ImplSkipDelimiters( pBuf ); 1279 nDay = ImplGetNum( pBuf, bError ); 1280 ImplSkipDelimiters( pBuf ); 1281 if ( bYear ) 1282 nYear = ImplGetNum( pBuf, bError ); 1283 } 1284 break; 1285 case XTDATEF_SHORT_YYMMDD: 1286 case XTDATEF_SHORT_YYYYMMDD: 1287 case XTDATEF_SHORT_YYMMDD_DIN5008: 1288 case XTDATEF_SHORT_YYYYMMDD_DIN5008: 1289 { 1290 if ( bYear ) 1291 nYear = ImplGetNum( pBuf, bError ); 1292 ImplSkipDelimiters( pBuf ); 1293 nMonth = ImplGetNum( pBuf, bError ); 1294 ImplSkipDelimiters( pBuf ); 1295 nDay = ImplGetNum( pBuf, bError ); 1296 } 1297 break; 1298 1299 default: 1300 { 1301 DBG_ERROR( "DateFormat???" ); 1302 } 1303 } 1304 } 1305 1306 if ( bError || !nDay || !nMonth ) 1307 return sal_False; 1308 1309 Date aNewDate( nDay, nMonth, nYear ); 1310 DateFormatter::ExpandCentury( aNewDate, utl::MiscCfg().GetYear2000() ); 1311 if ( aNewDate.IsValid() ) 1312 { 1313 rDate = aNewDate; 1314 return sal_True; 1315 } 1316 return sal_False; 1317 } 1318 1319 // ----------------------------------------------------------------------- 1320 1321 sal_Bool DateFormatter::ImplDateReformat( const XubString& rStr, XubString& rOutStr, const AllSettings& rSettings ) 1322 { 1323 Date aDate( 0, 0, 0 ); 1324 if ( !ImplDateGetValue( rStr, aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) ) 1325 return sal_True; 1326 1327 Date aTempDate = aDate; 1328 if ( aTempDate > GetMax() ) 1329 aTempDate = GetMax(); 1330 else if ( aTempDate < GetMin() ) 1331 aTempDate = GetMin(); 1332 1333 if ( GetErrorHdl().IsSet() && (aDate != aTempDate) ) 1334 { 1335 maCorrectedDate = aTempDate; 1336 if( !GetErrorHdl().Call( this ) ) 1337 { 1338 maCorrectedDate = Date(); 1339 return sal_False; 1340 } 1341 else 1342 maCorrectedDate = Date(); 1343 } 1344 1345 rOutStr = ImplGetDateAsText( aTempDate, rSettings ); 1346 1347 return sal_True; 1348 } 1349 1350 // ----------------------------------------------------------------------- 1351 1352 XubString DateFormatter::ImplGetDateAsText( const Date& rDate, 1353 const AllSettings& ) const 1354 { 1355 sal_Bool bShowCentury = sal_False; 1356 switch ( GetExtDateFormat() ) 1357 { 1358 case XTDATEF_SYSTEM_SHORT_YYYY: 1359 case XTDATEF_SYSTEM_LONG: 1360 case XTDATEF_SHORT_DDMMYYYY: 1361 case XTDATEF_SHORT_MMDDYYYY: 1362 case XTDATEF_SHORT_YYYYMMDD: 1363 case XTDATEF_SHORT_YYYYMMDD_DIN5008: 1364 { 1365 bShowCentury = sal_True; 1366 } 1367 break; 1368 default: 1369 { 1370 bShowCentury = sal_False; 1371 } 1372 } 1373 1374 if ( !bShowCentury ) 1375 { 1376 // Check if I have to use force showing the century 1377 sal_uInt16 nTwoDigitYearStart = utl::MiscCfg().GetYear2000(); 1378 sal_uInt16 nYear = rDate.GetYear(); 1379 1380 // Wenn Jahr nicht im 2stelligen Grenzbereich liegt, 1381 if ( (nYear < nTwoDigitYearStart) || (nYear >= nTwoDigitYearStart+100) ) 1382 bShowCentury = sal_True; 1383 } 1384 1385 sal_Unicode aBuf[128]; 1386 sal_Unicode* pBuf = aBuf; 1387 1388 String aDateSep = ImplGetDateSep( ImplGetLocaleDataWrapper(), GetExtDateFormat( sal_True ) ); 1389 sal_uInt16 nDay = rDate.GetDay(); 1390 sal_uInt16 nMonth = rDate.GetMonth(); 1391 sal_uInt16 nYear = rDate.GetYear(); 1392 sal_uInt16 nYearLen = bShowCentury ? 4 : 2; 1393 1394 if ( !bShowCentury ) 1395 nYear %= 100; 1396 1397 switch ( GetExtDateFormat( sal_True ) ) 1398 { 1399 case XTDATEF_SYSTEM_LONG: 1400 { 1401 return ImplGetLocaleDataWrapper().getLongDate( rDate, GetCalendarWrapper(), 1, sal_False, 1, !bShowCentury ); 1402 } 1403 case XTDATEF_SHORT_DDMMYY: 1404 case XTDATEF_SHORT_DDMMYYYY: 1405 { 1406 pBuf = ImplAddNum( pBuf, nDay, 2 ); 1407 pBuf = ImplAddString( pBuf, aDateSep ); 1408 pBuf = ImplAddNum( pBuf, nMonth, 2 ); 1409 pBuf = ImplAddString( pBuf, aDateSep ); 1410 pBuf = ImplAddNum( pBuf, nYear, nYearLen ); 1411 } 1412 break; 1413 case XTDATEF_SHORT_MMDDYY: 1414 case XTDATEF_SHORT_MMDDYYYY: 1415 { 1416 pBuf = ImplAddNum( pBuf, nMonth, 2 ); 1417 pBuf = ImplAddString( pBuf, aDateSep ); 1418 pBuf = ImplAddNum( pBuf, nDay, 2 ); 1419 pBuf = ImplAddString( pBuf, aDateSep ); 1420 pBuf = ImplAddNum( pBuf, nYear, nYearLen ); 1421 } 1422 break; 1423 case XTDATEF_SHORT_YYMMDD: 1424 case XTDATEF_SHORT_YYYYMMDD: 1425 case XTDATEF_SHORT_YYMMDD_DIN5008: 1426 case XTDATEF_SHORT_YYYYMMDD_DIN5008: 1427 { 1428 pBuf = ImplAddNum( pBuf, nYear, nYearLen ); 1429 pBuf = ImplAddString( pBuf, aDateSep ); 1430 pBuf = ImplAddNum( pBuf, nMonth, 2 ); 1431 pBuf = ImplAddString( pBuf, aDateSep ); 1432 pBuf = ImplAddNum( pBuf, nDay, 2 ); 1433 } 1434 break; 1435 default: 1436 { 1437 DBG_ERROR( "DateFormat???" ); 1438 } 1439 } 1440 1441 return String( aBuf, (xub_StrLen)(sal_uLong)(pBuf-aBuf) ); 1442 } 1443 1444 // ----------------------------------------------------------------------- 1445 1446 static void ImplDateIncrementDay( Date& rDate, sal_Bool bUp ) 1447 { 1448 DateFormatter::ExpandCentury( rDate ); 1449 1450 if ( bUp ) 1451 { 1452 if ( (rDate.GetDay() != 31) || (rDate.GetMonth() != 12) || (rDate.GetYear() != 9999) ) 1453 rDate++; 1454 } 1455 else 1456 { 1457 if ( (rDate.GetDay() != 1 ) || (rDate.GetMonth() != 1) || (rDate.GetYear() != 0) ) 1458 rDate--; 1459 } 1460 } 1461 1462 // ----------------------------------------------------------------------- 1463 1464 static void ImplDateIncrementMonth( Date& rDate, sal_Bool bUp ) 1465 { 1466 DateFormatter::ExpandCentury( rDate ); 1467 1468 sal_uInt16 nMonth = rDate.GetMonth(); 1469 sal_uInt16 nYear = rDate.GetYear(); 1470 if ( bUp ) 1471 { 1472 if ( (nMonth == 12) && (nYear < 9999) ) 1473 { 1474 rDate.SetMonth( 1 ); 1475 rDate.SetYear( nYear + 1 ); 1476 } 1477 else 1478 { 1479 if ( nMonth < 12 ) 1480 rDate.SetMonth( nMonth + 1 ); 1481 } 1482 } 1483 else 1484 { 1485 if ( (nMonth == 1) && (nYear > 0) ) 1486 { 1487 rDate.SetMonth( 12 ); 1488 rDate.SetYear( nYear - 1 ); 1489 } 1490 else 1491 { 1492 if ( nMonth > 1 ) 1493 rDate.SetMonth( nMonth - 1 ); 1494 } 1495 } 1496 1497 sal_uInt16 nDaysInMonth = rDate.GetDaysInMonth(); 1498 if ( rDate.GetDay() > nDaysInMonth ) 1499 rDate.SetDay( nDaysInMonth ); 1500 } 1501 1502 // ----------------------------------------------------------------------- 1503 1504 static void ImplDateIncrementYear( Date& rDate, sal_Bool bUp ) 1505 { 1506 DateFormatter::ExpandCentury( rDate ); 1507 1508 sal_uInt16 nYear = rDate.GetYear(); 1509 if ( bUp ) 1510 { 1511 if ( nYear < 9999 ) 1512 rDate.SetYear( nYear + 1 ); 1513 } 1514 else 1515 { 1516 if ( nYear > 0 ) 1517 rDate.SetYear( nYear - 1 ); 1518 } 1519 } 1520 1521 // ----------------------------------------------------------------------- 1522 sal_Bool DateFormatter::ImplAllowMalformedInput() const 1523 { 1524 return !IsEnforceValidValue(); 1525 } 1526 1527 // ----------------------------------------------------------------------- 1528 1529 void DateField::ImplDateSpinArea( sal_Bool bUp ) 1530 { 1531 // Wenn alles selektiert ist, Tage hochzaehlen 1532 if ( GetField() ) 1533 { 1534 Date aDate( GetDate() ); 1535 Selection aSelection = GetField()->GetSelection(); 1536 aSelection.Justify(); 1537 XubString aText( GetText() ); 1538 if ( (xub_StrLen)aSelection.Len() == aText.Len() ) 1539 ImplDateIncrementDay( aDate, bUp ); 1540 else 1541 { 1542 xub_StrLen nDateArea = 0; 1543 1544 ExtDateFieldFormat eFormat = GetExtDateFormat( sal_True ); 1545 if ( eFormat == XTDATEF_SYSTEM_LONG ) 1546 { 1547 eFormat = ImplGetExtFormat( ImplGetLocaleDataWrapper().getLongDateFormat() ); 1548 nDateArea = 1; 1549 } 1550 else 1551 { 1552 // Area suchen 1553 xub_StrLen nPos = 0; 1554 String aDateSep = ImplGetDateSep( ImplGetLocaleDataWrapper(), eFormat ); 1555 for ( xub_StrLen i = 1; i <= 3; i++ ) 1556 { 1557 nPos = aText.Search( aDateSep, nPos ); 1558 if ( nPos >= (sal_uInt16)aSelection.Max() ) 1559 { 1560 nDateArea = i; 1561 break; 1562 } 1563 else 1564 nPos++; 1565 } 1566 } 1567 1568 1569 switch( eFormat ) 1570 { 1571 case XTDATEF_SHORT_MMDDYY: 1572 case XTDATEF_SHORT_MMDDYYYY: 1573 switch( nDateArea ) 1574 { 1575 case 1: ImplDateIncrementMonth( aDate, bUp ); 1576 break; 1577 case 2: ImplDateIncrementDay( aDate, bUp ); 1578 break; 1579 case 3: ImplDateIncrementYear( aDate, bUp ); 1580 break; 1581 } 1582 break; 1583 case XTDATEF_SHORT_DDMMYY: 1584 case XTDATEF_SHORT_DDMMYYYY: 1585 switch( nDateArea ) 1586 { 1587 case 1: ImplDateIncrementDay( aDate, bUp ); 1588 break; 1589 case 2: ImplDateIncrementMonth( aDate, bUp ); 1590 break; 1591 case 3: ImplDateIncrementYear( aDate, bUp ); 1592 break; 1593 } 1594 break; 1595 case XTDATEF_SHORT_YYMMDD: 1596 case XTDATEF_SHORT_YYYYMMDD: 1597 case XTDATEF_SHORT_YYMMDD_DIN5008: 1598 case XTDATEF_SHORT_YYYYMMDD_DIN5008: 1599 switch( nDateArea ) 1600 { 1601 case 1: ImplDateIncrementYear( aDate, bUp ); 1602 break; 1603 case 2: ImplDateIncrementMonth( aDate, bUp ); 1604 break; 1605 case 3: ImplDateIncrementDay( aDate, bUp ); 1606 break; 1607 } 1608 break; 1609 default: 1610 DBG_ERROR( "invalid conversion" ); 1611 break; 1612 } 1613 } 1614 1615 ImplNewFieldValue( aDate ); 1616 } 1617 } 1618 1619 // ----------------------------------------------------------------------- 1620 1621 void DateFormatter::ImplInit() 1622 { 1623 mbLongFormat = sal_False; 1624 mbShowDateCentury = sal_True; 1625 mpCalendarWrapper = NULL; 1626 mnDateFormat = 0xFFFF; 1627 mnExtDateFormat = XTDATEF_SYSTEM_SHORT; 1628 } 1629 1630 // ----------------------------------------------------------------------- 1631 1632 DateFormatter::DateFormatter() : 1633 maFieldDate( 0 ), 1634 maLastDate( 0 ), 1635 maMin( 1, 1, 1900 ), 1636 maMax( 31, 12, 2200 ), 1637 mbEnforceValidValue( sal_True ) 1638 { 1639 ImplInit(); 1640 } 1641 1642 // ----------------------------------------------------------------------- 1643 1644 void DateFormatter::ImplLoadRes( const ResId& rResId ) 1645 { 1646 ResMgr* pMgr = rResId.GetResMgr(); 1647 if( pMgr ) 1648 { 1649 sal_uLong nMask = pMgr->ReadLong(); 1650 1651 if ( DATEFORMATTER_MIN & nMask ) 1652 { 1653 maMin = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ); 1654 pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) ); 1655 } 1656 if ( DATEFORMATTER_MAX & nMask ) 1657 { 1658 maMax = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ); 1659 pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) ); 1660 } 1661 if ( DATEFORMATTER_LONGFORMAT & nMask ) 1662 mbLongFormat = (sal_Bool)pMgr->ReadShort(); 1663 1664 if ( DATEFORMATTER_STRICTFORMAT & nMask ) 1665 SetStrictFormat( (sal_Bool)pMgr->ReadShort() ); 1666 1667 if ( DATEFORMATTER_VALUE & nMask ) 1668 { 1669 maFieldDate = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ); 1670 pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) ); 1671 if ( maFieldDate > maMax ) 1672 maFieldDate = maMax; 1673 if ( maFieldDate < maMin ) 1674 maFieldDate = maMin; 1675 maLastDate = maFieldDate; 1676 } 1677 } 1678 } 1679 1680 // ----------------------------------------------------------------------- 1681 1682 DateFormatter::~DateFormatter() 1683 { 1684 delete mpCalendarWrapper; 1685 mpCalendarWrapper = NULL; 1686 } 1687 1688 // ----------------------------------------------------------------------- 1689 1690 void DateFormatter::SetLocale( const ::com::sun::star::lang::Locale& rLocale ) 1691 { 1692 delete mpCalendarWrapper; 1693 mpCalendarWrapper = NULL; 1694 FormatterBase::SetLocale( rLocale ); 1695 } 1696 1697 1698 // ----------------------------------------------------------------------- 1699 1700 CalendarWrapper& DateFormatter::GetCalendarWrapper() const 1701 { 1702 if ( !mpCalendarWrapper ) 1703 { 1704 ((DateFormatter*)this)->mpCalendarWrapper = new CalendarWrapper( vcl::unohelper::GetMultiServiceFactory() ); 1705 mpCalendarWrapper->loadDefaultCalendar( GetLocale() ); 1706 } 1707 1708 return *mpCalendarWrapper; 1709 } 1710 1711 // ----------------------------------------------------------------------- 1712 1713 void DateFormatter::SetExtDateFormat( ExtDateFieldFormat eFormat ) 1714 { 1715 mnExtDateFormat = eFormat; 1716 ReformatAll(); 1717 } 1718 1719 // ----------------------------------------------------------------------- 1720 1721 ExtDateFieldFormat DateFormatter::GetExtDateFormat( sal_Bool bResolveSystemFormat ) const 1722 { 1723 ExtDateFieldFormat eDateFormat = (ExtDateFieldFormat)mnExtDateFormat; 1724 1725 if ( bResolveSystemFormat && ( eDateFormat <= XTDATEF_SYSTEM_SHORT_YYYY ) ) 1726 { 1727 sal_Bool bShowCentury = (eDateFormat == XTDATEF_SYSTEM_SHORT_YYYY); 1728 switch ( ImplGetLocaleDataWrapper().getDateFormat() ) 1729 { 1730 case DMY: eDateFormat = bShowCentury ? XTDATEF_SHORT_DDMMYYYY : XTDATEF_SHORT_DDMMYY; 1731 break; 1732 case MDY: eDateFormat = bShowCentury ? XTDATEF_SHORT_MMDDYYYY : XTDATEF_SHORT_MMDDYY; 1733 break; 1734 default: eDateFormat = bShowCentury ? XTDATEF_SHORT_YYYYMMDD : XTDATEF_SHORT_YYMMDD; 1735 1736 } 1737 } 1738 1739 return eDateFormat; 1740 } 1741 1742 // ----------------------------------------------------------------------- 1743 1744 void DateFormatter::ReformatAll() 1745 { 1746 Reformat(); 1747 } 1748 1749 // ----------------------------------------------------------------------- 1750 1751 void DateFormatter::SetMin( const Date& rNewMin ) 1752 { 1753 maMin = rNewMin; 1754 if ( !IsEmptyFieldValue() ) 1755 ReformatAll(); 1756 } 1757 1758 // ----------------------------------------------------------------------- 1759 1760 void DateFormatter::SetMax( const Date& rNewMax ) 1761 { 1762 maMax = rNewMax; 1763 if ( !IsEmptyFieldValue() ) 1764 ReformatAll(); 1765 } 1766 1767 // ----------------------------------------------------------------------- 1768 1769 void DateFormatter::SetLongFormat( sal_Bool bLong ) 1770 { 1771 mbLongFormat = bLong; 1772 1773 // #91913# Remove LongFormat and DateShowCentury - redundant 1774 if ( bLong ) 1775 { 1776 SetExtDateFormat( XTDATEF_SYSTEM_LONG ); 1777 } 1778 else 1779 { 1780 if( mnExtDateFormat == XTDATEF_SYSTEM_LONG ) 1781 SetExtDateFormat( XTDATEF_SYSTEM_SHORT ); 1782 } 1783 1784 ReformatAll(); 1785 } 1786 1787 // ----------------------------------------------------------------------- 1788 1789 void DateFormatter::SetShowDateCentury( sal_Bool bShowDateCentury ) 1790 { 1791 mbShowDateCentury = bShowDateCentury; 1792 1793 // #91913# Remove LongFormat and DateShowCentury - redundant 1794 if ( bShowDateCentury ) 1795 { 1796 switch ( GetExtDateFormat() ) 1797 { 1798 case XTDATEF_SYSTEM_SHORT: 1799 case XTDATEF_SYSTEM_SHORT_YY: 1800 SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY ); break; 1801 case XTDATEF_SHORT_DDMMYY: 1802 SetExtDateFormat( XTDATEF_SHORT_DDMMYYYY ); break; 1803 case XTDATEF_SHORT_MMDDYY: 1804 SetExtDateFormat( XTDATEF_SHORT_MMDDYYYY ); break; 1805 case XTDATEF_SHORT_YYMMDD: 1806 SetExtDateFormat( XTDATEF_SHORT_YYYYMMDD ); break; 1807 case XTDATEF_SHORT_YYMMDD_DIN5008: 1808 SetExtDateFormat( XTDATEF_SHORT_YYYYMMDD_DIN5008 ); break; 1809 default: 1810 ; 1811 } 1812 } 1813 else 1814 { 1815 switch ( GetExtDateFormat() ) 1816 { 1817 case XTDATEF_SYSTEM_SHORT: 1818 case XTDATEF_SYSTEM_SHORT_YYYY: 1819 SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YY ); break; 1820 case XTDATEF_SHORT_DDMMYYYY: 1821 SetExtDateFormat( XTDATEF_SHORT_DDMMYY ); break; 1822 case XTDATEF_SHORT_MMDDYYYY: 1823 SetExtDateFormat( XTDATEF_SHORT_MMDDYY ); break; 1824 case XTDATEF_SHORT_YYYYMMDD: 1825 SetExtDateFormat( XTDATEF_SHORT_YYMMDD ); break; 1826 case XTDATEF_SHORT_YYYYMMDD_DIN5008: 1827 SetExtDateFormat( XTDATEF_SHORT_YYMMDD_DIN5008 ); break; 1828 default: 1829 ; 1830 } 1831 } 1832 1833 ReformatAll(); 1834 } 1835 1836 // ----------------------------------------------------------------------- 1837 1838 void DateFormatter::SetDate( const Date& rNewDate ) 1839 { 1840 SetUserDate( rNewDate ); 1841 maFieldDate = maLastDate; 1842 maLastDate = GetDate(); 1843 } 1844 1845 // ----------------------------------------------------------------------- 1846 1847 void DateFormatter::SetUserDate( const Date& rNewDate ) 1848 { 1849 ImplSetUserDate( rNewDate ); 1850 } 1851 1852 // ----------------------------------------------------------------------- 1853 1854 void DateFormatter::ImplSetUserDate( const Date& rNewDate, Selection* pNewSelection ) 1855 { 1856 Date aNewDate = rNewDate; 1857 if ( aNewDate > maMax ) 1858 aNewDate = maMax; 1859 else if ( aNewDate < maMin ) 1860 aNewDate = maMin; 1861 maLastDate = aNewDate; 1862 1863 if ( GetField() ) 1864 ImplSetText( ImplGetDateAsText( aNewDate, GetFieldSettings() ), pNewSelection ); 1865 } 1866 1867 // ----------------------------------------------------------------------- 1868 1869 void DateFormatter::ImplNewFieldValue( const Date& rDate ) 1870 { 1871 if ( GetField() ) 1872 { 1873 Selection aSelection = GetField()->GetSelection(); 1874 aSelection.Justify(); 1875 XubString aText = GetField()->GetText(); 1876 // Wenn bis ans Ende selektiert war, soll das auch so bleiben... 1877 if ( (xub_StrLen)aSelection.Max() == aText.Len() ) 1878 { 1879 if ( !aSelection.Len() ) 1880 aSelection.Min() = SELECTION_MAX; 1881 aSelection.Max() = SELECTION_MAX; 1882 } 1883 1884 Date aOldLastDate = maLastDate; 1885 ImplSetUserDate( rDate, &aSelection ); 1886 maLastDate = aOldLastDate; 1887 1888 // Modify am Edit wird nur bei KeyInput gesetzt... 1889 if ( GetField()->GetText() != aText ) 1890 { 1891 GetField()->SetModifyFlag(); 1892 GetField()->Modify(); 1893 } 1894 } 1895 } 1896 1897 // ----------------------------------------------------------------------- 1898 1899 Date DateFormatter::GetDate() const 1900 { 1901 Date aDate( 0, 0, 0 ); 1902 1903 if ( GetField() ) 1904 { 1905 if ( ImplDateGetValue( GetField()->GetText(), aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) ) 1906 { 1907 if ( aDate > maMax ) 1908 aDate = maMax; 1909 else if ( aDate < maMin ) 1910 aDate = maMin; 1911 } 1912 else 1913 { 1914 // !!! TH-18.2.99: Wenn wir Zeit haben sollte einmal 1915 // !!! geklaert werden, warum dieses beim Datum gegenueber 1916 // !!! allen anderen Feldern anders behandelt wird. 1917 // !!! Siehe dazu Bug: 52304 1918 1919 if ( !ImplAllowMalformedInput() ) 1920 { 1921 if ( maLastDate.GetDate() ) 1922 aDate = maLastDate; 1923 else if ( !IsEmptyFieldValueEnabled() ) 1924 aDate = Date(); 1925 } 1926 else 1927 aDate = GetInvalidDate(); 1928 } 1929 } 1930 1931 return aDate; 1932 } 1933 1934 // ----------------------------------------------------------------------- 1935 1936 Date DateFormatter::GetRealDate() const 1937 { 1938 // !!! TH-18.2.99: Wenn wir Zeit haben sollte dieses auch einmal 1939 // !!! fuer die Numeric-Klassen eingebaut werden. 1940 1941 Date aDate( 0, 0, 0 ); 1942 1943 if ( GetField() ) 1944 { 1945 if ( !ImplDateGetValue( GetField()->GetText(), aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) ) 1946 if ( ImplAllowMalformedInput() ) 1947 aDate = GetInvalidDate(); 1948 } 1949 1950 return aDate; 1951 } 1952 1953 // ----------------------------------------------------------------------- 1954 1955 void DateFormatter::SetEmptyDate() 1956 { 1957 FormatterBase::SetEmptyFieldValue(); 1958 } 1959 1960 // ----------------------------------------------------------------------- 1961 1962 sal_Bool DateFormatter::IsEmptyDate() const 1963 { 1964 sal_Bool bEmpty = FormatterBase::IsEmptyFieldValue(); 1965 1966 if ( GetField() && MustBeReformatted() && IsEmptyFieldValueEnabled() ) 1967 { 1968 if ( !GetField()->GetText().Len() ) 1969 { 1970 bEmpty = sal_True; 1971 } 1972 else if ( !maLastDate.GetDate() ) 1973 { 1974 Date aDate; 1975 bEmpty = !ImplDateGetValue( GetField()->GetText(), aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ); 1976 } 1977 } 1978 return bEmpty; 1979 } 1980 1981 // ----------------------------------------------------------------------- 1982 1983 sal_Bool DateFormatter::IsDateModified() const 1984 { 1985 if ( ImplGetEmptyFieldValue() ) 1986 return !IsEmptyDate(); 1987 else if ( GetDate() != maFieldDate ) 1988 return sal_True; 1989 else 1990 return sal_False; 1991 } 1992 1993 // ----------------------------------------------------------------------- 1994 1995 void DateFormatter::Reformat() 1996 { 1997 if ( !GetField() ) 1998 return; 1999 2000 if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() ) 2001 return; 2002 2003 XubString aStr; 2004 sal_Bool bOK = ImplDateReformat( GetField()->GetText(), aStr, GetFieldSettings() ); 2005 if( !bOK ) 2006 return; 2007 2008 if ( aStr.Len() ) 2009 { 2010 ImplSetText( aStr ); 2011 ImplDateGetValue( aStr, maLastDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ); 2012 } 2013 else 2014 { 2015 if ( maLastDate.GetDate() ) 2016 SetDate( maLastDate ); 2017 else if ( !IsEmptyFieldValueEnabled() ) 2018 SetDate( Date() ); 2019 else 2020 { 2021 ImplSetText( ImplGetSVEmptyStr() ); 2022 SetEmptyFieldValueData( sal_True ); 2023 } 2024 } 2025 } 2026 2027 // ----------------------------------------------------------------------- 2028 2029 void DateFormatter::ExpandCentury( Date& rDate ) 2030 { 2031 ExpandCentury( rDate, utl::MiscCfg().GetYear2000() ); 2032 } 2033 2034 // ----------------------------------------------------------------------- 2035 2036 void DateFormatter::ExpandCentury( Date& rDate, sal_uInt16 nTwoDigitYearStart ) 2037 { 2038 sal_uInt16 nDateYear = rDate.GetYear(); 2039 if ( nDateYear < 100 ) 2040 { 2041 sal_uInt16 nCentury = nTwoDigitYearStart / 100; 2042 if ( nDateYear < (nTwoDigitYearStart % 100) ) 2043 nCentury++; 2044 rDate.SetYear( nDateYear + (nCentury*100) ); 2045 } 2046 } 2047 2048 // ----------------------------------------------------------------------- 2049 2050 DateField::DateField( Window* pParent, WinBits nWinStyle ) : 2051 SpinField( pParent, nWinStyle ), 2052 maFirst( GetMin() ), 2053 maLast( GetMax() ) 2054 { 2055 SetField( this ); 2056 SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) ); 2057 Reformat(); 2058 ResetLastDate(); 2059 } 2060 2061 // ----------------------------------------------------------------------- 2062 2063 DateField::DateField( Window* pParent, const ResId& rResId ) : 2064 SpinField( WINDOW_DATEFIELD ), 2065 maFirst( GetMin() ), 2066 maLast( GetMax() ) 2067 { 2068 rResId.SetRT( RSC_DATEFIELD ); 2069 WinBits nStyle = ImplInitRes( rResId ); 2070 SpinField::ImplInit( pParent, nStyle ); 2071 SetField( this ); 2072 SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) ); 2073 ImplLoadRes( rResId ); 2074 2075 if ( !(nStyle & WB_HIDE ) ) 2076 Show(); 2077 2078 ResetLastDate(); 2079 } 2080 2081 // ----------------------------------------------------------------------- 2082 2083 void DateField::ImplLoadRes( const ResId& rResId ) 2084 { 2085 SpinField::ImplLoadRes( rResId ); 2086 2087 ResMgr* pMgr = rResId.GetResMgr(); 2088 if( pMgr ) 2089 { 2090 DateFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); 2091 2092 sal_uLong nMask = ReadLongRes(); 2093 if ( DATEFIELD_FIRST & nMask ) 2094 { 2095 maFirst = Date( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); 2096 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) ); 2097 } 2098 if ( DATEFIELD_LAST & nMask ) 2099 { 2100 maLast = Date( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); 2101 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) ); 2102 } 2103 } 2104 2105 Reformat(); 2106 } 2107 2108 // ----------------------------------------------------------------------- 2109 2110 DateField::~DateField() 2111 { 2112 } 2113 2114 // ----------------------------------------------------------------------- 2115 2116 long DateField::PreNotify( NotifyEvent& rNEvt ) 2117 { 2118 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && IsStrictFormat() && 2119 ( GetExtDateFormat() != XTDATEF_SYSTEM_LONG ) && 2120 !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 2121 { 2122 if ( ImplDateProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetExtDateFormat( sal_True ), ImplGetLocaleDataWrapper() ) ) 2123 return 1; 2124 } 2125 2126 return SpinField::PreNotify( rNEvt ); 2127 } 2128 2129 // ----------------------------------------------------------------------- 2130 2131 long DateField::Notify( NotifyEvent& rNEvt ) 2132 { 2133 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 2134 MarkToBeReformatted( sal_False ); 2135 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 2136 { 2137 if ( MustBeReformatted() ) 2138 { 2139 // !!! TH-18.2.99: Wenn wir Zeit haben sollte einmal 2140 // !!! geklaert werden, warum dieses beim Datum gegenueber 2141 // !!! allen anderen Feldern anders behandelt wird. 2142 // !!! Siehe dazu Bug: 52304 2143 2144 sal_Bool bTextLen = GetText().Len() != 0; 2145 if ( bTextLen || !IsEmptyFieldValueEnabled() ) 2146 { 2147 if ( !ImplAllowMalformedInput() ) 2148 Reformat(); 2149 else 2150 { 2151 Date aDate( 0, 0, 0 ); 2152 if ( ImplDateGetValue( GetText(), aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) ) 2153 // even with strict text analysis, our text is a valid date -> do a complete 2154 // reformat 2155 Reformat(); 2156 } 2157 } 2158 else if ( !bTextLen && IsEmptyFieldValueEnabled() ) 2159 { 2160 ResetLastDate(); 2161 SetEmptyFieldValueData( sal_True ); 2162 } 2163 } 2164 } 2165 2166 return SpinField::Notify( rNEvt ); 2167 } 2168 2169 // ----------------------------------------------------------------------- 2170 2171 void DateField::DataChanged( const DataChangedEvent& rDCEvt ) 2172 { 2173 SpinField::DataChanged( rDCEvt ); 2174 2175 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & (SETTINGS_LOCALE|SETTINGS_MISC)) ) 2176 { 2177 if ( IsDefaultLocale() && ( rDCEvt.GetFlags() & SETTINGS_LOCALE ) ) 2178 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 2179 ReformatAll(); 2180 } 2181 } 2182 2183 // ----------------------------------------------------------------------- 2184 2185 void DateField::Modify() 2186 { 2187 MarkToBeReformatted( sal_True ); 2188 SpinField::Modify(); 2189 } 2190 2191 // ----------------------------------------------------------------------- 2192 2193 void DateField::Up() 2194 { 2195 ImplDateSpinArea( sal_True ); 2196 SpinField::Up(); 2197 } 2198 2199 // ----------------------------------------------------------------------- 2200 2201 void DateField::Down() 2202 { 2203 ImplDateSpinArea( sal_False ); 2204 SpinField::Down(); 2205 } 2206 2207 // ----------------------------------------------------------------------- 2208 2209 void DateField::First() 2210 { 2211 ImplNewFieldValue( maFirst ); 2212 SpinField::First(); 2213 } 2214 2215 // ----------------------------------------------------------------------- 2216 2217 void DateField::Last() 2218 { 2219 ImplNewFieldValue( maLast ); 2220 SpinField::Last(); 2221 } 2222 2223 // ----------------------------------------------------------------------- 2224 2225 DateBox::DateBox( Window* pParent, WinBits nWinStyle ) : 2226 ComboBox( pParent, nWinStyle ) 2227 { 2228 SetField( this ); 2229 SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) ); 2230 Reformat(); 2231 } 2232 2233 // ----------------------------------------------------------------------- 2234 2235 DateBox::DateBox( Window* pParent, const ResId& rResId ) : 2236 ComboBox( WINDOW_DATEBOX ) 2237 { 2238 rResId.SetRT( RSC_DATEBOX ); 2239 WinBits nStyle = ImplInitRes( rResId ); 2240 ComboBox::ImplInit( pParent, nStyle ); 2241 SetField( this ); 2242 SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) ); 2243 ComboBox::ImplLoadRes( rResId ); 2244 ResMgr* pMgr = rResId.GetResMgr(); 2245 if( pMgr ) 2246 DateFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); 2247 Reformat(); 2248 2249 if ( !( nStyle & WB_HIDE ) ) 2250 Show(); 2251 } 2252 2253 // ----------------------------------------------------------------------- 2254 2255 DateBox::~DateBox() 2256 { 2257 } 2258 2259 // ----------------------------------------------------------------------- 2260 2261 long DateBox::PreNotify( NotifyEvent& rNEvt ) 2262 { 2263 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && IsStrictFormat() && 2264 ( GetExtDateFormat() != XTDATEF_SYSTEM_LONG ) && 2265 !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 2266 { 2267 if ( ImplDateProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetExtDateFormat( sal_True ), ImplGetLocaleDataWrapper() ) ) 2268 return 1; 2269 } 2270 2271 return ComboBox::PreNotify( rNEvt ); 2272 } 2273 2274 // ----------------------------------------------------------------------- 2275 2276 void DateBox::DataChanged( const DataChangedEvent& rDCEvt ) 2277 { 2278 ComboBox::DataChanged( rDCEvt ); 2279 2280 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 2281 { 2282 if ( IsDefaultLocale() ) 2283 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 2284 ReformatAll(); 2285 } 2286 } 2287 2288 // ----------------------------------------------------------------------- 2289 2290 long DateBox::Notify( NotifyEvent& rNEvt ) 2291 { 2292 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 2293 MarkToBeReformatted( sal_False ); 2294 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 2295 { 2296 if ( MustBeReformatted() ) 2297 { 2298 sal_Bool bTextLen = GetText().Len() != 0; 2299 if ( bTextLen || !IsEmptyFieldValueEnabled() ) 2300 Reformat(); 2301 else if ( !bTextLen && IsEmptyFieldValueEnabled() ) 2302 { 2303 ResetLastDate(); 2304 SetEmptyFieldValueData( sal_True ); 2305 } 2306 } 2307 } 2308 2309 return ComboBox::Notify( rNEvt ); 2310 } 2311 2312 // ----------------------------------------------------------------------- 2313 2314 void DateBox::Modify() 2315 { 2316 MarkToBeReformatted( sal_True ); 2317 ComboBox::Modify(); 2318 } 2319 2320 // ----------------------------------------------------------------------- 2321 2322 void DateBox::ReformatAll() 2323 { 2324 XubString aStr; 2325 SetUpdateMode( sal_False ); 2326 sal_uInt16 nEntryCount = GetEntryCount(); 2327 for ( sal_uInt16 i=0; i < nEntryCount; i++ ) 2328 { 2329 ImplDateReformat( GetEntry( i ), aStr, GetFieldSettings() ); 2330 RemoveEntry( i ); 2331 InsertEntry( aStr, i ); 2332 } 2333 DateFormatter::Reformat(); 2334 SetUpdateMode( sal_True ); 2335 } 2336 2337 // ----------------------------------------------------------------------- 2338 2339 void DateBox::InsertDate( const Date& rDate, sal_uInt16 nPos ) 2340 { 2341 Date aDate = rDate; 2342 if ( aDate > GetMax() ) 2343 aDate = GetMax(); 2344 else if ( aDate < GetMin() ) 2345 aDate = GetMin(); 2346 2347 ComboBox::InsertEntry( ImplGetDateAsText( aDate, GetFieldSettings() ), nPos ); 2348 } 2349 2350 // ----------------------------------------------------------------------- 2351 2352 void DateBox::RemoveDate( const Date& rDate ) 2353 { 2354 ComboBox::RemoveEntry( ImplGetDateAsText( rDate, GetFieldSettings() ) ); 2355 } 2356 2357 // ----------------------------------------------------------------------- 2358 2359 Date DateBox::GetDate( sal_uInt16 nPos ) const 2360 { 2361 Date aDate( 0, 0, 0 ); 2362 ImplDateGetValue( ComboBox::GetEntry( nPos ), aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetSettings() ); 2363 return aDate; 2364 } 2365 2366 // ----------------------------------------------------------------------- 2367 2368 sal_uInt16 DateBox::GetDatePos( const Date& rDate ) const 2369 { 2370 XubString aStr; 2371 if ( IsLongFormat() ) 2372 aStr = ImplGetLocaleDataWrapper().getLongDate( rDate, GetCalendarWrapper(), 1, sal_False, 1, !IsShowDateCentury() ); 2373 else 2374 aStr = ImplGetLocaleDataWrapper().getDate( rDate ); 2375 return ComboBox::GetEntryPos( aStr ); 2376 } 2377 2378 // ----------------------------------------------------------------------- 2379 2380 static sal_Bool ImplTimeProcessKeyInput( Edit*, const KeyEvent& rKEvt, 2381 sal_Bool bStrictFormat, sal_Bool bDuration, 2382 TimeFieldFormat eFormat, 2383 const LocaleDataWrapper& rLocaleDataWrapper ) 2384 { 2385 xub_Unicode cChar = rKEvt.GetCharCode(); 2386 2387 if ( !bStrictFormat ) 2388 return sal_False; 2389 else 2390 { 2391 sal_uInt16 nGroup = rKEvt.GetKeyCode().GetGroup(); 2392 if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) || 2393 (nGroup == KEYGROUP_MISC) || 2394 ((cChar >= '0') && (cChar <= '9')) || 2395 (cChar == rLocaleDataWrapper.getTimeSep()) || 2396 ( ( rLocaleDataWrapper.getTimeAM().Search( cChar ) != STRING_NOTFOUND ) ) || 2397 ( ( rLocaleDataWrapper.getTimePM().Search( cChar ) != STRING_NOTFOUND ) ) || 2398 // Accept AM/PM: 2399 (cChar == 'a') || (cChar == 'A') || (cChar == 'm') || (cChar == 'M') || (cChar == 'p') || (cChar == 'P') || 2400 ((eFormat == TIMEF_100TH_SEC) && (cChar == rLocaleDataWrapper.getTime100SecSep())) || 2401 ((eFormat == TIMEF_SEC_CS) && (cChar == rLocaleDataWrapper.getTime100SecSep())) || 2402 (bDuration && (cChar == '-')) ) 2403 return sal_False; 2404 else 2405 return sal_True; 2406 } 2407 } 2408 2409 // ----------------------------------------------------------------------- 2410 2411 static sal_Bool ImplIsOnlyDigits( const String& _rStr ) 2412 { 2413 const sal_Unicode* _pChr = _rStr.GetBuffer(); 2414 for ( xub_StrLen i = 0; i < _rStr.Len(); ++i, ++_pChr ) 2415 { 2416 if ( *_pChr < '0' || *_pChr > '9' ) 2417 return sal_False; 2418 } 2419 return sal_True; 2420 } 2421 2422 // ----------------------------------------------------------------------- 2423 2424 static sal_Bool ImplIsValidTimePortion( sal_Bool _bSkipInvalidCharacters, const String& _rStr ) 2425 { 2426 if ( !_bSkipInvalidCharacters ) 2427 { 2428 if ( ( _rStr.Len() > 2 ) || ( _rStr.Len() < 1 ) || !ImplIsOnlyDigits( _rStr ) ) 2429 return sal_False; 2430 } 2431 return sal_True; 2432 } 2433 2434 // ----------------------------------------------------------------------- 2435 2436 static sal_Bool ImplCutTimePortion( String& _rStr, xub_StrLen _nSepPos, sal_Bool _bSkipInvalidCharacters, short* _pPortion ) 2437 { 2438 String sPortion = _rStr.Copy( 0, _nSepPos ); 2439 _rStr.Erase( 0, _nSepPos + 1 ); 2440 2441 if ( !ImplIsValidTimePortion( _bSkipInvalidCharacters, sPortion ) ) 2442 return sal_False; 2443 *_pPortion = (short)sPortion.ToInt32(); 2444 return sal_True; 2445 } 2446 2447 // ----------------------------------------------------------------------- 2448 2449 static sal_Bool ImplTimeGetValue( const XubString& rStr, Time& rTime, 2450 TimeFieldFormat eFormat, sal_Bool bDuration, 2451 const LocaleDataWrapper& rLocaleDataWrapper, sal_Bool _bSkipInvalidCharacters = sal_True ) 2452 { 2453 XubString aStr = rStr; 2454 short nHour = 0; 2455 short nMinute = 0; 2456 short nSecond = 0; 2457 short n100Sec = 0; 2458 Time aTime( 0, 0, 0 ); 2459 2460 if ( !rStr.Len() ) 2461 return sal_False; 2462 2463 // Nach Separatoren suchen 2464 if ( rLocaleDataWrapper.getTimeSep().Len() ) 2465 { 2466 XubString aSepStr( RTL_CONSTASCII_USTRINGPARAM( ",.;:/" ) ); 2467 if ( !bDuration ) 2468 aSepStr.Append( '-' ); 2469 2470 // Die obigen Zeichen durch das Separatorzeichen ersetzen 2471 for ( xub_StrLen i = 0; i < aSepStr.Len(); i++ ) 2472 { 2473 if ( aSepStr.GetChar( i ) == rLocaleDataWrapper.getTimeSep() ) 2474 continue; 2475 for ( xub_StrLen j = 0; j < aStr.Len(); j++ ) 2476 { 2477 if ( aStr.GetChar( j ) == aSepStr.GetChar( i ) ) 2478 aStr.SetChar( j, rLocaleDataWrapper.getTimeSep().GetChar(0) ); 2479 } 2480 } 2481 } 2482 2483 sal_Bool bNegative = sal_False; 2484 xub_StrLen nSepPos = aStr.Search( rLocaleDataWrapper.getTimeSep() ); 2485 if ( aStr.GetChar( 0 ) == '-' ) 2486 bNegative = sal_True; 2487 if ( eFormat != TIMEF_SEC_CS ) 2488 { 2489 if ( nSepPos == STRING_NOTFOUND ) 2490 nSepPos = aStr.Len(); 2491 if ( !ImplCutTimePortion( aStr, nSepPos, _bSkipInvalidCharacters, &nHour ) ) 2492 return sal_False; 2493 2494 nSepPos = aStr.Search( rLocaleDataWrapper.getTimeSep() ); 2495 if ( aStr.GetChar( 0 ) == '-' ) 2496 bNegative = sal_True; 2497 if ( nSepPos != STRING_NOTFOUND ) 2498 { 2499 if ( !ImplCutTimePortion( aStr, nSepPos, _bSkipInvalidCharacters, &nMinute ) ) 2500 return sal_False; 2501 2502 nSepPos = aStr.Search( rLocaleDataWrapper.getTimeSep() ); 2503 if ( aStr.GetChar( 0 ) == '-' ) 2504 bNegative = sal_True; 2505 if ( nSepPos != STRING_NOTFOUND ) 2506 { 2507 if ( !ImplCutTimePortion( aStr, nSepPos, _bSkipInvalidCharacters, &nSecond ) ) 2508 return sal_False; 2509 if ( aStr.GetChar( 0 ) == '-' ) 2510 bNegative = sal_True; 2511 n100Sec = (short)aStr.ToInt32(); 2512 } 2513 else 2514 nSecond = (short)aStr.ToInt32(); 2515 } 2516 else 2517 nMinute = (short)aStr.ToInt32(); 2518 } 2519 else if ( nSepPos == STRING_NOTFOUND ) 2520 { 2521 nSecond = (short)aStr.ToInt32(); 2522 nMinute += nSecond / 60; 2523 nSecond %= 60; 2524 nHour += nMinute / 60; 2525 nMinute %= 60; 2526 } 2527 else 2528 { 2529 nSecond = (short)aStr.Copy( 0, nSepPos ).ToInt32(); 2530 aStr.Erase( 0, nSepPos+1 ); 2531 2532 nSepPos = aStr.Search( rLocaleDataWrapper.getTimeSep() ); 2533 if ( aStr.GetChar( 0 ) == '-' ) 2534 bNegative = sal_True; 2535 if ( nSepPos != STRING_NOTFOUND ) 2536 { 2537 nMinute = nSecond; 2538 nSecond = (short)aStr.Copy( 0, nSepPos ).ToInt32(); 2539 aStr.Erase( 0, nSepPos+1 ); 2540 2541 nSepPos = aStr.Search( rLocaleDataWrapper.getTimeSep() ); 2542 if ( aStr.GetChar( 0 ) == '-' ) 2543 bNegative = sal_True; 2544 if ( nSepPos != STRING_NOTFOUND ) 2545 { 2546 nHour = nMinute; 2547 nMinute = nSecond; 2548 nSecond = (short)aStr.Copy( 0, nSepPos ).ToInt32(); 2549 aStr.Erase( 0, nSepPos+1 ); 2550 } 2551 else 2552 { 2553 nHour += nMinute / 60; 2554 nMinute %= 60; 2555 } 2556 } 2557 else 2558 { 2559 nMinute += nSecond / 60; 2560 nSecond %= 60; 2561 nHour += nMinute / 60; 2562 nMinute %= 60; 2563 } 2564 n100Sec = (short)aStr.ToInt32(); 2565 2566 if ( n100Sec ) 2567 { 2568 xub_StrLen nLen = 1; // mindestens eine Ziffer, weil sonst n100Sec==0 2569 2570 while ( aStr.GetChar(nLen) >= '0' && aStr.GetChar(nLen) <= '9' ) 2571 nLen++; 2572 2573 if ( nLen > 2 ) 2574 { 2575 while( nLen > 3 ) 2576 { 2577 n100Sec = n100Sec / 10; 2578 nLen--; 2579 } 2580 // Rundung bei negativen Zahlen??? 2581 n100Sec = (n100Sec + 5) / 10; 2582 } 2583 else 2584 { 2585 while( nLen < 2 ) 2586 { 2587 n100Sec = n100Sec * 10; 2588 nLen++; 2589 } 2590 } 2591 } 2592 } 2593 2594 if ( (nMinute > 59) || (nSecond > 59) || (n100Sec > 100) ) 2595 return sal_False; 2596 2597 if ( eFormat == TIMEF_NONE ) 2598 nSecond = n100Sec = 0; 2599 else if ( eFormat == TIMEF_SEC ) 2600 n100Sec = 0; 2601 2602 if ( !bDuration ) 2603 { 2604 if ( bNegative || (nHour < 0) || (nMinute < 0) || 2605 (nSecond < 0) || (n100Sec < 0) ) 2606 return sal_False; 2607 2608 aStr.ToUpperAscii(); 2609 XubString aAM( rLocaleDataWrapper.getTimeAM() ); 2610 XubString aPM( rLocaleDataWrapper.getTimePM() ); 2611 aAM.ToUpperAscii(); 2612 aPM.ToUpperAscii(); 2613 XubString aAM2( RTL_CONSTASCII_USTRINGPARAM( "AM" ) ); // aAM is localized 2614 XubString aPM2( RTL_CONSTASCII_USTRINGPARAM( "PM" ) ); // aPM is localized 2615 2616 if ( (nHour < 12) && ( ( aStr.Search( aPM ) != STRING_NOTFOUND ) || ( aStr.Search( aPM2 ) != STRING_NOTFOUND ) ) ) 2617 nHour += 12; 2618 2619 if ( (nHour == 12) && ( ( aStr.Search( aAM ) != STRING_NOTFOUND ) || ( aStr.Search( aAM2 ) != STRING_NOTFOUND ) ) ) 2620 nHour = 0; 2621 2622 aTime = Time( (sal_uInt16)nHour, (sal_uInt16)nMinute, (sal_uInt16)nSecond, 2623 (sal_uInt16)n100Sec ); 2624 } 2625 else 2626 { 2627 if ( bNegative || (nHour < 0) || (nMinute < 0) || 2628 (nSecond < 0) || (n100Sec < 0) ) 2629 { 2630 bNegative = sal_True; 2631 nHour = nHour < 0 ? -nHour : nHour; 2632 nMinute = nMinute < 0 ? -nMinute : nMinute; 2633 nSecond = nSecond < 0 ? -nSecond : nSecond; 2634 n100Sec = n100Sec < 0 ? -n100Sec : n100Sec; 2635 } 2636 2637 aTime = Time( (sal_uInt16)nHour, (sal_uInt16)nMinute, (sal_uInt16)nSecond, 2638 (sal_uInt16)n100Sec ); 2639 if ( bNegative ) 2640 aTime = -aTime; 2641 } 2642 2643 rTime = aTime; 2644 2645 return sal_True; 2646 } 2647 2648 // ----------------------------------------------------------------------- 2649 2650 sal_Bool TimeFormatter::ImplTimeReformat( const XubString& rStr, XubString& rOutStr ) 2651 { 2652 Time aTime( 0, 0, 0 ); 2653 if ( !ImplTimeGetValue( rStr, aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper() ) ) 2654 return sal_True; 2655 2656 Time aTempTime = aTime; 2657 if ( aTempTime > GetMax() ) 2658 aTempTime = GetMax() ; 2659 else if ( aTempTime < GetMin() ) 2660 aTempTime = GetMin(); 2661 2662 if ( GetErrorHdl().IsSet() && (aTime != aTempTime) ) 2663 { 2664 maCorrectedTime = aTempTime; 2665 if ( !GetErrorHdl().Call( this ) ) 2666 { 2667 maCorrectedTime = Time(); 2668 return sal_False; 2669 } 2670 else 2671 maCorrectedTime = Time(); 2672 } 2673 2674 sal_Bool bSecond = sal_False; 2675 sal_Bool b100Sec = sal_False; 2676 if ( meFormat != TIMEF_NONE ) 2677 bSecond = sal_True; 2678 if ( meFormat == TIMEF_100TH_SEC ) 2679 b100Sec = sal_True; 2680 2681 if ( meFormat == TIMEF_SEC_CS ) 2682 { 2683 sal_uLong n = aTempTime.GetHour() * 3600L; 2684 n += aTempTime.GetMin() * 60L; 2685 n += aTempTime.GetSec(); 2686 rOutStr = String::CreateFromInt32( n ); 2687 rOutStr += ImplGetLocaleDataWrapper().getTime100SecSep(); 2688 if ( aTempTime.Get100Sec() < 10 ) 2689 rOutStr += '0'; 2690 rOutStr += String::CreateFromInt32( aTempTime.Get100Sec() ); 2691 } 2692 else if ( mbDuration ) 2693 rOutStr = ImplGetLocaleDataWrapper().getDuration( aTempTime, bSecond, b100Sec ); 2694 else 2695 { 2696 rOutStr = ImplGetLocaleDataWrapper().getTime( aTempTime, bSecond, b100Sec ); 2697 if ( GetTimeFormat() == HOUR_12 ) 2698 { 2699 if ( aTempTime.GetHour() > 12 ) 2700 { 2701 Time aT( aTempTime ); 2702 aT.SetHour( aT.GetHour() % 12 ); 2703 rOutStr = ImplGetLocaleDataWrapper().getTime( aT, bSecond, b100Sec ); 2704 } 2705 // Don't use LocaleDataWrapper, we want AM/PM 2706 if ( aTempTime.GetHour() < 12 ) 2707 rOutStr += String( RTL_CONSTASCII_USTRINGPARAM( "AM" ) ); // ImplGetLocaleDataWrapper().getTimeAM(); 2708 else 2709 rOutStr += String( RTL_CONSTASCII_USTRINGPARAM( "PM" ) ); // ImplGetLocaleDataWrapper().getTimePM(); 2710 } 2711 } 2712 2713 return sal_True; 2714 } 2715 2716 // ----------------------------------------------------------------------- 2717 sal_Bool TimeFormatter::ImplAllowMalformedInput() const 2718 { 2719 return !IsEnforceValidValue(); 2720 } 2721 2722 // ----------------------------------------------------------------------- 2723 2724 void TimeField::ImplTimeSpinArea( sal_Bool bUp ) 2725 { 2726 if ( GetField() ) 2727 { 2728 xub_StrLen nTimeArea = 0; 2729 Time aTime( GetTime() ); 2730 XubString aText( GetText() ); 2731 Selection aSelection( GetField()->GetSelection() ); 2732 2733 // Area suchen 2734 if ( GetFormat() != TIMEF_SEC_CS ) 2735 { 2736 for ( xub_StrLen i = 1, nPos = 0; i <= 4; i++ ) 2737 { 2738 xub_StrLen nPos1 = aText.Search( ImplGetLocaleDataWrapper().getTimeSep(), nPos ); 2739 xub_StrLen nPos2 = aText.Search( ImplGetLocaleDataWrapper().getTime100SecSep(), nPos ); 2740 nPos = nPos1 < nPos2 ? nPos1 : nPos2; 2741 if ( nPos >= (xub_StrLen)aSelection.Max() ) 2742 { 2743 nTimeArea = i; 2744 break; 2745 } 2746 else 2747 nPos++; 2748 } 2749 } 2750 else 2751 { 2752 xub_StrLen nPos = aText.Search( ImplGetLocaleDataWrapper().getTime100SecSep() ); 2753 if ( nPos == STRING_NOTFOUND || nPos >= (xub_StrLen)aSelection.Max() ) 2754 nTimeArea = 3; 2755 else 2756 nTimeArea = 4; 2757 } 2758 2759 if ( nTimeArea ) 2760 { 2761 Time aAddTime( 0, 0, 0 ); 2762 if ( nTimeArea == 1 ) 2763 aAddTime = Time( 1, 0 ); 2764 else if ( nTimeArea == 2 ) 2765 aAddTime = Time( 0, 1 ); 2766 else if ( nTimeArea == 3 ) 2767 aAddTime = Time( 0, 0, 1 ); 2768 else if ( nTimeArea == 4 ) 2769 aAddTime = Time( 0, 0, 0, 1 ); 2770 2771 if ( !bUp ) 2772 aAddTime = -aAddTime; 2773 2774 aTime += aAddTime; 2775 if ( !IsDuration() ) 2776 { 2777 Time aAbsMaxTime( 23, 59, 59, 99 ); 2778 if ( aTime > aAbsMaxTime ) 2779 aTime = aAbsMaxTime; 2780 Time aAbsMinTime( 0, 0 ); 2781 if ( aTime < aAbsMinTime ) 2782 aTime = aAbsMinTime; 2783 } 2784 ImplNewFieldValue( aTime ); 2785 } 2786 2787 } 2788 } 2789 2790 // ----------------------------------------------------------------------- 2791 2792 void TimeFormatter::ImplInit() 2793 { 2794 meFormat = TIMEF_NONE; 2795 mbDuration = sal_False; 2796 mnTimeFormat = HOUR_24; // Should become a ExtTimeFieldFormat in next implementation, merge with mbDuration and meFormat 2797 } 2798 2799 // ----------------------------------------------------------------------- 2800 2801 TimeFormatter::TimeFormatter() : 2802 maLastTime( 0, 0 ), 2803 maMin( 0, 0 ), 2804 maMax( 23, 59, 59, 99 ), 2805 mbEnforceValidValue( sal_True ), 2806 maFieldTime( 0, 0 ) 2807 { 2808 ImplInit(); 2809 } 2810 2811 // ----------------------------------------------------------------------- 2812 2813 void TimeFormatter::ImplLoadRes( const ResId& rResId ) 2814 { 2815 ResMgr* pMgr = rResId.GetResMgr(); 2816 if( pMgr ) 2817 { 2818 sal_uLong nMask = pMgr->ReadLong(); 2819 2820 if ( TIMEFORMATTER_MIN & nMask ) 2821 { 2822 SetMin( Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ) ); 2823 pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) ); 2824 } 2825 2826 if ( TIMEFORMATTER_MAX & nMask ) 2827 { 2828 SetMax( Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ) ); 2829 pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) ); 2830 } 2831 2832 if ( TIMEFORMATTER_TIMEFIELDFORMAT & nMask ) 2833 meFormat = (TimeFieldFormat)pMgr->ReadLong(); 2834 2835 if ( TIMEFORMATTER_DURATION & nMask ) 2836 mbDuration = (sal_Bool)pMgr->ReadShort(); 2837 2838 if ( TIMEFORMATTER_STRICTFORMAT & nMask ) 2839 SetStrictFormat( (sal_Bool)pMgr->ReadShort() ); 2840 2841 if ( TIMEFORMATTER_VALUE & nMask ) 2842 { 2843 maFieldTime = Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ); 2844 if ( maFieldTime > GetMax() ) 2845 maFieldTime = GetMax(); 2846 if ( maFieldTime < GetMin() ) 2847 maFieldTime = GetMin(); 2848 maLastTime = maFieldTime; 2849 2850 pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) ); 2851 } 2852 } 2853 } 2854 2855 // ----------------------------------------------------------------------- 2856 2857 TimeFormatter::~TimeFormatter() 2858 { 2859 } 2860 2861 // ----------------------------------------------------------------------- 2862 2863 void TimeFormatter::ReformatAll() 2864 { 2865 Reformat(); 2866 } 2867 2868 // ----------------------------------------------------------------------- 2869 2870 void TimeFormatter::SetMin( const Time& rNewMin ) 2871 { 2872 maMin = rNewMin; 2873 if ( !IsEmptyFieldValue() ) 2874 ReformatAll(); 2875 } 2876 2877 // ----------------------------------------------------------------------- 2878 2879 void TimeFormatter::SetMax( const Time& rNewMax ) 2880 { 2881 maMax = rNewMax; 2882 if ( !IsEmptyFieldValue() ) 2883 ReformatAll(); 2884 } 2885 2886 // ----------------------------------------------------------------------- 2887 2888 void TimeFormatter::SetTimeFormat( TimeFormatter::TimeFormat eNewFormat ) 2889 { 2890 mnTimeFormat = sal::static_int_cast<sal_uInt16>(eNewFormat); 2891 } 2892 2893 // ----------------------------------------------------------------------- 2894 2895 TimeFormatter::TimeFormat TimeFormatter::GetTimeFormat() const 2896 { 2897 return (TimeFormat)mnTimeFormat; 2898 } 2899 2900 // ----------------------------------------------------------------------- 2901 2902 void TimeFormatter::SetFormat( TimeFieldFormat eNewFormat ) 2903 { 2904 meFormat = eNewFormat; 2905 ReformatAll(); 2906 } 2907 2908 // ----------------------------------------------------------------------- 2909 2910 void TimeFormatter::SetDuration( sal_Bool bNewDuration ) 2911 { 2912 mbDuration = bNewDuration; 2913 ReformatAll(); 2914 } 2915 2916 // ----------------------------------------------------------------------- 2917 2918 void TimeFormatter::SetTime( const Time& rNewTime ) 2919 { 2920 SetUserTime( rNewTime ); 2921 maFieldTime = maLastTime; 2922 SetEmptyFieldValueData( sal_False ); 2923 } 2924 2925 // ----------------------------------------------------------------------- 2926 2927 void TimeFormatter::ImplNewFieldValue( const Time& rTime ) 2928 { 2929 if ( GetField() ) 2930 { 2931 Selection aSelection = GetField()->GetSelection(); 2932 aSelection.Justify(); 2933 XubString aText = GetField()->GetText(); 2934 // Wenn bis ans Ende selektiert war, soll das auch so bleiben... 2935 if ( (xub_StrLen)aSelection.Max() == aText.Len() ) 2936 { 2937 if ( !aSelection.Len() ) 2938 aSelection.Min() = SELECTION_MAX; 2939 aSelection.Max() = SELECTION_MAX; 2940 } 2941 2942 Time aOldLastTime = maLastTime; 2943 ImplSetUserTime( rTime, &aSelection ); 2944 maLastTime = aOldLastTime; 2945 2946 // Modify am Edit wird nur bei KeyInput gesetzt... 2947 if ( GetField()->GetText() != aText ) 2948 { 2949 GetField()->SetModifyFlag(); 2950 GetField()->Modify(); 2951 } 2952 } 2953 } 2954 2955 // ----------------------------------------------------------------------- 2956 2957 void TimeFormatter::ImplSetUserTime( const Time& rNewTime, Selection* pNewSelection ) 2958 { 2959 Time aNewTime = rNewTime; 2960 if ( aNewTime > GetMax() ) 2961 aNewTime = GetMax(); 2962 else if ( aNewTime < GetMin() ) 2963 aNewTime = GetMin(); 2964 maLastTime = aNewTime; 2965 2966 if ( GetField() ) 2967 { 2968 XubString aStr; 2969 sal_Bool bSec = sal_False; 2970 sal_Bool b100Sec = sal_False; 2971 if ( meFormat != TIMEF_NONE ) 2972 bSec = sal_True; 2973 if ( meFormat == TIMEF_100TH_SEC || meFormat == TIMEF_SEC_CS ) 2974 b100Sec = sal_True; 2975 if ( meFormat == TIMEF_SEC_CS ) 2976 { 2977 sal_uLong n = aNewTime.GetHour() * 3600L; 2978 n += aNewTime.GetMin() * 60L; 2979 n += aNewTime.GetSec(); 2980 aStr = String::CreateFromInt32( n ); 2981 aStr += ImplGetLocaleDataWrapper().getTime100SecSep(); 2982 if ( aNewTime.Get100Sec() < 10 ) 2983 aStr += '0'; 2984 aStr += String::CreateFromInt32( aNewTime.Get100Sec() ); 2985 } 2986 else if ( mbDuration ) 2987 { 2988 aStr = ImplGetLocaleDataWrapper().getDuration( aNewTime, bSec, b100Sec ); 2989 } 2990 else 2991 { 2992 aStr = ImplGetLocaleDataWrapper().getTime( aNewTime, bSec, b100Sec ); 2993 if ( GetTimeFormat() == HOUR_12 ) 2994 { 2995 if ( aNewTime.GetHour() > 12 ) 2996 { 2997 Time aT( aNewTime ); 2998 aT.SetHour( aT.GetHour() % 12 ); 2999 aStr = ImplGetLocaleDataWrapper().getTime( aT, bSec, b100Sec ); 3000 } 3001 // Don't use LocaleDataWrapper, we want AM/PM 3002 if ( aNewTime.GetHour() < 12 ) 3003 aStr += String( RTL_CONSTASCII_USTRINGPARAM( "AM" ) ); // ImplGetLocaleDataWrapper().getTimeAM(); 3004 else 3005 aStr += String( RTL_CONSTASCII_USTRINGPARAM( "PM" ) ); // ImplGetLocaleDataWrapper().getTimePM(); 3006 } 3007 } 3008 3009 ImplSetText( aStr, pNewSelection ); 3010 } 3011 } 3012 3013 // ----------------------------------------------------------------------- 3014 3015 void TimeFormatter::SetUserTime( const Time& rNewTime ) 3016 { 3017 ImplSetUserTime( rNewTime ); 3018 } 3019 3020 // ----------------------------------------------------------------------- 3021 3022 Time TimeFormatter::GetTime() const 3023 { 3024 Time aTime( 0, 0, 0 ); 3025 3026 if ( GetField() ) 3027 { 3028 sal_Bool bAllowMailformed = ImplAllowMalformedInput(); 3029 if ( ImplTimeGetValue( GetField()->GetText(), aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper(), !bAllowMailformed ) ) 3030 { 3031 if ( aTime > GetMax() ) 3032 aTime = GetMax(); 3033 else if ( aTime < GetMin() ) 3034 aTime = GetMin(); 3035 } 3036 else 3037 { 3038 if ( bAllowMailformed ) 3039 aTime = GetInvalidTime(); 3040 else 3041 aTime = maLastTime; 3042 } 3043 } 3044 3045 return aTime; 3046 } 3047 3048 // ----------------------------------------------------------------------- 3049 3050 Time TimeFormatter::GetRealTime() const 3051 { 3052 Time aTime( 0, 0, 0 ); 3053 3054 if ( GetField() ) 3055 { 3056 sal_Bool bAllowMailformed = ImplAllowMalformedInput(); 3057 if ( !ImplTimeGetValue( GetField()->GetText(), aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper(), !bAllowMailformed ) ) 3058 if ( bAllowMailformed ) 3059 aTime = GetInvalidTime(); 3060 } 3061 3062 return aTime; 3063 } 3064 3065 // ----------------------------------------------------------------------- 3066 3067 sal_Bool TimeFormatter::IsTimeModified() const 3068 { 3069 if ( ImplGetEmptyFieldValue() ) 3070 return !IsEmptyTime(); 3071 else if ( GetTime() != maFieldTime ) 3072 return sal_True; 3073 else 3074 return sal_False; 3075 } 3076 3077 // ----------------------------------------------------------------------- 3078 3079 void TimeFormatter::Reformat() 3080 { 3081 if ( !GetField() ) 3082 return; 3083 3084 if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() ) 3085 return; 3086 3087 XubString aStr; 3088 sal_Bool bOK = ImplTimeReformat( GetField()->GetText(), aStr ); 3089 if ( !bOK ) 3090 return; 3091 3092 if ( aStr.Len() ) 3093 { 3094 ImplSetText( aStr ); 3095 ImplTimeGetValue( aStr, maLastTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper() ); 3096 } 3097 else 3098 SetTime( maLastTime ); 3099 } 3100 3101 // ----------------------------------------------------------------------- 3102 3103 TimeField::TimeField( Window* pParent, WinBits nWinStyle ) : 3104 SpinField( pParent, nWinStyle ), 3105 maFirst( GetMin() ), 3106 maLast( GetMax() ) 3107 { 3108 SetField( this ); 3109 SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime, sal_False, sal_False ) ); 3110 Reformat(); 3111 } 3112 3113 // ----------------------------------------------------------------------- 3114 3115 TimeField::TimeField( Window* pParent, const ResId& rResId ) : 3116 SpinField( WINDOW_TIMEFIELD ), 3117 maFirst( GetMin() ), 3118 maLast( GetMax() ) 3119 { 3120 rResId.SetRT( RSC_TIMEFIELD ); 3121 WinBits nStyle = ImplInitRes( rResId ); 3122 SpinField::ImplInit( pParent, nStyle ); 3123 SetField( this ); 3124 SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime, sal_False, sal_False ) ); 3125 ImplLoadRes( rResId ); 3126 3127 if ( !(nStyle & WB_HIDE ) ) 3128 Show(); 3129 } 3130 3131 // ----------------------------------------------------------------------- 3132 3133 void TimeField::ImplLoadRes( const ResId& rResId ) 3134 { 3135 SpinField::ImplLoadRes( rResId ); 3136 ResMgr* pMgr = rResId.GetResMgr(); 3137 if( pMgr ) 3138 { 3139 TimeFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); 3140 3141 sal_uLong nMask = ReadLongRes(); 3142 3143 if ( TIMEFIELD_FIRST & nMask ) 3144 { 3145 maFirst = Time( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); 3146 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) ); 3147 } 3148 if ( TIMEFIELD_LAST & nMask ) 3149 { 3150 maLast = Time( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); 3151 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) ); 3152 } 3153 } 3154 3155 Reformat(); 3156 } 3157 3158 // ----------------------------------------------------------------------- 3159 3160 TimeField::~TimeField() 3161 { 3162 } 3163 3164 // ----------------------------------------------------------------------- 3165 3166 long TimeField::PreNotify( NotifyEvent& rNEvt ) 3167 { 3168 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 3169 { 3170 if ( ImplTimeProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsDuration(), GetFormat(), ImplGetLocaleDataWrapper() ) ) 3171 return 1; 3172 } 3173 3174 return SpinField::PreNotify( rNEvt ); 3175 } 3176 3177 // ----------------------------------------------------------------------- 3178 3179 long TimeField::Notify( NotifyEvent& rNEvt ) 3180 { 3181 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 3182 MarkToBeReformatted( sal_False ); 3183 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 3184 { 3185 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 3186 { 3187 if ( !ImplAllowMalformedInput() ) 3188 Reformat(); 3189 else 3190 { 3191 Time aTime( 0, 0, 0 ); 3192 if ( ImplTimeGetValue( GetText(), aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper(), sal_False ) ) 3193 // even with strict text analysis, our text is a valid time -> do a complete 3194 // reformat 3195 Reformat(); 3196 } 3197 } 3198 } 3199 3200 return SpinField::Notify( rNEvt ); 3201 } 3202 3203 // ----------------------------------------------------------------------- 3204 3205 void TimeField::DataChanged( const DataChangedEvent& rDCEvt ) 3206 { 3207 SpinField::DataChanged( rDCEvt ); 3208 3209 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 3210 { 3211 if ( IsDefaultLocale() ) 3212 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 3213 ReformatAll(); 3214 } 3215 } 3216 3217 // ----------------------------------------------------------------------- 3218 3219 void TimeField::Modify() 3220 { 3221 MarkToBeReformatted( sal_True ); 3222 SpinField::Modify(); 3223 } 3224 3225 // ----------------------------------------------------------------------- 3226 3227 void TimeField::Up() 3228 { 3229 ImplTimeSpinArea( sal_True ); 3230 SpinField::Up(); 3231 } 3232 3233 // ----------------------------------------------------------------------- 3234 3235 void TimeField::Down() 3236 { 3237 ImplTimeSpinArea( sal_False ); 3238 SpinField::Down(); 3239 } 3240 3241 // ----------------------------------------------------------------------- 3242 3243 void TimeField::First() 3244 { 3245 ImplNewFieldValue( maFirst ); 3246 SpinField::First(); 3247 } 3248 3249 // ----------------------------------------------------------------------- 3250 3251 void TimeField::Last() 3252 { 3253 ImplNewFieldValue( maLast ); 3254 SpinField::Last(); 3255 } 3256 3257 // ----------------------------------------------------------------------- 3258 3259 void TimeField::SetExtFormat( ExtTimeFieldFormat eFormat ) 3260 { 3261 switch ( eFormat ) 3262 { 3263 case EXTTIMEF_24H_SHORT: 3264 { 3265 SetTimeFormat( HOUR_24 ); 3266 SetDuration( sal_False ); 3267 SetFormat( TIMEF_NONE ); 3268 } 3269 break; 3270 case EXTTIMEF_24H_LONG: 3271 { 3272 SetTimeFormat( HOUR_24 ); 3273 SetDuration( sal_False ); 3274 SetFormat( TIMEF_SEC ); 3275 } 3276 break; 3277 case EXTTIMEF_12H_SHORT: 3278 { 3279 SetTimeFormat( HOUR_12 ); 3280 SetDuration( sal_False ); 3281 SetFormat( TIMEF_NONE ); 3282 } 3283 break; 3284 case EXTTIMEF_12H_LONG: 3285 { 3286 SetTimeFormat( HOUR_12 ); 3287 SetDuration( sal_False ); 3288 SetFormat( TIMEF_SEC ); 3289 } 3290 break; 3291 case EXTTIMEF_DURATION_SHORT: 3292 { 3293 SetDuration( sal_True ); 3294 SetFormat( TIMEF_NONE ); 3295 } 3296 break; 3297 case EXTTIMEF_DURATION_LONG: 3298 { 3299 SetDuration( sal_True ); 3300 SetFormat( TIMEF_SEC ); 3301 } 3302 break; 3303 default: DBG_ERROR( "ExtTimeFieldFormat unknown!" ); 3304 } 3305 3306 if ( GetField() && GetField()->GetText().Len() ) 3307 SetUserTime( GetTime() ); 3308 ReformatAll(); 3309 } 3310 3311 // ----------------------------------------------------------------------- 3312 3313 TimeBox::TimeBox( Window* pParent, WinBits nWinStyle ) : 3314 ComboBox( pParent, nWinStyle ) 3315 { 3316 SetField( this ); 3317 SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime, sal_False, sal_False ) ); 3318 Reformat(); 3319 } 3320 3321 // ----------------------------------------------------------------------- 3322 3323 TimeBox::TimeBox( Window* pParent, const ResId& rResId ) : 3324 ComboBox( WINDOW_TIMEBOX ) 3325 { 3326 rResId.SetRT( RSC_TIMEBOX ); 3327 WinBits nStyle = ImplInitRes( rResId ); 3328 ComboBox::ImplInit( pParent, nStyle ); 3329 SetField( this ); 3330 SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime, sal_False, sal_False ) ); 3331 ComboBox::ImplLoadRes( rResId ); 3332 ResMgr* pMgr = rResId.GetResMgr(); 3333 if( pMgr ) 3334 TimeFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); 3335 Reformat(); 3336 3337 if ( !(nStyle & WB_HIDE) ) 3338 Show(); 3339 } 3340 3341 // ----------------------------------------------------------------------- 3342 3343 TimeBox::~TimeBox() 3344 { 3345 } 3346 3347 // ----------------------------------------------------------------------- 3348 3349 long TimeBox::PreNotify( NotifyEvent& rNEvt ) 3350 { 3351 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) 3352 { 3353 if ( ImplTimeProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsDuration(), GetFormat(), ImplGetLocaleDataWrapper() ) ) 3354 return 1; 3355 } 3356 3357 return ComboBox::PreNotify( rNEvt ); 3358 } 3359 3360 // ----------------------------------------------------------------------- 3361 3362 long TimeBox::Notify( NotifyEvent& rNEvt ) 3363 { 3364 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 3365 MarkToBeReformatted( sal_False ); 3366 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 3367 { 3368 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) 3369 Reformat(); 3370 } 3371 3372 return ComboBox::Notify( rNEvt ); 3373 } 3374 3375 // ----------------------------------------------------------------------- 3376 3377 void TimeBox::DataChanged( const DataChangedEvent& rDCEvt ) 3378 { 3379 ComboBox::DataChanged( rDCEvt ); 3380 3381 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) 3382 { 3383 if ( IsDefaultLocale() ) 3384 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); 3385 ReformatAll(); 3386 } 3387 } 3388 3389 // ----------------------------------------------------------------------- 3390 3391 void TimeBox::Modify() 3392 { 3393 MarkToBeReformatted( sal_True ); 3394 ComboBox::Modify(); 3395 } 3396 3397 // ----------------------------------------------------------------------- 3398 3399 void TimeBox::ReformatAll() 3400 { 3401 XubString aStr; 3402 SetUpdateMode( sal_False ); 3403 sal_uInt16 nEntryCount = GetEntryCount(); 3404 for ( sal_uInt16 i=0; i < nEntryCount; i++ ) 3405 { 3406 ImplTimeReformat( GetEntry( i ), aStr ); 3407 RemoveEntry( i ); 3408 InsertEntry( aStr, i ); 3409 } 3410 TimeFormatter::Reformat(); 3411 SetUpdateMode( sal_True ); 3412 } 3413 3414 // ----------------------------------------------------------------------- 3415 3416 void TimeBox::InsertTime( const Time& rTime, sal_uInt16 nPos ) 3417 { 3418 Time aTime = rTime; 3419 if ( aTime > GetMax() ) 3420 aTime = GetMax(); 3421 else if ( aTime < GetMin() ) 3422 aTime = GetMin(); 3423 3424 sal_Bool bSec = sal_False; 3425 sal_Bool b100Sec = sal_False; 3426 if ( GetFormat() == TIMEF_SEC ) 3427 bSec = sal_True; 3428 if ( GetFormat() == TIMEF_100TH_SEC || GetFormat() == TIMEF_SEC_CS ) 3429 bSec = b100Sec = sal_True; 3430 ComboBox::InsertEntry( ImplGetLocaleDataWrapper().getTime( aTime, bSec, b100Sec ), nPos ); 3431 } 3432 3433 // ----------------------------------------------------------------------- 3434 3435 void TimeBox::RemoveTime( const Time& rTime ) 3436 { 3437 sal_Bool bSec = sal_False; 3438 sal_Bool b100Sec = sal_False; 3439 if ( GetFormat() == TIMEF_SEC ) 3440 bSec = sal_True; 3441 if ( GetFormat() == TIMEF_100TH_SEC || TIMEF_SEC_CS ) 3442 bSec = b100Sec = sal_True; 3443 ComboBox::RemoveEntry( ImplGetLocaleDataWrapper().getTime( rTime, bSec, b100Sec ) ); 3444 } 3445 3446 // ----------------------------------------------------------------------- 3447 3448 Time TimeBox::GetTime( sal_uInt16 nPos ) const 3449 { 3450 Time aTime( 0, 0, 0 ); 3451 ImplTimeGetValue( ComboBox::GetEntry( nPos ), aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper() ); 3452 return aTime; 3453 } 3454 3455 // ----------------------------------------------------------------------- 3456 3457 sal_uInt16 TimeBox::GetTimePos( const Time& rTime ) const 3458 { 3459 sal_Bool bSec = sal_False; 3460 sal_Bool b100Sec = sal_False; 3461 if ( GetFormat() == TIMEF_SEC ) 3462 bSec = sal_True; 3463 if ( GetFormat() == TIMEF_100TH_SEC || TIMEF_SEC_CS ) 3464 bSec = b100Sec = sal_True; 3465 return ComboBox::GetEntryPos( ImplGetLocaleDataWrapper().getTime( rTime, bSec, b100Sec ) ); 3466 } 3467