24 #include "incidenceformatter.h"
26 #include <libkcal/attachment.h>
27 #include <libkcal/event.h>
28 #include <libkcal/todo.h>
29 #include <libkcal/journal.h>
31 #include <libkcal/calendarlocal.h>
32 #include <libkcal/icalformat.h>
33 #include <libkcal/freebusy.h>
36 #include <libemailfunctions/email.h>
38 #include <ktnef/ktnefparser.h>
39 #include <ktnef/ktnefmessage.h>
40 #include <ktnef/ktnefdefs.h>
41 #include <tdeabc/phonenumber.h>
42 #include <tdeabc/vcardconverter.h>
43 #include <tdeabc/stdaddressbook.h>
45 #include <tdeapplication.h>
46 #include <tdeemailsettings.h>
48 #include <tdelocale.h>
49 #include <tdeglobal.h>
50 #include <kiconloader.h>
51 #include <kcalendarsystem.h>
52 #include <kmimetype.h>
55 #include <tqstylesheet.h>
56 #include <tqdatetime.h>
67 static TQString htmlAddLink(
const TQString &ref,
const TQString &text,
70 TQString tmpStr(
"<a href=\"" + ref +
"\">" + text +
"</a>" );
71 if ( newline ) tmpStr +=
"\n";
75 static TQString htmlAddTag(
const TQString & tag,
const TQString & text )
77 int numLineBreaks = text.contains(
"\n" );
78 TQString str =
"<" + tag +
">";
79 TQString tmpText = text;
80 TQString tmpStr = str;
81 if( numLineBreaks >= 0 ) {
82 if ( numLineBreaks > 0) {
85 for(
int i = 0; i <= numLineBreaks; i++ ) {
86 pos = tmpText.find(
"\n" );
87 tmp = tmpText.left( pos );
88 tmpText = tmpText.right( tmpText.length() - pos - 1 );
89 tmpStr += tmp +
"<br>";
95 tmpStr +=
"</" + tag +
">";
99 static bool iamAttendee(
Attendee *attendee )
104 KEMailSettings settings;
105 TQStringList profiles = settings.profiles();
106 for( TQStringList::Iterator it=profiles.begin(); it!=profiles.end(); ++it ) {
107 settings.setProfile( *it );
108 if ( settings.getSetting( KEMailSettings::EmailAddress ) == attendee->email() ) {
116 static bool iamOrganizer(
Incidence *incidence )
125 KEMailSettings settings;
126 TQStringList profiles = settings.profiles();
127 for( TQStringList::Iterator it=profiles.begin(); it!=profiles.end(); ++it ) {
128 settings.setProfile( *it );
129 if ( settings.getSetting( KEMailSettings::EmailAddress ) == incidence->organizer().email() ) {
137 static bool senderIsOrganizer(
Incidence *incidence,
const TQString &sender )
141 if ( !incidence || sender.isEmpty() ) {
145 TQString senderName, senderEmail;
146 if ( KPIM::getNameAndMail( sender, senderName, senderEmail ) ) {
148 if ( incidence->organizer().email() != senderEmail &&
149 incidence->organizer().name() != senderName ) {
156 static TQString firstAttendeeName(
Incidence *incidence,
const TQString &defName )
164 if( attendees.count() > 0 ) {
165 Attendee *attendee = *attendees.begin();
166 name = attendee->name();
167 if ( name.isEmpty() ) {
168 name = attendee->email();
170 if ( name.isEmpty() ) {
181 static TQString displayViewLinkPerson(
const TQString& email, TQString name, TQString uid )
185 if ( !email.isEmpty() && ( name.isEmpty() || uid.isEmpty() ) ) {
186 TDEABC::AddressBook *add_book = TDEABC::StdAddressBook::self(
true );
187 TDEABC::Addressee::List addressList = add_book->findByEmail( email );
188 if ( !addressList.isEmpty() ) {
189 TDEABC::Addressee o = addressList.first();
190 if ( !o.isEmpty() && addressList.size() < 2 ) {
191 if ( name.isEmpty() ) {
193 name = o.formattedName();
205 if ( !uid.isEmpty() ) {
207 if ( name.isEmpty() ) {
209 tmpString += htmlAddLink(
"uid:" + uid, email );
211 tmpString += htmlAddLink(
"uid:" + uid, name );
215 tmpString += ( name.isEmpty() ? email : name );
219 if ( !email.isEmpty() ) {
221 mailto.setProtocol(
"mailto" );
222 mailto.setPath( email );
223 const TQString iconPath =
224 TDEGlobal::iconLoader()->iconPath(
"mail-message-new", TDEIcon::Small );
225 tmpString +=
" " +
226 htmlAddLink( mailto.url(),
227 "<img valign=\"top\" src=\"" + iconPath +
"\">" );
233 static TQString displayViewFormatAttendeeRoleList(
Incidence *incidence, Attendee::Role role )
236 Attendee::List::ConstIterator it;
239 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
241 if ( a->
role() != role ) {
245 if ( a->email() == incidence->organizer().email() ) {
249 tmpStr += displayViewLinkPerson( a->email(), a->name(), a->
uid() );
251 tmpStr += i18n(
" (delegated by %1)" ).arg( a->
delegator() );
254 tmpStr += i18n(
" (delegated to %1)" ).arg( a->
delegate() );
258 if ( tmpStr.endsWith(
"<br>" ) ) {
259 tmpStr.truncate( tmpStr.length() - 4 );
264 static TQString displayViewFormatAttendees(
Incidence *incidence )
266 TQString tmpStr, str;
269 int attendeeCount = incidence->
attendees().count();
270 if ( attendeeCount > 1 ||
271 ( attendeeCount == 1 &&
272 incidence->organizer().email() != incidence->
attendees().first()->email() ) ) {
274 tmpStr +=
"<td><b>" + i18n(
"Organizer:" ) +
"</b></td>";
276 displayViewLinkPerson( incidence->organizer().email(),
277 incidence->organizer().name(),
284 str = displayViewFormatAttendeeRoleList( incidence, Attendee::Chair );
285 if ( !str.isEmpty() ) {
287 tmpStr +=
"<td><b>" + i18n(
"Chair:" ) +
"</b></td>";
288 tmpStr +=
"<td>" + str +
"</td>";
293 str = displayViewFormatAttendeeRoleList( incidence, Attendee::ReqParticipant );
294 if ( !str.isEmpty() ) {
296 tmpStr +=
"<td><b>" + i18n(
"Required Participants:" ) +
"</b></td>";
297 tmpStr +=
"<td>" + str +
"</td>";
302 str = displayViewFormatAttendeeRoleList( incidence, Attendee::OptParticipant );
303 if ( !str.isEmpty() ) {
305 tmpStr +=
"<td><b>" + i18n(
"Optional Participants:" ) +
"</b></td>";
306 tmpStr +=
"<td>" + str +
"</td>";
311 str = displayViewFormatAttendeeRoleList( incidence, Attendee::NonParticipant );
312 if ( !str.isEmpty() ) {
314 tmpStr +=
"<td><b>" + i18n(
"Observers:" ) +
"</b></td>";
315 tmpStr +=
"<td>" + str +
"</td>";
322 static TQString displayViewFormatAttachments(
Incidence *incidence )
326 Attachment::List::ConstIterator it;
328 for( it = as.begin(); it != as.end(); ++it ) {
330 if ( (*it)->isUri() ) {
332 if ( (*it)->uri().startsWith(
"kmail:" ) ) {
333 name = i18n(
"Show mail" );
335 if ( (*it)->label().isEmpty() ) {
338 name = (*it)->label();
341 tmpStr += htmlAddLink( (*it)->uri(), name );
343 tmpStr += htmlAddLink(
"ATTACH:" + incidence->
uid() +
':' + (*it)->label(),
344 (*it)->label(), false );
346 if ( count < as.count() ) {
353 static TQString displayViewFormatCategories(
Incidence *incidence )
359 static TQString displayViewFormatCreationDate(
Incidence *incidence )
361 return i18n(
"Creation date: %1" ).
362 arg( IncidenceFormatter::dateTimeToString( incidence->
created(),
false, true ) );
365 static TQString displayViewFormatBirthday(
Event *event )
374 TQString uid =
event->customProperty(
"KABC",
"UID-1");
375 TQString name =
event->customProperty(
"KABC",
"NAME-1");
376 TQString email=
event->customProperty(
"KABC",
"EMAIL-1");
378 TQString tmpStr = displayViewLinkPerson( email, name, uid );
381 uid =
event->customProperty(
"KABC",
"UID-2");
382 name =
event->customProperty(
"KABC",
"NAME-2");
383 email=
event->customProperty(
"KABC",
"EMAIL-2");
385 tmpStr += displayViewLinkPerson( email, name, uid );
391 static TQString displayViewFormatHeader(
Incidence *incidence )
393 TQString tmpStr =
"<table><tr>";
399 if ( incidence->type() ==
"Event" ) {
402 if ( incidence->
customProperty(
"KABC",
"ANNIVERSARY" ) ==
"YES" ) {
404 TDEGlobal::iconLoader()->iconPath(
"calendaranniversary", TDEIcon::Small );
406 iconPath = TDEGlobal::iconLoader()->iconPath(
"calendarbirthday", TDEIcon::Small );
409 iconPath = TDEGlobal::iconLoader()->iconPath(
"appointment", TDEIcon::Small );
411 tmpStr +=
"<img valign=\"top\" src=\"" + iconPath +
"\">";
413 if ( incidence->type() ==
"Todo" ) {
414 tmpStr +=
"<img valign=\"top\" src=\"" +
415 TDEGlobal::iconLoader()->iconPath(
"todo", TDEIcon::Small ) +
418 if ( incidence->type() ==
"Journal" ) {
419 tmpStr +=
"<img valign=\"top\" src=\"" +
420 TDEGlobal::iconLoader()->iconPath(
"journal", TDEIcon::Small ) +
424 tmpStr +=
"<img valign=\"top\" src=\"" +
425 TDEGlobal::iconLoader()->iconPath(
"bell", TDEIcon::Small ) +
429 tmpStr +=
"<img valign=\"top\" src=\"" +
430 TDEGlobal::iconLoader()->iconPath(
"recur", TDEIcon::Small ) +
434 tmpStr +=
"<img valign=\"top\" src=\"" +
435 TDEGlobal::iconLoader()->iconPath(
"readonlyevent", TDEIcon::Small ) +
443 tmpStr +=
"<b><u>" + incidence->
summary() +
"</u></b>";
446 tmpStr +=
"</tr></table>";
451 static TQString displayViewFormatEvent(
Calendar *calendar,
Event *event,
458 TQString tmpStr = displayViewFormatHeader( event );
461 tmpStr +=
"<col width=\"25%\"/>";
462 tmpStr +=
"<col width=\"75%\"/>";
466 if ( !calStr.isEmpty() ) {
468 tmpStr +=
"<td><b>" + i18n(
"Calendar:" ) +
"</b></td>";
469 tmpStr +=
"<td>" + calStr +
"</td>";
474 if ( !event->
location().isEmpty() ) {
476 tmpStr +=
"<td><b>" + i18n(
"Location:" ) +
"</b></td>";
477 tmpStr +=
"<td>" +
event->location() +
"</td>";
481 TQDateTime startDt =
event->dtStart();
482 TQDateTime endDt =
event->dtEnd();
484 if ( date.isValid() ) {
485 TQDateTime dt( date, TQTime( 0, 0, 0 ) );
486 int diffDays = startDt.daysTo( dt );
487 dt = dt.addSecs( -1 );
490 endDt = endDt.addDays( diffDays );
491 if ( startDt > endDt ) {
493 endDt = startDt.addDays( event->
dtStart().daysTo( event->
dtEnd() ) );
502 tmpStr +=
"<td><b>" + i18n(
"Date:" ) +
"</b></td>";
504 i18n(
"<beginDate> - <endDate>",
"%1 - %2").
505 arg( IncidenceFormatter::dateToString( startDt,
false ) ).
506 arg( IncidenceFormatter::dateToString( endDt,
false ) ) +
509 tmpStr +=
"<td><b>" + i18n(
"Date:" ) +
"</b></td>";
511 i18n(
"date as string",
"%1").
512 arg( IncidenceFormatter::dateToString( startDt,
false ) ) +
517 tmpStr +=
"<td><b>" + i18n(
"Date:" ) +
"</b></td>";
519 i18n(
"<beginDate> - <endDate>",
"%1 - %2").
520 arg( IncidenceFormatter::dateToString( startDt,
false ) ).
521 arg( IncidenceFormatter::dateToString( endDt,
false ) ) +
524 tmpStr +=
"<td><b>" + i18n(
"Date:" ) +
"</b></td>";
526 i18n(
"date as string",
"%1").
527 arg( IncidenceFormatter::dateToString( startDt,
false ) ) +
530 tmpStr +=
"</tr><tr>";
531 tmpStr +=
"<td><b>" + i18n(
"Time:" ) +
"</b></td>";
532 if ( event->
hasEndDate() && startDt != endDt ) {
534 i18n(
"<beginTime> - <endTime>",
"%1 - %2").
535 arg( IncidenceFormatter::timeToString( startDt,
true ) ).
536 arg( IncidenceFormatter::timeToString( endDt,
true ) ) +
540 IncidenceFormatter::timeToString( startDt,
true ) +
548 if ( !durStr.isEmpty() ) {
550 tmpStr +=
"<td><b>" + i18n(
"Duration:" ) +
"</b></td>";
551 tmpStr +=
"<td>" + durStr +
"</td>";
557 tmpStr +=
"<td><b>" + i18n(
"Recurrence:" ) +
"</b></td>";
559 IncidenceFormatter::recurrenceString( event ) +
567 tmpStr +=
"<td><b>" + i18n(
"Anniversary:" ) +
"</b></td>";
569 tmpStr +=
"<td><b>" + i18n(
"Birthday:" ) +
"</b></td>";
571 tmpStr +=
"<td>" + displayViewFormatBirthday( event ) +
"</td>";
573 tmpStr +=
"</table>";
579 tmpStr +=
"<td><b>" + i18n(
"Description:" ) +
"</b></td>";
580 tmpStr +=
"<td>" +
event->description() +
"</td>";
586 int reminderCount =
event->alarms().count();
589 tmpStr +=
"<td><b>" +
590 i18n(
"Reminder:",
"%n Reminders:", reminderCount ) +
592 tmpStr +=
"<td>" + IncidenceFormatter::reminderStringList( event ).join(
"<br>" ) +
"</td>";
596 tmpStr += displayViewFormatAttendees( event );
598 int categoryCount =
event->categories().count();
599 if ( categoryCount > 0 ) {
601 tmpStr +=
"<td><b>" +
602 i18n(
"Category:",
"%n Categories:", categoryCount ) +
604 tmpStr +=
"<td>" + displayViewFormatCategories( event ) +
"</td>";
608 int attachmentCount =
event->attachments().count();
609 if ( attachmentCount > 0 ) {
611 tmpStr +=
"<td><b>" +
612 i18n(
"Attachment:",
"%n Attachments:", attachmentCount ) +
614 tmpStr +=
"<td>" + displayViewFormatAttachments( event ) +
"</td>";
617 tmpStr +=
"</table>";
619 tmpStr +=
"<em>" + displayViewFormatCreationDate( event ) +
"</em>";
624 static TQString displayViewFormatTodo(
Calendar *calendar,
Todo *todo,
631 TQString tmpStr = displayViewFormatHeader( todo );
634 tmpStr +=
"<col width=\"25%\"/>";
635 tmpStr +=
"<col width=\"75%\"/>";
639 if ( !calStr.isEmpty() ) {
641 tmpStr +=
"<td><b>" + i18n(
"Calendar:" ) +
"</b></td>";
642 tmpStr +=
"<td>" + calStr +
"</td>";
647 if ( !todo->
location().isEmpty() ) {
649 tmpStr +=
"<td><b>" + i18n(
"Location:" ) +
"</b></td>";
650 tmpStr +=
"<td>" + todo->
location() +
"</td>";
655 TQDateTime startDt = todo->
dtStart();
657 if ( date.isValid() ) {
658 startDt.setDate( date );
662 tmpStr +=
"<td><b>" + i18n(
"Start:" ) +
"</b></td>";
664 IncidenceFormatter::dateTimeToString( startDt,
671 TQDateTime dueDt = todo->
dtDue();
673 if ( date.isValid() ) {
674 TQDateTime dt( date, TQTime( 0, 0, 0 ) );
675 dt = dt.addSecs( -1 );
680 tmpStr +=
"<td><b>" + i18n(
"Due:" ) +
"</b></td>";
682 IncidenceFormatter::dateTimeToString( dueDt,
689 if ( !durStr.isEmpty() ) {
691 tmpStr +=
"<td><b>" + i18n(
"Duration:" ) +
"</b></td>";
692 tmpStr +=
"<td>" + durStr +
"</td>";
698 tmpStr +=
"<td><b>" + i18n(
"Recurrence:" ) +
"</b></td>";
700 IncidenceFormatter::recurrenceString( todo ) +
707 tmpStr +=
"<td><b>" + i18n(
"Description:" ) +
"</b></td>";
714 int reminderCount = todo->
alarms().count();
717 tmpStr +=
"<td><b>" +
718 i18n(
"Reminder:",
"%n Reminders:", reminderCount ) +
720 tmpStr +=
"<td>" + IncidenceFormatter::reminderStringList( todo ).join(
"<br>" ) +
"</td>";
724 tmpStr += displayViewFormatAttendees( todo );
726 int categoryCount = todo->
categories().count();
727 if ( categoryCount > 0 ) {
729 tmpStr +=
"<td><b>" +
730 i18n(
"Category:",
"%n Categories:", categoryCount ) +
732 tmpStr +=
"<td>" + displayViewFormatCategories( todo ) +
"</td>";
738 tmpStr +=
"<td><b>" + i18n(
"Priority:" ) +
"</b></td>";
740 tmpStr += TQString::number( todo->
priority() );
747 tmpStr +=
"<td><b>" + i18n(
"Completed:" ) +
"</b></td>";
751 tmpStr +=
"<td><b>" + i18n(
"Percent Done:" ) +
"</b></td>";
759 if ( attachmentCount > 0 ) {
761 tmpStr +=
"<td><b>" +
762 i18n(
"Attachment:",
"Attachments:", attachmentCount ) +
764 tmpStr +=
"<td>" + displayViewFormatAttachments( todo ) +
"</td>";
768 tmpStr +=
"</table>";
770 tmpStr +=
"<em>" + displayViewFormatCreationDate( todo ) +
"</em>";
775 static TQString displayViewFormatJournal(
Calendar *calendar,
Journal *journal )
781 TQString tmpStr = displayViewFormatHeader( journal );
784 tmpStr +=
"<col width=\"25%\"/>";
785 tmpStr +=
"<col width=\"75%\"/>";
789 if ( !calStr.isEmpty() ) {
791 tmpStr +=
"<td><b>" + i18n(
"Calendar:" ) +
"</b></td>";
792 tmpStr +=
"<td>" + calStr +
"</td>";
798 tmpStr +=
"<td><b>" + i18n(
"Date:" ) +
"</b></td>";
800 IncidenceFormatter::dateToString( journal->
dtStart(), false ) +
806 tmpStr +=
"<td><b>" + i18n(
"Description:" ) +
"</b></td>";
807 tmpStr +=
"<td>" + journal->
description() +
"</td>";
811 int categoryCount = journal->
categories().count();
812 if ( categoryCount > 0 ) {
814 tmpStr +=
"<td><b>" +
815 i18n(
"Category:",
"%n Categories:", categoryCount ) +
817 tmpStr +=
"<td>" + displayViewFormatCategories( journal ) +
"</td>";
820 tmpStr +=
"</table>";
822 tmpStr +=
"<em>" + displayViewFormatCreationDate( journal ) +
"</em>";
833 TQString tmpStr = htmlAddTag(
"h2",
835 i18n(
"Free/Busy information for %1").
836 arg( fb->organizer().fullName() ) ) );
838 tmpStr += htmlAddTag(
"h4", i18n(
"Busy times in date range %1 - %2:").
839 arg( IncidenceFormatter::dateToString( fb->
dtStart(), true ) ).
840 arg( IncidenceFormatter::dateToString( fb->dtEnd(), true ) ) );
842 TQValueList<Period> periods = fb->busyPeriods();
844 TQString text = htmlAddTag(
"em", htmlAddTag(
"b", i18n(
"Busy:") ) );
845 TQValueList<Period>::iterator it;
846 for ( it = periods.begin(); it != periods.end(); ++it ) {
848 if ( per.hasDuration() ) {
852 cont += i18n(
"1 hour ",
"%n hours ", dur / 3600 );
856 cont += i18n(
"1 minute ",
"%n minutes ", dur / 60);
860 cont += i18n(
"1 second",
"%n seconds", dur);
862 text += i18n(
"startDate for duration",
"%1 for %2").
863 arg( IncidenceFormatter::dateTimeToString( per.start(),
false, true ) ).
867 if ( per.start().date() == per.end().date() ) {
868 text += i18n(
"date, fromTime - toTime ",
"%1, %2 - %3").
869 arg( IncidenceFormatter::dateToString( per.start().date(), true ) ).
870 arg( IncidenceFormatter::timeToString( per.start(), true ) ).
871 arg( IncidenceFormatter::timeToString( per.end(), true ) );
873 text += i18n(
"fromDateTime - toDateTime",
"%1 - %2").
874 arg( IncidenceFormatter::dateTimeToString( per.start(),
false, true ) ).
875 arg( IncidenceFormatter::dateTimeToString( per.end(),
false, true ) );
880 tmpStr += htmlAddTag(
"p", text );
888 : mCalendar( 0 ), mResult(
"" ) {}
892 mCalendar = calendar;
895 return incidence->
accept( *
this );
897 TQString result()
const {
return mResult; }
900 bool visit(
Event *event )
902 mResult = displayViewFormatEvent( mCalendar, event, mDate );
903 return !mResult.isEmpty();
905 bool visit(
Todo *todo )
907 mResult = displayViewFormatTodo( mCalendar, todo, mDate );
908 return !mResult.isEmpty();
912 mResult = displayViewFormatJournal( mCalendar, journal );
913 return !mResult.isEmpty();
917 mResult = displayViewFormatFreeBusy( mCalendar, fb );
918 return !mResult.isEmpty();
927 TQString IncidenceFormatter::extensiveDisplayString(
IncidenceBase *incidence )
929 return extensiveDisplayStr( 0, incidence, TQDate() );
932 TQString IncidenceFormatter::extensiveDisplayStr(
Calendar *calendar,
940 EventViewerVisitor v;
941 if ( v.act( calendar, incidence, date ) ) {
952 static TQString string2HTML(
const TQString& str )
954 return TQStyleSheet::convertFromPlainText(str, TQStyleSheetItem::WhiteSpaceNormal);
957 static TQString cleanHtml(
const TQString &html )
959 TQRegExp rx(
"<body[^>]*>(.*)</body>" );
960 rx.setCaseSensitive(
false );
962 TQString body = rx.cap( 1 );
964 return TQStyleSheet::escape( body.remove( TQRegExp(
"<[^>]*>" ) ).stripWhiteSpace() );
967 static TQString eventStartTimeStr(
Event *event )
971 tmp = i18n(
"%1: Start Date, %2: Start Time",
"%1 %2" ).
972 arg( IncidenceFormatter::dateToString( event->
dtStart(), true ),
973 IncidenceFormatter::timeToString( event->
dtStart(), true ) );
975 tmp = i18n(
"%1: Start Date",
"%1 (all day)" ).
976 arg( IncidenceFormatter::dateToString( event->
dtStart(), true ) );
981 static TQString eventEndTimeStr(
Event *event )
984 if ( event->
hasEndDate() &&
event->dtEnd().isValid() ) {
986 tmp = i18n(
"%1: End Date, %2: End Time",
"%1 %2" ).
987 arg( IncidenceFormatter::dateToString( event->
dtEnd(), true ),
988 IncidenceFormatter::timeToString( event->
dtEnd(), true ) );
990 tmp = i18n(
"%1: End Date",
"%1 (all day)" ).
991 arg( IncidenceFormatter::dateToString( event->
dtEnd(), true ) );
997 static TQString invitationRow(
const TQString &cell1,
const TQString &cell2 )
999 return "<tr><td>" + cell1 +
"</td><td>" + cell2 +
"</td></tr>\n";
1011 KEMailSettings settings;
1012 TQStringList profiles = settings.profiles();
1013 for( TQStringList::Iterator it=profiles.begin(); it!=profiles.end(); ++it ) {
1014 settings.setProfile( *it );
1016 TQString delegatorName, delegatorEmail;
1018 Attendee::List::ConstIterator it2;
1019 for ( it2 = attendees.begin(); it2 != attendees.end(); ++it2 ) {
1021 KPIM::getNameAndMail( a->
delegator(), delegatorName, delegatorEmail );
1022 if ( settings.getSetting( KEMailSettings::EmailAddress ) == delegatorEmail ) {
1040 KEMailSettings settings;
1041 TQStringList profiles = settings.profiles();
1042 for( TQStringList::Iterator it=profiles.begin(); it!=profiles.end(); ++it ) {
1043 settings.setProfile( *it );
1046 Attendee::List::ConstIterator it2;
1047 for ( it2 = attendees.begin(); it2 != attendees.end(); ++it2 ) {
1049 if ( settings.getSetting( KEMailSettings::EmailAddress ) == a->email() ) {
1068 Attendee::List::ConstIterator it;
1069 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
1071 if ( email == a->email() ) {
1079 static bool rsvpRequested(
Incidence *incidence )
1089 Attendee::List::ConstIterator it;
1090 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
1091 if ( it == attendees.begin() ) {
1092 rsvp = (*it)->RSVP();
1094 if ( (*it)->RSVP() != rsvp ) {
1103 static TQString rsvpRequestedStr(
bool rsvpRequested,
const TQString &role )
1105 if ( rsvpRequested ) {
1106 if ( role.isEmpty() ) {
1107 return i18n(
"Your response is requested" );
1109 return i18n(
"Your response as <b>%1</b> is requested" ).arg( role );
1112 if ( role.isEmpty() ) {
1113 return i18n(
"No response is necessary" );
1115 return i18n(
"No response as <b>%1</b> is necessary" ).arg( role );
1120 static TQString myStatusStr(
Incidence *incidence )
1123 Attendee *a = findMyAttendee( incidence );
1125 a->
status() != Attendee::NeedsAction && a->
status() != Attendee::Delegated ) {
1126 ret = i18n(
"(<b>Note</b>: the Organizer preset your response to <b>%1</b>)" ).
1132 static TQString invitationPerson(
const TQString& email, TQString name, TQString uid )
1136 if ( !email.isEmpty() && ( name.isEmpty() || uid.isEmpty() ) ) {
1137 TDEABC::AddressBook *add_book = TDEABC::StdAddressBook::self(
true );
1138 TDEABC::Addressee::List addressList = add_book->findByEmail( email );
1139 if ( !addressList.isEmpty() ) {
1140 TDEABC::Addressee o = addressList.first();
1141 if ( !o.isEmpty() && addressList.size() < 2 ) {
1142 if ( name.isEmpty() ) {
1144 name = o.formattedName();
1156 if ( !uid.isEmpty() ) {
1158 if ( name.isEmpty() ) {
1160 tmpString += htmlAddLink(
"uid:" + uid, email );
1162 tmpString += htmlAddLink(
"uid:" + uid, name );
1166 tmpString += ( name.isEmpty() ? email : name );
1171 if ( !email.isEmpty() ) {
1174 mailto.setProtocol(
"mailto" );
1175 mailto.setPath( person.fullName() );
1176 const TQString iconPath =
1177 TDEGlobal::iconLoader()->iconPath(
"mail-message-new", TDEIcon::Small );
1178 tmpString +=
" " +
1179 htmlAddLink( mailto.url(),
"<img src=\"" + iconPath +
"\">" )
1187 static TQString invitationsDetailsIncidence(
Incidence *incidence,
bool noHtmlMode )
1195 TQStringList comments;
1197 if ( incidence->
comments().isEmpty() ) {
1200 if ( !TQStyleSheet::mightBeRichText( incidence->
description() ) ) {
1201 comments << string2HTML( incidence->
description() );
1205 comments[0] = cleanHtml( comments[0] );
1207 comments[0] = htmlAddTag(
"p", comments[0] );
1213 TQStringList cl = incidence->
comments();
1215 for( TQStringList::Iterator it=cl.begin(); it!=cl.end(); ++it ) {
1216 if ( !TQStyleSheet::mightBeRichText( *it ) ) {
1217 comments.append( string2HTML( *it ) );
1220 comments.append( cleanHtml(
"<body>" + (*it) +
"</body>" ) );
1222 comments.append( *it );
1229 if ( !TQStyleSheet::mightBeRichText( incidence->
description() ) ) {
1234 descr = cleanHtml( descr );
1236 descr = htmlAddTag(
"p", descr );
1241 if( !descr.isEmpty() ) {
1243 html +=
"<table border=\"0\" style=\"margin-top:4px;\">";
1244 html +=
"<tr><td><center>" +
1245 htmlAddTag(
"u", i18n(
"Description:" ) ) +
1246 "</center></td></tr>";
1247 html +=
"<tr><td>" + descr +
"</td></tr>";
1251 if ( !comments.isEmpty() ) {
1253 html +=
"<table border=\"0\" style=\"margin-top:4px;\">";
1254 html +=
"<tr><td><center>" +
1255 htmlAddTag(
"u", i18n(
"Comments:" ) ) +
1256 "</center></td></tr>";
1258 if ( comments.count() > 1 ) {
1260 for ( uint i=0; i < comments.count(); ++i ) {
1261 html +=
"<li>" + comments[i] +
"</li>";
1265 html += comments[0];
1267 html +=
"</td></tr>";
1273 static TQString invitationDetailsEvent(
Event* event,
bool noHtmlMode )
1280 TQString sSummary = i18n(
"Summary unspecified" );
1281 if ( !event->
summary().isEmpty() ) {
1282 if ( !TQStyleSheet::mightBeRichText( event->
summary() ) ) {
1283 sSummary = TQStyleSheet::escape( event->
summary() );
1285 sSummary =
event->summary();
1287 sSummary = cleanHtml( sSummary );
1292 TQString sLocation = i18n(
"Location unspecified" );
1293 if ( !event->
location().isEmpty() ) {
1294 if ( !TQStyleSheet::mightBeRichText( event->
location() ) ) {
1295 sLocation = TQStyleSheet::escape( event->
location() );
1297 sLocation =
event->location();
1299 sLocation = cleanHtml( sLocation );
1304 TQString dir = ( TQApplication::reverseLayout() ?
"rtl" :
"ltr" );
1305 TQString html = TQString(
"<div dir=\"%1\">\n").arg(dir);
1307 html +=
"<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n";
1310 html += invitationRow( i18n(
"What:" ), sSummary );
1311 html += invitationRow( i18n(
"Where:" ), sLocation );
1314 html += invitationRow( i18n(
"First Start Time:" ), eventStartTimeStr( event ) );
1315 html += invitationRow( i18n(
"First End Time:" ), eventEndTimeStr( event ) );
1319 if ( event->
dtStart().date() ==
event->dtEnd().date() ) {
1320 html += invitationRow( i18n(
"Date:" ),
1321 IncidenceFormatter::dateToString( event->
dtStart(), false ) );
1323 html += invitationRow( i18n(
"Time:" ),
1324 IncidenceFormatter::timeToString( event->
dtStart(), true ) +
1326 IncidenceFormatter::timeToString( event->
dtEnd(), true ) );
1329 html += invitationRow( i18n(
"Starting date of an event",
"From:" ),
1330 IncidenceFormatter::dateToString( event->
dtStart(), false ) );
1332 html += invitationRow( i18n(
"Starting time of an event",
"At:" ),
1333 IncidenceFormatter::timeToString( event->
dtStart(), true ) );
1336 html += invitationRow( i18n(
"Ending date of an event",
"To:" ),
1337 IncidenceFormatter::dateToString( event->
dtEnd(), false ) );
1339 html += invitationRow( i18n(
"Starting time of an event",
"At:" ),
1340 IncidenceFormatter::timeToString( event->
dtEnd(), true ) );
1343 html += invitationRow( i18n(
"Ending date of an event",
"To:" ),
1344 i18n(
"no end date specified" ) );
1351 if ( !durStr.isEmpty() ) {
1352 html += invitationRow( i18n(
"Duration:" ), durStr );
1358 html += invitationRow( i18n(
"Recurrence:" ), IncidenceFormatter::recurrenceString( event ) );
1360 DateList exceptions = recur->exDates();
1361 if (exceptions.isEmpty() ==
false) {
1363 isFirstExRow =
true;
1364 DateList::ConstIterator ex_iter;
1365 for ( ex_iter = exceptions.begin(); ex_iter != exceptions.end(); ++ex_iter ) {
1366 if (isFirstExRow ==
true) {
1367 isFirstExRow =
false;
1368 html += invitationRow( i18n(
"Cancelled on:"), TDEGlobal::locale()->formatDate(* ex_iter ) );
1371 html += invitationRow(
" ", TDEGlobal::locale()->formatDate(* ex_iter ) );
1377 html +=
"</table>\n";
1378 html += invitationsDetailsIncidence( event, noHtmlMode );
1384 static TQString invitationDetailsTodo(
Todo *todo,
bool noHtmlMode )
1391 TQString sSummary = i18n(
"Summary unspecified" );
1392 if ( !todo->
summary().isEmpty() ) {
1393 if ( !TQStyleSheet::mightBeRichText( todo->
summary() ) ) {
1394 sSummary = TQStyleSheet::escape( todo->
summary() );
1398 sSummary = cleanHtml( sSummary );
1403 TQString sLocation = i18n(
"Location unspecified" );
1404 if ( !todo->
location().isEmpty() ) {
1405 if ( !TQStyleSheet::mightBeRichText( todo->
location() ) ) {
1406 sLocation = TQStyleSheet::escape( todo->
location() );
1410 sLocation = cleanHtml( sLocation );
1415 TQString dir = ( TQApplication::reverseLayout() ?
"rtl" :
"ltr" );
1416 TQString html = TQString(
"<div dir=\"%1\">\n").arg(dir);
1417 html +=
"<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n";
1420 html += invitationRow( i18n(
"What:" ), sSummary );
1421 html += invitationRow( i18n(
"Where:" ), sLocation );
1424 html += invitationRow( i18n(
"Start Date:" ),
1425 IncidenceFormatter::dateToString( todo->
dtStart(), false ) );
1427 html += invitationRow( i18n(
"Start Time:" ),
1428 IncidenceFormatter::timeToString( todo->
dtStart(), false ) );
1432 html += invitationRow( i18n(
"Due Date:" ),
1433 IncidenceFormatter::dateToString( todo->
dtDue(), false ) );
1435 html += invitationRow( i18n(
"Due Time:" ),
1436 IncidenceFormatter::timeToString( todo->
dtDue(), false ) );
1440 html += invitationRow( i18n(
"Due Date:" ), i18n(
"Due Date: None",
"None" ) );
1443 html +=
"</table></div>\n";
1444 html += invitationsDetailsIncidence( todo, noHtmlMode );
1449 static TQString invitationDetailsJournal(
Journal *journal,
bool noHtmlMode )
1455 TQString sSummary = i18n(
"Summary unspecified" );
1456 TQString sDescr = i18n(
"Description unspecified" );
1457 if ( ! journal->
summary().isEmpty() ) {
1458 sSummary = journal->
summary();
1460 sSummary = cleanHtml( sSummary );
1466 sDescr = cleanHtml( sDescr );
1469 TQString html(
"<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n" );
1470 html += invitationRow( i18n(
"Summary:" ), sSummary );
1471 html += invitationRow( i18n(
"Date:" ),
1472 IncidenceFormatter::dateToString( journal->
dtStart(), false ) );
1473 html += invitationRow( i18n(
"Description:" ), sDescr );
1474 html +=
"</table>\n";
1475 html += invitationsDetailsIncidence( journal, noHtmlMode );
1480 static TQString invitationDetailsFreeBusy(
FreeBusy *fb,
bool )
1484 TQString html(
"<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n" );
1486 html += invitationRow( i18n(
"Person:"), fb->organizer().fullName() );
1487 html += invitationRow( i18n(
"Start date:"),
1488 IncidenceFormatter::dateToString( fb->
dtStart(), true ) );
1489 html += invitationRow( i18n(
"End date:"),
1490 TDEGlobal::locale()->formatDate( fb->dtEnd().date(), true ) );
1491 html +=
"<tr><td colspan=2><hr></td></tr>\n";
1492 html +=
"<tr><td colspan=2>Busy periods given in this free/busy object:</td></tr>\n";
1494 TQValueList<Period> periods = fb->busyPeriods();
1496 TQValueList<Period>::iterator it;
1497 for ( it = periods.begin(); it != periods.end(); ++it ) {
1499 if ( per.hasDuration() ) {
1502 if ( dur >= 3600 ) {
1503 cont += i18n(
"1 hour ",
"%n hours ", dur / 3600);
1507 cont += i18n(
"1 minute",
"%n minutes ", dur / 60);
1511 cont += i18n(
"1 second",
"%n seconds", dur);
1513 html += invitationRow( TQString(), i18n(
"startDate for duration",
"%1 for %2")
1514 .arg( TDEGlobal::locale()->formatDateTime( per.start(), false ) )
1518 if ( per.start().date() == per.end().date() ) {
1519 cont = i18n(
"date, fromTime - toTime ",
"%1, %2 - %3")
1520 .arg( TDEGlobal::locale()->formatDate( per.start().date() ) )
1521 .arg( TDEGlobal::locale()->formatTime( per.start().time() ) )
1522 .arg( TDEGlobal::locale()->formatTime( per.end().time() ) );
1524 cont = i18n(
"fromDateTime - toDateTime",
"%1 - %2")
1525 .arg( TDEGlobal::locale()->formatDateTime( per.start(), false ) )
1526 .arg( TDEGlobal::locale()->formatDateTime( per.end(), false ) );
1529 html += invitationRow( TQString(), cont );
1533 html +=
"</table>\n";
1537 static bool replyMeansCounter(
Incidence * )
1556 static TQString invitationHeaderEvent(
Event *event,
Incidence *existingIncidence,
1559 if ( !msg || !event )
1562 switch ( msg->
method() ) {
1563 case Scheduler::Publish:
1564 return i18n(
"This invitation has been published" );
1565 case Scheduler::Request:
1566 if ( existingIncidence && event->
revision() > 0 ) {
1567 return i18n(
"This invitation has been updated by the organizer %1" ).
1568 arg( event->organizer().fullName() );
1570 if ( iamOrganizer( event ) ) {
1571 return i18n(
"I created this invitation" );
1574 if ( !event->organizer().fullName().isEmpty() ) {
1575 orgStr =
event->organizer().fullName();
1576 }
else if ( !event->organizer().email().isEmpty() ) {
1577 orgStr =
event->organizer().email();
1579 if ( senderIsOrganizer( event, sender ) ) {
1580 if ( !orgStr.isEmpty() ) {
1581 return i18n(
"You received an invitation from %1" ).arg( orgStr );
1583 return i18n(
"You received an invitation" );
1586 if ( !orgStr.isEmpty() ) {
1587 return i18n(
"You received an invitation from %1 as a representative of %2" ).
1588 arg( sender, orgStr );
1590 return i18n(
"You received an invitation from %1 as the organizer's representative" ).
1595 case Scheduler::Refresh:
1596 return i18n(
"This invitation was refreshed" );
1597 case Scheduler::Cancel:
1598 return i18n(
"This invitation has been canceled" );
1599 case Scheduler::Add:
1600 return i18n(
"Addition to the invitation" );
1601 case Scheduler::Reply:
1603 if ( replyMeansCounter( event ) ) {
1604 return i18n(
"%1 makes this counter proposal" ).
1605 arg( firstAttendeeName( event, i18n(
"Sender" ) ) );
1609 if( attendees.count() == 0 ) {
1610 kdDebug(5850) <<
"No attendees in the iCal reply!" << endl;
1613 if( attendees.count() != 1 ) {
1614 kdDebug(5850) <<
"Warning: attendeecount in the reply should be 1 "
1615 <<
"but is " << attendees.count() << endl;
1617 TQString attendeeName = firstAttendeeName( event, i18n(
"Sender" ) );
1619 TQString delegatorName, dummy;
1620 Attendee* attendee = *attendees.begin();
1621 KPIM::getNameAndMail( attendee->
delegator(), delegatorName, dummy );
1622 if ( delegatorName.isEmpty() ) {
1626 switch( attendee->
status() ) {
1627 case Attendee::NeedsAction:
1628 return i18n(
"%1 indicates this invitation still needs some action" ).arg( attendeeName );
1629 case Attendee::Accepted:
1631 if ( !sender.isEmpty() ) {
1632 return i18n(
"This invitation has been updated by attendee %1" ).arg( sender );
1634 return i18n(
"This invitation has been updated by an attendee" );
1637 if ( delegatorName.isEmpty() ) {
1638 return i18n(
"%1 accepts this invitation" ).arg( attendeeName );
1640 return i18n(
"%1 accepts this invitation on behalf of %2" ).
1641 arg( attendeeName ).arg( delegatorName );
1644 case Attendee::Tentative:
1645 if ( delegatorName.isEmpty() ) {
1646 return i18n(
"%1 tentatively accepts this invitation" ).
1647 arg( attendeeName );
1649 return i18n(
"%1 tentatively accepts this invitation on behalf of %2" ).
1650 arg( attendeeName ).arg( delegatorName );
1652 case Attendee::Declined:
1653 if ( delegatorName.isEmpty() ) {
1654 return i18n(
"%1 declines this invitation" ).arg( attendeeName );
1656 return i18n(
"%1 declines this invitation on behalf of %2" ).
1657 arg( attendeeName ).arg( delegatorName );
1659 case Attendee::Delegated: {
1660 TQString delegate, dummy;
1661 KPIM::getNameAndMail( attendee->
delegate(), delegate, dummy );
1662 if ( delegate.isEmpty() ) {
1665 if ( !delegate.isEmpty() ) {
1666 return i18n(
"%1 has delegated this invitation to %2" ).
1667 arg( attendeeName ) .arg( delegate );
1669 return i18n(
"%1 has delegated this invitation" ).arg( attendeeName );
1672 case Attendee::Completed:
1673 return i18n(
"This invitation is now completed" );
1674 case Attendee::InProcess:
1675 return i18n(
"%1 is still processing the invitation" ).
1676 arg( attendeeName );
1678 return i18n(
"Unknown response to this invitation" );
1683 case Scheduler::Counter:
1684 return i18n(
"%1 makes this counter proposal" ).
1685 arg( firstAttendeeName( event, i18n(
"Sender" ) ) );
1687 case Scheduler::Declinecounter:
1688 return i18n(
"%1 declines the counter proposal" ).
1689 arg( firstAttendeeName( event, i18n(
"Sender" ) ) );
1691 case Scheduler::NoMethod:
1692 return i18n(
"Error: iMIP message with unknown method: '%1'").
1698 static TQString invitationHeaderTodo(
Todo *todo,
Incidence *existingIncidence,
1701 if ( !msg || !todo ) {
1705 switch ( msg->
method() ) {
1706 case Scheduler::Publish:
1707 return i18n(
"This task has been published");
1708 case Scheduler::Request:
1709 if ( existingIncidence && todo->
revision() > 0 ) {
1710 return i18n(
"This task has been updated by the organizer %1" ).
1711 arg( todo->organizer().fullName() );
1713 if ( iamOrganizer( todo ) ) {
1714 return i18n(
"I created this task" );
1717 if ( !todo->organizer().fullName().isEmpty() ) {
1718 orgStr = todo->organizer().fullName();
1719 }
else if ( !todo->organizer().email().isEmpty() ) {
1720 orgStr = todo->organizer().email();
1722 if ( senderIsOrganizer( todo, sender ) ) {
1723 if ( !orgStr.isEmpty() ) {
1724 return i18n(
"You have been assigned this task by %1" ).arg( orgStr );
1726 return i18n(
"You have been assigned this task" );
1729 if ( !orgStr.isEmpty() ) {
1730 return i18n(
"You have been assigned this task by %1 as a representative of %2" ).
1731 arg( sender, orgStr );
1733 return i18n(
"You have been assigned this task by %1 as the organizer's representative" ).
1739 case Scheduler::Refresh:
1740 return i18n(
"This task was refreshed" );
1741 case Scheduler::Cancel:
1742 return i18n(
"This task was canceled" );
1743 case Scheduler::Add:
1744 return i18n(
"Addition to the task" );
1745 case Scheduler::Reply:
1747 if ( replyMeansCounter( todo ) ) {
1748 return i18n(
"%1 makes this counter proposal" ).
1749 arg( firstAttendeeName( todo, i18n(
"Sender" ) ) );
1753 if( attendees.count() == 0 ) {
1754 kdDebug(5850) <<
"No attendees in the iCal reply!" << endl;
1757 if( attendees.count() != 1 ) {
1758 kdDebug(5850) <<
"Warning: attendeecount in the reply should be 1 "
1759 <<
"but is " << attendees.count() << endl;
1761 TQString attendeeName = firstAttendeeName( todo, i18n(
"Sender" ) );
1763 TQString delegatorName, dummy;
1764 Attendee* attendee = *attendees.begin();
1765 KPIM::getNameAndMail( attendee->
delegator(), delegatorName, dummy );
1766 if ( delegatorName.isEmpty() ) {
1770 switch( attendee->
status() ) {
1771 case Attendee::NeedsAction:
1772 return i18n(
"%1 indicates this task assignment still needs some action" ).arg( attendeeName );
1773 case Attendee::Accepted:
1775 if ( !sender.isEmpty() ) {
1777 return i18n(
"This task has been completed by assignee %1" ).arg( sender );
1779 return i18n(
"This task has been updated by assignee %1" ).arg( sender );
1783 return i18n(
"This task has been completed by an assignee" );
1785 return i18n(
"This task has been updated by an assignee" );
1789 if ( delegatorName.isEmpty() ) {
1790 return i18n(
"%1 accepts this task" ).arg( attendeeName );
1792 return i18n(
"%1 accepts this task on behalf of %2" ).
1793 arg( attendeeName ).arg( delegatorName );
1796 case Attendee::Tentative:
1797 if ( delegatorName.isEmpty() ) {
1798 return i18n(
"%1 tentatively accepts this task" ).
1799 arg( attendeeName );
1801 return i18n(
"%1 tentatively accepts this task on behalf of %2" ).
1802 arg( attendeeName ).arg( delegatorName );
1804 case Attendee::Declined:
1805 if ( delegatorName.isEmpty() ) {
1806 return i18n(
"%1 declines this task" ).arg( attendeeName );
1808 return i18n(
"%1 declines this task on behalf of %2" ).
1809 arg( attendeeName ).arg( delegatorName );
1811 case Attendee::Delegated: {
1812 TQString delegate, dummy;
1813 KPIM::getNameAndMail( attendee->
delegate(), delegate, dummy );
1814 if ( delegate.isEmpty() ) {
1817 if ( !delegate.isEmpty() ) {
1818 return i18n(
"%1 has delegated this request for the task to %2" ).
1819 arg( attendeeName ).arg( delegate );
1821 return i18n(
"%1 has delegated this request for the task" ).
1822 arg( attendeeName );
1825 case Attendee::Completed:
1826 return i18n(
"The request for this task is now completed" );
1827 case Attendee::InProcess:
1828 return i18n(
"%1 is still processing the task" ).
1829 arg( attendeeName );
1831 return i18n(
"Unknown response to this task" );
1836 case Scheduler::Counter:
1837 return i18n(
"%1 makes this counter proposal" ).
1838 arg( firstAttendeeName( todo, i18n(
"Sender" ) ) );
1840 case Scheduler::Declinecounter:
1841 return i18n(
"%1 declines the counter proposal" ).
1842 arg( firstAttendeeName( todo, i18n(
"Sender" ) ) );
1844 case Scheduler::NoMethod:
1845 return i18n(
"Error: iMIP message with unknown method: '%1'" ).
1853 if ( !msg || !journal ) {
1857 switch ( msg->
method() ) {
1858 case Scheduler::Publish:
1859 return i18n(
"This journal has been published");
1860 case Scheduler::Request:
1861 return i18n(
"You have been assigned this journal" );
1862 case Scheduler::Refresh:
1863 return i18n(
"This journal was refreshed" );
1864 case Scheduler::Cancel:
1865 return i18n(
"This journal was canceled" );
1866 case Scheduler::Add:
1867 return i18n(
"Addition to the journal" );
1868 case Scheduler::Reply:
1870 if ( replyMeansCounter( journal ) ) {
1871 return i18n(
"Sender makes this counter proposal" );
1875 if( attendees.count() == 0 ) {
1876 kdDebug(5850) <<
"No attendees in the iCal reply!" << endl;
1879 if( attendees.count() != 1 ) {
1880 kdDebug(5850) <<
"Warning: attendeecount in the reply should be 1 "
1881 <<
"but is " << attendees.count() << endl;
1883 Attendee* attendee = *attendees.begin();
1885 switch( attendee->
status() ) {
1886 case Attendee::NeedsAction:
1887 return i18n(
"Sender indicates this journal assignment still needs some action" );
1888 case Attendee::Accepted:
1889 return i18n(
"Sender accepts this journal" );
1890 case Attendee::Tentative:
1891 return i18n(
"Sender tentatively accepts this journal" );
1892 case Attendee::Declined:
1893 return i18n(
"Sender declines this journal" );
1894 case Attendee::Delegated:
1895 return i18n(
"Sender has delegated this request for the journal" );
1896 case Attendee::Completed:
1897 return i18n(
"The request for this journal is now completed" );
1898 case Attendee::InProcess:
1899 return i18n(
"Sender is still processing the invitation" );
1901 return i18n(
"Unknown response to this journal" );
1905 case Scheduler::Counter:
1906 return i18n(
"Sender makes this counter proposal" );
1907 case Scheduler::Declinecounter:
1908 return i18n(
"Sender declines the counter proposal" );
1909 case Scheduler::NoMethod:
1910 return i18n(
"Error: iMIP message with unknown method: '%1'").
1918 if ( !msg || !fb ) {
1922 switch ( msg->
method() ) {
1923 case Scheduler::Publish:
1924 return i18n(
"This free/busy list has been published");
1925 case Scheduler::Request:
1926 return i18n(
"The free/busy list has been requested" );
1927 case Scheduler::Refresh:
1928 return i18n(
"This free/busy list was refreshed" );
1929 case Scheduler::Cancel:
1930 return i18n(
"This free/busy list was canceled" );
1931 case Scheduler::Add:
1932 return i18n(
"Addition to the free/busy list" );
1933 case Scheduler::NoMethod:
1935 return i18n(
"Error: Free/Busy iMIP message with unknown method: '%1'").
1940 static TQString invitationAttendees(
Incidence *incidence )
1947 if ( incidence->type() ==
"Todo" ) {
1948 tmpStr += htmlAddTag(
"u", i18n(
"Assignees" ) );
1950 tmpStr += htmlAddTag(
"u", i18n(
"Attendees" ) );
1956 if ( !attendees.isEmpty() ) {
1958 Attendee::List::ConstIterator it;
1959 for( it = attendees.begin(); it != attendees.end(); ++it ) {
1961 if ( !iamAttendee( a ) ) {
1964 tmpStr +=
"<table border=\"1\" cellpadding=\"1\" cellspacing=\"0\" columns=\"2\">";
1968 tmpStr += invitationPerson( a->email(), a->name(), TQString() );
1970 tmpStr += i18n(
" (delegated by %1)" ).arg( a->
delegator() );
1973 tmpStr += i18n(
" (delegated to %1)" ).arg( a->
delegate() );
1976 tmpStr +=
"<td>" + a->
statusStr() +
"</td>";
1982 tmpStr +=
"</table>";
1984 tmpStr +=
"<i>" + i18n(
"No attendee",
"None" ) +
"</i>";
1990 static TQString invitationAttachments( InvitationFormatterHelper *helper,
Incidence *incidence )
1998 if ( !attachments.isEmpty() ) {
1999 tmpStr += i18n(
"Attached Documents:" ) +
"<ol>";
2001 Attachment::List::ConstIterator it;
2002 for( it = attachments.begin(); it != attachments.end(); ++it ) {
2006 KMimeType::Ptr mimeType = KMimeType::mimeType( a->mimeType() );
2007 const TQString iconStr = mimeType ? mimeType->icon( a->uri(), false ) : TQString(
"application-octet-stream" );
2008 const TQString iconPath = TDEGlobal::iconLoader()->iconPath( iconStr, TDEIcon::Small );
2009 if ( !iconPath.isEmpty() ) {
2010 tmpStr +=
"<img valign=\"top\" src=\"" + iconPath +
"\">";
2012 tmpStr += helper->makeLink(
"ATTACH:" + a->label(), a->label() );
2021 class IncidenceFormatter::ScheduleMessageVisitor
2025 ScheduleMessageVisitor() : mExistingIncidence( 0 ), mMessage( 0 ) { mResult =
""; }
2027 const TQString &sender )
2029 mExistingIncidence = existingIncidence;
2032 return incidence->
accept( *
this );
2034 TQString result()
const {
return mResult; }
2043 class IncidenceFormatter::InvitationHeaderVisitor
2044 :
public IncidenceFormatter::ScheduleMessageVisitor
2047 bool visit(
Event *event )
2049 mResult = invitationHeaderEvent( event, mExistingIncidence, mMessage, mSender );
2050 return !mResult.isEmpty();
2052 bool visit(
Todo *todo )
2054 mResult = invitationHeaderTodo( todo, mExistingIncidence, mMessage, mSender );
2055 return !mResult.isEmpty();
2057 bool visit(
Journal *journal )
2059 mResult = invitationHeaderJournal( journal, mMessage );
2060 return !mResult.isEmpty();
2064 mResult = invitationHeaderFreeBusy( fb, mMessage );
2065 return !mResult.isEmpty();
2069 class IncidenceFormatter::InvitationBodyVisitor
2070 :
public IncidenceFormatter::ScheduleMessageVisitor
2073 InvitationBodyVisitor(
bool noHtmlMode )
2074 : ScheduleMessageVisitor(), mNoHtmlMode( noHtmlMode ) {}
2077 bool visit(
Event *event )
2079 mResult = invitationDetailsEvent( event, mNoHtmlMode );
2080 return !mResult.isEmpty();
2082 bool visit(
Todo *todo )
2084 mResult = invitationDetailsTodo( todo, mNoHtmlMode );
2085 return !mResult.isEmpty();
2087 bool visit(
Journal *journal )
2089 mResult = invitationDetailsJournal( journal, mNoHtmlMode );
2090 return !mResult.isEmpty();
2094 mResult = invitationDetailsFreeBusy( fb, mNoHtmlMode );
2095 return !mResult.isEmpty();
2102 class IncidenceFormatter::IncidenceCompareVisitor
2106 IncidenceCompareVisitor() : mExistingIncidence(0) {}
2110 if ( !inc || !existingIncidence || inc->
revision() <= existingIncidence->
revision() )
2112 mExistingIncidence = existingIncidence;
2114 return incidence->
accept( *
this );
2117 TQString result()
const
2119 if ( mChanges.isEmpty() ) {
2122 TQString html =
"<div align=\"left\"><ul><li>";
2123 html += mChanges.join(
"</li><li>" );
2124 html +=
"</li><ul></div>";
2129 bool visit(
Event *event )
2131 compareEvents( event, dynamic_cast<Event*>( mExistingIncidence ) );
2132 compareIncidences( event, mExistingIncidence, mMethod );
2133 return !mChanges.isEmpty();
2135 bool visit(
Todo *todo )
2137 compareTodos( todo, dynamic_cast<Todo*>( mExistingIncidence ) );
2138 compareIncidences( todo, mExistingIncidence, mMethod );
2139 return !mChanges.isEmpty();
2141 bool visit(
Journal *journal )
2143 compareIncidences( journal, mExistingIncidence, mMethod );
2144 return !mChanges.isEmpty();
2149 return !mChanges.isEmpty();
2153 void compareEvents(
Event *newEvent,
Event *oldEvent )
2155 if ( !oldEvent || !newEvent )
2158 mChanges += i18n(
"The invitation starting time has been changed from %1 to %2" )
2159 .arg( eventStartTimeStr( oldEvent ) ).arg( eventStartTimeStr( newEvent ) );
2161 mChanges += i18n(
"The invitation ending time has been changed from %1 to %2" )
2162 .arg( eventEndTimeStr( oldEvent ) ).arg( eventEndTimeStr( newEvent ) );
2165 void compareTodos(
Todo *newTodo,
Todo *oldTodo )
2167 if ( !oldTodo || !newTodo ) {
2172 mChanges += i18n(
"The task has been completed" );
2175 mChanges += i18n(
"The task is no longer completed" );
2178 const TQString oldPer = i18n(
"%1%" ).arg( oldTodo->
percentComplete() );
2179 const TQString newPer = i18n(
"%1%" ).arg( newTodo->
percentComplete() );
2180 mChanges += i18n(
"The task completed percentage has changed from %1 to %2" ).
2181 arg( oldPer, newPer );
2185 mChanges += i18n(
"A task starting time has been added" );
2188 mChanges += i18n(
"The task starting time has been removed" );
2192 mChanges += i18n(
"The task starting time has been changed from %1 to %2" ).
2198 mChanges += i18n(
"A task due time has been added" );
2201 mChanges += i18n(
"The task due time has been removed" );
2205 mChanges += i18n(
"The task due time has been changed from %1 to %2" ).
2206 arg( dateTimeToString( oldTodo->
dtDue(), oldTodo->
doesFloat(), false ),
2207 dateTimeToString( newTodo->
dtDue(), newTodo->
doesFloat(), false ) );
2213 if ( !oldInc || !newInc )
2216 mChanges += i18n(
"The summary has been changed to: \"%1\"" ).arg( newInc->
summary() );
2218 mChanges += i18n(
"The location has been changed to: \"%1\"" ).arg( newInc->
location() );
2220 mChanges += i18n(
"The description has been changed to: \"%1\"" ).arg( newInc->
description() );
2223 for ( Attendee::List::ConstIterator it = newAttendees.constBegin();
2224 it != newAttendees.constEnd(); ++it ) {
2227 mChanges += i18n(
"Attendee %1 has been added" ).arg( (*it)->fullName() );
2229 if ( oldAtt->
status() != (*it)->status() )
2230 mChanges += i18n(
"The status of attendee %1 has been changed to: %2" ).
2231 arg( (*it)->fullName() ).arg( (*it)->statusStr() );
2234 if ( method == Scheduler::Request ) {
2235 for ( Attendee::List::ConstIterator it = oldAttendees.constBegin();
2236 it != oldAttendees.constEnd(); ++it ) {
2237 if ( (*it)->email() != oldInc->organizer().email() ) {
2240 mChanges += i18n(
"Attendee %1 has been removed" ).arg( (*it)->fullName() );
2250 TQStringList mChanges;
2254 TQString InvitationFormatterHelper::makeLink(
const TQString &
id,
const TQString &text )
2256 if ( !
id.startsWith(
"ATTACH:" ) ) {
2257 TQString res = TQString(
"<a href=\"%1\"><b>%2</b></a>" ).
2258 arg( generateLinkURL(
id ), text );
2262 TQString res = TQString(
"<a href=\"%1\">%2</a>" ).
2263 arg( generateLinkURL(
id ), text );
2273 if ( !cal || !incidence ) {
2281 if ( !subRes.contains(
"/.INBOX.directory/" ) ) {
2288 static TQString spacer =
"<td> </td>";
2290 static TQString tdOpen =
"<td>";
2291 static TQString tdClose =
"</td>" + spacer;
2293 static TQString responseButtons(
Incidence *inc,
bool rsvpReq,
bool rsvpRec,
2294 InvitationFormatterHelper *helper )
2301 if ( !rsvpReq && ( inc && inc->
revision() == 0 ) ) {
2304 html += helper->makeLink(
"record", i18n(
"[Record]" ) );
2309 html += helper->makeLink(
"delete", i18n(
"[Move to Trash]" ) );
2316 html += helper->makeLink(
"accept", i18n(
"[Accept]" ) );
2321 html += helper->makeLink(
"accept_conditionally",
2322 i18n(
"Accept conditionally",
"[Accept cond.]" ) );
2327 html += helper->makeLink(
"counter", i18n(
"[Counter proposal]" ) );
2332 html += helper->makeLink(
"decline", i18n(
"[Decline]" ) );
2336 if ( !rsvpRec || ( inc && inc->
revision() > 0 ) ) {
2339 html += helper->makeLink(
"delegate", i18n(
"[Delegate]" ) );
2344 html += helper->makeLink(
"forward", i18n(
"[Forward]" ) );
2348 if ( inc && inc->type() ==
"Event" ) {
2350 html += helper->makeLink(
"check_calendar", i18n(
"[Check my calendar]" ) );
2357 static TQString counterButtons(
Incidence *incidence,
2358 InvitationFormatterHelper *helper )
2367 html += helper->makeLink(
"accept_counter", i18n(
"[Accept]") );
2372 html += helper->makeLink(
"decline_counter", i18n(
"[Decline]") );
2376 if ( incidence && incidence->type() ==
"Event" ) {
2378 html += helper->makeLink(
"check_calendar", i18n(
"[Check my calendar]" ) );
2384 TQString IncidenceFormatter::formatICalInvitationHelper( TQString invitation,
2386 InvitationFormatterHelper *helper,
2388 const TQString &sender )
2390 if ( invitation.isEmpty() ) {
2399 kdDebug( 5850 ) <<
"Failed to parse the scheduling message" << endl;
2409 if ( incBase && helper->calendar() ) {
2410 existingIncidence = helper->calendar()->incidence( incBase->
uid() );
2411 if ( !incidenceOwnedByMe( helper->calendar(), existingIncidence ) ) {
2412 existingIncidence = 0;
2414 if ( !existingIncidence ) {
2416 for ( Incidence::List::ConstIterator it = list.begin(), end = list.end(); it != end; ++it ) {
2417 if ( (*it)->schedulingID() == incBase->
uid() &&
2418 incidenceOwnedByMe( helper->calendar(), *it ) ) {
2419 existingIncidence = *it;
2429 TQString tableStyle = TQString::fromLatin1(
2430 "style=\"border: solid 1px; margin: 0em;\"" );
2431 TQString tableHead = TQString::fromLatin1(
2432 "<div align=\"center\">"
2433 "<table width=\"80%\" cellpadding=\"1\" cellspacing=\"0\" %1>"
2434 "<tr><td>").arg(tableStyle);
2437 InvitationHeaderVisitor headerVisitor;
2439 if ( !headerVisitor.act( incBase, existingIncidence, msg, sender ) )
2441 html +=
"<b>" + headerVisitor.result() +
"</b>";
2443 InvitationBodyVisitor bodyVisitor( noHtmlMode );
2444 if ( !bodyVisitor.act( incBase, existingIncidence, msg, sender ) )
2446 html += bodyVisitor.result();
2448 if ( msg->
method() == Scheduler::Request ) {
2449 IncidenceCompareVisitor compareVisitor;
2450 if ( compareVisitor.act( incBase, existingIncidence, msg->
method() ) ) {
2451 html +=
"<p align=\"left\">";
2452 html += i18n(
"The following changes have been made by the organizer:" );
2454 html += compareVisitor.result();
2457 if ( msg->
method() == Scheduler::Reply ) {
2458 IncidenceCompareVisitor compareVisitor;
2459 if ( compareVisitor.act( incBase, existingIncidence, msg->
method() ) ) {
2460 html +=
"<p align=\"left\">";
2461 if ( !sender.isEmpty() ) {
2462 html += i18n(
"The following changes have been made by %1:" ).arg( sender );
2464 html += i18n(
"The following changes have been made by an attendee:" );
2467 html += compareVisitor.result();
2474 bool myInc = iamOrganizer( inc );
2477 bool rsvpRec =
false;
2480 Incidence *rsvpIncidence = existingIncidence;
2481 if ( !rsvpIncidence && inc && inc->
revision() > 0 ) {
2482 rsvpIncidence = inc;
2484 if ( rsvpIncidence ) {
2485 ea = findMyAttendee( rsvpIncidence );
2488 ( ea->
status() == Attendee::Accepted ||
2489 ea->
status() == Attendee::Declined ||
2490 ea->
status() == Attendee::Tentative ) ) {
2497 bool isDelegated =
false;
2498 Attendee *a = findMyAttendee( inc );
2505 isDelegated = ( a->
status() == Attendee::Delegated );
2510 bool rsvpReq = rsvpRequested( inc );
2511 if ( !myInc && a ) {
2514 if ( rsvpRec && inc ) {
2516 html += i18n(
"Your <b>%1</b> response has already been recorded" ).
2519 html += i18n(
"Your status for this invitation is <b>%1</b>" ).
2523 }
else if ( msg->
method() == Scheduler::Cancel ) {
2524 html += i18n(
"This invitation was declined" );
2525 }
else if ( msg->
method() == Scheduler::Add ) {
2526 html += i18n(
"This invitation was accepted" );
2528 if ( !isDelegated ) {
2529 html += rsvpRequestedStr( rsvpReq, role );
2531 html += i18n(
"Awaiting delegation response" );
2539 if ( inc && inc->
revision() == 0 ) {
2540 TQString statStr = myStatusStr( inc );
2541 if ( !statStr.isEmpty() ) {
2552 html +=
"<br><table border=\"0\" cellspacing=\"0\"><tr><td> </td></tr>";
2554 switch ( msg->
method() ) {
2555 case Scheduler::Publish:
2556 case Scheduler::Request:
2557 case Scheduler::Refresh:
2558 case Scheduler::Add:
2560 if ( inc && inc->
revision() > 0 && ( existingIncidence || !helper->calendar() ) ) {
2562 if ( inc->type() ==
"Todo" ) {
2563 html +=
"<td colspan=\"9\">";
2564 html += helper->makeLink(
"reply", i18n(
"[Record invitation in my task list]" ) );
2566 html +=
"<td colspan=\"13\">";
2567 html += helper->makeLink(
"reply", i18n(
"[Record invitation in my calendar]" ) );
2569 html +=
"</td></tr>";
2572 if ( !myInc && a ) {
2573 html +=
"<tr>" + responseButtons( inc, rsvpReq, rsvpRec, helper ) +
"</tr>";
2578 case Scheduler::Cancel:
2582 if ( inc->type() ==
"Todo" ) {
2583 html +=
"<td colspan=\"9\">";
2584 html += helper->makeLink(
"cancel", i18n(
"[Remove invitation from my task list]" ) );
2586 html +=
"<td colspan=\"13\">";
2587 html += helper->makeLink(
"cancel", i18n(
"[Remove invitation from my calendar]" ) );
2589 html +=
"</td></tr>";
2593 case Scheduler::Reply:
2600 if ( replyMeansCounter( inc ) ) {
2601 html +=
"<tr>" + counterButtons( inc, helper ) +
"</tr>";
2610 a = findDelegatedFromMyAttendee( inc );
2612 if ( a->
status() != Attendee::Accepted ||
2613 a->
status() != Attendee::Tentative ) {
2614 html +=
"<tr>" + responseButtons( inc, rsvpReq, rsvpRec, helper ) +
"</tr>";
2624 ea = findAttendee( existingIncidence, a->email() );
2627 if ( ea && ( ea->
status() != Attendee::NeedsAction ) && ( ea->
status() == a->
status() ) ) {
2628 if ( inc && inc->
revision() > 0 ) {
2629 html +=
"<br><u><i>";
2630 html += i18n(
"The response has been recorded [%1]" ).arg( ea->
statusStr() );
2636 if ( inc->type() ==
"Todo" ) {
2637 html += helper->makeLink(
"reply", i18n(
"[Record response in my task list]" ) );
2639 html += helper->makeLink(
"reply", i18n(
"[Record response in my calendar]" ) );
2641 html +=
"</td></tr>";
2647 case Scheduler::Counter:
2649 html +=
"<tr>" + counterButtons( inc, helper ) +
"</tr>";
2652 case Scheduler::Declinecounter:
2653 case Scheduler::NoMethod:
2658 html +=
"</td></tr></table>";
2661 if ( myInc && helper->calendar() ) {
2662 html += invitationAttendees( helper->calendar()->incidence( inc->
uid() ) );
2666 html +=
"</td></tr></table><br></div>";
2669 html += invitationAttachments( helper, inc );
2674 TQString IncidenceFormatter::formatICalInvitation( TQString invitation,
2676 InvitationFormatterHelper *helper )
2678 return formatICalInvitationHelper( invitation, mCalendar, helper,
false, TQString() );
2681 TQString IncidenceFormatter::formatICalInvitationNoHtml( TQString invitation,
2683 InvitationFormatterHelper *helper )
2685 return formatICalInvitationHelper( invitation, mCalendar, helper,
true, TQString() );
2688 TQString IncidenceFormatter::formatICalInvitationNoHtml( TQString invitation,
2690 InvitationFormatterHelper *helper,
2691 const TQString &sender )
2693 return formatICalInvitationHelper( invitation, mCalendar, helper,
true, sender );
2704 static TQString stringProp( KTNEFMessage* tnefMsg,
const TQ_UINT32& key,
2705 const TQString& fallback = TQString())
2707 return tnefMsg->findProp( key < 0x10000 ? key & 0xFFFF : key >> 16,
2711 static TQString sNamedProp( KTNEFMessage* tnefMsg,
const TQString& name,
2712 const TQString& fallback = TQString() )
2714 return tnefMsg->findNamedProp( name, fallback );
2717 struct save_tz {
char* old_tz;
char* tz_env_str; };
2720 static struct save_tz set_tz( const char* _tc )
2722 const char *tc = _tc?_tc:
"UTC";
2732 if( getenv(
"TZ" ) ) {
2733 tz_env = strdup( getenv(
"TZ" ) );
2736 char* tmp_env = (
char*)malloc( strlen( tc ) + 4 );
2737 strcpy( tmp_env,
"TZ=" );
2738 strcpy( tmp_env+3, tc );
2741 rv.tz_env_str = tmp_env;
2752 static void unset_tz(
struct save_tz old_tz )
2754 if( old_tz.old_tz ) {
2755 char* tmp_env = (
char*)malloc( strlen( old_tz.old_tz ) + 4 );
2756 strcpy( tmp_env,
"TZ=" );
2757 strcpy( tmp_env+3, old_tz.old_tz );
2760 free( old_tz.old_tz );
2763 putenv( strdup(
"TZ") );
2768 if( old_tz.tz_env_str ) free( old_tz.tz_env_str );
2771 static TQDateTime utc2Local(
const TQDateTime& utcdt )
2775 save_tz tmp_tz = set_tz(
"UTC");
2776 time_t utc = utcdt.toTime_t();
2779 localtime_r( &utc, &tmL );
2780 return TQDateTime( TQDate( tmL.tm_year+1900, tmL.tm_mon+1, tmL.tm_mday ),
2781 TQTime( tmL.tm_hour, tmL.tm_min, tmL.tm_sec ) );
2785 static TQDateTime pureISOToLocalTQDateTime(
const TQString& dtStr,
2786 bool bDateOnly =
false )
2790 int year, month, day, hour, minute, second;
2793 year = dtStr.left( 4 ).toInt();
2794 month = dtStr.mid( 4, 2 ).toInt();
2795 day = dtStr.mid( 6, 2 ).toInt();
2800 year = dtStr.left( 4 ).toInt();
2801 month = dtStr.mid( 4, 2 ).toInt();
2802 day = dtStr.mid( 6, 2 ).toInt();
2803 hour = dtStr.mid( 9, 2 ).toInt();
2804 minute = dtStr.mid( 11, 2 ).toInt();
2805 second = dtStr.mid( 13, 2 ).toInt();
2807 tmpDate.setYMD( year, month, day );
2808 tmpTime.setHMS( hour, minute, second );
2810 if( tmpDate.isValid() && tmpTime.isValid() ) {
2811 TQDateTime dT = TQDateTime( tmpDate, tmpTime );
2815 if (dtStr.at(dtStr.length()-1) ==
'Z') {
2818 dT = utc2Local( dT );
2823 return TQDateTime();
2833 TQBuffer buf( tnef );
2835 TDEABC::Addressee addressee;
2836 TDEABC::VCardConverter cardConv;
2840 if( parser.openDevice( &TQT_TQIODEVICE_OBJECT(buf) ) ) {
2841 KTNEFMessage* tnefMsg = parser.message();
2846 TQString msgClass = tnefMsg->findProp( 0x001A, TQString(),
true )
2848 if( !msgClass.isEmpty() ) {
2851 bool bCompatClassAppointment =
false;
2852 bool bCompatMethodRequest =
false;
2853 bool bCompatMethodCancled =
false;
2854 bool bCompatMethodAccepted =
false;
2855 bool bCompatMethodAcceptedCond =
false;
2856 bool bCompatMethodDeclined =
false;
2857 if( msgClass.startsWith(
"IPM.MICROSOFT SCHEDULE." ) ) {
2858 bCompatClassAppointment =
true;
2859 if( msgClass.endsWith(
".MTGREQ" ) )
2860 bCompatMethodRequest =
true;
2861 if( msgClass.endsWith(
".MTGCNCL" ) )
2862 bCompatMethodCancled =
true;
2863 if( msgClass.endsWith(
".MTGRESPP" ) )
2864 bCompatMethodAccepted =
true;
2865 if( msgClass.endsWith(
".MTGRESPA" ) )
2866 bCompatMethodAcceptedCond =
true;
2867 if( msgClass.endsWith(
".MTGRESPN" ) )
2868 bCompatMethodDeclined =
true;
2870 bool bCompatClassNote = ( msgClass ==
"IPM.MICROSOFT MAIL.NOTE" );
2872 if( bCompatClassAppointment ||
"IPM.APPOINTMENT" == msgClass ) {
2874 bool bIsReply =
false;
2875 TQString prodID =
"-//Microsoft Corporation//Outlook ";
2876 prodID += tnefMsg->findNamedProp(
"0x8554",
"9.0" );
2877 prodID +=
"MIMEDIR/EN\n";
2878 prodID +=
"VERSION:2.0\n";
2882 if( bCompatMethodRequest )
2883 method = Scheduler::Request;
2884 else if( bCompatMethodCancled )
2885 method = Scheduler::Cancel;
2886 else if( bCompatMethodAccepted || bCompatMethodAcceptedCond ||
2887 bCompatMethodDeclined ) {
2888 method = Scheduler::Reply;
2899 if( tnefMsg->findProp(0x0c17) ==
"1" )
2901 method = Scheduler::Request;
2907 TQString sSenderSearchKeyEmail( tnefMsg->findProp( 0x0C1D ) );
2909 if( !sSenderSearchKeyEmail.isEmpty() ) {
2910 int colon = sSenderSearchKeyEmail.find(
':' );
2912 if( sSenderSearchKeyEmail.find(
':' ) == -1 )
2913 sSenderSearchKeyEmail.remove( 0, colon+1 );
2916 TQString s( tnefMsg->findProp( 0x0e04 ) );
2917 TQStringList attendees = TQStringList::split(
';', s );
2918 if( attendees.count() ) {
2919 for( TQStringList::Iterator it = attendees.begin();
2920 it != attendees.end(); ++it ) {
2923 if( (*it).find(
'@') == -1 ) {
2924 s = (*it).stripWhiteSpace();
2928 if( bCompatMethodAccepted )
2929 attendee->
setStatus( Attendee::Accepted );
2930 if( bCompatMethodDeclined )
2931 attendee->
setStatus( Attendee::Declined );
2932 if( bCompatMethodAcceptedCond )
2933 attendee->
setStatus(Attendee::Tentative);
2935 attendee->
setStatus( Attendee::NeedsAction );
2936 attendee->
setRole( Attendee::ReqParticipant );
2938 event->addAttendee(attendee);
2944 s = sSenderSearchKeyEmail;
2945 if( !s.isEmpty() ) {
2949 if( bCompatMethodAccepted )
2950 attendee->
setStatus( Attendee::Accepted );
2951 if( bCompatMethodAcceptedCond )
2952 attendee->
setStatus( Attendee::Declined );
2953 if( bCompatMethodDeclined )
2954 attendee->
setStatus( Attendee::Tentative );
2956 attendee->
setStatus(Attendee::NeedsAction);
2957 attendee->
setRole(Attendee::ReqParticipant);
2959 event->addAttendee(attendee);
2962 s = tnefMsg->findProp( 0x0c1f );
2963 if( s.isEmpty() && !bIsReply )
2964 s = sSenderSearchKeyEmail;
2969 s = tnefMsg->findProp( 0x8516 ).replace( TQChar(
'-' ), TQString() )
2970 .replace( TQChar(
':' ), TQString() );
2971 event->setDtStart( TQDateTime::fromString( s ) );
2973 s = tnefMsg->findProp( 0x8517 ).replace( TQChar(
'-' ), TQString() )
2974 .replace( TQChar(
':' ), TQString() );
2975 event->setDtEnd( TQDateTime::fromString( s ) );
2977 s = tnefMsg->findProp( 0x8208 );
2978 event->setLocation( s );
2985 s = tnefMsg->findProp( 0x0023 );
2991 s = tnefMsg->findProp( 0x8202 ).replace( TQChar(
'-' ), TQString() )
2992 .replace( TQChar(
':' ), TQString() );
2996 s = tnefMsg->findNamedProp(
"Keywords" );
2997 event->setCategories( s );
2999 s = tnefMsg->findProp( 0x1000 );
3000 event->setDescription( s );
3002 s = tnefMsg->findProp( 0x0070 );
3003 event->setSummary( s );
3005 s = tnefMsg->findProp( 0x0026 );
3006 event->setPriority( s.toInt() );
3009 if(!tnefMsg->findProp(0x8503).isEmpty()) {
3011 TQDateTime highNoonTime =
3012 pureISOToLocalTQDateTime( tnefMsg->findProp( 0x8502 )
3013 .replace( TQChar(
'-' ),
"" )
3014 .replace( TQChar(
':' ),
"" ) );
3015 TQDateTime wakeMeUpTime =
3016 pureISOToLocalTQDateTime( tnefMsg->findProp( 0x8560,
"" )
3017 .replace( TQChar(
'-' ),
"" )
3018 .replace( TQChar(
':' ),
"" ) );
3021 if( highNoonTime.isValid() && wakeMeUpTime.isValid() )
3030 event->addAlarm( alarm );
3035 }
else if( bCompatClassNote ||
"IPM.CONTACT" == msgClass ) {
3036 addressee.setUid( stringProp( tnefMsg, attMSGID ) );
3037 addressee.setFormattedName( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME ) );
3038 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL1EMAILADDRESS ),
true );
3039 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL2EMAILADDRESS ),
false );
3040 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL3EMAILADDRESS ),
false );
3041 addressee.insertCustom(
"KADDRESSBOOK",
"X-IMAddress", sNamedProp( tnefMsg, MAPI_TAG_CONTACT_IMADDRESS ) );
3042 addressee.insertCustom(
"KADDRESSBOOK",
"X-SpousesName", stringProp( tnefMsg, MAPI_TAG_PR_SPOUSE_NAME ) );
3043 addressee.insertCustom(
"KADDRESSBOOK",
"X-ManagersName", stringProp( tnefMsg, MAPI_TAG_PR_MANAGER_NAME ) );
3044 addressee.insertCustom(
"KADDRESSBOOK",
"X-AssistantsName", stringProp( tnefMsg, MAPI_TAG_PR_ASSISTANT ) );
3045 addressee.insertCustom(
"KADDRESSBOOK",
"X-Department", stringProp( tnefMsg, MAPI_TAG_PR_DEPARTMENT_NAME ) );
3046 addressee.insertCustom(
"KADDRESSBOOK",
"X-Office", stringProp( tnefMsg, MAPI_TAG_PR_OFFICE_LOCATION ) );
3047 addressee.insertCustom(
"KADDRESSBOOK",
"X-Profession", stringProp( tnefMsg, MAPI_TAG_PR_PROFESSION ) );
3049 TQString s = tnefMsg->findProp( MAPI_TAG_PR_WEDDING_ANNIVERSARY )
3050 .replace( TQChar(
'-' ), TQString() )
3051 .replace( TQChar(
':' ), TQString() );
3053 addressee.insertCustom(
"KADDRESSBOOK",
"X-Anniversary", s );
3055 addressee.setUrl( KURL( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_WEBPAGE ) ) );
3058 addressee.setFamilyName( stringProp( tnefMsg, MAPI_TAG_PR_SURNAME ) );
3059 addressee.setGivenName( stringProp( tnefMsg, MAPI_TAG_PR_GIVEN_NAME ) );
3060 addressee.setAdditionalName( stringProp( tnefMsg, MAPI_TAG_PR_MIDDLE_NAME ) );
3061 addressee.setPrefix( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME_PREFIX ) );
3062 addressee.setSuffix( stringProp( tnefMsg, MAPI_TAG_PR_GENERATION ) );
3064 addressee.setNickName( stringProp( tnefMsg, MAPI_TAG_PR_NICKNAME ) );
3065 addressee.setRole( stringProp( tnefMsg, MAPI_TAG_PR_TITLE ) );
3066 addressee.setOrganization( stringProp( tnefMsg, MAPI_TAG_PR_COMPANY_NAME ) );
3072 TDEABC::Address adr;
3073 adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_PO_BOX ) );
3074 adr.setStreet( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STREET ) );
3075 adr.setLocality( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_CITY ) );
3076 adr.setRegion( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STATE_OR_PROVINCE ) );
3077 adr.setPostalCode( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_POSTAL_CODE ) );
3078 adr.setCountry( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_COUNTRY ) );
3079 adr.setType(TDEABC::Address::Home);
3080 addressee.insertAddress(adr);
3082 adr.setPostOfficeBox( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOBOX ) );
3083 adr.setStreet( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTREET ) );
3084 adr.setLocality( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCITY ) );
3085 adr.setRegion( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTATE ) );
3086 adr.setPostalCode( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOSTALCODE ) );
3087 adr.setCountry( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCOUNTRY ) );
3088 adr.setType( TDEABC::Address::Work );
3089 addressee.insertAddress( adr );
3091 adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_PO_BOX ) );
3092 adr.setStreet( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STREET ) );
3093 adr.setLocality( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_CITY ) );
3094 adr.setRegion( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STATE_OR_PROVINCE ) );
3095 adr.setPostalCode( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_POSTAL_CODE ) );
3096 adr.setCountry( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_COUNTRY ) );
3097 adr.setType( TDEABC::Address::Dom );
3098 addressee.insertAddress(adr);
3105 nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_TELEPHONE_NUMBER );
3106 addressee.insertPhoneNumber( TDEABC::PhoneNumber( nr, TDEABC::PhoneNumber::Home ) );
3107 nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_TELEPHONE_NUMBER );
3108 addressee.insertPhoneNumber( TDEABC::PhoneNumber( nr, TDEABC::PhoneNumber::Work ) );
3109 nr = stringProp( tnefMsg, MAPI_TAG_PR_MOBILE_TELEPHONE_NUMBER );
3110 addressee.insertPhoneNumber( TDEABC::PhoneNumber( nr, TDEABC::PhoneNumber::Cell ) );
3111 nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_FAX_NUMBER );
3112 addressee.insertPhoneNumber( TDEABC::PhoneNumber( nr, TDEABC::PhoneNumber::Fax | TDEABC::PhoneNumber::Home ) );
3113 nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_FAX_NUMBER );
3114 addressee.insertPhoneNumber( TDEABC::PhoneNumber( nr, TDEABC::PhoneNumber::Fax | TDEABC::PhoneNumber::Work ) );
3116 s = tnefMsg->findProp( MAPI_TAG_PR_BIRTHDAY )
3117 .replace( TQChar(
'-' ), TQString() )
3118 .replace( TQChar(
':' ), TQString() );
3120 addressee.setBirthday( TQDateTime::fromString( s ) );
3122 bOk = ( !addressee.isEmpty() );
3123 }
else if(
"IPM.NOTE" == msgClass ) {
3130 TQString iCal = calFormat.
toString( &cal );
3131 if( !iCal.isEmpty() )
3136 TDEABC::VCardConverter converter;
3137 return converter.createVCard( addressee );
3141 TQString IncidenceFormatter::formatTNEFInvitation(
const TQByteArray& tnef,
3142 Calendar *mCalendar, InvitationFormatterHelper *helper )
3145 TQString iCal = IncidenceFormatter::formatICalInvitation( vPart, mCalendar, helper );
3146 if( !iCal.isEmpty() )
3162 : mCalendar( 0 ), mRichText( true ), mResult(
"" ) {}
3165 const TQDate &date=TQDate(),
bool richText=
true )
3167 mCalendar = calendar;
3169 mRichText = richText;
3171 return incidence ? incidence->
accept( *
this ) :
false;
3173 TQString result()
const {
return mResult; }
3176 bool visit(
Event *event );
3177 bool visit(
Todo *todo );
3178 bool visit(
Journal *journal );
3181 TQString dateRangeText(
Event *event,
const TQDate &date );
3182 TQString dateRangeText(
Todo *todo,
const TQDate &date );
3183 TQString dateRangeText(
Journal *journal );
3184 TQString dateRangeText(
FreeBusy *fb );
3186 TQString generateToolTip(
Incidence* incidence, TQString dtRangeText );
3195 TQString IncidenceFormatter::ToolTipVisitor::dateRangeText(
Event *event,
const TQDate &date )
3200 TQDateTime startDt =
event->dtStart();
3201 TQDateTime endDt =
event->dtEnd();
3203 if ( date.isValid() ) {
3204 TQDateTime dt( date, TQTime( 0, 0, 0 ) );
3205 int diffDays = startDt.daysTo( dt );
3206 dt = dt.addSecs( -1 );
3209 endDt = endDt.addDays( diffDays );
3210 if ( startDt > endDt ) {
3212 endDt = startDt.addDays( event->
dtStart().daysTo( event->
dtEnd() ) );
3219 tmp =
"<br>" + i18n(
"Event start",
"<i>From:</i> %1");
3221 ret += tmp.arg( IncidenceFormatter::dateToString( startDt,
false ).replace(
" ",
" ") );
3223 ret += tmp.arg( IncidenceFormatter::dateToString( startDt ).replace(
" ",
" ") );
3225 tmp =
"<br>" + i18n(
"Event end",
"<i>To:</i> %1");
3227 ret += tmp.arg( IncidenceFormatter::dateToString( endDt,
false ).replace(
" ",
" ") );
3229 ret += tmp.arg( IncidenceFormatter::dateToString( endDt ).replace(
" ",
" ") );
3233 ret +=
"<br>"+i18n(
"<i>Date:</i> %1").
3234 arg( IncidenceFormatter::dateToString( startDt,
false ).replace(
" ",
" ") );
3236 const TQString dtStartTime =
3237 IncidenceFormatter::timeToString( startDt,
true ).replace(
" ",
" " );
3238 const TQString dtEndTime =
3239 IncidenceFormatter::timeToString( endDt,
true ).replace(
" ",
" " );
3240 if ( dtStartTime == dtEndTime ) {
3241 tmp =
"<br>" + i18n(
"time for event, to prevent ugly line breaks",
3242 "<i>Time:</i> %1").
3245 tmp =
"<br>" + i18n(
"time range for event, to prevent ugly line breaks",
3246 "<i>Time:</i> %1 - %2").
3247 arg( dtStartTime, dtEndTime );
3256 TQString IncidenceFormatter::ToolTipVisitor::dateRangeText(
Todo *todo,
const TQDate &date )
3262 TQDateTime startDt = todo->
dtStart();
3264 if ( date.isValid() ) {
3265 startDt.setDate( date );
3269 i18n(
"<i>Start:</i> %1").
3270 arg( IncidenceFormatter::dateTimeToString( startDt, floats,
false ).
3271 replace(
" ",
" " ) );
3275 TQDateTime dueDt = todo->
dtDue();
3277 if ( date.isValid() ) {
3278 TQDateTime dt( date, TQTime( 0, 0, 0 ) );
3279 dt = dt.addSecs( -1 );
3284 i18n(
"<i>Due:</i> %1").
3285 arg( IncidenceFormatter::dateTimeToString( dueDt, floats,
false ).
3286 replace(
" ",
" " ) );
3293 ret +=
"<i>" + i18n(
"Priority:" ) +
"</i>" +
" ";
3294 ret += TQString::number( todo->
priority() );
3299 ret +=
"<i>" + i18n(
"Completed:" ) +
"</i>" +
" ";
3302 ret +=
"<i>" + i18n(
"Percent Done:" ) +
"</i>" +
" ";
3309 TQString IncidenceFormatter::ToolTipVisitor::dateRangeText(
Journal*journal )
3312 if (journal->
dtStart().isValid() ) {
3314 i18n(
"<i>Date:</i> %1").
3315 arg( IncidenceFormatter::dateToString( journal->
dtStart(), false ) );
3320 TQString IncidenceFormatter::ToolTipVisitor::dateRangeText(
FreeBusy *fb )
3322 TQString tmp(
"<br>" + i18n(
"<i>Period start:</i> %1") );
3323 TQString ret = tmp.arg( TDEGlobal::locale()->formatDateTime( fb->
dtStart() ) );
3324 tmp =
"<br>" + i18n(
"<i>Period start:</i> %1");
3325 ret += tmp.arg( TDEGlobal::locale()->formatDateTime( fb->dtEnd() ) );
3331 bool IncidenceFormatter::ToolTipVisitor::visit(
Event *event )
3333 mResult = generateToolTip( event, dateRangeText( event, mDate ) );
3334 return !mResult.isEmpty();
3337 bool IncidenceFormatter::ToolTipVisitor::visit(
Todo *todo )
3339 mResult = generateToolTip( todo, dateRangeText( todo, mDate ) );
3340 return !mResult.isEmpty();
3343 bool IncidenceFormatter::ToolTipVisitor::visit(
Journal *journal )
3345 mResult = generateToolTip( journal, dateRangeText( journal ) );
3346 return !mResult.isEmpty();
3349 bool IncidenceFormatter::ToolTipVisitor::visit(
FreeBusy *fb )
3351 mResult =
"<qt><b>" + i18n(
"Free/Busy information for %1")
3352 .arg(fb->organizer().fullName()) +
"</b>";
3353 mResult += dateRangeText( fb );
3355 return !mResult.isEmpty();
3358 static TQString tooltipPerson(
const TQString& email, TQString name )
3362 if ( name.isEmpty() && !email.isEmpty() ) {
3363 TDEABC::AddressBook *add_book = TDEABC::StdAddressBook::self(
true );
3364 TDEABC::Addressee::List addressList = add_book->findByEmail( email );
3365 if ( !addressList.isEmpty() ) {
3366 TDEABC::Addressee o = addressList.first();
3367 if ( !o.isEmpty() && addressList.size() < 2 ) {
3369 name = o.formattedName();
3375 TQString tmpString = ( name.isEmpty() ? email : name );
3380 static TQString etc = i18n(
"elipsis",
"..." );
3381 static TQString tooltipFormatAttendeeRoleList(
Incidence *incidence, Attendee::Role role )
3384 TQString sep = i18n(
"separator for lists of people names",
", " );
3385 int sepLen = sep.length();
3389 Attendee::List::ConstIterator it;
3392 for( it = attendees.begin(); it != attendees.end(); ++it ) {
3394 if ( a->
role() != role ) {
3398 if ( a->email() == incidence->organizer().email() ) {
3402 if ( i == maxNumAtts ) {
3406 tmpStr += tooltipPerson( a->email(), a->name() );
3408 tmpStr += i18n(
" (delegated by %1)" ).arg( a->
delegator() );
3411 tmpStr += i18n(
" (delegated to %1)" ).arg( a->
delegate() );
3416 if ( tmpStr.endsWith( sep ) ) {
3417 tmpStr.truncate( tmpStr.length() - sepLen );
3422 static TQString tooltipFormatAttendees(
Incidence *incidence )
3424 TQString tmpStr, str;
3427 int attendeeCount = incidence->
attendees().count();
3428 if ( attendeeCount > 1 ||
3429 ( attendeeCount == 1 &&
3430 incidence->organizer().email() != incidence->
attendees().first()->email() ) ) {
3431 tmpStr +=
"<i>" + i18n(
"Organizer:" ) +
"</i>" +
" ";
3432 tmpStr += tooltipPerson( incidence->organizer().email(),
3433 incidence->organizer().name() );
3437 str = tooltipFormatAttendeeRoleList( incidence, Attendee::Chair );
3438 if ( !str.isEmpty() ) {
3439 tmpStr +=
"<br><i>" + i18n(
"Chair:" ) +
"</i>" +
" ";
3444 str = tooltipFormatAttendeeRoleList( incidence, Attendee::ReqParticipant );
3445 if ( !str.isEmpty() ) {
3446 tmpStr +=
"<br><i>" + i18n(
"Required Participants:" ) +
"</i>" +
" ";
3451 str = tooltipFormatAttendeeRoleList( incidence, Attendee::OptParticipant );
3452 if ( !str.isEmpty() ) {
3453 tmpStr +=
"<br><i>" + i18n(
"Optional Participants:" ) +
"</i>" +
" ";
3458 str = tooltipFormatAttendeeRoleList( incidence, Attendee::NonParticipant );
3459 if ( !str.isEmpty() ) {
3460 tmpStr +=
"<br><i>" + i18n(
"Observers:" ) +
"</i>" +
" ";
3467 TQString IncidenceFormatter::ToolTipVisitor::generateToolTip(
Incidence* incidence, TQString dtRangeText )
3469 uint maxDescLen = 120;
3475 TQString tmp =
"<qt>";
3478 tmp +=
"<b>" + incidence->
summary().replace(
"\n",
"<br>" ) +
"</b>";
3480 tmp +=
"<br>----------<br>";
3484 if ( !calStr.isEmpty() ) {
3485 tmp +=
"<i>" + i18n(
"Calendar:" ) +
"</i>" +
" ";
3492 if ( !incidence->
location().isEmpty() ) {
3494 tmp +=
"<i>" + i18n(
"Location:" ) +
"</i>" +
" ";
3495 tmp += incidence->
location().replace(
"\n",
"<br>" );
3499 if ( !durStr.isEmpty() ) {
3501 tmp +=
"<i>" + i18n(
"Duration:" ) +
"</i>" +
" ";
3507 tmp +=
"<i>" + i18n(
"Recurrence:" ) +
"</i>" +
" ";
3508 tmp += IncidenceFormatter::recurrenceString( incidence );
3513 if ( desc.length() > maxDescLen ) {
3514 desc = desc.left( maxDescLen ) + etc;
3516 tmp +=
"<br>----------<br>";
3517 tmp +=
"<i>" + i18n(
"Description:" ) +
"</i>" +
"<br>";
3518 tmp += desc.replace(
"\n",
"<br>" );
3519 tmp +=
"<br>----------";
3522 int reminderCount = incidence->
alarms().count();
3525 tmp +=
"<i>" + i18n(
"Reminder:",
"%n Reminders:", reminderCount ) +
"</i>" +
" ";
3526 tmp += IncidenceFormatter::reminderStringList( incidence ).join(
", " );
3530 tmp += tooltipFormatAttendees( incidence );
3532 int categoryCount = incidence->
categories().count();
3533 if ( categoryCount > 0 ) {
3535 tmp +=
"<i>" + i18n(
"Category:",
"%n Categories:", categoryCount ) +
"</i>" +
" ";
3543 TQString IncidenceFormatter::toolTipString(
IncidenceBase *incidence,
bool richText )
3545 return toolTipStr( 0, incidence, TQDate(), richText );
3548 TQString IncidenceFormatter::toolTipStr(
Calendar *calendar,
3554 if ( v.act( calendar, incidence, date, richText ) ) {
3568 MailBodyVisitor() : mResult(
"" ) {}
3573 return incidence ? incidence->
accept( *
this ) :
false;
3575 TQString result()
const {
return mResult; }
3578 bool visit(
Event *event );
3579 bool visit(
Todo *todo );
3580 bool visit(
Journal *journal );
3581 bool visit(
FreeBusy * ) { mResult = i18n(
"This is a Free Busy Object");
return !mResult.isEmpty(); }
3587 static TQString mailBodyIncidence(
Incidence *incidence )
3590 if ( !incidence->
summary().isEmpty() ) {
3591 body += i18n(
"Summary: %1\n").arg( incidence->
summary() );
3593 if ( !incidence->organizer().isEmpty() ) {
3594 body += i18n(
"Organizer: %1\n").arg( incidence->organizer().fullName() );
3596 if ( !incidence->
location().isEmpty() ) {
3597 body += i18n(
"Location: %1\n").arg( incidence->
location() );
3602 bool IncidenceFormatter::MailBodyVisitor::visit(
Event *event )
3604 TQString recurrence[]= {i18n(
"no recurrence",
"None"),
3605 i18n(
"Minutely"), i18n(
"Hourly"), i18n(
"Daily"),
3606 i18n(
"Weekly"), i18n(
"Monthly Same Day"), i18n(
"Monthly Same Position"),
3607 i18n(
"Yearly"), i18n(
"Yearly"), i18n(
"Yearly")};
3609 mResult = mailBodyIncidence( event );
3610 mResult += i18n(
"Start Date: %1\n").
3611 arg( IncidenceFormatter::dateToString( event->
dtStart(), true ) );
3613 mResult += i18n(
"Start Time: %1\n").
3614 arg( IncidenceFormatter::timeToString( event->
dtStart(), true ) );
3616 if ( event->
dtStart() !=
event->dtEnd() ) {
3617 mResult += i18n(
"End Date: %1\n").
3618 arg( IncidenceFormatter::dateToString( event->
dtEnd(), true ) );
3621 mResult += i18n(
"End Time: %1\n").
3622 arg( IncidenceFormatter::timeToString( event->
dtEnd(), true ) );
3627 mResult += i18n(
"Recurs: %1\n")
3629 mResult += i18n(
"Frequency: %1\n")
3633 mResult += i18n (
"Repeats once",
"Repeats %n times", recur->
duration());
3640 endstr = TDEGlobal::locale()->formatDate( recur->
endDate() );
3642 endstr = TDEGlobal::locale()->formatDateTime( recur->
endDateTime() );
3644 mResult += i18n(
"Repeat until: %1\n").arg( endstr );
3646 mResult += i18n(
"Repeats forever\n");
3650 DateList exceptions = recur->exDates();
3651 if (exceptions.isEmpty() ==
false) {
3652 mResult += i18n(
"This recurring meeting has been cancelled on the following days:\n");
3653 DateList::ConstIterator ex_iter;
3654 for ( ex_iter = exceptions.begin(); ex_iter != exceptions.end(); ++ex_iter ) {
3655 mResult += i18n(
" %1\n").arg( TDEGlobal::locale()->formatDate(* ex_iter ) );
3659 TQString details =
event->description();
3660 if ( !details.isEmpty() ) {
3661 mResult += i18n(
"Details:\n%1\n").arg( details );
3663 return !mResult.isEmpty();
3666 bool IncidenceFormatter::MailBodyVisitor::visit(
Todo *todo )
3668 mResult = mailBodyIncidence( todo );
3671 mResult += i18n(
"Start Date: %1\n").
3672 arg( IncidenceFormatter::dateToString( todo->
dtStart(
false ), true ) );
3674 mResult += i18n(
"Start Time: %1\n").
3675 arg( IncidenceFormatter::timeToString( todo->
dtStart(
false ),true ) );
3679 mResult += i18n(
"Due Date: %1\n").
3680 arg( IncidenceFormatter::dateToString( todo->
dtDue(), true ) );
3682 mResult += i18n(
"Due Time: %1\n").
3683 arg( IncidenceFormatter::timeToString( todo->
dtDue(), true ) );
3687 if ( !details.isEmpty() ) {
3688 mResult += i18n(
"Details:\n%1\n").arg( details );
3690 return !mResult.isEmpty();
3693 bool IncidenceFormatter::MailBodyVisitor::visit(
Journal *journal )
3695 mResult = mailBodyIncidence( journal );
3696 mResult += i18n(
"Date: %1\n").
3697 arg( IncidenceFormatter::dateToString( journal->
dtStart(), true ) );
3699 mResult += i18n(
"Time: %1\n").
3700 arg( IncidenceFormatter::timeToString( journal->
dtStart(), true ) );
3703 mResult += i18n(
"Text of the journal:\n%1\n").arg( journal->
description() );
3704 return !mResult.isEmpty();
3709 TQString IncidenceFormatter::mailBodyString(
IncidenceBase *incidence )
3715 if ( v.act( incidence ) ) {
3721 static TQString recurEnd(
Incidence *incidence )
3735 TQString IncidenceFormatter::recurrenceString(
Incidence *incidence )
3738 return i18n(
"No recurrence" );
3740 TQStringList dayList;
3741 dayList.append( i18n(
"31st Last" ) );
3742 dayList.append( i18n(
"30th Last" ) );
3743 dayList.append( i18n(
"29th Last" ) );
3744 dayList.append( i18n(
"28th Last" ) );
3745 dayList.append( i18n(
"27th Last" ) );
3746 dayList.append( i18n(
"26th Last" ) );
3747 dayList.append( i18n(
"25th Last" ) );
3748 dayList.append( i18n(
"24th Last" ) );
3749 dayList.append( i18n(
"23rd Last" ) );
3750 dayList.append( i18n(
"22nd Last" ) );
3751 dayList.append( i18n(
"21st Last" ) );
3752 dayList.append( i18n(
"20th Last" ) );
3753 dayList.append( i18n(
"19th Last" ) );
3754 dayList.append( i18n(
"18th Last" ) );
3755 dayList.append( i18n(
"17th Last" ) );
3756 dayList.append( i18n(
"16th Last" ) );
3757 dayList.append( i18n(
"15th Last" ) );
3758 dayList.append( i18n(
"14th Last" ) );
3759 dayList.append( i18n(
"13th Last" ) );
3760 dayList.append( i18n(
"12th Last" ) );
3761 dayList.append( i18n(
"11th Last" ) );
3762 dayList.append( i18n(
"10th Last" ) );
3763 dayList.append( i18n(
"9th Last" ) );
3764 dayList.append( i18n(
"8th Last" ) );
3765 dayList.append( i18n(
"7th Last" ) );
3766 dayList.append( i18n(
"6th Last" ) );
3767 dayList.append( i18n(
"5th Last" ) );
3768 dayList.append( i18n(
"4th Last" ) );
3769 dayList.append( i18n(
"3rd Last" ) );
3770 dayList.append( i18n(
"2nd Last" ) );
3771 dayList.append( i18n(
"last day of the month",
"Last" ) );
3772 dayList.append( i18n(
"unknown day of the month",
"unknown" ) );
3773 dayList.append( i18n(
"1st" ) );
3774 dayList.append( i18n(
"2nd" ) );
3775 dayList.append( i18n(
"3rd" ) );
3776 dayList.append( i18n(
"4th" ) );
3777 dayList.append( i18n(
"5th" ) );
3778 dayList.append( i18n(
"6th" ) );
3779 dayList.append( i18n(
"7th" ) );
3780 dayList.append( i18n(
"8th" ) );
3781 dayList.append( i18n(
"9th" ) );
3782 dayList.append( i18n(
"10th" ) );
3783 dayList.append( i18n(
"11th" ) );
3784 dayList.append( i18n(
"12th" ) );
3785 dayList.append( i18n(
"13th" ) );
3786 dayList.append( i18n(
"14th" ) );
3787 dayList.append( i18n(
"15th" ) );
3788 dayList.append( i18n(
"16th" ) );
3789 dayList.append( i18n(
"17th" ) );
3790 dayList.append( i18n(
"18th" ) );
3791 dayList.append( i18n(
"19th" ) );
3792 dayList.append( i18n(
"20th" ) );
3793 dayList.append( i18n(
"21st" ) );
3794 dayList.append( i18n(
"22nd" ) );
3795 dayList.append( i18n(
"23rd" ) );
3796 dayList.append( i18n(
"24th" ) );
3797 dayList.append( i18n(
"25th" ) );
3798 dayList.append( i18n(
"26th" ) );
3799 dayList.append( i18n(
"27th" ) );
3800 dayList.append( i18n(
"28th" ) );
3801 dayList.append( i18n(
"29th" ) );
3802 dayList.append( i18n(
"30th" ) );
3803 dayList.append( i18n(
"31st" ) );
3804 int weekStart = TDEGlobal::locale()->weekStartDay();
3806 TQString recurStr, txt;
3807 const KCalendarSystem *calSys = TDEGlobal::locale()->calendar();
3810 case Recurrence::rNone:
3811 return i18n(
"No recurrence" );
3813 case Recurrence::rMinutely:
3814 recurStr = i18n(
"Recurs every minute",
"Recurs every %n minutes", recur->
frequency() );
3816 txt = i18n(
"%1 until %2" ).arg( recurStr ).arg( recurEnd( incidence ) );
3818 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3824 case Recurrence::rHourly:
3825 recurStr = i18n(
"Recurs hourly",
"Recurs every %n hours", recur->
frequency() );
3827 txt = i18n(
"%1 until %2" ).arg( recurStr ).arg( recurEnd( incidence ) );
3829 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3835 case Recurrence::rDaily:
3836 recurStr = i18n(
"Recurs daily",
"Recurs every %n days", recur->
frequency() );
3839 txt = i18n(
"%1 until %2" ).arg( recurStr ).arg( recurEnd( incidence ) );
3841 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3847 case Recurrence::rWeekly:
3849 recurStr = i18n(
"Recurs weekly",
"Recurs every %n weeks", recur->
frequency() );
3851 bool addSpace =
false;
3852 for (
int i = 0; i < 7; ++i ) {
3853 if ( recur->
days().testBit( ( i + weekStart + 6 ) % 7 ) ) {
3855 dayNames.append( i18n(
"separator for list of days",
", " ) );
3857 dayNames.append( calSys->weekDayName( ( ( i + weekStart + 6 ) % 7 ) + 1,
true ) );
3861 if ( dayNames.isEmpty() ) {
3862 dayNames = i18n(
"Recurs weekly on no days",
"no days" );
3865 txt = i18n(
"%1 on %2 until %3" ).
3866 arg( recurStr ).arg( dayNames ).arg( recurEnd( incidence ) );
3868 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3872 txt = i18n(
"%1 on %2" ).arg( recurStr ).arg( dayNames );
3875 case Recurrence::rMonthlyPos:
3877 recurStr = i18n(
"Recurs monthly",
"Recurs every %n months", recur->
frequency() );
3882 txt = i18n(
"%1 on the %2 %3 until %4" ).
3884 arg( dayList[rule.pos() + 31] ).
3885 arg( calSys->weekDayName( rule.day(), false ) ).
3886 arg( recurEnd( incidence ) );
3888 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3892 txt = i18n(
"%1 on the %2 %3" ).
3894 arg( dayList[rule.pos() + 31] ).
3895 arg( calSys->weekDayName( rule.day(), false ) );
3902 case Recurrence::rMonthlyDay:
3904 recurStr = i18n(
"Recurs monthly",
"Recurs every %n months", recur->
frequency() );
3909 txt = i18n(
"%1 on the %2 day until %3" ).
3911 arg( dayList[days + 31] ).
3912 arg( recurEnd( incidence ) );
3914 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3918 txt = i18n(
"%1 on the %2 day" ).arg( recurStr ).arg( dayList[days + 31] );
3925 case Recurrence::rYearlyMonth:
3927 recurStr = i18n(
"Recurs yearly",
"Recurs every %n years", recur->
frequency() );
3931 txt = i18n(
"%1 on %2 %3 until %4" ).
3934 arg( dayList[ recur->
yearDates()[0] + 31 ] ).
3935 arg( recurEnd( incidence ) );
3937 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3943 txt = i18n(
"%1 on %2 %3" ).
3946 arg( dayList[ recur->
yearDates()[0] + 31 ] );
3950 txt = i18n(
"Recurs yearly on %1 %2" ).
3951 arg( calSys->monthName( recur->
yearMonths()[0],
3953 arg( dayList[ recur->
startDate().day() + 31 ] );
3955 txt = i18n(
"Recurs yearly on %1 %2" ).
3956 arg( calSys->monthName( recur->
startDate().month(),
3958 arg( dayList[ recur->
startDate().day() + 31 ] );
3964 case Recurrence::rYearlyDay:
3966 recurStr = i18n(
"Recurs yearly",
"Recurs every %n years", recur->
frequency() );
3967 if ( !recur->
yearDays().isEmpty() ) {
3969 txt = i18n(
"%1 on day %2 until %3" ).
3972 arg( recurEnd( incidence ) );
3974 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3978 txt = i18n(
"%1 on day %2" ).arg( recurStr ).arg( recur->
yearDays()[0] );
3985 case Recurrence::rYearlyPos:
3987 recurStr = i18n(
"Every year",
"Every %n years", recur->
frequency() );
3991 txt = i18n(
"%1 on the %2 %3 of %4 until %5" ).
3993 arg( dayList[rule.pos() + 31] ).
3994 arg( calSys->weekDayName( rule.day(), false ) ).
3996 arg( recurEnd( incidence ) );
3998 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
4002 txt = i18n(
"%1 on the %2 %3 of %4" ).
4004 arg( dayList[rule.pos() + 31] ).
4005 arg( calSys->weekDayName( rule.day(), false ) ).
4015 return i18n(
"Incidence recurs" );
4018 TQString IncidenceFormatter::timeToString(
const TQDateTime &date,
bool shortfmt )
4020 return TDEGlobal::locale()->formatTime( date.time(), !shortfmt );
4023 TQString IncidenceFormatter::dateToString(
const TQDateTime &date,
bool shortfmt )
4026 TDEGlobal::locale()->formatDate( date.date(), shortfmt );
4029 TQString IncidenceFormatter::dateTimeToString(
const TQDateTime &date,
4030 bool allDay,
bool shortfmt )
4033 return dateToString( date, shortfmt );
4036 return TDEGlobal::locale()->formatDateTime( date, shortfmt );
4041 if ( !calendar || !incidence ) {
4046 if ( !calendarResource ) {
4051 if ( resourceCalendar ) {
4054 if ( subRes.isEmpty() ) {
4055 return resourceCalendar->resourceName();
4060 return resourceCalendar->resourceName();
4066 static TQString secs2Duration(
int secs )
4069 int days = secs / 86400;
4071 tmp += i18n(
"1 day",
"%n days", days );
4073 secs -= ( days * 86400 );
4075 int hours = secs / 3600;
4077 tmp += i18n(
"1 hour",
"%n hours", hours );
4079 secs -= ( hours * 3600 );
4081 int mins = secs / 60;
4083 tmp += i18n(
"1 minute",
"%n minutes", mins );
4091 if ( incidence->type() ==
"Event" ) {
4092 Event *
event =
static_cast<Event *
>( incidence );
4095 tmp = secs2Duration( event->
dtStart().secsTo( event->
dtEnd() ) );
4097 tmp = i18n(
"1 day",
"%n days",
4098 event->
dtStart().date().daysTo( event->
dtEnd().date() ) + 1 );
4101 tmp = i18n(
"forever" );
4103 }
else if ( incidence->type() ==
"Todo" ) {
4104 Todo *todo =
static_cast<Todo *
>( incidence );
4108 tmp = secs2Duration( todo->
dtStart().secsTo( todo->
dtDue() ) );
4110 tmp = i18n(
"1 day",
"%n days",
4111 todo->
dtStart().date().daysTo( todo->
dtDue().date() ) + 1 );
4119 TQStringList IncidenceFormatter::reminderStringList(
Incidence *incidence,
bool shortfmt )
4122 Q_UNUSED( shortfmt );
4124 TQStringList reminderStringList;
4128 Alarm::List::ConstIterator it;
4129 for ( it = alarms.begin(); it != alarms.end(); ++it ) {
4132 TQString remStr, atStr, offsetStr;
4135 if ( alarm->
time().isValid() ) {
4136 atStr = TDEGlobal::locale()->formatDateTime( alarm->
time() );
4142 offsetStr = i18n(
"N days/hours/minutes before the start datetime",
4143 "%1 before the start" );
4144 }
else if ( offset > 0 ) {
4145 offsetStr = i18n(
"N days/hours/minutes after the start datetime",
4146 "%1 after the start" );
4148 if ( incidence->
dtStart().isValid() ) {
4149 atStr = TDEGlobal::locale()->formatDateTime( incidence->
dtStart() );
4156 if ( incidence->type() ==
"Todo" ) {
4157 offsetStr = i18n(
"N days/hours/minutes before the due datetime",
4158 "%1 before the to-do is due" );
4160 offsetStr = i18n(
"N days/hours/minutes before the end datetime",
4161 "%1 before the end" );
4163 }
else if ( offset > 0 ) {
4164 if ( incidence->type() ==
"Todo" ) {
4165 offsetStr = i18n(
"N days/hours/minutes after the due datetime",
4166 "%1 after the to-do is due" );
4168 offsetStr = i18n(
"N days/hours/minutes after the end datetime",
4169 "%1 after the end" );
4172 if ( incidence->type() ==
"Todo" ) {
4173 Todo *t =
static_cast<Todo *
>( incidence );
4174 if ( t->
dtDue().isValid() ) {
4175 atStr = TDEGlobal::locale()->formatDateTime( t->
dtDue() );
4178 Event *e =
static_cast<Event *
>( incidence );
4179 if ( e->
dtEnd().isValid() ) {
4180 atStr = TDEGlobal::locale()->formatDateTime( e->
dtEnd() );
4185 if ( offset == 0 ) {
4186 if ( !atStr.isEmpty() ) {
4187 remStr = i18n(
"reminder occurs at datetime",
"at %1" ).arg( atStr );
4190 remStr = offsetStr.arg( secs2Duration( offset ) );
4194 TQString countStr = i18n(
"repeats once",
"repeats %n times", alarm->
repeatCount() );
4195 TQString intervalStr = i18n(
"interval is N days/hours/minutes",
"interval is %1" ).
4197 TQString repeatStr = i18n(
"(repeat string, interval string)",
"(%1, %2)" ).
4198 arg( countStr, intervalStr );
4199 remStr = remStr +
' ' + repeatStr;
4202 reminderStringList << remStr;
4206 return reminderStringList;
virtual TQStringList subresources() const
If this resource has subresources, return a TQStringList of them.
virtual bool accept(Visitor &)
Accept IncidenceVisitor.
TQDateTime getNextDateTime(const TQDateTime &preDateTime) const
Returns the date and time of the next recurrence, after the specified date/time.
TQValueList< int > yearDates() const
Returns the dates within a yearly recurrence.
bool doesRecur() const
Forward to Recurrence::doesRecur().
bool doesFloat() const
Return true or false depending on whether the incidence "floats," i.e.
bool isReadOnly() const
Return if the object is read-only.
static TQString roleName(Role)
Return string represenation of role.
IncidenceBase * event()
Return event associated with this message.
TQString customProperty(const TQCString &app, const TQCString &key) const
Return the value of a custom calendar property.
TQDate endDate() const
Returns the date of the last recurrence.
This class provides a Todo in the sense of RFC2445.
This is the main "calendar" object class.
int duration() const
Returns -1 if the event recurs infinitely, 0 if the end date is set, otherwise the total number of re...
This class provides the base class common to all calendar components.
TQString uid() const
Return unique id of the attendee.
virtual const TQString labelForSubresource(const TQString &resource) const
What is the label for this subresource?
TQDateTime getPreviousDateTime(const TQDateTime &afterDateTime) const
Returns the date and time of the last previous recurrence, before the specified date/time.
int repeatCount() const
Get how many times an alarm repeats, after its initial occurrence.
This class represents information related to an attendee of an event.
This class provides a Calendar which is composed of other Calendars known as "Resources".
TQStringList categories() const
Return categories as a list of strings.
TQDateTime created() const
Return time and date of creation.
This class provides an Event in the sense of RFC2445.
This class provides an encapsulation of a scheduling message.
int method()
Return iTIP method associated with this message.
int frequency() const
Returns frequency of recurrence, in terms of the recurrence time period type.
TQString statusStr() const
Return status as human-readable string.
This class provides a calendar stored as a local file.
bool isAlarmEnabled() const
Return whether any alarm associated with this incidence is enabled.
void setStartOffset(const Duration &)
Set offset of alarm in time relative to the start of the event.
virtual TQDateTime dtEnd() const
Return end date and time.
int asSeconds() const
Returns the length of the duration in seconds.
virtual TQDateTime dtStart() const
returns an event's starting date/time as a TQDateTime.
void setRole(Role)
Set role of Attendee.
This class provides the interfaces for a calendar resource.
PartStat status() const
Return status.
This class provides the interface for a visitor of calendar components.
bool isCompleted() const
Returns true if the todo is 100% completed, otherwise return false.
void setOrganizer(const Person &o)
sets the organizer for the event
bool addEvent(Event *event)
Add Event to calendar.
bool isMultiDay() const
Return true if the event spans multiple days, otherwise return false.
bool hasTime() const
Return true, if the alarm has an explicit date/time.
TQString summary() const
Return short summary.
TQDateTime time() const
Return the date/time when an alarm goes off.
structure for describing the n-th weekday of the month/year.
Provides a Calendar composed of several Calendar Resources.
This class represents a person.
Attachment::List attachments() const
Return list of all associated attachments.
bool hasEndDate() const
Return whether the event has an end date/time.
Provides the main "calendar" object class.
bool hasStartOffset() const
Return whether the alarm is defined in terms of an offset relative to the start of the event...
TQString uid() const
Return the unique id for the event.
TQValueList< int > monthDays() const
Returns list of day numbers of a month.
void setStatus(PartStat s)
Set status.
TQValueList< RecurrenceRule::WDayPos > yearPositions() const
Returns the positions within a yearly recurrence.
This class provides the base class common to all calendar components.
bool hasEndOffset() const
Return whether the alarm is defined in terms of an offset relative to the end of the event...
void setDisplayAlarm(const TQString &text=TQString())
Set the alarm to be a display alarm.
TQString delegator() const
Returns the delegator.
This class represents information related to an attachment.
bool hasDueDate() const
Returns true if the todo has a due date, otherwise return false.
This class provides a Journal in the sense of RFC2445.
Duration endOffset() const
Return offset of alarm in time relative to the end of the event.
ResourceCalendar * resource(Incidence *incidence)
Get the Resource associated with a specified Incidence.
Duration startOffset() const
Return offset of alarm in time relative to the start of the event.
const Alarm::List & alarms() const
All alarms that are associated with this incidence.
This class represents a period of time.
virtual TQString subresourceIdentifier(Incidence *incidence)
Get the identifier of the subresource associated with a specified incidence.
Attendee * attendeeByMail(const TQString &) const
Return the Attendee with this email address.
TQValueList< int > yearDays() const
Returns the day numbers within a yearly recurrence.
Namespace KCal is for global classes, objects and/or functions in libkcal.
Duration snoozeTime() const
Get how long the alarm snooze interval is.
void setTime(const TQDateTime &alarmTime)
Set the time to trigger an alarm.
Role role() const
Return role of Attendee.
TQString location() const
Return the event's/todo's location.
TQValueList< RecurrenceRule::WDayPos > monthPositions() const
Returns list of day positions in months.
bool hasStartDate() const
Returns true if the todo has a start date, otherwise return false.
This class represents a duration.
const Attendee::List & attendees() const
Return list of attendees.
static TQString statusName(PartStat)
Return string representation of attendee status.
TQStringList comments() const
Return all comments associated with this incidence.
TQString delegate() const
Returns the delegate.
Recurrence * recurrence() const
Return the recurrence rule associated with this incidence.
int percentComplete() const
Returns how many percent of the task are completed.
TQBitArray days() const
Returns week day mask (bit 0 = Monday).
TQDateTime dtDue(bool first=false) const
Returns due date and time.
TQString description() const
Return long description.
TQDateTime endDateTime() const
Returns the date/time of the last recurrence.
int priority() const
Return priority.
TQString completedStr() const
Returns string contaiting date and time when the todo was completed formatted according to the users ...
ushort recurrenceType() const
Returns the event's recurrence status.
int revision() const
Return the number of revisions this event has seen.
TQValueList< int > yearMonths() const
Returns the months within a yearly recurrence.
TQDate startDate() const
Return the start date/time of the recurrence.
This class provides information about free/busy time of a calendar user.
This class represents an alarm notification.
This class represents a recurrence rule for a calendar incidence.
TQDateTime dtStart(bool first=false) const
Returns the startdate of the todo.