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