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

Generated by: LCOV version 1.10