/**************************************************************
 * 
 * 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 <tools/debug.hxx>

#include <tools/rc.h>

#include <vcl/svapp.hxx>
#include <vcl/sound.hxx>
#include <vcl/event.hxx>
#include <vcl/field.hxx>
#include <vcl/unohelp.hxx>

#include <svdata.hxx>

#include <i18npool/mslangid.hxx>

#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/i18n/XCharacterClassification.hpp>
#include <com/sun/star/i18n/KCharacterType.hpp>


#include <unotools/localedatawrapper.hxx>
#include <unotools/calendarwrapper.hxx>
#include <unotools/charclass.hxx>
#include <unotools/misccfg.hxx>

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<sal_uInt16>(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 ) );
}
