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: */
|