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