1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: field2.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
33 #include <tools/debug.hxx>
38 #include <vcl/svdata.hxx>
40 #include <vcl/field.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/sound.hxx>
44 #include <vcl/event.hxx>
45 #include <vcl/field.hxx>
46 #include <i18npool/mslangid.hxx>
48 #include <vcl/unohelp.hxx>
50 #include <com/sun/star/lang/Locale.hpp>
51 #include <com/sun/star/i18n/XCharacterClassification.hpp>
52 #include <com/sun/star/i18n/KCharacterType.hpp>
55 #include <unotools/localedatawrapper.hxx>
56 #include <unotools/calendarwrapper.hxx>
57 #include <unotools/charclass.hxx>
59 using namespace ::com::sun::star
;
61 // =======================================================================
63 #define EDITMASK_LITERAL 'L'
64 #define EDITMASK_ALPHA 'a'
65 #define EDITMASK_UPPERALPHA 'A'
66 #define EDITMASK_ALPHANUM 'c'
67 #define EDITMASK_UPPERALPHANUM 'C'
68 #define EDITMASK_NUM 'N'
69 #define EDITMASK_NUMSPACE 'n'
70 #define EDITMASK_ALLCHAR 'x'
71 #define EDITMASK_UPPERALLCHAR 'X'
73 uno::Reference
< i18n::XCharacterClassification
> ImplGetCharClass()
75 static uno::Reference
< i18n::XCharacterClassification
> xCharClass
;
76 if ( !xCharClass
.is() )
77 xCharClass
= vcl::unohelper::CreateCharacterClassification();
82 // -----------------------------------------------------------------------
84 static sal_Unicode
* ImplAddString( sal_Unicode
* pBuf
, const String
& rStr
)
86 if ( rStr
.Len() == 1 )
87 *pBuf
++ = rStr
.GetChar(0);
88 else if ( rStr
.Len() == 0 )
92 memcpy( pBuf
, rStr
.GetBuffer(), rStr
.Len() * sizeof(sal_Unicode
) );
98 // -----------------------------------------------------------------------
100 static sal_Unicode
* ImplAddNum( sal_Unicode
* pBuf
, ULONG nNumber
, int nMinLen
)
102 // fill temp buffer with digits
103 sal_Unicode aTempBuf
[30];
104 sal_Unicode
* pTempBuf
= aTempBuf
;
107 *pTempBuf
= (sal_Unicode
)(nNumber
% 10) + '0';
115 // fill with zeros up to the minimal length
116 while ( nMinLen
> 0 )
123 // copy temp buffer to real buffer
130 while ( pTempBuf
!= aTempBuf
);
135 // -----------------------------------------------------------------------
137 static USHORT
ImplGetNum( const sal_Unicode
*& rpBuf
, BOOL
& rbError
)
146 while( ( *rpBuf
>= '0' ) && ( *rpBuf
<= '9' ) )
149 nNumber
+= *rpBuf
- '0';
156 // -----------------------------------------------------------------------
158 static void ImplSkipDelimiters( const sal_Unicode
*& rpBuf
)
160 while( ( *rpBuf
== ',' ) || ( *rpBuf
== '.' ) || ( *rpBuf
== ';' ) ||
161 ( *rpBuf
== ':' ) || ( *rpBuf
== '-' ) || ( *rpBuf
== '/' ) )
167 // -----------------------------------------------------------------------
169 static int ImplIsPatternChar( xub_Unicode cChar
, sal_Char cEditMask
)
175 String
aCharStr( cChar
);
176 nType
= ImplGetCharClass()->getStringType( aCharStr
, 0, aCharStr
.Len(), Application::GetSettings().GetLocale() );
178 catch ( ::com::sun::star::uno::Exception
& )
180 DBG_ERRORFILE( "ImplIsPatternChar: Exception caught!" );
184 if ( (cEditMask
== EDITMASK_ALPHA
) || (cEditMask
== EDITMASK_UPPERALPHA
) )
186 if( !CharClass::isLetterType( nType
) )
189 else if ( cEditMask
== EDITMASK_NUM
)
191 if( !CharClass::isNumericType( nType
) )
194 else if ( (cEditMask
== EDITMASK_ALPHANUM
) || (cEditMask
== EDITMASK_UPPERALPHANUM
) )
196 if( !CharClass::isLetterNumericType( nType
) )
199 else if ( (cEditMask
== EDITMASK_ALLCHAR
) || (cEditMask
== EDITMASK_UPPERALLCHAR
) )
204 else if ( cEditMask
== EDITMASK_NUMSPACE
)
206 if ( !CharClass::isNumericType( nType
) && ( cChar
!= ' ' ) )
215 // -----------------------------------------------------------------------
217 static xub_Unicode
ImplPatternChar( xub_Unicode cChar
, sal_Char cEditMask
)
219 if ( ImplIsPatternChar( cChar
, cEditMask
) )
221 if ( (cEditMask
== EDITMASK_UPPERALPHA
) ||
222 (cEditMask
== EDITMASK_UPPERALPHANUM
) ||
223 ( cEditMask
== EDITMASK_UPPERALLCHAR
) )
225 cChar
= ImplGetCharClass()->toUpper( String(cChar
),0,1,Application::GetSettings().GetLocale() )[0];
233 // -----------------------------------------------------------------------
235 static int ImplKommaPointCharEqual( xub_Unicode c1
, xub_Unicode c2
)
239 else if ( ((c1
== '.') || (c1
== ',')) &&
240 ((c2
== '.') || (c2
== ',')) )
246 // -----------------------------------------------------------------------
248 static XubString
ImplPatternReformat( const XubString
& rStr
,
249 const ByteString
& rEditMask
,
250 const XubString
& rLiteralMask
,
251 USHORT nFormatFlags
)
253 if ( !rEditMask
.Len() )
256 XubString aStr
= rStr
;
257 XubString aOutStr
= rLiteralMask
;
258 xub_Unicode cTempChar
;
260 xub_Unicode cLiteral
;
262 xub_StrLen nStrIndex
= 0;
266 while ( i
< rEditMask
.Len() )
268 if ( nStrIndex
>= aStr
.Len() )
271 cChar
= aStr
.GetChar(nStrIndex
);
272 cLiteral
= rLiteralMask
.GetChar(i
);
273 cMask
= rEditMask
.GetChar(i
);
275 // Aktuelle Position ein Literal
276 if ( cMask
== EDITMASK_LITERAL
)
278 // Wenn es das Literal-Zeichen ist, uebernehmen, ansonsten
279 // ignorieren, da es das naechste gueltige Zeichen vom String
281 if ( ImplKommaPointCharEqual( cChar
, cLiteral
) )
285 // Ansonsten testen wir, ob es ein ungueltiges Zeichen ist.
286 // Dies ist dann der Fall, wenn es nicht in das Muster
287 // des naechsten nicht Literal-Zeichens passt
289 while ( n
< rEditMask
.Len() )
291 if ( rEditMask
.GetChar(n
) != EDITMASK_LITERAL
)
293 if ( !ImplIsPatternChar( cChar
, rEditMask
.GetChar(n
) ) )
304 // Gueltiges Zeichen an der Stelle
305 cTempChar
= ImplPatternChar( cChar
, cMask
);
308 // dann Zeichen uebernehmen
309 aOutStr
.SetChar( i
, cTempChar
);
314 // Wenn es das Literalzeichen ist, uebernehmen
315 if ( cLiteral
== cChar
)
319 // Wenn das ungueltige Zeichen das naechste Literalzeichen
320 // sein kann, dann springen wir bis dahin vor, ansonten
321 // das Zeichen ignorieren
322 // Nur machen, wenn leere Literale erlaubt sind
323 if ( nFormatFlags
& PATTERN_FORMAT_EMPTYLITERALS
)
326 while ( n
< rEditMask
.Len() )
328 if ( rEditMask
.GetChar( n
) == EDITMASK_LITERAL
)
330 if ( ImplKommaPointCharEqual( cChar
, rLiteralMask
.GetChar( n
) ) )
352 // -----------------------------------------------------------------------
354 static void ImplPatternMaxPos( const XubString rStr
, const ByteString
& rEditMask
,
355 USHORT nFormatFlags
, BOOL bSameMask
,
356 USHORT nCursorPos
, USHORT
& rPos
)
359 // Letzte Position darf nicht groesser als der enthaltene String sein
360 xub_StrLen nMaxPos
= rStr
.Len();
362 // Wenn keine leeren Literale erlaubt sind, auch Leerzeichen
363 // am Ende ignorieren
364 if ( bSameMask
&& !(nFormatFlags
& PATTERN_FORMAT_EMPTYLITERALS
) )
368 if ( (rEditMask
.GetChar(nMaxPos
-1) != EDITMASK_LITERAL
) &&
369 (rStr
.GetChar(nMaxPos
-1) != ' ') )
374 // Wenn wir vor einem Literal stehen, dann solange weitersuchen,
375 // bis erste Stelle nach Literal
376 xub_StrLen nTempPos
= nMaxPos
;
377 while ( nTempPos
< rEditMask
.Len() )
379 if ( rEditMask
.GetChar(nTempPos
) != EDITMASK_LITERAL
)
388 if ( rPos
> nMaxPos
)
390 // Zeichen sollte nicht nach links wandern
391 if ( rPos
< nCursorPos
)
395 // -----------------------------------------------------------------------
397 static void ImplPatternProcessStrictModify( Edit
* pEdit
,
398 const ByteString
& rEditMask
,
399 const XubString
& rLiteralMask
,
400 USHORT nFormatFlags
, BOOL bSameMask
)
402 XubString aText
= pEdit
->GetText();
404 // Leerzeichen am Anfang entfernen
405 if ( bSameMask
&& !(nFormatFlags
& PATTERN_FORMAT_EMPTYLITERALS
) )
408 xub_StrLen nMaxLen
= aText
.Len();
409 while ( i
< nMaxLen
)
411 if ( (rEditMask
.GetChar( i
) != EDITMASK_LITERAL
) &&
412 (aText
.GetChar( i
) != ' ') )
417 // Alle Literalzeichen beibehalten
418 while ( i
&& (rEditMask
.GetChar( i
) == EDITMASK_LITERAL
) )
423 XubString aNewText
= ImplPatternReformat( aText
, rEditMask
, rLiteralMask
, nFormatFlags
);
424 if ( aNewText
!= aText
)
426 // Selection so anpassen, das diese wenn sie vorher am Ende
427 // stand, immer noch am Ende steht
428 Selection aSel
= pEdit
->GetSelection();
429 ULONG nMaxSel
= Max( aSel
.Min(), aSel
.Max() );
430 if ( nMaxSel
>= aText
.Len() )
432 xub_StrLen nMaxPos
= aNewText
.Len();
433 ImplPatternMaxPos( aNewText
, rEditMask
, nFormatFlags
, bSameMask
, (xub_StrLen
)nMaxSel
, nMaxPos
);
434 if ( aSel
.Min() == aSel
.Max() )
436 aSel
.Min() = nMaxPos
;
437 aSel
.Max() = aSel
.Min();
439 else if ( aSel
.Min() > aSel
.Max() )
440 aSel
.Min() = nMaxPos
;
442 aSel
.Max() = nMaxPos
;
444 pEdit
->SetText( aNewText
, aSel
);
448 // -----------------------------------------------------------------------
450 static xub_StrLen
ImplPatternLeftPos( const ByteString
& rEditMask
, xub_StrLen nCursorPos
)
452 // Vorheriges Zeichen suchen, was kein Literal ist
453 xub_StrLen nNewPos
= nCursorPos
;
454 xub_StrLen nTempPos
= nNewPos
;
457 if ( rEditMask
.GetChar(nTempPos
-1) != EDITMASK_LITERAL
)
459 nNewPos
= nTempPos
-1;
467 // -----------------------------------------------------------------------
469 static xub_StrLen
ImplPatternRightPos( const XubString
& rStr
, const ByteString
& rEditMask
,
470 USHORT nFormatFlags
, BOOL bSameMask
,
471 xub_StrLen nCursorPos
)
473 // Naechstes Zeichen suchen, was kein Literal ist
474 xub_StrLen nNewPos
= nCursorPos
;
475 xub_StrLen nTempPos
= nNewPos
;
476 while ( nTempPos
< rEditMask
.Len() )
478 if ( rEditMask
.GetChar(nTempPos
+1) != EDITMASK_LITERAL
)
480 nNewPos
= nTempPos
+1;
485 ImplPatternMaxPos( rStr
, rEditMask
, nFormatFlags
, bSameMask
, nCursorPos
, nNewPos
);
489 // -----------------------------------------------------------------------
491 static BOOL
ImplPatternProcessKeyInput( Edit
* pEdit
, const KeyEvent
& rKEvt
,
492 const ByteString
& rEditMask
,
493 const XubString
& rLiteralMask
,
499 if ( !rEditMask
.Len() || !bStrictFormat
)
502 Selection aOldSel
= pEdit
->GetSelection();
503 KeyCode aCode
= rKEvt
.GetKeyCode();
504 xub_Unicode cChar
= rKEvt
.GetCharCode();
505 USHORT nKeyCode
= aCode
.GetCode();
506 BOOL bShift
= aCode
.IsShift();
507 xub_StrLen nCursorPos
= (xub_StrLen
)aOldSel
.Max();
511 if ( nKeyCode
&& !aCode
.IsMod1() && !aCode
.IsMod2() )
513 if ( nKeyCode
== KEY_LEFT
)
515 Selection
aSel( ImplPatternLeftPos( rEditMask
, nCursorPos
) );
517 aSel
.Min() = aOldSel
.Min();
518 pEdit
->SetSelection( aSel
);
521 else if ( nKeyCode
== KEY_RIGHT
)
523 // Hier nehmen wir Selectionsanfang als minimum, da falls durch
524 // Focus alles selektiert ist, ist eine kleine Position schon
526 Selection
aSel( aOldSel
);
528 nCursorPos
= (xub_StrLen
)aSel
.Min();
529 aSel
.Max() = ImplPatternRightPos( pEdit
->GetText(), rEditMask
, nFormatFlags
, bSameMask
, nCursorPos
);
531 aSel
.Min() = aOldSel
.Min();
533 aSel
.Min() = aSel
.Max();
534 pEdit
->SetSelection( aSel
);
537 else if ( nKeyCode
== KEY_HOME
)
539 // Home ist Position des ersten nicht literalen Zeichens
541 while ( (nNewPos
< rEditMask
.Len()) &&
542 (rEditMask
.GetChar(nNewPos
) == EDITMASK_LITERAL
) )
544 // Home sollte nicht nach rechts wandern
545 if ( nCursorPos
< nNewPos
)
546 nNewPos
= nCursorPos
;
547 Selection
aSel( nNewPos
);
549 aSel
.Min() = aOldSel
.Min();
550 pEdit
->SetSelection( aSel
);
553 else if ( nKeyCode
== KEY_END
)
555 // End ist die Position des letzten nicht literalen Zeichens
556 nNewPos
= rEditMask
.Len();
558 (rEditMask
.GetChar(nNewPos
-1) == EDITMASK_LITERAL
) )
560 // Hier nehmen wir Selectionsanfang als minimum, da falls durch
561 // Focus alles selektiert ist, ist eine kleine Position schon
563 Selection
aSel( aOldSel
);
565 nCursorPos
= (xub_StrLen
)aSel
.Min();
566 ImplPatternMaxPos( pEdit
->GetText(), rEditMask
, nFormatFlags
, bSameMask
, nCursorPos
, nNewPos
);
567 aSel
.Max() = nNewPos
;
569 aSel
.Min() = aOldSel
.Min();
571 aSel
.Min() = aSel
.Max();
572 pEdit
->SetSelection( aSel
);
575 else if ( (nKeyCode
== KEY_BACKSPACE
) || (nKeyCode
== KEY_DELETE
) )
577 XubString
aStr( pEdit
->GetText() );
578 XubString aOldStr
= aStr
;
579 Selection aSel
= aOldSel
;
582 nNewPos
= (xub_StrLen
)aSel
.Min();
584 // Wenn Selection, dann diese Loeschen
588 aStr
.Erase( (xub_StrLen
)aSel
.Min(), (xub_StrLen
)aSel
.Len() );
591 XubString aRep
= rLiteralMask
.Copy( (xub_StrLen
)aSel
.Min(), (xub_StrLen
)aSel
.Len() );
592 aStr
.Replace( (xub_StrLen
)aSel
.Min(), aRep
.Len(), aRep
);
597 if ( nKeyCode
== KEY_BACKSPACE
)
600 nNewPos
= ImplPatternLeftPos( rEditMask
, nTempPos
);
603 nTempPos
= ImplPatternRightPos( aStr
, rEditMask
, nFormatFlags
, bSameMask
, nNewPos
);
605 if ( nNewPos
!= nTempPos
)
609 if ( rEditMask
.GetChar( nNewPos
) != EDITMASK_LITERAL
)
610 aStr
.Erase( nNewPos
, 1 );
614 XubString aTempStr
= rLiteralMask
.Copy( nNewPos
, 1 );
615 aStr
.Replace( nNewPos
, aTempStr
.Len(), aTempStr
);
620 if ( aOldStr
!= aStr
)
623 aStr
= ImplPatternReformat( aStr
, rEditMask
, rLiteralMask
, nFormatFlags
);
625 pEdit
->SetText( aStr
, Selection( nNewPos
) );
626 pEdit
->SetModifyFlag();
628 rbInKeyInput
= FALSE
;
631 pEdit
->SetSelection( Selection( nNewPos
) );
635 else if ( nKeyCode
== KEY_INSERT
)
637 // InsertModus kann man beim PatternField nur einstellen,
638 // wenn Maske an jeder Eingabeposition die gleiche
648 if ( rKEvt
.GetKeyCode().IsMod2() || (cChar
< 32) || (cChar
== 127) )
651 Selection aSel
= aOldSel
;
653 nNewPos
= (xub_StrLen
)aSel
.Min();
655 if ( nNewPos
< rEditMask
.Len() )
657 xub_Unicode cPattChar
= ImplPatternChar( cChar
, rEditMask
.GetChar(nNewPos
) );
662 // Wenn kein gueltiges Zeichen, dann testen wir, ob der
663 // Anwender zum naechsten Literal springen wollte. Dies machen
664 // wir nur, wenn er hinter einem Zeichen steht, damit
665 // eingebene Literale die automatisch uebersprungenen wurden
666 // nicht dazu fuehren, das der Anwender dann da steht, wo
667 // er nicht stehen wollte.
669 (rEditMask
.GetChar(nNewPos
-1) != EDITMASK_LITERAL
) &&
672 // Naechstes Zeichen suchen, was kein Literal ist
674 while ( nTempPos
< rEditMask
.Len() )
676 if ( rEditMask
.GetChar(nTempPos
) == EDITMASK_LITERAL
)
678 // Gilt nur, wenn ein Literalzeichen vorhanden
679 if ( (rEditMask
.GetChar(nTempPos
+1) != EDITMASK_LITERAL
) &&
680 ImplKommaPointCharEqual( cChar
, rLiteralMask
.GetChar(nTempPos
) ) )
683 ImplPatternMaxPos( pEdit
->GetText(), rEditMask
, nFormatFlags
, bSameMask
, nNewPos
, nTempPos
);
684 if ( nTempPos
> nNewPos
)
686 pEdit
->SetSelection( Selection( nTempPos
) );
703 XubString aStr
= pEdit
->GetText();
705 if ( bSameMask
&& pEdit
->IsInsertMode() )
707 // Text um Spacezeichen und Literale am Ende kuerzen, bis zur
708 // aktuellen Position
709 xub_StrLen n
= aStr
.Len();
710 while ( n
&& (n
> nNewPos
) )
712 if ( (aStr
.GetChar( n
-1 ) != ' ') &&
713 ((n
> rEditMask
.Len()) || (rEditMask
.GetChar(n
-1) != EDITMASK_LITERAL
)) )
721 aStr
.Erase( (xub_StrLen
)aSel
.Min(), (xub_StrLen
)aSel
.Len() );
723 if ( aStr
.Len() < rEditMask
.Len() )
725 // String evtl. noch bis Cursor-Position erweitern
726 if ( aStr
.Len() < nNewPos
)
727 aStr
+= rLiteralMask
.Copy( aStr
.Len(), nNewPos
-aStr
.Len() );
728 if ( nNewPos
< aStr
.Len() )
729 aStr
.Insert( cChar
, nNewPos
);
730 else if ( nNewPos
< rEditMask
.Len() )
732 aStr
= ImplPatternReformat( aStr
, rEditMask
, rLiteralMask
, nFormatFlags
);
741 // Selection loeschen
742 XubString aRep
= rLiteralMask
.Copy( (xub_StrLen
)aSel
.Min(), (xub_StrLen
)aSel
.Len() );
743 aStr
.Replace( (xub_StrLen
)aSel
.Min(), aRep
.Len(), aRep
);
746 if ( nNewPos
< aStr
.Len() )
747 aStr
.SetChar( nNewPos
, cChar
);
748 else if ( nNewPos
< rEditMask
.Len() )
757 Selection
aNewSel( ImplPatternRightPos( aStr
, rEditMask
, nFormatFlags
, bSameMask
, nNewPos
) );
758 pEdit
->SetText( aStr
, aNewSel
);
759 pEdit
->SetModifyFlag();
761 rbInKeyInput
= FALSE
;
770 // -----------------------------------------------------------------------
772 void PatternFormatter::ImplSetMask( const ByteString
& rEditMask
,
773 const XubString
& rLiteralMask
)
775 maEditMask
= rEditMask
;
776 maLiteralMask
= rLiteralMask
;
779 if ( maEditMask
.Len() != maLiteralMask
.Len() )
781 if ( maEditMask
.Len() < maLiteralMask
.Len() )
782 maLiteralMask
.Erase( maEditMask
.Len() );
784 maLiteralMask
.Expand( maEditMask
.Len(), ' ' );
787 // StrictModus erlaubt nur Input-Mode, wenn als Maske nur
788 // gleiche Zeichen zugelassen werden und als Vorgabe nur
789 // Spacezeichen vorgegeben werden, die durch die Maske
790 // nicht zugelassen sind
793 while ( i
< rEditMask
.Len() )
795 sal_Char cTemp
= rEditMask
.GetChar( i
);
796 if ( cTemp
!= EDITMASK_LITERAL
)
798 if ( (cTemp
== EDITMASK_ALLCHAR
) ||
799 (cTemp
== EDITMASK_UPPERALLCHAR
) ||
800 (cTemp
== EDITMASK_NUMSPACE
) )
805 if ( i
< rLiteralMask
.Len() )
807 if ( rLiteralMask
.GetChar( i
) != ' ' )
825 // -----------------------------------------------------------------------
827 PatternFormatter::PatternFormatter()
831 mbInPattKeyInput
= FALSE
;
834 // -----------------------------------------------------------------------
836 void PatternFormatter::ImplLoadRes( const ResId
& rResId
)
838 ByteString aEditMask
;
839 XubString aLiteralMask
;
840 ResMgr
* pMgr
= rResId
.GetResMgr();
843 ULONG nMask
= pMgr
->ReadLong();
845 if ( PATTERNFORMATTER_STRICTFORMAT
& nMask
)
846 SetStrictFormat( (BOOL
)pMgr
->ReadShort() );
848 if ( PATTERNFORMATTER_EDITMASK
& nMask
)
849 aEditMask
= ByteString( pMgr
->ReadString(), RTL_TEXTENCODING_ASCII_US
);
851 if ( PATTERNFORMATTER_LITTERALMASK
& nMask
)
852 aLiteralMask
= pMgr
->ReadString();
854 if ( (PATTERNFORMATTER_EDITMASK
| PATTERNFORMATTER_LITTERALMASK
) & nMask
)
855 ImplSetMask( aEditMask
, aLiteralMask
);
859 // -----------------------------------------------------------------------
861 PatternFormatter::~PatternFormatter()
865 // -----------------------------------------------------------------------
867 void PatternFormatter::SetMask( const ByteString
& rEditMask
,
868 const XubString
& rLiteralMask
)
870 ImplSetMask( rEditMask
, rLiteralMask
);
874 // -----------------------------------------------------------------------
876 void PatternFormatter::SetString( const XubString
& rStr
)
878 maFieldString
= rStr
;
881 GetField()->SetText( rStr
);
882 MarkToBeReformatted( FALSE
);
886 // -----------------------------------------------------------------------
888 XubString
PatternFormatter::GetString() const
891 return ImplGetSVEmptyStr();
893 return ImplPatternReformat( GetField()->GetText(), maEditMask
, maLiteralMask
, mnFormatFlags
);
896 // -----------------------------------------------------------------------
898 void PatternFormatter::Reformat()
902 ImplSetText( ImplPatternReformat( GetField()->GetText(), maEditMask
, maLiteralMask
, mnFormatFlags
) );
903 if ( !mbSameMask
&& IsStrictFormat() && !GetField()->IsReadOnly() )
904 GetField()->SetInsertMode( FALSE
);
908 // -----------------------------------------------------------------------
910 void PatternFormatter::SelectFixedFont()
914 Font aFont
= OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED
, Application::GetSettings().GetLanguage(), 0 );
916 aControlFont
.SetName( aFont
.GetName() );
917 aControlFont
.SetFamily( aFont
.GetFamily() );
918 aControlFont
.SetPitch( aFont
.GetPitch() );
919 GetField()->SetControlFont( aControlFont
);
923 \f// -----------------------------------------------------------------------
925 PatternField::PatternField( Window
* pParent
, WinBits nWinStyle
) :
926 SpinField( pParent
, nWinStyle
)
932 // -----------------------------------------------------------------------
934 PatternField::PatternField( Window
* pParent
, const ResId
& rResId
) :
935 SpinField( WINDOW_PATTERNFIELD
)
937 rResId
.SetRT( RSC_PATTERNFIELD
);
938 WinBits nStyle
= ImplInitRes( rResId
);
939 ImplInit( pParent
, nStyle
);
941 SpinField::ImplLoadRes( rResId
);
942 PatternFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE
*)GetClassRes(), *rResId
.GetResMgr() ) );
945 if ( !(nStyle
& WB_HIDE
) )
949 // -----------------------------------------------------------------------
951 PatternField::~PatternField()
955 // -----------------------------------------------------------------------
957 long PatternField::PreNotify( NotifyEvent
& rNEvt
)
959 if ( (rNEvt
.GetType() == EVENT_KEYINPUT
) && !rNEvt
.GetKeyEvent()->GetKeyCode().IsMod2() )
961 if ( ImplPatternProcessKeyInput( GetField(), *rNEvt
.GetKeyEvent(), GetEditMask(), GetLiteralMask(),
962 IsStrictFormat(), GetFormatFlags(),
963 ImplIsSameMask(), ImplGetInPattKeyInput() ) )
967 return SpinField::PreNotify( rNEvt
);
970 // -----------------------------------------------------------------------
972 long PatternField::Notify( NotifyEvent
& rNEvt
)
974 if ( rNEvt
.GetType() == EVENT_GETFOCUS
)
975 MarkToBeReformatted( FALSE
);
976 else if ( rNEvt
.GetType() == EVENT_LOSEFOCUS
)
978 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
982 return SpinField::Notify( rNEvt
);
985 // -----------------------------------------------------------------------
987 void PatternField::Modify()
989 if ( !ImplGetInPattKeyInput() )
991 if ( IsStrictFormat() )
992 ImplPatternProcessStrictModify( GetField(), GetEditMask(), GetLiteralMask(), GetFormatFlags(), ImplIsSameMask() );
994 MarkToBeReformatted( TRUE
);
1000 // -----------------------------------------------------------------------
1002 PatternBox::PatternBox( Window
* pParent
, WinBits nWinStyle
) :
1003 ComboBox( pParent
, nWinStyle
)
1009 // -----------------------------------------------------------------------
1011 PatternBox::PatternBox( Window
* pParent
, const ResId
& rResId
) :
1012 ComboBox( WINDOW_PATTERNBOX
)
1014 rResId
.SetRT( RSC_PATTERNBOX
);
1015 WinBits nStyle
= ImplInitRes( rResId
);
1016 ImplInit( pParent
, nStyle
);
1019 ComboBox::ImplLoadRes( rResId
);
1020 PatternFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE
*)GetClassRes(), *rResId
.GetResMgr() ) );
1023 if ( !(nStyle
& WB_HIDE
) )
1027 // -----------------------------------------------------------------------
1029 PatternBox::~PatternBox()
1033 // -----------------------------------------------------------------------
1035 long PatternBox::PreNotify( NotifyEvent
& rNEvt
)
1037 if ( (rNEvt
.GetType() == EVENT_KEYINPUT
) && !rNEvt
.GetKeyEvent()->GetKeyCode().IsMod2() )
1039 if ( ImplPatternProcessKeyInput( GetField(), *rNEvt
.GetKeyEvent(), GetEditMask(), GetLiteralMask(),
1040 IsStrictFormat(), GetFormatFlags(),
1041 ImplIsSameMask(), ImplGetInPattKeyInput() ) )
1045 return ComboBox::PreNotify( rNEvt
);
1048 // -----------------------------------------------------------------------
1050 long PatternBox::Notify( NotifyEvent
& rNEvt
)
1052 if ( rNEvt
.GetType() == EVENT_GETFOCUS
)
1053 MarkToBeReformatted( FALSE
);
1054 else if ( rNEvt
.GetType() == EVENT_LOSEFOCUS
)
1056 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
1060 return ComboBox::Notify( rNEvt
);
1063 // -----------------------------------------------------------------------
1065 void PatternBox::Modify()
1067 if ( !ImplGetInPattKeyInput() )
1069 if ( IsStrictFormat() )
1070 ImplPatternProcessStrictModify( GetField(), GetEditMask(), GetLiteralMask(), GetFormatFlags(), ImplIsSameMask() );
1072 MarkToBeReformatted( TRUE
);
1078 // -----------------------------------------------------------------------
1080 void PatternBox::ReformatAll()
1083 SetUpdateMode( FALSE
);
1084 USHORT nEntryCount
= GetEntryCount();
1085 for ( USHORT i
=0; i
< nEntryCount
; i
++ )
1087 aStr
= ImplPatternReformat( GetEntry( i
), GetEditMask(), GetLiteralMask(), GetFormatFlags() );
1089 InsertEntry( aStr
, i
);
1091 PatternFormatter::Reformat();
1092 SetUpdateMode( TRUE
);
1095 // -----------------------------------------------------------------------
1097 void PatternBox::InsertString( const XubString
& rStr
, USHORT nPos
)
1099 ComboBox::InsertEntry( ImplPatternReformat( rStr
, GetEditMask(), GetLiteralMask(), GetFormatFlags() ), nPos
);
1102 // -----------------------------------------------------------------------
1104 void PatternBox::RemoveString( const XubString
& rStr
)
1106 ComboBox::RemoveEntry( ImplPatternReformat( rStr
, GetEditMask(), GetLiteralMask(), GetFormatFlags() ) );
1109 // -----------------------------------------------------------------------
1111 XubString
PatternBox::GetString( USHORT nPos
) const
1113 return ImplPatternReformat( ComboBox::GetEntry( nPos
), GetEditMask(), GetLiteralMask(), GetFormatFlags() );
1116 // -----------------------------------------------------------------------
1118 USHORT
PatternBox::GetStringPos( const XubString
& rStr
) const
1120 return ComboBox::GetEntryPos( ImplPatternReformat( rStr
, GetEditMask(), GetLiteralMask(), GetFormatFlags() ) );
1123 // =======================================================================
1125 static ExtDateFieldFormat
ImplGetExtFormat( DateFormat eOld
)
1129 case DMY
: return XTDATEF_SHORT_DDMMYY
;
1130 case MDY
: return XTDATEF_SHORT_MMDDYY
;
1131 default: return XTDATEF_SHORT_YYMMDD
;
1135 // -----------------------------------------------------------------------
1137 static USHORT
ImplCutNumberFromString( XubString
& rStr
)
1140 while ( rStr
.Len() && !(rStr
.GetChar( 0 ) >= '0' && rStr
.GetChar( 0 ) <= '9') )
1145 while ( rStr
.Len() && (rStr
.GetChar( 0 ) >= '0' && rStr
.GetChar( 0 ) <= '9') )
1147 aNumStr
.Insert( rStr
.GetChar( 0 ) );
1150 return (USHORT
)aNumStr
.ToInt32();
1153 // -----------------------------------------------------------------------
1155 static BOOL
ImplCutMonthName( XubString
& rStr
, const XubString
& _rLookupMonthName
)
1157 USHORT nPos
= rStr
.Search( _rLookupMonthName
);
1158 if ( nPos
!= STRING_NOTFOUND
)
1160 rStr
.Erase( 0, nPos
+ _rLookupMonthName
.Len() );
1166 // -----------------------------------------------------------------------
1168 static USHORT
ImplCutMonthFromString( XubString
& rStr
, const CalendarWrapper
& rCalendarWrapper
)
1170 // search for a month' name
1171 for ( USHORT i
=1; i
<= 12; i
++ )
1173 String aMonthName
= rCalendarWrapper
.getMonths()[i
-1].FullName
;
1175 if ( ImplCutMonthName( rStr
, aMonthName
) )
1178 // short month name?
1179 String aAbbrevMonthName
= rCalendarWrapper
.getMonths()[i
-1].AbbrevName
;
1180 if ( ImplCutMonthName( rStr
, aAbbrevMonthName
) )
1184 return ImplCutNumberFromString( rStr
);
1187 // -----------------------------------------------------------------------
1189 static String
ImplGetDateSep( const LocaleDataWrapper
& rLocaleDataWrapper
, ExtDateFieldFormat eFormat
)
1191 String aDateSep
= rLocaleDataWrapper
.getDateSep();
1193 if ( ( eFormat
== XTDATEF_SHORT_YYMMDD_DIN5008
) || ( eFormat
== XTDATEF_SHORT_YYYYMMDD_DIN5008
) )
1194 aDateSep
= String( RTL_CONSTASCII_USTRINGPARAM( "-" ) );
1199 static BOOL
ImplDateProcessKeyInput( Edit
*, const KeyEvent
& rKEvt
, ExtDateFieldFormat eFormat
,
1200 const LocaleDataWrapper
& rLocaleDataWrapper
)
1202 xub_Unicode cChar
= rKEvt
.GetCharCode();
1203 USHORT nGroup
= rKEvt
.GetKeyCode().GetGroup();
1204 if ( (nGroup
== KEYGROUP_FKEYS
) || (nGroup
== KEYGROUP_CURSOR
) ||
1205 (nGroup
== KEYGROUP_MISC
)||
1206 ((cChar
>= '0') && (cChar
<= '9')) ||
1207 (cChar
== ImplGetDateSep( rLocaleDataWrapper
, eFormat
).GetChar(0) ) )
1213 // -----------------------------------------------------------------------
1215 static BOOL
ImplDateGetValue( const XubString
& rStr
, Date
& rDate
, ExtDateFieldFormat eDateFormat
,
1216 const LocaleDataWrapper
& rLocaleDataWrapper
, const CalendarWrapper
& rCalendarWrapper
,
1217 const AllSettings
& rSettings
)
1223 BOOL bError
= FALSE
;
1224 String
aStr( rStr
);
1226 if ( eDateFormat
== XTDATEF_SYSTEM_LONG
)
1228 DateFormat eFormat
= rLocaleDataWrapper
.getLongDateFormat();
1232 nMonth
= ImplCutMonthFromString( aStr
, rCalendarWrapper
);
1233 nDay
= ImplCutNumberFromString( aStr
);
1234 nYear
= ImplCutNumberFromString( aStr
);
1237 nDay
= ImplCutNumberFromString( aStr
);
1238 nMonth
= ImplCutMonthFromString( aStr
, rCalendarWrapper
);
1239 nYear
= ImplCutNumberFromString( aStr
);
1243 nYear
= ImplCutNumberFromString( aStr
);
1244 nMonth
= ImplCutMonthFromString( aStr
, rCalendarWrapper
);
1245 nDay
= ImplCutNumberFromString( aStr
);
1251 // Check if year is present:
1252 String aDateSep
= ImplGetDateSep( rLocaleDataWrapper
, eDateFormat
);
1253 USHORT nSepPos
= aStr
.Search( aDateSep
);
1254 if ( nSepPos
== STRING_NOTFOUND
)
1256 nSepPos
= aStr
.Search( aDateSep
, nSepPos
+1 );
1257 if ( ( nSepPos
== STRING_NOTFOUND
) || ( nSepPos
== (aStr
.Len()-1) ) )
1260 nYear
= Date().GetYear();
1263 const sal_Unicode
* pBuf
= aStr
.GetBuffer();
1264 ImplSkipDelimiters( pBuf
);
1266 switch ( eDateFormat
)
1268 case XTDATEF_SHORT_DDMMYY
:
1269 case XTDATEF_SHORT_DDMMYYYY
:
1271 nDay
= ImplGetNum( pBuf
, bError
);
1272 ImplSkipDelimiters( pBuf
);
1273 nMonth
= ImplGetNum( pBuf
, bError
);
1274 ImplSkipDelimiters( pBuf
);
1276 nYear
= ImplGetNum( pBuf
, bError
);
1279 case XTDATEF_SHORT_MMDDYY
:
1280 case XTDATEF_SHORT_MMDDYYYY
:
1282 nMonth
= ImplGetNum( pBuf
, bError
);
1283 ImplSkipDelimiters( pBuf
);
1284 nDay
= ImplGetNum( pBuf
, bError
);
1285 ImplSkipDelimiters( pBuf
);
1287 nYear
= ImplGetNum( pBuf
, bError
);
1290 case XTDATEF_SHORT_YYMMDD
:
1291 case XTDATEF_SHORT_YYYYMMDD
:
1292 case XTDATEF_SHORT_YYMMDD_DIN5008
:
1293 case XTDATEF_SHORT_YYYYMMDD_DIN5008
:
1296 nYear
= ImplGetNum( pBuf
, bError
);
1297 ImplSkipDelimiters( pBuf
);
1298 nMonth
= ImplGetNum( pBuf
, bError
);
1299 ImplSkipDelimiters( pBuf
);
1300 nDay
= ImplGetNum( pBuf
, bError
);
1306 DBG_ERROR( "DateFormat???" );
1311 if ( bError
|| !nDay
|| !nMonth
)
1314 Date
aNewDate( nDay
, nMonth
, nYear
);
1315 DateFormatter::ExpandCentury( aNewDate
, rSettings
.GetMiscSettings().GetTwoDigitYearStart() );
1316 if ( aNewDate
.IsValid() )
1324 // -----------------------------------------------------------------------
1326 BOOL
DateFormatter::ImplDateReformat( const XubString
& rStr
, XubString
& rOutStr
, const AllSettings
& rSettings
)
1328 Date
aDate( 0, 0, 0 );
1329 if ( !ImplDateGetValue( rStr
, aDate
, GetExtDateFormat(TRUE
), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) )
1332 Date aTempDate
= aDate
;
1333 if ( aTempDate
> GetMax() )
1334 aTempDate
= GetMax();
1335 else if ( aTempDate
< GetMin() )
1336 aTempDate
= GetMin();
1338 if ( GetErrorHdl().IsSet() && (aDate
!= aTempDate
) )
1340 maCorrectedDate
= aTempDate
;
1341 if( !GetErrorHdl().Call( this ) )
1343 maCorrectedDate
= Date();
1347 maCorrectedDate
= Date();
1350 rOutStr
= ImplGetDateAsText( aTempDate
, rSettings
);
1355 // -----------------------------------------------------------------------
1357 XubString
DateFormatter::ImplGetDateAsText( const Date
& rDate
,
1358 const AllSettings
& rSettings
) const
1360 BOOL bShowCentury
= FALSE
;
1361 switch ( GetExtDateFormat() )
1363 case XTDATEF_SYSTEM_SHORT_YYYY
:
1364 case XTDATEF_SYSTEM_LONG
:
1365 case XTDATEF_SHORT_DDMMYYYY
:
1366 case XTDATEF_SHORT_MMDDYYYY
:
1367 case XTDATEF_SHORT_YYYYMMDD
:
1368 case XTDATEF_SHORT_YYYYMMDD_DIN5008
:
1370 bShowCentury
= TRUE
;
1375 bShowCentury
= FALSE
;
1379 if ( !bShowCentury
)
1381 // Check if I have to use force showing the century
1382 USHORT nTwoDigitYearStart
= rSettings
.GetMiscSettings().GetTwoDigitYearStart();
1383 USHORT nYear
= rDate
.GetYear();
1385 // Wenn Jahr nicht im 2stelligen Grenzbereich liegt,
1386 if ( (nYear
< nTwoDigitYearStart
) || (nYear
>= nTwoDigitYearStart
+100) )
1387 bShowCentury
= TRUE
;
1390 sal_Unicode aBuf
[128];
1391 sal_Unicode
* pBuf
= aBuf
;
1393 String aDateSep
= ImplGetDateSep( ImplGetLocaleDataWrapper(), GetExtDateFormat( TRUE
) );
1394 USHORT nDay
= rDate
.GetDay();
1395 USHORT nMonth
= rDate
.GetMonth();
1396 USHORT nYear
= rDate
.GetYear();
1397 USHORT nYearLen
= bShowCentury
? 4 : 2;
1399 if ( !bShowCentury
)
1402 switch ( GetExtDateFormat( TRUE
) )
1404 case XTDATEF_SYSTEM_LONG
:
1406 return ImplGetLocaleDataWrapper().getLongDate( rDate
, GetCalendarWrapper(), 1, FALSE
, 1, !bShowCentury
);
1408 case XTDATEF_SHORT_DDMMYY
:
1409 case XTDATEF_SHORT_DDMMYYYY
:
1411 pBuf
= ImplAddNum( pBuf
, nDay
, 2 );
1412 pBuf
= ImplAddString( pBuf
, aDateSep
);
1413 pBuf
= ImplAddNum( pBuf
, nMonth
, 2 );
1414 pBuf
= ImplAddString( pBuf
, aDateSep
);
1415 pBuf
= ImplAddNum( pBuf
, nYear
, nYearLen
);
1418 case XTDATEF_SHORT_MMDDYY
:
1419 case XTDATEF_SHORT_MMDDYYYY
:
1421 pBuf
= ImplAddNum( pBuf
, nMonth
, 2 );
1422 pBuf
= ImplAddString( pBuf
, aDateSep
);
1423 pBuf
= ImplAddNum( pBuf
, nDay
, 2 );
1424 pBuf
= ImplAddString( pBuf
, aDateSep
);
1425 pBuf
= ImplAddNum( pBuf
, nYear
, nYearLen
);
1428 case XTDATEF_SHORT_YYMMDD
:
1429 case XTDATEF_SHORT_YYYYMMDD
:
1430 case XTDATEF_SHORT_YYMMDD_DIN5008
:
1431 case XTDATEF_SHORT_YYYYMMDD_DIN5008
:
1433 pBuf
= ImplAddNum( pBuf
, nYear
, nYearLen
);
1434 pBuf
= ImplAddString( pBuf
, aDateSep
);
1435 pBuf
= ImplAddNum( pBuf
, nMonth
, 2 );
1436 pBuf
= ImplAddString( pBuf
, aDateSep
);
1437 pBuf
= ImplAddNum( pBuf
, nDay
, 2 );
1442 DBG_ERROR( "DateFormat???" );
1446 return String( aBuf
, (xub_StrLen
)(ULONG
)(pBuf
-aBuf
) );
1449 // -----------------------------------------------------------------------
1451 static void ImplDateIncrementDay( Date
& rDate
, BOOL bUp
)
1453 DateFormatter::ExpandCentury( rDate
);
1457 if ( (rDate
.GetDay() != 31) || (rDate
.GetMonth() != 12) || (rDate
.GetYear() != 9999) )
1462 if ( (rDate
.GetDay() != 1 ) || (rDate
.GetMonth() != 1) || (rDate
.GetYear() != 0) )
1467 // -----------------------------------------------------------------------
1469 static void ImplDateIncrementMonth( Date
& rDate
, BOOL bUp
)
1471 DateFormatter::ExpandCentury( rDate
);
1473 USHORT nMonth
= rDate
.GetMonth();
1474 USHORT nYear
= rDate
.GetYear();
1477 if ( (nMonth
== 12) && (nYear
< 9999) )
1479 rDate
.SetMonth( 1 );
1480 rDate
.SetYear( nYear
+ 1 );
1485 rDate
.SetMonth( nMonth
+ 1 );
1490 if ( (nMonth
== 1) && (nYear
> 0) )
1492 rDate
.SetMonth( 12 );
1493 rDate
.SetYear( nYear
- 1 );
1498 rDate
.SetMonth( nMonth
- 1 );
1502 USHORT nDaysInMonth
= rDate
.GetDaysInMonth();
1503 if ( rDate
.GetDay() > nDaysInMonth
)
1504 rDate
.SetDay( nDaysInMonth
);
1507 // -----------------------------------------------------------------------
1509 static void ImplDateIncrementYear( Date
& rDate
, BOOL bUp
)
1511 DateFormatter::ExpandCentury( rDate
);
1513 USHORT nYear
= rDate
.GetYear();
1517 rDate
.SetYear( nYear
+ 1 );
1522 rDate
.SetYear( nYear
- 1 );
1526 // -----------------------------------------------------------------------
1527 BOOL
DateFormatter::ImplAllowMalformedInput() const
1529 return !IsEnforceValidValue();
1532 // -----------------------------------------------------------------------
1534 void DateField::ImplDateSpinArea( BOOL bUp
)
1536 // Wenn alles selektiert ist, Tage hochzaehlen
1539 Date
aDate( GetDate() );
1540 Selection aSelection
= GetField()->GetSelection();
1541 aSelection
.Justify();
1542 XubString
aText( GetText() );
1543 if ( (xub_StrLen
)aSelection
.Len() == aText
.Len() )
1544 ImplDateIncrementDay( aDate
, bUp
);
1547 xub_StrLen nDateArea
= 0;
1549 ExtDateFieldFormat eFormat
= GetExtDateFormat( TRUE
);
1550 if ( eFormat
== XTDATEF_SYSTEM_LONG
)
1552 eFormat
= ImplGetExtFormat( ImplGetLocaleDataWrapper().getLongDateFormat() );
1558 xub_StrLen nPos
= 0;
1559 String aDateSep
= ImplGetDateSep( ImplGetLocaleDataWrapper(), eFormat
);
1560 for ( xub_StrLen i
= 1; i
<= 3; i
++ )
1562 nPos
= aText
.Search( aDateSep
, nPos
);
1563 if ( nPos
>= (USHORT
)aSelection
.Max() )
1576 case XTDATEF_SHORT_MMDDYY
:
1577 case XTDATEF_SHORT_MMDDYYYY
:
1580 case 1: ImplDateIncrementMonth( aDate
, bUp
);
1582 case 2: ImplDateIncrementDay( aDate
, bUp
);
1584 case 3: ImplDateIncrementYear( aDate
, bUp
);
1588 case XTDATEF_SHORT_DDMMYY
:
1589 case XTDATEF_SHORT_DDMMYYYY
:
1592 case 1: ImplDateIncrementDay( aDate
, bUp
);
1594 case 2: ImplDateIncrementMonth( aDate
, bUp
);
1596 case 3: ImplDateIncrementYear( aDate
, bUp
);
1600 case XTDATEF_SHORT_YYMMDD
:
1601 case XTDATEF_SHORT_YYYYMMDD
:
1602 case XTDATEF_SHORT_YYMMDD_DIN5008
:
1603 case XTDATEF_SHORT_YYYYMMDD_DIN5008
:
1606 case 1: ImplDateIncrementYear( aDate
, bUp
);
1608 case 2: ImplDateIncrementMonth( aDate
, bUp
);
1610 case 3: ImplDateIncrementDay( aDate
, bUp
);
1615 DBG_ERROR( "invalid conversion" );
1620 ImplNewFieldValue( aDate
);
1624 // -----------------------------------------------------------------------
1626 void DateFormatter::ImplInit()
1628 mbLongFormat
= FALSE
;
1629 mbShowDateCentury
= TRUE
;
1630 mpCalendarWrapper
= NULL
;
1631 mnDateFormat
= 0xFFFF;
1632 mnExtDateFormat
= XTDATEF_SYSTEM_SHORT
;
1635 // -----------------------------------------------------------------------
1637 DateFormatter::DateFormatter() :
1640 maMin( 1, 1, 1900 ),
1641 maMax( 31, 12, 2200 ),
1642 mbEnforceValidValue( TRUE
)
1647 // -----------------------------------------------------------------------
1649 void DateFormatter::ImplLoadRes( const ResId
& rResId
)
1651 ResMgr
* pMgr
= rResId
.GetResMgr();
1654 ULONG nMask
= pMgr
->ReadLong();
1656 if ( DATEFORMATTER_MIN
& nMask
)
1658 maMin
= Date( ResId( (RSHEADER_TYPE
*)pMgr
->GetClass(), *pMgr
) );
1659 pMgr
->Increment( pMgr
->GetObjSize( (RSHEADER_TYPE
*)pMgr
->GetClass() ) );
1661 if ( DATEFORMATTER_MAX
& nMask
)
1663 maMax
= Date( ResId( (RSHEADER_TYPE
*)pMgr
->GetClass(), *pMgr
) );
1664 pMgr
->Increment( pMgr
->GetObjSize( (RSHEADER_TYPE
*)pMgr
->GetClass() ) );
1666 if ( DATEFORMATTER_LONGFORMAT
& nMask
)
1667 mbLongFormat
= (BOOL
)pMgr
->ReadShort();
1669 if ( DATEFORMATTER_STRICTFORMAT
& nMask
)
1670 SetStrictFormat( (BOOL
)pMgr
->ReadShort() );
1672 if ( DATEFORMATTER_VALUE
& nMask
)
1674 maFieldDate
= Date( ResId( (RSHEADER_TYPE
*)pMgr
->GetClass(), *pMgr
) );
1675 pMgr
->Increment( pMgr
->GetObjSize( (RSHEADER_TYPE
*)pMgr
->GetClass() ) );
1676 if ( maFieldDate
> maMax
)
1677 maFieldDate
= maMax
;
1678 if ( maFieldDate
< maMin
)
1679 maFieldDate
= maMin
;
1680 maLastDate
= maFieldDate
;
1685 // -----------------------------------------------------------------------
1687 DateFormatter::~DateFormatter()
1689 delete mpCalendarWrapper
;
1690 mpCalendarWrapper
= NULL
;
1693 // -----------------------------------------------------------------------
1695 void DateFormatter::SetLocale( const ::com::sun::star::lang::Locale
& rLocale
)
1697 delete mpCalendarWrapper
;
1698 mpCalendarWrapper
= NULL
;
1699 FormatterBase::SetLocale( rLocale
);
1703 // -----------------------------------------------------------------------
1705 CalendarWrapper
& DateFormatter::GetCalendarWrapper() const
1707 if ( !mpCalendarWrapper
)
1709 ((DateFormatter
*)this)->mpCalendarWrapper
= new CalendarWrapper( vcl::unohelper::GetMultiServiceFactory() );
1710 mpCalendarWrapper
->loadDefaultCalendar( GetLocale() );
1713 return *mpCalendarWrapper
;
1716 // -----------------------------------------------------------------------
1718 void DateFormatter::SetExtDateFormat( ExtDateFieldFormat eFormat
)
1720 mnExtDateFormat
= eFormat
;
1724 // -----------------------------------------------------------------------
1726 ExtDateFieldFormat
DateFormatter::GetExtDateFormat( BOOL bResolveSystemFormat
) const
1728 ExtDateFieldFormat eDateFormat
= (ExtDateFieldFormat
)mnExtDateFormat
;
1730 if ( bResolveSystemFormat
&& ( eDateFormat
<= XTDATEF_SYSTEM_SHORT_YYYY
) )
1732 BOOL bShowCentury
= (eDateFormat
== XTDATEF_SYSTEM_SHORT_YYYY
);
1733 switch ( ImplGetLocaleDataWrapper().getDateFormat() )
1735 case DMY
: eDateFormat
= bShowCentury
? XTDATEF_SHORT_DDMMYYYY
: XTDATEF_SHORT_DDMMYY
;
1737 case MDY
: eDateFormat
= bShowCentury
? XTDATEF_SHORT_MMDDYYYY
: XTDATEF_SHORT_MMDDYY
;
1739 default: eDateFormat
= bShowCentury
? XTDATEF_SHORT_YYYYMMDD
: XTDATEF_SHORT_YYMMDD
;
1747 // -----------------------------------------------------------------------
1749 void DateFormatter::ReformatAll()
1754 // -----------------------------------------------------------------------
1756 void DateFormatter::SetMin( const Date
& rNewMin
)
1759 if ( !IsEmptyFieldValue() )
1763 // -----------------------------------------------------------------------
1765 void DateFormatter::SetMax( const Date
& rNewMax
)
1768 if ( !IsEmptyFieldValue() )
1772 // -----------------------------------------------------------------------
1774 void DateFormatter::SetLongFormat( BOOL bLong
)
1776 mbLongFormat
= bLong
;
1778 // #91913# Remove LongFormat and DateShowCentury - redundant
1781 SetExtDateFormat( XTDATEF_SYSTEM_LONG
);
1785 if( mnExtDateFormat
== XTDATEF_SYSTEM_LONG
)
1786 SetExtDateFormat( XTDATEF_SYSTEM_SHORT
);
1792 // -----------------------------------------------------------------------
1794 void DateFormatter::SetShowDateCentury( BOOL bShowDateCentury
)
1796 mbShowDateCentury
= bShowDateCentury
;
1798 // #91913# Remove LongFormat and DateShowCentury - redundant
1799 if ( bShowDateCentury
)
1801 switch ( GetExtDateFormat() )
1803 case XTDATEF_SYSTEM_SHORT
:
1804 case XTDATEF_SYSTEM_SHORT_YY
:
1805 SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY
); break;
1806 case XTDATEF_SHORT_DDMMYY
:
1807 SetExtDateFormat( XTDATEF_SHORT_DDMMYYYY
); break;
1808 case XTDATEF_SHORT_MMDDYY
:
1809 SetExtDateFormat( XTDATEF_SHORT_MMDDYYYY
); break;
1810 case XTDATEF_SHORT_YYMMDD
:
1811 SetExtDateFormat( XTDATEF_SHORT_YYYYMMDD
); break;
1812 case XTDATEF_SHORT_YYMMDD_DIN5008
:
1813 SetExtDateFormat( XTDATEF_SHORT_YYYYMMDD_DIN5008
); break;
1820 switch ( GetExtDateFormat() )
1822 case XTDATEF_SYSTEM_SHORT
:
1823 case XTDATEF_SYSTEM_SHORT_YYYY
:
1824 SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YY
); break;
1825 case XTDATEF_SHORT_DDMMYYYY
:
1826 SetExtDateFormat( XTDATEF_SHORT_DDMMYY
); break;
1827 case XTDATEF_SHORT_MMDDYYYY
:
1828 SetExtDateFormat( XTDATEF_SHORT_MMDDYY
); break;
1829 case XTDATEF_SHORT_YYYYMMDD
:
1830 SetExtDateFormat( XTDATEF_SHORT_YYMMDD
); break;
1831 case XTDATEF_SHORT_YYYYMMDD_DIN5008
:
1832 SetExtDateFormat( XTDATEF_SHORT_YYMMDD_DIN5008
); break;
1841 // -----------------------------------------------------------------------
1843 void DateFormatter::SetDate( const Date
& rNewDate
)
1845 SetUserDate( rNewDate
);
1846 maFieldDate
= maLastDate
;
1847 maLastDate
= GetDate();
1850 // -----------------------------------------------------------------------
1852 void DateFormatter::SetUserDate( const Date
& rNewDate
)
1854 ImplSetUserDate( rNewDate
);
1857 // -----------------------------------------------------------------------
1859 void DateFormatter::ImplSetUserDate( const Date
& rNewDate
, Selection
* pNewSelection
)
1861 Date aNewDate
= rNewDate
;
1862 if ( aNewDate
> maMax
)
1864 else if ( aNewDate
< maMin
)
1866 maLastDate
= aNewDate
;
1869 ImplSetText( ImplGetDateAsText( aNewDate
, GetFieldSettings() ), pNewSelection
);
1872 // -----------------------------------------------------------------------
1874 void DateFormatter::ImplNewFieldValue( const Date
& rDate
)
1878 Selection aSelection
= GetField()->GetSelection();
1879 aSelection
.Justify();
1880 XubString aText
= GetField()->GetText();
1881 // Wenn bis ans Ende selektiert war, soll das auch so bleiben...
1882 if ( (xub_StrLen
)aSelection
.Max() == aText
.Len() )
1884 if ( !aSelection
.Len() )
1885 aSelection
.Min() = SELECTION_MAX
;
1886 aSelection
.Max() = SELECTION_MAX
;
1889 Date aOldLastDate
= maLastDate
;
1890 ImplSetUserDate( rDate
, &aSelection
);
1891 maLastDate
= aOldLastDate
;
1893 // Modify am Edit wird nur bei KeyInput gesetzt...
1894 if ( GetField()->GetText() != aText
)
1896 GetField()->SetModifyFlag();
1897 GetField()->Modify();
1902 // -----------------------------------------------------------------------
1904 Date
DateFormatter::GetDate() const
1906 Date
aDate( 0, 0, 0 );
1910 if ( ImplDateGetValue( GetField()->GetText(), aDate
, GetExtDateFormat(TRUE
), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) )
1912 if ( aDate
> maMax
)
1914 else if ( aDate
< maMin
)
1919 // !!! TH-18.2.99: Wenn wir Zeit haben sollte einmal
1920 // !!! geklaert werden, warum dieses beim Datum gegenueber
1921 // !!! allen anderen Feldern anders behandelt wird.
1922 // !!! Siehe dazu Bug: 52304
1924 if ( !ImplAllowMalformedInput() )
1926 if ( maLastDate
.GetDate() )
1928 else if ( !IsEmptyFieldValueEnabled() )
1932 aDate
= GetInvalidDate();
1939 // -----------------------------------------------------------------------
1941 Date
DateFormatter::GetRealDate() const
1943 // !!! TH-18.2.99: Wenn wir Zeit haben sollte dieses auch einmal
1944 // !!! fuer die Numeric-Klassen eingebaut werden.
1946 Date
aDate( 0, 0, 0 );
1950 if ( !ImplDateGetValue( GetField()->GetText(), aDate
, GetExtDateFormat(TRUE
), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) )
1951 if ( ImplAllowMalformedInput() )
1952 aDate
= GetInvalidDate();
1958 // -----------------------------------------------------------------------
1960 void DateFormatter::SetEmptyDate()
1962 FormatterBase::SetEmptyFieldValue();
1965 // -----------------------------------------------------------------------
1967 BOOL
DateFormatter::IsEmptyDate() const
1969 BOOL bEmpty
= FormatterBase::IsEmptyFieldValue();
1971 if ( GetField() && MustBeReformatted() && IsEmptyFieldValueEnabled() )
1973 if ( !GetField()->GetText().Len() )
1977 else if ( !maLastDate
.GetDate() )
1980 bEmpty
= !ImplDateGetValue( GetField()->GetText(), aDate
, GetExtDateFormat(TRUE
), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() );
1986 // -----------------------------------------------------------------------
1988 BOOL
DateFormatter::IsDateModified() const
1990 if ( ImplGetEmptyFieldValue() )
1991 return !IsEmptyDate();
1992 else if ( GetDate() != maFieldDate
)
1998 // -----------------------------------------------------------------------
2000 void DateFormatter::Reformat()
2005 if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() )
2009 BOOL bOK
= ImplDateReformat( GetField()->GetText(), aStr
, GetFieldSettings() );
2015 ImplSetText( aStr
);
2016 ImplDateGetValue( aStr
, maLastDate
, GetExtDateFormat(TRUE
), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() );
2020 if ( maLastDate
.GetDate() )
2021 SetDate( maLastDate
);
2022 else if ( !IsEmptyFieldValueEnabled() )
2026 ImplSetText( ImplGetSVEmptyStr() );
2027 SetEmptyFieldValueData( TRUE
);
2032 // -----------------------------------------------------------------------
2034 void DateFormatter::ExpandCentury( Date
& rDate
)
2036 ExpandCentury( rDate
, Application::GetSettings().GetMiscSettings().GetTwoDigitYearStart() );
2039 // -----------------------------------------------------------------------
2041 void DateFormatter::ExpandCentury( Date
& rDate
, USHORT nTwoDigitYearStart
)
2043 USHORT nDateYear
= rDate
.GetYear();
2044 if ( nDateYear
< 100 )
2046 USHORT nCentury
= nTwoDigitYearStart
/ 100;
2047 if ( nDateYear
< (nTwoDigitYearStart
% 100) )
2049 rDate
.SetYear( nDateYear
+ (nCentury
*100) );
2053 // -----------------------------------------------------------------------
2055 DateField::DateField( Window
* pParent
, WinBits nWinStyle
) :
2056 SpinField( pParent
, nWinStyle
),
2057 maFirst( GetMin() ),
2061 SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) );
2066 // -----------------------------------------------------------------------
2068 DateField::DateField( Window
* pParent
, const ResId
& rResId
) :
2069 SpinField( WINDOW_DATEFIELD
),
2070 maFirst( GetMin() ),
2073 rResId
.SetRT( RSC_DATEFIELD
);
2074 WinBits nStyle
= ImplInitRes( rResId
);
2075 SpinField::ImplInit( pParent
, nStyle
);
2077 SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) );
2078 ImplLoadRes( rResId
);
2080 if ( !(nStyle
& WB_HIDE
) )
2086 // -----------------------------------------------------------------------
2088 void DateField::ImplLoadRes( const ResId
& rResId
)
2090 SpinField::ImplLoadRes( rResId
);
2092 ResMgr
* pMgr
= rResId
.GetResMgr();
2095 DateFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
2097 ULONG nMask
= ReadLongRes();
2098 if ( DATEFIELD_FIRST
& nMask
)
2100 maFirst
= Date( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
2101 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE
*)GetClassRes() ) );
2103 if ( DATEFIELD_LAST
& nMask
)
2105 maLast
= Date( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
2106 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE
*)GetClassRes() ) );
2113 // -----------------------------------------------------------------------
2115 DateField::~DateField()
2119 // -----------------------------------------------------------------------
2121 long DateField::PreNotify( NotifyEvent
& rNEvt
)
2123 if ( (rNEvt
.GetType() == EVENT_KEYINPUT
) && IsStrictFormat() &&
2124 ( GetExtDateFormat() != XTDATEF_SYSTEM_LONG
) &&
2125 !rNEvt
.GetKeyEvent()->GetKeyCode().IsMod2() )
2127 if ( ImplDateProcessKeyInput( GetField(), *rNEvt
.GetKeyEvent(), GetExtDateFormat( TRUE
), ImplGetLocaleDataWrapper() ) )
2131 return SpinField::PreNotify( rNEvt
);
2134 // -----------------------------------------------------------------------
2136 long DateField::Notify( NotifyEvent
& rNEvt
)
2138 if ( rNEvt
.GetType() == EVENT_GETFOCUS
)
2139 MarkToBeReformatted( FALSE
);
2140 else if ( rNEvt
.GetType() == EVENT_LOSEFOCUS
)
2142 if ( MustBeReformatted() )
2144 // !!! TH-18.2.99: Wenn wir Zeit haben sollte einmal
2145 // !!! geklaert werden, warum dieses beim Datum gegenueber
2146 // !!! allen anderen Feldern anders behandelt wird.
2147 // !!! Siehe dazu Bug: 52304
2149 BOOL bTextLen
= GetText().Len() != 0;
2150 if ( bTextLen
|| !IsEmptyFieldValueEnabled() )
2152 if ( !ImplAllowMalformedInput() )
2156 Date
aDate( 0, 0, 0 );
2157 if ( ImplDateGetValue( GetText(), aDate
, GetExtDateFormat(TRUE
), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) )
2158 // even with strict text analysis, our text is a valid date -> do a complete
2163 else if ( !bTextLen
&& IsEmptyFieldValueEnabled() )
2166 SetEmptyFieldValueData( TRUE
);
2171 return SpinField::Notify( rNEvt
);
2174 // -----------------------------------------------------------------------
2176 void DateField::DataChanged( const DataChangedEvent
& rDCEvt
)
2178 SpinField::DataChanged( rDCEvt
);
2180 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) && (rDCEvt
.GetFlags() & (SETTINGS_LOCALE
|SETTINGS_MISC
)) )
2182 if ( IsDefaultLocale() && ( rDCEvt
.GetFlags() & SETTINGS_LOCALE
) )
2183 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
2188 // -----------------------------------------------------------------------
2190 void DateField::Modify()
2192 MarkToBeReformatted( TRUE
);
2193 SpinField::Modify();
2196 // -----------------------------------------------------------------------
2198 void DateField::Up()
2200 ImplDateSpinArea( TRUE
);
2204 // -----------------------------------------------------------------------
2206 void DateField::Down()
2208 ImplDateSpinArea( FALSE
);
2212 // -----------------------------------------------------------------------
2214 void DateField::First()
2216 ImplNewFieldValue( maFirst
);
2220 // -----------------------------------------------------------------------
2222 void DateField::Last()
2224 ImplNewFieldValue( maLast
);
2228 // -----------------------------------------------------------------------
2230 DateBox::DateBox( Window
* pParent
, WinBits nWinStyle
) :
2231 ComboBox( pParent
, nWinStyle
)
2234 SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) );
2238 // -----------------------------------------------------------------------
2240 DateBox::DateBox( Window
* pParent
, const ResId
& rResId
) :
2241 ComboBox( WINDOW_DATEBOX
)
2243 rResId
.SetRT( RSC_DATEBOX
);
2244 WinBits nStyle
= ImplInitRes( rResId
);
2245 ComboBox::ImplInit( pParent
, nStyle
);
2247 SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) );
2248 ComboBox::ImplLoadRes( rResId
);
2249 ResMgr
* pMgr
= rResId
.GetResMgr();
2251 DateFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
2254 if ( !( nStyle
& WB_HIDE
) )
2258 // -----------------------------------------------------------------------
2264 // -----------------------------------------------------------------------
2266 long DateBox::PreNotify( NotifyEvent
& rNEvt
)
2268 if ( (rNEvt
.GetType() == EVENT_KEYINPUT
) && IsStrictFormat() &&
2269 ( GetExtDateFormat() != XTDATEF_SYSTEM_LONG
) &&
2270 !rNEvt
.GetKeyEvent()->GetKeyCode().IsMod2() )
2272 if ( ImplDateProcessKeyInput( GetField(), *rNEvt
.GetKeyEvent(), GetExtDateFormat( TRUE
), ImplGetLocaleDataWrapper() ) )
2276 return ComboBox::PreNotify( rNEvt
);
2279 // -----------------------------------------------------------------------
2281 void DateBox::DataChanged( const DataChangedEvent
& rDCEvt
)
2283 ComboBox::DataChanged( rDCEvt
);
2285 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) && (rDCEvt
.GetFlags() & SETTINGS_LOCALE
) )
2287 if ( IsDefaultLocale() )
2288 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
2293 // -----------------------------------------------------------------------
2295 long DateBox::Notify( NotifyEvent
& rNEvt
)
2297 if ( rNEvt
.GetType() == EVENT_GETFOCUS
)
2298 MarkToBeReformatted( FALSE
);
2299 else if ( rNEvt
.GetType() == EVENT_LOSEFOCUS
)
2301 if ( MustBeReformatted() )
2303 BOOL bTextLen
= GetText().Len() != 0;
2304 if ( bTextLen
|| !IsEmptyFieldValueEnabled() )
2306 else if ( !bTextLen
&& IsEmptyFieldValueEnabled() )
2309 SetEmptyFieldValueData( TRUE
);
2314 return ComboBox::Notify( rNEvt
);
2317 // -----------------------------------------------------------------------
2319 void DateBox::Modify()
2321 MarkToBeReformatted( TRUE
);
2325 // -----------------------------------------------------------------------
2327 void DateBox::ReformatAll()
2330 SetUpdateMode( FALSE
);
2331 USHORT nEntryCount
= GetEntryCount();
2332 for ( USHORT i
=0; i
< nEntryCount
; i
++ )
2334 ImplDateReformat( GetEntry( i
), aStr
, GetFieldSettings() );
2336 InsertEntry( aStr
, i
);
2338 DateFormatter::Reformat();
2339 SetUpdateMode( TRUE
);
2342 // -----------------------------------------------------------------------
2344 void DateBox::InsertDate( const Date
& rDate
, USHORT nPos
)
2347 if ( aDate
> GetMax() )
2349 else if ( aDate
< GetMin() )
2352 ComboBox::InsertEntry( ImplGetDateAsText( aDate
, GetFieldSettings() ), nPos
);
2355 // -----------------------------------------------------------------------
2357 void DateBox::RemoveDate( const Date
& rDate
)
2359 ComboBox::RemoveEntry( ImplGetDateAsText( rDate
, GetFieldSettings() ) );
2362 // -----------------------------------------------------------------------
2364 Date
DateBox::GetDate( USHORT nPos
) const
2366 Date
aDate( 0, 0, 0 );
2367 ImplDateGetValue( ComboBox::GetEntry( nPos
), aDate
, GetExtDateFormat(TRUE
), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetSettings() );
2371 // -----------------------------------------------------------------------
2373 USHORT
DateBox::GetDatePos( const Date
& rDate
) const
2376 if ( IsLongFormat() )
2377 aStr
= ImplGetLocaleDataWrapper().getLongDate( rDate
, GetCalendarWrapper(), 1, FALSE
, 1, !IsShowDateCentury() );
2379 aStr
= ImplGetLocaleDataWrapper().getDate( rDate
);
2380 return ComboBox::GetEntryPos( aStr
);
2383 // -----------------------------------------------------------------------
2385 static BOOL
ImplTimeProcessKeyInput( Edit
*, const KeyEvent
& rKEvt
,
2386 BOOL bStrictFormat
, BOOL bDuration
,
2387 TimeFieldFormat eFormat
,
2388 const LocaleDataWrapper
& rLocaleDataWrapper
)
2390 xub_Unicode cChar
= rKEvt
.GetCharCode();
2392 if ( !bStrictFormat
)
2396 USHORT nGroup
= rKEvt
.GetKeyCode().GetGroup();
2397 if ( (nGroup
== KEYGROUP_FKEYS
) || (nGroup
== KEYGROUP_CURSOR
) ||
2398 (nGroup
== KEYGROUP_MISC
) ||
2399 ((cChar
>= '0') && (cChar
<= '9')) ||
2400 (cChar
== rLocaleDataWrapper
.getTimeSep()) ||
2401 ( ( rLocaleDataWrapper
.getTimeAM().Search( cChar
) != STRING_NOTFOUND
) ) ||
2402 ( ( rLocaleDataWrapper
.getTimePM().Search( cChar
) != STRING_NOTFOUND
) ) ||
2404 (cChar
== 'a') || (cChar
== 'A') || (cChar
== 'm') || (cChar
== 'M') || (cChar
== 'p') || (cChar
== 'P') ||
2405 ((eFormat
== TIMEF_100TH_SEC
) && (cChar
== rLocaleDataWrapper
.getTime100SecSep())) ||
2406 ((eFormat
== TIMEF_SEC_CS
) && (cChar
== rLocaleDataWrapper
.getTime100SecSep())) ||
2407 (bDuration
&& (cChar
== '-')) )
2414 // -----------------------------------------------------------------------
2416 static BOOL
ImplIsOnlyDigits( const String
& _rStr
)
2418 const sal_Unicode
* _pChr
= _rStr
.GetBuffer();
2419 for ( xub_StrLen i
= 0; i
< _rStr
.Len(); ++i
, ++_pChr
)
2421 if ( *_pChr
< '0' || *_pChr
> '9' )
2427 // -----------------------------------------------------------------------
2429 static BOOL
ImplIsValidTimePortion( BOOL _bSkipInvalidCharacters
, const String
& _rStr
)
2431 if ( !_bSkipInvalidCharacters
)
2433 if ( ( _rStr
.Len() > 2 ) || ( _rStr
.Len() < 1 ) || !ImplIsOnlyDigits( _rStr
) )
2439 // -----------------------------------------------------------------------
2441 static BOOL
ImplCutTimePortion( String
& _rStr
, xub_StrLen _nSepPos
, BOOL _bSkipInvalidCharacters
, short* _pPortion
)
2443 String sPortion
= _rStr
.Copy( 0, _nSepPos
);
2444 _rStr
.Erase( 0, _nSepPos
+ 1 );
2446 if ( !ImplIsValidTimePortion( _bSkipInvalidCharacters
, sPortion
) )
2448 *_pPortion
= (short)sPortion
.ToInt32();
2452 // -----------------------------------------------------------------------
2454 static BOOL
ImplTimeGetValue( const XubString
& rStr
, Time
& rTime
,
2455 TimeFieldFormat eFormat
, BOOL bDuration
,
2456 const LocaleDataWrapper
& rLocaleDataWrapper
, BOOL _bSkipInvalidCharacters
= TRUE
)
2458 XubString aStr
= rStr
;
2463 Time
aTime( 0, 0, 0 );
2468 // Nach Separatoren suchen
2469 if ( rLocaleDataWrapper
.getTimeSep().Len() )
2471 XubString
aSepStr( RTL_CONSTASCII_USTRINGPARAM( ",.;:/" ) );
2473 aSepStr
.Append( '-' );
2475 // Die obigen Zeichen durch das Separatorzeichen ersetzen
2476 for ( xub_StrLen i
= 0; i
< aSepStr
.Len(); i
++ )
2478 if ( aSepStr
.GetChar( i
) == rLocaleDataWrapper
.getTimeSep() )
2480 for ( xub_StrLen j
= 0; j
< aStr
.Len(); j
++ )
2482 if ( aStr
.GetChar( j
) == aSepStr
.GetChar( i
) )
2483 aStr
.SetChar( j
, rLocaleDataWrapper
.getTimeSep().GetChar(0) );
2488 BOOL bNegative
= FALSE
;
2489 xub_StrLen nSepPos
= aStr
.Search( rLocaleDataWrapper
.getTimeSep() );
2490 if ( aStr
.GetChar( 0 ) == '-' )
2492 if ( eFormat
!= TIMEF_SEC_CS
)
2494 if ( nSepPos
== STRING_NOTFOUND
)
2495 nSepPos
= aStr
.Len();
2496 if ( !ImplCutTimePortion( aStr
, nSepPos
, _bSkipInvalidCharacters
, &nHour
) )
2499 nSepPos
= aStr
.Search( rLocaleDataWrapper
.getTimeSep() );
2500 if ( aStr
.GetChar( 0 ) == '-' )
2502 if ( nSepPos
!= STRING_NOTFOUND
)
2504 if ( !ImplCutTimePortion( aStr
, nSepPos
, _bSkipInvalidCharacters
, &nMinute
) )
2507 nSepPos
= aStr
.Search( rLocaleDataWrapper
.getTimeSep() );
2508 if ( aStr
.GetChar( 0 ) == '-' )
2510 if ( nSepPos
!= STRING_NOTFOUND
)
2512 if ( !ImplCutTimePortion( aStr
, nSepPos
, _bSkipInvalidCharacters
, &nSecond
) )
2514 if ( aStr
.GetChar( 0 ) == '-' )
2516 n100Sec
= (short)aStr
.ToInt32();
2519 nSecond
= (short)aStr
.ToInt32();
2522 nMinute
= (short)aStr
.ToInt32();
2524 else if ( nSepPos
== STRING_NOTFOUND
)
2526 nSecond
= (short)aStr
.ToInt32();
2527 nMinute
+= nSecond
/ 60;
2529 nHour
+= nMinute
/ 60;
2534 nSecond
= (short)aStr
.Copy( 0, nSepPos
).ToInt32();
2535 aStr
.Erase( 0, nSepPos
+1 );
2537 nSepPos
= aStr
.Search( rLocaleDataWrapper
.getTimeSep() );
2538 if ( aStr
.GetChar( 0 ) == '-' )
2540 if ( nSepPos
!= STRING_NOTFOUND
)
2543 nSecond
= (short)aStr
.Copy( 0, nSepPos
).ToInt32();
2544 aStr
.Erase( 0, nSepPos
+1 );
2546 nSepPos
= aStr
.Search( rLocaleDataWrapper
.getTimeSep() );
2547 if ( aStr
.GetChar( 0 ) == '-' )
2549 if ( nSepPos
!= STRING_NOTFOUND
)
2553 nSecond
= (short)aStr
.Copy( 0, nSepPos
).ToInt32();
2554 aStr
.Erase( 0, nSepPos
+1 );
2558 nHour
+= nMinute
/ 60;
2564 nMinute
+= nSecond
/ 60;
2566 nHour
+= nMinute
/ 60;
2569 n100Sec
= (short)aStr
.ToInt32();
2573 xub_StrLen nLen
= 1; // mindestens eine Ziffer, weil sonst n100Sec==0
2575 while ( aStr
.GetChar(nLen
) >= '0' && aStr
.GetChar(nLen
) <= '9' )
2582 n100Sec
= n100Sec
/ 10;
2585 // Rundung bei negativen Zahlen???
2586 n100Sec
= (n100Sec
+ 5) / 10;
2592 n100Sec
= n100Sec
* 10;
2599 if ( (nMinute
> 59) || (nSecond
> 59) || (n100Sec
> 100) )
2602 if ( eFormat
== TIMEF_NONE
)
2603 nSecond
= n100Sec
= 0;
2604 else if ( eFormat
== TIMEF_SEC
)
2609 if ( bNegative
|| (nHour
< 0) || (nMinute
< 0) ||
2610 (nSecond
< 0) || (n100Sec
< 0) )
2613 aStr
.ToUpperAscii();
2614 XubString
aAM( rLocaleDataWrapper
.getTimeAM() );
2615 XubString
aPM( rLocaleDataWrapper
.getTimePM() );
2618 XubString
aAM2( RTL_CONSTASCII_USTRINGPARAM( "AM" ) ); // aAM is localized
2619 XubString
aPM2( RTL_CONSTASCII_USTRINGPARAM( "PM" ) ); // aPM is localized
2621 if ( (nHour
< 12) && ( ( aStr
.Search( aPM
) != STRING_NOTFOUND
) || ( aStr
.Search( aPM2
) != STRING_NOTFOUND
) ) )
2624 if ( (nHour
== 12) && ( ( aStr
.Search( aAM
) != STRING_NOTFOUND
) || ( aStr
.Search( aAM2
) != STRING_NOTFOUND
) ) )
2627 aTime
= Time( (USHORT
)nHour
, (USHORT
)nMinute
, (USHORT
)nSecond
,
2632 if ( bNegative
|| (nHour
< 0) || (nMinute
< 0) ||
2633 (nSecond
< 0) || (n100Sec
< 0) )
2636 nHour
= nHour
< 0 ? -nHour
: nHour
;
2637 nMinute
= nMinute
< 0 ? -nMinute
: nMinute
;
2638 nSecond
= nSecond
< 0 ? -nSecond
: nSecond
;
2639 n100Sec
= n100Sec
< 0 ? -n100Sec
: n100Sec
;
2642 aTime
= Time( (USHORT
)nHour
, (USHORT
)nMinute
, (USHORT
)nSecond
,
2653 // -----------------------------------------------------------------------
2655 BOOL
TimeFormatter::ImplTimeReformat( const XubString
& rStr
, XubString
& rOutStr
)
2657 Time
aTime( 0, 0, 0 );
2658 if ( !ImplTimeGetValue( rStr
, aTime
, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper() ) )
2661 Time aTempTime
= aTime
;
2662 if ( aTempTime
> GetMax() )
2663 aTempTime
= GetMax() ;
2664 else if ( aTempTime
< GetMin() )
2665 aTempTime
= GetMin();
2667 if ( GetErrorHdl().IsSet() && (aTime
!= aTempTime
) )
2669 maCorrectedTime
= aTempTime
;
2670 if ( !GetErrorHdl().Call( this ) )
2672 maCorrectedTime
= Time();
2676 maCorrectedTime
= Time();
2679 BOOL bSecond
= FALSE
;
2680 BOOL b100Sec
= FALSE
;
2681 if ( meFormat
!= TIMEF_NONE
)
2683 if ( meFormat
== TIMEF_100TH_SEC
)
2686 if ( meFormat
== TIMEF_SEC_CS
)
2688 ULONG n
= aTempTime
.GetHour() * 3600L;
2689 n
+= aTempTime
.GetMin() * 60L;
2690 n
+= aTempTime
.GetSec();
2691 rOutStr
= String::CreateFromInt32( n
);
2692 rOutStr
+= ImplGetLocaleDataWrapper().getTime100SecSep();
2693 if ( aTempTime
.Get100Sec() < 10 )
2695 rOutStr
+= String::CreateFromInt32( aTempTime
.Get100Sec() );
2697 else if ( mbDuration
)
2698 rOutStr
= ImplGetLocaleDataWrapper().getDuration( aTempTime
, bSecond
, b100Sec
);
2701 rOutStr
= ImplGetLocaleDataWrapper().getTime( aTempTime
, bSecond
, b100Sec
);
2702 if ( GetTimeFormat() == HOUR_12
)
2704 if ( aTempTime
.GetHour() > 12 )
2706 Time
aT( aTempTime
);
2707 aT
.SetHour( aT
.GetHour() % 12 );
2708 rOutStr
= ImplGetLocaleDataWrapper().getTime( aT
, bSecond
, b100Sec
);
2710 // Don't use LocaleDataWrapper, we want AM/PM
2711 if ( aTempTime
.GetHour() < 12 )
2712 rOutStr
+= String( RTL_CONSTASCII_USTRINGPARAM( "AM" ) ); // ImplGetLocaleDataWrapper().getTimeAM();
2714 rOutStr
+= String( RTL_CONSTASCII_USTRINGPARAM( "PM" ) ); // ImplGetLocaleDataWrapper().getTimePM();
2721 // -----------------------------------------------------------------------
2722 BOOL
TimeFormatter::ImplAllowMalformedInput() const
2724 return !IsEnforceValidValue();
2727 // -----------------------------------------------------------------------
2729 void TimeField::ImplTimeSpinArea( BOOL bUp
)
2733 xub_StrLen nTimeArea
= 0;
2734 Time
aTime( GetTime() );
2735 XubString
aText( GetText() );
2736 Selection
aSelection( GetField()->GetSelection() );
2739 if ( GetFormat() != TIMEF_SEC_CS
)
2741 for ( xub_StrLen i
= 1, nPos
= 0; i
<= 4; i
++ )
2743 xub_StrLen nPos1
= aText
.Search( ImplGetLocaleDataWrapper().getTimeSep(), nPos
);
2744 xub_StrLen nPos2
= aText
.Search( ImplGetLocaleDataWrapper().getTime100SecSep(), nPos
);
2745 nPos
= nPos1
< nPos2
? nPos1
: nPos2
;
2746 if ( nPos
>= (xub_StrLen
)aSelection
.Max() )
2757 xub_StrLen nPos
= aText
.Search( ImplGetLocaleDataWrapper().getTime100SecSep() );
2758 if ( nPos
== STRING_NOTFOUND
|| nPos
>= (xub_StrLen
)aSelection
.Max() )
2766 Time
aAddTime( 0, 0, 0 );
2767 if ( nTimeArea
== 1 )
2768 aAddTime
= Time( 1, 0 );
2769 else if ( nTimeArea
== 2 )
2770 aAddTime
= Time( 0, 1 );
2771 else if ( nTimeArea
== 3 )
2772 aAddTime
= Time( 0, 0, 1 );
2773 else if ( nTimeArea
== 4 )
2774 aAddTime
= Time( 0, 0, 0, 1 );
2777 aAddTime
= -aAddTime
;
2780 if ( !IsDuration() )
2782 Time
aAbsMaxTime( 23, 59, 59, 99 );
2783 if ( aTime
> aAbsMaxTime
)
2784 aTime
= aAbsMaxTime
;
2785 Time
aAbsMinTime( 0, 0 );
2786 if ( aTime
< aAbsMinTime
)
2787 aTime
= aAbsMinTime
;
2789 ImplNewFieldValue( aTime
);
2795 // -----------------------------------------------------------------------
2797 void TimeFormatter::ImplInit()
2799 meFormat
= TIMEF_NONE
;
2801 mnTimeFormat
= HOUR_24
; // Should become a ExtTimeFieldFormat in next implementation, merge with mbDuration and meFormat
2804 // -----------------------------------------------------------------------
2806 TimeFormatter::TimeFormatter() :
2809 maMax( 23, 59, 59, 99 ),
2810 mbEnforceValidValue( TRUE
),
2816 // -----------------------------------------------------------------------
2818 void TimeFormatter::ImplLoadRes( const ResId
& rResId
)
2820 ResMgr
* pMgr
= rResId
.GetResMgr();
2823 ULONG nMask
= pMgr
->ReadLong();
2825 if ( TIMEFORMATTER_MIN
& nMask
)
2827 SetMin( Time( ResId( (RSHEADER_TYPE
*)pMgr
->GetClass(), *pMgr
) ) );
2828 pMgr
->Increment( pMgr
->GetObjSize( (RSHEADER_TYPE
*)pMgr
->GetClass() ) );
2831 if ( TIMEFORMATTER_MAX
& nMask
)
2833 SetMax( Time( ResId( (RSHEADER_TYPE
*)pMgr
->GetClass(), *pMgr
) ) );
2834 pMgr
->Increment( pMgr
->GetObjSize( (RSHEADER_TYPE
*)pMgr
->GetClass() ) );
2837 if ( TIMEFORMATTER_TIMEFIELDFORMAT
& nMask
)
2838 meFormat
= (TimeFieldFormat
)pMgr
->ReadLong();
2840 if ( TIMEFORMATTER_DURATION
& nMask
)
2841 mbDuration
= (BOOL
)pMgr
->ReadShort();
2843 if ( TIMEFORMATTER_STRICTFORMAT
& nMask
)
2844 SetStrictFormat( (BOOL
)pMgr
->ReadShort() );
2846 if ( TIMEFORMATTER_VALUE
& nMask
)
2848 maFieldTime
= Time( ResId( (RSHEADER_TYPE
*)pMgr
->GetClass(), *pMgr
) );
2849 if ( maFieldTime
> GetMax() )
2850 maFieldTime
= GetMax();
2851 if ( maFieldTime
< GetMin() )
2852 maFieldTime
= GetMin();
2853 maLastTime
= maFieldTime
;
2855 pMgr
->Increment( pMgr
->GetObjSize( (RSHEADER_TYPE
*)pMgr
->GetClass() ) );
2860 // -----------------------------------------------------------------------
2862 TimeFormatter::~TimeFormatter()
2866 // -----------------------------------------------------------------------
2868 void TimeFormatter::ReformatAll()
2873 // -----------------------------------------------------------------------
2875 void TimeFormatter::SetMin( const Time
& rNewMin
)
2878 if ( !IsEmptyFieldValue() )
2882 // -----------------------------------------------------------------------
2884 void TimeFormatter::SetMax( const Time
& rNewMax
)
2887 if ( !IsEmptyFieldValue() )
2891 // -----------------------------------------------------------------------
2893 void TimeFormatter::SetTimeFormat( TimeFormatter::TimeFormat eNewFormat
)
2895 mnTimeFormat
= sal::static_int_cast
<USHORT
>(eNewFormat
);
2898 // -----------------------------------------------------------------------
2900 TimeFormatter::TimeFormat
TimeFormatter::GetTimeFormat() const
2902 return (TimeFormat
)mnTimeFormat
;
2905 // -----------------------------------------------------------------------
2907 void TimeFormatter::SetFormat( TimeFieldFormat eNewFormat
)
2909 meFormat
= eNewFormat
;
2913 // -----------------------------------------------------------------------
2915 void TimeFormatter::SetDuration( BOOL bNewDuration
)
2917 mbDuration
= bNewDuration
;
2921 // -----------------------------------------------------------------------
2923 void TimeFormatter::SetTime( const Time
& rNewTime
)
2925 SetUserTime( rNewTime
);
2926 maFieldTime
= maLastTime
;
2927 SetEmptyFieldValueData( FALSE
);
2930 // -----------------------------------------------------------------------
2932 void TimeFormatter::ImplNewFieldValue( const Time
& rTime
)
2936 Selection aSelection
= GetField()->GetSelection();
2937 aSelection
.Justify();
2938 XubString aText
= GetField()->GetText();
2939 // Wenn bis ans Ende selektiert war, soll das auch so bleiben...
2940 if ( (xub_StrLen
)aSelection
.Max() == aText
.Len() )
2942 if ( !aSelection
.Len() )
2943 aSelection
.Min() = SELECTION_MAX
;
2944 aSelection
.Max() = SELECTION_MAX
;
2947 Time aOldLastTime
= maLastTime
;
2948 ImplSetUserTime( rTime
, &aSelection
);
2949 maLastTime
= aOldLastTime
;
2951 // Modify am Edit wird nur bei KeyInput gesetzt...
2952 if ( GetField()->GetText() != aText
)
2954 GetField()->SetModifyFlag();
2955 GetField()->Modify();
2960 // -----------------------------------------------------------------------
2962 void TimeFormatter::ImplSetUserTime( const Time
& rNewTime
, Selection
* pNewSelection
)
2964 Time aNewTime
= rNewTime
;
2965 if ( aNewTime
> GetMax() )
2966 aNewTime
= GetMax();
2967 else if ( aNewTime
< GetMin() )
2968 aNewTime
= GetMin();
2969 maLastTime
= aNewTime
;
2975 BOOL b100Sec
= FALSE
;
2976 if ( meFormat
!= TIMEF_NONE
)
2978 if ( meFormat
== TIMEF_100TH_SEC
|| meFormat
== TIMEF_SEC_CS
)
2980 if ( meFormat
== TIMEF_SEC_CS
)
2982 ULONG n
= aNewTime
.GetHour() * 3600L;
2983 n
+= aNewTime
.GetMin() * 60L;
2984 n
+= aNewTime
.GetSec();
2985 aStr
= String::CreateFromInt32( n
);
2986 aStr
+= ImplGetLocaleDataWrapper().getTime100SecSep();
2987 if ( aNewTime
.Get100Sec() < 10 )
2989 aStr
+= String::CreateFromInt32( aNewTime
.Get100Sec() );
2991 else if ( mbDuration
)
2993 aStr
= ImplGetLocaleDataWrapper().getDuration( aNewTime
, bSec
, b100Sec
);
2997 aStr
= ImplGetLocaleDataWrapper().getTime( aNewTime
, bSec
, b100Sec
);
2998 if ( GetTimeFormat() == HOUR_12
)
3000 if ( aNewTime
.GetHour() > 12 )
3002 Time
aT( aNewTime
);
3003 aT
.SetHour( aT
.GetHour() % 12 );
3004 aStr
= ImplGetLocaleDataWrapper().getTime( aT
, bSec
, b100Sec
);
3006 // Don't use LocaleDataWrapper, we want AM/PM
3007 if ( aNewTime
.GetHour() < 12 )
3008 aStr
+= String( RTL_CONSTASCII_USTRINGPARAM( "AM" ) ); // ImplGetLocaleDataWrapper().getTimeAM();
3010 aStr
+= String( RTL_CONSTASCII_USTRINGPARAM( "PM" ) ); // ImplGetLocaleDataWrapper().getTimePM();
3014 ImplSetText( aStr
, pNewSelection
);
3018 // -----------------------------------------------------------------------
3020 void TimeFormatter::SetUserTime( const Time
& rNewTime
)
3022 ImplSetUserTime( rNewTime
);
3025 // -----------------------------------------------------------------------
3027 Time
TimeFormatter::GetTime() const
3029 Time
aTime( 0, 0, 0 );
3033 BOOL bAllowMailformed
= ImplAllowMalformedInput();
3034 if ( ImplTimeGetValue( GetField()->GetText(), aTime
, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper(), !bAllowMailformed
) )
3036 if ( aTime
> GetMax() )
3038 else if ( aTime
< GetMin() )
3043 if ( bAllowMailformed
)
3044 aTime
= GetInvalidTime();
3053 // -----------------------------------------------------------------------
3055 Time
TimeFormatter::GetRealTime() const
3057 Time
aTime( 0, 0, 0 );
3061 BOOL bAllowMailformed
= ImplAllowMalformedInput();
3062 if ( !ImplTimeGetValue( GetField()->GetText(), aTime
, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper(), !bAllowMailformed
) )
3063 if ( bAllowMailformed
)
3064 aTime
= GetInvalidTime();
3070 // -----------------------------------------------------------------------
3072 BOOL
TimeFormatter::IsTimeModified() const
3074 if ( ImplGetEmptyFieldValue() )
3075 return !IsEmptyTime();
3076 else if ( GetTime() != maFieldTime
)
3082 // -----------------------------------------------------------------------
3084 void TimeFormatter::Reformat()
3089 if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() )
3093 BOOL bOK
= ImplTimeReformat( GetField()->GetText(), aStr
);
3099 ImplSetText( aStr
);
3100 ImplTimeGetValue( aStr
, maLastTime
, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper() );
3103 SetTime( maLastTime
);
3106 // -----------------------------------------------------------------------
3108 TimeField::TimeField( Window
* pParent
, WinBits nWinStyle
) :
3109 SpinField( pParent
, nWinStyle
),
3110 maFirst( GetMin() ),
3114 SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime
, FALSE
, FALSE
) );
3118 // -----------------------------------------------------------------------
3120 TimeField::TimeField( Window
* pParent
, const ResId
& rResId
) :
3121 SpinField( WINDOW_TIMEFIELD
),
3122 maFirst( GetMin() ),
3125 rResId
.SetRT( RSC_TIMEFIELD
);
3126 WinBits nStyle
= ImplInitRes( rResId
);
3127 SpinField::ImplInit( pParent
, nStyle
);
3129 SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime
, FALSE
, FALSE
) );
3130 ImplLoadRes( rResId
);
3132 if ( !(nStyle
& WB_HIDE
) )
3136 // -----------------------------------------------------------------------
3138 void TimeField::ImplLoadRes( const ResId
& rResId
)
3140 SpinField::ImplLoadRes( rResId
);
3141 ResMgr
* pMgr
= rResId
.GetResMgr();
3144 TimeFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
3146 ULONG nMask
= ReadLongRes();
3148 if ( TIMEFIELD_FIRST
& nMask
)
3150 maFirst
= Time( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
3151 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE
*)GetClassRes() ) );
3153 if ( TIMEFIELD_LAST
& nMask
)
3155 maLast
= Time( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
3156 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE
*)GetClassRes() ) );
3163 // -----------------------------------------------------------------------
3165 TimeField::~TimeField()
3169 // -----------------------------------------------------------------------
3171 long TimeField::PreNotify( NotifyEvent
& rNEvt
)
3173 if ( (rNEvt
.GetType() == EVENT_KEYINPUT
) && !rNEvt
.GetKeyEvent()->GetKeyCode().IsMod2() )
3175 if ( ImplTimeProcessKeyInput( GetField(), *rNEvt
.GetKeyEvent(), IsStrictFormat(), IsDuration(), GetFormat(), ImplGetLocaleDataWrapper() ) )
3179 return SpinField::PreNotify( rNEvt
);
3182 // -----------------------------------------------------------------------
3184 long TimeField::Notify( NotifyEvent
& rNEvt
)
3186 if ( rNEvt
.GetType() == EVENT_GETFOCUS
)
3187 MarkToBeReformatted( FALSE
);
3188 else if ( rNEvt
.GetType() == EVENT_LOSEFOCUS
)
3190 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
3192 if ( !ImplAllowMalformedInput() )
3196 Time
aTime( 0, 0, 0 );
3197 if ( ImplTimeGetValue( GetText(), aTime
, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper(), FALSE
) )
3198 // even with strict text analysis, our text is a valid time -> do a complete
3205 return SpinField::Notify( rNEvt
);
3208 // -----------------------------------------------------------------------
3210 void TimeField::DataChanged( const DataChangedEvent
& rDCEvt
)
3212 SpinField::DataChanged( rDCEvt
);
3214 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) && (rDCEvt
.GetFlags() & SETTINGS_LOCALE
) )
3216 if ( IsDefaultLocale() )
3217 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
3222 // -----------------------------------------------------------------------
3224 void TimeField::Modify()
3226 MarkToBeReformatted( TRUE
);
3227 SpinField::Modify();
3230 // -----------------------------------------------------------------------
3232 void TimeField::Up()
3234 ImplTimeSpinArea( TRUE
);
3238 // -----------------------------------------------------------------------
3240 void TimeField::Down()
3242 ImplTimeSpinArea( FALSE
);
3246 // -----------------------------------------------------------------------
3248 void TimeField::First()
3250 ImplNewFieldValue( maFirst
);
3254 // -----------------------------------------------------------------------
3256 void TimeField::Last()
3258 ImplNewFieldValue( maLast
);
3262 // -----------------------------------------------------------------------
3264 void TimeField::SetExtFormat( ExtTimeFieldFormat eFormat
)
3268 case EXTTIMEF_24H_SHORT
:
3270 SetTimeFormat( HOUR_24
);
3271 SetDuration( FALSE
);
3272 SetFormat( TIMEF_NONE
);
3275 case EXTTIMEF_24H_LONG
:
3277 SetTimeFormat( HOUR_24
);
3278 SetDuration( FALSE
);
3279 SetFormat( TIMEF_SEC
);
3282 case EXTTIMEF_12H_SHORT
:
3284 SetTimeFormat( HOUR_12
);
3285 SetDuration( FALSE
);
3286 SetFormat( TIMEF_NONE
);
3289 case EXTTIMEF_12H_LONG
:
3291 SetTimeFormat( HOUR_12
);
3292 SetDuration( FALSE
);
3293 SetFormat( TIMEF_SEC
);
3296 case EXTTIMEF_DURATION_SHORT
:
3298 SetDuration( TRUE
);
3299 SetFormat( TIMEF_NONE
);
3302 case EXTTIMEF_DURATION_LONG
:
3304 SetDuration( TRUE
);
3305 SetFormat( TIMEF_SEC
);
3308 default: DBG_ERROR( "ExtTimeFieldFormat unknown!" );
3311 if ( GetField() && GetField()->GetText().Len() )
3312 SetUserTime( GetTime() );
3316 // -----------------------------------------------------------------------
3318 TimeBox::TimeBox( Window
* pParent
, WinBits nWinStyle
) :
3319 ComboBox( pParent
, nWinStyle
)
3322 SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime
, FALSE
, FALSE
) );
3326 // -----------------------------------------------------------------------
3328 TimeBox::TimeBox( Window
* pParent
, const ResId
& rResId
) :
3329 ComboBox( WINDOW_TIMEBOX
)
3331 rResId
.SetRT( RSC_TIMEBOX
);
3332 WinBits nStyle
= ImplInitRes( rResId
);
3333 ComboBox::ImplInit( pParent
, nStyle
);
3335 SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime
, FALSE
, FALSE
) );
3336 ComboBox::ImplLoadRes( rResId
);
3337 ResMgr
* pMgr
= rResId
.GetResMgr();
3339 TimeFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
3342 if ( !(nStyle
& WB_HIDE
) )
3346 // -----------------------------------------------------------------------
3352 // -----------------------------------------------------------------------
3354 long TimeBox::PreNotify( NotifyEvent
& rNEvt
)
3356 if ( (rNEvt
.GetType() == EVENT_KEYINPUT
) && !rNEvt
.GetKeyEvent()->GetKeyCode().IsMod2() )
3358 if ( ImplTimeProcessKeyInput( GetField(), *rNEvt
.GetKeyEvent(), IsStrictFormat(), IsDuration(), GetFormat(), ImplGetLocaleDataWrapper() ) )
3362 return ComboBox::PreNotify( rNEvt
);
3365 // -----------------------------------------------------------------------
3367 long TimeBox::Notify( NotifyEvent
& rNEvt
)
3369 if ( rNEvt
.GetType() == EVENT_GETFOCUS
)
3370 MarkToBeReformatted( FALSE
);
3371 else if ( rNEvt
.GetType() == EVENT_LOSEFOCUS
)
3373 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
3377 return ComboBox::Notify( rNEvt
);
3380 // -----------------------------------------------------------------------
3382 void TimeBox::DataChanged( const DataChangedEvent
& rDCEvt
)
3384 ComboBox::DataChanged( rDCEvt
);
3386 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) && (rDCEvt
.GetFlags() & SETTINGS_LOCALE
) )
3388 if ( IsDefaultLocale() )
3389 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
3394 // -----------------------------------------------------------------------
3396 void TimeBox::Modify()
3398 MarkToBeReformatted( TRUE
);
3402 // -----------------------------------------------------------------------
3404 void TimeBox::ReformatAll()
3407 SetUpdateMode( FALSE
);
3408 USHORT nEntryCount
= GetEntryCount();
3409 for ( USHORT i
=0; i
< nEntryCount
; i
++ )
3411 ImplTimeReformat( GetEntry( i
), aStr
);
3413 InsertEntry( aStr
, i
);
3415 TimeFormatter::Reformat();
3416 SetUpdateMode( TRUE
);
3419 // -----------------------------------------------------------------------
3421 void TimeBox::InsertTime( const Time
& rTime
, USHORT nPos
)
3424 if ( aTime
> GetMax() )
3426 else if ( aTime
< GetMin() )
3430 BOOL b100Sec
= FALSE
;
3431 if ( GetFormat() == TIMEF_SEC
)
3433 if ( GetFormat() == TIMEF_100TH_SEC
|| GetFormat() == TIMEF_SEC_CS
)
3434 bSec
= b100Sec
= TRUE
;
3435 ComboBox::InsertEntry( ImplGetLocaleDataWrapper().getTime( aTime
, bSec
, b100Sec
), nPos
);
3438 // -----------------------------------------------------------------------
3440 void TimeBox::RemoveTime( const Time
& rTime
)
3443 BOOL b100Sec
= FALSE
;
3444 if ( GetFormat() == TIMEF_SEC
)
3446 if ( GetFormat() == TIMEF_100TH_SEC
|| TIMEF_SEC_CS
)
3447 bSec
= b100Sec
= TRUE
;
3448 ComboBox::RemoveEntry( ImplGetLocaleDataWrapper().getTime( rTime
, bSec
, b100Sec
) );
3451 // -----------------------------------------------------------------------
3453 Time
TimeBox::GetTime( USHORT nPos
) const
3455 Time
aTime( 0, 0, 0 );
3456 ImplTimeGetValue( ComboBox::GetEntry( nPos
), aTime
, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper() );
3460 // -----------------------------------------------------------------------
3462 USHORT
TimeBox::GetTimePos( const Time
& rTime
) const
3465 BOOL b100Sec
= FALSE
;
3466 if ( GetFormat() == TIMEF_SEC
)
3468 if ( GetFormat() == TIMEF_100TH_SEC
|| TIMEF_SEC_CS
)
3469 bSec
= b100Sec
= TRUE
;
3470 return ComboBox::GetEntryPos( ImplGetLocaleDataWrapper().getTime( rTime
, bSec
, b100Sec
) );