author | zautrix <zautrix> | 2004-09-14 01:03:08 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-09-14 01:03:08 (UTC) |
commit | 30762fe125216362e1a6c1d5ec5d22d9525aa336 (patch) (side-by-side diff) | |
tree | 4ff0fbf43efa921c86d64ff3f50baa9e59d207d9 /libkcal | |
parent | 8ce7eae438dcd20f9c79fc0a36dfef0a6d3931eb (diff) | |
download | kdepimpi-30762fe125216362e1a6c1d5ec5d22d9525aa336.zip kdepimpi-30762fe125216362e1a6c1d5ec5d22d9525aa336.tar.gz kdepimpi-30762fe125216362e1a6c1d5ec5d22d9525aa336.tar.bz2 |
Many bugfixes
-rw-r--r-- | libkcal/alarm.cpp | 36 | ||||
-rw-r--r-- | libkcal/recurrence.cpp | 56 | ||||
-rw-r--r-- | libkcal/sharpformat.cpp | 7 |
3 files changed, 83 insertions, 16 deletions
diff --git a/libkcal/alarm.cpp b/libkcal/alarm.cpp index 29e6205..1fc7169 100644 --- a/libkcal/alarm.cpp +++ b/libkcal/alarm.cpp @@ -1,423 +1,457 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <kdebug.h> #include "incidence.h" #include "todo.h" #include "alarm.h" using namespace KCal; #include <qwidget.h> Alarm::Alarm(Incidence *parent) : mParent(parent), mType(Audio), mDescription(""), // to make operator==() not fail mFile(""), // to make operator==() not fail mMailSubject(""), // to make operator==() not fail mAlarmSnoozeTime(5), mAlarmRepeatCount(0), mEndOffset(false), mHasTime(false), mAlarmEnabled(false) { } Alarm::~Alarm() { } bool Alarm::operator==( const Alarm& rhs ) const { + if ( mType != rhs.mType || mAlarmSnoozeTime != rhs.mAlarmSnoozeTime || mAlarmRepeatCount != rhs.mAlarmRepeatCount || mAlarmEnabled != rhs.mAlarmEnabled || mHasTime != rhs.mHasTime) return false; +#if 0 + if ( mType != rhs.mType ) { + + qDebug("aaa1 "); + return false; + } + + if ( mAlarmSnoozeTime != rhs.mAlarmSnoozeTime ) { + + qDebug("aaa2 "); + return false; + } + + + if ( mAlarmRepeatCount != rhs.mAlarmRepeatCount ) { + + qDebug("aaa3 "); + return false; + } + + if ( mAlarmEnabled != rhs.mAlarmEnabled ) { + + qDebug("aaa4 "); + return false; + } + + if ( mHasTime != rhs.mHasTime ) { + + qDebug("aaa5 "); + return false; + } +#endif + + if (mHasTime) { if (mAlarmTime != rhs.mAlarmTime) return false; } else { if (mOffset != rhs.mOffset || mEndOffset != rhs.mEndOffset) return false; } - switch (mType) { case Display: return mDescription == rhs.mDescription; case Email: return mDescription == rhs.mDescription && mMailAttachFiles == rhs.mMailAttachFiles && mMailAddresses == rhs.mMailAddresses && mMailSubject == rhs.mMailSubject; case Procedure: return mFile == rhs.mFile && mDescription == rhs.mDescription; case Audio: return mFile == rhs.mFile; case Invalid: break; } return false; } void Alarm::setType(Alarm::Type type) { if (type == mType) return; switch (type) { case Display: mDescription = ""; break; case Procedure: mFile = mDescription = ""; break; case Audio: mFile = ""; break; case Email: mMailSubject = mDescription = ""; mMailAddresses.clear(); mMailAttachFiles.clear(); break; case Invalid: break; default: return; } mType = type; mParent->updated(); } Alarm::Type Alarm::type() const { return mType; } void Alarm::setAudioAlarm(const QString &audioFile) { mType = Audio; mFile = audioFile; mParent->updated(); } void Alarm::setAudioFile(const QString &audioFile) { if (mType == Audio) { mFile = audioFile; mParent->updated(); } } QString Alarm::audioFile() const { return (mType == Audio) ? mFile : QString::null; } void Alarm::setProcedureAlarm(const QString &programFile, const QString &arguments) { mType = Procedure; mFile = programFile; mDescription = arguments; mParent->updated(); } void Alarm::setProgramFile(const QString &programFile) { if (mType == Procedure) { mFile = programFile; mParent->updated(); } } QString Alarm::programFile() const { return (mType == Procedure) ? mFile : QString::null; } void Alarm::setProgramArguments(const QString &arguments) { if (mType == Procedure) { mDescription = arguments; mParent->updated(); } } QString Alarm::programArguments() const { return (mType == Procedure) ? mDescription : QString::null; } void Alarm::setEmailAlarm(const QString &subject, const QString &text, const QValueList<Person> &addressees, const QStringList &attachments) { mType = Email; mMailSubject = subject; mDescription = text; mMailAddresses = addressees; mMailAttachFiles = attachments; mParent->updated(); } void Alarm::setMailAddress(const Person &mailAddress) { if (mType == Email) { mMailAddresses.clear(); mMailAddresses += mailAddress; mParent->updated(); } } void Alarm::setMailAddresses(const QValueList<Person> &mailAddresses) { if (mType == Email) { mMailAddresses = mailAddresses; mParent->updated(); } } void Alarm::addMailAddress(const Person &mailAddress) { if (mType == Email) { mMailAddresses += mailAddress; mParent->updated(); } } QValueList<Person> Alarm::mailAddresses() const { return (mType == Email) ? mMailAddresses : QValueList<Person>(); } void Alarm::setMailSubject(const QString &mailAlarmSubject) { if (mType == Email) { mMailSubject = mailAlarmSubject; mParent->updated(); } } QString Alarm::mailSubject() const { return (mType == Email) ? mMailSubject : QString::null; } void Alarm::setMailAttachment(const QString &mailAttachFile) { if (mType == Email) { mMailAttachFiles.clear(); mMailAttachFiles += mailAttachFile; mParent->updated(); } } void Alarm::setMailAttachments(const QStringList &mailAttachFiles) { if (mType == Email) { mMailAttachFiles = mailAttachFiles; mParent->updated(); } } void Alarm::addMailAttachment(const QString &mailAttachFile) { if (mType == Email) { mMailAttachFiles += mailAttachFile; mParent->updated(); } } QStringList Alarm::mailAttachments() const { return (mType == Email) ? mMailAttachFiles : QStringList(); } void Alarm::setMailText(const QString &text) { if (mType == Email) { mDescription = text; mParent->updated(); } } QString Alarm::mailText() const { return (mType == Email) ? mDescription : QString::null; } void Alarm::setDisplayAlarm(const QString &text) { mType = Display; mDescription = text; mParent->updated(); } void Alarm::setText(const QString &text) { if (mType == Display) { mDescription = text; mParent->updated(); } } QString Alarm::text() const { return (mType == Display) ? mDescription : QString::null; } void Alarm::setTime(const QDateTime &alarmTime) { mAlarmTime = alarmTime; mHasTime = true; mParent->updated(); } int Alarm::offset() { if ( hasTime() ) { if (mParent->type()=="Todo") { Todo *t = static_cast<Todo*>(mParent); return t->dtDue().secsTo( mAlarmTime ) ; } else return mParent->dtStart().secsTo( mAlarmTime ) ; } else { return mOffset.asSeconds(); } } QDateTime Alarm::time() const { if ( hasTime() ) return mAlarmTime; else { if (mParent->type()=="Todo") { Todo *t = static_cast<Todo*>(mParent); return mOffset.end( t->dtDue() ); } else if (mEndOffset) { return mOffset.end( mParent->dtEnd() ); } else { return mOffset.end( mParent->dtStart() ); } } } bool Alarm::hasTime() const { return mHasTime; } void Alarm::setSnoozeTime(int alarmSnoozeTime) { mAlarmSnoozeTime = alarmSnoozeTime; mParent->updated(); } int Alarm::snoozeTime() const { return mAlarmSnoozeTime; } void Alarm::setRepeatCount(int alarmRepeatCount) { kdDebug(5800) << "Alarm::setRepeatCount(): " << alarmRepeatCount << endl; mAlarmRepeatCount = alarmRepeatCount; mParent->updated(); } int Alarm::repeatCount() const { kdDebug(5800) << "Alarm::repeatCount(): " << mAlarmRepeatCount << endl; return mAlarmRepeatCount; } void Alarm::toggleAlarm() { mAlarmEnabled = !mAlarmEnabled; mParent->updated(); } void Alarm::setEnabled(bool enable) { mAlarmEnabled = enable; mParent->updated(); } bool Alarm::enabled() const { return mAlarmEnabled; } void Alarm::setStartOffset( const Duration &offset ) { mOffset = offset; mEndOffset = false; mHasTime = false; mParent->updated(); } Duration Alarm::startOffset() const { return (mHasTime || mEndOffset) ? 0 : mOffset; } bool Alarm::hasStartOffset() const { return !mHasTime && !mEndOffset; } bool Alarm::hasEndOffset() const { return !mHasTime && mEndOffset; } void Alarm::setEndOffset( const Duration &offset ) { mOffset = offset; mEndOffset = true; mHasTime = false; mParent->updated(); } Duration Alarm::endOffset() const { return (mHasTime || !mEndOffset) ? 0 : mOffset; } void Alarm::setParent( Incidence *parent ) { mParent = parent; } diff --git a/libkcal/recurrence.cpp b/libkcal/recurrence.cpp index dd74e10..e84f672 100644 --- a/libkcal/recurrence.cpp +++ b/libkcal/recurrence.cpp @@ -1,648 +1,680 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> Copyright (c) 2002 David Jarvie <software@astrojar.org.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <limits.h> #include <kdebug.h> #include <kglobal.h> #include <klocale.h> #include "incidence.h" #include "recurrence.h" using namespace KCal; Recurrence::Feb29Type Recurrence::mFeb29YearlyDefaultType = Recurrence::rMar1; Recurrence::Recurrence(Incidence *parent, int compatVersion) : recurs(rNone), // by default, it's not a recurring event rWeekStart(1), // default is Monday rDays(7), mFloats(parent ? parent->doesFloat() : false), mRecurReadOnly(false), mRecurExDatesCount(0), mFeb29YearlyType(mFeb29YearlyDefaultType), mCompatVersion(compatVersion ? compatVersion : INT_MAX), mCompatRecurs(rNone), mCompatDuration(0), mParent(parent) { rMonthDays.setAutoDelete( true ); rMonthPositions.setAutoDelete( true ); rYearNums.setAutoDelete( true ); } Recurrence::Recurrence(const Recurrence &r, Incidence *parent) : recurs(r.recurs), rWeekStart(r.rWeekStart), rDays(r.rDays.copy()), rFreq(r.rFreq), rDuration(r.rDuration), rEndDateTime(r.rEndDateTime), mRecurStart(r.mRecurStart), mFloats(r.mFloats), mRecurReadOnly(r.mRecurReadOnly), mRecurExDatesCount(r.mRecurExDatesCount), mFeb29YearlyType(r.mFeb29YearlyType), mCompatVersion(r.mCompatVersion), mCompatRecurs(r.mCompatRecurs), mCompatDuration(r.mCompatDuration), mParent(parent) { for (QPtrListIterator<rMonthPos> mp(r.rMonthPositions); mp.current(); ++mp) { rMonthPos *tmp = new rMonthPos; tmp->rPos = mp.current()->rPos; tmp->negative = mp.current()->negative; tmp->rDays = mp.current()->rDays.copy(); rMonthPositions.append(tmp); } for (QPtrListIterator<int> md(r.rMonthDays); md.current(); ++md) { int *tmp = new int; *tmp = *md.current(); rMonthDays.append(tmp); } for (QPtrListIterator<int> yn(r.rYearNums); yn.current(); ++yn) { int *tmp = new int; *tmp = *yn.current(); rYearNums.append(tmp); } rMonthDays.setAutoDelete( true ); rMonthPositions.setAutoDelete( true ); rYearNums.setAutoDelete( true ); } Recurrence::~Recurrence() { } bool Recurrence::operator==( const Recurrence& r2 ) const { // the following line is obvious if ( recurs == rNone && r2.recurs == rNone ) return true; // we need the above line, because two non recurring events may // differ in the other settings, because one (or both) // may be not initialized properly + if ( recurs != r2.recurs || rFreq != r2.rFreq || rDuration != r2.rDuration || !rDuration && rEndDateTime != r2.rEndDateTime || mRecurStart != r2.mRecurStart || mFloats != r2.mFloats || mRecurReadOnly != r2.mRecurReadOnly || mRecurExDatesCount != r2.mRecurExDatesCount ) return false; // no need to compare mCompat* and mParent // OK to compare the pointers switch ( recurs ) { case rWeekly: return rDays == r2.rDays && rWeekStart == r2.rWeekStart; - case rMonthlyPos: - return rMonthPositions.count() == r2.rMonthPositions.count(); - case rMonthlyDay: - return rMonthDays.count() == r2.rMonthDays.count(); - case rYearlyPos: - return rYearNums.count() == r2.rYearNums.count() - && rMonthPositions.count() == r2.rMonthPositions.count(); - case rYearlyMonth: - return rYearNums.count() == r2.rYearNums.count() - && mFeb29YearlyType == r2.mFeb29YearlyType; - case rYearlyDay: - return rYearNums == r2.rYearNums; + case rMonthlyPos: { + QPtrList<rMonthPos> MonthPositions = rMonthPositions; + QPtrList<rMonthPos> MonthPositions2 = r2.rMonthPositions; + if ( !MonthPositions.count() ) + return false; + if ( !MonthPositions2.count() ) + return false; + return MonthPositions.first()->rPos == MonthPositions2.first()->rPos; + } + case rMonthlyDay: { + QPtrList<int> MonthDays = rMonthDays ; + QPtrList<int> MonthDays2 = r2.rMonthDays ; + if ( !MonthDays.count() ) + return false; + if ( !MonthDays2.count() ) + return false; + return *MonthDays.first() == *MonthDays2.first() ; + } + case rYearlyPos: { + + QPtrList<int> YearNums = rYearNums; + QPtrList<int> YearNums2 = r2.rYearNums; + if ( *YearNums.first() != *YearNums2.first() ) + return false; + QPtrList<rMonthPos> MonthPositions = rMonthPositions; + QPtrList<rMonthPos> MonthPositions2 = r2.rMonthPositions; + if ( !MonthPositions.count() ) + return false; + if ( !MonthPositions2.count() ) + return false; + return MonthPositions.first()->rPos == MonthPositions2.first()->rPos; + + } + case rYearlyMonth: { + QPtrList<int> YearNums = rYearNums; + QPtrList<int> YearNums2 = r2.rYearNums; + return ( *YearNums.first() == *YearNums2.first() && mFeb29YearlyType == r2.mFeb29YearlyType); + } + case rYearlyDay: { + QPtrList<int> YearNums = rYearNums; + QPtrList<int> YearNums2 = r2.rYearNums; + return ( *YearNums.first() == *YearNums2.first() ); + } case rNone: case rMinutely: case rHourly: case rDaily: default: return true; } } /* bool Recurrence::compareLists( const QPtrList<int> &l1 ,const QPtrList<int> &l2) { if ( l1.count() != l2.count() ) return false; int count = l1.count(); int i; for ( i = 0; i < count ; ++i ) { // if ( l1.at(i) != l2.at(i) ) return false; qDebug("compüare "); } return true; } */ QString Recurrence::recurrenceText() const { QString recurText = i18n("No"); if ( recurs == Recurrence::rMinutely ) recurText = i18n("minutely"); else if ( recurs == Recurrence::rHourly ) recurText = i18n("hourly"); else if ( recurs == Recurrence::rDaily ) recurText = i18n("daily"); else if ( recurs == Recurrence::rWeekly ) recurText = i18n("weekly"); else if ( recurs == Recurrence::rMonthlyPos ) recurText = i18n("monthly"); else if ( recurs == Recurrence::rMonthlyDay ) recurText = i18n("day-monthly"); else if ( recurs == Recurrence::rYearlyMonth ) recurText = i18n("month-yearly"); else if ( recurs == Recurrence::rYearlyDay ) recurText = i18n("day-yearly"); else if ( recurs == Recurrence::rYearlyPos ) recurText = i18n("position-yearly"); return recurText; } void Recurrence::setCompatVersion(int version) { mCompatVersion = version ? version : INT_MAX; } ushort Recurrence::doesRecur() const { return recurs; } bool Recurrence::recursOnPure(const QDate &qd) const { switch(recurs) { case rMinutely: return recursSecondly(qd, rFreq*60); case rHourly: return recursSecondly(qd, rFreq*3600); case rDaily: return recursDaily(qd); case rWeekly: return recursWeekly(qd); case rMonthlyPos: case rMonthlyDay: return recursMonthly(qd); case rYearlyMonth: return recursYearlyByMonth(qd); case rYearlyDay: return recursYearlyByDay(qd); case rYearlyPos: return recursYearlyByPos(qd); default: return false; case rNone: return false; } // case return false; } bool Recurrence::recursAtPure(const QDateTime &dt) const { switch(recurs) { case rMinutely: return recursMinutelyAt(dt, rFreq); case rHourly: return recursMinutelyAt(dt, rFreq*60); default: if (dt.time() != mRecurStart.time()) return false; switch(recurs) { case rDaily: return recursDaily(dt.date()); case rWeekly: return recursWeekly(dt.date()); case rMonthlyPos: case rMonthlyDay: return recursMonthly(dt.date()); case rYearlyMonth: return recursYearlyByMonth(dt.date()); case rYearlyDay: return recursYearlyByDay(dt.date()); case rYearlyPos: return recursYearlyByPos(dt.date()); default: return false; case rNone: return false; } } // case return false; } QDate Recurrence::endDate() const { int count = 0; QDate end; if (recurs != rNone) { if (rDuration < 0) return QDate(); // infinite recurrence if (rDuration == 0) return rEndDateTime.date(); // The end date is determined by the recurrence count QDate dStart = mRecurStart.date(); switch (recurs) { case rMinutely: return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*60).date(); case rHourly: return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*3600).date(); case rDaily: return dStart.addDays((rDuration-1+mRecurExDatesCount)*rFreq); case rWeekly: count = weeklyCalc(END_DATE_AND_COUNT, end); break; case rMonthlyPos: case rMonthlyDay: count = monthlyCalc(END_DATE_AND_COUNT, end); break; case rYearlyMonth: count = yearlyMonthCalc(END_DATE_AND_COUNT, end); break; case rYearlyDay: count = yearlyDayCalc(END_DATE_AND_COUNT, end); break; case rYearlyPos: count = yearlyPosCalc(END_DATE_AND_COUNT, end); break; default: // catch-all. Should never get here. kdDebug(5800) << "Control should never reach here in endDate()!" << endl; break; } } if (!count) return QDate(); // error - there is no recurrence return end; } QDateTime Recurrence::endDateTime() const { int count = 0; QDate end; if (recurs != rNone) { if (rDuration < 0) return QDateTime(); // infinite recurrence if (rDuration == 0) return rEndDateTime; // The end date is determined by the recurrence count QDate dStart = mRecurStart.date(); switch (recurs) { case rMinutely: return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*60); case rHourly: return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*3600); case rDaily: return dStart.addDays((rDuration-1+mRecurExDatesCount)*rFreq); case rWeekly: count = weeklyCalc(END_DATE_AND_COUNT, end); break; case rMonthlyPos: case rMonthlyDay: count = monthlyCalc(END_DATE_AND_COUNT, end); break; case rYearlyMonth: count = yearlyMonthCalc(END_DATE_AND_COUNT, end); break; case rYearlyDay: count = yearlyDayCalc(END_DATE_AND_COUNT, end); break; case rYearlyPos: count = yearlyPosCalc(END_DATE_AND_COUNT, end); break; default: // catch-all. Should never get here. kdDebug(5800) << "Control should never reach here in endDate()!" << endl; break; } } if (!count) return QDateTime(); // error - there is no recurrence return QDateTime(end, mRecurStart.time()); } int Recurrence::durationTo(const QDate &date) const { QDate d = date; return recurCalc(COUNT_TO_DATE, d); } int Recurrence::durationTo(const QDateTime &datetime) const { QDateTime dt = datetime; return recurCalc(COUNT_TO_DATE, dt); } void Recurrence::unsetRecurs() { if (mRecurReadOnly) return; recurs = rNone; rMonthPositions.clear(); rMonthDays.clear(); rYearNums.clear(); } void Recurrence::setRecurStart(const QDateTime &start) { mRecurStart = start; mFloats = false; switch (recurs) { case rMinutely: case rHourly: break; case rDaily: case rWeekly: case rMonthlyPos: case rMonthlyDay: case rYearlyMonth: case rYearlyDay: case rYearlyPos: default: rEndDateTime.setTime(start.time()); break; } } void Recurrence::setRecurStart(const QDate &start) { mRecurStart.setDate(start); mRecurStart.setTime(QTime(0,0,0)); switch (recurs) { case rMinutely: case rHourly: break; case rDaily: case rWeekly: case rMonthlyPos: case rMonthlyDay: case rYearlyMonth: case rYearlyDay: case rYearlyPos: default: mFloats = true; break; } } void Recurrence::setFloats(bool f) { switch (recurs) { case rDaily: case rWeekly: case rMonthlyPos: case rMonthlyDay: case rYearlyMonth: case rYearlyDay: case rYearlyPos: break; case rMinutely: case rHourly: default: return; // can't set sub-daily to floating } mFloats = f; if (f) { mRecurStart.setTime(QTime(0,0,0)); rEndDateTime.setTime(QTime(0,0,0)); } } int Recurrence::frequency() const { return rFreq; } int Recurrence::duration() const { return rDuration; } void Recurrence::setDuration(int _rDuration) { if (mRecurReadOnly) return; if (_rDuration > 0) { rDuration = _rDuration; // Compatibility mode is only needed when reading the calendar in ICalFormatImpl, // so explicitly setting the duration means no backwards compatibility is needed. mCompatDuration = 0; } } QString Recurrence::endDateStr(bool shortfmt) const { return KGlobal::locale()->formatDate(rEndDateTime.date(),shortfmt); } const QBitArray &Recurrence::days() const { return rDays; } const QPtrList<Recurrence::rMonthPos> &Recurrence::monthPositions() const { return rMonthPositions; } const QPtrList<Recurrence::rMonthPos> &Recurrence::yearMonthPositions() const { return rMonthPositions; } const QPtrList<int> &Recurrence::monthDays() const { return rMonthDays; } void Recurrence::setMinutely(int _rFreq, int _rDuration) { if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) return; setDailySub(rMinutely, _rFreq, _rDuration); } void Recurrence::setMinutely(int _rFreq, const QDateTime &_rEndDateTime) { if (mRecurReadOnly) return; rEndDateTime = _rEndDateTime; setDailySub(rMinutely, _rFreq, 0); } void Recurrence::setHourly(int _rFreq, int _rDuration) { if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) return; setDailySub(rHourly, _rFreq, _rDuration); } void Recurrence::setHourly(int _rFreq, const QDateTime &_rEndDateTime) { if (mRecurReadOnly) return; rEndDateTime = _rEndDateTime; setDailySub(rHourly, _rFreq, 0); } void Recurrence::setDaily(int _rFreq, int _rDuration) { if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) return; setDailySub(rDaily, _rFreq, _rDuration); } void Recurrence::setDaily(int _rFreq, const QDate &_rEndDate) { if (mRecurReadOnly) return; rEndDateTime.setDate(_rEndDate); rEndDateTime.setTime(mRecurStart.time()); setDailySub(rDaily, _rFreq, 0); } void Recurrence::setWeekly(int _rFreq, const QBitArray &_rDays, int _rDuration, int _rWeekStart) { if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) return; recurs = rWeekly; rFreq = _rFreq; rDays = _rDays; rWeekStart = _rWeekStart; rDuration = _rDuration; if (mCompatVersion < 310 && _rDuration > 0) { // Backwards compatibility for KDE < 3.1. // rDuration was set to the number of time periods to recur, // with week start always on a Monday. // Convert this to the number of occurrences. mCompatDuration = _rDuration; int weeks = ((mCompatDuration-1+mRecurExDatesCount)*7) + (7 - mRecurStart.date().dayOfWeek()); QDate end(mRecurStart.date().addDays(weeks * rFreq)); rDuration = INT_MAX; // ensure that weeklyCalc() does its job correctly rDuration = weeklyCalc(COUNT_TO_DATE, end); } else { mCompatDuration = 0; } rMonthPositions.clear(); rMonthDays.clear(); if (mParent) mParent->updated(); } void Recurrence::setWeekly(int _rFreq, const QBitArray &_rDays, const QDate &_rEndDate, int _rWeekStart) { if (mRecurReadOnly) return; recurs = rWeekly; rFreq = _rFreq; rDays = _rDays; rWeekStart = _rWeekStart; rEndDateTime.setDate(_rEndDate); rEndDateTime.setTime(mRecurStart.time()); rDuration = 0; // set to 0 because there is an end date mCompatDuration = 0; rMonthPositions.clear(); rMonthDays.clear(); rYearNums.clear(); if (mParent) mParent->updated(); } void Recurrence::setMonthly(short type, int _rFreq, int _rDuration) { if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) return; recurs = type; rFreq = _rFreq; rDuration = _rDuration; if (mCompatVersion < 310) mCompatDuration = (_rDuration > 0) ? _rDuration : 0; rYearNums.clear(); if (mParent) mParent->updated(); } void Recurrence::setMonthly(short type, int _rFreq, const QDate &_rEndDate) { if (mRecurReadOnly) return; recurs = type; rFreq = _rFreq; rEndDateTime.setDate(_rEndDate); rEndDateTime.setTime(mRecurStart.time()); rDuration = 0; // set to 0 because there is an end date mCompatDuration = 0; rYearNums.clear(); if (mParent) mParent->updated(); } void Recurrence::addMonthlyPos(short _rPos, const QBitArray &_rDays) { if (recurs == rMonthlyPos) addMonthlyPos_(_rPos, _rDays); } void Recurrence::addMonthlyPos_(short _rPos, const QBitArray &_rDays) { if (mRecurReadOnly || _rPos == 0 || _rPos > 5 || _rPos < -5) // invalid week number return; for (rMonthPos* it = rMonthPositions.first(); it; it = rMonthPositions.next()) { int itPos = it->negative ? -it->rPos : it->rPos; if (_rPos == itPos) { // This week is already in the list. // Combine the specified days with those in the list. it->rDays |= _rDays; if (mParent) mParent->updated(); return; } } // Add the new position to the list rMonthPos *tmpPos = new rMonthPos; if (_rPos > 0) { tmpPos->rPos = _rPos; tmpPos->negative = false; } else { tmpPos->rPos = -_rPos; // take abs() tmpPos->negative = true; } tmpPos->rDays = _rDays; tmpPos->rDays.detach(); rMonthPositions.append(tmpPos); if (mCompatVersion < 310 && mCompatDuration > 0) { // Backwards compatibility for KDE < 3.1. // rDuration was set to the number of time periods to recur. // Convert this to the number of occurrences. int monthsAhead = (mCompatDuration-1+mRecurExDatesCount) * rFreq; int month = mRecurStart.date().month() - 1 + monthsAhead; QDate end(mRecurStart.date().year() + month/12, month%12 + 1, 31); rDuration = INT_MAX; // ensure that recurCalc() does its job correctly diff --git a/libkcal/sharpformat.cpp b/libkcal/sharpformat.cpp index defdb09..89eb72f 100644 --- a/libkcal/sharpformat.cpp +++ b/libkcal/sharpformat.cpp @@ -1,889 +1,890 @@ /* This file is part of libkcal. Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qdatetime.h> #include <qstring.h> #include <qapplication.h> #include <qptrlist.h> #include <qregexp.h> #include <qmessagebox.h> #include <qclipboard.h> #include <qfile.h> #include <qtextstream.h> #include <qtextcodec.h> #include <qxml.h> #include <qlabel.h> #include <kdebug.h> #include <klocale.h> #include <kglobal.h> #include "calendar.h" #include "alarm.h" #include "recurrence.h" #include "calendarlocal.h" #include "sharpformat.h" #include "syncdefines.h" using namespace KCal; //CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //ARSD silentalarm = 0 // 11 RTYP 225 no /0 dialy/ 1 weekly/ 3 month by date/ 2 month by day(pos)/ yearly // 12 RFRQ // 13 RPOS pos = 4. monday in month // 14 RDYS days: 1 mon/ 2 tue .. 64 sun // 15 REND 0 = no end/ 1 = end // 16 REDT rec end dt //ALSD //ALED //MDAY class SharpParser : public QObject { public: SharpParser( Calendar *calendar ) : mCalendar( calendar ) { oldCategories = 0; } bool startElement( Calendar *existingCalendar, const QStringList & attList, QString qName ) { int i = 1; bool skip = true; int max = attList.count() -2; while ( i < max ) { if ( !attList[i].isEmpty() ) { skip = false; break; } ++i ; } if ( skip ) return false; ulong cSum = SharpFormat::getCsum(attList ); if ( qName == "Event" ) { Event *event; event = existingCalendar->event( "Sharp_DTM",attList[0] ); if ( event ) event = (Event*)event->clone(); else event = new Event; event->setID("Sharp_DTM", attList[0] ); event->setCsum( "Sharp_DTM", QString::number( cSum )); event->setTempSyncStat(SYNC_TEMPSTATE_NEW_EXTERNAL ); event->setSummary( attList[2] ); event->setLocation( attList[3] ); event->setDescription( attList[4] ); if ( attList[7] == "1" ) { event->setDtStart( QDateTime(fromString( attList[17]+"T000000", false ).date(),QTime(0,0,0 ) )); event->setDtEnd( QDateTime(fromString( attList[18]+"T000000", false ).date(),QTime(0,0,0 ))); event->setFloats( true ); } else { event->setFloats( false ); event->setDtStart( fromString( attList[5] ) ); event->setDtEnd( fromString( attList[6] )); } QString rtype = attList[11]; if ( rtype != "255" ) { // qDebug("recurs "); QDate startDate = event->dtStart().date(); QString freqStr = attList[12]; int freq = freqStr.toInt(); QString hasEndDateStr = attList[15] ; bool hasEndDate = hasEndDateStr == "1"; QString endDateStr = attList[16]; QDate endDate = fromString( endDateStr ).date(); QString weekDaysStr = attList[14]; uint weekDaysNum = weekDaysStr.toInt(); QBitArray weekDays( 7 ); int i; int bb = 1; for( i = 1; i <= 7; ++i ) { weekDays.setBit( i - 1, ( bb & weekDaysNum )); bb = 2 << (i-1); //qDebug(" %d bit %d ",i-1,weekDays.at(i-1) ); } // qDebug("next "); QString posStr = attList[13]; int pos = posStr.toInt(); Recurrence *r = event->recurrence(); if ( rtype == "0" ) { if ( hasEndDate ) r->setDaily( freq, endDate ); else r->setDaily( freq, -1 ); } else if ( rtype == "1" ) { if ( hasEndDate ) r->setWeekly( freq, weekDays, endDate ); else r->setWeekly( freq, weekDays, -1 ); } else if ( rtype == "3" ) { if ( hasEndDate ) r->setMonthly( Recurrence::rMonthlyDay, freq, endDate ); else r->setMonthly( Recurrence::rMonthlyDay, freq, -1 ); r->addMonthlyDay( startDate.day() ); } else if ( rtype == "2" ) { if ( hasEndDate ) r->setMonthly( Recurrence::rMonthlyPos, freq, endDate ); else r->setMonthly( Recurrence::rMonthlyPos, freq, -1 ); QBitArray days( 7 ); days.fill( false ); days.setBit( startDate.dayOfWeek() - 1 ); r->addMonthlyPos( pos, days ); } else if ( rtype == "4" ) { if ( hasEndDate ) r->setYearly( Recurrence::rYearlyMonth, freq, endDate ); else r->setYearly( Recurrence::rYearlyMonth, freq, -1 ); r->addYearlyNum( startDate.month() ); } } else { event->recurrence()->unsetRecurs(); } QString categoryList = attList[1] ; event->setCategories( lookupCategories( categoryList ) ); // strange 0 semms to mean: alarm enabled if ( attList[8] == "0" ) { Alarm *alarm; if ( event->alarms().count() > 0 ) alarm = event->alarms().first(); else { alarm = new Alarm( event ); event->addAlarm( alarm ); + alarm->setType( Alarm::Audio ); } - alarm->setType( Alarm::Audio ); + //alarm->setType( Alarm::Audio ); alarm->setEnabled( true ); int alarmOffset = attList[9].toInt(); alarm->setStartOffset( alarmOffset * -60 ); } else { Alarm *alarm; if ( event->alarms().count() > 0 ) { alarm = event->alarms().first(); alarm->setType( Alarm::Audio ); alarm->setStartOffset( -60*15 ); alarm->setEnabled( false ); } } mCalendar->addEvent( event); } else if ( qName == "Todo" ) { Todo *todo; todo = existingCalendar->todo( "Sharp_DTM", attList[0] ); if (todo ) todo = (Todo*)todo->clone(); else todo = new Todo; //CARDID,CATEGORY,ETDY,LTDY,FNDY,MARK,PRTY,TITL,MEM1 // 0 1 2 3 4 5 6 7 8 //1,,,,,1,4,Loch zumachen,"" //3,Privat,20040317T000000,20040318T000000,20040319T000000,0,5,Call bbb,"notes123 bbb gggg ""bb "" " //2,"Familie,Freunde,Holiday",20040318T000000,20040324T000000,20040317T000000,1,2,tod2,notes todo->setID( "Sharp_DTM", attList[0]); todo->setCsum( "Sharp_DTM", QString::number( cSum )); todo->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); todo->setSummary( attList[7] ); todo->setDescription( attList[8]); int priority = attList[6].toInt(); if ( priority == 0 ) priority = 3; todo->setPriority( priority ); QString categoryList = attList[1]; todo->setCategories( lookupCategories( categoryList ) ); QString hasDateStr = attList[3]; // due if ( !hasDateStr.isEmpty() ) { if ( hasDateStr.right(6) == "000000" ) { todo->setDtDue( QDateTime(fromString( hasDateStr, false ).date(), QTime(0,0,0 )) ); todo->setFloats( true ); } else { todo->setDtDue( fromString( hasDateStr ) ); todo->setFloats( false ); } todo->setHasDueDate( true ); } hasDateStr = attList[2];//start if ( !hasDateStr.isEmpty() ) { todo->setDtStart( fromString( hasDateStr ) ); todo->setHasStartDate( true); } else todo->setHasStartDate( false ); hasDateStr = attList[4];//completed if ( !hasDateStr.isEmpty() ) { todo->setCompleted(fromString( hasDateStr ) ); } QString completedStr = attList[5]; if ( completedStr == "0" ) todo->setCompleted( true ); else todo->setCompleted( false ); mCalendar->addTodo( todo ); } else if ( qName == "Category" ) { /* QString id = attributes.value( "id" ); QString name = attributes.value( "name" ); setCategory( id, name ); */ } //qDebug("end "); return true; } void setCategoriesList ( QStringList * c ) { oldCategories = c; } QDateTime fromString ( QString s, bool useTz = true ) { QDateTime dt; int y,m,t,h,min,sec; y = s.mid(0,4).toInt(); m = s.mid(4,2).toInt(); t = s.mid(6,2).toInt(); h = s.mid(9,2).toInt(); min = s.mid(11,2).toInt(); sec = s.mid(13,2).toInt(); dt = QDateTime(QDate(y,m,t), QTime(h,min,sec)); int offset = KGlobal::locale()->localTimeOffset( dt ); if ( useTz ) dt = dt.addSecs ( offset*60); return dt; } protected: QDateTime toDateTime( const QString &value ) { QDateTime dt; dt.setTime_t( value.toUInt() ); return dt; } QStringList lookupCategories( const QString &categoryList ) { QStringList categoryIds = QStringList::split( ";", categoryList ); QStringList categories; QStringList::ConstIterator it; for( it = categoryIds.begin(); it != categoryIds.end(); ++it ) { QString cate = category( *it ); if ( oldCategories ) { if ( ! oldCategories->contains( cate ) ) oldCategories->append( cate ); } categories.append(cate ); } return categories; } private: Calendar *mCalendar; QStringList * oldCategories; static QString category( const QString &id ) { QMap<QString,QString>::ConstIterator it = mCategoriesMap.find( id ); if ( it == mCategoriesMap.end() ) return id; else return *it; } static void setCategory( const QString &id, const QString &name ) { mCategoriesMap.insert( id, name ); } static QMap<QString,QString> mCategoriesMap; }; QMap<QString,QString> SharpParser::mCategoriesMap; SharpFormat::SharpFormat() { mCategories = 0; } SharpFormat::~SharpFormat() { } ulong SharpFormat::getCsum( const QStringList & attList) { int max = attList.count() -1; ulong cSum = 0; int j,k,i; int add; for ( i = 1; i < max ; ++i ) { QString s = attList[i]; if ( ! s.isEmpty() ){ j = s.length(); for ( k = 0; k < j; ++k ) { int mul = k +1; add = s[k].unicode (); if ( k < 16 ) mul = mul * mul; add = add * mul *i*i*i; cSum += add; } } } return cSum; } #include <stdlib.h> -#define DEBUGMODE false +//#define DEBUGMODE false +#define DEBUGMODE true bool SharpFormat::load( Calendar *calendar, Calendar *existngCal ) { bool debug = DEBUGMODE; - //debug = true; QString text; QString codec = "utf8"; QLabel status ( i18n("Reading events ..."), 0 ); int w = status.sizeHint().width()+20 ; if ( w < 200 ) w = 200; int h = status.sizeHint().height()+20 ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); status.setCaption(i18n("Reading DTM Data") ); status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); status.show(); status.raise(); qApp->processEvents(); QString fileName; if ( ! debug ) { fileName = "/tmp/kopitempout"; QString command ="db2file datebook -r -c "+ codec + " > " + fileName; system ( command.latin1() ); } else { fileName = "/tmp/events.txt"; } QFile file( fileName ); if (!file.open( IO_ReadOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); text = ts.read(); file.close(); status.setText( i18n("Processing events ...") ); status.raise(); qApp->processEvents(); fromString2Cal( calendar, existngCal, text, "Event" ); status.setText( i18n("Reading todos ...") ); qApp->processEvents(); if ( ! debug ) { fileName = "/tmp/kopitempout"; QString command = "db2file todo -r -c " + codec+ " > " + fileName; system ( command.latin1() ); } else { fileName = "/tmp/todo.txt"; } file.setName( fileName ); if (!file.open( IO_ReadOnly ) ) { return false; } ts.setDevice( &file ); text = ts.read(); file.close(); status.setText( i18n("Processing todos ...") ); status.raise(); qApp->processEvents(); fromString2Cal( calendar, existngCal, text, "Todo" ); return true; } int SharpFormat::getNumFromRecord( QString answer, Incidence* inc ) { int retval = -1; QStringList templist; QString tempString; int start = 0; int len = answer.length(); int end = answer.find ("\n",start)+1; bool ok = true; start = end; int ccc = 0; while ( start > 0 ) { templist.clear(); ok = true; int loopCount = 0; while ( ok ) { ++loopCount; if ( loopCount > 25 ) { qDebug("KO: Error in while loop"); ok = false; start = 0; break; } if ( ok ) tempString = getPart( answer, ok, start ); if ( start >= len || start == 0 ) { start = 0; ok = false; } if ( tempString.right(1) =="\n" ) tempString = tempString.left( tempString.length()-1); templist.append( tempString ); } ++ccc; if ( ccc == 2 && loopCount < 25 ) { start = 0; bool ok; int newnum = templist[0].toInt( &ok ); if ( ok && newnum > 0) { retval = newnum; inc->setID( "Sharp_DTM",templist[0] ); inc->setCsum( "Sharp_DTM", QString::number( getCsum( templist ) )); inc->setTempSyncStat( SYNC_TEMPSTATE_NEW_ID ); } } } //qDebug("getNumFromRecord returning : %d ", retval); return retval; } bool SharpFormat::save( Calendar *calendar) { QLabel status ( i18n("Processing/adding events ..."), 0 ); int w = status.sizeHint().width()+20 ; if ( w < 200 ) w = 200; int h = status.sizeHint().height()+20 ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); status.setCaption(i18n("Writing DTM Data") ); status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); status.show(); status.raise(); qApp->processEvents(); bool debug = DEBUGMODE; QString codec = "utf8"; QString answer; QString ePrefix = "CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY\n"; QString tPrefix = "CARDID,CATEGORY,ETDY,LTDY,FNDY,MARK,PRTY,TITL,MEM1\n"; QString command; QPtrList<Event> er = calendar->rawEvents(); Event* ev = er.first(); QString fileName = "/tmp/kopitempout"; int i = 0; QString changeString = ePrefix; QString deleteString = ePrefix; bool deleteEnt = false; bool changeEnt = false; QString message = i18n("Processing event # "); int procCount = 0; while ( ev ) { //qDebug("i %d ", ++i); if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { status.setText ( message + QString::number ( ++procCount ) ); qApp->processEvents(); QString eString = getEventString( ev ); if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete // deleting empty strings does not work. // we write first and x and then delete the record with the x eString = eString.replace( QRegExp(",\"\""),",\"x\"" ); changeString += eString + "\n"; deleteString += eString + "\n"; deleteEnt = true; changeEnt = true; } else if ( ev->getID("Sharp_DTM").isEmpty() ) { // add new command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName; system ( command.utf8() ); QFile file( fileName ); if (!file.open( IO_ReadOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); answer = ts.read(); file.close(); //qDebug("answer \n%s ", answer.latin1()); getNumFromRecord( answer, ev ) ; } else { // change existing //qDebug("canging %d %d",ev->zaurusStat() ,ev->zaurusId() ); //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName; changeString += eString + "\n"; changeEnt = true; } } ev = er.next(); } status.setText ( i18n("Changing events ...") ); qApp->processEvents(); //qDebug("changing... "); if ( changeEnt ) { QFile file( fileName ); if (!file.open( IO_WriteOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); ts << changeString ; file.close(); command = "db2file datebook -w -g -c " + codec+ " < "+ fileName; system ( command.latin1() ); //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1()); } status.setText ( i18n("Deleting events ...") ); qApp->processEvents(); //qDebug("deleting... "); if ( deleteEnt ) { QFile file( fileName ); if (!file.open( IO_WriteOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); ts << deleteString; file.close(); command = "db2file datebook -d -c " + codec+ " < "+ fileName; system ( command.latin1() ); // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1()); } changeString = tPrefix; deleteString = tPrefix; status.setText ( i18n("Processing todos ...") ); qApp->processEvents(); QPtrList<Todo> tl = calendar->rawTodos(); Todo* to = tl.first(); i = 0; message = i18n("Processing todo # "); procCount = 0; while ( to ) { if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { status.setText ( message + QString::number ( ++procCount ) ); qApp->processEvents(); QString eString = getTodoString( to ); if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete // deleting empty strings does not work. // we write first and x and then delete the record with the x eString = eString.replace( QRegExp(",\"\""),",\"x\"" ); changeString += eString + "\n"; deleteString += eString + "\n"; deleteEnt = true; changeEnt = true; } else if ( to->getID("Sharp_DTM").isEmpty() ) { // add new command = "(echo \"" + tPrefix + eString + "\" ) | db2file todo -w -g -c " + codec+ " > "+ fileName; system ( command.utf8() ); QFile file( fileName ); if (!file.open( IO_ReadOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); answer = ts.read(); file.close(); //qDebug("answer \n%s ", answer.latin1()); getNumFromRecord( answer, to ) ; } else { // change existing //qDebug("canging %d %d",to->zaurusStat() ,to->zaurusId() ); //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName; changeString += eString + "\n"; changeEnt = true; } } to = tl.next(); } status.setText ( i18n("Changing todos ...") ); qApp->processEvents(); //qDebug("changing... "); if ( changeEnt ) { QFile file( fileName ); if (!file.open( IO_WriteOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); ts << changeString ; file.close(); command = "db2file todo -w -g -c " + codec+ " < "+ fileName; system ( command.latin1() ); //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1()); } status.setText ( i18n("Deleting todos ...") ); qApp->processEvents(); //qDebug("deleting... "); if ( deleteEnt ) { QFile file( fileName ); if (!file.open( IO_WriteOnly ) ) { return false; } QTextStream ts( &file ); ts.setCodec( QTextCodec::codecForName("utf8") ); ts << deleteString; file.close(); command = "db2file todo -d -c " + codec+ " < "+ fileName; system ( command.latin1() ); // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1()); } return true; } QString SharpFormat::dtToString( const QDateTime& dti, bool useTZ ) { QString datestr; QString timestr; int offset = KGlobal::locale()->localTimeOffset( dti ); QDateTime dt; if (useTZ) dt = dti.addSecs ( -(offset*60)); else dt = dti; if(dt.date().isValid()){ const QDate& date = dt.date(); datestr.sprintf("%04d%02d%02d", date.year(), date.month(), date.day()); } if(dt.time().isValid()){ const QTime& time = dt.time(); timestr.sprintf("T%02d%02d%02d", time.hour(), time.minute(), time.second()); } return datestr + timestr; } QString SharpFormat::getEventString( Event* event ) { QStringList list; list.append( event->getID("Sharp_DTM") ); list.append( event->categories().join(",") ); if ( !event->summary().isEmpty() ) list.append( event->summary() ); else list.append("" ); if ( !event->location().isEmpty() ) list.append( event->location() ); else list.append("" ); if ( !event->description().isEmpty() ) list.append( event->description() ); else list.append( "" ); if ( event->doesFloat () ) { list.append( dtToString( QDateTime(event->dtStart().date(), QTime(0,0,0)), false )); list.append( dtToString( QDateTime(event->dtEnd().date(),QTime(23,59,59)), false )); //6 list.append( "1" ); } else { list.append( dtToString( event->dtStart()) ); list.append( dtToString( event->dtEnd()) ); //6 list.append( "0" ); } bool noAlarm = true; if ( event->alarms().count() > 0 ) { Alarm * al = event->alarms().first(); if ( al->enabled() ) { noAlarm = false; list.append( "0" ); // yes, 0 == alarm list.append( QString::number( al->startOffset().asSeconds()/(-60) ) ); if ( al->type() == Alarm::Audio ) list.append( "1" ); // type audio else list.append( "0" ); // type silent } } if ( noAlarm ) { list.append( "1" ); // yes, 1 == no alarm list.append( "0" ); // no alarm offset list.append( "1" ); // type } // next is: 11 // next is: 11-16 are recurrence Recurrence* rec = event->recurrence(); bool writeEndDate = false; switch ( rec->doesRecur() ) { case Recurrence::rDaily: // 0 list.append( "0" ); list.append( QString::number( rec->frequency() ));//12 list.append( "0" ); list.append( "0" ); writeEndDate = true; break; case Recurrence::rWeekly:// 1 list.append( "1" ); list.append( QString::number( rec->frequency()) );//12 list.append( "0" ); { int days = 0; QBitArray weekDays = rec->days(); int i; for( i = 1; i <= 7; ++i ) { if ( weekDays[i-1] ) { days += 1 << (i-1); } } list.append( QString::number( days ) ); } //pending weekdays writeEndDate = true; break; case Recurrence::rMonthlyPos:// 2 list.append( "2" ); list.append( QString::number( rec->frequency()) );//12 writeEndDate = true; { int count = 1; QPtrList<Recurrence::rMonthPos> rmp; rmp = rec->monthPositions(); if ( rmp.first()->negative ) count = 5 - rmp.first()->rPos - 1; else count = rmp.first()->rPos - 1; list.append( QString::number( count ) ); } list.append( "0" ); break; case Recurrence::rMonthlyDay:// 3 list.append( "3" ); list.append( QString::number( rec->frequency()) );//12 list.append( "0" ); list.append( "0" ); writeEndDate = true; break; case Recurrence::rYearlyMonth://4 list.append( "4" ); list.append( QString::number( rec->frequency()) );//12 list.append( "0" ); list.append( "0" ); writeEndDate = true; break; default: list.append( "255" ); list.append( QString() ); list.append( "0" ); list.append( QString() ); list.append( "0" ); list.append( "20991231T000000" ); break; } if ( writeEndDate ) { if ( rec->endDate().isValid() ) { // 15 + 16 list.append( "1" ); list.append( dtToString( rec->endDate()) ); } else { list.append( "0" ); list.append( "20991231T000000" ); } } if ( event->doesFloat () ) { list.append( dtToString( event->dtStart(), false ).left( 8 )); list.append( dtToString( event->dtEnd(), false ).left( 8 )); //6 } else { list.append( QString() ); list.append( QString() ); } if (event->dtStart().date() == event->dtEnd().date() ) list.append( "0" ); else list.append( "1" ); for(QStringList::Iterator it=list.begin(); it!=list.end(); ++it){ QString& s = (*it); s.replace(QRegExp("\""), "\"\""); if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){ s.prepend('\"'); s.append('\"'); } else if(s.isEmpty() && !s.isNull()){ s = "\"\""; } } return list.join(","); } QString SharpFormat::getTodoString( Todo* todo ) { QStringList list; list.append( todo->getID("Sharp_DTM") ); list.append( todo->categories().join(",") ); if ( todo->hasStartDate() ) { list.append( dtToString( todo->dtStart()) ); } else list.append( QString() ); if ( todo->hasDueDate() ) { QTime tim; if ( todo->doesFloat()) { list.append( dtToString( QDateTime(todo->dtDue().date(),QTime( 0,0,0 )), false)) ; } else { list.append( dtToString(todo->dtDue() ) ); } } else list.append( QString() ); |