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 )
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( &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;
2967 event->setOrganizer( s );
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 ) );
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;