42 "find a bucket or create a new one"
75 Object::createString<CalendarDouble>,
true);
79 "setValue", setPythonValue, METH_VARARGS | METH_KEYWORDS,
80 "update the value in a date range"
83 getEvents, METH_VARARGS,
"return an event iterator");
102 x.
addMethod(
"toXML",
toXML, METH_VARARGS,
"return a XML representation");
157 pElement >> defaultValue;
168 Bucket* tmp = firstBucket;
169 firstBucket = firstBucket->nextBucket;
176 if (l->getAvailable() ==
this)
177 l->setAvailable(NULL);
187 if (b->getMinimumCalendar()==
this) b->setMinimumCalendar(NULL);
188 if (b->getMaximumCalendar()==
this) b->setMaximumCalendar(NULL);
193 if (r->getMaximumCalendar()==
this) r->setMaximumCalendar(NULL);
202 return createNewBucket(end, start,
id);
204 return createNewBucket(start, end,
id);
212 while (b && b != bkt) b = b->nextBucket;
216 throw DataException(
"Trying to remove unavailable bucket from calendar '"
222 bkt->prevBucket->nextBucket = bkt->nextBucket;
225 firstBucket = bkt->nextBucket;
228 bkt->nextBucket->prevBucket = bkt->prevBucket;
239 throw DataException(
"Calendar bucket end must be later than its start");
250 throw DataException(
"Calendar bucket start must be earlier than its end");
268 nextBucket->startdate < startdate ||
269 (nextBucket->startdate == startdate && nextBucket->priority < priority)
273 if (nextBucket->nextBucket)
274 nextBucket->nextBucket->prevBucket =
this;
276 prevBucket->nextBucket = nextBucket;
278 cal->firstBucket = nextBucket;
279 nextBucket->prevBucket = prevBucket;
280 prevBucket = nextBucket;
282 nextBucket->nextBucket =
this;
286 else if (prevBucket && (
287 prevBucket->startdate > startdate ||
288 (prevBucket->startdate == startdate && prevBucket->priority > priority)
292 if (prevBucket->prevBucket)
293 prevBucket->prevBucket->nextBucket =
this;
295 nextBucket->prevBucket = prevBucket;
296 prevBucket->nextBucket = nextBucket;
297 nextBucket = prevBucket;
299 prevBucket->prevBucket =
this;
311 double curPriority = DBL_MAX;
312 long timeInWeek = INT_MIN;
313 for (
Bucket *b = firstBucket; b; b = b->nextBucket)
315 if (b->getStart() > d)
319 else if (curPriority > b->getPriority()
320 && ( (fwd && d >= b->getStart() && d < b->getEnd()) ||
321 (!fwd && d > b->getStart() && d <= b->getEnd())
324 if (!b->offsetcounter)
333 if (timeInWeek == INT_MIN)
336 timeInWeek = d.getSecondsWeek();
338 if (!fwd && timeInWeek == 0L) timeInWeek = 604800L;
341 for (
short i=0; i<b->offsetcounter; i+=2)
342 if ((fwd && timeInWeek >= b->offsets[i] && timeInWeek < b->offsets[i+1]) ||
343 (!fwd && timeInWeek > b->offsets[i] && timeInWeek <= b->offsets[i+1]))
359 for (
Bucket *b = firstBucket; b; b = b->nextBucket)
360 if (b->id == ident)
return b;
396 Date startdate = *d ? d->
getDate() : Date::infinitePast;
398 Date enddate = *d ? d->
getDate() : Date::infiniteFuture;
400 int id = *d ? d->
getInt() : INT_MIN;
406 switch (MetaClass::decodeAction(atts))
413 o <<
"Bucket " <<
id <<
" already exists in calendar '" <<
getName() <<
"'";
416 result =
addBucket(startdate, enddate,
id);
423 o <<
"Bucket " <<
id <<
" doesn't exist in calendar '" <<
getName() <<
"'";
432 o <<
"Bucket " <<
id <<
" doesn't exist in calendar '" <<
getName() <<
"'";
444 result =
addBucket(startdate, enddate,
id);
465 if (startdate != Date::infinitePast)
467 if (enddate != Date::infiniteFuture)
474 if (enddate != Date::infiniteFuture)
500 pElement >> priority;
502 setDays(pElement.
getInt());
514 throw LogicException(
"Generating calendar bucket without calendar");
516 if (ident == INT_MIN)
520 for (
BucketIterator i = cal->beginBuckets(); i != cal->endBuckets(); ++i)
521 if (i->id >= ident) ident = i->id + 1;
522 if (ident == INT_MIN) ident = 1;
531 for (
BucketIterator i = cal->beginBuckets(); i != cal->endBuckets(); ++i)
532 if (i->id == ident && &(*i) !=
this)
551 throw LogicException(
"Can't walk forward on event iterator of NULL calendar.");
555 curDate = Date::infiniteFuture;
556 for (
const Calendar::Bucket *b = theCalendar->firstBucket; b; b = b->nextBucket)
557 b->nextEvent(
this, d);
560 lastBucket = curBucket;
561 lastPriority = curPriority;
569 throw LogicException(
"Can't walk backward on event iterator of NULL calendar.");
573 curDate = Date::infinitePast;
574 for (
const Calendar::Bucket *b = theCalendar->firstBucket; b; b = b->nextBucket)
575 b->prevEvent(
this, d);
578 lastBucket = curBucket;
579 lastPriority = curPriority;
590 if (refDate < startdate && priority <= iter->lastPriority && (
591 startdate < iter->curDate ||
592 (startdate == iter->
curDate && priority <= iter->curPriority)
602 if (refDate < enddate && enddate <= iter->curDate && iter->
lastBucket ==
this)
617 bool allowEqualAtStart =
false;
618 if (refDate < startdate && (
619 startdate < iter->curDate ||
620 (startdate == iter->
curDate && priority <= iter->curPriority)
624 allowEqualAtStart =
true;
631 for (
short i=0; i<offsetcounter; i+=2)
638 bool canReturn =
true;
662 if ((refDate < st || (allowEqualAtStart && refDate == st)) && priority <= iter->lastPriority)
667 if (canReturn)
break;
674 if (canReturn)
return;
676 if (refDate < nd && iter->lastBucket ==
this)
681 if (canReturn)
break;
689 if (canReturn)
return;
695 DECLARE_EXPORT void Calendar::Bucket::prevEvent(EventIterator* iter,
Date refDate)
const
701 if (refDate > enddate && priority <= iter->lastPriority && (
702 enddate > iter->curDate ||
703 (enddate == iter->curDate && priority < iter->curPriority)
706 iter->curDate = enddate;
707 iter->curBucket =
this;
708 iter->curPriority = priority;
713 if (refDate > startdate && startdate > iter->curDate && iter->lastBucket ==
this)
715 iter->curDate = startdate;
716 iter->curBucket = iter->theCalendar->findBucket(startdate,
false);
717 iter->curPriority = iter->curBucket ? iter->curBucket->priority : INT_MAX;
728 bool allowEqualAtEnd =
false;
729 if (refDate > enddate && (
730 enddate > iter->curDate ||
731 (enddate == iter->curDate && priority < iter->curPriority)
735 allowEqualAtEnd =
true;
742 for (
short i=offsetcounter-1; i>=0; i-=2)
749 bool canReturn =
true;
773 if ((refDate > nd || (allowEqualAtEnd && refDate == nd))
774 && priority <= iter->lastPriority)
776 if (nd < iter->curDate || (nd == iter->curDate && priority <= iter->curPriority))
779 if (canReturn)
break;
784 iter->curBucket =
this;
785 if (canReturn)
return;
787 if (refDate > st && iter->lastBucket ==
this)
789 if (st < iter->curDate || (st == iter->curDate && priority <= iter->curPriority))
792 if (canReturn)
break;
798 iter->curBucket = iter->theCalendar->findBucket(st,
false);
799 iter->curPriority = iter->curBucket ? iter->curBucket->priority : INT_MAX;
800 if (canReturn)
return;
850 if (!cal)
throw LogicException(
"Can't set value of a NULL calendar");
853 PyObject *pystart, *pyend, *pyval;
854 if (!PyArg_ParseTuple(args,
"OOO:setValue", &pystart, &pyend, &pyval))
863 PythonType::evalException();
866 return Py_BuildValue(
"");
876 if (!cal)
throw LogicException(
"Can't set value of a NULL calendar");
880 if (!PyArg_ParseTuple(args,
"|i:addBucket", &
id))
885 if (!b) b = cal->
addBucket(Date::infinitePast, Date::infiniteFuture,
id);
893 PythonType::evalException();
896 return Py_BuildValue(
"");
904 x.
setName(
"calendarBucketIterator");
905 x.
setDoc(
"frePPLe iterator for calendar buckets");
911 PyObject* CalendarBucketIterator::iternext()
913 if (i == cal->endBuckets())
return NULL;
914 PyObject *result = &*(i++);
929 return PythonObject(dynamic_cast< CalendarDouble::BucketDouble* >(
this)->getValue());
958 setPriority(field.
getInt());
968 dynamic_cast< CalendarDouble::BucketDouble* >(
this)->setValue(field.
getDouble());
982 PyObject*
self, PyObject* args
991 cal = static_cast<CalendarDouble*>(
self);
996 PyObject* pystart = NULL;
997 PyObject* pydirection = NULL;
998 if (!PyArg_ParseTuple(args,
"|OO:setvalue", &pystart, &pydirection))
1008 PythonType::evalException();
1018 x.
setName(
"calendarEventIterator");
1019 x.
setDoc(
"frePPLe iterator for calendar events");
1025 PyObject* CalendarEventIterator::iternext()
1027 if ((forward && eventiter.getDate() == Date::infiniteFuture)
1028 || (!forward && eventiter.getDate() == Date::infinitePast))
1031 if (dynamic_cast<CalendarDouble*>(cal))
1033 if (eventiter.getBucket())
1034 x =
PythonObject(dynamic_cast<const CalendarDouble::BucketDouble*>(eventiter.getBucket())->getValue());
1036 x =
PythonObject(dynamic_cast<CalendarDouble*>(cal)->getDefault());
1041 PyObject* result = Py_BuildValue(
"(N,N)",
1042 static_cast<PyObject*>(
PythonObject(eventiter.getDate())),
1043 static_cast<PyObject*
>(x)
1055 if (days==127 && !starttime && endtime==
TimePeriod(86400L))
1064 for (
short i=0; i<=6; ++i)
1069 if (offsetcounter>=1 && (offsets[offsetcounter] == 86400*i + starttime))
1073 offsets[offsetcounter] = 86400*i + endtime;
1077 offsets[++offsetcounter] = 86400*i + starttime;
1078 offsets[++offsetcounter] = 86400*i + endtime;
1086 if (offsetcounter >= 1 && offsets[0]==0 && offsets[offsetcounter]==86400*7)
1088 offsets[0] = offsets[offsetcounter-1] - 86400*7;
1089 offsets[offsetcounter] = 86400*7 + offsets[1];