LCOV - code coverage report
Current view: top level - vcl/source/control - field2.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1601 0.0 %
Date: 2014-04-14 Functions: 0 142 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "sal/config.h"
      21             : 
      22             : #include <algorithm>
      23             : 
      24             : #include <tools/diagnose_ex.h>
      25             : #include <comphelper/processfactory.hxx>
      26             : #include <comphelper/string.hxx>
      27             : #include <tools/rc.h>
      28             : #include <vcl/svapp.hxx>
      29             : #include <vcl/event.hxx>
      30             : #include <vcl/field.hxx>
      31             : #include <vcl/unohelp.hxx>
      32             : #include <vcl/settings.hxx>
      33             : 
      34             : #include <svdata.hxx>
      35             : 
      36             : #include <i18nlangtag/mslangid.hxx>
      37             : 
      38             : #include <com/sun/star/lang/Locale.hpp>
      39             : #include <com/sun/star/i18n/XCharacterClassification.hpp>
      40             : #include <com/sun/star/i18n/KCharacterType.hpp>
      41             : 
      42             : #include <unotools/localedatawrapper.hxx>
      43             : #include <unotools/calendarwrapper.hxx>
      44             : #include <unotools/charclass.hxx>
      45             : #include <unotools/misccfg.hxx>
      46             : 
      47             : using namespace ::com::sun::star;
      48             : using namespace ::comphelper;
      49             : 
      50             : #define EDITMASK_LITERAL       'L'
      51             : #define EDITMASK_ALPHA         'a'
      52             : #define EDITMASK_UPPERALPHA    'A'
      53             : #define EDITMASK_ALPHANUM      'c'
      54             : #define EDITMASK_UPPERALPHANUM 'C'
      55             : #define EDITMASK_NUM           'N'
      56             : #define EDITMASK_NUMSPACE      'n'
      57             : #define EDITMASK_ALLCHAR       'x'
      58             : #define EDITMASK_UPPERALLCHAR  'X'
      59             : 
      60           0 : uno::Reference< i18n::XCharacterClassification > ImplGetCharClass()
      61             : {
      62           0 :     static uno::Reference< i18n::XCharacterClassification > xCharClass;
      63           0 :     if ( !xCharClass.is() )
      64           0 :         xCharClass = vcl::unohelper::CreateCharacterClassification();
      65             : 
      66           0 :     return xCharClass;
      67             : }
      68             : 
      69           0 : static sal_Unicode* ImplAddString( sal_Unicode* pBuf, const OUString& rStr )
      70             : {
      71           0 :     if ( rStr.getLength() == 1 )
      72           0 :         *pBuf++ = rStr[0];
      73           0 :     else if ( rStr.isEmpty() )
      74             :         ;
      75             :     else
      76             :     {
      77           0 :         memcpy( pBuf, rStr.getStr(), rStr.getLength() * sizeof(sal_Unicode) );
      78           0 :         pBuf += rStr.getLength();
      79             :     }
      80           0 :     return pBuf;
      81             : }
      82             : 
      83           0 : static sal_Unicode* ImplAddNum( sal_Unicode* pBuf, sal_uLong nNumber, int nMinLen )
      84             : {
      85             :     // fill temp buffer with digits
      86             :     sal_Unicode aTempBuf[30];
      87           0 :     sal_Unicode* pTempBuf = aTempBuf;
      88           0 :     do
      89             :     {
      90           0 :         *pTempBuf = (sal_Unicode)(nNumber % 10) + '0';
      91           0 :         pTempBuf++;
      92           0 :         nNumber /= 10;
      93           0 :         if ( nMinLen )
      94           0 :             nMinLen--;
      95             :     }
      96             :     while ( nNumber );
      97             : 
      98             :     // fill with zeros up to the minimal length
      99           0 :     while ( nMinLen > 0 )
     100             :     {
     101           0 :         *pBuf = '0';
     102           0 :         pBuf++;
     103           0 :         nMinLen--;
     104             :     }
     105             : 
     106             :     // copy temp buffer to real buffer
     107           0 :     do
     108             :     {
     109           0 :         pTempBuf--;
     110           0 :         *pBuf = *pTempBuf;
     111           0 :         pBuf++;
     112             :     }
     113             :     while ( pTempBuf != aTempBuf );
     114             : 
     115           0 :     return pBuf;
     116             : }
     117             : 
     118           0 : static sal_uInt16 ImplGetNum( const sal_Unicode*& rpBuf, bool& rbError )
     119             : {
     120           0 :     if ( !*rpBuf )
     121             :     {
     122           0 :         rbError = true;
     123           0 :         return 0;
     124             :     }
     125             : 
     126           0 :     sal_uInt16 nNumber = 0;
     127           0 :     while( ( *rpBuf >= '0' ) && ( *rpBuf <= '9' ) )
     128             :     {
     129           0 :         nNumber *= 10;
     130           0 :         nNumber += *rpBuf - '0';
     131           0 :         rpBuf++;
     132             :     }
     133             : 
     134           0 :     return nNumber;
     135             : }
     136             : 
     137           0 : static void ImplSkipDelimiters( const sal_Unicode*& rpBuf )
     138             : {
     139           0 :     while( ( *rpBuf == ',' ) || ( *rpBuf == '.' ) || ( *rpBuf == ';' ) ||
     140           0 :            ( *rpBuf == ':' ) || ( *rpBuf == '-' ) || ( *rpBuf == '/' ) )
     141             :     {
     142           0 :         rpBuf++;
     143             :     }
     144           0 : }
     145             : 
     146           0 : static bool ImplIsPatternChar( sal_Unicode cChar, sal_Char cEditMask )
     147             : {
     148           0 :     sal_Int32 nType = 0;
     149             : 
     150             :     try
     151             :     {
     152           0 :         OUString aCharStr(cChar);
     153           0 :         nType = ImplGetCharClass()->getStringType( aCharStr, 0, aCharStr.getLength(),
     154           0 :                 Application::GetSettings().GetLanguageTag().getLocale() );
     155             :     }
     156           0 :     catch (const ::com::sun::star::uno::Exception&)
     157             :     {
     158             :         SAL_WARN( "vcl.control", "ImplIsPatternChar: Exception caught!" );
     159             :         DBG_UNHANDLED_EXCEPTION();
     160           0 :         return false;
     161             :     }
     162             : 
     163           0 :     if ( (cEditMask == EDITMASK_ALPHA) || (cEditMask == EDITMASK_UPPERALPHA) )
     164             :     {
     165           0 :         if( !CharClass::isLetterType( nType ) )
     166           0 :             return false;
     167             :     }
     168           0 :     else if ( cEditMask == EDITMASK_NUM )
     169             :     {
     170           0 :         if( !CharClass::isNumericType( nType ) )
     171           0 :             return false;
     172             :     }
     173           0 :     else if ( (cEditMask == EDITMASK_ALPHANUM) || (cEditMask == EDITMASK_UPPERALPHANUM) )
     174             :     {
     175           0 :         if( !CharClass::isLetterNumericType( nType ) )
     176           0 :             return false;
     177             :     }
     178           0 :     else if ( (cEditMask == EDITMASK_ALLCHAR) || (cEditMask == EDITMASK_UPPERALLCHAR) )
     179             :     {
     180           0 :         if ( cChar < 32 )
     181           0 :             return false;
     182             :     }
     183           0 :     else if ( cEditMask == EDITMASK_NUMSPACE )
     184             :     {
     185           0 :         if ( !CharClass::isNumericType( nType ) && ( cChar != ' ' ) )
     186           0 :             return false;
     187             :     }
     188             :     else
     189           0 :         return false;
     190             : 
     191           0 :     return true;
     192             : }
     193             : 
     194           0 : static sal_Unicode ImplPatternChar( sal_Unicode cChar, sal_Char cEditMask )
     195             : {
     196           0 :     if ( ImplIsPatternChar( cChar, cEditMask ) )
     197             :     {
     198           0 :         if ( (cEditMask == EDITMASK_UPPERALPHA) ||
     199           0 :              (cEditMask == EDITMASK_UPPERALPHANUM) ||
     200             :              ( cEditMask == EDITMASK_UPPERALLCHAR ) )
     201             :         {
     202           0 :             cChar = ImplGetCharClass()->toUpper(OUString(cChar), 0, 1,
     203           0 :                     Application::GetSettings().GetLanguageTag().getLocale())[0];
     204             :         }
     205           0 :         return cChar;
     206             :     }
     207             :     else
     208           0 :         return 0;
     209             : }
     210             : 
     211           0 : static bool ImplCommaPointCharEqual( sal_Unicode c1, sal_Unicode c2 )
     212             : {
     213           0 :     if ( c1 == c2 )
     214           0 :         return true;
     215           0 :     else if ( ((c1 == '.') || (c1 == ',')) &&
     216           0 :               ((c2 == '.') || (c2 == ',')) )
     217           0 :         return true;
     218             :     else
     219           0 :         return false;
     220             : }
     221             : 
     222           0 : static OUString ImplPatternReformat( const OUString& rStr,
     223             :                                      const OString& rEditMask,
     224             :                                      const OUString& rLiteralMask,
     225             :                                      sal_uInt16 nFormatFlags )
     226             : {
     227           0 :     if (rEditMask.isEmpty())
     228           0 :         return rStr;
     229             : 
     230           0 :     OUString    aStr    = rStr;
     231           0 :     OUStringBuffer    aOutStr = OUString(rLiteralMask);
     232             :     sal_Unicode cTempChar;
     233             :     sal_Unicode cChar;
     234             :     sal_Unicode cLiteral;
     235             :     sal_Char    cMask;
     236           0 :     sal_Int32   nStrIndex = 0;
     237           0 :     sal_Int32   i = 0;
     238             :     sal_Int32   n;
     239             : 
     240           0 :     while ( i < rEditMask.getLength() )
     241             :     {
     242           0 :         if ( nStrIndex >= aStr.getLength() )
     243           0 :             break;
     244             : 
     245           0 :         cChar = aStr[nStrIndex];
     246           0 :         cLiteral = rLiteralMask[i];
     247           0 :         cMask = rEditMask[i];
     248             : 
     249             :         // current position is a literal
     250           0 :         if ( cMask == EDITMASK_LITERAL )
     251             :         {
     252             :             // if it is a literal copy otherwise ignore because it might be the next valid
     253             :             // character of the string
     254           0 :             if ( ImplCommaPointCharEqual( cChar, cLiteral ) )
     255           0 :                 nStrIndex++;
     256             :             else
     257             :             {
     258             :                 // Otherwise we check if it is a invalid character. This is the case if it does not
     259             :                 // fit in the pattern of the next non-literal character.
     260           0 :                 n = i+1;
     261           0 :                 while ( n < rEditMask.getLength() )
     262             :                 {
     263           0 :                     if ( rEditMask[n] != EDITMASK_LITERAL )
     264             :                     {
     265           0 :                         if ( !ImplIsPatternChar( cChar, rEditMask[n] ) )
     266           0 :                             nStrIndex++;
     267           0 :                         break;
     268             :                     }
     269             : 
     270           0 :                     n++;
     271             :                 }
     272             :             }
     273             :         }
     274             :         else
     275             :         {
     276             :             // valid character at this position
     277           0 :             cTempChar = ImplPatternChar( cChar, cMask );
     278           0 :             if ( cTempChar )
     279             :             {
     280             :                 // use this character
     281           0 :                 aOutStr[i] = cTempChar;
     282           0 :                 nStrIndex++;
     283             :             }
     284             :             else
     285             :             {
     286             :                 // copy if it is a literal character
     287           0 :                 if ( cLiteral == cChar )
     288           0 :                     nStrIndex++;
     289             :                 else
     290             :                 {
     291             :                     // If the invalid character might be the next literal character then we jump
     292             :                     // ahead to it, otherwise we ignore it. Do only if empty literals are allowed.
     293           0 :                     if ( nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS )
     294             :                     {
     295           0 :                         n = i;
     296           0 :                         while ( n < rEditMask.getLength() )
     297             :                         {
     298           0 :                             if ( rEditMask[n] == EDITMASK_LITERAL )
     299             :                             {
     300           0 :                                 if ( ImplCommaPointCharEqual( cChar, rLiteralMask[n] ) )
     301           0 :                                     i = n+1;
     302             : 
     303           0 :                                 break;
     304             :                             }
     305             : 
     306           0 :                             n++;
     307             :                         }
     308             :                     }
     309             : 
     310           0 :                     nStrIndex++;
     311           0 :                     continue;
     312             :                 }
     313             :             }
     314             :         }
     315             : 
     316           0 :         i++;
     317             :     }
     318             : 
     319           0 :     return aOutStr.makeStringAndClear();
     320             : }
     321             : 
     322           0 : static void ImplPatternMaxPos( const OUString& rStr, const OString& rEditMask,
     323             :                                sal_uInt16 nFormatFlags, bool bSameMask,
     324             :                                sal_Int32 nCursorPos, sal_Int32& rPos )
     325             : {
     326             : 
     327             :     // last position must not be longer than the contained string
     328           0 :     sal_Int32 nMaxPos = rStr.getLength();
     329             : 
     330             :     // if non empty literals are allowed ignore blanks at the end as well
     331           0 :     if ( bSameMask && !(nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS) )
     332             :     {
     333           0 :         while ( nMaxPos )
     334             :         {
     335           0 :             if ( (rEditMask[nMaxPos-1] != EDITMASK_LITERAL) &&
     336           0 :                  (rStr[nMaxPos-1] != ' ') )
     337           0 :                 break;
     338           0 :             nMaxPos--;
     339             :         }
     340             : 
     341             :         // if we are in front of a literal, continue search until first character after the literal
     342           0 :         sal_Int32 nTempPos = nMaxPos;
     343           0 :         while ( nTempPos < rEditMask.getLength() )
     344             :         {
     345           0 :             if ( rEditMask[nTempPos] != EDITMASK_LITERAL )
     346             :             {
     347           0 :                 nMaxPos = nTempPos;
     348           0 :                 break;
     349             :             }
     350           0 :             nTempPos++;
     351             :         }
     352             :     }
     353             : 
     354           0 :     if ( rPos > nMaxPos )
     355           0 :         rPos = nMaxPos;
     356             : 
     357             :     // character should not move left
     358           0 :     if ( rPos < nCursorPos )
     359           0 :         rPos = nCursorPos;
     360           0 : }
     361             : 
     362           0 : static void ImplPatternProcessStrictModify( Edit* pEdit,
     363             :                                             const OString& rEditMask,
     364             :                                             const OUString& rLiteralMask,
     365             :                                             sal_uInt16 nFormatFlags, bool bSameMask )
     366             : {
     367           0 :     OUString aText = pEdit->GetText();
     368             : 
     369             :     // remove leading blanks
     370           0 :     if ( bSameMask && !(nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS) )
     371             :     {
     372           0 :         sal_Int32 i = 0;
     373           0 :         sal_Int32 nMaxLen = aText.getLength();
     374           0 :         while ( i < nMaxLen )
     375             :         {
     376           0 :             if ( (rEditMask[i] != EDITMASK_LITERAL) &&
     377           0 :                  (aText[i] != ' ') )
     378           0 :                 break;
     379             : 
     380           0 :             i++;
     381             :         }
     382             :         // keep all literal characters
     383           0 :         while ( i && (rEditMask[i] == EDITMASK_LITERAL) )
     384           0 :             i--;
     385           0 :         aText = aText.copy( i );
     386             :     }
     387             : 
     388           0 :     OUString aNewText = ImplPatternReformat( aText, rEditMask, rLiteralMask, nFormatFlags );
     389           0 :     if ( aNewText != aText )
     390             :     {
     391             :         // adjust selection such that it remains at the end if it was there before
     392           0 :         Selection aSel = pEdit->GetSelection();
     393           0 :         sal_Int64 nMaxSel = std::max( aSel.Min(), aSel.Max() );
     394           0 :         if ( nMaxSel >= aText.getLength() )
     395             :         {
     396           0 :             sal_Int32 nMaxPos = aNewText.getLength();
     397           0 :             ImplPatternMaxPos( aNewText, rEditMask, nFormatFlags, bSameMask, nMaxSel, nMaxPos );
     398           0 :             if ( aSel.Min() == aSel.Max() )
     399             :             {
     400           0 :                 aSel.Min() = nMaxPos;
     401           0 :                 aSel.Max() = aSel.Min();
     402             :             }
     403           0 :             else if ( aSel.Min() > aSel.Max() )
     404           0 :                 aSel.Min() = nMaxPos;
     405             :             else
     406           0 :                 aSel.Max() = nMaxPos;
     407             :         }
     408           0 :         pEdit->SetText( aNewText, aSel );
     409           0 :     }
     410           0 : }
     411             : 
     412           0 : static sal_Int32 ImplPatternLeftPos(const OString& rEditMask, sal_Int32 nCursorPos)
     413             : {
     414             :     // search non-literal predecessor
     415           0 :     sal_Int32 nNewPos = nCursorPos;
     416           0 :     sal_Int32 nTempPos = nNewPos;
     417           0 :     while ( nTempPos )
     418             :     {
     419           0 :         if ( rEditMask[nTempPos-1] != EDITMASK_LITERAL )
     420             :         {
     421           0 :             nNewPos = nTempPos-1;
     422           0 :             break;
     423             :         }
     424           0 :         nTempPos--;
     425             :     }
     426           0 :     return nNewPos;
     427             : }
     428             : 
     429           0 : static sal_Int32 ImplPatternRightPos( const OUString& rStr, const OString& rEditMask,
     430             :                                        sal_uInt16 nFormatFlags, bool bSameMask,
     431             :                                        sal_Int32 nCursorPos )
     432             : {
     433             :     // search non-literal successor
     434           0 :     sal_Int32 nNewPos = nCursorPos;
     435           0 :     sal_Int32 nTempPos = nNewPos;
     436           0 :     while ( nTempPos < rEditMask.getLength() )
     437             :     {
     438           0 :         if ( rEditMask[nTempPos+1] != EDITMASK_LITERAL )
     439             :         {
     440           0 :             nNewPos = nTempPos+1;
     441           0 :             break;
     442             :         }
     443           0 :         nTempPos++;
     444             :     }
     445           0 :     ImplPatternMaxPos( rStr, rEditMask, nFormatFlags, bSameMask, nCursorPos, nNewPos );
     446           0 :     return nNewPos;
     447             : }
     448             : 
     449           0 : static bool ImplPatternProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
     450             :                                         const OString& rEditMask,
     451             :                                         const OUString& rLiteralMask,
     452             :                                         bool bStrictFormat,
     453             :                                         sal_uInt16 nFormatFlags,
     454             :                                         bool bSameMask,
     455             :                                         bool& rbInKeyInput )
     456             : {
     457           0 :     if ( rEditMask.isEmpty() || !bStrictFormat )
     458           0 :         return false;
     459             : 
     460           0 :     Selection   aOldSel     = pEdit->GetSelection();
     461           0 :     KeyCode     aCode       = rKEvt.GetKeyCode();
     462           0 :     sal_Unicode cChar       = rKEvt.GetCharCode();
     463           0 :     sal_uInt16      nKeyCode    = aCode.GetCode();
     464           0 :     bool        bShift      = aCode.IsShift();
     465           0 :     sal_Int32  nCursorPos = static_cast<sal_Int32>(aOldSel.Max());
     466             :     sal_Int32  nNewPos;
     467             :     sal_Int32  nTempPos;
     468             : 
     469           0 :     if ( nKeyCode && !aCode.IsMod1() && !aCode.IsMod2() )
     470             :     {
     471           0 :         if ( nKeyCode == KEY_LEFT )
     472             :         {
     473           0 :             Selection aSel( ImplPatternLeftPos( rEditMask, nCursorPos ) );
     474           0 :             if ( bShift )
     475           0 :                 aSel.Min() = aOldSel.Min();
     476           0 :             pEdit->SetSelection( aSel );
     477           0 :             return true;
     478             :         }
     479           0 :         else if ( nKeyCode == KEY_RIGHT )
     480             :         {
     481             :             // Use the start of selection as minimum; even a small position is allowed in case that
     482             :             // all was selected by the focus
     483           0 :             Selection aSel( aOldSel );
     484           0 :             aSel.Justify();
     485           0 :             nCursorPos = aSel.Min();
     486           0 :             aSel.Max() = ImplPatternRightPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nCursorPos );
     487           0 :             if ( bShift )
     488           0 :                 aSel.Min() = aOldSel.Min();
     489             :             else
     490           0 :                 aSel.Min() = aSel.Max();
     491           0 :             pEdit->SetSelection( aSel );
     492           0 :             return true;
     493             :         }
     494           0 :         else if ( nKeyCode == KEY_HOME )
     495             :         {
     496             :             // Home is the position of the first non-literal character
     497           0 :             nNewPos = 0;
     498           0 :             while ( (nNewPos < rEditMask.getLength()) &&
     499           0 :                     (rEditMask[nNewPos] == EDITMASK_LITERAL) )
     500           0 :                 nNewPos++;
     501             : 
     502             :             // Home should not move to the right
     503           0 :             if ( nCursorPos < nNewPos )
     504           0 :                 nNewPos = nCursorPos;
     505           0 :             Selection aSel( nNewPos );
     506           0 :             if ( bShift )
     507           0 :                 aSel.Min() = aOldSel.Min();
     508           0 :             pEdit->SetSelection( aSel );
     509           0 :             return true;
     510             :         }
     511           0 :         else if ( nKeyCode == KEY_END )
     512             :         {
     513             :             // End is position of last non-literal character
     514           0 :             nNewPos = rEditMask.getLength();
     515           0 :             while ( nNewPos &&
     516           0 :                     (rEditMask[nNewPos-1] == EDITMASK_LITERAL) )
     517           0 :                 nNewPos--;
     518             :             // Use the start of selection as minimum; even a small position is allowed in case that
     519             :             // all was selected by the focus
     520           0 :             Selection aSel( aOldSel );
     521           0 :             aSel.Justify();
     522           0 :             nCursorPos = static_cast<sal_Int32>(aSel.Min());
     523           0 :             ImplPatternMaxPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nCursorPos, nNewPos );
     524           0 :             aSel.Max() = nNewPos;
     525           0 :             if ( bShift )
     526           0 :                 aSel.Min() = aOldSel.Min();
     527             :             else
     528           0 :                 aSel.Min() = aSel.Max();
     529           0 :             pEdit->SetSelection( aSel );
     530           0 :             return true;
     531             :         }
     532           0 :         else if ( (nKeyCode == KEY_BACKSPACE) || (nKeyCode == KEY_DELETE) )
     533             :         {
     534           0 :             OUString          aOldStr( pEdit->GetText() );
     535           0 :             OUStringBuffer    aStr( aOldStr );
     536           0 :             Selection   aSel = aOldSel;
     537             : 
     538           0 :             aSel.Justify();
     539           0 :             nNewPos = static_cast<sal_Int32>(aSel.Min());
     540             : 
     541             :              // if selection then delete it
     542           0 :             if ( aSel.Len() )
     543             :             {
     544           0 :                 if ( bSameMask )
     545           0 :                     aStr.remove( static_cast<sal_Int32>(aSel.Min()), static_cast<sal_Int32>(aSel.Len()) );
     546             :                 else
     547             :                 {
     548           0 :                     OUString aRep = rLiteralMask.copy( static_cast<sal_Int32>(aSel.Min()), static_cast<sal_Int32>(aSel.Len()) );
     549           0 :                     aStr.remove( aSel.Min(), aRep.getLength() );
     550           0 :                     aStr.insert( aSel.Min(), aRep );
     551             :                 }
     552             :             }
     553             :             else
     554             :             {
     555           0 :                 if ( nKeyCode == KEY_BACKSPACE )
     556             :                 {
     557           0 :                     nTempPos = nNewPos;
     558           0 :                     nNewPos = ImplPatternLeftPos( rEditMask, nTempPos );
     559             :                 }
     560             :                 else
     561           0 :                     nTempPos = ImplPatternRightPos( aStr.toString(), rEditMask, nFormatFlags, bSameMask, nNewPos );
     562             : 
     563           0 :                 if ( nNewPos != nTempPos )
     564             :                 {
     565           0 :                     if ( bSameMask )
     566             :                     {
     567           0 :                         if ( rEditMask[nNewPos] != EDITMASK_LITERAL )
     568           0 :                             aStr.remove( nNewPos, 1 );
     569             :                     }
     570             :                     else
     571             :                     {
     572           0 :                         aStr[nNewPos] = rLiteralMask[nNewPos];
     573             :                     }
     574             :                 }
     575             :             }
     576             : 
     577           0 :             if ( aOldStr != aStr.toString() )
     578             :             {
     579           0 :                 if ( bSameMask )
     580           0 :                     aStr = ImplPatternReformat( aStr.toString(), rEditMask, rLiteralMask, nFormatFlags );
     581           0 :                 rbInKeyInput = true;
     582           0 :                 pEdit->SetText( aStr.toString(), Selection( nNewPos ) );
     583           0 :                 pEdit->SetModifyFlag();
     584           0 :                 pEdit->Modify();
     585           0 :                 rbInKeyInput = false;
     586             :             }
     587             :             else
     588           0 :                 pEdit->SetSelection( Selection( nNewPos ) );
     589             : 
     590           0 :             return true;
     591             :         }
     592           0 :         else if ( nKeyCode == KEY_INSERT )
     593             :         {
     594             :             // you can only set InsertModus for a PatternField if the
     595             :             // mask is equal at all input positions
     596           0 :             if ( !bSameMask )
     597             :             {
     598           0 :                 return true;
     599             :             }
     600             :         }
     601             :     }
     602             : 
     603           0 :     if ( rKEvt.GetKeyCode().IsMod2() || (cChar < 32) || (cChar == 127) )
     604           0 :         return false;
     605             : 
     606           0 :     Selection aSel = aOldSel;
     607           0 :     aSel.Justify();
     608           0 :     nNewPos = aSel.Min();
     609             : 
     610           0 :     if ( nNewPos < rEditMask.getLength() )
     611             :     {
     612           0 :         sal_Unicode cPattChar = ImplPatternChar( cChar, rEditMask[nNewPos] );
     613           0 :         if ( cPattChar )
     614           0 :             cChar = cPattChar;
     615             :         else
     616             :         {
     617             :             // If no valid character, check if the user wanted to jump to next literal. We do this
     618             :             // only if we're after a character, so that literals that were skipped automatically
     619             :             // do not influence the position anymore.
     620           0 :             if ( nNewPos &&
     621           0 :                  (rEditMask[nNewPos-1] != EDITMASK_LITERAL) &&
     622           0 :                  !aSel.Len() )
     623             :             {
     624             :                 // search for next character not being a literal
     625           0 :                 nTempPos = nNewPos;
     626           0 :                 while ( nTempPos < rEditMask.getLength() )
     627             :                 {
     628           0 :                     if ( rEditMask[nTempPos] == EDITMASK_LITERAL )
     629             :                     {
     630             :                         // only valid if no literal present
     631           0 :                         if ( (rEditMask[nTempPos+1] != EDITMASK_LITERAL ) &&
     632           0 :                              ImplCommaPointCharEqual( cChar, rLiteralMask[nTempPos] ) )
     633             :                         {
     634           0 :                             nTempPos++;
     635           0 :                             ImplPatternMaxPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nNewPos, nTempPos );
     636           0 :                             if ( nTempPos > nNewPos )
     637             :                             {
     638           0 :                                 pEdit->SetSelection( Selection( nTempPos ) );
     639           0 :                                 return true;
     640             :                             }
     641             :                         }
     642           0 :                         break;
     643             :                     }
     644           0 :                     nTempPos++;
     645             :                 }
     646             :             }
     647             : 
     648           0 :             cChar = 0;
     649             :         }
     650             :     }
     651             :     else
     652           0 :         cChar = 0;
     653           0 :     if ( cChar )
     654             :     {
     655           0 :         OUStringBuffer  aStr = pEdit->GetText();
     656           0 :         bool        bError = false;
     657           0 :         if ( bSameMask && pEdit->IsInsertMode() )
     658             :         {
     659             :             // crop spaces and literals at the end until current position
     660           0 :             sal_Int32 n = aStr.getLength();
     661           0 :             while ( n && (n > nNewPos) )
     662             :             {
     663           0 :                 if ( (aStr[n-1] != ' ') &&
     664           0 :                      ((n > rEditMask.getLength()) || (rEditMask[n-1] != EDITMASK_LITERAL)) )
     665           0 :                     break;
     666             : 
     667           0 :                 n--;
     668             :             }
     669           0 :             aStr.truncate( n );
     670             : 
     671           0 :             if ( aSel.Len() )
     672           0 :                 aStr.remove( aSel.Min(), aSel.Len() );
     673             : 
     674           0 :             if ( aStr.getLength() < rEditMask.getLength() )
     675             :             {
     676             :                 // possibly extend string until cursor position
     677           0 :                 if ( aStr.getLength() < nNewPos )
     678           0 :                     aStr.append( rLiteralMask.copy( aStr.getLength(), nNewPos-aStr.getLength() ));
     679           0 :                 if ( nNewPos < aStr.getLength() )
     680           0 :                     aStr.insert( cChar, nNewPos );
     681           0 :                 else if ( nNewPos < rEditMask.getLength() )
     682           0 :                     aStr.append(cChar);
     683           0 :                 aStr = ImplPatternReformat( aStr.toString(), rEditMask, rLiteralMask, nFormatFlags );
     684             :             }
     685             :             else
     686           0 :                 bError = true;
     687             :         }
     688             :         else
     689             :         {
     690           0 :             if ( aSel.Len() )
     691             :             {
     692             :                 // delete selection
     693           0 :                 OUString aRep = rLiteralMask.copy( aSel.Min(), aSel.Len() );
     694           0 :                 aStr.remove( aSel.Min(), aRep.getLength() );
     695           0 :                 aStr.insert( aSel.Min(), aRep );
     696             :             }
     697             : 
     698           0 :             if ( nNewPos < aStr.getLength() )
     699           0 :                 aStr[nNewPos] = cChar;
     700           0 :             else if ( nNewPos < rEditMask.getLength() )
     701           0 :                 aStr.append(cChar);
     702             :         }
     703             : 
     704           0 :         if ( !bError )
     705             :         {
     706           0 :             rbInKeyInput = true;
     707           0 :             Selection aNewSel( ImplPatternRightPos( aStr.toString(), rEditMask, nFormatFlags, bSameMask, nNewPos ) );
     708           0 :             pEdit->SetText( aStr.toString(), aNewSel );
     709           0 :             pEdit->SetModifyFlag();
     710           0 :             pEdit->Modify();
     711           0 :             rbInKeyInput = false;
     712           0 :         }
     713             :     }
     714             : 
     715           0 :     return true;
     716             : }
     717             : 
     718           0 : void PatternFormatter::ImplSetMask(const OString& rEditMask, const OUString& rLiteralMask)
     719             : {
     720           0 :     m_aEditMask     = rEditMask;
     721           0 :     maLiteralMask   = rLiteralMask;
     722           0 :     mbSameMask      = true;
     723             : 
     724           0 :     if ( m_aEditMask.getLength() != maLiteralMask.getLength() )
     725             :     {
     726           0 :         OUStringBuffer aBuf(maLiteralMask);
     727           0 :         if (m_aEditMask.getLength() < aBuf.getLength())
     728           0 :             aBuf.remove(m_aEditMask.getLength(), aBuf.getLength() - m_aEditMask.getLength());
     729             :         else
     730           0 :             comphelper::string::padToLength(aBuf, m_aEditMask.getLength(), ' ');
     731           0 :         maLiteralMask = aBuf.makeStringAndClear();
     732             :     }
     733             : 
     734             :     // Strict mode allows only the input mode if only equal characters are allowed as mask and if
     735             :     // only spaces are specified which are not allowed by the mask
     736           0 :     sal_Int32   i = 0;
     737           0 :     sal_Char    c = 0;
     738           0 :     while ( i < rEditMask.getLength() )
     739             :     {
     740           0 :         sal_Char cTemp = rEditMask[i];
     741           0 :         if ( cTemp != EDITMASK_LITERAL )
     742             :         {
     743           0 :             if ( (cTemp == EDITMASK_ALLCHAR) ||
     744           0 :                  (cTemp == EDITMASK_UPPERALLCHAR) ||
     745             :                  (cTemp == EDITMASK_NUMSPACE) )
     746             :             {
     747           0 :                 mbSameMask = false;
     748           0 :                 break;
     749             :             }
     750           0 :             if ( i < rLiteralMask.getLength() )
     751             :             {
     752           0 :                 if ( rLiteralMask[i] != ' ' )
     753             :                 {
     754           0 :                     mbSameMask = false;
     755           0 :                     break;
     756             :                 }
     757             :             }
     758           0 :             if ( !c )
     759           0 :                 c = cTemp;
     760           0 :             if ( cTemp != c )
     761             :             {
     762           0 :                 mbSameMask = false;
     763           0 :                 break;
     764             :             }
     765             :         }
     766           0 :         i++;
     767             :     }
     768           0 : }
     769             : 
     770           0 : PatternFormatter::PatternFormatter()
     771             : {
     772           0 :     mnFormatFlags       = 0;
     773           0 :     mbSameMask          = true;
     774           0 :     mbInPattKeyInput    = false;
     775           0 : }
     776             : 
     777           0 : PatternFormatter::~PatternFormatter()
     778             : {
     779           0 : }
     780             : 
     781           0 : void PatternFormatter::SetMask( const OString& rEditMask,
     782             :                                 const OUString& rLiteralMask )
     783             : {
     784           0 :     ImplSetMask( rEditMask, rLiteralMask );
     785           0 :     ReformatAll();
     786           0 : }
     787             : 
     788           0 : void PatternFormatter::SetString( const OUString& rStr )
     789             : {
     790           0 :     maFieldString = rStr;
     791           0 :     if ( GetField() )
     792             :     {
     793           0 :         GetField()->SetText( rStr );
     794           0 :         MarkToBeReformatted( false );
     795             :     }
     796           0 : }
     797             : 
     798           0 : OUString PatternFormatter::GetString() const
     799             : {
     800           0 :     if ( !GetField() )
     801           0 :         return OUString();
     802             :     else
     803           0 :         return ImplPatternReformat( GetField()->GetText(), m_aEditMask, maLiteralMask, mnFormatFlags );
     804             : }
     805             : 
     806           0 : void PatternFormatter::Reformat()
     807             : {
     808           0 :     if ( GetField() )
     809             :     {
     810           0 :         ImplSetText( ImplPatternReformat( GetField()->GetText(), m_aEditMask, maLiteralMask, mnFormatFlags ) );
     811           0 :         if ( !mbSameMask && IsStrictFormat() && !GetField()->IsReadOnly() )
     812           0 :             GetField()->SetInsertMode( false );
     813             :     }
     814           0 : }
     815             : 
     816           0 : PatternField::PatternField( Window* pParent, WinBits nWinStyle ) :
     817           0 :     SpinField( pParent, nWinStyle )
     818             : {
     819           0 :     SetField( this );
     820           0 :     Reformat();
     821           0 : }
     822             : 
     823           0 : PatternField::~PatternField()
     824             : {
     825           0 : }
     826             : 
     827           0 : bool PatternField::PreNotify( NotifyEvent& rNEvt )
     828             : {
     829           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
     830             :     {
     831           0 :         if ( ImplPatternProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetEditMask(), GetLiteralMask(),
     832           0 :                                          IsStrictFormat(), GetFormatFlags(),
     833           0 :                                          ImplIsSameMask(), ImplGetInPattKeyInput() ) )
     834           0 :             return true;
     835             :     }
     836             : 
     837           0 :     return SpinField::PreNotify( rNEvt );
     838             : }
     839             : 
     840           0 : bool PatternField::Notify( NotifyEvent& rNEvt )
     841             : {
     842           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
     843           0 :         MarkToBeReformatted( false );
     844           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
     845             :     {
     846           0 :         if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
     847           0 :             Reformat();
     848             :     }
     849             : 
     850           0 :     return SpinField::Notify( rNEvt );
     851             : }
     852             : 
     853           0 : void PatternField::Modify()
     854             : {
     855           0 :     if ( !ImplGetInPattKeyInput() )
     856             :     {
     857           0 :         if ( IsStrictFormat() )
     858           0 :             ImplPatternProcessStrictModify( GetField(), GetEditMask(), GetLiteralMask(), GetFormatFlags(), ImplIsSameMask() );
     859             :         else
     860           0 :             MarkToBeReformatted( true );
     861             :     }
     862             : 
     863           0 :     SpinField::Modify();
     864           0 : }
     865             : 
     866           0 : PatternBox::PatternBox( Window* pParent, WinBits nWinStyle ) :
     867           0 :     ComboBox( pParent, nWinStyle )
     868             : {
     869           0 :     SetField( this );
     870           0 :     Reformat();
     871           0 : }
     872             : 
     873           0 : PatternBox::~PatternBox()
     874             : {
     875           0 : }
     876             : 
     877           0 : bool PatternBox::PreNotify( NotifyEvent& rNEvt )
     878             : {
     879           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
     880             :     {
     881           0 :         if ( ImplPatternProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetEditMask(), GetLiteralMask(),
     882           0 :                                          IsStrictFormat(), GetFormatFlags(),
     883           0 :                                          ImplIsSameMask(), ImplGetInPattKeyInput() ) )
     884           0 :             return true;
     885             :     }
     886             : 
     887           0 :     return ComboBox::PreNotify( rNEvt );
     888             : }
     889             : 
     890           0 : bool PatternBox::Notify( NotifyEvent& rNEvt )
     891             : {
     892           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
     893           0 :         MarkToBeReformatted( false );
     894           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
     895             :     {
     896           0 :         if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
     897           0 :             Reformat();
     898             :     }
     899             : 
     900           0 :     return ComboBox::Notify( rNEvt );
     901             : }
     902             : 
     903           0 : void PatternBox::Modify()
     904             : {
     905           0 :     if ( !ImplGetInPattKeyInput() )
     906             :     {
     907           0 :         if ( IsStrictFormat() )
     908           0 :             ImplPatternProcessStrictModify( GetField(), GetEditMask(), GetLiteralMask(), GetFormatFlags(), ImplIsSameMask() );
     909             :         else
     910           0 :             MarkToBeReformatted( true );
     911             :     }
     912             : 
     913           0 :     ComboBox::Modify();
     914           0 : }
     915             : 
     916           0 : void PatternBox::ReformatAll()
     917             : {
     918           0 :     OUString aStr;
     919           0 :     SetUpdateMode( false );
     920           0 :     sal_uInt16 nEntryCount = GetEntryCount();
     921           0 :     for ( sal_uInt16 i=0; i < nEntryCount; i++ )
     922             :     {
     923           0 :         aStr = ImplPatternReformat( GetEntry( i ), GetEditMask(), GetLiteralMask(), GetFormatFlags() );
     924           0 :         RemoveEntryAt(i);
     925           0 :         InsertEntry( aStr, i );
     926             :     }
     927           0 :     PatternFormatter::Reformat();
     928           0 :     SetUpdateMode( true );
     929           0 : }
     930             : 
     931           0 : static ExtDateFieldFormat ImplGetExtFormat( DateFormat eOld )
     932             : {
     933           0 :     switch( eOld )
     934             :     {
     935           0 :         case DMY:   return XTDATEF_SHORT_DDMMYY;
     936           0 :         case MDY:   return XTDATEF_SHORT_MMDDYY;
     937           0 :         default:    return XTDATEF_SHORT_YYMMDD;
     938             :     }
     939             : }
     940             : 
     941           0 : static sal_uInt16 ImplCutNumberFromString( OUString& rStr )
     942             : {
     943           0 :     sal_Int32 i1 = 0;
     944           0 :     while (i1 != rStr.getLength() && !(rStr[i1] >= '0' && rStr[i1] <= '9')) {
     945           0 :         ++i1;
     946             :     }
     947           0 :     sal_Int32 i2 = i1;
     948           0 :     while (i2 != rStr.getLength() && rStr[i2] >= '0' && rStr[i2] <= '9') {
     949           0 :         ++i2;
     950             :     }
     951           0 :     sal_Int32 nValue = rStr.copy(i1, i2-i1).toInt32();
     952           0 :     rStr = rStr.copy(std::min(i2+1, rStr.getLength()));
     953           0 :     return nValue;
     954             : }
     955             : 
     956           0 : static bool ImplCutMonthName( OUString& rStr, const OUString& _rLookupMonthName )
     957             : {
     958           0 :     sal_Int32 index = 0;
     959           0 :     rStr = rStr.replaceFirst(_rLookupMonthName, OUString(), &index);
     960           0 :     return index >= 0;
     961             : }
     962             : 
     963           0 : static sal_uInt16 ImplCutMonthFromString( OUString& rStr, const CalendarWrapper& rCalendarWrapper )
     964             : {
     965             :     // search for a month' name
     966           0 :     for ( sal_uInt16 i=1; i <= 12; i++ )
     967             :     {
     968           0 :         OUString aMonthName = rCalendarWrapper.getMonths()[i-1].FullName;
     969             :         // long month name?
     970           0 :         if ( ImplCutMonthName( rStr, aMonthName ) )
     971           0 :             return i;
     972             : 
     973             :         // short month name?
     974           0 :         OUString aAbbrevMonthName = rCalendarWrapper.getMonths()[i-1].AbbrevName;
     975           0 :         if ( ImplCutMonthName( rStr, aAbbrevMonthName ) )
     976           0 :             return i;
     977           0 :     }
     978             : 
     979           0 :     return ImplCutNumberFromString( rStr );
     980             : }
     981             : 
     982           0 : static OUString ImplGetDateSep( const LocaleDataWrapper& rLocaleDataWrapper, ExtDateFieldFormat eFormat )
     983             : {
     984           0 :     if ( ( eFormat == XTDATEF_SHORT_YYMMDD_DIN5008 ) || ( eFormat == XTDATEF_SHORT_YYYYMMDD_DIN5008 ) )
     985           0 :         return OUString("-");
     986             :     else
     987           0 :         return rLocaleDataWrapper.getDateSep();
     988             : }
     989             : 
     990           0 : static bool ImplDateProcessKeyInput( Edit*, const KeyEvent& rKEvt, ExtDateFieldFormat eFormat,
     991             :                                      const LocaleDataWrapper& rLocaleDataWrapper  )
     992             : {
     993           0 :     sal_Unicode cChar = rKEvt.GetCharCode();
     994           0 :     sal_uInt16 nGroup = rKEvt.GetKeyCode().GetGroup();
     995           0 :     if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
     996           0 :          (nGroup == KEYGROUP_MISC)||
     997           0 :          ((cChar >= '0') && (cChar <= '9')) ||
     998           0 :          (cChar == ImplGetDateSep( rLocaleDataWrapper, eFormat )[0]) )
     999           0 :         return false;
    1000             :     else
    1001           0 :         return true;
    1002             : }
    1003             : 
    1004           0 : static bool ImplDateGetValue( const OUString& rStr, Date& rDate, ExtDateFieldFormat eDateFormat,
    1005             :                               const LocaleDataWrapper& rLocaleDataWrapper, const CalendarWrapper& rCalendarWrapper,
    1006             :                               const AllSettings& )
    1007             : {
    1008           0 :     sal_uInt16 nDay = 0;
    1009           0 :     sal_uInt16 nMonth = 0;
    1010           0 :     sal_uInt16 nYear = 0;
    1011           0 :     bool bYear = true;
    1012           0 :     bool bError = false;
    1013           0 :     OUString aStr( rStr );
    1014             : 
    1015           0 :     if ( eDateFormat == XTDATEF_SYSTEM_LONG )
    1016             :     {
    1017           0 :         DateFormat eFormat = rLocaleDataWrapper.getLongDateFormat();
    1018           0 :         switch( eFormat )
    1019             :         {
    1020             :             case MDY:
    1021           0 :                 nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper );
    1022           0 :                 nDay = ImplCutNumberFromString( aStr );
    1023           0 :                 nYear  = ImplCutNumberFromString( aStr );
    1024           0 :                 break;
    1025             :             case DMY:
    1026           0 :                 nDay = ImplCutNumberFromString( aStr );
    1027           0 :                 nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper );
    1028           0 :                 nYear  = ImplCutNumberFromString( aStr );
    1029           0 :                 break;
    1030             :             case YMD:
    1031             :             default:
    1032           0 :                 nYear = ImplCutNumberFromString( aStr );
    1033           0 :                 nMonth = ImplCutMonthFromString( aStr, rCalendarWrapper );
    1034           0 :                 nDay  = ImplCutNumberFromString( aStr );
    1035           0 :                 break;
    1036             :         }
    1037             :     }
    1038             :     else
    1039             :     {
    1040             :         // Check if year is present:
    1041           0 :         OUString aDateSep = ImplGetDateSep( rLocaleDataWrapper, eDateFormat );
    1042           0 :         sal_Int32 nSepPos = aStr.indexOf( aDateSep );
    1043           0 :         if ( nSepPos < 0 )
    1044           0 :             return false;
    1045           0 :         nSepPos = aStr.indexOf( aDateSep, nSepPos+1 );
    1046           0 :         if ( ( nSepPos < 0 ) || ( nSepPos == (aStr.getLength()-1) ) )
    1047             :         {
    1048           0 :             bYear = false;
    1049           0 :             nYear = Date( Date::SYSTEM ).GetYear();
    1050             :         }
    1051             : 
    1052           0 :         const sal_Unicode* pBuf = aStr.getStr();
    1053           0 :         ImplSkipDelimiters( pBuf );
    1054             : 
    1055           0 :         switch ( eDateFormat )
    1056             :         {
    1057             :             case XTDATEF_SHORT_DDMMYY:
    1058             :             case XTDATEF_SHORT_DDMMYYYY:
    1059             :             {
    1060           0 :                 nDay = ImplGetNum( pBuf, bError );
    1061           0 :                 ImplSkipDelimiters( pBuf );
    1062           0 :                 nMonth = ImplGetNum( pBuf, bError );
    1063           0 :                 ImplSkipDelimiters( pBuf );
    1064           0 :                 if ( bYear )
    1065           0 :                     nYear = ImplGetNum( pBuf, bError );
    1066             :             }
    1067           0 :             break;
    1068             :             case XTDATEF_SHORT_MMDDYY:
    1069             :             case XTDATEF_SHORT_MMDDYYYY:
    1070             :             {
    1071           0 :                 nMonth = ImplGetNum( pBuf, bError );
    1072           0 :                 ImplSkipDelimiters( pBuf );
    1073           0 :                 nDay = ImplGetNum( pBuf, bError );
    1074           0 :                 ImplSkipDelimiters( pBuf );
    1075           0 :                 if ( bYear )
    1076           0 :                     nYear = ImplGetNum( pBuf, bError );
    1077             :             }
    1078           0 :             break;
    1079             :             case XTDATEF_SHORT_YYMMDD:
    1080             :             case XTDATEF_SHORT_YYYYMMDD:
    1081             :             case XTDATEF_SHORT_YYMMDD_DIN5008:
    1082             :             case XTDATEF_SHORT_YYYYMMDD_DIN5008:
    1083             :             {
    1084           0 :                 if ( bYear )
    1085           0 :                     nYear = ImplGetNum( pBuf, bError );
    1086           0 :                 ImplSkipDelimiters( pBuf );
    1087           0 :                 nMonth = ImplGetNum( pBuf, bError );
    1088           0 :                 ImplSkipDelimiters( pBuf );
    1089           0 :                 nDay = ImplGetNum( pBuf, bError );
    1090             :             }
    1091           0 :             break;
    1092             : 
    1093             :             default:
    1094             :             {
    1095             :                 OSL_FAIL( "DateFormat???" );
    1096             :             }
    1097           0 :         }
    1098             :     }
    1099             : 
    1100           0 :     if ( bError || !nDay || !nMonth )
    1101           0 :         return false;
    1102             : 
    1103           0 :     Date aNewDate( nDay, nMonth, nYear );
    1104           0 :     DateFormatter::ExpandCentury( aNewDate, utl::MiscCfg().GetYear2000() );
    1105           0 :     if ( aNewDate.IsValidDate() )
    1106             :     {
    1107           0 :         rDate = aNewDate;
    1108           0 :         return true;
    1109             :     }
    1110           0 :     return false;
    1111             : }
    1112             : 
    1113           0 : bool DateFormatter::ImplDateReformat( const OUString& rStr, OUString& rOutStr, const AllSettings& rSettings )
    1114             : {
    1115           0 :     Date aDate( 0, 0, 0 );
    1116           0 :     if ( !ImplDateGetValue( rStr, aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) )
    1117           0 :         return true;
    1118             : 
    1119           0 :     Date aTempDate = aDate;
    1120           0 :     if ( aTempDate > GetMax() )
    1121           0 :         aTempDate = GetMax();
    1122           0 :     else if ( aTempDate < GetMin() )
    1123           0 :         aTempDate = GetMin();
    1124             : 
    1125           0 :     if ( GetErrorHdl().IsSet() && (aDate != aTempDate) )
    1126             :     {
    1127           0 :         maCorrectedDate = aTempDate;
    1128           0 :         if( !GetErrorHdl().Call( this ) )
    1129             :         {
    1130           0 :             maCorrectedDate = Date( Date::SYSTEM );
    1131           0 :             return false;
    1132             :         }
    1133             :         else
    1134           0 :             maCorrectedDate = Date( Date::SYSTEM );
    1135             :     }
    1136             : 
    1137           0 :     rOutStr = ImplGetDateAsText( aTempDate, rSettings );
    1138             : 
    1139           0 :     return true;
    1140             : }
    1141             : 
    1142           0 : OUString DateFormatter::ImplGetDateAsText( const Date& rDate,
    1143             :                                            const AllSettings& ) const
    1144             : {
    1145           0 :     bool bShowCentury = false;
    1146           0 :     switch ( GetExtDateFormat() )
    1147             :     {
    1148             :         case XTDATEF_SYSTEM_SHORT_YYYY:
    1149             :         case XTDATEF_SYSTEM_LONG:
    1150             :         case XTDATEF_SHORT_DDMMYYYY:
    1151             :         case XTDATEF_SHORT_MMDDYYYY:
    1152             :         case XTDATEF_SHORT_YYYYMMDD:
    1153             :         case XTDATEF_SHORT_YYYYMMDD_DIN5008:
    1154             :         {
    1155           0 :             bShowCentury = true;
    1156             :         }
    1157           0 :         break;
    1158             :         default:
    1159             :         {
    1160           0 :             bShowCentury = false;
    1161             :         }
    1162             :     }
    1163             : 
    1164           0 :     if ( !bShowCentury )
    1165             :     {
    1166             :         // Check if I have to use force showing the century
    1167           0 :         sal_uInt16 nTwoDigitYearStart = utl::MiscCfg().GetYear2000();
    1168           0 :         sal_uInt16 nYear = rDate.GetYear();
    1169             : 
    1170             :         // If year is not in double digit range
    1171           0 :         if ( (nYear < nTwoDigitYearStart) || (nYear >= nTwoDigitYearStart+100) )
    1172           0 :             bShowCentury = true;
    1173             :     }
    1174             : 
    1175             :     sal_Unicode aBuf[128];
    1176           0 :     sal_Unicode* pBuf = aBuf;
    1177             : 
    1178           0 :     OUString aDateSep = ImplGetDateSep( ImplGetLocaleDataWrapper(), GetExtDateFormat( true ) );
    1179           0 :     sal_uInt16 nDay = rDate.GetDay();
    1180           0 :     sal_uInt16 nMonth = rDate.GetMonth();
    1181           0 :     sal_uInt16 nYear = rDate.GetYear();
    1182           0 :     sal_uInt16 nYearLen = bShowCentury ? 4 : 2;
    1183             : 
    1184           0 :     if ( !bShowCentury )
    1185           0 :         nYear %= 100;
    1186             : 
    1187           0 :     switch ( GetExtDateFormat( true ) )
    1188             :     {
    1189             :         case XTDATEF_SYSTEM_LONG:
    1190             :         {
    1191           0 :             return ImplGetLocaleDataWrapper().getLongDate( rDate, GetCalendarWrapper(), 1, false, 1, !bShowCentury );
    1192             :         }
    1193             :         case XTDATEF_SHORT_DDMMYY:
    1194             :         case XTDATEF_SHORT_DDMMYYYY:
    1195             :         {
    1196           0 :             pBuf = ImplAddNum( pBuf, nDay, 2 );
    1197           0 :             pBuf = ImplAddString( pBuf, aDateSep );
    1198           0 :             pBuf = ImplAddNum( pBuf, nMonth, 2 );
    1199           0 :             pBuf = ImplAddString( pBuf, aDateSep );
    1200           0 :             pBuf = ImplAddNum( pBuf, nYear, nYearLen );
    1201             :         }
    1202           0 :         break;
    1203             :         case XTDATEF_SHORT_MMDDYY:
    1204             :         case XTDATEF_SHORT_MMDDYYYY:
    1205             :         {
    1206           0 :             pBuf = ImplAddNum( pBuf, nMonth, 2 );
    1207           0 :             pBuf = ImplAddString( pBuf, aDateSep );
    1208           0 :             pBuf = ImplAddNum( pBuf, nDay, 2 );
    1209           0 :             pBuf = ImplAddString( pBuf, aDateSep );
    1210           0 :             pBuf = ImplAddNum( pBuf, nYear, nYearLen );
    1211             :         }
    1212           0 :         break;
    1213             :         case XTDATEF_SHORT_YYMMDD:
    1214             :         case XTDATEF_SHORT_YYYYMMDD:
    1215             :         case XTDATEF_SHORT_YYMMDD_DIN5008:
    1216             :         case XTDATEF_SHORT_YYYYMMDD_DIN5008:
    1217             :         {
    1218           0 :             pBuf = ImplAddNum( pBuf, nYear, nYearLen );
    1219           0 :             pBuf = ImplAddString( pBuf, aDateSep );
    1220           0 :             pBuf = ImplAddNum( pBuf, nMonth, 2 );
    1221           0 :             pBuf = ImplAddString( pBuf, aDateSep );
    1222           0 :             pBuf = ImplAddNum( pBuf, nDay, 2 );
    1223             :         }
    1224           0 :         break;
    1225             :         default:
    1226             :         {
    1227             :             OSL_FAIL( "DateFormat???" );
    1228             :         }
    1229             :     }
    1230             : 
    1231           0 :     return OUString(aBuf, pBuf-aBuf);
    1232             : }
    1233             : 
    1234           0 : static void ImplDateIncrementDay( Date& rDate, bool bUp )
    1235             : {
    1236           0 :     DateFormatter::ExpandCentury( rDate );
    1237             : 
    1238           0 :     if ( bUp )
    1239             :     {
    1240           0 :         if ( (rDate.GetDay() != 31) || (rDate.GetMonth() != 12) || (rDate.GetYear() != 9999) )
    1241           0 :             rDate++;
    1242             :     }
    1243             :     else
    1244             :     {
    1245           0 :         if ( (rDate.GetDay() != 1 ) || (rDate.GetMonth() != 1) || (rDate.GetYear() != 0) )
    1246           0 :             rDate--;
    1247             :     }
    1248           0 : }
    1249             : 
    1250           0 : static void ImplDateIncrementMonth( Date& rDate, bool bUp )
    1251             : {
    1252           0 :     DateFormatter::ExpandCentury( rDate );
    1253             : 
    1254           0 :     sal_uInt16 nMonth = rDate.GetMonth();
    1255           0 :     sal_uInt16 nYear = rDate.GetYear();
    1256           0 :     if ( bUp )
    1257             :     {
    1258           0 :         if ( (nMonth == 12) && (nYear < 9999) )
    1259             :         {
    1260           0 :             rDate.SetMonth( 1 );
    1261           0 :             rDate.SetYear( nYear + 1 );
    1262             :         }
    1263             :         else
    1264             :         {
    1265           0 :             if ( nMonth < 12 )
    1266           0 :                 rDate.SetMonth( nMonth + 1 );
    1267             :         }
    1268             :     }
    1269             :     else
    1270             :     {
    1271           0 :         if ( (nMonth == 1) && (nYear > 0) )
    1272             :         {
    1273           0 :             rDate.SetMonth( 12 );
    1274           0 :             rDate.SetYear( nYear - 1 );
    1275             :         }
    1276             :         else
    1277             :         {
    1278           0 :             if ( nMonth > 1 )
    1279           0 :                 rDate.SetMonth( nMonth - 1 );
    1280             :         }
    1281             :     }
    1282             : 
    1283           0 :     sal_uInt16 nDaysInMonth = Date::GetDaysInMonth( rDate.GetMonth(), rDate.GetYear());
    1284           0 :     if ( rDate.GetDay() > nDaysInMonth )
    1285           0 :         rDate.SetDay( nDaysInMonth );
    1286           0 : }
    1287             : 
    1288           0 : static void ImplDateIncrementYear( Date& rDate, bool bUp )
    1289             : {
    1290           0 :     DateFormatter::ExpandCentury( rDate );
    1291             : 
    1292           0 :     sal_uInt16 nYear = rDate.GetYear();
    1293           0 :     sal_uInt16 nMonth = rDate.GetMonth();
    1294           0 :     if ( bUp )
    1295             :     {
    1296           0 :         if ( nYear < 9999 )
    1297           0 :             rDate.SetYear( nYear + 1 );
    1298             :     }
    1299             :     else
    1300             :     {
    1301           0 :         if ( nYear > 0 )
    1302           0 :             rDate.SetYear( nYear - 1 );
    1303             :     }
    1304           0 :     if (nMonth == 2)
    1305             :     {
    1306             :         // Handle February 29 from leap year to non-leap year.
    1307           0 :         sal_uInt16 nDay = rDate.GetDay();
    1308           0 :         if (nDay > 28)
    1309             :         {
    1310             :             // The check would not be necessary if it was guaranteed that the
    1311             :             // date was valid before and actually was a leap year,
    1312             :             // de-/incrementing a leap year with 29 always results in 28.
    1313           0 :             sal_uInt16 nDaysInMonth = Date::GetDaysInMonth( nMonth, rDate.GetYear());
    1314           0 :             if (nDay > nDaysInMonth)
    1315           0 :                 rDate.SetDay( nDaysInMonth);
    1316             :         }
    1317             :     }
    1318           0 : }
    1319             : 
    1320           0 : bool DateFormatter::ImplAllowMalformedInput() const
    1321             : {
    1322           0 :     return !IsEnforceValidValue();
    1323             : }
    1324             : 
    1325           0 : void DateField::ImplDateSpinArea( bool bUp )
    1326             : {
    1327             :     // increment days if all is selected
    1328           0 :     if ( GetField() )
    1329             :     {
    1330           0 :         Date aDate( GetDate() );
    1331           0 :         Selection aSelection = GetField()->GetSelection();
    1332           0 :         aSelection.Justify();
    1333           0 :         OUString aText( GetText() );
    1334           0 :         if ( (sal_Int32)aSelection.Len() == aText.getLength() )
    1335           0 :             ImplDateIncrementDay( aDate, bUp );
    1336             :         else
    1337             :         {
    1338           0 :             sal_Int8 nDateArea = 0;
    1339             : 
    1340           0 :             ExtDateFieldFormat eFormat = GetExtDateFormat( true );
    1341           0 :             if ( eFormat == XTDATEF_SYSTEM_LONG )
    1342             :             {
    1343           0 :                 eFormat = ImplGetExtFormat( ImplGetLocaleDataWrapper().getLongDateFormat() );
    1344           0 :                 nDateArea = 1;
    1345             :             }
    1346             :             else
    1347             :             {
    1348             :                 // search area
    1349           0 :                 sal_Int32 nPos = 0;
    1350           0 :                 OUString aDateSep = ImplGetDateSep( ImplGetLocaleDataWrapper(), eFormat );
    1351           0 :                 for ( sal_Int8 i = 1; i <= 3; i++ )
    1352             :                 {
    1353           0 :                     nPos = aText.indexOf( aDateSep, nPos );
    1354           0 :                     if ( nPos >= (sal_Int32)aSelection.Max() )
    1355             :                     {
    1356           0 :                         nDateArea = i;
    1357           0 :                         break;
    1358             :                     }
    1359             :                     else
    1360           0 :                         nPos++;
    1361           0 :                 }
    1362             :             }
    1363             : 
    1364           0 :             switch( eFormat )
    1365             :             {
    1366             :                 case XTDATEF_SHORT_MMDDYY:
    1367             :                 case XTDATEF_SHORT_MMDDYYYY:
    1368           0 :                 switch( nDateArea )
    1369             :                 {
    1370           0 :                     case 1: ImplDateIncrementMonth( aDate, bUp );
    1371           0 :                             break;
    1372           0 :                     case 2: ImplDateIncrementDay( aDate, bUp );
    1373           0 :                             break;
    1374           0 :                     case 3: ImplDateIncrementYear( aDate, bUp );
    1375           0 :                             break;
    1376             :                 }
    1377           0 :                 break;
    1378             :                 case XTDATEF_SHORT_DDMMYY:
    1379             :                 case XTDATEF_SHORT_DDMMYYYY:
    1380           0 :                 switch( nDateArea )
    1381             :                 {
    1382           0 :                     case 1: ImplDateIncrementDay( aDate, bUp );
    1383           0 :                             break;
    1384           0 :                     case 2: ImplDateIncrementMonth( aDate, bUp );
    1385           0 :                             break;
    1386           0 :                     case 3: ImplDateIncrementYear( aDate, bUp );
    1387           0 :                             break;
    1388             :                 }
    1389           0 :                 break;
    1390             :                 case XTDATEF_SHORT_YYMMDD:
    1391             :                 case XTDATEF_SHORT_YYYYMMDD:
    1392             :                 case XTDATEF_SHORT_YYMMDD_DIN5008:
    1393             :                 case XTDATEF_SHORT_YYYYMMDD_DIN5008:
    1394           0 :                 switch( nDateArea )
    1395             :                 {
    1396           0 :                     case 1: ImplDateIncrementYear( aDate, bUp );
    1397           0 :                             break;
    1398           0 :                     case 2: ImplDateIncrementMonth( aDate, bUp );
    1399           0 :                             break;
    1400           0 :                     case 3: ImplDateIncrementDay( aDate, bUp );
    1401           0 :                             break;
    1402             :                 }
    1403           0 :                 break;
    1404             :                 default:
    1405             :                     OSL_FAIL( "invalid conversion" );
    1406           0 :                     break;
    1407             :             }
    1408             :         }
    1409             : 
    1410           0 :         ImplNewFieldValue( aDate );
    1411             :     }
    1412           0 : }
    1413             : 
    1414           0 : void DateFormatter::ImplInit()
    1415             : {
    1416           0 :     mbLongFormat        = false;
    1417           0 :     mbShowDateCentury   = true;
    1418           0 :     mpCalendarWrapper   = NULL;
    1419           0 :     mnDateFormat        = 0xFFFF;
    1420           0 :     mnExtDateFormat     = XTDATEF_SYSTEM_SHORT;
    1421           0 : }
    1422             : 
    1423           0 : DateFormatter::DateFormatter() :
    1424             :     maFieldDate( 0 ),
    1425             :     maLastDate( 0 ),
    1426             :     maMin( 1, 1, 1900 ),
    1427             :     maMax( 31, 12, 2200 ),
    1428             :     maCorrectedDate( Date::SYSTEM ),
    1429           0 :     mbEnforceValidValue( true )
    1430             : {
    1431           0 :     ImplInit();
    1432           0 : }
    1433             : 
    1434           0 : void DateFormatter::ImplLoadRes( const ResId& rResId )
    1435             : {
    1436           0 :     ResMgr*     pMgr = rResId.GetResMgr();
    1437           0 :     if( pMgr )
    1438             :     {
    1439           0 :         sal_uLong       nMask = pMgr->ReadLong();
    1440             : 
    1441           0 :         if ( DATEFORMATTER_MIN & nMask )
    1442             :         {
    1443           0 :             maMin = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) );
    1444           0 :             pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) );
    1445             :         }
    1446           0 :         if ( DATEFORMATTER_MAX & nMask )
    1447             :         {
    1448           0 :             maMax = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) );
    1449           0 :             pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) );
    1450             :         }
    1451           0 :         if ( DATEFORMATTER_LONGFORMAT & nMask )
    1452           0 :             mbLongFormat = pMgr->ReadShort() != 0;
    1453             : 
    1454           0 :         if ( DATEFORMATTER_STRICTFORMAT & nMask )
    1455           0 :             SetStrictFormat( pMgr->ReadShort() != 0 );
    1456             : 
    1457           0 :         if ( DATEFORMATTER_VALUE & nMask )
    1458             :         {
    1459           0 :             maFieldDate = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) );
    1460           0 :             pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) );
    1461           0 :             if ( maFieldDate > maMax )
    1462           0 :                 maFieldDate = maMax;
    1463           0 :             if ( maFieldDate < maMin )
    1464           0 :                 maFieldDate = maMin;
    1465           0 :             maLastDate = maFieldDate;
    1466             :         }
    1467             :     }
    1468           0 : }
    1469             : 
    1470           0 : DateFormatter::~DateFormatter()
    1471             : {
    1472           0 :     delete mpCalendarWrapper;
    1473           0 :     mpCalendarWrapper = NULL;
    1474           0 : }
    1475             : 
    1476           0 : void DateFormatter::SetLocale( const ::com::sun::star::lang::Locale& rLocale )
    1477             : {
    1478           0 :     delete mpCalendarWrapper;
    1479           0 :     mpCalendarWrapper = NULL;
    1480           0 :     FormatterBase::SetLocale( rLocale );
    1481           0 : }
    1482             : 
    1483           0 : CalendarWrapper& DateFormatter::GetCalendarWrapper() const
    1484             : {
    1485           0 :     if ( !mpCalendarWrapper )
    1486             :     {
    1487           0 :         ((DateFormatter*)this)->mpCalendarWrapper = new CalendarWrapper( comphelper::getProcessComponentContext() );
    1488           0 :         mpCalendarWrapper->loadDefaultCalendar( GetLocale() );
    1489             :     }
    1490             : 
    1491           0 :     return *mpCalendarWrapper;
    1492             : }
    1493             : 
    1494           0 : void DateFormatter::SetExtDateFormat( ExtDateFieldFormat eFormat )
    1495             : {
    1496           0 :     mnExtDateFormat = eFormat;
    1497           0 :     ReformatAll();
    1498           0 : }
    1499             : 
    1500           0 : ExtDateFieldFormat DateFormatter::GetExtDateFormat( bool bResolveSystemFormat ) const
    1501             : {
    1502           0 :     ExtDateFieldFormat eDateFormat = (ExtDateFieldFormat)mnExtDateFormat;
    1503             : 
    1504           0 :     if ( bResolveSystemFormat && ( eDateFormat <= XTDATEF_SYSTEM_SHORT_YYYY ) )
    1505             :     {
    1506           0 :         bool bShowCentury = (eDateFormat == XTDATEF_SYSTEM_SHORT_YYYY);
    1507           0 :         switch ( ImplGetLocaleDataWrapper().getDateFormat() )
    1508             :         {
    1509           0 :             case DMY:   eDateFormat = bShowCentury ? XTDATEF_SHORT_DDMMYYYY : XTDATEF_SHORT_DDMMYY;
    1510           0 :                         break;
    1511           0 :             case MDY:   eDateFormat = bShowCentury ? XTDATEF_SHORT_MMDDYYYY : XTDATEF_SHORT_MMDDYY;
    1512           0 :                         break;
    1513           0 :             default:    eDateFormat = bShowCentury ? XTDATEF_SHORT_YYYYMMDD : XTDATEF_SHORT_YYMMDD;
    1514             : 
    1515             :         }
    1516             :     }
    1517             : 
    1518           0 :     return eDateFormat;
    1519             : }
    1520             : 
    1521           0 : void DateFormatter::ReformatAll()
    1522             : {
    1523           0 :     Reformat();
    1524           0 : }
    1525             : 
    1526           0 : void DateFormatter::SetMin( const Date& rNewMin )
    1527             : {
    1528           0 :     maMin = rNewMin;
    1529           0 :     if ( !IsEmptyFieldValue() )
    1530           0 :         ReformatAll();
    1531           0 : }
    1532             : 
    1533           0 : void DateFormatter::SetMax( const Date& rNewMax )
    1534             : {
    1535           0 :     maMax = rNewMax;
    1536           0 :     if ( !IsEmptyFieldValue() )
    1537           0 :         ReformatAll();
    1538           0 : }
    1539             : 
    1540           0 : void DateFormatter::SetLongFormat( bool bLong )
    1541             : {
    1542           0 :     mbLongFormat = bLong;
    1543             : 
    1544             :     // #91913# Remove LongFormat and DateShowCentury - redundant
    1545           0 :     if ( bLong )
    1546             :     {
    1547           0 :         SetExtDateFormat( XTDATEF_SYSTEM_LONG );
    1548             :     }
    1549             :     else
    1550             :     {
    1551           0 :         if( mnExtDateFormat == XTDATEF_SYSTEM_LONG )
    1552           0 :             SetExtDateFormat( XTDATEF_SYSTEM_SHORT );
    1553             :     }
    1554             : 
    1555           0 :     ReformatAll();
    1556           0 : }
    1557             : 
    1558           0 : void DateFormatter::SetShowDateCentury( bool bShowDateCentury )
    1559             : {
    1560           0 :     mbShowDateCentury = bShowDateCentury;
    1561             : 
    1562             :     // #91913# Remove LongFormat and DateShowCentury - redundant
    1563           0 :     if ( bShowDateCentury )
    1564             :     {
    1565           0 :         switch ( GetExtDateFormat() )
    1566             :         {
    1567             :             case XTDATEF_SYSTEM_SHORT:
    1568             :             case XTDATEF_SYSTEM_SHORT_YY:
    1569           0 :                 SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY );  break;
    1570             :             case XTDATEF_SHORT_DDMMYY:
    1571           0 :                 SetExtDateFormat( XTDATEF_SHORT_DDMMYYYY );     break;
    1572             :             case XTDATEF_SHORT_MMDDYY:
    1573           0 :                 SetExtDateFormat( XTDATEF_SHORT_MMDDYYYY );     break;
    1574             :             case XTDATEF_SHORT_YYMMDD:
    1575           0 :                 SetExtDateFormat( XTDATEF_SHORT_YYYYMMDD );     break;
    1576             :             case XTDATEF_SHORT_YYMMDD_DIN5008:
    1577           0 :                 SetExtDateFormat( XTDATEF_SHORT_YYYYMMDD_DIN5008 ); break;
    1578             :             default:
    1579             :                 ;
    1580             :         }
    1581             :     }
    1582             :     else
    1583             :     {
    1584           0 :         switch ( GetExtDateFormat() )
    1585             :         {
    1586             :             case XTDATEF_SYSTEM_SHORT:
    1587             :             case XTDATEF_SYSTEM_SHORT_YYYY:
    1588           0 :                 SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YY );    break;
    1589             :             case XTDATEF_SHORT_DDMMYYYY:
    1590           0 :                 SetExtDateFormat( XTDATEF_SHORT_DDMMYY );       break;
    1591             :             case XTDATEF_SHORT_MMDDYYYY:
    1592           0 :                 SetExtDateFormat( XTDATEF_SHORT_MMDDYY );       break;
    1593             :             case XTDATEF_SHORT_YYYYMMDD:
    1594           0 :                 SetExtDateFormat( XTDATEF_SHORT_YYMMDD );       break;
    1595             :             case XTDATEF_SHORT_YYYYMMDD_DIN5008:
    1596           0 :                 SetExtDateFormat( XTDATEF_SHORT_YYMMDD_DIN5008 );  break;
    1597             :             default:
    1598             :                 ;
    1599             :         }
    1600             :     }
    1601             : 
    1602           0 :     ReformatAll();
    1603           0 : }
    1604             : 
    1605           0 : void DateFormatter::SetDate( const Date& rNewDate )
    1606             : {
    1607           0 :     SetUserDate( rNewDate );
    1608           0 :     maFieldDate = maLastDate;
    1609           0 :     maLastDate = GetDate();
    1610           0 : }
    1611             : 
    1612           0 : void DateFormatter::SetUserDate( const Date& rNewDate )
    1613             : {
    1614           0 :     ImplSetUserDate( rNewDate );
    1615           0 : }
    1616             : 
    1617           0 : void DateFormatter::ImplSetUserDate( const Date& rNewDate, Selection* pNewSelection )
    1618             : {
    1619           0 :     Date aNewDate = rNewDate;
    1620           0 :     if ( aNewDate > maMax )
    1621           0 :         aNewDate = maMax;
    1622           0 :     else if ( aNewDate < maMin )
    1623           0 :         aNewDate = maMin;
    1624           0 :     maLastDate = aNewDate;
    1625             : 
    1626           0 :     if ( GetField() )
    1627           0 :         ImplSetText( ImplGetDateAsText( aNewDate, GetFieldSettings() ), pNewSelection );
    1628           0 : }
    1629             : 
    1630           0 : void DateFormatter::ImplNewFieldValue( const Date& rDate )
    1631             : {
    1632           0 :     if ( GetField() )
    1633             :     {
    1634           0 :         Selection aSelection = GetField()->GetSelection();
    1635           0 :         aSelection.Justify();
    1636           0 :         OUString aText = GetField()->GetText();
    1637             : 
    1638             :         // If selected until the end then keep it that way
    1639           0 :         if ( (sal_Int32)aSelection.Max() == aText.getLength() )
    1640             :         {
    1641           0 :             if ( !aSelection.Len() )
    1642           0 :                 aSelection.Min() = SELECTION_MAX;
    1643           0 :             aSelection.Max() = SELECTION_MAX;
    1644             :         }
    1645             : 
    1646           0 :         Date aOldLastDate  = maLastDate;
    1647           0 :         ImplSetUserDate( rDate, &aSelection );
    1648           0 :         maLastDate = aOldLastDate;
    1649             : 
    1650             :         // Modify at Edit is only set at KeyInput
    1651           0 :         if ( GetField()->GetText() != aText )
    1652             :         {
    1653           0 :             GetField()->SetModifyFlag();
    1654           0 :             GetField()->Modify();
    1655           0 :         }
    1656             :     }
    1657           0 : }
    1658             : 
    1659           0 : Date DateFormatter::GetDate() const
    1660             : {
    1661           0 :     Date aDate( 0, 0, 0 );
    1662             : 
    1663           0 :     if ( GetField() )
    1664             :     {
    1665           0 :         if ( ImplDateGetValue( GetField()->GetText(), aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) )
    1666             :         {
    1667           0 :             if ( aDate > maMax )
    1668           0 :                 aDate = maMax;
    1669           0 :             else if ( aDate < maMin )
    1670           0 :                 aDate = maMin;
    1671             :         }
    1672             :         else
    1673             :         {
    1674             :             // !!! We should find out why dates are treated differently than other fields (see
    1675             :             // also bug: 52384)
    1676             : 
    1677           0 :             if ( !ImplAllowMalformedInput() )
    1678             :             {
    1679           0 :                 if ( maLastDate.GetDate() )
    1680           0 :                     aDate = maLastDate;
    1681           0 :                 else if ( !IsEmptyFieldValueEnabled() )
    1682           0 :                     aDate = Date( Date::SYSTEM );
    1683             :             }
    1684             :             else
    1685           0 :                 aDate = GetInvalidDate();
    1686             :         }
    1687             :     }
    1688             : 
    1689           0 :     return aDate;
    1690             : }
    1691             : 
    1692           0 : void DateFormatter::SetEmptyDate()
    1693             : {
    1694           0 :     FormatterBase::SetEmptyFieldValue();
    1695           0 : }
    1696             : 
    1697           0 : bool DateFormatter::IsEmptyDate() const
    1698             : {
    1699           0 :     bool bEmpty = FormatterBase::IsEmptyFieldValue();
    1700             : 
    1701           0 :     if ( GetField() && MustBeReformatted() && IsEmptyFieldValueEnabled() )
    1702             :     {
    1703           0 :         if ( GetField()->GetText().isEmpty() )
    1704             :         {
    1705           0 :             bEmpty = true;
    1706             :         }
    1707           0 :         else if ( !maLastDate.GetDate() )
    1708             :         {
    1709           0 :             Date aDate( Date::EMPTY );
    1710           0 :             bEmpty = !ImplDateGetValue( GetField()->GetText(), aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() );
    1711             :         }
    1712             :     }
    1713           0 :     return bEmpty;
    1714             : }
    1715             : 
    1716           0 : void DateFormatter::Reformat()
    1717             : {
    1718           0 :     if ( !GetField() )
    1719           0 :         return;
    1720             : 
    1721           0 :     if ( GetField()->GetText().isEmpty() && ImplGetEmptyFieldValue() )
    1722           0 :         return;
    1723             : 
    1724           0 :     OUString aStr;
    1725           0 :     bool bOK = ImplDateReformat( GetField()->GetText(), aStr, GetFieldSettings() );
    1726           0 :     if( !bOK )
    1727           0 :         return;
    1728             : 
    1729           0 :     if ( !aStr.isEmpty() )
    1730             :     {
    1731           0 :         ImplSetText( aStr );
    1732           0 :         ImplDateGetValue( aStr, maLastDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() );
    1733             :     }
    1734             :     else
    1735             :     {
    1736           0 :         if ( maLastDate.GetDate() )
    1737           0 :             SetDate( maLastDate );
    1738           0 :         else if ( !IsEmptyFieldValueEnabled() )
    1739           0 :             SetDate( Date( Date::SYSTEM ) );
    1740             :         else
    1741             :         {
    1742           0 :             ImplSetText( OUString() );
    1743           0 :             SetEmptyFieldValueData( true );
    1744             :         }
    1745           0 :     }
    1746             : }
    1747             : 
    1748           0 : void DateFormatter::ExpandCentury( Date& rDate )
    1749             : {
    1750           0 :     ExpandCentury( rDate, utl::MiscCfg().GetYear2000() );
    1751           0 : }
    1752             : 
    1753           0 : void DateFormatter::ExpandCentury( Date& rDate, sal_uInt16 nTwoDigitYearStart )
    1754             : {
    1755           0 :     sal_uInt16 nDateYear = rDate.GetYear();
    1756           0 :     if ( nDateYear < 100 )
    1757             :     {
    1758           0 :         sal_uInt16 nCentury = nTwoDigitYearStart / 100;
    1759           0 :         if ( nDateYear < (nTwoDigitYearStart % 100) )
    1760           0 :             nCentury++;
    1761           0 :         rDate.SetYear( nDateYear + (nCentury*100) );
    1762             :     }
    1763           0 : }
    1764             : 
    1765           0 : DateField::DateField( Window* pParent, WinBits nWinStyle ) :
    1766             :     SpinField( pParent, nWinStyle ),
    1767           0 :     maFirst( GetMin() ),
    1768           0 :     maLast( GetMax() )
    1769             : {
    1770           0 :     SetField( this );
    1771           0 :     SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) );
    1772           0 :     Reformat();
    1773           0 :     ResetLastDate();
    1774           0 : }
    1775             : 
    1776           0 : DateField::DateField( Window* pParent, const ResId& rResId ) :
    1777             :     SpinField( WINDOW_DATEFIELD ),
    1778           0 :     maFirst( GetMin() ),
    1779           0 :     maLast( GetMax() )
    1780             : {
    1781           0 :     rResId.SetRT( RSC_DATEFIELD );
    1782           0 :     WinBits nStyle = ImplInitRes( rResId );
    1783           0 :     SpinField::ImplInit( pParent, nStyle );
    1784           0 :     SetField( this );
    1785           0 :     SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) );
    1786           0 :     ImplLoadRes( rResId );
    1787             : 
    1788           0 :     if ( !(nStyle & WB_HIDE ) )
    1789           0 :         Show();
    1790             : 
    1791           0 :     ResetLastDate();
    1792           0 : }
    1793             : 
    1794           0 : void DateField::ImplLoadRes( const ResId& rResId )
    1795             : {
    1796           0 :     SpinField::ImplLoadRes( rResId );
    1797             : 
    1798           0 :     ResMgr* pMgr = rResId.GetResMgr();
    1799           0 :     if( pMgr )
    1800             :     {
    1801           0 :         DateFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) );
    1802             : 
    1803           0 :         sal_uLong  nMask = ReadLongRes();
    1804           0 :         if ( DATEFIELD_FIRST & nMask )
    1805             :         {
    1806           0 :             maFirst = Date( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) );
    1807           0 :             IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
    1808             :         }
    1809           0 :         if ( DATEFIELD_LAST & nMask )
    1810             :         {
    1811           0 :             maLast = Date( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) );
    1812           0 :             IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
    1813             :         }
    1814             :     }
    1815             : 
    1816           0 :     Reformat();
    1817           0 : }
    1818             : 
    1819           0 : DateField::~DateField()
    1820             : {
    1821           0 : }
    1822             : 
    1823           0 : bool DateField::PreNotify( NotifyEvent& rNEvt )
    1824             : {
    1825           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && IsStrictFormat() &&
    1826           0 :          ( GetExtDateFormat() != XTDATEF_SYSTEM_LONG ) &&
    1827           0 :          !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
    1828             :     {
    1829           0 :         if ( ImplDateProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetExtDateFormat( true ), ImplGetLocaleDataWrapper() ) )
    1830           0 :             return true;
    1831             :     }
    1832             : 
    1833           0 :     return SpinField::PreNotify( rNEvt );
    1834             : }
    1835             : 
    1836           0 : bool DateField::Notify( NotifyEvent& rNEvt )
    1837             : {
    1838           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
    1839           0 :         MarkToBeReformatted( false );
    1840           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
    1841             :     {
    1842           0 :         if ( MustBeReformatted() )
    1843             :         {
    1844             :             // !!! We should find out why dates are treated differently than other fields (see
    1845             :             // also bug: 52384)
    1846             : 
    1847           0 :             bool bTextLen = !GetText().isEmpty();
    1848           0 :             if ( bTextLen || !IsEmptyFieldValueEnabled() )
    1849             :             {
    1850           0 :                 if ( !ImplAllowMalformedInput() )
    1851           0 :                     Reformat();
    1852             :                 else
    1853             :                 {
    1854           0 :                     Date aDate( 0, 0, 0 );
    1855           0 :                     if ( ImplDateGetValue( GetText(), aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper(), GetFieldSettings() ) )
    1856             :                         // even with strict text analysis, our text is a valid date -> do a complete
    1857             :                         // reformat
    1858           0 :                         Reformat();
    1859             :                 }
    1860             :             }
    1861           0 :             else if ( !bTextLen && IsEmptyFieldValueEnabled() )
    1862             :             {
    1863           0 :                 ResetLastDate();
    1864           0 :                 SetEmptyFieldValueData( true );
    1865             :             }
    1866             :         }
    1867             :     }
    1868             : 
    1869           0 :     return SpinField::Notify( rNEvt );
    1870             : }
    1871             : 
    1872           0 : void DateField::DataChanged( const DataChangedEvent& rDCEvt )
    1873             : {
    1874           0 :     SpinField::DataChanged( rDCEvt );
    1875             : 
    1876           0 :     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & (SETTINGS_LOCALE|SETTINGS_MISC)) )
    1877             :     {
    1878           0 :         if ( IsDefaultLocale() && ( rDCEvt.GetFlags() & SETTINGS_LOCALE ) )
    1879           0 :             ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
    1880           0 :         ReformatAll();
    1881             :     }
    1882           0 : }
    1883             : 
    1884           0 : void DateField::Modify()
    1885             : {
    1886           0 :     MarkToBeReformatted( true );
    1887           0 :     SpinField::Modify();
    1888           0 : }
    1889             : 
    1890           0 : void DateField::Up()
    1891             : {
    1892           0 :     ImplDateSpinArea( true );
    1893           0 :     SpinField::Up();
    1894           0 : }
    1895             : 
    1896           0 : void DateField::Down()
    1897             : {
    1898           0 :     ImplDateSpinArea( false );
    1899           0 :     SpinField::Down();
    1900           0 : }
    1901             : 
    1902           0 : void DateField::First()
    1903             : {
    1904           0 :     ImplNewFieldValue( maFirst );
    1905           0 :     SpinField::First();
    1906           0 : }
    1907             : 
    1908           0 : void DateField::Last()
    1909             : {
    1910           0 :     ImplNewFieldValue( maLast );
    1911           0 :     SpinField::Last();
    1912           0 : }
    1913             : 
    1914           0 : DateBox::DateBox( Window* pParent, WinBits nWinStyle ) :
    1915           0 :     ComboBox( pParent, nWinStyle )
    1916             : {
    1917           0 :     SetField( this );
    1918           0 :     SetText( ImplGetLocaleDataWrapper().getDate( ImplGetFieldDate() ) );
    1919           0 :     Reformat();
    1920           0 : }
    1921             : 
    1922           0 : DateBox::~DateBox()
    1923             : {
    1924           0 : }
    1925             : 
    1926           0 : bool DateBox::PreNotify( NotifyEvent& rNEvt )
    1927             : {
    1928           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && IsStrictFormat() &&
    1929           0 :          ( GetExtDateFormat() != XTDATEF_SYSTEM_LONG ) &&
    1930           0 :          !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
    1931             :     {
    1932           0 :         if ( ImplDateProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetExtDateFormat( true ), ImplGetLocaleDataWrapper() ) )
    1933           0 :             return true;
    1934             :     }
    1935             : 
    1936           0 :     return ComboBox::PreNotify( rNEvt );
    1937             : }
    1938             : 
    1939           0 : void DateBox::DataChanged( const DataChangedEvent& rDCEvt )
    1940             : {
    1941           0 :     ComboBox::DataChanged( rDCEvt );
    1942             : 
    1943           0 :     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
    1944             :     {
    1945           0 :         if ( IsDefaultLocale() )
    1946           0 :             ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
    1947           0 :         ReformatAll();
    1948             :     }
    1949           0 : }
    1950             : 
    1951           0 : bool DateBox::Notify( NotifyEvent& rNEvt )
    1952             : {
    1953           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
    1954           0 :         MarkToBeReformatted( false );
    1955           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
    1956             :     {
    1957           0 :         if ( MustBeReformatted() )
    1958             :         {
    1959           0 :             bool bTextLen = !GetText().isEmpty();
    1960           0 :             if ( bTextLen || !IsEmptyFieldValueEnabled() )
    1961           0 :                 Reformat();
    1962           0 :             else if ( !bTextLen && IsEmptyFieldValueEnabled() )
    1963             :             {
    1964           0 :                 ResetLastDate();
    1965           0 :                 SetEmptyFieldValueData( true );
    1966             :             }
    1967             :         }
    1968             :     }
    1969             : 
    1970           0 :     return ComboBox::Notify( rNEvt );
    1971             : }
    1972             : 
    1973           0 : void DateBox::Modify()
    1974             : {
    1975           0 :     MarkToBeReformatted( true );
    1976           0 :     ComboBox::Modify();
    1977           0 : }
    1978             : 
    1979           0 : void DateBox::ReformatAll()
    1980             : {
    1981           0 :     OUString aStr;
    1982           0 :     SetUpdateMode( false );
    1983           0 :     sal_uInt16 nEntryCount = GetEntryCount();
    1984           0 :     for ( sal_uInt16 i=0; i < nEntryCount; i++ )
    1985             :     {
    1986           0 :         ImplDateReformat( GetEntry( i ), aStr, GetFieldSettings() );
    1987           0 :         RemoveEntryAt(i);
    1988           0 :         InsertEntry( aStr, i );
    1989             :     }
    1990           0 :     DateFormatter::Reformat();
    1991           0 :     SetUpdateMode( true );
    1992           0 : }
    1993             : 
    1994           0 : static bool ImplTimeProcessKeyInput( Edit*, const KeyEvent& rKEvt,
    1995             :                                      bool bStrictFormat, bool bDuration,
    1996             :                                      TimeFieldFormat eFormat,
    1997             :                                      const LocaleDataWrapper& rLocaleDataWrapper  )
    1998             : {
    1999           0 :     sal_Unicode cChar = rKEvt.GetCharCode();
    2000             : 
    2001           0 :     if ( !bStrictFormat )
    2002           0 :         return false;
    2003             :     else
    2004             :     {
    2005           0 :         sal_uInt16 nGroup = rKEvt.GetKeyCode().GetGroup();
    2006           0 :         if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
    2007           0 :              (nGroup == KEYGROUP_MISC)   ||
    2008           0 :              ((cChar >= '0') && (cChar <= '9')) ||
    2009           0 :              string::equals(rLocaleDataWrapper.getTimeSep(), cChar) ||
    2010           0 :              (rLocaleDataWrapper.getTimeAM().indexOf(cChar) != -1) ||
    2011           0 :              (rLocaleDataWrapper.getTimePM().indexOf(cChar) != -1) ||
    2012             :              // Accept AM/PM:
    2013           0 :              (cChar == 'a') || (cChar == 'A') || (cChar == 'm') || (cChar == 'M') || (cChar == 'p') || (cChar == 'P') ||
    2014           0 :              ((eFormat == TIMEF_100TH_SEC) && string::equals(rLocaleDataWrapper.getTime100SecSep(), cChar)) ||
    2015           0 :              ((eFormat == TIMEF_SEC_CS) && string::equals(rLocaleDataWrapper.getTime100SecSep(), cChar)) ||
    2016           0 :              (bDuration && (cChar == '-')) )
    2017           0 :             return false;
    2018             :         else
    2019           0 :             return true;
    2020             :     }
    2021             : }
    2022             : 
    2023           0 : static bool ImplIsOnlyDigits( const OUStringBuffer& _rStr )
    2024             : {
    2025           0 :     const sal_Unicode* _pChr = _rStr.getStr();
    2026           0 :     for ( sal_Int32 i = 0; i < _rStr.getLength(); ++i, ++_pChr )
    2027             :     {
    2028           0 :         if ( *_pChr < '0' || *_pChr > '9' )
    2029           0 :             return false;
    2030             :     }
    2031           0 :     return true;
    2032             : }
    2033             : 
    2034           0 : static bool ImplIsValidTimePortion( bool _bSkipInvalidCharacters, const OUStringBuffer& _rStr )
    2035             : {
    2036           0 :     if ( !_bSkipInvalidCharacters )
    2037             :     {
    2038           0 :         if ( ( _rStr.getLength() > 2 ) || _rStr.isEmpty() || !ImplIsOnlyDigits( _rStr ) )
    2039           0 :             return false;
    2040             :     }
    2041           0 :     return true;
    2042             : }
    2043             : 
    2044           0 : static bool ImplCutTimePortion( OUStringBuffer& _rStr, sal_Int32 _nSepPos, bool _bSkipInvalidCharacters, short* _pPortion )
    2045             : {
    2046           0 :     OUString sPortion(_rStr.getStr(), _nSepPos );
    2047           0 :     _rStr = _nSepPos < _rStr.getLength()
    2048           0 :         ? _rStr.copy( _nSepPos + 1 ) : OUStringBuffer();
    2049             : 
    2050           0 :     if ( !ImplIsValidTimePortion( _bSkipInvalidCharacters, sPortion ) )
    2051           0 :         return false;
    2052           0 :     *_pPortion = (short)sPortion.toInt32();
    2053           0 :     return true;
    2054             : }
    2055             : 
    2056           0 : static bool ImplTimeGetValue( const OUString& rStr, Time& rTime,
    2057             :                               TimeFieldFormat eFormat, bool bDuration,
    2058             :                               const LocaleDataWrapper& rLocaleDataWrapper, bool _bSkipInvalidCharacters = true )
    2059             : {
    2060           0 :     OUStringBuffer    aStr    = rStr;
    2061           0 :     short       nHour   = 0;
    2062           0 :     short       nMinute = 0;
    2063           0 :     short       nSecond = 0;
    2064           0 :     sal_Int64   nNanoSec = 0;
    2065           0 :     Time        aTime( 0, 0, 0 );
    2066             : 
    2067           0 :     if ( rStr.isEmpty() )
    2068           0 :         return false;
    2069             : 
    2070             :     // Search for separators
    2071           0 :     if (!rLocaleDataWrapper.getTimeSep().isEmpty())
    2072             :     {
    2073           0 :         OUStringBuffer aSepStr(",.;:/");
    2074           0 :         if ( !bDuration )
    2075           0 :             aSepStr.append('-');
    2076             : 
    2077             :         // Replace characters above by the separator character
    2078           0 :         for (sal_Int32 i = 0; i < aSepStr.getLength(); ++i)
    2079             :         {
    2080           0 :             if (string::equals(rLocaleDataWrapper.getTimeSep(), aSepStr[i]))
    2081           0 :                 continue;
    2082           0 :             for ( sal_Int32 j = 0; j < aStr.getLength(); j++ )
    2083             :             {
    2084           0 :                 if (aStr[j] == aSepStr[i])
    2085           0 :                     aStr[j] = rLocaleDataWrapper.getTimeSep()[0];
    2086             :             }
    2087           0 :         }
    2088             :     }
    2089             : 
    2090           0 :     bool bNegative = false;
    2091           0 :     sal_Int32 nSepPos = aStr.indexOf( rLocaleDataWrapper.getTimeSep() );
    2092           0 :     if ( aStr[0] == '-' )
    2093           0 :         bNegative = true;
    2094           0 :     if ( eFormat != TIMEF_SEC_CS )
    2095             :     {
    2096           0 :         if ( nSepPos < 0 )
    2097           0 :             nSepPos = aStr.getLength();
    2098           0 :         if ( !ImplCutTimePortion( aStr, nSepPos, _bSkipInvalidCharacters, &nHour ) )
    2099           0 :             return false;
    2100             : 
    2101           0 :         nSepPos = aStr.indexOf( rLocaleDataWrapper.getTimeSep() );
    2102           0 :         if ( !aStr.isEmpty() && aStr[0] == '-' )
    2103           0 :             bNegative = true;
    2104           0 :         if ( nSepPos >= 0 )
    2105             :         {
    2106           0 :             if ( !ImplCutTimePortion( aStr, nSepPos, _bSkipInvalidCharacters, &nMinute ) )
    2107           0 :                 return false;
    2108             : 
    2109           0 :             nSepPos = aStr.indexOf( rLocaleDataWrapper.getTimeSep() );
    2110           0 :             if ( !aStr.isEmpty() && aStr[0] == '-' )
    2111           0 :                 bNegative = true;
    2112           0 :             if ( nSepPos >= 0 )
    2113             :             {
    2114           0 :                 if ( !ImplCutTimePortion( aStr, nSepPos, _bSkipInvalidCharacters, &nSecond ) )
    2115           0 :                     return false;
    2116           0 :                 if ( !aStr.isEmpty() && aStr[0] == '-' )
    2117           0 :                     bNegative = true;
    2118           0 :                 nNanoSec = aStr.toString().toInt64();
    2119             :             }
    2120             :             else
    2121           0 :                 nSecond = (short)aStr.toString().toInt32();
    2122             :         }
    2123             :         else
    2124           0 :             nMinute = (short)aStr.toString().toInt32();
    2125             :     }
    2126           0 :     else if ( nSepPos < 0 )
    2127             :     {
    2128           0 :         nSecond = (short)aStr.toString().toInt32();
    2129           0 :         nMinute += nSecond / 60;
    2130           0 :         nSecond %= 60;
    2131           0 :         nHour += nMinute / 60;
    2132           0 :         nMinute %= 60;
    2133             :     }
    2134             :     else
    2135             :     {
    2136           0 :         nSecond = (short)aStr.copy( 0, nSepPos ).toString().toInt32();
    2137           0 :         aStr.remove( 0, nSepPos+1 );
    2138             : 
    2139           0 :         nSepPos = aStr.indexOf( rLocaleDataWrapper.getTimeSep() );
    2140           0 :         if ( !aStr.isEmpty() && aStr[0] == '-' )
    2141           0 :             bNegative = true;
    2142           0 :         if ( nSepPos >= 0 )
    2143             :         {
    2144           0 :             nMinute = nSecond;
    2145           0 :             nSecond = (short)aStr.copy( 0, nSepPos ).toString().toInt32();
    2146           0 :             aStr.remove( 0, nSepPos+1 );
    2147             : 
    2148           0 :             nSepPos = aStr.indexOf( rLocaleDataWrapper.getTimeSep() );
    2149           0 :             if ( !aStr.isEmpty() && aStr[0] == '-' )
    2150           0 :                 bNegative = true;
    2151           0 :             if ( nSepPos >= 0 )
    2152             :             {
    2153           0 :                 nHour   = nMinute;
    2154           0 :                 nMinute = nSecond;
    2155           0 :                 nSecond = (short)aStr.copy( 0, nSepPos ).toString().toInt32();
    2156           0 :                 aStr.remove( 0, nSepPos+1 );
    2157             :             }
    2158             :             else
    2159             :             {
    2160           0 :                 nHour += nMinute / 60;
    2161           0 :                 nMinute %= 60;
    2162             :             }
    2163             :         }
    2164             :         else
    2165             :         {
    2166           0 :             nMinute += nSecond / 60;
    2167           0 :             nSecond %= 60;
    2168           0 :             nHour += nMinute / 60;
    2169           0 :             nMinute %= 60;
    2170             :         }
    2171           0 :         nNanoSec = aStr.toString().toInt64();
    2172             :     }
    2173             : 
    2174           0 :     if ( nNanoSec )
    2175             :     {
    2176             :         assert(aStr.getLength() >= 1);
    2177             : 
    2178           0 :         sal_Int32 nLen = 1; // at least one digit, otherwise nNanoSec==0
    2179             : 
    2180           0 :         while ( aStr.getLength() > nLen && aStr[nLen] >= '0' && aStr[nLen] <= '9' )
    2181           0 :             nLen++;
    2182             : 
    2183           0 :         while ( nLen < 9)
    2184             :         {
    2185           0 :             nNanoSec *= 10;
    2186           0 :             ++nLen;
    2187             :         }
    2188           0 :         while ( nLen > 9 )
    2189             :         {
    2190             :             // round if negative?
    2191           0 :             nNanoSec = (nNanoSec + 5) / 10;
    2192           0 :             --nLen;
    2193             :         }
    2194             :     }
    2195             : 
    2196             :     assert(nNanoSec > -1000000000 && nNanoSec < 1000000000);
    2197           0 :     if ( (nMinute > 59) || (nSecond > 59) || (nNanoSec > 1000000000) )
    2198           0 :         return false;
    2199             : 
    2200           0 :     if ( eFormat == TIMEF_NONE )
    2201           0 :         nSecond = nNanoSec = 0;
    2202           0 :     else if ( eFormat == TIMEF_SEC )
    2203           0 :         nNanoSec = 0;
    2204             : 
    2205           0 :     if ( !bDuration )
    2206             :     {
    2207           0 :         if ( bNegative || (nHour < 0) || (nMinute < 0) ||
    2208           0 :              (nSecond < 0) || (nNanoSec < 0) )
    2209           0 :             return false;
    2210             : 
    2211           0 :         OUString aUpperCaseStr = aStr.toString().toAsciiUpperCase();
    2212           0 :         OUString aAM(rLocaleDataWrapper.getTimeAM().toAsciiUpperCase());
    2213           0 :         OUString aPM(rLocaleDataWrapper.getTimePM().toAsciiUpperCase());
    2214           0 :         OUString aAM2("AM");  // aAM is localized
    2215           0 :         OUString aPM2("PM");  // aPM is localized
    2216             : 
    2217           0 :         if ( (nHour < 12) && ( ( aUpperCaseStr.indexOf( aPM ) >= 0 ) || ( aUpperCaseStr.indexOf( aPM2 ) >= 0 ) ) )
    2218           0 :             nHour += 12;
    2219             : 
    2220           0 :         if ( (nHour == 12) && ( ( aUpperCaseStr.indexOf( aAM ) >= 0 ) || ( aUpperCaseStr.indexOf( aAM2 ) >= 0 ) ) )
    2221           0 :             nHour = 0;
    2222             : 
    2223           0 :         aTime = Time( (sal_uInt16)nHour, (sal_uInt16)nMinute, (sal_uInt16)nSecond,
    2224           0 :                       (sal_uInt32)nNanoSec );
    2225             :     }
    2226             :     else
    2227             :     {
    2228             :         assert( !bNegative || (nHour < 0) || (nMinute < 0) ||
    2229             :              (nSecond < 0) || (nNanoSec < 0) );
    2230           0 :         if ( bNegative || (nHour < 0) || (nMinute < 0) ||
    2231           0 :              (nSecond < 0) || (nNanoSec < 0) )
    2232             :         {
    2233             :             // LEM TODO: this looks weird... I think buggy when parsing "05:-02:18"
    2234           0 :             bNegative   = true;
    2235           0 :             nHour       = nHour < 0 ? -nHour : nHour;
    2236           0 :             nMinute     = nMinute < 0 ? -nMinute : nMinute;
    2237           0 :             nSecond     = nSecond < 0 ? -nSecond : nSecond;
    2238           0 :             nNanoSec    = nNanoSec < 0 ? -nNanoSec : nNanoSec;
    2239             :         }
    2240             : 
    2241           0 :         aTime = Time( (sal_uInt16)nHour, (sal_uInt16)nMinute, (sal_uInt16)nSecond,
    2242           0 :                       (sal_uInt32)nNanoSec );
    2243           0 :         if ( bNegative )
    2244           0 :             aTime = -aTime;
    2245             :     }
    2246             : 
    2247           0 :     rTime = aTime;
    2248             : 
    2249           0 :     return true;
    2250             : }
    2251             : 
    2252           0 : bool TimeFormatter::ImplTimeReformat( const OUString& rStr, OUString& rOutStr )
    2253             : {
    2254           0 :     Time aTime( 0, 0, 0 );
    2255           0 :     if ( !ImplTimeGetValue( rStr, aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper() ) )
    2256           0 :         return true;
    2257             : 
    2258           0 :     Time aTempTime = aTime;
    2259           0 :     if ( aTempTime > GetMax() )
    2260           0 :         aTempTime = GetMax() ;
    2261           0 :     else if ( aTempTime < GetMin() )
    2262           0 :         aTempTime = GetMin();
    2263             : 
    2264           0 :     if ( GetErrorHdl().IsSet() && (aTime != aTempTime) )
    2265             :     {
    2266           0 :         maCorrectedTime = aTempTime;
    2267           0 :         if ( !GetErrorHdl().Call( this ) )
    2268             :         {
    2269           0 :             maCorrectedTime = Time( Time::SYSTEM );
    2270           0 :             return false;
    2271             :         }
    2272             :         else
    2273           0 :             maCorrectedTime = Time( Time::SYSTEM );
    2274             :     }
    2275             : 
    2276           0 :     bool bSecond = false;
    2277           0 :     bool b100Sec = false;
    2278           0 :     if ( meFormat != TIMEF_NONE )
    2279           0 :         bSecond = true;
    2280           0 :     if ( meFormat == TIMEF_100TH_SEC )
    2281           0 :         b100Sec = true;
    2282             : 
    2283           0 :     if ( meFormat == TIMEF_SEC_CS )
    2284             :     {
    2285           0 :         sal_uLong n  = aTempTime.GetHour() * 3600L;
    2286           0 :         n       += aTempTime.GetMin()  * 60L;
    2287           0 :         n       += aTempTime.GetSec();
    2288           0 :         rOutStr  = OUString::number( n );
    2289           0 :         rOutStr += ImplGetLocaleDataWrapper().getTime100SecSep();
    2290           0 :         std::ostringstream ostr;
    2291           0 :         ostr.fill('0');
    2292           0 :         ostr.width(9);
    2293           0 :         ostr << aTempTime.GetNanoSec();
    2294           0 :         rOutStr += OUString::createFromAscii(ostr.str().c_str());
    2295             :     }
    2296           0 :     else if ( mbDuration )
    2297           0 :         rOutStr = ImplGetLocaleDataWrapper().getDuration( aTempTime, bSecond, b100Sec );
    2298             :     else
    2299             :     {
    2300           0 :         rOutStr = ImplGetLocaleDataWrapper().getTime( aTempTime, bSecond, b100Sec );
    2301           0 :         if ( GetTimeFormat() == HOUR_12 )
    2302             :         {
    2303           0 :             if ( aTempTime.GetHour() > 12 )
    2304             :             {
    2305           0 :                 Time aT( aTempTime );
    2306           0 :                 aT.SetHour( aT.GetHour() % 12 );
    2307           0 :                 rOutStr = ImplGetLocaleDataWrapper().getTime( aT, bSecond, b100Sec );
    2308             :             }
    2309             :             // Don't use LocaleDataWrapper, we want AM/PM
    2310           0 :             if ( aTempTime.GetHour() < 12 )
    2311           0 :                 rOutStr += "AM"; // ImplGetLocaleDataWrapper().getTimeAM();
    2312             :             else
    2313           0 :                 rOutStr += "PM"; // ImplGetLocaleDataWrapper().getTimePM();
    2314             :         }
    2315             :     }
    2316             : 
    2317           0 :     return true;
    2318             : }
    2319           0 : bool TimeFormatter::ImplAllowMalformedInput() const
    2320             : {
    2321           0 :     return !IsEnforceValidValue();
    2322             : }
    2323             : 
    2324           0 : void TimeField::ImplTimeSpinArea( bool bUp )
    2325             : {
    2326           0 :     if ( GetField() )
    2327             :     {
    2328           0 :         sal_Int32 nTimeArea = 0;
    2329           0 :         Time aTime( GetTime() );
    2330           0 :         OUString aText( GetText() );
    2331           0 :         Selection aSelection( GetField()->GetSelection() );
    2332             : 
    2333             :         // Area search
    2334           0 :         if ( GetFormat() != TIMEF_SEC_CS )
    2335             :         {
    2336             :             //Which area is the cursor in of HH:MM:SS.TT
    2337           0 :             for ( sal_Int32 i = 1, nPos = 0; i <= 4; i++ )
    2338             :             {
    2339           0 :                 sal_Int32 nPos1 = aText.indexOf( ImplGetLocaleDataWrapper().getTimeSep(), nPos );
    2340           0 :                 sal_Int32 nPos2 = aText.indexOf( ImplGetLocaleDataWrapper().getTime100SecSep(), nPos );
    2341             :                 //which ever comes first, bearing in mind that one might not be there
    2342           0 :                 if (nPos1 >= 0 && nPos2 >= 0)
    2343           0 :                     nPos = nPos1 < nPos2 ? nPos1 : nPos2;
    2344           0 :                 else if (nPos1 >= 0)
    2345           0 :                     nPos = nPos1;
    2346             :                 else
    2347           0 :                     nPos = nPos2;
    2348           0 :                 if ( nPos < 0 || nPos >= aSelection.Max() )
    2349             :                 {
    2350           0 :                     nTimeArea = i;
    2351           0 :                     break;
    2352             :                 }
    2353             :                 else
    2354           0 :                     nPos++;
    2355             :             }
    2356             :         }
    2357             :         else
    2358             :         {
    2359           0 :             sal_Int32 nPos = aText.indexOf( ImplGetLocaleDataWrapper().getTime100SecSep() );
    2360           0 :             if ( nPos < 0 || nPos >= aSelection.Max() )
    2361           0 :                 nTimeArea = 3;
    2362             :             else
    2363           0 :                 nTimeArea = 4;
    2364             :         }
    2365             : 
    2366           0 :         if ( nTimeArea )
    2367             :         {
    2368           0 :             Time aAddTime( 0, 0, 0 );
    2369           0 :             if ( nTimeArea == 1 )
    2370           0 :                 aAddTime = Time( 1, 0 );
    2371           0 :             else if ( nTimeArea == 2 )
    2372           0 :                 aAddTime = Time( 0, 1 );
    2373           0 :             else if ( nTimeArea == 3 )
    2374           0 :                 aAddTime = Time( 0, 0, 1 );
    2375           0 :             else if ( nTimeArea == 4 )
    2376           0 :                 aAddTime = Time( 0, 0, 0, 1 );
    2377             : 
    2378           0 :             if ( !bUp )
    2379           0 :                 aAddTime = -aAddTime;
    2380             : 
    2381           0 :             aTime += aAddTime;
    2382           0 :             if ( !IsDuration() )
    2383             :             {
    2384           0 :                 Time aAbsMaxTime( 23, 59, 59, 999999999 );
    2385           0 :                 if ( aTime > aAbsMaxTime )
    2386           0 :                     aTime = aAbsMaxTime;
    2387           0 :                 Time aAbsMinTime( 0, 0 );
    2388           0 :                 if ( aTime < aAbsMinTime )
    2389           0 :                     aTime = aAbsMinTime;
    2390             :             }
    2391           0 :             ImplNewFieldValue( aTime );
    2392           0 :         }
    2393             : 
    2394             :     }
    2395           0 : }
    2396             : 
    2397           0 : void TimeFormatter::ImplInit()
    2398             : {
    2399           0 :     meFormat        = TIMEF_NONE;
    2400           0 :     mbDuration      = false;
    2401           0 :     mnTimeFormat    = HOUR_24;  // Should become a ExtTimeFieldFormat in next implementation, merge with mbDuration and meFormat
    2402           0 : }
    2403             : 
    2404           0 : TimeFormatter::TimeFormatter() :
    2405             :     maLastTime( 0, 0 ),
    2406             :     maMin( 0, 0 ),
    2407             :     maMax( 23, 59, 59, 999999999 ),
    2408             :     maCorrectedTime( Time::SYSTEM ),
    2409             :     mbEnforceValidValue( true ),
    2410           0 :     maFieldTime( 0, 0 )
    2411             : {
    2412           0 :     ImplInit();
    2413           0 : }
    2414             : 
    2415           0 : void TimeFormatter::ImplLoadRes( const ResId& rResId )
    2416             : {
    2417           0 :     ResMgr* pMgr = rResId.GetResMgr();
    2418           0 :     if( pMgr )
    2419             :     {
    2420           0 :         sal_uLong   nMask = pMgr->ReadLong();
    2421             : 
    2422           0 :         if ( TIMEFORMATTER_MIN & nMask )
    2423             :         {
    2424           0 :             SetMin( Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ) );
    2425           0 :             pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) );
    2426             :         }
    2427             : 
    2428           0 :         if ( TIMEFORMATTER_MAX & nMask )
    2429             :         {
    2430           0 :             SetMax( Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) ) );
    2431           0 :             pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) );
    2432             :         }
    2433             : 
    2434           0 :         if ( TIMEFORMATTER_TIMEFIELDFORMAT & nMask )
    2435           0 :             meFormat = (TimeFieldFormat)pMgr->ReadLong();
    2436             : 
    2437           0 :         if ( TIMEFORMATTER_DURATION & nMask )
    2438           0 :             mbDuration = pMgr->ReadShort() != 0;
    2439             : 
    2440           0 :         if ( TIMEFORMATTER_STRICTFORMAT & nMask )
    2441           0 :             SetStrictFormat( pMgr->ReadShort() != 0 );
    2442             : 
    2443           0 :         if ( TIMEFORMATTER_VALUE & nMask )
    2444             :         {
    2445           0 :             maFieldTime = Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass(), *pMgr ) );
    2446           0 :             if ( maFieldTime > GetMax() )
    2447           0 :                 maFieldTime = GetMax();
    2448           0 :             if ( maFieldTime < GetMin() )
    2449           0 :                 maFieldTime = GetMin();
    2450           0 :             maLastTime = maFieldTime;
    2451             : 
    2452           0 :             pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) );
    2453             :         }
    2454             :     }
    2455           0 : }
    2456             : 
    2457           0 : TimeFormatter::~TimeFormatter()
    2458             : {
    2459           0 : }
    2460             : 
    2461           0 : void TimeFormatter::ReformatAll()
    2462             : {
    2463           0 :     Reformat();
    2464           0 : }
    2465             : 
    2466           0 : void TimeFormatter::SetMin( const Time& rNewMin )
    2467             : {
    2468           0 :     maMin = rNewMin;
    2469           0 :     if ( !IsEmptyFieldValue() )
    2470           0 :         ReformatAll();
    2471           0 : }
    2472             : 
    2473           0 : void TimeFormatter::SetMax( const Time& rNewMax )
    2474             : {
    2475           0 :     maMax = rNewMax;
    2476           0 :     if ( !IsEmptyFieldValue() )
    2477           0 :         ReformatAll();
    2478           0 : }
    2479             : 
    2480           0 : void TimeFormatter::SetTimeFormat( TimeFormatter::TimeFormat eNewFormat )
    2481             : {
    2482           0 :     mnTimeFormat = sal::static_int_cast<sal_uInt16>(eNewFormat);
    2483           0 : }
    2484             : 
    2485           0 : TimeFormatter::TimeFormat TimeFormatter::GetTimeFormat() const
    2486             : {
    2487           0 :     return (TimeFormat)mnTimeFormat;
    2488             : }
    2489             : 
    2490           0 : void TimeFormatter::SetFormat( TimeFieldFormat eNewFormat )
    2491             : {
    2492           0 :     meFormat = eNewFormat;
    2493           0 :     ReformatAll();
    2494           0 : }
    2495             : 
    2496           0 : void TimeFormatter::SetDuration( bool bNewDuration )
    2497             : {
    2498           0 :     mbDuration = bNewDuration;
    2499           0 :     ReformatAll();
    2500           0 : }
    2501             : 
    2502           0 : void TimeFormatter::SetTime( const Time& rNewTime )
    2503             : {
    2504           0 :     SetUserTime( rNewTime );
    2505           0 :     maFieldTime = maLastTime;
    2506           0 :     SetEmptyFieldValueData( false );
    2507           0 : }
    2508             : 
    2509           0 : void TimeFormatter::ImplNewFieldValue( const Time& rTime )
    2510             : {
    2511           0 :     if ( GetField() )
    2512             :     {
    2513           0 :         Selection aSelection = GetField()->GetSelection();
    2514           0 :         aSelection.Justify();
    2515           0 :         OUString aText = GetField()->GetText();
    2516             : 
    2517             :         // If selected until the end then keep it that way
    2518           0 :         if ( (sal_Int32)aSelection.Max() == aText.getLength() )
    2519             :         {
    2520           0 :             if ( !aSelection.Len() )
    2521           0 :                 aSelection.Min() = SELECTION_MAX;
    2522           0 :             aSelection.Max() = SELECTION_MAX;
    2523             :         }
    2524             : 
    2525           0 :         Time aOldLastTime = maLastTime;
    2526           0 :         ImplSetUserTime( rTime, &aSelection );
    2527           0 :         maLastTime = aOldLastTime;
    2528             : 
    2529             :         // Modify at Edit is only set at KeyInput
    2530           0 :         if ( GetField()->GetText() != aText )
    2531             :         {
    2532           0 :             GetField()->SetModifyFlag();
    2533           0 :             GetField()->Modify();
    2534           0 :         }
    2535             :     }
    2536           0 : }
    2537             : 
    2538           0 : void TimeFormatter::ImplSetUserTime( const Time& rNewTime, Selection* pNewSelection )
    2539             : {
    2540           0 :     Time aNewTime = rNewTime;
    2541           0 :     if ( aNewTime > GetMax() )
    2542           0 :         aNewTime = GetMax();
    2543           0 :     else if ( aNewTime < GetMin() )
    2544           0 :         aNewTime = GetMin();
    2545           0 :     maLastTime = aNewTime;
    2546             : 
    2547           0 :     if ( GetField() )
    2548             :     {
    2549           0 :         OUString aStr;
    2550           0 :         bool bSec    = false;
    2551           0 :         bool b100Sec = false;
    2552           0 :         if ( meFormat != TIMEF_NONE )
    2553           0 :             bSec = true;
    2554           0 :         if ( meFormat == TIMEF_100TH_SEC || meFormat == TIMEF_SEC_CS )
    2555           0 :             b100Sec = true;
    2556           0 :         if ( meFormat == TIMEF_SEC_CS )
    2557             :         {
    2558           0 :             sal_uLong n  = aNewTime.GetHour() * 3600L;
    2559           0 :             n       += aNewTime.GetMin()  * 60L;
    2560           0 :             n       += aNewTime.GetSec();
    2561           0 :             aStr     = OUString::number( n );
    2562           0 :             aStr    += ImplGetLocaleDataWrapper().getTime100SecSep();
    2563           0 :             std::ostringstream ostr;
    2564           0 :             ostr.fill('0');
    2565           0 :             ostr.width(9);
    2566           0 :             ostr << aNewTime.GetNanoSec();
    2567           0 :             aStr += OUString::createFromAscii(ostr.str().c_str());
    2568             :         }
    2569           0 :         else if ( mbDuration )
    2570             :         {
    2571           0 :             aStr = ImplGetLocaleDataWrapper().getDuration( aNewTime, bSec, b100Sec );
    2572             :         }
    2573             :         else
    2574             :         {
    2575           0 :             aStr = ImplGetLocaleDataWrapper().getTime( aNewTime, bSec, b100Sec );
    2576           0 :             if ( GetTimeFormat() == HOUR_12 )
    2577             :             {
    2578           0 :                 if ( aNewTime.GetHour() > 12 )
    2579             :                 {
    2580           0 :                     Time aT( aNewTime );
    2581           0 :                     aT.SetHour( aT.GetHour() % 12 );
    2582           0 :                     aStr = ImplGetLocaleDataWrapper().getTime( aT, bSec, b100Sec );
    2583             :                 }
    2584             :                 // Don't use LocaleDataWrapper, we want AM/PM
    2585           0 :                 if ( aNewTime.GetHour() < 12 )
    2586           0 :                     aStr += "AM"; // ImplGetLocaleDataWrapper().getTimeAM();
    2587             :                 else
    2588           0 :                     aStr += "PM"; // ImplGetLocaleDataWrapper().getTimePM();
    2589             :             }
    2590             :         }
    2591             : 
    2592           0 :         ImplSetText( aStr, pNewSelection );
    2593             :     }
    2594           0 : }
    2595             : 
    2596           0 : void TimeFormatter::SetUserTime( const Time& rNewTime )
    2597             : {
    2598           0 :     ImplSetUserTime( rNewTime );
    2599           0 : }
    2600             : 
    2601           0 : Time TimeFormatter::GetTime() const
    2602             : {
    2603           0 :     Time aTime( 0, 0, 0 );
    2604             : 
    2605           0 :     if ( GetField() )
    2606             :     {
    2607           0 :         bool bAllowMailformed = ImplAllowMalformedInput();
    2608           0 :         if ( ImplTimeGetValue( GetField()->GetText(), aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper(), !bAllowMailformed ) )
    2609             :         {
    2610           0 :             if ( aTime > GetMax() )
    2611           0 :                 aTime = GetMax();
    2612           0 :             else if ( aTime < GetMin() )
    2613           0 :                 aTime = GetMin();
    2614             :         }
    2615             :         else
    2616             :         {
    2617           0 :             if ( bAllowMailformed )
    2618           0 :                 aTime = GetInvalidTime();
    2619             :             else
    2620           0 :                 aTime = maLastTime;
    2621             :         }
    2622             :     }
    2623             : 
    2624           0 :     return aTime;
    2625             : }
    2626             : 
    2627           0 : void TimeFormatter::Reformat()
    2628             : {
    2629           0 :     if ( !GetField() )
    2630           0 :         return;
    2631             : 
    2632           0 :     if ( GetField()->GetText().isEmpty() && ImplGetEmptyFieldValue() )
    2633           0 :         return;
    2634             : 
    2635           0 :     OUString aStr;
    2636           0 :     bool bOK = ImplTimeReformat( GetField()->GetText(), aStr );
    2637           0 :     if ( !bOK )
    2638           0 :         return;
    2639             : 
    2640           0 :     if ( !aStr.isEmpty() )
    2641             :     {
    2642           0 :         ImplSetText( aStr );
    2643           0 :         ImplTimeGetValue( aStr, maLastTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper() );
    2644             :     }
    2645             :     else
    2646           0 :         SetTime( maLastTime );
    2647             : }
    2648             : 
    2649           0 : TimeField::TimeField( Window* pParent, WinBits nWinStyle ) :
    2650             :     SpinField( pParent, nWinStyle ),
    2651           0 :     maFirst( GetMin() ),
    2652           0 :     maLast( GetMax() )
    2653             : {
    2654           0 :     SetField( this );
    2655           0 :     SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime, false, false ) );
    2656           0 :     Reformat();
    2657           0 : }
    2658             : 
    2659           0 : TimeField::TimeField( Window* pParent, const ResId& rResId ) :
    2660             :     SpinField( WINDOW_TIMEFIELD ),
    2661           0 :     maFirst( GetMin() ),
    2662           0 :     maLast( GetMax() )
    2663             : {
    2664           0 :     rResId.SetRT( RSC_TIMEFIELD );
    2665           0 :     WinBits nStyle = ImplInitRes( rResId );
    2666           0 :     SpinField::ImplInit( pParent, nStyle );
    2667           0 :     SetField( this );
    2668           0 :     SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime, false, false ) );
    2669           0 :     ImplLoadRes( rResId );
    2670             : 
    2671           0 :     if ( !(nStyle & WB_HIDE ) )
    2672           0 :         Show();
    2673           0 : }
    2674             : 
    2675           0 : void TimeField::ImplLoadRes( const ResId& rResId )
    2676             : {
    2677           0 :     SpinField::ImplLoadRes( rResId );
    2678           0 :     ResMgr* pMgr = rResId.GetResMgr();
    2679           0 :     if( pMgr )
    2680             :     {
    2681           0 :         TimeFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) );
    2682             : 
    2683           0 :         sal_uLong      nMask = ReadLongRes();
    2684             : 
    2685           0 :         if ( TIMEFIELD_FIRST & nMask )
    2686             :         {
    2687           0 :             maFirst = Time( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) );
    2688           0 :             IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
    2689             :         }
    2690           0 :         if ( TIMEFIELD_LAST & nMask )
    2691             :         {
    2692           0 :             maLast = Time( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) );
    2693           0 :             IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
    2694             :         }
    2695             :     }
    2696             : 
    2697           0 :     Reformat();
    2698           0 : }
    2699             : 
    2700           0 : TimeField::~TimeField()
    2701             : {
    2702           0 : }
    2703             : 
    2704           0 : bool TimeField::PreNotify( NotifyEvent& rNEvt )
    2705             : {
    2706           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
    2707             :     {
    2708           0 :         if ( ImplTimeProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsDuration(), GetFormat(), ImplGetLocaleDataWrapper() ) )
    2709           0 :             return true;
    2710             :     }
    2711             : 
    2712           0 :     return SpinField::PreNotify( rNEvt );
    2713             : }
    2714             : 
    2715           0 : bool TimeField::Notify( NotifyEvent& rNEvt )
    2716             : {
    2717           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
    2718           0 :         MarkToBeReformatted( false );
    2719           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
    2720             :     {
    2721           0 :         if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
    2722             :         {
    2723           0 :             if ( !ImplAllowMalformedInput() )
    2724           0 :                 Reformat();
    2725             :             else
    2726             :             {
    2727           0 :                 Time aTime( 0, 0, 0 );
    2728           0 :                 if ( ImplTimeGetValue( GetText(), aTime, GetFormat(), IsDuration(), ImplGetLocaleDataWrapper(), false ) )
    2729             :                     // even with strict text analysis, our text is a valid time -> do a complete
    2730             :                     // reformat
    2731           0 :                     Reformat();
    2732             :             }
    2733             :         }
    2734             :     }
    2735             : 
    2736           0 :     return SpinField::Notify( rNEvt );
    2737             : }
    2738             : 
    2739           0 : void TimeField::DataChanged( const DataChangedEvent& rDCEvt )
    2740             : {
    2741           0 :     SpinField::DataChanged( rDCEvt );
    2742             : 
    2743           0 :     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
    2744             :     {
    2745           0 :         if ( IsDefaultLocale() )
    2746           0 :             ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
    2747           0 :         ReformatAll();
    2748             :     }
    2749           0 : }
    2750             : 
    2751           0 : void TimeField::Modify()
    2752             : {
    2753           0 :     MarkToBeReformatted( true );
    2754           0 :     SpinField::Modify();
    2755           0 : }
    2756             : 
    2757           0 : void TimeField::Up()
    2758             : {
    2759           0 :     ImplTimeSpinArea( true );
    2760           0 :     SpinField::Up();
    2761           0 : }
    2762             : 
    2763           0 : void TimeField::Down()
    2764             : {
    2765           0 :     ImplTimeSpinArea( false );
    2766           0 :     SpinField::Down();
    2767           0 : }
    2768             : 
    2769           0 : void TimeField::First()
    2770             : {
    2771           0 :     ImplNewFieldValue( maFirst );
    2772           0 :     SpinField::First();
    2773           0 : }
    2774             : 
    2775           0 : void TimeField::Last()
    2776             : {
    2777           0 :     ImplNewFieldValue( maLast );
    2778           0 :     SpinField::Last();
    2779           0 : }
    2780             : 
    2781           0 : void TimeField::SetExtFormat( ExtTimeFieldFormat eFormat )
    2782             : {
    2783           0 :     switch ( eFormat )
    2784             :     {
    2785             :         case EXTTIMEF_24H_SHORT:
    2786             :         {
    2787           0 :             SetTimeFormat( HOUR_24 );
    2788           0 :             SetDuration( false );
    2789           0 :             SetFormat( TIMEF_NONE );
    2790             :         }
    2791           0 :         break;
    2792             :         case EXTTIMEF_24H_LONG:
    2793             :         {
    2794           0 :             SetTimeFormat( HOUR_24 );
    2795           0 :             SetDuration( false );
    2796           0 :             SetFormat( TIMEF_SEC );
    2797             :         }
    2798           0 :         break;
    2799             :         case EXTTIMEF_12H_SHORT:
    2800             :         {
    2801           0 :             SetTimeFormat( HOUR_12 );
    2802           0 :             SetDuration( false );
    2803           0 :             SetFormat( TIMEF_NONE );
    2804             :         }
    2805           0 :         break;
    2806             :         case EXTTIMEF_12H_LONG:
    2807             :         {
    2808           0 :             SetTimeFormat( HOUR_12 );
    2809           0 :             SetDuration( false );
    2810           0 :             SetFormat( TIMEF_SEC );
    2811             :         }
    2812           0 :         break;
    2813             :         case EXTTIMEF_DURATION_SHORT:
    2814             :         {
    2815           0 :             SetDuration( true );
    2816           0 :             SetFormat( TIMEF_NONE );
    2817             :         }
    2818           0 :         break;
    2819             :         case EXTTIMEF_DURATION_LONG:
    2820             :         {
    2821           0 :             SetDuration( true );
    2822           0 :             SetFormat( TIMEF_SEC );
    2823             :         }
    2824           0 :         break;
    2825             :         default:    OSL_FAIL( "ExtTimeFieldFormat unknown!" );
    2826             :     }
    2827             : 
    2828           0 :     if ( GetField() && !GetField()->GetText().isEmpty() )
    2829           0 :         SetUserTime( GetTime() );
    2830           0 :     ReformatAll();
    2831           0 : }
    2832             : 
    2833           0 : TimeBox::TimeBox( Window* pParent, WinBits nWinStyle ) :
    2834           0 :     ComboBox( pParent, nWinStyle )
    2835             : {
    2836           0 :     SetField( this );
    2837           0 :     SetText( ImplGetLocaleDataWrapper().getTime( maFieldTime, false, false ) );
    2838           0 :     Reformat();
    2839           0 : }
    2840             : 
    2841           0 : TimeBox::~TimeBox()
    2842             : {
    2843           0 : }
    2844             : 
    2845           0 : bool TimeBox::PreNotify( NotifyEvent& rNEvt )
    2846             : {
    2847           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
    2848             :     {
    2849           0 :         if ( ImplTimeProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsDuration(), GetFormat(), ImplGetLocaleDataWrapper() ) )
    2850           0 :             return true;
    2851             :     }
    2852             : 
    2853           0 :     return ComboBox::PreNotify( rNEvt );
    2854             : }
    2855             : 
    2856           0 : bool TimeBox::Notify( NotifyEvent& rNEvt )
    2857             : {
    2858           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
    2859           0 :         MarkToBeReformatted( false );
    2860           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
    2861             :     {
    2862           0 :         if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
    2863           0 :             Reformat();
    2864             :     }
    2865             : 
    2866           0 :     return ComboBox::Notify( rNEvt );
    2867             : }
    2868             : 
    2869           0 : void TimeBox::DataChanged( const DataChangedEvent& rDCEvt )
    2870             : {
    2871           0 :     ComboBox::DataChanged( rDCEvt );
    2872             : 
    2873           0 :     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
    2874             :     {
    2875           0 :         if ( IsDefaultLocale() )
    2876           0 :             ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
    2877           0 :         ReformatAll();
    2878             :     }
    2879           0 : }
    2880             : 
    2881           0 : void TimeBox::Modify()
    2882             : {
    2883           0 :     MarkToBeReformatted( true );
    2884           0 :     ComboBox::Modify();
    2885           0 : }
    2886             : 
    2887           0 : void TimeBox::ReformatAll()
    2888             : {
    2889           0 :     OUString aStr;
    2890           0 :     SetUpdateMode( false );
    2891           0 :     sal_uInt16 nEntryCount = GetEntryCount();
    2892           0 :     for ( sal_uInt16 i=0; i < nEntryCount; i++ )
    2893             :     {
    2894           0 :         ImplTimeReformat( GetEntry( i ), aStr );
    2895           0 :         RemoveEntryAt(i);
    2896           0 :         InsertEntry( aStr, i );
    2897             :     }
    2898           0 :     TimeFormatter::Reformat();
    2899           0 :     SetUpdateMode( true );
    2900           0 : }
    2901             : 
    2902             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10