/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; // ======================================================================= #define EDITMASK_LITERAL 'L' #define EDITMASK_ALPHA 'a' #define EDITMASK_UPPERALPHA 'A' #define EDITMASK_ALPHANUM 'c' #define EDITMASK_UPPERALPHANUM 'C' #define EDITMASK_NUM 'N' #define EDITMASK_NUMSPACE 'n' #define EDITMASK_ALLCHAR 'x' #define EDITMASK_UPPERALLCHAR 'X' uno::Reference< i18n::XCharacterClassification > ImplGetCharClass() { static uno::Reference< i18n::XCharacterClassification > xCharClass; if ( !xCharClass.is() ) xCharClass = vcl::unohelper::CreateCharacterClassification(); return xCharClass; } // ----------------------------------------------------------------------- static sal_Unicode* ImplAddString( sal_Unicode* pBuf, const String& rStr ) { if ( rStr.Len() == 1 ) *pBuf++ = rStr.GetChar(0); else if ( rStr.Len() == 0 ) ; else { memcpy( pBuf, rStr.GetBuffer(), rStr.Len() * sizeof(sal_Unicode) ); pBuf += rStr.Len(); } return pBuf; } // ----------------------------------------------------------------------- static sal_Unicode* ImplAddNum( sal_Unicode* pBuf, sal_uLong nNumber, int nMinLen ) { // fill temp buffer with digits sal_Unicode aTempBuf[30]; sal_Unicode* pTempBuf = aTempBuf; do { *pTempBuf = (sal_Unicode)(nNumber % 10) + '0'; pTempBuf++; nNumber /= 10; if ( nMinLen ) nMinLen--; } while ( nNumber ); // fill with zeros up to the minimal length while ( nMinLen > 0 ) { *pBuf = '0'; pBuf++; nMinLen--; } // copy temp buffer to real buffer do { pTempBuf--; *pBuf = *pTempBuf; pBuf++; } while ( pTempBuf != aTempBuf ); return pBuf; } // ----------------------------------------------------------------------- static sal_uInt16 ImplGetNum( const sal_Unicode*& rpBuf, sal_Bool& rbError ) { if ( !*rpBuf ) { rbError = sal_True; return 0; } sal_uInt16 nNumber = 0; while( ( *rpBuf >= '0' ) && ( *rpBuf <= '9' ) ) { nNumber *= 10; nNumber += *rpBuf - '0'; rpBuf++; } return nNumber; } // ----------------------------------------------------------------------- static void ImplSkipDelimiters( const sal_Unicode*& rpBuf ) { while( ( *rpBuf == ',' ) || ( *rpBuf == '.' ) || ( *rpBuf == ';' ) || ( *rpBuf == ':' ) || ( *rpBuf == '-' ) || ( *rpBuf == '/' ) ) { rpBuf++; } } // ----------------------------------------------------------------------- static int ImplIsPatternChar( xub_Unicode cChar, sal_Char cEditMask ) { sal_Int32 nType = 0; try { String aCharStr( cChar ); nType = ImplGetCharClass()->getStringType( aCharStr, 0, aCharStr.Len(), Application::GetSettings().GetLocale() ); } catch ( ::com::sun::star::uno::Exception& ) { DBG_ERRORFILE( "ImplIsPatternChar: Exception caught!" ); return sal_False; } if ( (cEditMask == EDITMASK_ALPHA) || (cEditMask == EDITMASK_UPPERALPHA) ) { if( !CharClass::isLetterType( nType ) ) return sal_False; } else if ( cEditMask == EDITMASK_NUM ) { if( !CharClass::isNumericType( nType ) ) return sal_False; } else if ( (cEditMask == EDITMASK_ALPHANUM) || (cEditMask == EDITMASK_UPPERALPHANUM) ) { if( !CharClass::isLetterNumericType( nType ) ) return sal_False; } else if ( (cEditMask == EDITMASK_ALLCHAR) || (cEditMask == EDITMASK_UPPERALLCHAR) ) { if ( cChar < 32 ) return sal_False; } else if ( cEditMask == EDITMASK_NUMSPACE ) { if ( !CharClass::isNumericType( nType ) && ( cChar != ' ' ) ) return sal_False; } else return sal_False; return sal_True; } // ----------------------------------------------------------------------- static xub_Unicode ImplPatternChar( xub_Unicode cChar, sal_Char cEditMask ) { if ( ImplIsPatternChar( cChar, cEditMask ) ) { if ( (cEditMask == EDITMASK_UPPERALPHA) || (cEditMask == EDITMASK_UPPERALPHANUM) || ( cEditMask == EDITMASK_UPPERALLCHAR ) ) { cChar = ImplGetCharClass()->toUpper( String(cChar),0,1,Application::GetSettings().GetLocale() )[0]; } return cChar; } else return 0; } // ----------------------------------------------------------------------- static int ImplKommaPointCharEqual( xub_Unicode c1, xub_Unicode c2 ) { if ( c1 == c2 ) return sal_True; else if ( ((c1 == '.') || (c1 == ',')) && ((c2 == '.') || (c2 == ',')) ) return sal_True; else return sal_False; } // ----------------------------------------------------------------------- static XubString ImplPatternReformat( const XubString& rStr, const ByteString& rEditMask, const XubString& rLiteralMask, sal_uInt16 nFormatFlags ) { if ( !rEditMask.Len() ) return rStr; XubString aStr = rStr; XubString aOutStr = rLiteralMask; xub_Unicode cTempChar; xub_Unicode cChar; xub_Unicode cLiteral; sal_Char cMask; xub_StrLen nStrIndex = 0; xub_StrLen i = 0; xub_StrLen n; while ( i < rEditMask.Len() ) { if ( nStrIndex >= aStr.Len() ) break; cChar = aStr.GetChar(nStrIndex); cLiteral = rLiteralMask.GetChar(i); cMask = rEditMask.GetChar(i); // Aktuelle Position ein Literal if ( cMask == EDITMASK_LITERAL ) { // Wenn es das Literal-Zeichen ist, uebernehmen, ansonsten // ignorieren, da es das naechste gueltige Zeichen vom String // sein kann if ( ImplKommaPointCharEqual( cChar, cLiteral ) ) nStrIndex++; else { // Ansonsten testen wir, ob es ein ungueltiges Zeichen ist. // Dies ist dann der Fall, wenn es nicht in das Muster // des naechsten nicht Literal-Zeichens passt n = i+1; while ( n < rEditMask.Len() ) { if ( rEditMask.GetChar(n) != EDITMASK_LITERAL ) { if ( !ImplIsPatternChar( cChar, rEditMask.GetChar(n) ) ) nStrIndex++; break; } n++; } } } else { // Gueltiges Zeichen an der Stelle cTempChar = ImplPatternChar( cChar, cMask ); if ( cTempChar ) { // dann Zeichen uebernehmen aOutStr.SetChar( i, cTempChar ); nStrIndex++; } else { // Wenn es das Literalzeichen ist, uebernehmen if ( cLiteral == cChar ) nStrIndex++; else { // Wenn das ungueltige Zeichen das naechste Literalzeichen // sein kann, dann springen wir bis dahin vor, ansonten // das Zeichen ignorieren // Nur machen, wenn leere Literale erlaubt sind if ( nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS ) { n = i; while ( n < rEditMask.Len() ) { if ( rEditMask.GetChar( n ) == EDITMASK_LITERAL ) { if ( ImplKommaPointCharEqual( cChar, rLiteralMask.GetChar( n ) ) ) i = n+1; break; } n++; } } nStrIndex++; continue; } } } i++; } return aOutStr; } // ----------------------------------------------------------------------- static void ImplPatternMaxPos( const XubString rStr, const ByteString& rEditMask, sal_uInt16 nFormatFlags, sal_Bool bSameMask, sal_uInt16 nCursorPos, sal_uInt16& rPos ) { // Letzte Position darf nicht groesser als der enthaltene String sein xub_StrLen nMaxPos = rStr.Len(); // Wenn keine leeren Literale erlaubt sind, auch Leerzeichen // am Ende ignorieren if ( bSameMask && !(nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS) ) { while ( nMaxPos ) { if ( (rEditMask.GetChar(nMaxPos-1) != EDITMASK_LITERAL) && (rStr.GetChar(nMaxPos-1) != ' ') ) break; nMaxPos--; } // Wenn wir vor einem Literal stehen, dann solange weitersuchen, // bis erste Stelle nach Literal xub_StrLen nTempPos = nMaxPos; while ( nTempPos < rEditMask.Len() ) { if ( rEditMask.GetChar(nTempPos) != EDITMASK_LITERAL ) { nMaxPos = nTempPos; break; } nTempPos++; } } if ( rPos > nMaxPos ) rPos = nMaxPos; // Zeichen sollte nicht nach links wandern if ( rPos < nCursorPos ) rPos = nCursorPos; } // ----------------------------------------------------------------------- static void ImplPatternProcessStrictModify( Edit* pEdit, const ByteString& rEditMask, const XubString& rLiteralMask, sal_uInt16 nFormatFlags, sal_Bool bSameMask ) { XubString aText = pEdit->GetText(); // Leerzeichen am Anfang entfernen if ( bSameMask && !(nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS) ) { xub_StrLen i = 0; xub_StrLen nMaxLen = aText.Len(); while ( i < nMaxLen ) { if ( (rEditMask.GetChar( i ) != EDITMASK_LITERAL) && (aText.GetChar( i ) != ' ') ) break; i++; } // Alle Literalzeichen beibehalten while ( i && (rEditMask.GetChar( i ) == EDITMASK_LITERAL) ) i--; aText.Erase( 0, i ); } XubString aNewText = ImplPatternReformat( aText, rEditMask, rLiteralMask, nFormatFlags ); if ( aNewText != aText ) { // Selection so anpassen, das diese wenn sie vorher am Ende // stand, immer noch am Ende steht Selection aSel = pEdit->GetSelection(); sal_uLong nMaxSel = Max( aSel.Min(), aSel.Max() ); if ( nMaxSel >= aText.Len() ) { xub_StrLen nMaxPos = aNewText.Len(); ImplPatternMaxPos( aNewText, rEditMask, nFormatFlags, bSameMask, (xub_StrLen)nMaxSel, nMaxPos ); if ( aSel.Min() == aSel.Max() ) { aSel.Min() = nMaxPos; aSel.Max() = aSel.Min(); } else if ( aSel.Min() > aSel.Max() ) aSel.Min() = nMaxPos; else aSel.Max() = nMaxPos; } pEdit->SetText( aNewText, aSel ); } } // ----------------------------------------------------------------------- static xub_StrLen ImplPatternLeftPos( const ByteString& rEditMask, xub_StrLen nCursorPos ) { // Vorheriges Zeichen suchen, was kein Literal ist xub_StrLen nNewPos = nCursorPos; xub_StrLen nTempPos = nNewPos; while ( nTempPos ) { if ( rEditMask.GetChar(nTempPos-1) != EDITMASK_LITERAL ) { nNewPos = nTempPos-1; break; } nTempPos--; } return nNewPos; } // ----------------------------------------------------------------------- static xub_StrLen ImplPatternRightPos( const XubString& rStr, const ByteString& rEditMask, sal_uInt16 nFormatFlags, sal_Bool bSameMask, xub_StrLen nCursorPos ) { // Naechstes Zeichen suchen, was kein Literal ist xub_StrLen nNewPos = nCursorPos; xub_StrLen nTempPos = nNewPos; while ( nTempPos < rEditMask.Len() ) { if ( rEditMask.GetChar(nTempPos+1) != EDITMASK_LITERAL ) { nNewPos = nTempPos+1; break; } nTempPos++; } ImplPatternMaxPos( rStr, rEditMask, nFormatFlags, bSameMask, nCursorPos, nNewPos ); return nNewPos; } // ----------------------------------------------------------------------- static sal_Bool ImplPatternProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt, const ByteString& rEditMask, const XubString& rLiteralMask, sal_Bool bStrictFormat, sal_uInt16 nFormatFlags, sal_Bool bSameMask, sal_Bool& rbInKeyInput ) { if ( !rEditMask.Len() || !bStrictFormat ) return sal_False; Selection aOldSel = pEdit->GetSelection(); KeyCode aCode = rKEvt.GetKeyCode(); xub_Unicode cChar = rKEvt.GetCharCode(); sal_uInt16 nKeyCode = aCode.GetCode(); sal_Bool bShift = aCode.IsShift(); xub_StrLen nCursorPos = (xub_StrLen)aOldSel.Max(); xub_StrLen nNewPos; xub_StrLen nTempPos; if ( nKeyCode && !aCode.IsMod1() && !aCode.IsMod2() ) { if ( nKeyCode == KEY_LEFT ) { Selection aSel( ImplPatternLeftPos( rEditMask, nCursorPos ) ); if ( bShift ) aSel.Min() = aOldSel.Min(); pEdit->SetSelection( aSel ); return sal_True; } else if ( nKeyCode == KEY_RIGHT ) { // Hier nehmen wir Selectionsanfang als minimum, da falls durch // Focus alles selektiert ist, ist eine kleine Position schon // erlaubt. Selection aSel( aOldSel ); aSel.Justify(); nCursorPos = (xub_StrLen)aSel.Min(); aSel.Max() = ImplPatternRightPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nCursorPos ); if ( bShift ) aSel.Min() = aOldSel.Min(); else aSel.Min() = aSel.Max(); pEdit->SetSelection( aSel ); return sal_True; } else if ( nKeyCode == KEY_HOME ) { // Home ist Position des ersten nicht literalen Zeichens nNewPos = 0; while ( (nNewPos < rEditMask.Len()) && (rEditMask.GetChar(nNewPos) == EDITMASK_LITERAL) ) nNewPos++; // Home sollte nicht nach rechts wandern if ( nCursorPos < nNewPos ) nNewPos = nCursorPos; Selection aSel( nNewPos ); if ( bShift ) aSel.Min() = aOldSel.Min(); pEdit->SetSelection( aSel ); return sal_True; } else if ( nKeyCode == KEY_END ) { // End ist die Position des letzten nicht literalen Zeichens nNewPos = rEditMask.Len(); while ( nNewPos && (rEditMask.GetChar(nNewPos-1) == EDITMASK_LITERAL) ) nNewPos--; // Hier nehmen wir Selectionsanfang als minimum, da falls durch // Focus alles selektiert ist, ist eine kleine Position schon // erlaubt. Selection aSel( aOldSel ); aSel.Justify(); nCursorPos = (xub_StrLen)aSel.Min(); ImplPatternMaxPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nCursorPos, nNewPos ); aSel.Max() = nNewPos; if ( bShift ) aSel.Min() = aOldSel.Min(); else aSel.Min() = aSel.Max(); pEdit->SetSelection( aSel ); return sal_True; } else if ( (nKeyCode == KEY_BACKSPACE) || (nKeyCode == KEY_DELETE) ) { XubString aStr( pEdit->GetText() ); XubString aOldStr = aStr; Selection aSel = aOldSel; aSel.Justify(); nNewPos = (xub_StrLen)aSel.Min(); // Wenn Selection, dann diese Loeschen if ( aSel.Len() ) { if ( bSameMask ) aStr.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() ); else { XubString aRep = rLiteralMask.Copy( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() ); aStr.Replace( (xub_StrLen)aSel.Min(), aRep.Len(), aRep ); } } else { if ( nKeyCode == KEY_BACKSPACE ) { nTempPos = nNewPos; nNewPos = ImplPatternLeftPos( rEditMask, nTempPos ); } else nTempPos = ImplPatternRightPos( aStr, rEditMask, nFormatFlags, bSameMask, nNewPos ); if ( nNewPos != nTempPos ) { if ( bSameMask ) { if ( rEditMask.GetChar( nNewPos ) != EDITMASK_LITERAL ) aStr.Erase( nNewPos, 1 ); } else { XubString aTempStr = rLiteralMask.Copy( nNewPos, 1 ); aStr.Replace( nNewPos, aTempStr.Len(), aTempStr ); } } } if ( aOldStr != aStr ) { if ( bSameMask ) aStr = ImplPatternReformat( aStr, rEditMask, rLiteralMask, nFormatFlags ); rbInKeyInput = sal_True; pEdit->SetText( aStr, Selection( nNewPos ) ); pEdit->SetModifyFlag(); pEdit->Modify(); rbInKeyInput = sal_False; } else pEdit->SetSelection( Selection( nNewPos ) ); return sal_True; } else if ( nKeyCode == KEY_INSERT ) { // InsertModus kann man beim PatternField nur einstellen, // wenn Maske an jeder Eingabeposition die gleiche // ist if ( !bSameMask ) { Sound::Beep(); return sal_True; } } } if ( rKEvt.GetKeyCode().IsMod2() || (cChar < 32) || (cChar == 127) ) return sal_False; Selection aSel = aOldSel; aSel.Justify(); nNewPos = (xub_StrLen)aSel.Min(); if ( nNewPos < rEditMask.Len() ) { xub_Unicode cPattChar = ImplPatternChar( cChar, rEditMask.GetChar(nNewPos) ); if ( cPattChar ) cChar = cPattChar; else { // Wenn kein gueltiges Zeichen, dann testen wir, ob der // Anwender zum naechsten Literal springen wollte. Dies machen // wir nur, wenn er hinter einem Zeichen steht, damit // eingebene Literale die automatisch uebersprungenen wurden // nicht dazu fuehren, das der Anwender dann da steht, wo // er nicht stehen wollte. if ( nNewPos && (rEditMask.GetChar(nNewPos-1) != EDITMASK_LITERAL) && !aSel.Len() ) { // Naechstes Zeichen suchen, was kein Literal ist nTempPos = nNewPos; while ( nTempPos < rEditMask.Len() ) { if ( rEditMask.GetChar(nTempPos) == EDITMASK_LITERAL ) { // Gilt nur, wenn ein Literalzeichen vorhanden if ( (rEditMask.GetChar(nTempPos+1) != EDITMASK_LITERAL ) && ImplKommaPointCharEqual( cChar, rLiteralMask.GetChar(nTempPos) ) ) { nTempPos++; ImplPatternMaxPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nNewPos, nTempPos ); if ( nTempPos > nNewPos ) { pEdit->SetSelection( Selection( nTempPos ) ); return sal_True; } } break; } nTempPos++; } } cChar = 0; } } else cChar = 0; if ( cChar ) { XubString aStr = pEdit->GetText(); sal_Bool bError = sal_False; if ( bSameMask && pEdit->IsInsertMode() ) { // Text um Spacezeichen und Literale am Ende kuerzen, bis zur // aktuellen Position xub_StrLen n = aStr.Len(); while ( n && (n > nNewPos) ) { if ( (aStr.GetChar( n-1 ) != ' ') && ((n > rEditMask.Len()) || (rEditMask.GetChar(n-1) != EDITMASK_LITERAL)) ) break; n--; } aStr.Erase( n ); if ( aSel.Len() ) aStr.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() ); if ( aStr.Len() < rEditMask.Len() ) { // String evtl. noch bis Cursor-Position erweitern if ( aStr.Len() < nNewPos ) aStr += rLiteralMask.Copy( aStr.Len(), nNewPos-aStr.Len() ); if ( nNewPos < aStr.Len() ) aStr.Insert( cChar, nNewPos ); else if ( nNewPos < rEditMask.Len() ) aStr += cChar; aStr = ImplPatternReformat( aStr, rEditMask, rLiteralMask, nFormatFlags ); } else bError = sal_True; } else { if ( aSel.Len() ) { // Selection loeschen XubString aRep = rLiteralMask.Copy( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() ); aStr.Replace( (xub_StrLen)aSel.Min(), aRep.Len(), aRep ); } if ( nNewPos < aStr.Len() ) aStr.SetChar( nNewPos, cChar ); else if ( nNewPos < rEditMask.Len() ) aStr += cChar; } if ( bError ) Sound::Beep(); else { rbInKeyInput = sal_True; Selection aNewSel( ImplPatternRightPos( aStr, rEditMask, nFormatFlags, bSameMask, nNewPos ) ); pEdit->SetText( aStr, aNewSel ); pEdit->SetModifyFlag(); pEdit->Modify(); rbInKeyInput = sal_False; } } else Sound::Beep(); return sal_True; } // ----------------------------------------------------------------------- void PatternFormatter::ImplSetMask( const ByteString& rEditMask, const XubString& rLiteralMask ) { maEditMask = rEditMask; maLiteralMask = rLiteralMask; mbSameMask = sal_True; if ( maEditMask.Len() != maLiteralMask.Len() ) { if ( maEditMask.Len() < maLiteralMask.Len() ) maLiteralMask.Erase( maEditMask.Len() ); else maLiteralMask.Expand( maEditMask.Len(), ' ' ); } // StrictModus erlaubt nur Input-Mode, wenn als Maske nur // gleiche Zeichen zugelassen werden und als Vorgabe nur // Spacezeichen vorgegeben werden, die durch die Maske // nicht zugelassen sind xub_StrLen i = 0; sal_Char c = 0; while ( i < rEditMask.Len() ) { sal_Char cTemp = rEditMask.GetChar( i ); if ( cTemp != EDITMASK_LITERAL ) { if ( (cTemp == EDITMASK_ALLCHAR) || (cTemp == EDITMASK_UPPERALLCHAR) || (cTemp == EDITMASK_NUMSPACE) ) { mbSameMask = sal_False; break; } if ( i < rLiteralMask.Len() ) { if ( rLiteralMask.GetChar( i ) != ' ' ) { mbSameMask = sal_False; break; } } if ( !c ) c = cTemp; if ( cTemp != c ) { mbSameMask = sal_False; break; } } i++; } } // ----------------------------------------------------------------------- PatternFormatter::PatternFormatter() { mnFormatFlags = 0; mbSameMask = sal_True; mbInPattKeyInput = sal_False; } // ----------------------------------------------------------------------- void PatternFormatter::ImplLoadRes( const ResId& rResId ) { ByteString aEditMask; XubString aLiteralMask; ResMgr* pMgr = rResId.GetResMgr(); if( pMgr ) { sal_uLong nMask = pMgr->ReadLong(); if ( PATTERNFORMATTER_STRICTFORMAT & nMask ) SetStrictFormat( (sal_Bool)pMgr->ReadShort() ); if ( PATTERNFORMATTER_EDITMASK & nMask ) aEditMask = ByteString( pMgr->ReadString(), RTL_TEXTENCODING_ASCII_US ); if ( PATTERNFORMATTER_LITTERALMASK & nMask ) aLiteralMask = pMgr->ReadString(); if ( (PATTERNFORMATTER_EDITMASK | PATTERNFORMATTER_LITTERALMASK) & nMask ) ImplSetMask( aEditMask, aLiteralMask ); } } // ----------------------------------------------------------------------- PatternFormatter::~PatternFormatter() { } // ----------------------------------------------------------------------- void PatternFormatter::SetMask( const ByteString& rEditMask, const XubString& rLiteralMask ) { ImplSetMask( rEditMask, rLiteralMask ); ReformatAll(); } // ----------------------------------------------------------------------- void PatternFormatter::SetString( const XubString& rStr ) { maFieldString = rStr; if ( GetField() ) { GetField()->SetText( rStr ); MarkToBeReformatted( sal_False ); } } // ----------------------------------------------------------------------- XubString PatternFormatter::GetString() const { if ( !GetField() ) return ImplGetSVEmptyStr(); else return ImplPatternReformat( GetField()->GetText(), maEditMask, maLiteralMask, mnFormatFlags ); } // ----------------------------------------------------------------------- void PatternFormatter::Reformat() { if ( GetField() ) { ImplSetText( ImplPatternReformat( GetField()->GetText(), maEditMask, maLiteralMask, mnFormatFlags ) ); if ( !mbSameMask && IsStrictFormat() && !GetField()->IsReadOnly() ) GetField()->SetInsertMode( sal_False ); } } // ----------------------------------------------------------------------- void PatternFormatter::SelectFixedFont() { if ( GetField() ) { Font aFont = OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, Application::GetSettings().GetLanguage(), 0 ); Font aControlFont; aControlFont.SetName( aFont.GetName() ); aControlFont.SetFamily( aFont.GetFamily() ); aControlFont.SetPitch( aFont.GetPitch() ); GetField()->SetControlFont( aControlFont ); } } // ----------------------------------------------------------------------- PatternField::PatternField( Window* pParent, WinBits nWinStyle ) : SpinField( pParent, nWinStyle ) { SetField( this ); Reformat(); } // ----------------------------------------------------------------------- PatternField::PatternField( Window* pParent, const ResId& rResId ) : SpinField( WINDOW_PATTERNFIELD ) { rResId.SetRT( RSC_PATTERNFIELD ); WinBits nStyle = ImplInitRes( rResId ); ImplInit( pParent, nStyle ); SetField( this ); SpinField::ImplLoadRes( rResId ); PatternFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); Reformat(); if ( !(nStyle & WB_HIDE ) ) Show(); } // ----------------------------------------------------------------------- PatternField::~PatternField() { } // ----------------------------------------------------------------------- long PatternField::PreNotify( NotifyEvent& rNEvt ) { if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) { if ( ImplPatternProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetEditMask(), GetLiteralMask(), IsStrictFormat(), GetFormatFlags(), ImplIsSameMask(), ImplGetInPattKeyInput() ) ) return 1; } return SpinField::PreNotify( rNEvt ); } // ----------------------------------------------------------------------- long PatternField::Notify( NotifyEvent& rNEvt ) { if ( rNEvt.GetType() == EVENT_GETFOCUS ) MarkToBeReformatted( sal_False ); else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) { if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) Reformat(); } return SpinField::Notify( rNEvt ); } // ----------------------------------------------------------------------- void PatternField::Modify() { if ( !ImplGetInPattKeyInput() ) { if ( IsStrictFormat() ) ImplPatternProcessStrictModify( GetField(), GetEditMask(), GetLiteralMask(), GetFormatFlags(), ImplIsSameMask() ); else MarkToBeReformatted( sal_True ); } SpinField::Modify(); } // ----------------------------------------------------------------------- PatternBox::PatternBox( Window* pParent, WinBits nWinStyle ) : ComboBox( pParent, nWinStyle ) { SetField( this ); Reformat(); } // ----------------------------------------------------------------------- PatternBox::PatternBox( Window* pParent, const ResId& rResId ) : ComboBox( WINDOW_PATTERNBOX ) { rResId.SetRT( RSC_PATTERNBOX ); WinBits nStyle = ImplInitRes( rResId ); ImplInit( pParent, nStyle ); SetField( this ); ComboBox::ImplLoadRes( rResId ); PatternFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) ); Reformat(); if ( !(nStyle & WB_HIDE ) ) Show(); } // ----------------------------------------------------------------------- PatternBox::~PatternBox() { } // ----------------------------------------------------------------------- long PatternBox::PreNotify( NotifyEvent& rNEvt ) { if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) { if ( ImplPatternProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetEditMask(), GetLiteralMask(), IsStrictFormat(), GetFormatFlags(), ImplIsSameMask(), ImplGetInPattKeyInput() ) ) return 1; } return ComboBox::PreNotify( rNEvt ); } // ----------------------------------------------------------------------- long PatternBox::Notify( NotifyEvent& rNEvt ) { if ( rNEvt.GetType() == EVENT_GETFOCUS ) MarkToBeReformatted( sal_False ); else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) { if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) Reformat(); } return ComboBox::Notify( rNEvt ); } // ----------------------------------------------------------------------- void PatternBox::Modify() { if ( !ImplGetInPattKeyInput() ) { if ( IsStrictFormat() ) ImplPatternProcessStrictModify( GetField(), GetEditMask(), GetLiteralMask(), GetFormatFlags(), ImplIsSameMask() ); else MarkToBeReformatted( sal_True ); } ComboBox::Modify(); } // ----------------------------------------------------------------------- void PatternBox::ReformatAll() { XubString aStr; SetUpdateMode( sal_False ); sal_uInt16 nEntryCount = GetEntryCount(); for ( sal_uInt16 i=0; i < nEntryCount; i++ ) { aStr = ImplPatternReformat( GetEntry( i ), GetEditMask(), GetLiteralMask(), GetFormatFlags() ); RemoveEntry( i ); InsertEntry( aStr, i ); } PatternFormatter::Reformat(); SetUpdateMode( sal_True ); } // ----------------------------------------------------------------------- void PatternBox::InsertString( const XubString& rStr, sal_uInt16 nPos ) { ComboBox::InsertEntry( ImplPatternReformat( rStr, GetEditMask(), GetLiteralMask(), GetFormatFlags() ), nPos ); } // ----------------------------------------------------------------------- void PatternBox::RemoveString( const XubString& rStr ) { ComboBox::RemoveEntry( ImplPatternReformat( rStr, GetEditMask(), GetLiteralMask(), GetFormatFlags() ) ); } // ----------------------------------------------------------------------- XubString PatternBox::GetString( sal_uInt16 nPos ) const { return ImplPatternReformat( ComboBox::GetEntry( nPos ), GetEditMask(), GetLiteralMask(), GetFormatFlags() ); } // ----------------------------------------------------------------------- sal_uInt16 PatternBox::GetStringPos( const XubString& rStr ) const { return ComboBox::GetEntryPos( ImplPatternReformat( rStr, GetEditMask(), GetLiteralMask(), GetFormatFlags() ) ); } // ======================================================================= static ExtDateFieldFormat ImplGetExtFormat( DateFormat eOld ) { switch( eOld ) { case DMY: return XTDATEF_SHORT_DDMMYY; case MDY: return XTDATEF_SHORT_MMDDYY; default: return XTDATEF_SHORT_YYMMDD; } } // ----------------------------------------------------------------------- static sal_uInt16 ImplCutNumberFromString( XubString& rStr ) { // Nach Zahl suchen while ( rStr.Len() && !(rStr.GetChar( 0 ) >= '0' && rStr.GetChar( 0 ) <= '9') ) rStr.Erase( 0, 1 ); if ( !rStr.Len() ) return 0; XubString aNumStr; while ( rStr.Len() && (rStr.GetChar( 0 ) >= '0' && rStr.GetChar( 0 ) <= '9') ) { aNumStr.Insert( rStr.GetChar( 0 ) ); rStr.Erase( 0, 1 ); } return (sal_uInt16)aNumStr.ToInt32(); } // ----------------------------------------------------------------------- static sal_Bool ImplCutMonthName( XubString& rStr, const XubString& _rLookupMonthName ) { sal_uInt16 nPos = rStr.Search( _rLookupMonthName ); if ( nPos != STRING_NOTFOUND ) { rStr.Erase( 0, nPos + _rLookupMonthName.Len() ); return sal_True; } return sal_False; } // ----------------------------------------------------------------------- static sal_uInt16 ImplCutMonthFromString( XubString& rStr, const CalendarWrapper& rCalendarWrapper ) { // search for a month' name for ( sal_uInt16 i=1; i <= 12; i++ ) { String aMonthName = rCalendarWrapper.getMonths()[i-1].FullName; // long month name? if ( ImplCutMonthName( rStr, aMonthName ) ) return i; // short month name? String aAbbrevMonthName = rCalendarWrapper.getMonths()[i-1].AbbrevName; if ( ImplCutMonthName( rStr, aAbbrevMonthName ) ) return i; } return ImplCutNumberFromString( rStr ); } // ----------------------------------------------------------------------- static String ImplGetDateSep( const LocaleDataWrapper& rLocaleDataWrapper, ExtDateFieldFormat eFormat ) { String aDateSep = rLocaleDataWrapper.getDateSep(); if ( ( eFormat == XTDATEF_SHORT_YYMMDD_DIN5008 ) || ( eFormat == XTDATEF_SHORT_YYYYMMDD_DIN5008 ) ) aDateSep = String( RTL_CONSTASCII_USTRINGPARAM( "-" ) ); return aDateSep; } static sal_Bool ImplDateProcessKeyInput( Edit*, const KeyEvent& rKEvt, ExtDateFieldFormat eFormat, const LocaleDataWrapper& rLocaleDataWrapper ) { xub_Unicode cChar = rKEvt.GetCharCode(); sal_uInt16 nGroup = rKEvt.GetKeyCode().GetGroup(); if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) || (nGroup == KEYGROUP_MISC)|| ((cChar >= '0') && (cChar <= '9')) || (cChar == ImplGetDateSep( rLocaleDataWrapper, eFormat ).GetChar(0) ) ) return sal_False; else return sal_True; } // ----------------------------------------------------------------------- static sal_Bool ImplDateGetValue( const XubString& rStr, Date& rDate, ExtDateFieldFormat eDateFormat, const LocaleDataWrapper& rLocaleDataWrapper, const CalendarWrapper& rCalendarWrapper, const AllSettings& ) { sal_uInt16 nDay = 0; sal_uInt16 nMonth = 0; sal_uInt16 nYear = 0; sal_Bool bYear = sal_True; sal_Bool bError = sal_False; String aStr( rStr ); if ( eDateFormat == XTDATEF_SYSTEM_LONG ) { DateFormat eFormat = rLocaleDataWrapper.getLongDateFormat(); switch( eFormat ) { case MDY: nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper ); nDay = ImplCutNumberFromString( aStr ); nYear = ImplCutNumberFromString( aStr ); break; case DMY: nDay = ImplCutNumberFromString( aStr ); nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper ); nYear = ImplCutNumberFromString( aStr ); break; case YMD: default: nYear = ImplCutNumberFromString( aStr ); nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper ); nDay = ImplCutNumberFromString( aStr ); break; } } else { // Check if year is present: String aDateSep = ImplGetDateSep( rLocaleDataWrapper, eDateFormat ); sal_uInt16 nSepPos = aStr.Search( aDateSep ); if ( nSepPos == STRING_NOTFOUND ) return sal_False; nSepPos = aStr.Search( aDateSep, nSepPos+1 ); if ( ( nSepPos == STRING_NOTFOUND ) || ( nSepPos == (aStr.Len()-1) ) ) { bYear = sal_False; nYear = Date().GetYear(); } const sal_Unicode* pBuf = aStr.GetBuffer(); ImplSkipDelimiters( pBuf ); switch ( eDateFormat ) { case XTDATEF_SHORT_DDMMYY: case XTDATEF_SHORT_DDMMYYYY: { nDay = ImplGetNum( pBuf, bError ); ImplSkipDelimiters( pBuf ); nMonth = ImplGetNum( pBuf, bError ); ImplSkipDelimiters( pBuf ); if ( bYear ) nYear = ImplGetNum( pBuf, bError ); } break; case XTDATEF_SHORT_MMDDYY: case XTDATEF_SHORT_MMDDYYYY: { nMonth = ImplGetNum( pBuf, bError ); ImplSkipDelimiters( pBuf ); nDay = ImplGetNum( pBuf, bError ); ImplSkipDelimiters( pBuf ); if ( bYear ) nYear = ImplGetNum( pBuf, bError ); } break; case XTDATEF_SHORT_YYMMDD: case XTDATEF_SHORT_YYYYMMDD: case XTDATEF_SHORT_YYMMDD_DIN5008: case XTDATEF_SHORT_YYYYMMDD_DIN5008: { if ( bYear ) nYear = ImplGetNum( pBuf, bError ); ImplSkipDelimiters( pBuf ); nMonth = ImplGetNum( pBuf, bError ); ImplSkipDelimiters( pBuf ); nDay = ImplGetNum( pBuf, bError ); } break; default: { DBG_ERROR( "DateFormat???" ); } } } if ( bError || !nDay || !nMonth ) return sal_False; Date aNewDate( nDay, nMonth, nYear ); DateFormatter::ExpandCentury( aNewDate, utl::MiscCfg().GetYear2000() ); if ( aNewDate.IsValid() ) { rDate = aNewDate; return sal_True; } return sal_False; } // ----------------------------------------------------------------------- sal_Bool DateFormatter::ImplDateReformat( const XubString& rStr, XubString& rOutStr, const AllSettings& rSettings ) { Date aDate( 0, 0, 0 ); if ( !ImplDateGetValue( rStr, aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) ) return sal_True; Date aTempDate = aDate; if ( aTempDate > GetMax() ) aTempDate = GetMax(); else if ( aTempDate < GetMin() ) aTempDate = GetMin(); if ( GetErrorHdl().IsSet() && (aDate != aTempDate) ) { maCorrectedDate = aTempDate; if( !GetErrorHdl().Call( this ) ) { maCorrectedDate = Date(); return sal_False; } else maCorrectedDate = Date(); } rOutStr = ImplGetDateAsText( aTempDate, rSettings ); return sal_True; } // ----------------------------------------------------------------------- XubString DateFormatter::ImplGetDateAsText( const Date& rDate, const AllSettings& ) const { sal_Bool bShowCentury = sal_False; switch ( GetExtDateFormat() ) { case XTDATEF_SYSTEM_SHORT_YYYY: case XTDATEF_SYSTEM_LONG: case XTDATEF_SHORT_DDMMYYYY: case XTDATEF_SHORT_MMDDYYYY: case XTDATEF_SHORT_YYYYMMDD: case XTDATEF_SHORT_YYYYMMDD_DIN5008: { bShowCentury = sal_True; } break; default: { bShowCentury = sal_False; } } if ( !bShowCentury ) { // Check if I have to use force showing the century sal_uInt16 nTwoDigitYearStart = utl::MiscCfg().GetYear2000(); sal_uInt16 nYear = rDate.GetYear(); // Wenn Jahr nicht im 2stelligen Grenzbereich liegt, if ( (nYear < nTwoDigitYearStart) || (nYear >= nTwoDigitYearStart+100) ) bShowCentury = sal_True; } sal_Unicode aBuf[128]; sal_Unicode* pBuf = aBuf; String aDateSep = ImplGetDateSep( ImplGetLocaleDataWrapper(), GetExtDateFormat( sal_True ) ); sal_uInt16 nDay = rDate.GetDay(); sal_uInt16 nMonth = rDate.GetMonth(); sal_uInt16 nYear = rDate.GetYear(); sal_uInt16 nYearLen = bShowCentury ? 4 : 2; if ( !bShowCentury ) nYear %= 100; switch ( GetExtDateFormat( sal_True ) ) { case XTDATEF_SYSTEM_LONG: { return ImplGetLocaleDataWrapper().getLongDate( rDate, GetCalendarWrapper(), 1, sal_False, 1, !bShowCentury ); } case XTDATEF_SHORT_DDMMYY: case XTDATEF_SHORT_DDMMYYYY: { pBuf = ImplAddNum( pBuf, nDay, 2 ); pBuf = ImplAddString( pBuf, aDateSep ); pBuf = ImplAddNum( pBuf, nMonth, 2 ); pBuf = ImplAddString( pBuf, aDateSep ); pBuf = ImplAddNum( pBuf, nYear, nYearLen ); } break; case XTDATEF_SHORT_MMDDYY: case XTDATEF_SHORT_MMDDYYYY: { pBuf = ImplAddNum( pBuf, nMonth, 2 ); pBuf = ImplAddString( pBuf, aDateSep ); pBuf = ImplAddNum( pBuf, nDay, 2 ); pBuf = ImplAddString( pBuf, aDateSep ); pBuf = ImplAddNum( pBuf, nYear, nYearLen ); } break; case XTDATEF_SHORT_YYMMDD: case XTDATEF_SHORT_YYYYMMDD: case XTDATEF_SHORT_YYMMDD_DIN5008: case XTDATEF_SHORT_YYYYMMDD_DIN5008: { pBuf = ImplAddNum( pBuf, nYear, nYearLen ); pBuf = ImplAddString( pBuf, aDateSep ); pBuf = ImplAddNum( pBuf, nMonth, 2 ); pBuf = ImplAddString( pBuf, aDateSep ); pBuf = ImplAddNum( pBuf, nDay, 2 ); } break; default: { DBG_ERROR( "DateFormat???" ); } } return String( aBuf, (xub_StrLen)(sal_uLong)(pBuf-aBuf) ); } // ----------------------------------------------------------------------- static void ImplDateIncrementDay( Date& rDate, sal_Bool bUp ) { DateFormatter::ExpandCentury( rDate ); if ( bUp ) { if ( (rDate.GetDay() != 31) || (rDate.GetMonth() != 12) || (rDate.GetYear() != 9999) ) rDate++; } else { if ( (rDate.GetDay() != 1 ) || (rDate.GetMonth() != 1) || (rDate.GetYear() != 0) ) rDate--; } } // ----------------------------------------------------------------------- static void ImplDateIncrementMonth( Date& rDate, sal_Bool bUp ) { DateFormatter::ExpandCentury( rDate ); sal_uInt16 nMonth = rDate.GetMonth(); sal_uInt16 nYear = rDate.GetYear(); if ( bUp ) { if ( (nMonth == 12) && (nYear < 9999) ) { rDate.SetMonth( 1 ); rDate.SetYear( nYear + 1 ); } else { if ( nMonth < 12 ) rDate.SetMonth( nMonth + 1 ); } } else { if ( (nMonth == 1) && (nYear > 0) ) { rDate.SetMonth( 12 ); rDate.SetYear( nYear - 1 ); } else { if ( nMonth > 1 ) rDate.SetMonth( nMonth - 1 ); } } sal_uInt16 nDaysInMonth = rDate.GetDaysInMonth(); if ( rDate.GetDay() > nDaysInMonth ) rDate.SetDay( nDaysInMonth ); } // ----------------------------------------------------------------------- static void ImplDateIncrementYear( Date& rDate, sal_Bool bUp ) { DateFormatter::ExpandCentury( rDate ); sal_uInt16 nYear = rDate.GetYear(); if ( bUp ) { if ( nYear < 9999 ) rDate.SetYear( nYear + 1 ); } else { if ( nYear > 0 ) rDate.SetYear( nYear - 1 ); } } // ----------------------------------------------------------------------- sal_Bool DateFormatter::ImplAllowMalformedInput() const { return !IsEnforceValidValue(); } // ----------------------------------------------------------------------- void DateField::ImplDateSpinArea( sal_Bool bUp ) { // Wenn alles selektiert ist, Tage hochzaehlen if ( GetField() ) { Date aDate( GetDate() ); Selection aSelection = GetField()->GetSelection(); aSelection.Justify(); XubString aText( GetText() ); if ( (xub_StrLen)aSelection.Len() == aText.Len() ) ImplDateIncrementDay( aDate, bUp ); else { xub_StrLen nDateArea = 0; ExtDateFieldFormat eFormat = GetExtDateFormat( sal_True ); if ( eFormat == XTDATEF_SYSTEM_LONG ) { eFormat = ImplGetExtFormat( ImplGetLocaleDataWrapper().getLongDateFormat() ); nDateArea = 1; } else { // Area suchen xub_StrLen nPos = 0; String aDateSep = ImplGetDateSep( ImplGetLocaleDataWrapper(), eFormat ); for ( xub_StrLen i = 1; i <= 3; i++ ) { nPos = aText.Search( aDateSep, nPos ); if ( nPos >= (sal_uInt16)aSelection.Max() ) { nDateArea = i; break; } else nPos++; } } switch( eFormat ) { case XTDATEF_SHORT_MMDDYY: case XTDATEF_SHORT_MMDDYYYY: switch( nDateArea ) { case 1: ImplDateIncrementMonth( aDate, bUp ); break; case 2: ImplDateIncrementDay( aDate, bUp ); break; case 3: ImplDateIncrementYear( aDate, bUp ); break; } break; case XTDATEF_SHORT_DDMMYY: case XTDATEF_SHORT_DDMMYYYY: switch( nDateArea ) { case 1: ImplDateIncrementDay( aDate, bUp ); break; case 2: ImplDateIncrementMonth( aDate, bUp ); break; case 3: ImplDateIncrementYear( aDate, bUp ); break; } break; case XTDATEF_SHORT_YYMMDD: case XTDATEF_SHORT_YYYYMMDD: case XTDATEF_SHORT_YYMMDD_DIN5008: case XTDATEF_SHORT_YYYYMMDD_DIN5008: switch( nDateArea ) { case 1: ImplDateIncrementYear( aDate, bUp ); break; case 2: ImplDateIncrementMonth( aDate, bUp ); break; case 3: ImplDateIncrementDay( aDate, bUp ); break; } break; default: DBG_ERROR( "invalid conversion" ); break; } } ImplNewFieldValue( aDate ); } } // ----------------------------------------------------------------------- void DateFormatter::ImplInit() { mbLongFormat = sal_False; mbShowDateCentury = sal_True; mpCalendarWrapper = NULL; mnDateFormat = 0xFFFF; mnExtDateFormat = XTDATEF_SYSTEM_SHORT; } // ----------------------------------------------------------------------- DateFormatter::DateFormatter() : maFieldDate( 0 ), maLastDate( 0 ), maMin( 1, 1, 1900 ), maMax( 31, 12, 2200 ), mbEnforceValidValue( sal_True ) { ImplInit(); } // ----------------------------------------------------------------------- void DateFormatter::ImplLoadRes( const ResId& rResId ) { ResMgr* pMgr = rResId.GetResMgr(); if( pMgr ) { sal_uLong nMask = pMgr->ReadLong(); if ( DATEFORMATTER_MIN & nMask ) { maMin = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ); pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) ); } if ( DATEFORMATTER_MAX & nMask ) { maMax = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ); pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) ); } if ( DATEFORMATTER_LONGFORMAT & nMask ) mbLongFormat = (sal_Bool)pMgr->ReadShort(); if ( DATEFORMATTER_STRICTFORMAT & nMask ) SetStrictFormat( (sal_Bool)pMgr->ReadShort() ); if ( DATEFORMATTER_VALUE & nMask ) { maFieldDate = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ); pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) ); if ( maFieldDate > maMax ) maFieldDate = maMax; if ( maFieldDate < maMin ) maFieldDate = maMin; maLastDate = maFieldDate; } } } // ----------------------------------------------------------------------- DateFormatter::~DateFormatter() { delete mpCalendarWrapper; mpCalendarWrapper = NULL; } // ----------------------------------------------------------------------- void DateFormatter::SetLocale( const ::com::sun::star::lang::Locale& rLocale ) { delete mpCalendarWrapper; mpCalendarWrapper = NULL; FormatterBase::SetLocale( rLocale ); } // ----------------------------------------------------------------------- CalendarWrapper& DateFormatter::GetCalendarWrapper() const { if ( !mpCalendarWrapper ) { ((DateFormatter*)this)->mpCalendarWrapper = new CalendarWrapper( vcl::unohelper::GetMultiServiceFactory() ); mpCalendarWrapper->loadDefaultCalendar( GetLocale() ); } return *mpCalendarWrapper; } // ----------------------------------------------------------------------- void DateFormatter::SetExtDateFormat( ExtDateFieldFormat eFormat ) { mnExtDateFormat = eFormat; ReformatAll(); } // ----------------------------------------------------------------------- ExtDateFieldFormat DateFormatter::GetExtDateFormat( sal_Bool bResolveSystemFormat ) const { ExtDateFieldFormat eDateFormat = (ExtDateFieldFormat)mnExtDateFormat; if ( bResolveSystemFormat && ( eDateFormat <= XTDATEF_SYSTEM_SHORT_YYYY ) ) { sal_Bool bShowCentury = (eDateFormat == XTDATEF_SYSTEM_SHORT_YYYY); switch ( ImplGetLocaleDataWrapper().getDateFormat() ) { case DMY: eDateFormat = bShowCentury ? XTDATEF_SHORT_DDMMYYYY : XTDATEF_SHORT_DDMMYY; break; case MDY: eDateFormat = bShowCentury ? XTDATEF_SHORT_MMDDYYYY : XTDATEF_SHORT_MMDDYY; break; default: eDateFormat = bShowCentury ? XTDATEF_SHORT_YYYYMMDD : XTDATEF_SHORT_YYMMDD; } } return eDateFormat; } // ----------------------------------------------------------------------- void DateFormatter::ReformatAll() { Reformat(); } // ----------------------------------------------------------------------- void DateFormatter::SetMin( const Date& rNewMin ) { maMin = rNewMin; if ( !IsEmptyFieldValue() ) ReformatAll(); } // ----------------------------------------------------------------------- void DateFormatter::SetMax( const Date& rNewMax ) { maMax = rNewMax; if ( !IsEmptyFieldValue() ) ReformatAll(); } // ----------------------------------------------------------------------- void DateFormatter::SetLongFormat( sal_Bool bLong ) { mbLongFormat = bLong; // #91913# Remove LongFormat and DateShowCentury - redundant if ( bLong ) { SetExtDateFormat( XTDATEF_SYSTEM_LONG ); } else { if( mnExtDateFormat == XTDATEF_SYSTEM_LONG ) SetExtDateFormat( XTDATEF_SYSTEM_SHORT ); } ReformatAll(); } // ----------------------------------------------------------------------- void DateFormatter::SetShowDateCentury( sal_Bool bShowDateCentury ) { mbShowDateCentury = bShowDateCentury; // #91913# Remove LongFormat and DateShowCentury - redundant if ( bShowDateCentury ) { switch ( GetExtDateFormat() ) { case XTDATEF_SYSTEM_SHORT: case XTDATEF_SYSTEM_SHORT_YY: SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY ); break; case XTDATEF_SHORT_DDMMYY: SetExtDateFormat( XTDATEF_SHORT_DDMMYYYY ); break; case XTDATEF_SHORT_MMDDYY: SetExtDateFormat( XTDATEF_SHORT_MMDDYYYY ); break; case XTDATEF_SHORT_YYMMDD: SetExtDateFormat( XTDATEF_SHORT_YYYYMMDD ); break; case XTDATEF_SHORT_YYMMDD_DIN5008: SetExtDateFormat( XTDATEF_SHORT_YYYYMMDD_DIN5008 ); break; default: ; } } else { switch ( GetExtDateFormat() ) { case XTDATEF_SYSTEM_SHORT: case XTDATEF_SYSTEM_SHORT_YYYY: SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YY ); break; case XTDATEF_SHORT_DDMMYYYY: SetExtDateFormat( XTDATEF_SHORT_DDMMYY ); break; case XTDATEF_SHORT_MMDDYYYY: SetExtDateFormat( XTDATEF_SHORT_MMDDYY ); break; case XTDATEF_SHORT_YYYYMMDD: SetExtDateFormat( XTDATEF_SHORT_YYMMDD ); break; case XTDATEF_SHORT_YYYYMMDD_DIN5008: SetExtDateFormat( XTDATEF_SHORT_YYMMDD_DIN5008 ); break; default: ; } } ReformatAll(); } // ----------------------------------------------------------------------- void DateFormatter::SetDate( const Date& rNewDate ) { SetUserDate( rNewDate ); maFieldDate = maLastDate; maLastDate = GetDate(); } // ----------------------------------------------------------------------- void DateFormatter::SetUserDate( const Date& rNewDate ) { ImplSetUserDate( rNewDate ); } // ----------------------------------------------------------------------- void DateFormatter::ImplSetUserDate( const Date& rNewDate, Selection* pNewSelection ) { Date aNewDate = rNewDate; if ( aNewDate > maMax ) aNewDate = maMax; else if ( aNewDate < maMin ) aNewDate = maMin; maLastDate = aNewDate; if ( GetField() ) ImplSetText( ImplGetDateAsText( aNewDate, GetFieldSettings() ), pNewSelection ); } // ----------------------------------------------------------------------- void DateFormatter::ImplNewFieldValue( const Date& rDate ) { if ( GetField() ) { Selection aSelection = GetField()->GetSelection(); aSelection.Justify(); XubString aText = GetField()->GetText(); // Wenn bis ans Ende selektiert war, soll das auch so bleiben... if ( (xub_StrLen)aSelection.Max() == aText.Len() ) { if ( !aSelection.Len() ) aSelection.Min() = SELECTION_MAX; aSelection.Max() = SELECTION_MAX; } Date aOldLastDate = maLastDate; ImplSetUserDate( rDate, &aSelection ); maLastDate = aOldLastDate; // Modify am Edit wird nur bei KeyInput gesetzt... if ( GetField()->GetText() != aText ) { GetField()->SetModifyFlag(); GetField()->Modify(); } } } // ----------------------------------------------------------------------- Date DateFormatter::GetDate() const { Date aDate( 0, 0, 0 ); if ( GetField() ) { if ( ImplDateGetValue( GetField()->GetText(), aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) ) { if ( aDate > maMax ) aDate = maMax; else if ( aDate < maMin ) aDate = maMin; } else { // !!! TH-18.2.99: Wenn wir Zeit haben sollte einmal // !!! geklaert werden, warum dieses beim Datum gegenueber // !!! allen anderen Feldern anders behandelt wird. // !!! Siehe dazu Bug: 52304 if ( !ImplAllowMalformedInput() ) { if ( maLastDate.GetDate() ) aDate = maLastDate; else if ( !IsEmptyFieldValueEnabled() ) aDate = Date(); } else aDate = GetInvalidDate(); } } return aDate; } // ----------------------------------------------------------------------- Date DateFormatter::GetRealDate() const { // !!! TH-18.2.99: Wenn wir Zeit haben sollte dieses auch einmal // !!! fuer die Numeric-Klassen eingebaut werden. Date aDate( 0, 0, 0 ); if ( GetField() ) { if ( !ImplDateGetValue( GetField()->GetText(), aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) ) if ( ImplAllowMalformedInput() ) aDate = GetInvalidDate(); } return aDate; } // ----------------------------------------------------------------------- void DateFormatter::SetEmptyDate() { FormatterBase::SetEmptyFieldValue(); } // ----------------------------------------------------------------------- sal_Bool DateFormatter::IsEmptyDate() const { sal_Bool bEmpty = FormatterBase::IsEmptyFieldValue(); if ( GetField() && MustBeReformatted() && IsEmptyFieldValueEnabled() ) { if ( !GetField()->GetText().Len() ) { bEmpty = sal_True; } else if ( !maLastDate.GetDate() ) { Date aDate; bEmpty = !ImplDateGetValue( GetField()->GetText(), aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ); } } return bEmpty; } // ----------------------------------------------------------------------- sal_Bool DateFormatter::IsDateModified() const { if ( ImplGetEmptyFieldValue() ) return !IsEmptyDate(); else if ( GetDate() != maFieldDate ) return sal_True; else return sal_False; } // ----------------------------------------------------------------------- void DateFormatter::Reformat() { if ( !GetField() ) return; if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() ) return; XubString aStr; sal_Bool bOK = ImplDateReformat( GetField()->GetText(), aStr, GetFieldSettings() ); if( !bOK ) return; if ( aStr.Len() ) { ImplSetText( aStr ); ImplDateGetValue( aStr, maLastDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ); } else { if ( maLastDate.GetDate() ) SetDate( maLastDate ); else if ( !IsEmptyFieldValueEnabled() ) SetDate( Date() ); else { ImplSetText( ImplGetSVEmptyStr() ); SetEmptyFieldValueData( sal_True ); } } } // ----------------------------------------------------------------------- void DateFormatter::ExpandCentury( Date& rDate ) { ExpandCentury( rDate, utl::MiscCfg().GetYear2000() ); } // ----------------------------------------------------------------------- void DateFormatter::ExpandCentury( Date& rDate, sal_uInt16 nTwoDigitYearStart ) { sal_uInt16 nDateYear = rDate.GetYear(); if ( nDateYear < 100 ) { sal_uInt16 nCentury = nTwoDigitYearStart / 100; if ( nDateYear < (nTwoDigitYearStart % 100) ) nCentury++; rDate.SetYear( nDateYear + (nCentury*100) ); } } // ----------------------------------------------------------------------- DateField::DateField( Window* pParent, WinBits nWinStyle ) : SpinField( pParent, nWinStyle ), maFirst( GetMin() ), maLast( GetMax() ) { SetField( this ); SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) ); Reformat(); ResetLastDate(); } // ----------------------------------------------------------------------- DateField::DateField( Window* pParent, const ResId& rResId ) : SpinField( WINDOW_DATEFIELD ), maFirst( GetMin() ), maLast( GetMax() ) { rResId.SetRT( RSC_DATEFIELD ); WinBits nStyle = ImplInitRes( rResId ); SpinField::ImplInit( pParent, nStyle ); SetField( this ); SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) ); ImplLoadRes( rResId ); if ( !(nStyle & WB_HIDE ) ) Show(); ResetLastDate(); } // ----------------------------------------------------------------------- void DateField::ImplLoadRes( const ResId& rResId ) { SpinField::ImplLoadRes( rResId ); ResMgr* pMgr = rResId.GetResMgr(); if( pMgr ) { DateFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); sal_uLong nMask = ReadLongRes(); if ( DATEFIELD_FIRST & nMask ) { maFirst = Date( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) ); } if ( DATEFIELD_LAST & nMask ) { maLast = Date( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) ); } } Reformat(); } // ----------------------------------------------------------------------- DateField::~DateField() { } // ----------------------------------------------------------------------- long DateField::PreNotify( NotifyEvent& rNEvt ) { if ( (rNEvt.GetType() == EVENT_KEYINPUT) && IsStrictFormat() && ( GetExtDateFormat() != XTDATEF_SYSTEM_LONG ) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) { if ( ImplDateProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetExtDateFormat( sal_True ), ImplGetLocaleDataWrapper() ) ) return 1; } return SpinField::PreNotify( rNEvt ); } // ----------------------------------------------------------------------- long DateField::Notify( NotifyEvent& rNEvt ) { if ( rNEvt.GetType() == EVENT_GETFOCUS ) MarkToBeReformatted( sal_False ); else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) { if ( MustBeReformatted() ) { // !!! TH-18.2.99: Wenn wir Zeit haben sollte einmal // !!! geklaert werden, warum dieses beim Datum gegenueber // !!! allen anderen Feldern anders behandelt wird. // !!! Siehe dazu Bug: 52304 sal_Bool bTextLen = GetText().Len() != 0; if ( bTextLen || !IsEmptyFieldValueEnabled() ) { if ( !ImplAllowMalformedInput() ) Reformat(); else { Date aDate( 0, 0, 0 ); if ( ImplDateGetValue( GetText(), aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) ) // even with strict text analysis, our text is a valid date -> do a complete // reformat Reformat(); } } else if ( !bTextLen && IsEmptyFieldValueEnabled() ) { ResetLastDate(); SetEmptyFieldValueData( sal_True ); } } } return SpinField::Notify( rNEvt ); } // ----------------------------------------------------------------------- void DateField::DataChanged( const DataChangedEvent& rDCEvt ) { SpinField::DataChanged( rDCEvt ); if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & (SETTINGS_LOCALE|SETTINGS_MISC)) ) { if ( IsDefaultLocale() && ( rDCEvt.GetFlags() & SETTINGS_LOCALE ) ) ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); ReformatAll(); } } // ----------------------------------------------------------------------- void DateField::Modify() { MarkToBeReformatted( sal_True ); SpinField::Modify(); } // ----------------------------------------------------------------------- void DateField::Up() { ImplDateSpinArea( sal_True ); SpinField::Up(); } // ----------------------------------------------------------------------- void DateField::Down() { ImplDateSpinArea( sal_False ); SpinField::Down(); } // ----------------------------------------------------------------------- void DateField::First() { ImplNewFieldValue( maFirst ); SpinField::First(); } // ----------------------------------------------------------------------- void DateField::Last() { ImplNewFieldValue( maLast ); SpinField::Last(); } // ----------------------------------------------------------------------- DateBox::DateBox( Window* pParent, WinBits nWinStyle ) : ComboBox( pParent, nWinStyle ) { SetField( this ); SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) ); Reformat(); } // ----------------------------------------------------------------------- DateBox::DateBox( Window* pParent, const ResId& rResId ) : ComboBox( WINDOW_DATEBOX ) { rResId.SetRT( RSC_DATEBOX ); WinBits nStyle = ImplInitRes( rResId ); ComboBox::ImplInit( pParent, nStyle ); SetField( this ); SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) ); ComboBox::ImplLoadRes( rResId ); ResMgr* pMgr = rResId.GetResMgr(); if( pMgr ) DateFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); Reformat(); if ( !( nStyle & WB_HIDE ) ) Show(); } // ----------------------------------------------------------------------- DateBox::~DateBox() { } // ----------------------------------------------------------------------- long DateBox::PreNotify( NotifyEvent& rNEvt ) { if ( (rNEvt.GetType() == EVENT_KEYINPUT) && IsStrictFormat() && ( GetExtDateFormat() != XTDATEF_SYSTEM_LONG ) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) { if ( ImplDateProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetExtDateFormat( sal_True ), ImplGetLocaleDataWrapper() ) ) return 1; } return ComboBox::PreNotify( rNEvt ); } // ----------------------------------------------------------------------- void DateBox::DataChanged( const DataChangedEvent& rDCEvt ) { ComboBox::DataChanged( rDCEvt ); if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) { if ( IsDefaultLocale() ) ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); ReformatAll(); } } // ----------------------------------------------------------------------- long DateBox::Notify( NotifyEvent& rNEvt ) { if ( rNEvt.GetType() == EVENT_GETFOCUS ) MarkToBeReformatted( sal_False ); else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) { if ( MustBeReformatted() ) { sal_Bool bTextLen = GetText().Len() != 0; if ( bTextLen || !IsEmptyFieldValueEnabled() ) Reformat(); else if ( !bTextLen && IsEmptyFieldValueEnabled() ) { ResetLastDate(); SetEmptyFieldValueData( sal_True ); } } } return ComboBox::Notify( rNEvt ); } // ----------------------------------------------------------------------- void DateBox::Modify() { MarkToBeReformatted( sal_True ); ComboBox::Modify(); } // ----------------------------------------------------------------------- void DateBox::ReformatAll() { XubString aStr; SetUpdateMode( sal_False ); sal_uInt16 nEntryCount = GetEntryCount(); for ( sal_uInt16 i=0; i < nEntryCount; i++ ) { ImplDateReformat( GetEntry( i ), aStr, GetFieldSettings() ); RemoveEntry( i ); InsertEntry( aStr, i ); } DateFormatter::Reformat(); SetUpdateMode( sal_True ); } // ----------------------------------------------------------------------- void DateBox::InsertDate( const Date& rDate, sal_uInt16 nPos ) { Date aDate = rDate; if ( aDate > GetMax() ) aDate = GetMax(); else if ( aDate < GetMin() ) aDate = GetMin(); ComboBox::InsertEntry( ImplGetDateAsText( aDate, GetFieldSettings() ), nPos ); } // ----------------------------------------------------------------------- void DateBox::RemoveDate( const Date& rDate ) { ComboBox::RemoveEntry( ImplGetDateAsText( rDate, GetFieldSettings() ) ); } // ----------------------------------------------------------------------- Date DateBox::GetDate( sal_uInt16 nPos ) const { Date aDate( 0, 0, 0 ); ImplDateGetValue( ComboBox::GetEntry( nPos ), aDate, GetExtDateFormat(sal_True), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetSettings() ); return aDate; } // ----------------------------------------------------------------------- sal_uInt16 DateBox::GetDatePos( const Date& rDate ) const { XubString aStr; if ( IsLongFormat() ) aStr = ImplGetLocaleDataWrapper().getLongDate( rDate, GetCalendarWrapper(), 1, sal_False, 1, !IsShowDateCentury() ); else aStr = ImplGetLocaleDataWrapper().getDate( rDate ); return ComboBox::GetEntryPos( aStr ); } // ----------------------------------------------------------------------- static sal_Bool ImplTimeProcessKeyInput( Edit*, const KeyEvent& rKEvt, sal_Bool bStrictFormat, sal_Bool bDuration, TimeFieldFormat eFormat, const LocaleDataWrapper& rLocaleDataWrapper ) { xub_Unicode cChar = rKEvt.GetCharCode(); if ( !bStrictFormat ) return sal_False; else { sal_uInt16 nGroup = rKEvt.GetKeyCode().GetGroup(); if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) || (nGroup == KEYGROUP_MISC) || ((cChar >= '0') && (cChar <= '9')) || (cChar == rLocaleDataWrapper.getTimeSep()) || ( ( rLocaleDataWrapper.getTimeAM().Search( cChar ) != STRING_NOTFOUND ) ) || ( ( rLocaleDataWrapper.getTimePM().Search( cChar ) != STRING_NOTFOUND ) ) || // Accept AM/PM: (cChar == 'a') || (cChar == 'A') || (cChar == 'm') || (cChar == 'M') || (cChar == 'p') || (cChar == 'P') || ((eFormat == TIMEF_100TH_SEC) && (cChar == rLocaleDataWrapper.getTime100SecSep())) || ((eFormat == TIMEF_SEC_CS) && (cChar == rLocaleDataWrapper.getTime100SecSep())) || (bDuration && (cChar == '-')) ) return sal_False; else return sal_True; } } // ----------------------------------------------------------------------- static sal_Bool ImplIsOnlyDigits( const String& _rStr ) { const sal_Unicode* _pChr = _rStr.GetBuffer(); for ( xub_StrLen i = 0; i < _rStr.Len(); ++i, ++_pChr ) { if ( *_pChr < '0' || *_pChr > '9' ) return sal_False; } return sal_True; } // ----------------------------------------------------------------------- static sal_Bool ImplIsValidTimePortion( sal_Bool _bSkipInvalidCharacters, const String& _rStr ) { if ( !_bSkipInvalidCharacters ) { if ( ( _rStr.Len() > 2 ) || ( _rStr.Len() < 1 ) || !ImplIsOnlyDigits( _rStr ) ) return sal_False; } return sal_True; } // ----------------------------------------------------------------------- static sal_Bool ImplCutTimePortion( String& _rStr, xub_StrLen _nSepPos, sal_Bool _bSkipInvalidCharacters, short* _pPortion ) { String sPortion = _rStr.Copy( 0, _nSepPos ); _rStr.Erase( 0, _nSepPos + 1 ); if ( !ImplIsValidTimePortion( _bSkipInvalidCharacters, sPortion ) ) return sal_False; *_pPortion = (short)sPortion.ToInt32(); return sal_True; } // ----------------------------------------------------------------------- static sal_Bool ImplTimeGetValue( const XubString& rStr, Time& rTime, TimeFieldFormat eFormat, sal_Bool bDuration, const LocaleDataWrapper& rLocaleDataWrapper, sal_Bool _bSkipInvalidCharacters = sal_True ) { XubString aStr = rStr; short nHour = 0; short nMinute = 0; short nSecond = 0; short n100Sec = 0; Time aTime( 0, 0, 0 ); if ( !rStr.Len() ) return sal_False; // Nach Separatoren suchen if ( rLocaleDataWrapper.getTimeSep().Len() ) { XubString aSepStr( RTL_CONSTASCII_USTRINGPARAM( ",.;:/" ) ); if ( !bDuration ) aSepStr.Append( '-' ); // Die obigen Zeichen durch das Separatorzeichen ersetzen for ( xub_StrLen i = 0; i < aSepStr.Len(); i++ ) { if ( aSepStr.GetChar( i ) == rLocaleDataWrapper.getTimeSep() ) continue; for ( xub_StrLen j = 0; j < aStr.Len(); j++ ) { if ( aStr.GetChar( j ) == aSepStr.GetChar( i ) ) aStr.SetChar( j, rLocaleDataWrapper.getTimeSep().GetChar(0) ); } } } sal_Bool bNegative = sal_False; xub_StrLen nSepPos = aStr.Search( rLocaleDataWrapper.getTimeSep() ); if ( aStr.GetChar( 0 ) == '-' ) bNegative = sal_True; if ( eFormat != TIMEF_SEC_CS ) { if ( nSepPos == STRING_NOTFOUND ) nSepPos = aStr.Len(); if ( !ImplCutTimePortion( aStr, nSepPos, _bSkipInvalidCharacters, &nHour ) ) return sal_False; nSepPos = aStr.Search( rLocaleDataWrapper.getTimeSep() ); if ( aStr.GetChar( 0 ) == '-' ) bNegative = sal_True; if ( nSepPos != STRING_NOTFOUND ) { if ( !ImplCutTimePortion( aStr, nSepPos, _bSkipInvalidCharacters, &nMinute ) ) return sal_False; nSepPos = aStr.Search( rLocaleDataWrapper.getTimeSep() ); if ( aStr.GetChar( 0 ) == '-' ) bNegative = sal_True; if ( nSepPos != STRING_NOTFOUND ) { if ( !ImplCutTimePortion( aStr, nSepPos, _bSkipInvalidCharacters, &nSecond ) ) return sal_False; if ( aStr.GetChar( 0 ) == '-' ) bNegative = sal_True; n100Sec = (short)aStr.ToInt32(); } else nSecond = (short)aStr.ToInt32(); } else nMinute = (short)aStr.ToInt32(); } else if ( nSepPos == STRING_NOTFOUND ) { nSecond = (short)aStr.ToInt32(); nMinute += nSecond / 60; nSecond %= 60; nHour += nMinute / 60; nMinute %= 60; } else { nSecond = (short)aStr.Copy( 0, nSepPos ).ToInt32(); aStr.Erase( 0, nSepPos+1 ); nSepPos = aStr.Search( rLocaleDataWrapper.getTimeSep() ); if ( aStr.GetChar( 0 ) == '-' ) bNegative = sal_True; if ( nSepPos != STRING_NOTFOUND ) { nMinute = nSecond; nSecond = (short)aStr.Copy( 0, nSepPos ).ToInt32(); aStr.Erase( 0, nSepPos+1 ); nSepPos = aStr.Search( rLocaleDataWrapper.getTimeSep() ); if ( aStr.GetChar( 0 ) == '-' ) bNegative = sal_True; if ( nSepPos != STRING_NOTFOUND ) { nHour = nMinute; nMinute = nSecond; nSecond = (short)aStr.Copy( 0, nSepPos ).ToInt32(); aStr.Erase( 0, nSepPos+1 ); } else { nHour += nMinute / 60; nMinute %= 60; } } else { nMinute += nSecond / 60; nSecond %= 60; nHour += nMinute / 60; nMinute %= 60; } n100Sec = (short)aStr.ToInt32(); if ( n100Sec ) { xub_StrLen nLen = 1; // mindestens eine Ziffer, weil sonst n100Sec==0 while ( aStr.GetChar(nLen) >= '0' && aStr.GetChar(nLen) <= '9' ) nLen++; if ( nLen > 2 ) { while( nLen > 3 ) { n100Sec = n100Sec / 10; nLen--; } // Rundung bei negativen Zahlen??? n100Sec = (n100Sec + 5) / 10; } else { while( nLen < 2 ) { n100Sec = n100Sec * 10; nLen++; } } } } if ( (nMinute > 59) || (nSecond > 59) || (n100Sec > 100) ) return sal_False; if ( eFormat == TIMEF_NONE ) nSecond = n100Sec = 0; else if ( eFormat == TIMEF_SEC ) n100Sec = 0; if ( !bDuration ) { if ( bNegative || (nHour < 0) || (nMinute < 0) || (nSecond < 0) || (n100Sec < 0) ) return sal_False; aStr.ToUpperAscii(); XubString aAM( rLocaleDataWrapper.getTimeAM() ); XubString aPM( rLocaleDataWrapper.getTimePM() ); aAM.ToUpperAscii(); aPM.ToUpperAscii(); XubString aAM2( RTL_CONSTASCII_USTRINGPARAM( "AM" ) ); // aAM is localized XubString aPM2( RTL_CONSTASCII_USTRINGPARAM( "PM" ) ); // aPM is localized if ( (nHour < 12) && ( ( aStr.Search( aPM ) != STRING_NOTFOUND ) || ( aStr.Search( aPM2 ) != STRING_NOTFOUND ) ) ) nHour += 12; if ( (nHour == 12) && ( ( aStr.Search( aAM ) != STRING_NOTFOUND ) || ( aStr.Search( aAM2 ) != STRING_NOTFOUND ) ) ) nHour = 0; aTime = Time( (sal_uInt16)nHour, (sal_uInt16)nMinute, (sal_uInt16)nSecond, (sal_uInt16)n100Sec ); } else { if ( bNegative || (nHour < 0) || (nMinute < 0) || (nSecond < 0) || (n100Sec < 0) ) { bNegative = sal_True; nHour = nHour < 0 ? -nHour : nHour; nMinute = nMinute < 0 ? -nMinute : nMinute; nSecond = nSecond < 0 ? -nSecond : nSecond; n100Sec = n100Sec < 0 ? -n100Sec : n100Sec; } aTime = Time( (sal_uInt16)nHour, (sal_uInt16)nMinute, (sal_uInt16)nSecond, (sal_uInt16)n100Sec ); if ( bNegative ) aTime = -aTime; } rTime = aTime; return sal_True; } // ----------------------------------------------------------------------- sal_Bool TimeFormatter::ImplTimeReformat( const XubString& rStr, XubString& rOutStr ) { Time aTime( 0, 0, 0 ); if ( !ImplTimeGetValue( rStr, aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper() ) ) return sal_True; Time aTempTime = aTime; if ( aTempTime > GetMax() ) aTempTime = GetMax() ; else if ( aTempTime < GetMin() ) aTempTime = GetMin(); if ( GetErrorHdl().IsSet() && (aTime != aTempTime) ) { maCorrectedTime = aTempTime; if ( !GetErrorHdl().Call( this ) ) { maCorrectedTime = Time(); return sal_False; } else maCorrectedTime = Time(); } sal_Bool bSecond = sal_False; sal_Bool b100Sec = sal_False; if ( meFormat != TIMEF_NONE ) bSecond = sal_True; if ( meFormat == TIMEF_100TH_SEC ) b100Sec = sal_True; if ( meFormat == TIMEF_SEC_CS ) { sal_uLong n = aTempTime.GetHour() * 3600L; n += aTempTime.GetMin() * 60L; n += aTempTime.GetSec(); rOutStr = String::CreateFromInt32( n ); rOutStr += ImplGetLocaleDataWrapper().getTime100SecSep(); if ( aTempTime.Get100Sec() < 10 ) rOutStr += '0'; rOutStr += String::CreateFromInt32( aTempTime.Get100Sec() ); } else if ( mbDuration ) rOutStr = ImplGetLocaleDataWrapper().getDuration( aTempTime, bSecond, b100Sec ); else { rOutStr = ImplGetLocaleDataWrapper().getTime( aTempTime, bSecond, b100Sec ); if ( GetTimeFormat() == HOUR_12 ) { if ( aTempTime.GetHour() > 12 ) { Time aT( aTempTime ); aT.SetHour( aT.GetHour() % 12 ); rOutStr = ImplGetLocaleDataWrapper().getTime( aT, bSecond, b100Sec ); } // Don't use LocaleDataWrapper, we want AM/PM if ( aTempTime.GetHour() < 12 ) rOutStr += String( RTL_CONSTASCII_USTRINGPARAM( "AM" ) ); // ImplGetLocaleDataWrapper().getTimeAM(); else rOutStr += String( RTL_CONSTASCII_USTRINGPARAM( "PM" ) ); // ImplGetLocaleDataWrapper().getTimePM(); } } return sal_True; } // ----------------------------------------------------------------------- sal_Bool TimeFormatter::ImplAllowMalformedInput() const { return !IsEnforceValidValue(); } // ----------------------------------------------------------------------- void TimeField::ImplTimeSpinArea( sal_Bool bUp ) { if ( GetField() ) { xub_StrLen nTimeArea = 0; Time aTime( GetTime() ); XubString aText( GetText() ); Selection aSelection( GetField()->GetSelection() ); // Area suchen if ( GetFormat() != TIMEF_SEC_CS ) { for ( xub_StrLen i = 1, nPos = 0; i <= 4; i++ ) { xub_StrLen nPos1 = aText.Search( ImplGetLocaleDataWrapper().getTimeSep(), nPos ); xub_StrLen nPos2 = aText.Search( ImplGetLocaleDataWrapper().getTime100SecSep(), nPos ); nPos = nPos1 < nPos2 ? nPos1 : nPos2; if ( nPos >= (xub_StrLen)aSelection.Max() ) { nTimeArea = i; break; } else nPos++; } } else { xub_StrLen nPos = aText.Search( ImplGetLocaleDataWrapper().getTime100SecSep() ); if ( nPos == STRING_NOTFOUND || nPos >= (xub_StrLen)aSelection.Max() ) nTimeArea = 3; else nTimeArea = 4; } if ( nTimeArea ) { Time aAddTime( 0, 0, 0 ); if ( nTimeArea == 1 ) aAddTime = Time( 1, 0 ); else if ( nTimeArea == 2 ) aAddTime = Time( 0, 1 ); else if ( nTimeArea == 3 ) aAddTime = Time( 0, 0, 1 ); else if ( nTimeArea == 4 ) aAddTime = Time( 0, 0, 0, 1 ); if ( !bUp ) aAddTime = -aAddTime; aTime += aAddTime; if ( !IsDuration() ) { Time aAbsMaxTime( 23, 59, 59, 99 ); if ( aTime > aAbsMaxTime ) aTime = aAbsMaxTime; Time aAbsMinTime( 0, 0 ); if ( aTime < aAbsMinTime ) aTime = aAbsMinTime; } ImplNewFieldValue( aTime ); } } } // ----------------------------------------------------------------------- void TimeFormatter::ImplInit() { meFormat = TIMEF_NONE; mbDuration = sal_False; mnTimeFormat = HOUR_24; // Should become a ExtTimeFieldFormat in next implementation, merge with mbDuration and meFormat } // ----------------------------------------------------------------------- TimeFormatter::TimeFormatter() : maLastTime( 0, 0 ), maMin( 0, 0 ), maMax( 23, 59, 59, 99 ), mbEnforceValidValue( sal_True ), maFieldTime( 0, 0 ) { ImplInit(); } // ----------------------------------------------------------------------- void TimeFormatter::ImplLoadRes( const ResId& rResId ) { ResMgr* pMgr = rResId.GetResMgr(); if( pMgr ) { sal_uLong nMask = pMgr->ReadLong(); if ( TIMEFORMATTER_MIN & nMask ) { SetMin( Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ) ); pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) ); } if ( TIMEFORMATTER_MAX & nMask ) { SetMax( Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ) ); pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) ); } if ( TIMEFORMATTER_TIMEFIELDFORMAT & nMask ) meFormat = (TimeFieldFormat)pMgr->ReadLong(); if ( TIMEFORMATTER_DURATION & nMask ) mbDuration = (sal_Bool)pMgr->ReadShort(); if ( TIMEFORMATTER_STRICTFORMAT & nMask ) SetStrictFormat( (sal_Bool)pMgr->ReadShort() ); if ( TIMEFORMATTER_VALUE & nMask ) { maFieldTime = Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ); if ( maFieldTime > GetMax() ) maFieldTime = GetMax(); if ( maFieldTime < GetMin() ) maFieldTime = GetMin(); maLastTime = maFieldTime; pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) ); } } } // ----------------------------------------------------------------------- TimeFormatter::~TimeFormatter() { } // ----------------------------------------------------------------------- void TimeFormatter::ReformatAll() { Reformat(); } // ----------------------------------------------------------------------- void TimeFormatter::SetMin( const Time& rNewMin ) { maMin = rNewMin; if ( !IsEmptyFieldValue() ) ReformatAll(); } // ----------------------------------------------------------------------- void TimeFormatter::SetMax( const Time& rNewMax ) { maMax = rNewMax; if ( !IsEmptyFieldValue() ) ReformatAll(); } // ----------------------------------------------------------------------- void TimeFormatter::SetTimeFormat( TimeFormatter::TimeFormat eNewFormat ) { mnTimeFormat = sal::static_int_cast(eNewFormat); } // ----------------------------------------------------------------------- TimeFormatter::TimeFormat TimeFormatter::GetTimeFormat() const { return (TimeFormat)mnTimeFormat; } // ----------------------------------------------------------------------- void TimeFormatter::SetFormat( TimeFieldFormat eNewFormat ) { meFormat = eNewFormat; ReformatAll(); } // ----------------------------------------------------------------------- void TimeFormatter::SetDuration( sal_Bool bNewDuration ) { mbDuration = bNewDuration; ReformatAll(); } // ----------------------------------------------------------------------- void TimeFormatter::SetTime( const Time& rNewTime ) { SetUserTime( rNewTime ); maFieldTime = maLastTime; SetEmptyFieldValueData( sal_False ); } // ----------------------------------------------------------------------- void TimeFormatter::ImplNewFieldValue( const Time& rTime ) { if ( GetField() ) { Selection aSelection = GetField()->GetSelection(); aSelection.Justify(); XubString aText = GetField()->GetText(); // Wenn bis ans Ende selektiert war, soll das auch so bleiben... if ( (xub_StrLen)aSelection.Max() == aText.Len() ) { if ( !aSelection.Len() ) aSelection.Min() = SELECTION_MAX; aSelection.Max() = SELECTION_MAX; } Time aOldLastTime = maLastTime; ImplSetUserTime( rTime, &aSelection ); maLastTime = aOldLastTime; // Modify am Edit wird nur bei KeyInput gesetzt... if ( GetField()->GetText() != aText ) { GetField()->SetModifyFlag(); GetField()->Modify(); } } } // ----------------------------------------------------------------------- void TimeFormatter::ImplSetUserTime( const Time& rNewTime, Selection* pNewSelection ) { Time aNewTime = rNewTime; if ( aNewTime > GetMax() ) aNewTime = GetMax(); else if ( aNewTime < GetMin() ) aNewTime = GetMin(); maLastTime = aNewTime; if ( GetField() ) { XubString aStr; sal_Bool bSec = sal_False; sal_Bool b100Sec = sal_False; if ( meFormat != TIMEF_NONE ) bSec = sal_True; if ( meFormat == TIMEF_100TH_SEC || meFormat == TIMEF_SEC_CS ) b100Sec = sal_True; if ( meFormat == TIMEF_SEC_CS ) { sal_uLong n = aNewTime.GetHour() * 3600L; n += aNewTime.GetMin() * 60L; n += aNewTime.GetSec(); aStr = String::CreateFromInt32( n ); aStr += ImplGetLocaleDataWrapper().getTime100SecSep(); if ( aNewTime.Get100Sec() < 10 ) aStr += '0'; aStr += String::CreateFromInt32( aNewTime.Get100Sec() ); } else if ( mbDuration ) { aStr = ImplGetLocaleDataWrapper().getDuration( aNewTime, bSec, b100Sec ); } else { aStr = ImplGetLocaleDataWrapper().getTime( aNewTime, bSec, b100Sec ); if ( GetTimeFormat() == HOUR_12 ) { if ( aNewTime.GetHour() > 12 ) { Time aT( aNewTime ); aT.SetHour( aT.GetHour() % 12 ); aStr = ImplGetLocaleDataWrapper().getTime( aT, bSec, b100Sec ); } // Don't use LocaleDataWrapper, we want AM/PM if ( aNewTime.GetHour() < 12 ) aStr += String( RTL_CONSTASCII_USTRINGPARAM( "AM" ) ); // ImplGetLocaleDataWrapper().getTimeAM(); else aStr += String( RTL_CONSTASCII_USTRINGPARAM( "PM" ) ); // ImplGetLocaleDataWrapper().getTimePM(); } } ImplSetText( aStr, pNewSelection ); } } // ----------------------------------------------------------------------- void TimeFormatter::SetUserTime( const Time& rNewTime ) { ImplSetUserTime( rNewTime ); } // ----------------------------------------------------------------------- Time TimeFormatter::GetTime() const { Time aTime( 0, 0, 0 ); if ( GetField() ) { sal_Bool bAllowMailformed = ImplAllowMalformedInput(); if ( ImplTimeGetValue( GetField()->GetText(), aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper(), !bAllowMailformed ) ) { if ( aTime > GetMax() ) aTime = GetMax(); else if ( aTime < GetMin() ) aTime = GetMin(); } else { if ( bAllowMailformed ) aTime = GetInvalidTime(); else aTime = maLastTime; } } return aTime; } // ----------------------------------------------------------------------- Time TimeFormatter::GetRealTime() const { Time aTime( 0, 0, 0 ); if ( GetField() ) { sal_Bool bAllowMailformed = ImplAllowMalformedInput(); if ( !ImplTimeGetValue( GetField()->GetText(), aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper(), !bAllowMailformed ) ) if ( bAllowMailformed ) aTime = GetInvalidTime(); } return aTime; } // ----------------------------------------------------------------------- sal_Bool TimeFormatter::IsTimeModified() const { if ( ImplGetEmptyFieldValue() ) return !IsEmptyTime(); else if ( GetTime() != maFieldTime ) return sal_True; else return sal_False; } // ----------------------------------------------------------------------- void TimeFormatter::Reformat() { if ( !GetField() ) return; if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() ) return; XubString aStr; sal_Bool bOK = ImplTimeReformat( GetField()->GetText(), aStr ); if ( !bOK ) return; if ( aStr.Len() ) { ImplSetText( aStr ); ImplTimeGetValue( aStr, maLastTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper() ); } else SetTime( maLastTime ); } // ----------------------------------------------------------------------- TimeField::TimeField( Window* pParent, WinBits nWinStyle ) : SpinField( pParent, nWinStyle ), maFirst( GetMin() ), maLast( GetMax() ) { SetField( this ); SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime, sal_False, sal_False ) ); Reformat(); } // ----------------------------------------------------------------------- TimeField::TimeField( Window* pParent, const ResId& rResId ) : SpinField( WINDOW_TIMEFIELD ), maFirst( GetMin() ), maLast( GetMax() ) { rResId.SetRT( RSC_TIMEFIELD ); WinBits nStyle = ImplInitRes( rResId ); SpinField::ImplInit( pParent, nStyle ); SetField( this ); SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime, sal_False, sal_False ) ); ImplLoadRes( rResId ); if ( !(nStyle & WB_HIDE ) ) Show(); } // ----------------------------------------------------------------------- void TimeField::ImplLoadRes( const ResId& rResId ) { SpinField::ImplLoadRes( rResId ); ResMgr* pMgr = rResId.GetResMgr(); if( pMgr ) { TimeFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); sal_uLong nMask = ReadLongRes(); if ( TIMEFIELD_FIRST & nMask ) { maFirst = Time( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) ); } if ( TIMEFIELD_LAST & nMask ) { maLast = Time( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) ); } } Reformat(); } // ----------------------------------------------------------------------- TimeField::~TimeField() { } // ----------------------------------------------------------------------- long TimeField::PreNotify( NotifyEvent& rNEvt ) { if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) { if ( ImplTimeProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsDuration(), GetFormat(), ImplGetLocaleDataWrapper() ) ) return 1; } return SpinField::PreNotify( rNEvt ); } // ----------------------------------------------------------------------- long TimeField::Notify( NotifyEvent& rNEvt ) { if ( rNEvt.GetType() == EVENT_GETFOCUS ) MarkToBeReformatted( sal_False ); else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) { if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) { if ( !ImplAllowMalformedInput() ) Reformat(); else { Time aTime( 0, 0, 0 ); if ( ImplTimeGetValue( GetText(), aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper(), sal_False ) ) // even with strict text analysis, our text is a valid time -> do a complete // reformat Reformat(); } } } return SpinField::Notify( rNEvt ); } // ----------------------------------------------------------------------- void TimeField::DataChanged( const DataChangedEvent& rDCEvt ) { SpinField::DataChanged( rDCEvt ); if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) { if ( IsDefaultLocale() ) ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); ReformatAll(); } } // ----------------------------------------------------------------------- void TimeField::Modify() { MarkToBeReformatted( sal_True ); SpinField::Modify(); } // ----------------------------------------------------------------------- void TimeField::Up() { ImplTimeSpinArea( sal_True ); SpinField::Up(); } // ----------------------------------------------------------------------- void TimeField::Down() { ImplTimeSpinArea( sal_False ); SpinField::Down(); } // ----------------------------------------------------------------------- void TimeField::First() { ImplNewFieldValue( maFirst ); SpinField::First(); } // ----------------------------------------------------------------------- void TimeField::Last() { ImplNewFieldValue( maLast ); SpinField::Last(); } // ----------------------------------------------------------------------- void TimeField::SetExtFormat( ExtTimeFieldFormat eFormat ) { switch ( eFormat ) { case EXTTIMEF_24H_SHORT: { SetTimeFormat( HOUR_24 ); SetDuration( sal_False ); SetFormat( TIMEF_NONE ); } break; case EXTTIMEF_24H_LONG: { SetTimeFormat( HOUR_24 ); SetDuration( sal_False ); SetFormat( TIMEF_SEC ); } break; case EXTTIMEF_12H_SHORT: { SetTimeFormat( HOUR_12 ); SetDuration( sal_False ); SetFormat( TIMEF_NONE ); } break; case EXTTIMEF_12H_LONG: { SetTimeFormat( HOUR_12 ); SetDuration( sal_False ); SetFormat( TIMEF_SEC ); } break; case EXTTIMEF_DURATION_SHORT: { SetDuration( sal_True ); SetFormat( TIMEF_NONE ); } break; case EXTTIMEF_DURATION_LONG: { SetDuration( sal_True ); SetFormat( TIMEF_SEC ); } break; default: DBG_ERROR( "ExtTimeFieldFormat unknown!" ); } if ( GetField() && GetField()->GetText().Len() ) SetUserTime( GetTime() ); ReformatAll(); } // ----------------------------------------------------------------------- TimeBox::TimeBox( Window* pParent, WinBits nWinStyle ) : ComboBox( pParent, nWinStyle ) { SetField( this ); SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime, sal_False, sal_False ) ); Reformat(); } // ----------------------------------------------------------------------- TimeBox::TimeBox( Window* pParent, const ResId& rResId ) : ComboBox( WINDOW_TIMEBOX ) { rResId.SetRT( RSC_TIMEBOX ); WinBits nStyle = ImplInitRes( rResId ); ComboBox::ImplInit( pParent, nStyle ); SetField( this ); SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime, sal_False, sal_False ) ); ComboBox::ImplLoadRes( rResId ); ResMgr* pMgr = rResId.GetResMgr(); if( pMgr ) TimeFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) ); Reformat(); if ( !(nStyle & WB_HIDE) ) Show(); } // ----------------------------------------------------------------------- TimeBox::~TimeBox() { } // ----------------------------------------------------------------------- long TimeBox::PreNotify( NotifyEvent& rNEvt ) { if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() ) { if ( ImplTimeProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsDuration(), GetFormat(), ImplGetLocaleDataWrapper() ) ) return 1; } return ComboBox::PreNotify( rNEvt ); } // ----------------------------------------------------------------------- long TimeBox::Notify( NotifyEvent& rNEvt ) { if ( rNEvt.GetType() == EVENT_GETFOCUS ) MarkToBeReformatted( sal_False ); else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) { if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) ) Reformat(); } return ComboBox::Notify( rNEvt ); } // ----------------------------------------------------------------------- void TimeBox::DataChanged( const DataChangedEvent& rDCEvt ) { ComboBox::DataChanged( rDCEvt ); if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) ) { if ( IsDefaultLocale() ) ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() ); ReformatAll(); } } // ----------------------------------------------------------------------- void TimeBox::Modify() { MarkToBeReformatted( sal_True ); ComboBox::Modify(); } // ----------------------------------------------------------------------- void TimeBox::ReformatAll() { XubString aStr; SetUpdateMode( sal_False ); sal_uInt16 nEntryCount = GetEntryCount(); for ( sal_uInt16 i=0; i < nEntryCount; i++ ) { ImplTimeReformat( GetEntry( i ), aStr ); RemoveEntry( i ); InsertEntry( aStr, i ); } TimeFormatter::Reformat(); SetUpdateMode( sal_True ); } // ----------------------------------------------------------------------- void TimeBox::InsertTime( const Time& rTime, sal_uInt16 nPos ) { Time aTime = rTime; if ( aTime > GetMax() ) aTime = GetMax(); else if ( aTime < GetMin() ) aTime = GetMin(); sal_Bool bSec = sal_False; sal_Bool b100Sec = sal_False; if ( GetFormat() == TIMEF_SEC ) bSec = sal_True; if ( GetFormat() == TIMEF_100TH_SEC || GetFormat() == TIMEF_SEC_CS ) bSec = b100Sec = sal_True; ComboBox::InsertEntry( ImplGetLocaleDataWrapper().getTime( aTime, bSec, b100Sec ), nPos ); } // ----------------------------------------------------------------------- void TimeBox::RemoveTime( const Time& rTime ) { sal_Bool bSec = sal_False; sal_Bool b100Sec = sal_False; if ( GetFormat() == TIMEF_SEC ) bSec = sal_True; if ( GetFormat() == TIMEF_100TH_SEC || TIMEF_SEC_CS ) bSec = b100Sec = sal_True; ComboBox::RemoveEntry( ImplGetLocaleDataWrapper().getTime( rTime, bSec, b100Sec ) ); } // ----------------------------------------------------------------------- Time TimeBox::GetTime( sal_uInt16 nPos ) const { Time aTime( 0, 0, 0 ); ImplTimeGetValue( ComboBox::GetEntry( nPos ), aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper() ); return aTime; } // ----------------------------------------------------------------------- sal_uInt16 TimeBox::GetTimePos( const Time& rTime ) const { sal_Bool bSec = sal_False; sal_Bool b100Sec = sal_False; if ( GetFormat() == TIMEF_SEC ) bSec = sal_True; if ( GetFormat() == TIMEF_100TH_SEC || TIMEF_SEC_CS ) bSec = b100Sec = sal_True; return ComboBox::GetEntryPos( ImplGetLocaleDataWrapper().getTime( rTime, bSec, b100Sec ) ); }