-rw-r--r-- | library/datebookdb.cpp | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/library/datebookdb.cpp b/library/datebookdb.cpp index e4ec2bf..165a637 100644 --- a/library/datebookdb.cpp +++ b/library/datebookdb.cpp @@ -137,512 +137,515 @@ bool nextOccurance(const Event &e, const QDate &from, QDateTime &next) return TRUE; case Event::MonthlyDay: iday = from.day(); iyear = from.year(); imonth = from.month(); /* find equivelent day of month for this month */ dayOfWeek = e.start().date().dayOfWeek(); weekOfMonth = (e.start().date().day() - 1) / 7; /* work out when the next valid month is */ a = from.year() - e.start().date().year(); a *= 12; a = a + (imonth - e.start().date().month()); /* a is e.start()monthsFrom(from); */ if(a % freq) { a = freq - (a % freq); imonth = from.month() + a; if (imonth > 12) { imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; } } /* imonth is now the first month after or on from that matches the frequency given */ /* find for this month */ tmpDate = QDate( iyear, imonth, 1 ); iday = 1; iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; iday += 7 * weekOfMonth; while (iday > tmpDate.daysInMonth()) { imonth += freq; if (imonth > 12) { imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; } tmpDate = QDate( iyear, imonth, 1 ); /* these loops could go for a while, check end case now */ if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) return FALSE; iday = 1; iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; iday += 7 * weekOfMonth; } tmpDate = QDate(iyear, imonth, iday); if (tmpDate >= from) { next = QDateTime(tmpDate, e.start().time()); if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) return FALSE; return TRUE; } /* need to find the next iteration */ do { imonth += freq; if (imonth > 12) { imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; } tmpDate = QDate( iyear, imonth, 1 ); /* these loops could go for a while, check end case now */ if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) return FALSE; iday = 1; iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; iday += 7 * weekOfMonth; } while (iday > tmpDate.daysInMonth()); tmpDate = QDate(iyear, imonth, iday); next = QDateTime(tmpDate, e.start().time()); if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) return FALSE; return TRUE; case Event::MonthlyDate: iday = e.start().date().day(); iyear = from.year(); imonth = from.month(); a = from.year() - e.start().date().year(); a *= 12; a = a + (imonth - e.start().date().month()); /* a is e.start()monthsFrom(from); */ if(a % freq) { a = freq - (a % freq); imonth = from.month() + a; if (imonth > 12) { imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; } } /* imonth is now the first month after or on from that matches the frequencey given */ /* this could go for a while, worse case, 4*12 iterations, probably */ while(!QDate::isValid(iyear, imonth, iday) ) { imonth += freq; if (imonth > 12) { imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; } /* these loops could go for a while, check end case now */ if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) return FALSE; } if(QDate(iyear, imonth, iday) >= from) { /* done */ next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) return FALSE; return TRUE; } /* ok, need to cycle */ imonth += freq; imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; while(!QDate::isValid(iyear, imonth, iday) ) { imonth += freq; imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) return FALSE; } next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) return FALSE; return TRUE; case Event::Yearly: iday = e.start().date().day(); imonth = e.start().date().month(); iyear = from.year(); // after all, we want to start in this year diff = 1; if(imonth == 2 && iday > 28) { /* leap year, and it counts, calculate actual frequency */ if(freq % 4) if (freq % 2) freq = freq * 4; else freq = freq * 2; /* else divides by 4 already, leave freq alone */ diff = 4; } a = from.year() - e.start().date().year(); if(a % freq) { a = freq - (a % freq); iyear = iyear + a; } /* under the assumption we won't hit one of the special not-leap years twice */ if(!QDate::isValid(iyear, imonth, iday)) { /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ iyear += freq; } if(QDate(iyear, imonth, iday) >= from) { next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) return FALSE; return TRUE; } /* iyear == from.year(), need to advance again */ iyear += freq; /* under the assumption we won't hit one of the special not-leap years twice */ if(!QDate::isValid(iyear, imonth, iday)) { /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ iyear += freq; } next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) return FALSE; return TRUE; default: return FALSE; } } static bool nextAlarm( const Event &ev, QDateTime& when, int& warn) { QDateTime now = QDateTime::currentDateTime(); if ( ev.hasRepeat() ) { QDateTime ralarm; if (nextOccurance(ev, now.date(), ralarm)) { ralarm = ralarm.addSecs(-ev.alarmTime()*60); if ( ralarm > now ) { when = ralarm; warn = ev.alarmTime(); } else if ( nextOccurance(ev, now.date().addDays(1), ralarm) ) { ralarm = ralarm.addSecs( -ev.alarmTime()*60 ); if ( ralarm > now ) { when = ralarm; warn = ev.alarmTime(); } } } } else { warn = ev.alarmTime(); when = ev.start().addSecs( -ev.alarmTime()*60 ); } return when > now; } static void addEventAlarm( const Event &ev ) { QDateTime when; int warn; if ( nextAlarm(ev,when,warn) ) AlarmServer::addAlarm( when, "QPE/Application/datebook", "alarm(QDateTime,int)", warn ); } static void delEventAlarm( const Event &ev ) { QDateTime when; int warn; if ( nextAlarm(ev,when,warn) ) AlarmServer::deleteAlarm( when, "QPE/Application/datebook", "alarm(QDateTime,int)", warn ); } DateBookDB::DateBookDB() { init(); } DateBookDB::~DateBookDB() { save(); eventList.clear(); repeatEvents.clear(); + + delete d; + d=0; } //#### Why is this code duplicated in getEffectiveEvents ????? //#### Addendum. Don't use this function, lets faze it out if we can. QValueList<Event> DateBookDB::getEvents( const QDate &from, const QDate &to ) { QValueList<Event> tmpList; tmpList = getNonRepeatingEvents( from, to ); // check for repeating events... for (QValueList<Event>::ConstIterator it = repeatEvents.begin(); it != repeatEvents.end(); ++it) { QDate itDate = from; QDateTime due; /* create a false end date, to short circuit on hard MonthlyDay recurences */ Event dummy_event = *it; Event::RepeatPattern r = dummy_event.repeatPattern(); if ( !r.hasEndDate || r.endDate() > to ) { r.setEndDate( to ); r.hasEndDate = TRUE; } dummy_event.setRepeat(TRUE, r); while (nextOccurance(dummy_event, itDate, due)) { if (due.date() > to) break; Event newEvent = *it; newEvent.setStart(due); newEvent.setEnd(due.addSecs((*it).start().secsTo((*it).end()))); tmpList.append(newEvent); itDate = due.date().addDays(1); /* the next event */ } } qHeapSort(tmpList); return tmpList; } QValueList<Event> DateBookDB::getEvents( const QDateTime &start ) { QValueList<Event> day = getEvents(start.date(),start.date()); QValueListConstIterator<Event> it; QDateTime dtTmp; QValueList<Event> tmpList; for (it = day.begin(); it != day.end(); ++it ) { dtTmp = (*it).start(TRUE); if ( dtTmp == start ) tmpList.append( *it ); } return tmpList; } //#### Why is this code duplicated in getEvents ????? QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDate &from, const QDate &to ) { QValueList<EffectiveEvent> tmpList; QValueListIterator<Event> it; EffectiveEvent effEv; QDateTime dtTmp, dtEnd; for (it = eventList.begin(); it != eventList.end(); ++it ) { if (!(*it).isValidUid()) (*it).assignUid(); // FIXME: Hack to restore cleared uids dtTmp = (*it).start(TRUE); dtEnd = (*it).end(TRUE); if ( dtTmp.date() >= from && dtTmp.date() <= to ) { Event tmpEv = *it; effEv.setEvent(tmpEv); effEv.setDate( dtTmp.date() ); effEv.setStart( dtTmp.time() ); if ( dtTmp.date() != dtEnd.date() ) effEv.setEnd( QTime(23, 59, 0) ); else effEv.setEnd( dtEnd.time() ); tmpList.append( effEv ); } // we must also check for end date information... if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) { QDateTime dt = dtTmp.addDays( 1 ); dt.setTime( QTime(0, 0, 0) ); QDateTime dtStop; if ( dtEnd > to ) { dtStop = to; } else dtStop = dtEnd; while ( dt <= dtStop ) { Event tmpEv = *it; effEv.setEvent( tmpEv ); effEv.setDate( dt.date() ); if ( dt >= from ) { effEv.setStart( QTime(0, 0, 0) ); if ( dt.date() == dtEnd.date() ) effEv.setEnd( dtEnd.time() ); else effEv.setEnd( QTime(23, 59, 59) ); tmpList.append( effEv ); } dt = dt.addDays( 1 ); } } } // check for repeating events... QDateTime repeat; for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { if (!(*it).isValidUid()) (*it).assignUid(); // FIXME: Hack to restore cleared uids /* create a false end date, to short circuit on hard MonthlyDay recurences */ Event dummy_event = *it; int duration = (*it).start().date().daysTo( (*it).end().date() ); QDate itDate = from.addDays(-duration); Event::RepeatPattern r = dummy_event.repeatPattern(); if ( !r.hasEndDate || r.endDate() > to ) { r.setEndDate( to ); r.hasEndDate = TRUE; } dummy_event.setRepeat(TRUE, r); while (nextOccurance(dummy_event, itDate, repeat)) { if(repeat.date() > to) break; effEv.setDate( repeat.date() ); if ((*it).type() == Event::AllDay) { effEv.setStart( QTime(0,0,0) ); effEv.setEnd( QTime(23,59,59) ); } else { /* we only occur by days, not hours/minutes/seconds. Hence the actual end and start times will be the same for every repeated event. For multi day events this is fixed up later if on wronge day span */ effEv.setStart( (*it).start().time() ); effEv.setEnd( (*it).end().time() ); } if ( duration != 0 ) { // multi-day repeating events QDate sub_it = QMAX( repeat.date(), from ); QDate startDate = repeat.date(); QDate endDate = startDate.addDays( duration ); while ( sub_it <= endDate && sub_it <= to ) { EffectiveEvent tmpEffEv = effEv; Event tmpEv = *it; tmpEffEv.setEvent( tmpEv ); if ( sub_it != startDate ) tmpEffEv.setStart( QTime(0,0,0) ); if ( sub_it != endDate ) tmpEffEv.setEnd( QTime(23,59,59) ); tmpEffEv.setDate( sub_it ); tmpEffEv.setEffectiveDates( startDate, endDate ); tmpList.append( tmpEffEv ); sub_it = sub_it.addDays( 1 ); } itDate = endDate; } else { Event tmpEv = *it; effEv.setEvent( tmpEv ); tmpList.append( effEv ); itDate = repeat.date().addDays( 1 ); } } } qHeapSort( tmpList ); return tmpList; } QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDateTime &dt) { QValueList<EffectiveEvent> day = getEffectiveEvents(dt.date(), dt.date()); QValueListConstIterator<EffectiveEvent> it; QValueList<EffectiveEvent> tmpList; QDateTime dtTmp; for (it = day.begin(); it != day.end(); ++it ) { dtTmp = QDateTime( (*it).date(), (*it).start() ); // at the moment we don't have second granularity, be nice about that.. if ( QABS(dt.secsTo(dtTmp)) < 60 ) tmpList.append( *it ); } return tmpList; } void DateBookDB::addEvent( const Event &ev, bool doalarm ) { // write to the journal... saveJournalEntry( ev, ACTION_ADD, -1, false ); addJFEvent( ev, doalarm ); d->clean = false; } void DateBookDB::addJFEvent( const Event &ev, bool doalarm ) { if ( doalarm && ev.hasAlarm() ) addEventAlarm( ev ); if ( ev.hasRepeat() ) repeatEvents.append( ev ); else eventList.append( ev ); } void DateBookDB::editEvent( const Event &old, Event &editedEv ) { int oldIndex=0; bool oldHadRepeat = old.hasRepeat(); Event orig; // write to the journal... if ( oldHadRepeat ) { if ( origRepeat( old, orig ) ) // should work always... oldIndex = repeatEvents.findIndex( orig ); } else oldIndex = eventList.findIndex( old ); saveJournalEntry( editedEv, ACTION_REPLACE, oldIndex, oldHadRepeat ); // Delete old event if ( old.hasAlarm() ) delEventAlarm( old ); if ( oldHadRepeat ) { if ( editedEv.hasRepeat() ) { // This mean that origRepeat was run above and // orig is initialized // assumption, when someone edits a repeating event, they // want to change them all, maybe not perfect, but it works // for the moment... repeatEvents.remove( orig ); } else removeRepeat( old ); } else { QValueList<Event>::Iterator it = eventList.find( old ); if ( it != eventList.end() ) eventList.remove( it ); } // Add new event if ( editedEv.hasAlarm() ) addEventAlarm( editedEv ); if ( editedEv.hasRepeat() ) repeatEvents.append( editedEv ); else eventList.append( editedEv ); d->clean = false; } |