27 #include <calendarsupport/utils.h>
29 #include <Akonadi/Contact/ContactSearchJob>
31 #include <KCalCore/Attendee>
33 #include <KCalUtils/IncidenceFormatter>
35 #include <KCalendarSystem>
38 #include <KMessageBox>
39 #include <KTemporaryFile>
40 #include <KIO/NetAccess>
42 #include <QApplication>
44 #include <QTextStream>
48 static QString
cleanChars(
const QString &txt );
51 class KOrg::HtmlExportJob::Private
54 Private(
const Akonadi::ETMCalendar::Ptr &calendar,
57 : mCalendar( calendar ),
58 mSettings( settings ),
59 mAutoMode( autoMode ),
60 mMainWindow( mainWindow ),
61 mParentWidget( parent ),
65 Akonadi::ETMCalendar::Ptr mCalendar;
70 QMap<QDate,QString> mHolidayMap;
71 qulonglong mSubJobCount;
72 QMap<QString, KABC::Addressee> mOrganizersMap;
79 :
KJob( parent ), d( new Private( calendar, settings, autoMode, mainWindow, parent ) )
91 bool canExportItem =
false;
93 const KCalCore::Event::List events = d->mCalendar->events();
94 foreach (
const KCalCore::Event::Ptr &event, events ) {
96 const KCalCore::Attendee::List attendees =
event->attendees();
97 if ( !attendees.isEmpty() ) {
98 Akonadi::ContactSearchJob *job =
new Akonadi::ContactSearchJob(
this );
99 job->setQuery( Akonadi::ContactSearchJob::Email, event->organizer()->email() );
100 job->setProperty(
"incidenceUid", event->uid() );
101 connect( job, SIGNAL(result(
KJob*)), SLOT(receivedOrganizerInfo(
KJob*)) );
105 canExportItem =
true;
109 const KCalCore::Todo::List todos = d->mCalendar->todos();
110 foreach (
const KCalCore::Todo::Ptr &todo, todos ) {
112 const KCalCore::Attendee::List attendees = todo->attendees();
113 if ( !attendees.isEmpty() ) {
114 Akonadi::ContactSearchJob *job =
new Akonadi::ContactSearchJob(
this );
115 job->setQuery( Akonadi::ContactSearchJob::Email, todo->organizer()->email() );
116 job->setProperty(
"incidenceUid", todo->uid() );
117 connect( job, SIGNAL(result(
KJob*)), SLOT(receivedOrganizerInfo(
KJob*)) );
121 canExportItem =
true;
124 if( !canExportItem ) {
129 void HtmlExportJob::receivedOrganizerInfo(
KJob *job )
133 if ( !job->error() ) {
134 Akonadi::ContactSearchJob *searchJob = qobject_cast<Akonadi::ContactSearchJob*>( job );
135 const KABC::Addressee::List contacts = searchJob->contacts();
136 if ( !contacts.isEmpty() ) {
137 d->mOrganizersMap.insert(
138 searchJob->property(
"incidenceUid" ).toString(), contacts.first() );
141 if ( d->mSubJobCount == 0 ) {
146 void HtmlExportJob::finishExport()
148 QApplication::setOverrideCursor( QCursor ( Qt::WaitCursor ) );
151 QString errorMessage;
152 Q_ASSERT( d->mSettings );
153 KUrl dest( d->mSettings->outputFile() );
154 if ( dest.isLocalFile() ) {
155 saveStatus = save( dest.toLocalFile() );
156 errorMessage = i18n(
"Unable to write the output file." );
160 QString tfile = tf.fileName();
161 saveStatus = save( tfile );
162 errorMessage = i18n(
"Unable to write the temporary file for uploading." );
163 if ( !KIO::NetAccess::upload( tfile, dest, d->mParentWidget ) ) {
165 errorMessage = i18n(
"Unable to upload the export file." );
169 QApplication::restoreOverrideCursor();
173 saveMessage = i18n(
"Web page successfully written to \"%1\"", dest.url() );
175 saveMessage = i18n(
"Export failed. %1", errorMessage );
178 if ( !d->mAutoMode ) {
179 KMessageBox::information(
182 i18nc(
"@title:window",
"Export Status" ) );
184 d->mMainWindow->showStatusMessage(
185 i18nc(
"@info:status",
186 "Automatic Export: %1", saveMessage ) );
191 bool HtmlExportJob::save(
const QString &fileName )
193 QString fn( fileName );
194 if ( fn.isEmpty() && d->mSettings ) {
195 fn = d->mSettings->outputFile();
197 if ( !d->mSettings || fn.isEmpty() ) {
201 if ( !f.open( QIODevice::WriteOnly ) ) {
204 QTextStream ts( &f );
205 bool success = save( &ts );
210 bool HtmlExportJob::save( QTextStream *ts )
212 if ( !d->mSettings ) {
215 ts->setCodec(
"UTF-8" );
217 *ts <<
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" ";
218 *ts <<
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl;
220 *ts <<
"<html><head>" << endl;
221 *ts <<
" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=";
222 *ts <<
"UTF-8\" />" << endl;
223 if ( !d->mSettings->pageTitle().isEmpty() ) {
224 *ts <<
" <title>" << d->mSettings->pageTitle() <<
"</title>" << endl;
226 *ts <<
" <style type=\"text/css\">" << endl;
228 *ts <<
" </style>" << endl;
229 *ts <<
"</head><body>" << endl;
234 if ( d->mSettings->eventView() || d->mSettings->monthView() || d->mSettings->weekView() ) {
235 if ( !d->mSettings->eventTitle().isEmpty() ) {
236 *ts <<
"<h1>" << d->mSettings->eventTitle() <<
"</h1>" << endl;
240 if ( d->mSettings->weekView() ) {
244 if ( d->mSettings->monthView() ) {
248 if ( d->mSettings->eventView() ) {
254 if ( d->mSettings->todoView() ) {
255 if ( !d->mSettings->todoListTitle().isEmpty() ) {
256 *ts <<
"<h1>" << d->mSettings->todoListTitle() <<
"</h1>" << endl;
262 if ( d->mSettings->journalView() ) {
263 if ( !d->mSettings->journalTitle().isEmpty() ) {
264 *ts <<
"<h1>" << d->mSettings->journalTitle() <<
"</h1>" << endl;
270 if ( d->mSettings->freeBusyView() ) {
271 if ( !d->mSettings->freeBusyTitle().isEmpty() ) {
272 *ts <<
"<h1>" << d->mSettings->freeBusyTitle() <<
"</h1>" << endl;
280 *ts <<
"</body></html>" << endl;
288 start.setYMD( start.year(), start.month(), 1 );
290 QDate end( start.year(), start.month(), start.daysInMonth() );
292 int startmonth = start.month();
293 int startyear = start.year();
295 while ( start <
toDate() ) {
297 QDate hDate( start.year(), start.month(), 1 );
298 QString hMon = hDate.toString( QLatin1String(
"MMMM") );
299 QString hYear = hDate.toString( QLatin1String(
"yyyy" ));
301 << i18nc(
"@title month and year",
"%1 %2", hMon, hYear )
303 if ( KGlobal::locale()->weekStartDay() == 1 ) {
304 start = start.addDays( 1 - start.dayOfWeek() );
306 if ( start.dayOfWeek() != 7 ) {
307 start = start.addDays( -start.dayOfWeek() );
310 *ts <<
"<table border=\"1\">" << endl;
314 for (
int i=0; i < 7; ++i ) {
315 *ts <<
"<th>" << KGlobal::locale()->calendar()->weekDayName( start.addDays(i) ) <<
"</th>";
317 *ts <<
"</tr>" << endl;
320 while ( start <= end ) {
321 *ts <<
" <tr>" << endl;
322 for (
int i=0; i < 7; ++i ) {
323 *ts <<
" <td valign=\"top\"><table border=\"0\">";
326 if ( d->mHolidayMap.contains( start ) || start.dayOfWeek() == 7 ) {
327 *ts <<
"class=\"dateholiday\"";
329 *ts <<
"class=\"date\"";
331 *ts <<
">" << QString::number( start.day() );
333 if ( d->mHolidayMap.contains( start ) ) {
334 *ts <<
" <em>" << d->mHolidayMap[
start] <<
"</em>";
337 *ts <<
"</td></tr><tr><td valign=\"top\">";
341 KCalCore::Event::List events = d->mCalendar->events( start, d->mCalendar->timeSpec(),
342 KCalCore::EventSortStartDate,
343 KCalCore::SortDirectionAscending );
344 if ( events.count() ) {
346 foreach (
const KCalCore::Event::Ptr &event, events ) {
358 *ts <<
"</td></tr></table></td>" << endl;
359 start = start.addDays( 1 );
361 *ts <<
" </tr>" << endl;
363 *ts <<
"</table>" << endl;
365 if ( startmonth > 12 ) {
369 start.setYMD( startyear, startmonth, 1 );
370 end.setYMD( start.year(), start.month(), start.daysInMonth() );
377 *ts <<
"<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">" << endl;
378 *ts <<
" <tr>" << endl;
379 *ts <<
" <th class=\"sum\">" << i18nc(
"@title:column event start time",
380 "Start Time" ) <<
"</th>" << endl;
381 *ts <<
" <th>" << i18nc(
"@title:column event end time",
382 "End Time" ) <<
"</th>" << endl;
383 *ts <<
" <th>" << i18nc(
"@title:column event description",
384 "Event" ) <<
"</th>" << endl;
385 if ( d->mSettings->eventLocation() ) {
386 *ts <<
" <th>" << i18nc(
"@title:column event locatin",
387 "Location" ) <<
"</th>" << endl;
390 if ( d->mSettings->eventCategories() ) {
391 *ts <<
" <th>" << i18nc(
"@title:column event categories",
392 "Categories" ) <<
"</th>" << endl;
395 if ( d->mSettings->eventAttendees() ) {
396 *ts <<
" <th>" << i18nc(
"@title:column event attendees",
397 "Attendees" ) <<
"</th>" << endl;
401 *ts <<
" </tr>" << endl;
403 for ( QDate dt =
fromDate(); dt <=
toDate(); dt = dt.addDays(1) ) {
404 kDebug() <<
"Getting events for" << dt.toString();
405 KCalCore::Event::List events = d->mCalendar->events( dt, d->mCalendar->timeSpec(),
406 KCalCore::EventSortStartDate,
407 KCalCore::SortDirectionAscending );
408 if ( !events.isEmpty() ) {
409 *ts <<
" <tr><td colspan=\"" << QString::number( columns )
410 <<
"\" class=\"datehead\"><i>"
411 << KGlobal::locale()->formatDate( dt )
412 <<
"</i></td></tr>" << endl;
414 foreach (
const KCalCore::Event::Ptr &event, events ) {
423 *ts <<
"</table>" << endl;
427 QDate date,
bool withDescription )
429 kDebug() <<
event->summary();
430 *ts <<
" <tr>" << endl;
432 if ( !event->allDay() ) {
433 if ( event->isMultiDay( d->mCalendar->timeSpec() ) && ( event->dtStart().date() != date ) ) {
434 *ts <<
" <td> </td>" << endl;
436 *ts <<
" <td valign=\"top\">"
437 << KCalUtils::IncidenceFormatter::timeToString( event->dtStart(),
438 true, d->mCalendar->timeSpec() )
441 if ( event->isMultiDay( d->mCalendar->timeSpec() ) && ( event->dtEnd().date() != date ) ) {
442 *ts <<
" <td> </td>" << endl;
444 *ts <<
" <td valign=\"top\">"
445 << KCalUtils::IncidenceFormatter::timeToString( event->dtEnd(),
446 true, d->mCalendar->timeSpec() )
450 *ts <<
" <td> </td><td> </td>" << endl;
453 *ts <<
" <td class=\"sum\">" << endl;
454 *ts <<
" <b>" <<
cleanChars( event->summary() ) <<
"</b>" << endl;
455 if ( withDescription && !event->description().isEmpty() ) {
458 *ts <<
" </td>" << endl;
460 if ( d->mSettings->eventLocation() ) {
461 *ts <<
" <td>" << endl;
463 *ts <<
" </td>" << endl;
466 if ( d->mSettings->eventCategories() ) {
467 *ts <<
" <td>" << endl;
469 *ts <<
" </td>" << endl;
472 if ( d->mSettings->eventAttendees() ) {
473 *ts <<
" <td>" << endl;
475 *ts <<
" </td>" << endl;
478 *ts <<
" </tr>" << endl;
483 KCalCore::Todo::List rawTodoList = d->mCalendar->todos();
486 while ( index < rawTodoList.count() ) {
487 const KCalCore::Todo::Ptr todo = rawTodoList.value( index );
489 const Akonadi::Item parentItem = d->mCalendar->item( todo->relatedTo() );
496 KCalCore::Todo::List todoList;
497 KCalCore::Todo::List::ConstIterator it;
498 for (
int i = 1; i <= 9; ++i ) {
499 foreach (
const KCalCore::Todo::Ptr &todo, rawTodoList ) {
501 todoList.append( todo );
505 foreach (
const KCalCore::Todo::Ptr &todo, rawTodoList ) {
507 todoList.append( todo );
512 *ts <<
"<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">" << endl;
513 *ts <<
" <tr>" << endl;
514 *ts <<
" <th class=\"sum\">" << i18nc(
"@title:column",
"To-do" ) <<
"</th>" << endl;
515 *ts <<
" <th>" << i18nc(
"@title:column to-do priority",
"Priority" ) <<
"</th>" << endl;
516 *ts <<
" <th>" << i18nc(
"@title:column to-do percent completed",
517 "Completed" ) <<
"</th>" << endl;
518 if ( d->mSettings->taskDueDate() ) {
519 *ts <<
" <th>" << i18nc(
"@title:column to-do due date",
"Due Date" ) <<
"</th>" << endl;
522 if ( d->mSettings->taskLocation() ) {
523 *ts <<
" <th>" << i18nc(
"@title:column to-do location",
"Location" ) <<
"</th>" << endl;
526 if ( d->mSettings->taskCategories() ) {
527 *ts <<
" <th>" << i18nc(
"@title:column to-do categories",
"Categories" ) <<
"</th>" << endl;
530 if ( d->mSettings->taskAttendees() ) {
531 *ts <<
" <th>" << i18nc(
"@title:column to-do attendees",
"Attendees" ) <<
"</th>" << endl;
534 *ts <<
" </tr>" << endl;
537 for ( it = todoList.constBegin(); it != todoList.constEnd(); ++it ) {
538 const QString parentUid = (*it)->relatedTo();
539 if ( parentUid.isEmpty() ) {
549 for ( it = todoList.constBegin(); it != todoList.constEnd(); ++it ) {
551 Akonadi::Item item = d->mCalendar->item( ( *it )->uid() );
552 const Akonadi::Item::List relations = d->mCalendar->childItems( item.id() );
554 if ( !relations.isEmpty() ) {
556 *ts <<
" <tr>" << endl;
557 *ts <<
" <td class=\"subhead\" colspan=";
558 *ts <<
"\"" << QString::number(columns) <<
"\"";
559 *ts <<
"><a name=\"sub" << (*it)->uid() <<
"\"></a>"
560 << i18nc(
"@title:column sub-to-dos of the parent to-do",
561 "Sub-To-dos of: " ) <<
"<a href=\"#"
562 << (*it)->uid() <<
"\"><b>" <<
cleanChars( (*it)->summary() )
563 <<
"</b></a></td>" << endl;
564 *ts <<
" </tr>" << endl;
566 KCalCore::Todo::List sortedList;
569 for (
int i = 1; i <= 9; ++i ) {
570 foreach (
const Akonadi::Item &item, relations ) {
571 KCalCore::Todo::Ptr ev3 = CalendarSupport::todo( item );
572 if ( ev3 && ev3->priority() == i ) {
573 sortedList.append( ev3 );
578 foreach (
const Akonadi::Item &item, relations ) {
579 KCalCore::Todo::Ptr ev3 = CalendarSupport::todo( item );
580 if ( ev3 && ev3->priority() == 0 ) {
581 sortedList.append( ev3 );
585 KCalCore::Todo::List::ConstIterator it3;
586 for ( it3 = sortedList.constBegin(); it3 != sortedList.constEnd(); ++it3 ) {
592 *ts <<
"</table>" << endl;
599 const bool completed = todo->isCompleted();
601 Akonadi::Item it = d->mCalendar->item( todo->uid() );
602 Akonadi::Item::List relations = d->mCalendar->childItems( it.id() );
604 *ts <<
"<tr>" << endl;
606 *ts <<
" <td class=\"sum";
607 if (completed) *ts <<
"done";
608 *ts <<
"\">" << endl;
609 *ts <<
" <a name=\"" << todo->uid() <<
"\"></a>" << endl;
610 *ts <<
" <b>" <<
cleanChars( todo->summary() ) <<
"</b>" << endl;
611 if ( !todo->description().isEmpty() ) {
614 if ( relations.count() ) {
615 *ts <<
" <div align=\"right\"><a href=\"#sub" << todo->uid()
616 <<
"\">" << i18nc(
"@title:column sub-to-dos of the parent to-do",
617 "Sub-To-dos" ) <<
"</a></div>" << endl;
619 *ts <<
" </td>" << endl;
623 *ts <<
" class=\"done\"";
626 *ts <<
" " << todo->priority() << endl;
627 *ts <<
" </td>" << endl;
631 *ts <<
" class=\"done\"";
634 *ts <<
" " << i18nc(
"@info/plain to-do percent complete",
635 "%1 %", todo->percentComplete() ) << endl;
636 *ts <<
" </td>" << endl;
638 if ( d->mSettings->taskDueDate() ) {
641 *ts <<
" class=\"done\"";
644 if ( todo->hasDueDate() ) {
645 *ts <<
" " << KCalUtils::IncidenceFormatter::dateToString( todo->dtDue(
true ) ) << endl;
647 *ts <<
" " << endl;
649 *ts <<
" </td>" << endl;
652 if ( d->mSettings->taskLocation() ) {
655 *ts <<
" class=\"done\"";
659 *ts <<
" </td>" << endl;
662 if ( d->mSettings->taskCategories() ) {
665 *ts <<
" class=\"done\"";
669 *ts <<
" </td>" << endl;
672 if ( d->mSettings->taskAttendees() ) {
675 *ts <<
" class=\"done\"";
679 *ts <<
" </td>" << endl;
682 *ts <<
"</tr>" << endl;
706 int secrecy = incidence->secrecy();
707 if ( secrecy == KCalCore::Incidence::SecrecyPublic ) {
710 if ( secrecy == KCalCore::Incidence::SecrecyPrivate && !d->mSettings->excludePrivate() ) {
713 if ( secrecy == KCalCore::Incidence::SecrecyConfidential &&
714 !d->mSettings->excludeConfidential() ) {
722 if ( !incidence->location().isEmpty() ) {
723 *ts <<
" " <<
cleanChars( incidence->location() ) << endl;
725 *ts <<
" " << endl;
731 if ( !incidence->categoriesStr().isEmpty() ) {
732 *ts <<
" " <<
cleanChars( incidence->categoriesStr() ) << endl;
734 *ts <<
" " << endl;
740 KCalCore::Attendee::List attendees = incidence->attendees();
741 if ( attendees.count() ) {
743 const KABC::Addressee organizer = d->mOrganizersMap.value( incidence->uid() );
744 if ( !organizer.isEmpty() ) {
745 *ts <<
"<a href=\"mailto:" << incidence->organizer()->email() <<
"\">";
746 *ts <<
cleanChars( organizer.formattedName() ) <<
"</a>" << endl;
748 *ts << incidence->organizer()->fullName();
750 *ts <<
"</em><br />";
751 KCalCore::Attendee::List::ConstIterator it;
752 for ( it = attendees.constBegin(); it != attendees.constEnd(); ++it ) {
753 KCalCore::Attendee::Ptr a = *it;
754 if ( !a->email().isEmpty() ) {
755 *ts <<
"<a href=\"mailto:" << a->email();
756 *ts <<
"\">" <<
cleanChars( a->name() ) <<
"</a>";
760 *ts <<
"<br />" << endl;
763 *ts <<
" " << endl;
769 int number = text.count( QLatin1Char(
'\n') );
774 QString tmpText = text;
776 for (
int i = 0; i <= number; ++i ) {
777 const int pos = tmpText.indexOf( QLatin1Char(
'\n') );
778 tmp = tmpText.left( pos );
779 tmpText = tmpText.right( tmpText.length() - pos - 1 );
780 out += tmp + QLatin1String(
"<br />");
789 QString trailer = i18nc(
"@info/plain",
"This page was created " );
795 if ( !d->mSettings->eMail().isEmpty() ) {
796 if ( !d->mSettings->name().isEmpty() ) {
797 trailer += i18nc(
"@info/plain page creator email link with name",
798 "by <link url='mailto:%1'>%2</link> ",
799 d->mSettings->eMail(), d->mSettings->name() );
801 trailer += i18nc(
"@info/plain page creator email link",
802 "by <link url='mailto:%1'>%2</link> ",
803 d->mSettings->eMail(), d->mSettings->eMail() );
806 if ( !d->mSettings->name().isEmpty() ) {
807 trailer += i18nc(
"@info/plain page creator name only",
808 "by %1 ", d->mSettings->name() );
811 if ( !d->mSettings->creditName().isEmpty() ) {
812 if ( !d->mSettings->creditURL().isEmpty() ) {
813 trailer += i18nc(
"@info/plain page credit with name and link",
814 "with <link url='%1'>%2</link>",
815 d->mSettings->creditURL(), d->mSettings->creditName() );
817 trailer += i18nc(
"@info/plain page credit name only",
818 "with %1", d->mSettings->creditName() );
821 *ts <<
"<p>" << trailer <<
"</p>" << endl;
827 txt = txt.replace( QLatin1Char(
'&'), QLatin1String(
"&") );
828 txt = txt.replace( QLatin1Char(
'<'), QLatin1String(
"<") );
829 txt = txt.replace( QLatin1Char(
'>'), QLatin1String(
">") );
830 txt = txt.replace( QLatin1Char(
'\"'), QLatin1String(
""") );
831 txt = txt.replace( QString::fromUtf8(
"ä" ), QLatin1String(
"ä") );
832 txt = txt.replace( QString::fromUtf8(
"Ä" ), QLatin1String(
"Ä") );
833 txt = txt.replace( QString::fromUtf8(
"ö" ), QLatin1String(
"ö") );
834 txt = txt.replace( QString::fromUtf8(
"Ö" ), QLatin1String(
"Ö") );
835 txt = txt.replace( QString::fromUtf8(
"ü" ), QLatin1String(
"ü") );
836 txt = txt.replace( QString::fromUtf8(
"Ü" ), QLatin1String(
"Ü") );
837 txt = txt.replace( QString::fromUtf8(
"ß" ), QLatin1String(
"ß") );
838 txt = txt.replace( QString::fromUtf8(
"€" ), QLatin1String(
"€") );
839 txt = txt.replace( QString::fromUtf8(
"é" ), QLatin1String(
"é") );
846 if ( !d->mSettings->styleSheet().isEmpty() ) {
847 return d->mSettings->styleSheet();
852 if ( QApplication::isRightToLeft() ) {
853 css += QLatin1String(
" body { background-color:white; color:black; direction: rtl }\n");
854 css += QLatin1String(
" td { text-align:center; background-color:#eee }\n");
855 css += QLatin1String(
" th { text-align:center; background-color:#228; color:white }\n");
856 css += QLatin1String(
" td.sumdone { background-color:#ccc }\n");
857 css += QLatin1String(
" td.done { background-color:#ccc }\n");
858 css += QLatin1String(
" td.subhead { text-align:center; background-color:#ccf }\n");
859 css += QLatin1String(
" td.datehead { text-align:center; background-color:#ccf }\n");
860 css += QLatin1String(
" td.space { background-color:white }\n");
861 css += QLatin1String(
" td.dateholiday { color:red }\n");
863 css += QLatin1String(
" body { background-color:white; color:black }\n");
864 css += QLatin1String(
" td { text-align:center; background-color:#eee }\n");
865 css += QLatin1String(
" th { text-align:center; background-color:#228; color:white }\n");
866 css += QLatin1String(
" td.sum { text-align:left }\n");
867 css += QLatin1String(
" td.sumdone { text-align:left; background-color:#ccc }\n");
868 css += QLatin1String(
" td.done { background-color:#ccc }\n");
869 css += QLatin1String(
" td.subhead { text-align:center; background-color:#ccf }\n");
870 css += QLatin1String(
" td.datehead { text-align:center; background-color:#ccf }\n");
871 css += QLatin1String(
" td.space { background-color:white }\n");
872 css += QLatin1String(
" td.date { text-align:left }\n");
873 css += QLatin1String(
" td.dateholiday { text-align:left; color:red }\n");
881 if ( d->mHolidayMap[date].isEmpty() ) {
882 d->mHolidayMap[date] = name;
884 d->mHolidayMap[date] = i18nc(
"@info/plain holiday by date and name",
885 "%1, %2", d->mHolidayMap[date], name );
891 return d->mSettings->dateStart().date();
896 return d->mSettings->dateEnd().date();
904 #include "htmlexportjob.moc"
void createEvent(QTextStream *ts, const KCalCore::Event::Ptr &event, QDate date, bool withDescription=true)
void createTodo(QTextStream *ts, const KCalCore::Todo::Ptr &todo)
void createTodoList(QTextStream *ts)
void formatLocation(QTextStream *ts, const KCalCore::Incidence::Ptr &incidence)
static QString cleanChars(const QString &txt)
QString styleSheet() const
void addHoliday(const QDate &date, const QString &name)
HtmlExportJob(const Akonadi::ETMCalendar::Ptr &calendar, HTMLExportSettings *settings, bool autoMode, KOrg::MainWindow *mainWindow, QWidget *parent=0)
Create new HTML exporter for calendar.
void createMonthView(QTextStream *ts)
void createFooter(QTextStream *ts)
void createJournalView(QTextStream *ts)
interface for korganizer main window
bool checkSecrecy(const KCalCore::Incidence::Ptr &incidence)
HTMLExportSettings * settings() const
void formatAttendees(QTextStream *ts, const KCalCore::Incidence::Ptr &incidence)
void createFreeBusyView(QTextStream *ts)
void createWeekView(QTextStream *ts)
void formatCategories(QTextStream *ts, const KCalCore::Incidence::Ptr &incidence)
void createEventList(QTextStream *ts)
QString breakString(const QString &text)