1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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"
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
),
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
),
82 eFrqTimeMode ( eTMode
),
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
&
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 )
144 else if( aRange == aThisRange )
151 // -----------------------------------------------------------------------
153 SfxPoolItem
* SfxFrequencyItem::Create( SvStream
& rStream
, USHORT
) const
155 DBG_CHKTHIS(SfxFrequencyItem
, 0);
158 USHORT _eFrqTimeMode
;
166 rStream
>> _eFrqMode
;
167 rStream
>> _eFrqTimeMode
;
168 rStream
>> _nDInterval1
;
169 rStream
>> _nDInterval2
;
170 rStream
>> _nDInterval3
;
171 rStream
>> _nTInterval1
;
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();
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*/,
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
236 switch( eFrqTimeMode
)
238 //////////////////////////////////////////////////////////
242 // nTime1 = 00:00:00 - 24:00:00
248 //////////////////////////////////////////////////////////
251 // Wiederhole alle X Stunden
252 // nTInterval1 = 1 .. 8
254 case FRQ_TIME_REPEAT
:
255 aTime
= Time( 0, 0 );
262 aTime
+= Time( nTInterval1
, 0 );
263 SAVE_GOTO( RECALC_TIME_REPEAT
);
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
:
283 RECALC_TIME_REPEAT_RANGE
:
286 aTime
+= Time( nTInterval1
, 0 );
289 SAVE_GOTO( RECALC_TIME_REPEAT_RANGE
);
298 DateTime
SfxFrequencyItem::CalcNextTick( const DateTime
& rBase
, BOOL bFirst
)
307 aDateBase
= Date( 17, 2, 1969 );
308 aTimeBase
= Time( 8, 0, 0 );
312 aDateBase
= rBase
.GetDate();
313 aTimeBase
= rBase
.GetTime();
316 Time
aNextTime( _CalcTime(FALSE
) );
317 Date
aNextDate( aDateBase
);
318 bMissingDate
= FALSE
;
324 //////////////////////////////////////////////////////////
328 // nInterval1 = 1 .. 999
331 // nInterval1 = USHRT_MAX
337 aNextTime
= _CalcTime( TRUE
);
338 if( aNextTime
< aTimeToday
)
340 aNextTime
= _CalcTime( FALSE
);
341 aNextDate
= aDateToday
+ (USHORT
)
342 ((nDInterval1
== USHRT_MAX
)? 1 : nDInterval1
);
345 aNextDate
= aDateToday
;
350 if( aNextDate
< aDateToday
)
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
)
366 aMissingDate
.SetDate(aNextDate
.GetDate());
367 aMissingDate
.SetTime(_CalcTime(FALSE
).GetTime());
369 aNextDate
+= (USHORT
)((nDInterval1
== USHRT_MAX
)? 1 : nDInterval1
);
370 aNextTime
= _CalcTime( FALSE
);
374 aNextTime
= _CalcTime( FALSE
);
377 //////////////////////////////////////////////////////////
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 |
389 BOOL bInRecalc
= FALSE
;
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
) )
400 else if( nDInterval2
& WD_MONDAY
&& (aNextDate
+ 1 >= aDateToday
) )
402 else if( nDInterval2
& WD_TUESDAY
&& (aNextDate
+ 2 >= aDateToday
) )
404 else if( nDInterval2
& WD_WEDNESDAY
&& (aNextDate
+ 3 >= aDateToday
) )
406 else if( nDInterval2
& WD_THURSDAY
&& (aNextDate
+ 4 >= aDateToday
) )
408 else if( nDInterval2
& WD_FRIDAY
&& (aNextDate
+ 5 >= aDateToday
) )
410 else if( nDInterval2
& WD_SATURDAY
&& (aNextDate
+ 6 >= aDateToday
) )
413 if( aNextDate
< aDateToday
)
416 aMissingDate
.SetDate(aNextDate
.GetDate());
417 aMissingDate
.SetTime(_CalcTime(FALSE
).GetTime());
421 SAVE_GOTO( RECALC_FRQ_WEEKLY
);
423 if( aNextDate
== aDateToday
)
425 aNextTime
= _CalcTime( TRUE
);
426 if( aNextTime
< aTimeToday
)
430 SAVE_GOTO( RECALC_FRQ_WEEKLY
);
434 aNextTime
= _CalcTime( FALSE
);
437 //////////////////////////////////////////////////////////
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
;
455 sal::static_int_cast
< USHORT
>(
456 aNextDate
.GetYear() + nMonth
/ 12 ) );
458 sal::static_int_cast
< USHORT
>( ( nMonth
% 12 ) + 1 ) );
461 if( aNextDate
< aDateToday
)
464 aMissingDate
.SetDate(aNextDate
.GetDate());
465 aMissingDate
.SetTime(_CalcTime(FALSE
).GetTime());
468 SAVE_GOTO( RECALC_FRQ_MONTHLY_DAILY
);
471 if( aNextDate
== aDateToday
)
473 aNextTime
= _CalcTime( TRUE
);
474 if( aNextTime
< aTimeToday
)
477 aMissingDate
.SetDate(aNextDate
.GetDate());
478 aMissingDate
.SetTime(_CalcTime(FALSE
).GetTime());
481 SAVE_GOTO( RECALC_FRQ_MONTHLY_DAILY
);
485 aNextTime
= _CalcTime( FALSE
);
488 //////////////////////////////////////////////////////////
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 |
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
;
509 sal::static_int_cast
< USHORT
>(
510 aNextDate
.GetYear() + nMonth
/ 12 ) );
512 sal::static_int_cast
< USHORT
>( ( nMonth
% 12 ) + 1 ) );
516 if( nDInterval2
& WD_SUNDAY
)
518 else if( nDInterval2
& WD_MONDAY
)
520 else if( nDInterval2
& WD_TUESDAY
)
522 else if( nDInterval2
& WD_WEDNESDAY
)
524 else if( nDInterval2
& WD_THURSDAY
)
526 else if( nDInterval2
& WD_FRIDAY
)
530 if( nDInterval1
== 4 )
532 DateTime aDT
= aNextDate
;
534 aDT
+= (long)(aNextDate
.GetDaysInMonth() - 1);
535 if( aDT
.GetDayOfWeek() != nDay
)
536 for( aDT
--; aDT
.GetDayOfWeek() != nDay
; aDT
-- ) ;
541 DateTime aDT
= aNextDate
;
543 aDT
+= (long)(nDay
- USHORT(aDT
.GetDayOfWeek()));
544 if( aDT
.GetMonth() != aNextDate
.GetMonth() )
546 aDT
+= (long)(nDInterval1
* 7);
550 if( aNextDate
< aDateToday
)
553 aMissingDate
.SetDate(aNextDate
.GetDate());
554 aMissingDate
.SetTime(_CalcTime(FALSE
).GetTime());
557 SAVE_GOTO( RECALC_FRQ_MONTHLY_LOGIC
);
560 if( aNextDate
== aDateToday
)
562 aNextTime
= _CalcTime( TRUE
);
563 if( aNextTime
< aTimeToday
)
566 aMissingDate
.SetDate(aNextDate
.GetDate());
567 aMissingDate
.SetTime(_CalcTime(FALSE
).GetTime());
570 SAVE_GOTO( RECALC_FRQ_MONTHLY_LOGIC
);
574 aNextTime
= _CalcTime( FALSE
);
578 return DateTime( aNextDate
, aNextTime
);