merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / items1 / frqitem.cxx
blobd360592c86589752fe4145c2f73ac5086b1eb997
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: frqitem.cxx,v $
10 * $Revision: 1.8.136.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #ifndef GCC
34 #endif
36 #include <unotools/intlwrapper.hxx>
38 #include <tools/stream.hxx>
39 #include <tools/debug.hxx>
40 #include <tools/datetime.hxx>
42 #include <svtools/frqitem.hxx>
44 DBG_NAME( SfxFrequencyItem )
46 TYPEINIT1( SfxFrequencyItem, SfxPoolItem );
48 #define MAX_GOTO 32000
50 #define DECL_SAVE_GOTO() \
51 ULONG nSafetyMeasures = 0;
53 #define SAVE_GOTO(tag) \
54 if(nSafetyMeasures < MAX_GOTO) \
55 { nSafetyMeasures++; goto tag; }
57 // -----------------------------------------------------------------------
59 SfxFrequencyItem::SfxFrequencyItem( USHORT which ) :
60 SfxPoolItem ( which ),
61 eFrqMode ( FRQ_DAILY ),
62 eFrqTimeMode ( FRQ_TIME_AT ),
63 nDInterval1 ( 1 ),
64 nDInterval2 ( 0 ),
65 nDInterval3 ( 0 ),
66 nTInterval1 ( 1 ),
67 aTime1 ( Time( 12, 0, 0 ) ),
68 aTime2 ( Time( 12, 0, 0 ) ),
69 bMissingDate ( FALSE ),
70 aMissingDate ( DateTime(0, 0) )
72 DBG_CTOR( SfxFrequencyItem, 0 );
75 // -----------------------------------------------------------------------
77 SfxFrequencyItem::SfxFrequencyItem( USHORT which, FrequencyMode eMode, FrequencyTimeMode eTMode,
78 USHORT nDI1, USHORT nDI2, USHORT nDI3, USHORT nTI1,
79 const Time& rT1, const Time& rT2 ) :
80 SfxPoolItem ( which ),
81 eFrqMode ( eMode ),
82 eFrqTimeMode ( eTMode ),
83 nDInterval1 ( nDI1 ),
84 nDInterval2 ( nDI2 ),
85 nDInterval3 ( nDI3 ),
86 nTInterval1 ( nTI1 ),
87 aTime1 ( rT1 ),
88 aTime2 ( rT2 ),
89 bMissingDate ( FALSE )
91 DBG_CTOR( SfxFrequencyItem, 0 );
94 // -----------------------------------------------------------------------
96 SfxFrequencyItem::SfxFrequencyItem( const SfxFrequencyItem& rItem ) :
97 SfxPoolItem ( rItem ),
98 eFrqMode ( rItem.eFrqMode ),
99 eFrqTimeMode ( rItem.eFrqTimeMode ),
100 nDInterval1 ( rItem.nDInterval1 ),
101 nDInterval2 ( rItem.nDInterval2 ),
102 nDInterval3 ( rItem.nDInterval3 ),
103 nTInterval1 ( rItem.nTInterval1 ),
104 aTime1 ( rItem.aTime1 ),
105 aTime2 ( rItem.aTime2 ),
106 bMissingDate ( rItem.bMissingDate )
108 DBG_CTOR( SfxFrequencyItem, 0 );
111 // -----------------------------------------------------------------------
113 int SfxFrequencyItem::operator==( const SfxPoolItem& rItem ) const
115 DBG_CHKTHIS( SfxFrequencyItem, 0 );
116 DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
118 return ((SfxFrequencyItem&)rItem ).eFrqMode == eFrqMode &&
119 ((SfxFrequencyItem&)rItem ).eFrqTimeMode == eFrqTimeMode &&
120 ((SfxFrequencyItem&)rItem ).nDInterval1 == nDInterval1 &&
121 ((SfxFrequencyItem&)rItem ).nDInterval2 == nDInterval2 &&
122 ((SfxFrequencyItem&)rItem ).nDInterval3 == nDInterval3 &&
123 ((SfxFrequencyItem&)rItem ).nTInterval1 == nTInterval1 &&
124 ((SfxFrequencyItem&)rItem ).aTime1 == aTime1 &&
125 ((SfxFrequencyItem&)rItem ).aTime2 == aTime2;
128 // -----------------------------------------------------------------------
130 int SfxFrequencyItem::Compare( const SfxPoolItem&
131 #ifdef DBG_UTIL
132 rItem
133 #endif
134 ) const
136 DBG_CHKTHIS( SfxFrequencyItem, 0 );
137 DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
139 /* DateTime aThisRange( aEndDateTime - aStartDateTime );
140 DateTime aRange(((const SfxFrequencyItem&)rItem).aEndDateTime -
141 ((const SfxFrequencyItem&)rItem).aStartDateTime );
142 if( aRange < aThisRange )
143 return -1;
144 else if( aRange == aThisRange )
145 return 0;
146 else
148 return 1;
151 // -----------------------------------------------------------------------
153 SfxPoolItem* SfxFrequencyItem::Create( SvStream& rStream, USHORT ) const
155 DBG_CHKTHIS(SfxFrequencyItem, 0);
157 USHORT _eFrqMode;
158 USHORT _eFrqTimeMode;
159 USHORT _nDInterval1;
160 USHORT _nDInterval2;
161 USHORT _nDInterval3;
162 USHORT _nTInterval1;
163 long _nTime1;
164 long _nTime2;
166 rStream >> _eFrqMode;
167 rStream >> _eFrqTimeMode;
168 rStream >> _nDInterval1;
169 rStream >> _nDInterval2;
170 rStream >> _nDInterval3;
171 rStream >> _nTInterval1;
172 rStream >> _nTime1;
173 rStream >> _nTime2;
175 return new SfxFrequencyItem( Which(), (FrequencyMode)_eFrqMode,
176 (FrequencyTimeMode) _eFrqTimeMode, _nDInterval1, _nDInterval2, _nDInterval3,
177 _nTInterval1, Time(_nTime1), Time(_nTime2) );
180 // -----------------------------------------------------------------------
182 SvStream& SfxFrequencyItem::Store( SvStream& rStream, USHORT ) const
184 DBG_CHKTHIS( SfxFrequencyItem, 0 );
186 USHORT nEMode = (USHORT)eFrqMode;
187 USHORT nETimeMode = (USHORT)eFrqTimeMode;
189 rStream << (USHORT) nEMode;
190 rStream << (USHORT) nETimeMode;
192 rStream << nDInterval1;
193 rStream << nDInterval2;
194 rStream << nDInterval3;
196 rStream << nTInterval1;
197 rStream << aTime1.GetTime();
198 rStream << aTime2.GetTime();
200 return rStream;
203 // -----------------------------------------------------------------------
205 SfxPoolItem* SfxFrequencyItem::Clone( SfxItemPool* ) const
207 DBG_CHKTHIS( SfxFrequencyItem, 0 );
208 return new SfxFrequencyItem( *this );
211 // -----------------------------------------------------------------------
213 SfxItemPresentation SfxFrequencyItem::GetPresentation
215 SfxItemPresentation /*ePresentation*/,
216 SfxMapUnit /*eCoreMetric*/,
217 SfxMapUnit /*ePresentationMetric*/,
218 XubString& rText,
219 const IntlWrapper *
220 ) const
222 DBG_CHKTHIS(SfxFrequencyItem, 0);
223 rText.AssignAscii(RTL_CONSTASCII_STRINGPARAM("SNIY"));
224 return SFX_ITEM_PRESENTATION_NAMELESS;
227 // -----------------------------------------------------------------------
229 Time SfxFrequencyItem::_CalcTime( BOOL bForToday ) const
231 Time aNow;
232 Time aTime;
234 DECL_SAVE_GOTO();
236 switch( eFrqTimeMode )
238 //////////////////////////////////////////////////////////
239 // FRQ_TIME_AT
241 // Update um Uhrzeit
242 // nTime1 = 00:00:00 - 24:00:00
244 case FRQ_TIME_AT :
245 aTime = aTime1;
246 break;
248 //////////////////////////////////////////////////////////
249 // FRQ_TIME_REPEAT
251 // Wiederhole alle X Stunden
252 // nTInterval1 = 1 .. 8
254 case FRQ_TIME_REPEAT :
255 aTime = Time( 0, 0 );
256 if( bForToday )
259 RECALC_TIME_REPEAT:
260 if( aNow > aTime )
262 aTime += Time( nTInterval1, 0 );
263 SAVE_GOTO( RECALC_TIME_REPEAT );
265 break;
267 break;
269 //////////////////////////////////////////////////////////
270 // FRQ_TIME_REPEAT_RANGE
272 // FRQ_TIME_REPEAT zwischen Uhrzeit 1 und 2
273 // nTime1 = 00:00:00 - 24:00:00
274 // nTime2 = 00:00:00 - 24:00:00
276 case FRQ_TIME_REPEAT_RANGE :
277 aTime = aTime1;
278 if( bForToday )
280 if( aNow > aTime2 )
281 return aTime1;
283 RECALC_TIME_REPEAT_RANGE:
284 if( aNow > aTime )
286 aTime += Time( nTInterval1, 0 );
287 if( aTime > aTime2 )
288 return aTime1;
289 SAVE_GOTO( RECALC_TIME_REPEAT_RANGE );
291 break;
293 break;
295 return aTime;
298 DateTime SfxFrequencyItem::CalcNextTick( const DateTime& rBase, BOOL bFirst )
300 Date aDateToday;
301 Time aTimeToday;
302 Date aDateBase;
303 Time aTimeBase;
305 if( bFirst )
307 aDateBase = Date( 17, 2, 1969 );
308 aTimeBase = Time( 8, 0, 0 );
310 else
312 aDateBase = rBase.GetDate();
313 aTimeBase = rBase.GetTime();
316 Time aNextTime( _CalcTime(FALSE) );
317 Date aNextDate( aDateBase );
318 bMissingDate = FALSE;
320 DECL_SAVE_GOTO();
322 switch( eFrqMode )
324 //////////////////////////////////////////////////////////
325 // FRQ_DAILY
327 // jeden X'ten Tag
328 // nInterval1 = 1 .. 999
330 // jeden Wochentag
331 // nInterval1 = USHRT_MAX
333 case FRQ_DAILY :
335 if( bFirst )
337 aNextTime = _CalcTime( TRUE );
338 if( aNextTime < aTimeToday )
340 aNextTime = _CalcTime( FALSE );
341 aNextDate = aDateToday + (USHORT)
342 ((nDInterval1 == USHRT_MAX)? 1 : nDInterval1);
344 else
345 aNextDate = aDateToday;
346 break;
349 RECALC_FRQ_DAILY:
350 if( aNextDate < aDateToday )
352 bMissingDate = TRUE;
353 aMissingDate.SetDate(aNextDate.GetDate());
354 aMissingDate.SetTime(_CalcTime(FALSE).GetTime());
356 aNextDate += (USHORT)((nDInterval1 == USHRT_MAX)? 1 : nDInterval1);
357 SAVE_GOTO( RECALC_FRQ_DAILY );
360 if( aNextDate == aDateToday )
362 aNextTime = _CalcTime( TRUE );
363 if( aNextTime < aTimeToday )
365 bMissingDate = TRUE;
366 aMissingDate.SetDate(aNextDate.GetDate());
367 aMissingDate.SetTime(_CalcTime(FALSE).GetTime());
369 aNextDate += (USHORT)((nDInterval1 == USHRT_MAX)? 1 : nDInterval1);
370 aNextTime = _CalcTime( FALSE );
373 else
374 aNextTime = _CalcTime( FALSE );
375 } break;
377 //////////////////////////////////////////////////////////
378 // FRQ_WEEKLY
379 // wiederhole jede X'te Woche
380 // nInterval1 = 1 .. 99
382 // an SU, MO, TU, WE, TH, FR, SA
383 // nInterval2 = WD_SUNDAY | WD_MONDAY | WD_TUESDAY |
384 // WD_WEDNESDAY | WD_THURSDAY | WD_FRIDAY |
385 // WD_SATURDAY
387 case FRQ_WEEKLY :
389 BOOL bInRecalc = FALSE;
391 RECALC_FRQ_WEEKLY:
392 if( !bFirst || bInRecalc )
393 aNextDate += (nDInterval1 - 1) * 7;
395 aNextDate -= (USHORT) ((aNextDate.GetDayOfWeek() != SUNDAY) ?
396 aNextDate.GetDayOfWeek() + 1 : 0);
398 if( nDInterval2 & WD_SUNDAY && (aNextDate >= aDateToday) )
399 aNextDate += 0;
400 else if( nDInterval2 & WD_MONDAY && (aNextDate + 1 >= aDateToday) )
401 aNextDate += 1;
402 else if( nDInterval2 & WD_TUESDAY && (aNextDate + 2 >= aDateToday) )
403 aNextDate += 2;
404 else if( nDInterval2 & WD_WEDNESDAY && (aNextDate + 3 >= aDateToday) )
405 aNextDate += 3;
406 else if( nDInterval2 & WD_THURSDAY && (aNextDate + 4 >= aDateToday) )
407 aNextDate += 4;
408 else if( nDInterval2 & WD_FRIDAY && (aNextDate + 5 >= aDateToday) )
409 aNextDate += 5;
410 else if( nDInterval2 & WD_SATURDAY && (aNextDate + 6 >= aDateToday) )
411 aNextDate += 6;
413 if( aNextDate < aDateToday )
415 bMissingDate = TRUE;
416 aMissingDate.SetDate(aNextDate.GetDate());
417 aMissingDate.SetTime(_CalcTime(FALSE).GetTime());
419 bInRecalc = TRUE;
420 aNextDate += 7;
421 SAVE_GOTO( RECALC_FRQ_WEEKLY );
423 if( aNextDate == aDateToday )
425 aNextTime = _CalcTime( TRUE );
426 if( aNextTime < aTimeToday )
428 bInRecalc = TRUE;
429 aNextDate += 7;
430 SAVE_GOTO( RECALC_FRQ_WEEKLY );
433 else
434 aNextTime = _CalcTime( FALSE );
435 } break;
437 //////////////////////////////////////////////////////////
438 // FRQ_MONTHLY_DAILY
440 // jeden X'ten Tag von jedem X'ten Monat
441 // nInterval1 = 1 .. 31
442 // nInterval2 = 1 .. 6
444 case FRQ_MONTHLY_DAILY :
446 BOOL bInRecalc = FALSE;
447 aNextDate.SetDay( nDInterval1 );
449 RECALC_FRQ_MONTHLY_DAILY:
450 if( nDInterval2 > 1 || bInRecalc )
452 long nMonth = aNextDate.GetMonth() - 1;
453 nMonth += nDInterval2;
454 aNextDate.SetYear(
455 sal::static_int_cast< USHORT >(
456 aNextDate.GetYear() + nMonth / 12 ) );
457 aNextDate.SetMonth(
458 sal::static_int_cast< USHORT >( ( nMonth % 12 ) + 1 ) );
461 if( aNextDate < aDateToday )
463 bMissingDate = TRUE;
464 aMissingDate.SetDate(aNextDate.GetDate());
465 aMissingDate.SetTime(_CalcTime(FALSE).GetTime());
467 bInRecalc = TRUE;
468 SAVE_GOTO( RECALC_FRQ_MONTHLY_DAILY );
471 if( aNextDate == aDateToday )
473 aNextTime = _CalcTime( TRUE );
474 if( aNextTime < aTimeToday )
476 bMissingDate = TRUE;
477 aMissingDate.SetDate(aNextDate.GetDate());
478 aMissingDate.SetTime(_CalcTime(FALSE).GetTime());
480 bInRecalc = TRUE;
481 SAVE_GOTO( RECALC_FRQ_MONTHLY_DAILY );
484 else
485 aNextTime = _CalcTime( FALSE );
486 } break;
488 //////////////////////////////////////////////////////////
489 // FRQ_MONTHLY_LOGIC
491 // jeden ersten, zweiten, dritten, vierten oder letzten
492 // Wochentag jeden X'ten Monats
493 // nInterval1 = 0 .. 4
494 // nInterval2 = WD_SUNDAY | WD_MONDAY | WD_TUESDAY |
495 // WD_WEDNESDAY | WD_THURSDAY | WD_FRIDAY |
496 // WD_SATURDAY
497 // nInterval3 = 1 .. 6
499 case FRQ_MONTHLY_LOGIC :
501 BOOL bInRecalc = FALSE;
503 RECALC_FRQ_MONTHLY_LOGIC:
504 if( nDInterval3 > 1 || bInRecalc )
506 long nMonth = aNextDate.GetMonth() - 1;
507 nMonth += nDInterval3;
508 aNextDate.SetYear(
509 sal::static_int_cast< USHORT >(
510 aNextDate.GetYear() + nMonth / 12 ) );
511 aNextDate.SetMonth(
512 sal::static_int_cast< USHORT >( ( nMonth % 12 ) + 1 ) );
515 USHORT nDay;
516 if( nDInterval2 & WD_SUNDAY )
517 nDay = 6;
518 else if( nDInterval2 & WD_MONDAY )
519 nDay = 0;
520 else if( nDInterval2 & WD_TUESDAY )
521 nDay = 1;
522 else if( nDInterval2 & WD_WEDNESDAY )
523 nDay = 2;
524 else if( nDInterval2 & WD_THURSDAY )
525 nDay = 3;
526 else if( nDInterval2 & WD_FRIDAY )
527 nDay = 4;
528 else nDay = 5;
530 if( nDInterval1 == 4 )
532 DateTime aDT = aNextDate;
533 aDT.SetDay( 1 );
534 aDT += (long)(aNextDate.GetDaysInMonth() - 1);
535 if( aDT.GetDayOfWeek() != nDay )
536 for( aDT--; aDT.GetDayOfWeek() != nDay; aDT-- ) ;
537 aNextDate = aDT;
539 else
541 DateTime aDT = aNextDate;
542 aDT.SetDay( 1 );
543 aDT += (long)(nDay - USHORT(aDT.GetDayOfWeek()));
544 if( aDT.GetMonth() != aNextDate.GetMonth() )
545 aDT += 7L;
546 aDT += (long)(nDInterval1 * 7);
547 aNextDate = aDT;
550 if( aNextDate < aDateToday )
552 bMissingDate = TRUE;
553 aMissingDate.SetDate(aNextDate.GetDate());
554 aMissingDate.SetTime(_CalcTime(FALSE).GetTime());
556 bInRecalc = TRUE;
557 SAVE_GOTO( RECALC_FRQ_MONTHLY_LOGIC );
560 if( aNextDate == aDateToday )
562 aNextTime = _CalcTime( TRUE );
563 if( aNextTime < aTimeToday )
565 bMissingDate = TRUE;
566 aMissingDate.SetDate(aNextDate.GetDate());
567 aMissingDate.SetTime(_CalcTime(FALSE).GetTime());
569 bInRecalc = TRUE;
570 SAVE_GOTO( RECALC_FRQ_MONTHLY_LOGIC );
573 else
574 aNextTime = _CalcTime( FALSE );
575 } break;
578 return DateTime( aNextDate, aNextTime );