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>";
578 TQString description =
event->description();
581 TQRegExp urlRegex(
"https?://[^\\s]+");
584 while ((pos = urlRegex.search(description, pos)) != -1) {
585 TQString url = urlRegex.cap(0);
586 TQString link =
"<a href=\"" + url +
"\">" + url +
"</a>";
587 description.replace(pos, url.length(), link);
588 pos += link.length();
592 tmpStr +=
"<td><b>" + i18n(
"Description:" ) +
"</b></td>";
593 tmpStr +=
"<td>" + description +
"</td>";
599 int reminderCount =
event->alarms().count();
602 tmpStr +=
"<td><b>" +
603 i18n(
"Reminder:",
"%n Reminders:", reminderCount ) +
605 tmpStr +=
"<td>" + IncidenceFormatter::reminderStringList( event ).join(
"<br>" ) +
"</td>";
609 tmpStr += displayViewFormatAttendees( event );
611 int categoryCount =
event->categories().count();
612 if ( categoryCount > 0 ) {
614 tmpStr +=
"<td><b>" +
615 i18n(
"Category:",
"%n Categories:", categoryCount ) +
617 tmpStr +=
"<td>" + displayViewFormatCategories( event ) +
"</td>";
621 int attachmentCount =
event->attachments().count();
622 if ( attachmentCount > 0 ) {
624 tmpStr +=
"<td><b>" +
625 i18n(
"Attachment:",
"%n Attachments:", attachmentCount ) +
627 tmpStr +=
"<td>" + displayViewFormatAttachments( event ) +
"</td>";
630 tmpStr +=
"</table>";
632 tmpStr +=
"<em>" + displayViewFormatCreationDate( event ) +
"</em>";
637 static TQString displayViewFormatTodo(
Calendar *calendar,
Todo *todo,
644 TQString tmpStr = displayViewFormatHeader( todo );
647 tmpStr +=
"<col width=\"25%\"/>";
648 tmpStr +=
"<col width=\"75%\"/>";
652 if ( !calStr.isEmpty() ) {
654 tmpStr +=
"<td><b>" + i18n(
"Calendar:" ) +
"</b></td>";
655 tmpStr +=
"<td>" + calStr +
"</td>";
660 if ( !todo->
location().isEmpty() ) {
662 tmpStr +=
"<td><b>" + i18n(
"Location:" ) +
"</b></td>";
663 tmpStr +=
"<td>" + todo->
location() +
"</td>";
668 TQDateTime startDt = todo->
dtStart();
670 if ( date.isValid() ) {
671 startDt.setDate( date );
675 tmpStr +=
"<td><b>" + i18n(
"Start:" ) +
"</b></td>";
677 IncidenceFormatter::dateTimeToString( startDt,
684 TQDateTime dueDt = todo->
dtDue();
686 if ( date.isValid() ) {
687 TQDateTime dt( date, TQTime( 0, 0, 0 ) );
688 dt = dt.addSecs( -1 );
693 tmpStr +=
"<td><b>" + i18n(
"Due:" ) +
"</b></td>";
695 IncidenceFormatter::dateTimeToString( dueDt,
702 if ( !durStr.isEmpty() ) {
704 tmpStr +=
"<td><b>" + i18n(
"Duration:" ) +
"</b></td>";
705 tmpStr +=
"<td>" + durStr +
"</td>";
711 tmpStr +=
"<td><b>" + i18n(
"Recurrence:" ) +
"</b></td>";
713 IncidenceFormatter::recurrenceString( todo ) +
720 tmpStr +=
"<td><b>" + i18n(
"Description:" ) +
"</b></td>";
727 int reminderCount = todo->
alarms().count();
730 tmpStr +=
"<td><b>" +
731 i18n(
"Reminder:",
"%n Reminders:", reminderCount ) +
733 tmpStr +=
"<td>" + IncidenceFormatter::reminderStringList( todo ).join(
"<br>" ) +
"</td>";
737 tmpStr += displayViewFormatAttendees( todo );
739 int categoryCount = todo->
categories().count();
740 if ( categoryCount > 0 ) {
742 tmpStr +=
"<td><b>" +
743 i18n(
"Category:",
"%n Categories:", categoryCount ) +
745 tmpStr +=
"<td>" + displayViewFormatCategories( todo ) +
"</td>";
751 tmpStr +=
"<td><b>" + i18n(
"Priority:" ) +
"</b></td>";
753 tmpStr += TQString::number( todo->
priority() );
760 tmpStr +=
"<td><b>" + i18n(
"Completed:" ) +
"</b></td>";
764 tmpStr +=
"<td><b>" + i18n(
"Percent Done:" ) +
"</b></td>";
772 if ( attachmentCount > 0 ) {
774 tmpStr +=
"<td><b>" +
775 i18n(
"Attachment:",
"Attachments:", attachmentCount ) +
777 tmpStr +=
"<td>" + displayViewFormatAttachments( todo ) +
"</td>";
781 tmpStr +=
"</table>";
783 tmpStr +=
"<em>" + displayViewFormatCreationDate( todo ) +
"</em>";
788 static TQString displayViewFormatJournal(
Calendar *calendar,
Journal *journal )
794 TQString tmpStr = displayViewFormatHeader( journal );
797 tmpStr +=
"<col width=\"25%\"/>";
798 tmpStr +=
"<col width=\"75%\"/>";
802 if ( !calStr.isEmpty() ) {
804 tmpStr +=
"<td><b>" + i18n(
"Calendar:" ) +
"</b></td>";
805 tmpStr +=
"<td>" + calStr +
"</td>";
811 tmpStr +=
"<td><b>" + i18n(
"Date:" ) +
"</b></td>";
813 IncidenceFormatter::dateToString( journal->
dtStart(),
false ) +
819 tmpStr +=
"<td><b>" + i18n(
"Description:" ) +
"</b></td>";
820 tmpStr +=
"<td>" + journal->
description() +
"</td>";
824 int categoryCount = journal->
categories().count();
825 if ( categoryCount > 0 ) {
827 tmpStr +=
"<td><b>" +
828 i18n(
"Category:",
"%n Categories:", categoryCount ) +
830 tmpStr +=
"<td>" + displayViewFormatCategories( journal ) +
"</td>";
833 tmpStr +=
"</table>";
835 tmpStr +=
"<em>" + displayViewFormatCreationDate( journal ) +
"</em>";
846 TQString tmpStr = htmlAddTag(
"h2",
848 i18n(
"Free/Busy information for %1").
849 arg( fb->organizer().fullName() ) ) );
851 tmpStr += htmlAddTag(
"h4", i18n(
"Busy times in date range %1 - %2:").
852 arg( IncidenceFormatter::dateToString( fb->
dtStart(),
true ) ).
853 arg( IncidenceFormatter::dateToString( fb->dtEnd(),
true ) ) );
855 TQValueList<Period> periods = fb->busyPeriods();
857 TQString text = htmlAddTag(
"em", htmlAddTag(
"b", i18n(
"Busy:") ) );
858 TQValueList<Period>::iterator it;
859 for ( it = periods.begin(); it != periods.end(); ++it ) {
861 if ( per.hasDuration() ) {
865 cont += i18n(
"1 hour ",
"%n hours ", dur / 3600 );
869 cont += i18n(
"1 minute ",
"%n minutes ", dur / 60);
873 cont += i18n(
"1 second",
"%n seconds", dur);
875 text += i18n(
"startDate for duration",
"%1 for %2").
876 arg( IncidenceFormatter::dateTimeToString( per.start(),
false,
true ) ).
880 if ( per.start().date() == per.end().date() ) {
881 text += i18n(
"date, fromTime - toTime ",
"%1, %2 - %3").
882 arg( IncidenceFormatter::dateToString( per.start().date(),
true ) ).
883 arg( IncidenceFormatter::timeToString( per.start(),
true ) ).
884 arg( IncidenceFormatter::timeToString( per.end(),
true ) );
886 text += i18n(
"fromDateTime - toDateTime",
"%1 - %2").
887 arg( IncidenceFormatter::dateTimeToString( per.start(),
false,
true ) ).
888 arg( IncidenceFormatter::dateTimeToString( per.end(),
false,
true ) );
893 tmpStr += htmlAddTag(
"p", text );
901 : mCalendar( 0 ), mResult(
"" ) {}
905 mCalendar = calendar;
908 return incidence->
accept( *
this );
910 TQString result()
const {
return mResult; }
913 bool visit(
Event *event )
915 mResult = displayViewFormatEvent( mCalendar, event, mDate );
916 return !mResult.isEmpty();
918 bool visit(
Todo *todo )
920 mResult = displayViewFormatTodo( mCalendar, todo, mDate );
921 return !mResult.isEmpty();
925 mResult = displayViewFormatJournal( mCalendar, journal );
926 return !mResult.isEmpty();
930 mResult = displayViewFormatFreeBusy( mCalendar, fb );
931 return !mResult.isEmpty();
940 TQString IncidenceFormatter::extensiveDisplayString(
IncidenceBase *incidence )
942 return extensiveDisplayStr( 0, incidence, TQDate() );
945 TQString IncidenceFormatter::extensiveDisplayStr(
Calendar *calendar,
953 EventViewerVisitor v;
954 if ( v.act( calendar, incidence, date ) ) {
965 static TQString string2HTML(
const TQString& str )
967 return TQStyleSheet::convertFromPlainText(str, TQStyleSheetItem::WhiteSpaceNormal);
970 static TQString cleanHtml(
const TQString &html )
972 TQRegExp rx(
"<body[^>]*>(.*)</body>" );
973 rx.setCaseSensitive(
false );
975 TQString body = rx.cap( 1 );
977 return TQStyleSheet::escape( body.remove( TQRegExp(
"<[^>]*>" ) ).stripWhiteSpace() );
980 static TQString eventStartTimeStr(
Event *event )
984 tmp = i18n(
"%1: Start Date, %2: Start Time",
"%1 %2" ).
985 arg( IncidenceFormatter::dateToString( event->
dtStart(),
true ),
986 IncidenceFormatter::timeToString( event->
dtStart(),
true ) );
988 tmp = i18n(
"%1: Start Date",
"%1 (all day)" ).
989 arg( IncidenceFormatter::dateToString( event->
dtStart(),
true ) );
994 static TQString eventEndTimeStr(
Event *event )
999 tmp = i18n(
"%1: End Date, %2: End Time",
"%1 %2" ).
1000 arg( IncidenceFormatter::dateToString( event->
dtEnd(),
true ),
1001 IncidenceFormatter::timeToString( event->
dtEnd(),
true ) );
1003 tmp = i18n(
"%1: End Date",
"%1 (all day)" ).
1004 arg( IncidenceFormatter::dateToString( event->
dtEnd(),
true ) );
1010 static TQString invitationRow(
const TQString &cell1,
const TQString &cell2 )
1012 return "<tr><td>" + cell1 +
"</td><td>" + cell2 +
"</td></tr>\n";
1024 KEMailSettings settings;
1025 TQStringList profiles = settings.profiles();
1026 for( TQStringList::Iterator it=profiles.begin(); it!=profiles.end(); ++it ) {
1027 settings.setProfile( *it );
1029 TQString delegatorName, delegatorEmail;
1031 Attendee::List::ConstIterator it2;
1032 for ( it2 = attendees.begin(); it2 != attendees.end(); ++it2 ) {
1034 KPIM::getNameAndMail( a->
delegator(), delegatorName, delegatorEmail );
1035 if ( settings.getSetting( KEMailSettings::EmailAddress ) == delegatorEmail ) {
1053 KEMailSettings settings;
1054 TQStringList profiles = settings.profiles();
1055 for( TQStringList::Iterator it=profiles.begin(); it!=profiles.end(); ++it ) {
1056 settings.setProfile( *it );
1059 Attendee::List::ConstIterator it2;
1060 for ( it2 = attendees.begin(); it2 != attendees.end(); ++it2 ) {
1062 if ( settings.getSetting( KEMailSettings::EmailAddress ) == a->email() ) {
1081 Attendee::List::ConstIterator it;
1082 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
1084 if ( email == a->email() ) {
1092 static bool rsvpRequested(
Incidence *incidence )
1102 Attendee::List::ConstIterator it;
1103 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
1104 if ( it == attendees.begin() ) {
1105 rsvp = (*it)->RSVP();
1107 if ( (*it)->RSVP() != rsvp ) {
1116 static TQString rsvpRequestedStr(
bool rsvpRequested,
const TQString &role )
1118 if ( rsvpRequested ) {
1119 if ( role.isEmpty() ) {
1120 return i18n(
"Your response is requested" );
1122 return i18n(
"Your response as <b>%1</b> is requested" ).arg( role );
1125 if ( role.isEmpty() ) {
1126 return i18n(
"No response is necessary" );
1128 return i18n(
"No response as <b>%1</b> is necessary" ).arg( role );
1133 static TQString myStatusStr(
Incidence *incidence )
1136 Attendee *a = findMyAttendee( incidence );
1138 a->
status() != Attendee::NeedsAction && a->
status() != Attendee::Delegated ) {
1139 ret = i18n(
"(<b>Note</b>: the Organizer preset your response to <b>%1</b>)" ).
1145 static TQString invitationPerson(
const TQString& email, TQString name, TQString uid )
1149 if ( !email.isEmpty() && ( name.isEmpty() || uid.isEmpty() ) ) {
1150 TDEABC::AddressBook *add_book = TDEABC::StdAddressBook::self(
true );
1151 TDEABC::Addressee::List addressList = add_book->findByEmail( email );
1152 if ( !addressList.isEmpty() ) {
1153 TDEABC::Addressee o = addressList.first();
1154 if ( !o.isEmpty() && addressList.size() < 2 ) {
1155 if ( name.isEmpty() ) {
1157 name = o.formattedName();
1169 if ( !uid.isEmpty() ) {
1171 if ( name.isEmpty() ) {
1173 tmpString += htmlAddLink(
"uid:" + uid, email );
1175 tmpString += htmlAddLink(
"uid:" + uid, name );
1179 tmpString += ( name.isEmpty() ? email : name );
1184 if ( !email.isEmpty() ) {
1187 mailto.setProtocol(
"mailto" );
1188 mailto.setPath( person.fullName() );
1189 const TQString iconPath =
1190 TDEGlobal::iconLoader()->iconPath(
"mail-message-new", TDEIcon::Small );
1191 tmpString +=
" " +
1192 htmlAddLink( mailto.url(),
"<img src=\"" + iconPath +
"\">" )
1200 static TQString invitationsDetailsIncidence(
Incidence *incidence,
bool noHtmlMode )
1208 TQStringList comments;
1210 if ( incidence->
comments().isEmpty() ) {
1213 if ( !TQStyleSheet::mightBeRichText( incidence->
description() ) ) {
1214 comments << string2HTML( incidence->
description() );
1218 comments[0] = cleanHtml( comments[0] );
1220 comments[0] = htmlAddTag(
"p", comments[0] );
1226 TQStringList cl = incidence->
comments();
1228 for( TQStringList::Iterator it=cl.begin(); it!=cl.end(); ++it ) {
1229 if ( !TQStyleSheet::mightBeRichText( *it ) ) {
1230 comments.append( string2HTML( *it ) );
1233 comments.append( cleanHtml(
"<body>" + (*it) +
"</body>" ) );
1235 comments.append( *it );
1242 if ( !TQStyleSheet::mightBeRichText( incidence->
description() ) ) {
1247 descr = cleanHtml( descr );
1249 descr = htmlAddTag(
"p", descr );
1254 if( !descr.isEmpty() ) {
1256 html +=
"<table border=\"0\" style=\"margin-top:4px;\">";
1257 html +=
"<tr><td><center>" +
1258 htmlAddTag(
"u", i18n(
"Description:" ) ) +
1259 "</center></td></tr>";
1260 html +=
"<tr><td>" + descr +
"</td></tr>";
1264 if ( !comments.isEmpty() ) {
1266 html +=
"<table border=\"0\" style=\"margin-top:4px;\">";
1267 html +=
"<tr><td><center>" +
1268 htmlAddTag(
"u", i18n(
"Comments:" ) ) +
1269 "</center></td></tr>";
1271 if ( comments.count() > 1 ) {
1273 for ( uint i=0; i < comments.count(); ++i ) {
1274 html +=
"<li>" + comments[i] +
"</li>";
1278 html += comments[0];
1280 html +=
"</td></tr>";
1286 static TQString invitationDetailsEvent(
Event* event,
bool noHtmlMode )
1293 TQString sSummary = i18n(
"Summary unspecified" );
1294 if ( !event->
summary().isEmpty() ) {
1295 if ( !TQStyleSheet::mightBeRichText( event->
summary() ) ) {
1296 sSummary = TQStyleSheet::escape( event->
summary() );
1298 sSummary =
event->summary();
1300 sSummary = cleanHtml( sSummary );
1305 TQString sLocation = i18n(
"Location unspecified" );
1306 if ( !event->
location().isEmpty() ) {
1307 if ( !TQStyleSheet::mightBeRichText( event->
location() ) ) {
1308 sLocation = TQStyleSheet::escape( event->
location() );
1310 sLocation =
event->location();
1312 sLocation = cleanHtml( sLocation );
1317 TQString dir = ( TQApplication::reverseLayout() ?
"rtl" :
"ltr" );
1318 TQString html = TQString(
"<div dir=\"%1\">\n").arg(dir);
1320 html +=
"<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n";
1323 html += invitationRow( i18n(
"What:" ), sSummary );
1324 html += invitationRow( i18n(
"Where:" ), sLocation );
1327 html += invitationRow( i18n(
"First Start Time:" ), eventStartTimeStr( event ) );
1328 html += invitationRow( i18n(
"First End Time:" ), eventEndTimeStr( event ) );
1332 if ( event->
dtStart().date() == event->
dtEnd().date() ) {
1333 html += invitationRow( i18n(
"Date:" ),
1334 IncidenceFormatter::dateToString( event->
dtStart(),
false ) );
1336 html += invitationRow( i18n(
"Time:" ),
1337 IncidenceFormatter::timeToString( event->
dtStart(),
true ) +
1339 IncidenceFormatter::timeToString( event->
dtEnd(),
true ) );
1342 html += invitationRow( i18n(
"Starting date of an event",
"From:" ),
1343 IncidenceFormatter::dateToString( event->
dtStart(),
false ) );
1345 html += invitationRow( i18n(
"Starting time of an event",
"At:" ),
1346 IncidenceFormatter::timeToString( event->
dtStart(),
true ) );
1349 html += invitationRow( i18n(
"Ending date of an event",
"To:" ),
1350 IncidenceFormatter::dateToString( event->
dtEnd(),
false ) );
1352 html += invitationRow( i18n(
"Starting time of an event",
"At:" ),
1353 IncidenceFormatter::timeToString( event->
dtEnd(),
true ) );
1356 html += invitationRow( i18n(
"Ending date of an event",
"To:" ),
1357 i18n(
"no end date specified" ) );
1364 if ( !durStr.isEmpty() ) {
1365 html += invitationRow( i18n(
"Duration:" ), durStr );
1371 html += invitationRow( i18n(
"Recurrence:" ), IncidenceFormatter::recurrenceString( event ) );
1373 DateList exceptions = recur->exDates();
1374 if (exceptions.isEmpty() ==
false) {
1376 isFirstExRow =
true;
1377 DateList::ConstIterator ex_iter;
1378 for ( ex_iter = exceptions.begin(); ex_iter != exceptions.end(); ++ex_iter ) {
1379 if (isFirstExRow ==
true) {
1380 isFirstExRow =
false;
1381 html += invitationRow( i18n(
"Cancelled on:"), TDEGlobal::locale()->formatDate(* ex_iter ) );
1384 html += invitationRow(
" ", TDEGlobal::locale()->formatDate(* ex_iter ) );
1390 html +=
"</table>\n";
1391 html += invitationsDetailsIncidence( event, noHtmlMode );
1397 static TQString invitationDetailsTodo(
Todo *todo,
bool noHtmlMode )
1404 TQString sSummary = i18n(
"Summary unspecified" );
1405 if ( !todo->
summary().isEmpty() ) {
1406 if ( !TQStyleSheet::mightBeRichText( todo->
summary() ) ) {
1407 sSummary = TQStyleSheet::escape( todo->
summary() );
1411 sSummary = cleanHtml( sSummary );
1416 TQString sLocation = i18n(
"Location unspecified" );
1417 if ( !todo->
location().isEmpty() ) {
1418 if ( !TQStyleSheet::mightBeRichText( todo->
location() ) ) {
1419 sLocation = TQStyleSheet::escape( todo->
location() );
1423 sLocation = cleanHtml( sLocation );
1428 TQString dir = ( TQApplication::reverseLayout() ?
"rtl" :
"ltr" );
1429 TQString html = TQString(
"<div dir=\"%1\">\n").arg(dir);
1430 html +=
"<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n";
1433 html += invitationRow( i18n(
"What:" ), sSummary );
1434 html += invitationRow( i18n(
"Where:" ), sLocation );
1437 html += invitationRow( i18n(
"Start Date:" ),
1438 IncidenceFormatter::dateToString( todo->
dtStart(),
false ) );
1440 html += invitationRow( i18n(
"Start Time:" ),
1441 IncidenceFormatter::timeToString( todo->
dtStart(),
false ) );
1445 html += invitationRow( i18n(
"Due Date:" ),
1446 IncidenceFormatter::dateToString( todo->
dtDue(),
false ) );
1448 html += invitationRow( i18n(
"Due Time:" ),
1449 IncidenceFormatter::timeToString( todo->
dtDue(),
false ) );
1453 html += invitationRow( i18n(
"Due Date:" ), i18n(
"Due Date: None",
"None" ) );
1456 html +=
"</table></div>\n";
1457 html += invitationsDetailsIncidence( todo, noHtmlMode );
1462 static TQString invitationDetailsJournal(
Journal *journal,
bool noHtmlMode )
1468 TQString sSummary = i18n(
"Summary unspecified" );
1469 TQString sDescr = i18n(
"Description unspecified" );
1470 if ( ! journal->
summary().isEmpty() ) {
1471 sSummary = journal->
summary();
1473 sSummary = cleanHtml( sSummary );
1479 sDescr = cleanHtml( sDescr );
1482 TQString html(
"<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n" );
1483 html += invitationRow( i18n(
"Summary:" ), sSummary );
1484 html += invitationRow( i18n(
"Date:" ),
1485 IncidenceFormatter::dateToString( journal->
dtStart(),
false ) );
1486 html += invitationRow( i18n(
"Description:" ), sDescr );
1487 html +=
"</table>\n";
1488 html += invitationsDetailsIncidence( journal, noHtmlMode );
1493 static TQString invitationDetailsFreeBusy(
FreeBusy *fb,
bool )
1497 TQString html(
"<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n" );
1499 html += invitationRow( i18n(
"Person:"), fb->organizer().fullName() );
1500 html += invitationRow( i18n(
"Start date:"),
1501 IncidenceFormatter::dateToString( fb->
dtStart(),
true ) );
1502 html += invitationRow( i18n(
"End date:"),
1503 TDEGlobal::locale()->formatDate( fb->dtEnd().date(),
true ) );
1504 html +=
"<tr><td colspan=2><hr></td></tr>\n";
1505 html +=
"<tr><td colspan=2>Busy periods given in this free/busy object:</td></tr>\n";
1507 TQValueList<Period> periods = fb->busyPeriods();
1509 TQValueList<Period>::iterator it;
1510 for ( it = periods.begin(); it != periods.end(); ++it ) {
1512 if ( per.hasDuration() ) {
1515 if ( dur >= 3600 ) {
1516 cont += i18n(
"1 hour ",
"%n hours ", dur / 3600);
1520 cont += i18n(
"1 minute",
"%n minutes ", dur / 60);
1524 cont += i18n(
"1 second",
"%n seconds", dur);
1526 html += invitationRow( TQString(), i18n(
"startDate for duration",
"%1 for %2")
1527 .arg( TDEGlobal::locale()->formatDateTime( per.start(),
false ) )
1531 if ( per.start().date() == per.end().date() ) {
1532 cont = i18n(
"date, fromTime - toTime ",
"%1, %2 - %3")
1533 .arg( TDEGlobal::locale()->formatDate( per.start().date() ) )
1534 .arg( TDEGlobal::locale()->formatTime( per.start().time() ) )
1535 .arg( TDEGlobal::locale()->formatTime( per.end().time() ) );
1537 cont = i18n(
"fromDateTime - toDateTime",
"%1 - %2")
1538 .arg( TDEGlobal::locale()->formatDateTime( per.start(),
false ) )
1539 .arg( TDEGlobal::locale()->formatDateTime( per.end(),
false ) );
1542 html += invitationRow( TQString(), cont );
1546 html +=
"</table>\n";
1550 static bool replyMeansCounter(
Incidence * )
1569 static TQString invitationHeaderEvent(
Event *event,
Incidence *existingIncidence,
1572 if ( !msg || !event )
1575 switch ( msg->
method() ) {
1576 case Scheduler::Publish:
1577 return i18n(
"This invitation has been published" );
1578 case Scheduler::Request:
1579 if ( existingIncidence && event->
revision() > 0 ) {
1580 return i18n(
"This invitation has been updated by the organizer %1" ).
1581 arg( event->organizer().fullName() );
1583 if ( iamOrganizer( event ) ) {
1584 return i18n(
"I created this invitation" );
1587 if ( !event->organizer().fullName().isEmpty() ) {
1588 orgStr =
event->organizer().fullName();
1589 }
else if ( !event->organizer().email().isEmpty() ) {
1590 orgStr =
event->organizer().email();
1592 if ( senderIsOrganizer( event, sender ) ) {
1593 if ( !orgStr.isEmpty() ) {
1594 return i18n(
"You received an invitation from %1" ).arg( orgStr );
1596 return i18n(
"You received an invitation" );
1599 if ( !orgStr.isEmpty() ) {
1600 return i18n(
"You received an invitation from %1 as a representative of %2" ).
1601 arg( sender, orgStr );
1603 return i18n(
"You received an invitation from %1 as the organizer's representative" ).
1608 case Scheduler::Refresh:
1609 return i18n(
"This invitation was refreshed" );
1610 case Scheduler::Cancel:
1611 return i18n(
"This invitation has been canceled" );
1612 case Scheduler::Add:
1613 return i18n(
"Addition to the invitation" );
1614 case Scheduler::Reply:
1616 if ( replyMeansCounter( event ) ) {
1617 return i18n(
"%1 makes this counter proposal" ).
1618 arg( firstAttendeeName( event, i18n(
"Sender" ) ) );
1622 if( attendees.count() == 0 ) {
1623 kdDebug(5850) <<
"No attendees in the iCal reply!" << endl;
1626 if( attendees.count() != 1 ) {
1627 kdDebug(5850) <<
"Warning: attendeecount in the reply should be 1 "
1628 <<
"but is " << attendees.count() << endl;
1630 TQString attendeeName = firstAttendeeName( event, i18n(
"Sender" ) );
1632 TQString delegatorName, dummy;
1633 Attendee* attendee = *attendees.begin();
1634 KPIM::getNameAndMail( attendee->
delegator(), delegatorName, dummy );
1635 if ( delegatorName.isEmpty() ) {
1639 switch( attendee->
status() ) {
1640 case Attendee::NeedsAction:
1641 return i18n(
"%1 indicates this invitation still needs some action" ).arg( attendeeName );
1642 case Attendee::Accepted:
1644 if ( !sender.isEmpty() ) {
1645 return i18n(
"This invitation has been updated by attendee %1" ).arg( sender );
1647 return i18n(
"This invitation has been updated by an attendee" );
1650 if ( delegatorName.isEmpty() ) {
1651 return i18n(
"%1 accepts this invitation" ).arg( attendeeName );
1653 return i18n(
"%1 accepts this invitation on behalf of %2" ).
1654 arg( attendeeName ).arg( delegatorName );
1657 case Attendee::Tentative:
1658 if ( delegatorName.isEmpty() ) {
1659 return i18n(
"%1 tentatively accepts this invitation" ).
1660 arg( attendeeName );
1662 return i18n(
"%1 tentatively accepts this invitation on behalf of %2" ).
1663 arg( attendeeName ).arg( delegatorName );
1665 case Attendee::Declined:
1666 if ( delegatorName.isEmpty() ) {
1667 return i18n(
"%1 declines this invitation" ).arg( attendeeName );
1669 return i18n(
"%1 declines this invitation on behalf of %2" ).
1670 arg( attendeeName ).arg( delegatorName );
1672 case Attendee::Delegated: {
1673 TQString delegate, dummy;
1674 KPIM::getNameAndMail( attendee->
delegate(), delegate, dummy );
1675 if ( delegate.isEmpty() ) {
1678 if ( !delegate.isEmpty() ) {
1679 return i18n(
"%1 has delegated this invitation to %2" ).
1680 arg( attendeeName ) .arg( delegate );
1682 return i18n(
"%1 has delegated this invitation" ).arg( attendeeName );
1685 case Attendee::Completed:
1686 return i18n(
"This invitation is now completed" );
1687 case Attendee::InProcess:
1688 return i18n(
"%1 is still processing the invitation" ).
1689 arg( attendeeName );
1691 return i18n(
"Unknown response to this invitation" );
1696 case Scheduler::Counter:
1697 return i18n(
"%1 makes this counter proposal" ).
1698 arg( firstAttendeeName( event, i18n(
"Sender" ) ) );
1700 case Scheduler::Declinecounter:
1701 return i18n(
"%1 declines the counter proposal" ).
1702 arg( firstAttendeeName( event, i18n(
"Sender" ) ) );
1704 case Scheduler::NoMethod:
1705 return i18n(
"Error: iMIP message with unknown method: '%1'").
1711 static TQString invitationHeaderTodo(
Todo *todo,
Incidence *existingIncidence,
1714 if ( !msg || !todo ) {
1718 switch ( msg->
method() ) {
1719 case Scheduler::Publish:
1720 return i18n(
"This task has been published");
1721 case Scheduler::Request:
1722 if ( existingIncidence && todo->
revision() > 0 ) {
1723 return i18n(
"This task has been updated by the organizer %1" ).
1724 arg( todo->organizer().fullName() );
1726 if ( iamOrganizer( todo ) ) {
1727 return i18n(
"I created this task" );
1730 if ( !todo->organizer().fullName().isEmpty() ) {
1731 orgStr = todo->organizer().fullName();
1732 }
else if ( !todo->organizer().email().isEmpty() ) {
1733 orgStr = todo->organizer().email();
1735 if ( senderIsOrganizer( todo, sender ) ) {
1736 if ( !orgStr.isEmpty() ) {
1737 return i18n(
"You have been assigned this task by %1" ).arg( orgStr );
1739 return i18n(
"You have been assigned this task" );
1742 if ( !orgStr.isEmpty() ) {
1743 return i18n(
"You have been assigned this task by %1 as a representative of %2" ).
1744 arg( sender, orgStr );
1746 return i18n(
"You have been assigned this task by %1 as the organizer's representative" ).
1752 case Scheduler::Refresh:
1753 return i18n(
"This task was refreshed" );
1754 case Scheduler::Cancel:
1755 return i18n(
"This task was canceled" );
1756 case Scheduler::Add:
1757 return i18n(
"Addition to the task" );
1758 case Scheduler::Reply:
1760 if ( replyMeansCounter( todo ) ) {
1761 return i18n(
"%1 makes this counter proposal" ).
1762 arg( firstAttendeeName( todo, i18n(
"Sender" ) ) );
1766 if( attendees.count() == 0 ) {
1767 kdDebug(5850) <<
"No attendees in the iCal reply!" << endl;
1770 if( attendees.count() != 1 ) {
1771 kdDebug(5850) <<
"Warning: attendeecount in the reply should be 1 "
1772 <<
"but is " << attendees.count() << endl;
1774 TQString attendeeName = firstAttendeeName( todo, i18n(
"Sender" ) );
1776 TQString delegatorName, dummy;
1777 Attendee* attendee = *attendees.begin();
1778 KPIM::getNameAndMail( attendee->
delegator(), delegatorName, dummy );
1779 if ( delegatorName.isEmpty() ) {
1783 switch( attendee->
status() ) {
1784 case Attendee::NeedsAction:
1785 return i18n(
"%1 indicates this task assignment still needs some action" ).arg( attendeeName );
1786 case Attendee::Accepted:
1788 if ( !sender.isEmpty() ) {
1790 return i18n(
"This task has been completed by assignee %1" ).arg( sender );
1792 return i18n(
"This task has been updated by assignee %1" ).arg( sender );
1796 return i18n(
"This task has been completed by an assignee" );
1798 return i18n(
"This task has been updated by an assignee" );
1802 if ( delegatorName.isEmpty() ) {
1803 return i18n(
"%1 accepts this task" ).arg( attendeeName );
1805 return i18n(
"%1 accepts this task on behalf of %2" ).
1806 arg( attendeeName ).arg( delegatorName );
1809 case Attendee::Tentative:
1810 if ( delegatorName.isEmpty() ) {
1811 return i18n(
"%1 tentatively accepts this task" ).
1812 arg( attendeeName );
1814 return i18n(
"%1 tentatively accepts this task on behalf of %2" ).
1815 arg( attendeeName ).arg( delegatorName );
1817 case Attendee::Declined:
1818 if ( delegatorName.isEmpty() ) {
1819 return i18n(
"%1 declines this task" ).arg( attendeeName );
1821 return i18n(
"%1 declines this task on behalf of %2" ).
1822 arg( attendeeName ).arg( delegatorName );
1824 case Attendee::Delegated: {
1825 TQString delegate, dummy;
1826 KPIM::getNameAndMail( attendee->
delegate(), delegate, dummy );
1827 if ( delegate.isEmpty() ) {
1830 if ( !delegate.isEmpty() ) {
1831 return i18n(
"%1 has delegated this request for the task to %2" ).
1832 arg( attendeeName ).arg( delegate );
1834 return i18n(
"%1 has delegated this request for the task" ).
1835 arg( attendeeName );
1838 case Attendee::Completed:
1839 return i18n(
"The request for this task is now completed" );
1840 case Attendee::InProcess:
1841 return i18n(
"%1 is still processing the task" ).
1842 arg( attendeeName );
1844 return i18n(
"Unknown response to this task" );
1849 case Scheduler::Counter:
1850 return i18n(
"%1 makes this counter proposal" ).
1851 arg( firstAttendeeName( todo, i18n(
"Sender" ) ) );
1853 case Scheduler::Declinecounter:
1854 return i18n(
"%1 declines the counter proposal" ).
1855 arg( firstAttendeeName( todo, i18n(
"Sender" ) ) );
1857 case Scheduler::NoMethod:
1858 return i18n(
"Error: iMIP message with unknown method: '%1'" ).
1866 if ( !msg || !journal ) {
1870 switch ( msg->
method() ) {
1871 case Scheduler::Publish:
1872 return i18n(
"This journal has been published");
1873 case Scheduler::Request:
1874 return i18n(
"You have been assigned this journal" );
1875 case Scheduler::Refresh:
1876 return i18n(
"This journal was refreshed" );
1877 case Scheduler::Cancel:
1878 return i18n(
"This journal was canceled" );
1879 case Scheduler::Add:
1880 return i18n(
"Addition to the journal" );
1881 case Scheduler::Reply:
1883 if ( replyMeansCounter( journal ) ) {
1884 return i18n(
"Sender makes this counter proposal" );
1888 if( attendees.count() == 0 ) {
1889 kdDebug(5850) <<
"No attendees in the iCal reply!" << endl;
1892 if( attendees.count() != 1 ) {
1893 kdDebug(5850) <<
"Warning: attendeecount in the reply should be 1 "
1894 <<
"but is " << attendees.count() << endl;
1896 Attendee* attendee = *attendees.begin();
1898 switch( attendee->
status() ) {
1899 case Attendee::NeedsAction:
1900 return i18n(
"Sender indicates this journal assignment still needs some action" );
1901 case Attendee::Accepted:
1902 return i18n(
"Sender accepts this journal" );
1903 case Attendee::Tentative:
1904 return i18n(
"Sender tentatively accepts this journal" );
1905 case Attendee::Declined:
1906 return i18n(
"Sender declines this journal" );
1907 case Attendee::Delegated:
1908 return i18n(
"Sender has delegated this request for the journal" );
1909 case Attendee::Completed:
1910 return i18n(
"The request for this journal is now completed" );
1911 case Attendee::InProcess:
1912 return i18n(
"Sender is still processing the invitation" );
1914 return i18n(
"Unknown response to this journal" );
1918 case Scheduler::Counter:
1919 return i18n(
"Sender makes this counter proposal" );
1920 case Scheduler::Declinecounter:
1921 return i18n(
"Sender declines the counter proposal" );
1922 case Scheduler::NoMethod:
1923 return i18n(
"Error: iMIP message with unknown method: '%1'").
1931 if ( !msg || !fb ) {
1935 switch ( msg->
method() ) {
1936 case Scheduler::Publish:
1937 return i18n(
"This free/busy list has been published");
1938 case Scheduler::Request:
1939 return i18n(
"The free/busy list has been requested" );
1940 case Scheduler::Refresh:
1941 return i18n(
"This free/busy list was refreshed" );
1942 case Scheduler::Cancel:
1943 return i18n(
"This free/busy list was canceled" );
1944 case Scheduler::Add:
1945 return i18n(
"Addition to the free/busy list" );
1946 case Scheduler::NoMethod:
1948 return i18n(
"Error: Free/Busy iMIP message with unknown method: '%1'").
1953 static TQString invitationAttendees(
Incidence *incidence )
1960 if ( incidence->type() ==
"Todo" ) {
1961 tmpStr += htmlAddTag(
"u", i18n(
"Assignees" ) );
1963 tmpStr += htmlAddTag(
"u", i18n(
"Attendees" ) );
1969 if ( !attendees.isEmpty() ) {
1971 Attendee::List::ConstIterator it;
1972 for( it = attendees.begin(); it != attendees.end(); ++it ) {
1974 if ( !iamAttendee( a ) ) {
1977 tmpStr +=
"<table border=\"1\" cellpadding=\"1\" cellspacing=\"0\" columns=\"2\">";
1981 tmpStr += invitationPerson( a->email(), a->name(), TQString() );
1983 tmpStr += i18n(
" (delegated by %1)" ).arg( a->
delegator() );
1986 tmpStr += i18n(
" (delegated to %1)" ).arg( a->
delegate() );
1989 tmpStr +=
"<td>" + a->
statusStr() +
"</td>";
1995 tmpStr +=
"</table>";
1997 tmpStr +=
"<i>" + i18n(
"No attendee",
"None" ) +
"</i>";
2003 static TQString invitationAttachments( InvitationFormatterHelper *helper,
Incidence *incidence )
2011 if ( !attachments.isEmpty() ) {
2012 tmpStr += i18n(
"Attached Documents:" ) +
"<ol>";
2014 Attachment::List::ConstIterator it;
2015 for( it = attachments.begin(); it != attachments.end(); ++it ) {
2019 KMimeType::Ptr mimeType = KMimeType::mimeType( a->mimeType() );
2020 const TQString iconStr = mimeType ? mimeType->icon( a->uri(),
false ) : TQString(
"application-octet-stream" );
2021 const TQString iconPath = TDEGlobal::iconLoader()->iconPath( iconStr, TDEIcon::Small );
2022 if ( !iconPath.isEmpty() ) {
2023 tmpStr +=
"<img valign=\"top\" src=\"" + iconPath +
"\">";
2025 tmpStr += helper->makeLink(
"ATTACH:" + a->label(), a->label() );
2034 class IncidenceFormatter::ScheduleMessageVisitor
2038 ScheduleMessageVisitor() : mExistingIncidence( 0 ), mMessage( 0 ) { mResult =
""; }
2040 const TQString &sender )
2042 mExistingIncidence = existingIncidence;
2045 return incidence->
accept( *
this );
2047 TQString result()
const {
return mResult; }
2056 class IncidenceFormatter::InvitationHeaderVisitor
2057 :
public IncidenceFormatter::ScheduleMessageVisitor
2060 bool visit(
Event *event )
2062 mResult = invitationHeaderEvent( event, mExistingIncidence, mMessage, mSender );
2063 return !mResult.isEmpty();
2065 bool visit(
Todo *todo )
2067 mResult = invitationHeaderTodo( todo, mExistingIncidence, mMessage, mSender );
2068 return !mResult.isEmpty();
2070 bool visit(
Journal *journal )
2072 mResult = invitationHeaderJournal( journal, mMessage );
2073 return !mResult.isEmpty();
2077 mResult = invitationHeaderFreeBusy( fb, mMessage );
2078 return !mResult.isEmpty();
2082 class IncidenceFormatter::InvitationBodyVisitor
2083 :
public IncidenceFormatter::ScheduleMessageVisitor
2086 InvitationBodyVisitor(
bool noHtmlMode )
2087 : ScheduleMessageVisitor(), mNoHtmlMode( noHtmlMode ) {}
2090 bool visit(
Event *event )
2092 mResult = invitationDetailsEvent( event, mNoHtmlMode );
2093 return !mResult.isEmpty();
2095 bool visit(
Todo *todo )
2097 mResult = invitationDetailsTodo( todo, mNoHtmlMode );
2098 return !mResult.isEmpty();
2100 bool visit(
Journal *journal )
2102 mResult = invitationDetailsJournal( journal, mNoHtmlMode );
2103 return !mResult.isEmpty();
2107 mResult = invitationDetailsFreeBusy( fb, mNoHtmlMode );
2108 return !mResult.isEmpty();
2115 class IncidenceFormatter::IncidenceCompareVisitor
2119 IncidenceCompareVisitor() : mExistingIncidence(0) {}
2123 if ( !inc || !existingIncidence || inc->
revision() <= existingIncidence->
revision() )
2125 mExistingIncidence = existingIncidence;
2127 return incidence->
accept( *
this );
2130 TQString result()
const
2132 if ( mChanges.isEmpty() ) {
2135 TQString html =
"<div align=\"left\"><ul><li>";
2136 html += mChanges.join(
"</li><li>" );
2137 html +=
"</li><ul></div>";
2142 bool visit(
Event *event )
2144 compareEvents( event,
dynamic_cast<Event*
>( mExistingIncidence ) );
2145 compareIncidences( event, mExistingIncidence, mMethod );
2146 return !mChanges.isEmpty();
2148 bool visit(
Todo *todo )
2150 compareTodos( todo,
dynamic_cast<Todo*
>( mExistingIncidence ) );
2151 compareIncidences( todo, mExistingIncidence, mMethod );
2152 return !mChanges.isEmpty();
2154 bool visit(
Journal *journal )
2156 compareIncidences( journal, mExistingIncidence, mMethod );
2157 return !mChanges.isEmpty();
2162 return !mChanges.isEmpty();
2166 void compareEvents(
Event *newEvent,
Event *oldEvent )
2168 if ( !oldEvent || !newEvent )
2171 mChanges += i18n(
"The invitation starting time has been changed from %1 to %2" )
2172 .arg( eventStartTimeStr( oldEvent ) ).arg( eventStartTimeStr( newEvent ) );
2174 mChanges += i18n(
"The invitation ending time has been changed from %1 to %2" )
2175 .arg( eventEndTimeStr( oldEvent ) ).arg( eventEndTimeStr( newEvent ) );
2178 void compareTodos(
Todo *newTodo,
Todo *oldTodo )
2180 if ( !oldTodo || !newTodo ) {
2185 mChanges += i18n(
"The task has been completed" );
2188 mChanges += i18n(
"The task is no longer completed" );
2191 const TQString oldPer = i18n(
"%1%" ).arg( oldTodo->
percentComplete() );
2192 const TQString newPer = i18n(
"%1%" ).arg( newTodo->
percentComplete() );
2193 mChanges += i18n(
"The task completed percentage has changed from %1 to %2" ).
2194 arg( oldPer, newPer );
2198 mChanges += i18n(
"A task starting time has been added" );
2201 mChanges += i18n(
"The task starting time has been removed" );
2205 mChanges += i18n(
"The task starting time has been changed from %1 to %2" ).
2211 mChanges += i18n(
"A task due time has been added" );
2214 mChanges += i18n(
"The task due time has been removed" );
2218 mChanges += i18n(
"The task due time has been changed from %1 to %2" ).
2219 arg( dateTimeToString( oldTodo->
dtDue(), oldTodo->
doesFloat(),
false ),
2220 dateTimeToString( newTodo->
dtDue(), newTodo->
doesFloat(),
false ) );
2226 if ( !oldInc || !newInc )
2229 mChanges += i18n(
"The summary has been changed to: \"%1\"" ).arg( newInc->
summary() );
2231 mChanges += i18n(
"The location has been changed to: \"%1\"" ).arg( newInc->
location() );
2233 mChanges += i18n(
"The description has been changed to: \"%1\"" ).arg( newInc->
description() );
2236 for ( Attendee::List::ConstIterator it = newAttendees.constBegin();
2237 it != newAttendees.constEnd(); ++it ) {
2240 mChanges += i18n(
"Attendee %1 has been added" ).arg( (*it)->fullName() );
2242 if ( oldAtt->
status() != (*it)->status() )
2243 mChanges += i18n(
"The status of attendee %1 has been changed to: %2" ).
2244 arg( (*it)->fullName() ).arg( (*it)->statusStr() );
2247 if ( method == Scheduler::Request ) {
2248 for ( Attendee::List::ConstIterator it = oldAttendees.constBegin();
2249 it != oldAttendees.constEnd(); ++it ) {
2250 if ( (*it)->email() != oldInc->organizer().email() ) {
2253 mChanges += i18n(
"Attendee %1 has been removed" ).arg( (*it)->fullName() );
2263 TQStringList mChanges;
2267 TQString InvitationFormatterHelper::makeLink(
const TQString &
id,
const TQString &text )
2269 if ( !
id.startsWith(
"ATTACH:" ) ) {
2270 TQString res = TQString(
"<a href=\"%1\"><b>%2</b></a>" ).
2271 arg( generateLinkURL(
id ), text );
2275 TQString res = TQString(
"<a href=\"%1\">%2</a>" ).
2276 arg( generateLinkURL(
id ), text );
2286 if ( !cal || !incidence ) {
2294 if ( !subRes.contains(
"/.INBOX.directory/" ) ) {
2301 static TQString spacer =
"<td> </td>";
2303 static TQString tdOpen =
"<td>";
2304 static TQString tdClose =
"</td>" + spacer;
2306 static TQString responseButtons(
Incidence *inc,
bool rsvpReq,
bool rsvpRec,
2307 InvitationFormatterHelper *helper )
2314 if ( !rsvpReq && ( inc && inc->
revision() == 0 ) ) {
2317 html += helper->makeLink(
"record", i18n(
"[Record]" ) );
2322 html += helper->makeLink(
"delete", i18n(
"[Move to Trash]" ) );
2329 html += helper->makeLink(
"accept", i18n(
"[Accept]" ) );
2334 html += helper->makeLink(
"accept_conditionally",
2335 i18n(
"Accept conditionally",
"[Accept cond.]" ) );
2340 html += helper->makeLink(
"counter", i18n(
"[Counter proposal]" ) );
2345 html += helper->makeLink(
"decline", i18n(
"[Decline]" ) );
2349 if ( !rsvpRec || ( inc && inc->
revision() > 0 ) ) {
2352 html += helper->makeLink(
"delegate", i18n(
"[Delegate]" ) );
2357 html += helper->makeLink(
"forward", i18n(
"[Forward]" ) );
2361 if ( inc && inc->type() ==
"Event" ) {
2363 html += helper->makeLink(
"check_calendar", i18n(
"[Check my calendar]" ) );
2370 static TQString counterButtons(
Incidence *incidence,
2371 InvitationFormatterHelper *helper )
2380 html += helper->makeLink(
"accept_counter", i18n(
"[Accept]") );
2385 html += helper->makeLink(
"decline_counter", i18n(
"[Decline]") );
2389 if ( incidence && incidence->type() ==
"Event" ) {
2391 html += helper->makeLink(
"check_calendar", i18n(
"[Check my calendar]" ) );
2397 TQString IncidenceFormatter::formatICalInvitationHelper( TQString invitation,
2399 InvitationFormatterHelper *helper,
2401 const TQString &sender )
2403 if ( invitation.isEmpty() ) {
2412 kdDebug( 5850 ) <<
"Failed to parse the scheduling message" << endl;
2422 if ( incBase && helper->calendar() ) {
2423 existingIncidence = helper->calendar()->incidence( incBase->
uid() );
2424 if ( !incidenceOwnedByMe( helper->calendar(), existingIncidence ) ) {
2425 existingIncidence = 0;
2427 if ( !existingIncidence ) {
2429 for ( Incidence::List::ConstIterator it = list.begin(), end = list.end(); it != end; ++it ) {
2430 if ( (*it)->schedulingID() == incBase->
uid() &&
2431 incidenceOwnedByMe( helper->calendar(), *it ) ) {
2432 existingIncidence = *it;
2442 TQString tableStyle = TQString::fromLatin1(
2443 "style=\"border: solid 1px; margin: 0em;\"" );
2444 TQString tableHead = TQString::fromLatin1(
2445 "<div align=\"center\">"
2446 "<table width=\"80%\" cellpadding=\"1\" cellspacing=\"0\" %1>"
2447 "<tr><td>").arg(tableStyle);
2450 InvitationHeaderVisitor headerVisitor;
2452 if ( !headerVisitor.act( incBase, existingIncidence, msg, sender ) )
2454 html +=
"<b>" + headerVisitor.result() +
"</b>";
2456 InvitationBodyVisitor bodyVisitor( noHtmlMode );
2457 if ( !bodyVisitor.act( incBase, existingIncidence, msg, sender ) )
2459 html += bodyVisitor.result();
2461 if ( msg->
method() == Scheduler::Request ) {
2462 IncidenceCompareVisitor compareVisitor;
2463 if ( compareVisitor.act( incBase, existingIncidence, msg->
method() ) ) {
2464 html +=
"<p align=\"left\">";
2465 html += i18n(
"The following changes have been made by the organizer:" );
2467 html += compareVisitor.result();
2470 if ( msg->
method() == Scheduler::Reply ) {
2471 IncidenceCompareVisitor compareVisitor;
2472 if ( compareVisitor.act( incBase, existingIncidence, msg->
method() ) ) {
2473 html +=
"<p align=\"left\">";
2474 if ( !sender.isEmpty() ) {
2475 html += i18n(
"The following changes have been made by %1:" ).arg( sender );
2477 html += i18n(
"The following changes have been made by an attendee:" );
2480 html += compareVisitor.result();
2487 bool myInc = iamOrganizer( inc );
2490 bool rsvpRec =
false;
2493 Incidence *rsvpIncidence = existingIncidence;
2494 if ( !rsvpIncidence && inc && inc->
revision() > 0 ) {
2495 rsvpIncidence = inc;
2497 if ( rsvpIncidence ) {
2498 ea = findMyAttendee( rsvpIncidence );
2501 ( ea->
status() == Attendee::Accepted ||
2502 ea->
status() == Attendee::Declined ||
2503 ea->
status() == Attendee::Tentative ) ) {
2510 bool isDelegated =
false;
2511 Attendee *a = findMyAttendee( inc );
2518 isDelegated = ( a->
status() == Attendee::Delegated );
2523 bool rsvpReq = rsvpRequested( inc );
2524 if ( !myInc && a ) {
2527 if ( rsvpRec && inc ) {
2529 html += i18n(
"Your <b>%1</b> response has already been recorded" ).
2532 html += i18n(
"Your status for this invitation is <b>%1</b>" ).
2536 }
else if ( msg->
method() == Scheduler::Cancel ) {
2537 html += i18n(
"This invitation was declined" );
2538 }
else if ( msg->
method() == Scheduler::Add ) {
2539 html += i18n(
"This invitation was accepted" );
2541 if ( !isDelegated ) {
2542 html += rsvpRequestedStr( rsvpReq, role );
2544 html += i18n(
"Awaiting delegation response" );
2552 if ( inc && inc->
revision() == 0 ) {
2553 TQString statStr = myStatusStr( inc );
2554 if ( !statStr.isEmpty() ) {
2565 html +=
"<br><table border=\"0\" cellspacing=\"0\"><tr><td> </td></tr>";
2567 switch ( msg->
method() ) {
2568 case Scheduler::Publish:
2569 case Scheduler::Request:
2570 case Scheduler::Refresh:
2571 case Scheduler::Add:
2573 if ( inc && inc->
revision() > 0 && ( existingIncidence || !helper->calendar() ) ) {
2575 if ( inc->type() ==
"Todo" ) {
2576 html +=
"<td colspan=\"9\">";
2577 html += helper->makeLink(
"reply", i18n(
"[Record invitation in my task list]" ) );
2579 html +=
"<td colspan=\"13\">";
2580 html += helper->makeLink(
"reply", i18n(
"[Record invitation in my calendar]" ) );
2582 html +=
"</td></tr>";
2585 if ( !myInc && a ) {
2586 html +=
"<tr>" + responseButtons( inc, rsvpReq, rsvpRec, helper ) +
"</tr>";
2591 case Scheduler::Cancel:
2595 if ( inc->type() ==
"Todo" ) {
2596 html +=
"<td colspan=\"9\">";
2597 html += helper->makeLink(
"cancel", i18n(
"[Remove invitation from my task list]" ) );
2599 html +=
"<td colspan=\"13\">";
2600 html += helper->makeLink(
"cancel", i18n(
"[Remove invitation from my calendar]" ) );
2602 html +=
"</td></tr>";
2606 case Scheduler::Reply:
2613 if ( replyMeansCounter( inc ) ) {
2614 html +=
"<tr>" + counterButtons( inc, helper ) +
"</tr>";
2623 a = findDelegatedFromMyAttendee( inc );
2625 if ( a->
status() != Attendee::Accepted ||
2626 a->
status() != Attendee::Tentative ) {
2627 html +=
"<tr>" + responseButtons( inc, rsvpReq, rsvpRec, helper ) +
"</tr>";
2637 ea = findAttendee( existingIncidence, a->email() );
2640 if ( ea && ( ea->
status() != Attendee::NeedsAction ) && ( ea->
status() == a->
status() ) ) {
2641 if ( inc && inc->
revision() > 0 ) {
2642 html +=
"<br><u><i>";
2643 html += i18n(
"The response has been recorded [%1]" ).arg( ea->
statusStr() );
2649 if ( inc->type() ==
"Todo" ) {
2650 html += helper->makeLink(
"reply", i18n(
"[Record response in my task list]" ) );
2652 html += helper->makeLink(
"reply", i18n(
"[Record response in my calendar]" ) );
2654 html +=
"</td></tr>";
2660 case Scheduler::Counter:
2662 html +=
"<tr>" + counterButtons( inc, helper ) +
"</tr>";
2665 case Scheduler::Declinecounter:
2666 case Scheduler::NoMethod:
2671 html +=
"</td></tr></table>";
2674 if ( myInc && helper->calendar() ) {
2675 html += invitationAttendees( helper->calendar()->incidence( inc->
uid() ) );
2679 html +=
"</td></tr></table><br></div>";
2682 html += invitationAttachments( helper, inc );
2687 TQString IncidenceFormatter::formatICalInvitation( TQString invitation,
2689 InvitationFormatterHelper *helper )
2691 return formatICalInvitationHelper( invitation, mCalendar, helper,
false, TQString() );
2694 TQString IncidenceFormatter::formatICalInvitationNoHtml( TQString invitation,
2696 InvitationFormatterHelper *helper )
2698 return formatICalInvitationHelper( invitation, mCalendar, helper,
true, TQString() );
2701 TQString IncidenceFormatter::formatICalInvitationNoHtml( TQString invitation,
2703 InvitationFormatterHelper *helper,
2704 const TQString &sender )
2706 return formatICalInvitationHelper( invitation, mCalendar, helper,
true, sender );
2717 static TQString stringProp( KTNEFMessage* tnefMsg,
const TQ_UINT32& key,
2718 const TQString& fallback = TQString())
2720 return tnefMsg->findProp( key < 0x10000 ? key & 0xFFFF : key >> 16,
2724 static TQString sNamedProp( KTNEFMessage* tnefMsg,
const TQString& name,
2725 const TQString& fallback = TQString() )
2727 return tnefMsg->findNamedProp( name, fallback );
2730 struct save_tz {
char* old_tz;
char* tz_env_str; };
2733 static struct save_tz set_tz( const char* _tc )
2735 const char *tc = _tc?_tc:
"UTC";
2745 if( getenv(
"TZ" ) ) {
2746 tz_env = strdup( getenv(
"TZ" ) );
2749 char* tmp_env = (
char*)malloc( strlen( tc ) + 4 );
2750 strcpy( tmp_env,
"TZ=" );
2751 strcpy( tmp_env+3, tc );
2754 rv.tz_env_str = tmp_env;
2765 static void unset_tz(
struct save_tz old_tz )
2767 if( old_tz.old_tz ) {
2768 char* tmp_env = (
char*)malloc( strlen( old_tz.old_tz ) + 4 );
2769 strcpy( tmp_env,
"TZ=" );
2770 strcpy( tmp_env+3, old_tz.old_tz );
2773 free( old_tz.old_tz );
2776 putenv( strdup(
"TZ") );
2781 if( old_tz.tz_env_str ) free( old_tz.tz_env_str );
2784 static TQDateTime utc2Local(
const TQDateTime& utcdt )
2788 save_tz tmp_tz = set_tz(
"UTC");
2789 time_t utc = utcdt.toTime_t();
2792 localtime_r( &utc, &tmL );
2793 return TQDateTime( TQDate( tmL.tm_year+1900, tmL.tm_mon+1, tmL.tm_mday ),
2794 TQTime( tmL.tm_hour, tmL.tm_min, tmL.tm_sec ) );
2798 static TQDateTime pureISOToLocalTQDateTime(
const TQString& dtStr,
2799 bool bDateOnly =
false )
2803 int year, month, day, hour, minute, second;
2806 year = dtStr.left( 4 ).toInt();
2807 month = dtStr.mid( 4, 2 ).toInt();
2808 day = dtStr.mid( 6, 2 ).toInt();
2813 year = dtStr.left( 4 ).toInt();
2814 month = dtStr.mid( 4, 2 ).toInt();
2815 day = dtStr.mid( 6, 2 ).toInt();
2816 hour = dtStr.mid( 9, 2 ).toInt();
2817 minute = dtStr.mid( 11, 2 ).toInt();
2818 second = dtStr.mid( 13, 2 ).toInt();
2820 tmpDate.setYMD( year, month, day );
2821 tmpTime.setHMS( hour, minute, second );
2823 if( tmpDate.isValid() && tmpTime.isValid() ) {
2824 TQDateTime dT = TQDateTime( tmpDate, tmpTime );
2828 if (dtStr.at(dtStr.length()-1) ==
'Z') {
2831 dT = utc2Local( dT );
2836 return TQDateTime();
2846 TQBuffer buf( tnef );
2848 TDEABC::Addressee addressee;
2849 TDEABC::VCardConverter cardConv;
2853 if( parser.openDevice( &buf ) ) {
2854 KTNEFMessage* tnefMsg = parser.message();
2859 TQString msgClass = tnefMsg->findProp( 0x001A, TQString(),
true )
2861 if( !msgClass.isEmpty() ) {
2864 bool bCompatClassAppointment =
false;
2865 bool bCompatMethodRequest =
false;
2866 bool bCompatMethodCancled =
false;
2867 bool bCompatMethodAccepted =
false;
2868 bool bCompatMethodAcceptedCond =
false;
2869 bool bCompatMethodDeclined =
false;
2870 if( msgClass.startsWith(
"IPM.MICROSOFT SCHEDULE." ) ) {
2871 bCompatClassAppointment =
true;
2872 if( msgClass.endsWith(
".MTGREQ" ) )
2873 bCompatMethodRequest =
true;
2874 if( msgClass.endsWith(
".MTGCNCL" ) )
2875 bCompatMethodCancled =
true;
2876 if( msgClass.endsWith(
".MTGRESPP" ) )
2877 bCompatMethodAccepted =
true;
2878 if( msgClass.endsWith(
".MTGRESPA" ) )
2879 bCompatMethodAcceptedCond =
true;
2880 if( msgClass.endsWith(
".MTGRESPN" ) )
2881 bCompatMethodDeclined =
true;
2883 bool bCompatClassNote = ( msgClass ==
"IPM.MICROSOFT MAIL.NOTE" );
2885 if( bCompatClassAppointment ||
"IPM.APPOINTMENT" == msgClass ) {
2887 bool bIsReply =
false;
2888 TQString prodID =
"-//Microsoft Corporation//Outlook ";
2889 prodID += tnefMsg->findNamedProp(
"0x8554",
"9.0" );
2890 prodID +=
"MIMEDIR/EN\n";
2891 prodID +=
"VERSION:2.0\n";
2895 if( bCompatMethodRequest )
2896 method = Scheduler::Request;
2897 else if( bCompatMethodCancled )
2898 method = Scheduler::Cancel;
2899 else if( bCompatMethodAccepted || bCompatMethodAcceptedCond ||
2900 bCompatMethodDeclined ) {
2901 method = Scheduler::Reply;
2912 if( tnefMsg->findProp(0x0c17) ==
"1" )
2914 method = Scheduler::Request;
2920 TQString sSenderSearchKeyEmail( tnefMsg->findProp( 0x0C1D ) );
2922 if( !sSenderSearchKeyEmail.isEmpty() ) {
2923 int colon = sSenderSearchKeyEmail.find(
':' );
2925 if( sSenderSearchKeyEmail.find(
':' ) == -1 )
2926 sSenderSearchKeyEmail.remove( 0, colon+1 );
2929 TQString s( tnefMsg->findProp( 0x0e04 ) );
2930 TQStringList attendees = TQStringList::split(
';', s );
2931 if( attendees.count() ) {
2932 for( TQStringList::Iterator it = attendees.begin();
2933 it != attendees.end(); ++it ) {
2936 if( (*it).find(
'@') == -1 ) {
2937 s = (*it).stripWhiteSpace();
2941 if( bCompatMethodAccepted )
2942 attendee->
setStatus( Attendee::Accepted );
2943 if( bCompatMethodDeclined )
2944 attendee->
setStatus( Attendee::Declined );
2945 if( bCompatMethodAcceptedCond )
2946 attendee->
setStatus(Attendee::Tentative);
2948 attendee->
setStatus( Attendee::NeedsAction );
2949 attendee->
setRole( Attendee::ReqParticipant );
2951 event->addAttendee(attendee);
2957 s = sSenderSearchKeyEmail;
2958 if( !s.isEmpty() ) {
2962 if( bCompatMethodAccepted )
2963 attendee->
setStatus( Attendee::Accepted );
2964 if( bCompatMethodAcceptedCond )
2965 attendee->
setStatus( Attendee::Declined );
2966 if( bCompatMethodDeclined )
2967 attendee->
setStatus( Attendee::Tentative );
2969 attendee->
setStatus(Attendee::NeedsAction);
2970 attendee->
setRole(Attendee::ReqParticipant);
2972 event->addAttendee(attendee);
2975 s = tnefMsg->findProp( 0x0c1f );
2976 if( s.isEmpty() && !bIsReply )
2977 s = sSenderSearchKeyEmail;
2980 event->setOrganizer( s );
2982 s = tnefMsg->findProp( 0x8516 ).replace( TQChar(
'-' ), TQString() )
2983 .replace( TQChar(
':' ), TQString() );
2984 event->setDtStart( TQDateTime::fromString( s ) );
2986 s = tnefMsg->findProp( 0x8517 ).replace( TQChar(
'-' ), TQString() )
2987 .replace( TQChar(
':' ), TQString() );
2988 event->setDtEnd( TQDateTime::fromString( s ) );
2990 s = tnefMsg->findProp( 0x8208 );
2991 event->setLocation( s );
2998 s = tnefMsg->findProp( 0x0023 );
3004 s = tnefMsg->findProp( 0x8202 ).replace( TQChar(
'-' ), TQString() )
3005 .replace( TQChar(
':' ), TQString() );
3009 s = tnefMsg->findNamedProp(
"Keywords" );
3010 event->setCategories( s );
3012 s = tnefMsg->findProp( 0x1000 );
3013 event->setDescription( s );
3015 s = tnefMsg->findProp( 0x0070 );
3016 event->setSummary( s );
3018 s = tnefMsg->findProp( 0x0026 );
3019 event->setPriority( s.toInt() );
3022 if(!tnefMsg->findProp(0x8503).isEmpty()) {
3024 TQDateTime highNoonTime =
3025 pureISOToLocalTQDateTime( tnefMsg->findProp( 0x8502 )
3026 .replace( TQChar(
'-' ),
"" )
3027 .replace( TQChar(
':' ),
"" ) );
3028 TQDateTime wakeMeUpTime =
3029 pureISOToLocalTQDateTime( tnefMsg->findProp( 0x8560,
"" )
3030 .replace( TQChar(
'-' ),
"" )
3031 .replace( TQChar(
':' ),
"" ) );
3034 if( highNoonTime.isValid() && wakeMeUpTime.isValid() )
3043 event->addAlarm( alarm );
3048 }
else if( bCompatClassNote ||
"IPM.CONTACT" == msgClass ) {
3049 addressee.setUid( stringProp( tnefMsg, attMSGID ) );
3050 addressee.setFormattedName( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME ) );
3051 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL1EMAILADDRESS ),
true );
3052 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL2EMAILADDRESS ),
false );
3053 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL3EMAILADDRESS ),
false );
3054 addressee.insertCustom(
"KADDRESSBOOK",
"X-IMAddress", sNamedProp( tnefMsg, MAPI_TAG_CONTACT_IMADDRESS ) );
3055 addressee.insertCustom(
"KADDRESSBOOK",
"X-SpousesName", stringProp( tnefMsg, MAPI_TAG_PR_SPOUSE_NAME ) );
3056 addressee.insertCustom(
"KADDRESSBOOK",
"X-ManagersName", stringProp( tnefMsg, MAPI_TAG_PR_MANAGER_NAME ) );
3057 addressee.insertCustom(
"KADDRESSBOOK",
"X-AssistantsName", stringProp( tnefMsg, MAPI_TAG_PR_ASSISTANT ) );
3058 addressee.insertCustom(
"KADDRESSBOOK",
"X-Department", stringProp( tnefMsg, MAPI_TAG_PR_DEPARTMENT_NAME ) );
3059 addressee.insertCustom(
"KADDRESSBOOK",
"X-Office", stringProp( tnefMsg, MAPI_TAG_PR_OFFICE_LOCATION ) );
3060 addressee.insertCustom(
"KADDRESSBOOK",
"X-Profession", stringProp( tnefMsg, MAPI_TAG_PR_PROFESSION ) );
3062 TQString s = tnefMsg->findProp( MAPI_TAG_PR_WEDDING_ANNIVERSARY )
3063 .replace( TQChar(
'-' ), TQString() )
3064 .replace( TQChar(
':' ), TQString() );
3066 addressee.insertCustom(
"KADDRESSBOOK",
"X-Anniversary", s );
3068 addressee.setUrl( KURL( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_WEBPAGE ) ) );
3071 addressee.setFamilyName( stringProp( tnefMsg, MAPI_TAG_PR_SURNAME ) );
3072 addressee.setGivenName( stringProp( tnefMsg, MAPI_TAG_PR_GIVEN_NAME ) );
3073 addressee.setAdditionalName( stringProp( tnefMsg, MAPI_TAG_PR_MIDDLE_NAME ) );
3074 addressee.setPrefix( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME_PREFIX ) );
3075 addressee.setSuffix( stringProp( tnefMsg, MAPI_TAG_PR_GENERATION ) );
3077 addressee.setNickName( stringProp( tnefMsg, MAPI_TAG_PR_NICKNAME ) );
3078 addressee.setRole( stringProp( tnefMsg, MAPI_TAG_PR_TITLE ) );
3079 addressee.setOrganization( stringProp( tnefMsg, MAPI_TAG_PR_COMPANY_NAME ) );
3085 TDEABC::Address adr;
3086 adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_PO_BOX ) );
3087 adr.setStreet( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STREET ) );
3088 adr.setLocality( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_CITY ) );
3089 adr.setRegion( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STATE_OR_PROVINCE ) );
3090 adr.setPostalCode( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_POSTAL_CODE ) );
3091 adr.setCountry( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_COUNTRY ) );
3092 adr.setType(TDEABC::Address::Home);
3093 addressee.insertAddress(adr);
3095 adr.setPostOfficeBox( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOBOX ) );
3096 adr.setStreet( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTREET ) );
3097 adr.setLocality( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCITY ) );
3098 adr.setRegion( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTATE ) );
3099 adr.setPostalCode( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOSTALCODE ) );
3100 adr.setCountry( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCOUNTRY ) );
3101 adr.setType( TDEABC::Address::Work );
3102 addressee.insertAddress( adr );
3104 adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_PO_BOX ) );
3105 adr.setStreet( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STREET ) );
3106 adr.setLocality( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_CITY ) );
3107 adr.setRegion( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STATE_OR_PROVINCE ) );
3108 adr.setPostalCode( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_POSTAL_CODE ) );
3109 adr.setCountry( stringProp(tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_COUNTRY ) );
3110 adr.setType( TDEABC::Address::Dom );
3111 addressee.insertAddress(adr);
3118 nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_TELEPHONE_NUMBER );
3119 addressee.insertPhoneNumber( TDEABC::PhoneNumber( nr, TDEABC::PhoneNumber::Home ) );
3120 nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_TELEPHONE_NUMBER );
3121 addressee.insertPhoneNumber( TDEABC::PhoneNumber( nr, TDEABC::PhoneNumber::Work ) );
3122 nr = stringProp( tnefMsg, MAPI_TAG_PR_MOBILE_TELEPHONE_NUMBER );
3123 addressee.insertPhoneNumber( TDEABC::PhoneNumber( nr, TDEABC::PhoneNumber::Cell ) );
3124 nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_FAX_NUMBER );
3125 addressee.insertPhoneNumber( TDEABC::PhoneNumber( nr, TDEABC::PhoneNumber::Fax | TDEABC::PhoneNumber::Home ) );
3126 nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_FAX_NUMBER );
3127 addressee.insertPhoneNumber( TDEABC::PhoneNumber( nr, TDEABC::PhoneNumber::Fax | TDEABC::PhoneNumber::Work ) );
3129 s = tnefMsg->findProp( MAPI_TAG_PR_BIRTHDAY )
3130 .replace( TQChar(
'-' ), TQString() )
3131 .replace( TQChar(
':' ), TQString() );
3133 addressee.setBirthday( TQDateTime::fromString( s ) );
3135 bOk = ( !addressee.isEmpty() );
3136 }
else if(
"IPM.NOTE" == msgClass ) {
3143 TQString iCal = calFormat.
toString( &cal );
3144 if( !iCal.isEmpty() )
3149 TDEABC::VCardConverter converter;
3150 return converter.createVCard( addressee );
3154 TQString IncidenceFormatter::formatTNEFInvitation(
const TQByteArray& tnef,
3155 Calendar *mCalendar, InvitationFormatterHelper *helper )
3158 TQString iCal = IncidenceFormatter::formatICalInvitation( vPart, mCalendar, helper );
3159 if( !iCal.isEmpty() )
3175 : mCalendar( 0 ), mRichText( true ), mResult(
"" ) {}
3178 const TQDate &date=TQDate(),
bool richText=
true )
3180 mCalendar = calendar;
3182 mRichText = richText;
3184 return incidence ? incidence->
accept( *
this ) :
false;
3186 TQString result()
const {
return mResult; }
3189 bool visit(
Event *event );
3190 bool visit(
Todo *todo );
3191 bool visit(
Journal *journal );
3194 TQString dateRangeText(
Event *event,
const TQDate &date );
3195 TQString dateRangeText(
Todo *todo,
const TQDate &date );
3196 TQString dateRangeText(
Journal *journal );
3197 TQString dateRangeText(
FreeBusy *fb );
3199 TQString generateToolTip(
Incidence* incidence, TQString dtRangeText );
3208 TQString IncidenceFormatter::ToolTipVisitor::dateRangeText(
Event *event,
const TQDate &date )
3213 TQDateTime startDt =
event->dtStart();
3214 TQDateTime endDt =
event->dtEnd();
3216 if ( date.isValid() ) {
3217 TQDateTime dt( date, TQTime( 0, 0, 0 ) );
3218 int diffDays = startDt.daysTo( dt );
3219 dt = dt.addSecs( -1 );
3222 endDt = endDt.addDays( diffDays );
3223 if ( startDt > endDt ) {
3225 endDt = startDt.addDays( event->
dtStart().daysTo( event->
dtEnd() ) );
3232 tmp =
"<br>" + i18n(
"Event start",
"<i>From:</i> %1");
3234 ret += tmp.arg( IncidenceFormatter::dateToString( startDt,
false ).replace(
" ",
" ") );
3236 ret += tmp.arg( IncidenceFormatter::dateToString( startDt ).replace(
" ",
" ") );
3238 tmp =
"<br>" + i18n(
"Event end",
"<i>To:</i> %1");
3240 ret += tmp.arg( IncidenceFormatter::dateToString( endDt,
false ).replace(
" ",
" ") );
3242 ret += tmp.arg( IncidenceFormatter::dateToString( endDt ).replace(
" ",
" ") );
3246 ret +=
"<br>"+i18n(
"<i>Date:</i> %1").
3247 arg( IncidenceFormatter::dateToString( startDt,
false ).replace(
" ",
" ") );
3249 const TQString dtStartTime =
3250 IncidenceFormatter::timeToString( startDt,
true ).replace(
" ",
" " );
3251 const TQString dtEndTime =
3252 IncidenceFormatter::timeToString( endDt,
true ).replace(
" ",
" " );
3253 if ( dtStartTime == dtEndTime ) {
3254 tmp =
"<br>" + i18n(
"time for event, to prevent ugly line breaks",
3255 "<i>Time:</i> %1").
3258 tmp =
"<br>" + i18n(
"time range for event, to prevent ugly line breaks",
3259 "<i>Time:</i> %1 - %2").
3260 arg( dtStartTime, dtEndTime );
3269 TQString IncidenceFormatter::ToolTipVisitor::dateRangeText(
Todo *todo,
const TQDate &date )
3275 TQDateTime startDt = todo->
dtStart();
3277 if ( date.isValid() ) {
3278 startDt.setDate( date );
3282 i18n(
"<i>Start:</i> %1").
3283 arg( IncidenceFormatter::dateTimeToString( startDt, floats,
false ).
3284 replace(
" ",
" " ) );
3288 TQDateTime dueDt = todo->
dtDue();
3290 if ( date.isValid() ) {
3291 TQDateTime dt( date, TQTime( 0, 0, 0 ) );
3292 dt = dt.addSecs( -1 );
3297 i18n(
"<i>Due:</i> %1").
3298 arg( IncidenceFormatter::dateTimeToString( dueDt, floats,
false ).
3299 replace(
" ",
" " ) );
3306 ret +=
"<i>" + i18n(
"Priority:" ) +
"</i>" +
" ";
3307 ret += TQString::number( todo->
priority() );
3312 ret +=
"<i>" + i18n(
"Completed:" ) +
"</i>" +
" ";
3315 ret +=
"<i>" + i18n(
"Percent Done:" ) +
"</i>" +
" ";
3322 TQString IncidenceFormatter::ToolTipVisitor::dateRangeText(
Journal*journal )
3325 if (journal->
dtStart().isValid() ) {
3327 i18n(
"<i>Date:</i> %1").
3328 arg( IncidenceFormatter::dateToString( journal->
dtStart(),
false ) );
3333 TQString IncidenceFormatter::ToolTipVisitor::dateRangeText(
FreeBusy *fb )
3335 TQString tmp(
"<br>" + i18n(
"<i>Period start:</i> %1") );
3336 TQString ret = tmp.arg( TDEGlobal::locale()->formatDateTime( fb->
dtStart() ) );
3337 tmp =
"<br>" + i18n(
"<i>Period start:</i> %1");
3338 ret += tmp.arg( TDEGlobal::locale()->formatDateTime( fb->dtEnd() ) );
3344 bool IncidenceFormatter::ToolTipVisitor::visit(
Event *event )
3346 mResult = generateToolTip( event, dateRangeText( event, mDate ) );
3347 return !mResult.isEmpty();
3350 bool IncidenceFormatter::ToolTipVisitor::visit(
Todo *todo )
3352 mResult = generateToolTip( todo, dateRangeText( todo, mDate ) );
3353 return !mResult.isEmpty();
3356 bool IncidenceFormatter::ToolTipVisitor::visit(
Journal *journal )
3358 mResult = generateToolTip( journal, dateRangeText( journal ) );
3359 return !mResult.isEmpty();
3362 bool IncidenceFormatter::ToolTipVisitor::visit(
FreeBusy *fb )
3364 mResult =
"<qt><b>" + i18n(
"Free/Busy information for %1")
3365 .arg(fb->organizer().fullName()) +
"</b>";
3366 mResult += dateRangeText( fb );
3368 return !mResult.isEmpty();
3371 static TQString tooltipPerson(
const TQString& email, TQString name )
3375 if ( name.isEmpty() && !email.isEmpty() ) {
3376 TDEABC::AddressBook *add_book = TDEABC::StdAddressBook::self(
true );
3377 TDEABC::Addressee::List addressList = add_book->findByEmail( email );
3378 if ( !addressList.isEmpty() ) {
3379 TDEABC::Addressee o = addressList.first();
3380 if ( !o.isEmpty() && addressList.size() < 2 ) {
3382 name = o.formattedName();
3388 TQString tmpString = ( name.isEmpty() ? email : name );
3393 static TQString etc = i18n(
"elipsis",
"..." );
3394 static TQString tooltipFormatAttendeeRoleList(
Incidence *incidence, Attendee::Role role )
3397 TQString sep = i18n(
"separator for lists of people names",
", " );
3398 int sepLen = sep.length();
3402 Attendee::List::ConstIterator it;
3405 for( it = attendees.begin(); it != attendees.end(); ++it ) {
3407 if ( a->
role() != role ) {
3411 if ( a->email() == incidence->organizer().email() ) {
3415 if ( i == maxNumAtts ) {
3419 tmpStr += tooltipPerson( a->email(), a->name() );
3421 tmpStr += i18n(
" (delegated by %1)" ).arg( a->
delegator() );
3424 tmpStr += i18n(
" (delegated to %1)" ).arg( a->
delegate() );
3429 if ( tmpStr.endsWith( sep ) ) {
3430 tmpStr.truncate( tmpStr.length() - sepLen );
3435 static TQString tooltipFormatAttendees(
Incidence *incidence )
3437 TQString tmpStr, str;
3440 int attendeeCount = incidence->
attendees().count();
3441 if ( attendeeCount > 1 ||
3442 ( attendeeCount == 1 &&
3443 incidence->organizer().email() != incidence->
attendees().first()->email() ) ) {
3444 tmpStr +=
"<i>" + i18n(
"Organizer:" ) +
"</i>" +
" ";
3445 tmpStr += tooltipPerson( incidence->organizer().email(),
3446 incidence->organizer().name() );
3450 str = tooltipFormatAttendeeRoleList( incidence, Attendee::Chair );
3451 if ( !str.isEmpty() ) {
3452 tmpStr +=
"<br><i>" + i18n(
"Chair:" ) +
"</i>" +
" ";
3457 str = tooltipFormatAttendeeRoleList( incidence, Attendee::ReqParticipant );
3458 if ( !str.isEmpty() ) {
3459 tmpStr +=
"<br><i>" + i18n(
"Required Participants:" ) +
"</i>" +
" ";
3464 str = tooltipFormatAttendeeRoleList( incidence, Attendee::OptParticipant );
3465 if ( !str.isEmpty() ) {
3466 tmpStr +=
"<br><i>" + i18n(
"Optional Participants:" ) +
"</i>" +
" ";
3471 str = tooltipFormatAttendeeRoleList( incidence, Attendee::NonParticipant );
3472 if ( !str.isEmpty() ) {
3473 tmpStr +=
"<br><i>" + i18n(
"Observers:" ) +
"</i>" +
" ";
3480 TQString IncidenceFormatter::ToolTipVisitor::generateToolTip(
Incidence* incidence, TQString dtRangeText )
3482 uint maxDescLen = 120;
3488 TQString tmp =
"<qt>";
3491 tmp +=
"<b>" + incidence->
summary().replace(
"\n",
"<br>" ) +
"</b>";
3493 tmp +=
"<br>----------<br>";
3497 if ( !calStr.isEmpty() ) {
3498 tmp +=
"<i>" + i18n(
"Calendar:" ) +
"</i>" +
" ";
3505 if ( !incidence->
location().isEmpty() ) {
3507 tmp +=
"<i>" + i18n(
"Location:" ) +
"</i>" +
" ";
3508 tmp += incidence->
location().replace(
"\n",
"<br>" );
3512 if ( !durStr.isEmpty() ) {
3514 tmp +=
"<i>" + i18n(
"Duration:" ) +
"</i>" +
" ";
3520 tmp +=
"<i>" + i18n(
"Recurrence:" ) +
"</i>" +
" ";
3521 tmp += IncidenceFormatter::recurrenceString( incidence );
3526 if ( desc.length() > maxDescLen ) {
3527 desc = desc.left( maxDescLen ) + etc;
3529 tmp +=
"<br>----------<br>";
3530 tmp +=
"<i>" + i18n(
"Description:" ) +
"</i>" +
"<br>";
3531 tmp += desc.replace(
"\n",
"<br>" );
3532 tmp +=
"<br>----------";
3535 int reminderCount = incidence->
alarms().count();
3538 tmp +=
"<i>" + i18n(
"Reminder:",
"%n Reminders:", reminderCount ) +
"</i>" +
" ";
3539 tmp += IncidenceFormatter::reminderStringList( incidence ).join(
", " );
3543 tmp += tooltipFormatAttendees( incidence );
3545 int categoryCount = incidence->
categories().count();
3546 if ( categoryCount > 0 ) {
3548 tmp +=
"<i>" + i18n(
"Category:",
"%n Categories:", categoryCount ) +
"</i>" +
" ";
3556 TQString IncidenceFormatter::toolTipString(
IncidenceBase *incidence,
bool richText )
3558 return toolTipStr( 0, incidence, TQDate(), richText );
3561 TQString IncidenceFormatter::toolTipStr(
Calendar *calendar,
3567 if ( v.act( calendar, incidence, date, richText ) ) {
3581 MailBodyVisitor() : mResult(
"" ) {}
3586 return incidence ? incidence->
accept( *
this ) :
false;
3588 TQString result()
const {
return mResult; }
3591 bool visit(
Event *event );
3592 bool visit(
Todo *todo );
3593 bool visit(
Journal *journal );
3594 bool visit(
FreeBusy * ) { mResult = i18n(
"This is a Free Busy Object");
return !mResult.isEmpty(); }
3600 static TQString mailBodyIncidence(
Incidence *incidence )
3603 if ( !incidence->
summary().isEmpty() ) {
3604 body += i18n(
"Summary: %1\n").arg( incidence->
summary() );
3606 if ( !incidence->organizer().isEmpty() ) {
3607 body += i18n(
"Organizer: %1\n").arg( incidence->organizer().fullName() );
3609 if ( !incidence->
location().isEmpty() ) {
3610 body += i18n(
"Location: %1\n").arg( incidence->
location() );
3615 bool IncidenceFormatter::MailBodyVisitor::visit(
Event *event )
3617 TQString recurrence[]= {i18n(
"no recurrence",
"None"),
3618 i18n(
"Minutely"), i18n(
"Hourly"), i18n(
"Daily"),
3619 i18n(
"Weekly"), i18n(
"Monthly Same Day"), i18n(
"Monthly Same Position"),
3620 i18n(
"Yearly"), i18n(
"Yearly"), i18n(
"Yearly")};
3622 mResult = mailBodyIncidence( event );
3623 mResult += i18n(
"Start Date: %1\n").
3624 arg( IncidenceFormatter::dateToString( event->
dtStart(),
true ) );
3626 mResult += i18n(
"Start Time: %1\n").
3627 arg( IncidenceFormatter::timeToString( event->
dtStart(),
true ) );
3630 mResult += i18n(
"End Date: %1\n").
3631 arg( IncidenceFormatter::dateToString( event->
dtEnd(),
true ) );
3634 mResult += i18n(
"End Time: %1\n").
3635 arg( IncidenceFormatter::timeToString( event->
dtEnd(),
true ) );
3640 mResult += i18n(
"Recurs: %1\n")
3642 mResult += i18n(
"Frequency: %1\n")
3646 mResult += i18n (
"Repeats once",
"Repeats %n times", recur->
duration());
3653 endstr = TDEGlobal::locale()->formatDate( recur->
endDate() );
3655 endstr = TDEGlobal::locale()->formatDateTime( recur->
endDateTime() );
3657 mResult += i18n(
"Repeat until: %1\n").arg( endstr );
3659 mResult += i18n(
"Repeats forever\n");
3663 DateList exceptions = recur->exDates();
3664 if (exceptions.isEmpty() ==
false) {
3665 mResult += i18n(
"This recurring meeting has been cancelled on the following days:\n");
3666 DateList::ConstIterator ex_iter;
3667 for ( ex_iter = exceptions.begin(); ex_iter != exceptions.end(); ++ex_iter ) {
3668 mResult += i18n(
" %1\n").arg( TDEGlobal::locale()->formatDate(* ex_iter ) );
3672 TQString details =
event->description();
3673 if ( !details.isEmpty() ) {
3674 mResult += i18n(
"Details:\n%1\n").arg( details );
3676 return !mResult.isEmpty();
3679 bool IncidenceFormatter::MailBodyVisitor::visit(
Todo *todo )
3681 mResult = mailBodyIncidence( todo );
3684 mResult += i18n(
"Start Date: %1\n").
3685 arg( IncidenceFormatter::dateToString( todo->
dtStart(
false ),
true ) );
3687 mResult += i18n(
"Start Time: %1\n").
3688 arg( IncidenceFormatter::timeToString( todo->
dtStart(
false ),
true ) );
3692 mResult += i18n(
"Due Date: %1\n").
3693 arg( IncidenceFormatter::dateToString( todo->
dtDue(),
true ) );
3695 mResult += i18n(
"Due Time: %1\n").
3696 arg( IncidenceFormatter::timeToString( todo->
dtDue(),
true ) );
3700 if ( !details.isEmpty() ) {
3701 mResult += i18n(
"Details:\n%1\n").arg( details );
3703 return !mResult.isEmpty();
3706 bool IncidenceFormatter::MailBodyVisitor::visit(
Journal *journal )
3708 mResult = mailBodyIncidence( journal );
3709 mResult += i18n(
"Date: %1\n").
3710 arg( IncidenceFormatter::dateToString( journal->
dtStart(),
true ) );
3712 mResult += i18n(
"Time: %1\n").
3713 arg( IncidenceFormatter::timeToString( journal->
dtStart(),
true ) );
3716 mResult += i18n(
"Text of the journal:\n%1\n").arg( journal->
description() );
3717 return !mResult.isEmpty();
3722 TQString IncidenceFormatter::mailBodyString(
IncidenceBase *incidence )
3728 if ( v.act( incidence ) ) {
3734 static TQString recurEnd(
Incidence *incidence )
3748 TQString IncidenceFormatter::recurrenceString(
Incidence *incidence )
3751 return i18n(
"No recurrence" );
3753 TQStringList dayList;
3754 dayList.append( i18n(
"31st Last" ) );
3755 dayList.append( i18n(
"30th Last" ) );
3756 dayList.append( i18n(
"29th Last" ) );
3757 dayList.append( i18n(
"28th Last" ) );
3758 dayList.append( i18n(
"27th Last" ) );
3759 dayList.append( i18n(
"26th Last" ) );
3760 dayList.append( i18n(
"25th Last" ) );
3761 dayList.append( i18n(
"24th Last" ) );
3762 dayList.append( i18n(
"23rd Last" ) );
3763 dayList.append( i18n(
"22nd Last" ) );
3764 dayList.append( i18n(
"21st Last" ) );
3765 dayList.append( i18n(
"20th Last" ) );
3766 dayList.append( i18n(
"19th Last" ) );
3767 dayList.append( i18n(
"18th Last" ) );
3768 dayList.append( i18n(
"17th Last" ) );
3769 dayList.append( i18n(
"16th Last" ) );
3770 dayList.append( i18n(
"15th Last" ) );
3771 dayList.append( i18n(
"14th Last" ) );
3772 dayList.append( i18n(
"13th Last" ) );
3773 dayList.append( i18n(
"12th Last" ) );
3774 dayList.append( i18n(
"11th Last" ) );
3775 dayList.append( i18n(
"10th Last" ) );
3776 dayList.append( i18n(
"9th Last" ) );
3777 dayList.append( i18n(
"8th Last" ) );
3778 dayList.append( i18n(
"7th Last" ) );
3779 dayList.append( i18n(
"6th Last" ) );
3780 dayList.append( i18n(
"5th Last" ) );
3781 dayList.append( i18n(
"4th Last" ) );
3782 dayList.append( i18n(
"3rd Last" ) );
3783 dayList.append( i18n(
"2nd Last" ) );
3784 dayList.append( i18n(
"last day of the month",
"Last" ) );
3785 dayList.append( i18n(
"unknown day of the month",
"unknown" ) );
3786 dayList.append( i18n(
"1st" ) );
3787 dayList.append( i18n(
"2nd" ) );
3788 dayList.append( i18n(
"3rd" ) );
3789 dayList.append( i18n(
"4th" ) );
3790 dayList.append( i18n(
"5th" ) );
3791 dayList.append( i18n(
"6th" ) );
3792 dayList.append( i18n(
"7th" ) );
3793 dayList.append( i18n(
"8th" ) );
3794 dayList.append( i18n(
"9th" ) );
3795 dayList.append( i18n(
"10th" ) );
3796 dayList.append( i18n(
"11th" ) );
3797 dayList.append( i18n(
"12th" ) );
3798 dayList.append( i18n(
"13th" ) );
3799 dayList.append( i18n(
"14th" ) );
3800 dayList.append( i18n(
"15th" ) );
3801 dayList.append( i18n(
"16th" ) );
3802 dayList.append( i18n(
"17th" ) );
3803 dayList.append( i18n(
"18th" ) );
3804 dayList.append( i18n(
"19th" ) );
3805 dayList.append( i18n(
"20th" ) );
3806 dayList.append( i18n(
"21st" ) );
3807 dayList.append( i18n(
"22nd" ) );
3808 dayList.append( i18n(
"23rd" ) );
3809 dayList.append( i18n(
"24th" ) );
3810 dayList.append( i18n(
"25th" ) );
3811 dayList.append( i18n(
"26th" ) );
3812 dayList.append( i18n(
"27th" ) );
3813 dayList.append( i18n(
"28th" ) );
3814 dayList.append( i18n(
"29th" ) );
3815 dayList.append( i18n(
"30th" ) );
3816 dayList.append( i18n(
"31st" ) );
3817 int weekStart = TDEGlobal::locale()->weekStartDay();
3819 TQString recurStr, txt;
3820 const KCalendarSystem *calSys = TDEGlobal::locale()->calendar();
3823 case Recurrence::rNone:
3824 return i18n(
"No recurrence" );
3826 case Recurrence::rMinutely:
3827 recurStr = i18n(
"Recurs every minute",
"Recurs every %n minutes", recur->
frequency() );
3829 txt = i18n(
"%1 until %2" ).arg( recurStr ).arg( recurEnd( incidence ) );
3831 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3837 case Recurrence::rHourly:
3838 recurStr = i18n(
"Recurs hourly",
"Recurs every %n hours", recur->
frequency() );
3840 txt = i18n(
"%1 until %2" ).arg( recurStr ).arg( recurEnd( incidence ) );
3842 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3848 case Recurrence::rDaily:
3849 recurStr = i18n(
"Recurs daily",
"Recurs every %n days", recur->
frequency() );
3852 txt = i18n(
"%1 until %2" ).arg( recurStr ).arg( recurEnd( incidence ) );
3854 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3860 case Recurrence::rWeekly:
3862 recurStr = i18n(
"Recurs weekly",
"Recurs every %n weeks", recur->
frequency() );
3864 bool addSpace =
false;
3865 for (
int i = 0; i < 7; ++i ) {
3866 if ( recur->
days().testBit( ( i + weekStart + 6 ) % 7 ) ) {
3868 dayNames.append( i18n(
"separator for list of days",
", " ) );
3870 dayNames.append( calSys->weekDayName( ( ( i + weekStart + 6 ) % 7 ) + 1,
true ) );
3874 if ( dayNames.isEmpty() ) {
3875 dayNames = i18n(
"Recurs weekly on no days",
"no days" );
3878 txt = i18n(
"%1 on %2 until %3" ).
3879 arg( recurStr ).arg( dayNames ).arg( recurEnd( incidence ) );
3881 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3885 txt = i18n(
"%1 on %2" ).arg( recurStr ).arg( dayNames );
3888 case Recurrence::rMonthlyPos:
3890 recurStr = i18n(
"Recurs monthly",
"Recurs every %n months", recur->
frequency() );
3895 txt = i18n(
"%1 on the %2 %3 until %4" ).
3897 arg( dayList[rule.pos() + 31] ).
3898 arg( calSys->weekDayName( rule.day(),
false ) ).
3899 arg( recurEnd( incidence ) );
3901 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3905 txt = i18n(
"%1 on the %2 %3" ).
3907 arg( dayList[rule.pos() + 31] ).
3908 arg( calSys->weekDayName( rule.day(),
false ) );
3915 case Recurrence::rMonthlyDay:
3917 recurStr = i18n(
"Recurs monthly",
"Recurs every %n months", recur->
frequency() );
3922 txt = i18n(
"%1 on the %2 day until %3" ).
3924 arg( dayList[days + 31] ).
3925 arg( recurEnd( incidence ) );
3927 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3931 txt = i18n(
"%1 on the %2 day" ).arg( recurStr ).arg( dayList[days + 31] );
3938 case Recurrence::rYearlyMonth:
3940 recurStr = i18n(
"Recurs yearly",
"Recurs every %n years", recur->
frequency() );
3944 txt = i18n(
"%1 on %2 %3 until %4" ).
3947 arg( dayList[ recur->
yearDates()[0] + 31 ] ).
3948 arg( recurEnd( incidence ) );
3950 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3956 txt = i18n(
"%1 on %2 %3" ).
3959 arg( dayList[ recur->
yearDates()[0] + 31 ] );
3963 txt = i18n(
"Recurs yearly on %1 %2" ).
3964 arg( calSys->monthName( recur->
yearMonths()[0],
3966 arg( dayList[ recur->
startDate().day() + 31 ] );
3968 txt = i18n(
"Recurs yearly on %1 %2" ).
3969 arg( calSys->monthName( recur->
startDate().month(),
3971 arg( dayList[ recur->
startDate().day() + 31 ] );
3977 case Recurrence::rYearlyDay:
3979 recurStr = i18n(
"Recurs yearly",
"Recurs every %n years", recur->
frequency() );
3980 if ( !recur->
yearDays().isEmpty() ) {
3982 txt = i18n(
"%1 on day %2 until %3" ).
3985 arg( recurEnd( incidence ) );
3987 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
3991 txt = i18n(
"%1 on day %2" ).arg( recurStr ).arg( recur->
yearDays()[0] );
3998 case Recurrence::rYearlyPos:
4000 recurStr = i18n(
"Every year",
"Every %n years", recur->
frequency() );
4004 txt = i18n(
"%1 on the %2 %3 of %4 until %5" ).
4006 arg( dayList[rule.pos() + 31] ).
4007 arg( calSys->weekDayName( rule.day(),
false ) ).
4009 arg( recurEnd( incidence ) );
4011 txt += i18n(
" (%1 occurrences)" ).arg( recur->
duration() );
4015 txt = i18n(
"%1 on the %2 %3 of %4" ).
4017 arg( dayList[rule.pos() + 31] ).
4018 arg( calSys->weekDayName( rule.day(),
false ) ).
4028 return i18n(
"Incidence recurs" );
4031 TQString IncidenceFormatter::timeToString(
const TQDateTime &date,
bool shortfmt )
4033 return TDEGlobal::locale()->formatTime( date.time(), !shortfmt );
4036 TQString IncidenceFormatter::dateToString(
const TQDateTime &date,
bool shortfmt )
4039 TDEGlobal::locale()->formatDate( date.date(), shortfmt );
4042 TQString IncidenceFormatter::dateTimeToString(
const TQDateTime &date,
4043 bool allDay,
bool shortfmt )
4046 return dateToString( date, shortfmt );
4049 return TDEGlobal::locale()->formatDateTime( date, shortfmt );
4054 if ( !calendar || !incidence ) {
4059 if ( !calendarResource ) {
4064 if ( resourceCalendar ) {
4067 if ( subRes.isEmpty() ) {
4068 return resourceCalendar->resourceName();
4073 return resourceCalendar->resourceName();
4079 static TQString secs2Duration(
int secs )
4082 int days = secs / 86400;
4084 tmp += i18n(
"1 day",
"%n days", days );
4086 secs -= ( days * 86400 );
4088 int hours = secs / 3600;
4090 tmp += i18n(
"1 hour",
"%n hours", hours );
4092 secs -= ( hours * 3600 );
4094 int mins = secs / 60;
4096 tmp += i18n(
"1 minute",
"%n minutes", mins );
4104 if ( incidence->type() ==
"Event" ) {
4105 Event *
event =
static_cast<Event *
>( incidence );
4108 tmp = secs2Duration( event->
dtStart().secsTo( event->
dtEnd() ) );
4110 tmp = i18n(
"1 day",
"%n days",
4111 event->
dtStart().date().daysTo( event->
dtEnd().date() ) + 1 );
4114 tmp = i18n(
"forever" );
4116 }
else if ( incidence->type() ==
"Todo" ) {
4117 Todo *todo =
static_cast<Todo *
>( incidence );
4121 tmp = secs2Duration( todo->
dtStart().secsTo( todo->
dtDue() ) );
4123 tmp = i18n(
"1 day",
"%n days",
4124 todo->
dtStart().date().daysTo( todo->
dtDue().date() ) + 1 );
4132 TQStringList IncidenceFormatter::reminderStringList(
Incidence *incidence,
bool shortfmt )
4135 Q_UNUSED( shortfmt );
4137 TQStringList reminderStringList;
4141 Alarm::List::ConstIterator it;
4142 for ( it = alarms.begin(); it != alarms.end(); ++it ) {
4145 TQString remStr, atStr, offsetStr;
4148 if ( alarm->
time().isValid() ) {
4149 atStr = TDEGlobal::locale()->formatDateTime( alarm->
time() );
4155 offsetStr = i18n(
"N days/hours/minutes before the start datetime",
4156 "%1 before the start" );
4157 }
else if ( offset > 0 ) {
4158 offsetStr = i18n(
"N days/hours/minutes after the start datetime",
4159 "%1 after the start" );
4161 if ( incidence->
dtStart().isValid() ) {
4162 atStr = TDEGlobal::locale()->formatDateTime( incidence->
dtStart() );
4169 if ( incidence->type() ==
"Todo" ) {
4170 offsetStr = i18n(
"N days/hours/minutes before the due datetime",
4171 "%1 before the to-do is due" );
4173 offsetStr = i18n(
"N days/hours/minutes before the end datetime",
4174 "%1 before the end" );
4176 }
else if ( offset > 0 ) {
4177 if ( incidence->type() ==
"Todo" ) {
4178 offsetStr = i18n(
"N days/hours/minutes after the due datetime",
4179 "%1 after the to-do is due" );
4181 offsetStr = i18n(
"N days/hours/minutes after the end datetime",
4182 "%1 after the end" );
4185 if ( incidence->type() ==
"Todo" ) {
4186 Todo *t =
static_cast<Todo *
>( incidence );
4187 if ( t->
dtDue().isValid() ) {
4188 atStr = TDEGlobal::locale()->formatDateTime( t->
dtDue() );
4191 Event *e =
static_cast<Event *
>( incidence );
4192 if ( e->
dtEnd().isValid() ) {
4193 atStr = TDEGlobal::locale()->formatDateTime( e->
dtEnd() );
4198 if ( offset == 0 ) {
4199 if ( !atStr.isEmpty() ) {
4200 remStr = i18n(
"reminder occurs at datetime",
"at %1" ).arg( atStr );
4203 remStr = offsetStr.arg( secs2Duration( offset ) );
4207 TQString countStr = i18n(
"repeats once",
"repeats %n times", alarm->
repeatCount() );
4208 TQString intervalStr = i18n(
"interval is N days/hours/minutes",
"interval is %1" ).
4210 TQString repeatStr = i18n(
"(repeat string, interval string)",
"(%1, %2)" ).
4211 arg( countStr, intervalStr );
4212 remStr = remStr +
' ' + repeatStr;
4215 reminderStringList << remStr;
4219 return reminderStringList;