summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--bin/kdepim/WhatsNew.txt2
-rw-r--r--libkcal/icalformatimpl.cpp31
-rw-r--r--libkcal/incidencebase.cpp11
3 files changed, 27 insertions, 17 deletions
diff --git a/bin/kdepim/WhatsNew.txt b/bin/kdepim/WhatsNew.txt
index 06aa5f6..01d9e27 100644
--- a/bin/kdepim/WhatsNew.txt
+++ b/bin/kdepim/WhatsNew.txt
@@ -1,77 +1,79 @@
Info about the changes in new versions of KDE-Pim/Pi
********** VERSION 2.0.8 ************
Fixed a problem in dependency info in the ipk files for the Zaurus.
Added icon for the stealth new week view and made navigation more user friendly in monthview by adding a prev/next week button to the navigator bar.
Added a "go today" button to the datepicker.
Added "created" and "last modified" to event/todo viewer (and What'sThis viewer)
and made it configureable to show these values.
+Fixed a problem for events (from external iCal files) that do have a duration but no end date.
+
********** VERSION 2.0.7 ************
Added global application font settings
(for all KDE-Pim/Pi apps) to the general settings.
Fixed a problem in OM/Pi when trying to login to some IMAP servers
(like the IMAP server of Apple: mail.mac.com )
Added recurring todos to KO/Pi.
********** VERSION 2.0.6 ************
Some bugfixes in the pi-sync mode.
Added German translation for pi-sync mode.
KO/Pi:
Made the todolist using alternate background.
Other minor fixes in KO/Pi.
********** VERSION 2.0.5 ************
Bugfixes in KO/Pi.
********** VERSION 2.0.4 ************
KO/Pi:
Fixed problem loading translations for summary/location edit boxes in event/todo editor.
Added a general "select week number" to the toolbar.
Fixed some small problem of the new features introduced in version 2.0.3.
Made it possible to specify one specific category as category color,
if more than one categories are selected.
Fixed a bug in saving colors for categories with non-ascii characters.
(Like, e.g. German Umlauts).
Propably you have to set your colors again for those categories.
********** VERSION 2.0.3 ************
KO/Pi:
Added feature for changing alarm settings for many items at once:
Open list view (or search dialog), select the desired items and choose in
the popup menu: Set alarm for selected...
Added to the event/todo viewer the option to send an email to
all attendees or all selected (with RSVP) attendees.
Made the week-month mode changing in month view faster.
Made month view better useable with keyboard.
Now TAB key jumps to next cell with an event/todo.
Scroll in cell with coursor keys, scroll in time (next week) with
Shift/Control + coursorkeys.
Fixed bug that the todo view flat mode was reset after first view update.
If a todo is displayed closed in the todo view,
diff --git a/libkcal/icalformatimpl.cpp b/libkcal/icalformatimpl.cpp
index 2e38ae3..eae41aa 100644
--- a/libkcal/icalformatimpl.cpp
+++ b/libkcal/icalformatimpl.cpp
@@ -347,133 +347,133 @@ void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence)
QString catStr;
for ( QStringList::Iterator it = tmpStrList.begin();
it != tmpStrList.end();
++it ) {
catStr = *it;
if (catStr[0] == ' ')
tmpStr += catStr.mid(1);
else
tmpStr += catStr;
// this must be a ';' character as the vCalendar specification requires!
// vcc.y has been hacked to translate the ';' to a ',' when the vcal is
// read in.
tmpStr += ";";
}
if (!tmpStr.isEmpty()) {
tmpStr.truncate(tmpStr.length()-1);
icalcomponent_add_property(parent,icalproperty_new_categories(
writeText(incidence->getCategories().join(";"))));
}
*/
// related event
if (incidence->relatedTo()) {
icalcomponent_add_property(parent,icalproperty_new_relatedto(
incidence->relatedTo()->uid().utf8()));
}
// recurrence rule stuff
Recurrence *recur = incidence->recurrence();
if (recur->doesRecur()) {
icalcomponent_add_property(parent,writeRecurrenceRule(recur));
}
// recurrence excpetion dates
DateList dateList = incidence->exDates();
DateList::ConstIterator exIt;
for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) {
icalcomponent_add_property(parent,icalproperty_new_exdate(
writeICalDate(*exIt)));
}
// attachments
QPtrList<Attachment> attachments = incidence->attachments();
for (Attachment *at = attachments.first(); at; at = attachments.next())
icalcomponent_add_property(parent,writeAttachment(at));
// alarms
QPtrList<Alarm> alarms = incidence->alarms();
Alarm* alarm;
for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
if (alarm->enabled()) {
kdDebug(5800) << "Write alarm for " << incidence->summary() << endl;
icalcomponent_add_component(parent,writeAlarm(alarm));
}
}
if( incidence->hasRecurrenceID() ) {
icalcomponent_add_property(parent,
icalproperty_new_recurrenceid( writeICalDateTime( incidence->recurrenceID())));
}
// duration
// turned off as it always is set to PTS0 (and must not occur together with DTEND
-// if (incidence->hasDuration()) {
-// icaldurationtype duration;
-// duration = writeICalDuration(incidence->duration());
-// icalcomponent_add_property(parent,icalproperty_new_duration(duration));
-// }
+ if (incidence->hasDuration()) {
+ icaldurationtype duration;
+ duration = writeICalDuration(incidence->duration());
+ icalcomponent_add_property(parent,icalproperty_new_duration(duration));
+ }
}
void ICalFormatImpl::writeIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase)
{
icalcomponent_add_property(parent,icalproperty_new_dtstamp(
writeICalDateTime(QDateTime::currentDateTime())));
// organizer stuff
icalcomponent_add_property(parent,icalproperty_new_organizer(
("MAILTO:" + incidenceBase->organizer()).utf8()));
// attendees
if (incidenceBase->attendeeCount() != 0) {
QPtrList<Attendee> al = incidenceBase->attendees();
QPtrListIterator<Attendee> ai(al);
for (; ai.current(); ++ai) {
icalcomponent_add_property(parent,writeAttendee(ai.current()));
}
}
// custom properties
writeCustomProperties(parent, incidenceBase);
}
void ICalFormatImpl::writeCustomProperties(icalcomponent *parent,CustomProperties *properties)
{
QMap<QCString, QString> custom = properties->customProperties();
for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) {
icalproperty *p = icalproperty_new_x(c.data().utf8());
icalproperty_set_x_name(p,c.key());
icalcomponent_add_property(parent,p);
}
}
icalproperty *ICalFormatImpl::writeAttendee(Attendee *attendee)
{
icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().utf8());
if (!attendee->name().isEmpty()) {
icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name().utf8()));
}
icalproperty_add_parameter(p,icalparameter_new_rsvp(
attendee->RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE ));
icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION;
switch (attendee->status()) {
default:
case Attendee::NeedsAction:
status = ICAL_PARTSTAT_NEEDSACTION;
break;
case Attendee::Accepted:
status = ICAL_PARTSTAT_ACCEPTED;
break;
case Attendee::Declined:
status = ICAL_PARTSTAT_DECLINED;
break;
case Attendee::Tentative:
status = ICAL_PARTSTAT_TENTATIVE;
break;
case Attendee::Delegated:
status = ICAL_PARTSTAT_DELEGATED;
break;
@@ -1708,139 +1708,140 @@ icaltimetype ICalFormatImpl::writeICalDate(const QDate &date)
return t;
}
icaltimetype ICalFormatImpl::writeICalDateTime(const QDateTime &dt )
{
icaltimetype t;
t.is_date = 0;
t.zone = 0;
QDateTime datetime;
if ( mParent->utc() ) {
int offset = KGlobal::locale()->localTimeOffset( dt );
datetime = dt.addSecs ( -offset*60);
t.is_utc = 1;
}
else {
datetime = dt;
t.is_utc = 0;
}
t.year = datetime.date().year();
t.month = datetime.date().month();
t.day = datetime.date().day();
t.hour = datetime.time().hour();
t.minute = datetime.time().minute();
t.second = datetime.time().second();
//qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() );
// if ( mParent->utc() ) {
// datetime = KGlobal::locale()->localTime( dt );
// qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() );
// if (mParent->timeZoneId().isEmpty())
// t = icaltime_as_utc(t, 0);
// else
// t = icaltime_as_utc(t,mParent->timeZoneId().local8Bit());
// }
return t;
}
QDateTime ICalFormatImpl::readICalDateTime(icaltimetype t)
{
QDateTime dt (QDate(t.year,t.month,t.day),
QTime(t.hour,t.minute,t.second) );
if (t.is_utc) {
int offset = KGlobal::locale()->localTimeOffset( dt );
dt = dt.addSecs ( offset*60);
}
return dt;
}
QDate ICalFormatImpl::readICalDate(icaltimetype t)
{
return QDate(t.year,t.month,t.day);
}
icaldurationtype ICalFormatImpl::writeICalDuration(int seconds)
{
icaldurationtype d;
- d.weeks = seconds % gSecondsPerWeek;
- seconds -= d.weeks * gSecondsPerWeek;
- d.days = seconds % gSecondsPerDay;
- seconds -= d.days * gSecondsPerDay;
- d.hours = seconds % gSecondsPerHour;
- seconds -= d.hours * gSecondsPerHour;
- d.minutes = seconds % gSecondsPerMinute;
- seconds -= d.minutes * gSecondsPerMinute;
+ d.is_neg = (seconds<0)?1:0;
+ if (seconds<0) seconds = -seconds;
+
+ d.weeks = seconds / gSecondsPerWeek;
+ seconds %= gSecondsPerWeek;
+ d.days = seconds / gSecondsPerDay;
+ seconds %= gSecondsPerDay;
+ d.hours = seconds / gSecondsPerHour;
+ seconds %= gSecondsPerHour;
+ d.minutes = seconds / gSecondsPerMinute;
+ seconds %= gSecondsPerMinute;
d.seconds = seconds;
- d.is_neg = 0;
-
return d;
}
int ICalFormatImpl::readICalDuration(icaldurationtype d)
{
int result = 0;
result += d.weeks * gSecondsPerWeek;
result += d.days * gSecondsPerDay;
result += d.hours * gSecondsPerHour;
result += d.minutes * gSecondsPerMinute;
result += d.seconds;
if (d.is_neg) result *= -1;
return result;
}
icalcomponent *ICalFormatImpl::createCalendarComponent(Calendar *cal)
{
icalcomponent *calendar;
// Root component
calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
icalproperty *p;
// Product Identifier
p = icalproperty_new_prodid(CalFormat::productId().utf8());
icalcomponent_add_property(calendar,p);
// TODO: Add time zone
// iCalendar version (2.0)
p = icalproperty_new_version(const_cast<char *>(_ICAL_VERSION));
icalcomponent_add_property(calendar,p);
// Custom properties
if( cal != 0 )
writeCustomProperties(calendar, cal);
return calendar;
}
// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc.
// and break it down from its tree-like format into the dictionary format
// that is used internally in the ICalFormatImpl.
bool ICalFormatImpl::populate( Calendar *cal, icalcomponent *calendar)
{
// this function will populate the caldict dictionary and other event
// lists. It turns vevents into Events and then inserts them.
if (!calendar) return false;
// TODO: check for METHOD
#if 0
if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
char *methodType = 0;
methodType = fakeCString(vObjectUStringZValue(curVO));
if (mEnableDialogs)
KMessageBox::information(mTopWidget,
i18n("This calendar is an iTIP transaction of type \"%1\".")
diff --git a/libkcal/incidencebase.cpp b/libkcal/incidencebase.cpp
index 51f2e9d..1e99082 100644
--- a/libkcal/incidencebase.cpp
+++ b/libkcal/incidencebase.cpp
@@ -45,135 +45,142 @@ IncidenceBase::IncidenceBase() :
mSyncStatus = 0;
mAttendees.setAutoDelete( true );
}
IncidenceBase::IncidenceBase(const IncidenceBase &i) :
CustomProperties( i )
{
mReadOnly = i.mReadOnly;
mDtStart = i.mDtStart;
mDuration = i.mDuration;
mHasDuration = i.mHasDuration;
mOrganizer = i.mOrganizer;
mUid = i.mUid;
QPtrList<Attendee> attendees = i.attendees();
for( Attendee *a = attendees.first(); a; a = attendees.next() ) {
mAttendees.append( new Attendee( *a ) );
}
mFloats = i.mFloats;
mLastModified = i.mLastModified;
mPilotId = i.mPilotId;
mTempSyncStat = i.mTempSyncStat;
mSyncStatus = i.mSyncStatus;
mExternalId = i.mExternalId;
// The copied object is a new one, so it isn't observed by the observer
// of the original object.
mObservers.clear();
mAttendees.setAutoDelete( true );
}
IncidenceBase::~IncidenceBase()
{
}
bool KCal::operator==( const IncidenceBase& i1, const IncidenceBase& i2 )
{
// do not compare mSyncStatus and mExternalId
if( i1.attendees().count() != i2.attendees().count() ) {
return false; // no need to check further
}
if ( i1.attendees().count() > 0 ) {
Attendee * a1 = i1.attendees().first(), *a2 =i2.attendees().first() ;
while ( a1 ) {
if ( !( (*a1) == (*a2)) )
{
//qDebug("Attendee not equal ");
return false;
}
a1 = i1.attendees().next();
a2 = i2.attendees().next();
}
}
//if ( i1.dtStart() != i2.dtStart() )
// return false;
#if 0
qDebug("1 %d ",i1.doesFloat() == i2.doesFloat() );
qDebug("1 %d ",i1.duration() == i2.duration() );
qDebug("3 %d ",i1.hasDuration() == i2.hasDuration() );
qDebug("1 %d ",i1.pilotId() == i2.pilotId() );
qDebug("1 %d %d %d",i1.syncStatus() == i2.syncStatus() , i1.syncStatus(),i2.syncStatus() );
qDebug("6 %d ",i1.organizer() == i2.organizer() );
#endif
+ if ( i1.hasDuration() == i2.hasDuration() ) {
+ if ( i1.hasDuration() ) {
+ if ( i1.duration() != i2.duration() )
+ return false;
+ }
+ } else {
+ return false;
+ }
+
return ( i1.organizer() == i2.organizer() &&
// i1.uid() == i2.uid() &&
// Don't compare lastModified, otherwise the operator is not
// of much use. We are not comparing for identity, after all.
i1.doesFloat() == i2.doesFloat() &&
- i1.duration() == i2.duration() &&
- i1.hasDuration() == i2.hasDuration() &&
i1.pilotId() == i2.pilotId() );// && i1.syncStatus() == i2.syncStatus() );
// no need to compare mObserver
}
QDateTime IncidenceBase::getEvenTime( QDateTime dt )
{
QTime t = dt.time();
dt.setTime( QTime (t.hour (), t.minute (), t.second () ) );
return dt;
}
void IncidenceBase::setUid(const QString &uid)
{
mUid = uid;
updated();
}
QString IncidenceBase::uid() const
{
return mUid;
}
void IncidenceBase::setLastModified(const QDateTime &lm)
{
// DON'T! updated() because we call this from
// Calendar::updateEvent().
mLastModified = getEvenTime(lm);
//qDebug("IncidenceBase::setLastModified %s ",lm.toString().latin1());
}
QDateTime IncidenceBase::lastModified() const
{
return mLastModified;
}
void IncidenceBase::setOrganizer(const QString &o)
{
// we don't check for readonly here, because it is
// possible that by setting the organizer we are changing
// the event's readonly status...
mOrganizer = o;
if (mOrganizer.left(7).upper() == "MAILTO:")
mOrganizer = mOrganizer.remove(0,7);
updated();
}
QString IncidenceBase::organizer() const
{
return mOrganizer;
}
void IncidenceBase::setReadOnly( bool readOnly )
{
mReadOnly = readOnly;
}
void IncidenceBase::setDtStart(const QDateTime &dtStart)
{
// if (mReadOnly) return;
mDtStart = getEvenTime(dtStart);
updated();