• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 API Reference
  • KDE Home
  • Contact Us
 

KCal Library

  • kcal
htmlexport.cpp
1/*
2 This file is part of the kcal library.
3
4 Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#include "htmlexport.h"
24#include "htmlexportsettings.h"
25#include "incidenceformatter.h"
26#include "calendar.h"
27#include "event.h"
28#include "todo.h"
29#ifndef KORG_NOKABC
30 #include "kabc/stdaddressbook.h"
31#endif
32
33#include <kglobal.h>
34#include <klocalizedstring.h>
35#include <kdebug.h>
36#include <kcalendarsystem.h>
37
38#include <QtCore/QFile>
39#include <QtCore/QTextStream>
40#include <QtCore/QTextCodec>
41#include <QtCore/QRegExp>
42#include <QtCore/QMap>
43#include <QApplication>
44
45using namespace KCal;
46
47static QString cleanChars( const QString &txt );
48
49//@cond PRIVATE
50class KCal::HtmlExport::Private
51{
52 public:
53 Private( Calendar *calendar, HTMLExportSettings *settings )
54 : mCalendar( calendar ),
55 mSettings( settings )
56 {}
57
58 Calendar *mCalendar;
59 HTMLExportSettings *mSettings;
60 QMap<QDate,QString> mHolidayMap;
61};
62//@endcond
63
64HtmlExport::HtmlExport( Calendar *calendar, HTMLExportSettings *settings )
65 : d( new Private( calendar, settings ) )
66{
67}
68
69HtmlExport::~HtmlExport()
70{
71 delete d;
72}
73
74bool HtmlExport::save( const QString &fileName )
75{
76 QString fn( fileName );
77 if ( fn.isEmpty() && d->mSettings ) {
78 fn = d->mSettings->outputFile();
79 }
80 if ( !d->mSettings || fn.isEmpty() ) {
81 return false;
82 }
83 QFile f( fileName );
84 if ( !f.open( QIODevice::WriteOnly ) ) {
85 return false;
86 }
87 QTextStream ts( &f );
88 bool success = save( &ts );
89 f.close();
90 return success;
91}
92
93bool HtmlExport::save( QTextStream *ts )
94{
95 if ( !d->mSettings ) {
96 return false;
97 }
98 ts->setCodec( "UTF-8" );
99 // Write HTML header
100 *ts << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" ";
101 *ts << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl;
102
103 *ts << "<html><head>" << endl;
104 *ts << " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=";
105 *ts << "UTF-8\" />" << endl;
106 if ( !d->mSettings->pageTitle().isEmpty() ) {
107 *ts << " <title>" << d->mSettings->pageTitle() << "</title>" << endl;
108 }
109 *ts << " <style type=\"text/css\">" << endl;
110 *ts << styleSheet();
111 *ts << " </style>" << endl;
112 *ts << "</head><body>" << endl;
113
114 // FIXME: Write header
115 // (Heading, Calendar-Owner, Calendar-Date, ...)
116
117 if ( d->mSettings->eventView() || d->mSettings->monthView() || d->mSettings->weekView() ) {
118 if ( !d->mSettings->eventTitle().isEmpty() ) {
119 *ts << "<h1>" << d->mSettings->eventTitle() << "</h1>" << endl;
120 }
121
122 // Write Week View
123 if ( d->mSettings->weekView() ) {
124 createWeekView( ts );
125 }
126 // Write Month View
127 if ( d->mSettings->monthView() ) {
128 createMonthView( ts );
129 }
130 // Write Event List
131 if ( d->mSettings->eventView() ) {
132 createEventList( ts );
133 }
134 }
135
136 // Write Todo List
137 if ( d->mSettings->todoView() ) {
138 if ( !d->mSettings->todoListTitle().isEmpty() ) {
139 *ts << "<h1>" << d->mSettings->todoListTitle() << "</h1>" << endl;
140 }
141 createTodoList( ts );
142 }
143
144 // Write Journals
145 if ( d->mSettings->journalView() ) {
146 if ( !d->mSettings->journalTitle().isEmpty() ) {
147 *ts << "<h1>" << d->mSettings->journalTitle() << "</h1>" << endl;
148 }
149 createJournalView( ts );
150 }
151
152 // Write Free/Busy
153 if ( d->mSettings->freeBusyView() ) {
154 if ( !d->mSettings->freeBusyTitle().isEmpty() ) {
155 *ts << "<h1>" << d->mSettings->freeBusyTitle() << "</h1>" << endl;
156 }
157 createFreeBusyView( ts );
158 }
159
160 createFooter( ts );
161
162 // Write HTML trailer
163 *ts << "</body></html>" << endl;
164
165 return true;
166}
167
168void HtmlExport::createMonthView( QTextStream *ts )
169{
170 QDate start = fromDate();
171 start.setYMD( start.year(), start.month(), 1 ); // go back to first day in month
172
173 QDate end( start.year(), start.month(), start.daysInMonth() );
174
175 int startmonth = start.month();
176 int startyear = start.year();
177
178 while ( start < toDate() ) {
179 // Write header
180 QDate hDate( start.year(), start.month(), 1 );
181 QString hMon = hDate.toString( "MMMM" );
182 QString hYear = hDate.toString( "yyyy" );
183 *ts << "<h2>"
184 << i18nc( "@title month and year", "%1 %2", hMon, hYear )
185 << "</h2>" << endl;
186 if ( KGlobal::locale()->weekStartDay() == 1 ) {
187 start = start.addDays( 1 - start.dayOfWeek() );
188 } else {
189 if ( start.dayOfWeek() != 7 ) {
190 start = start.addDays( -start.dayOfWeek() );
191 }
192 }
193 *ts << "<table border=\"1\">" << endl;
194
195 // Write table header
196 *ts << " <tr>";
197 for ( int i=0; i < 7; ++i ) {
198 *ts << "<th>" << KGlobal::locale()->calendar()->weekDayName( start.addDays(i) ) << "</th>";
199 }
200 *ts << "</tr>" << endl;
201
202 // Write days
203 while ( start <= end ) {
204 *ts << " <tr>" << endl;
205 for ( int i=0; i < 7; ++i ) {
206 *ts << " <td valign=\"top\"><table border=\"0\">";
207
208 *ts << "<tr><td ";
209 if ( d->mHolidayMap.contains( start ) || start.dayOfWeek() == 7 ) {
210 *ts << "class=\"dateholiday\"";
211 } else {
212 *ts << "class=\"date\"";
213 }
214 *ts << ">" << QString::number( start.day() );
215
216 if ( d->mHolidayMap.contains( start ) ) {
217 *ts << " <em>" << d->mHolidayMap[start] << "</em>";
218 }
219
220 *ts << "</td></tr><tr><td valign=\"top\">";
221
222 // Only print events within the from-to range
223 if ( start >= fromDate() && start <= toDate() ) {
224 Event::List events = d->mCalendar->events( start, d->mCalendar->timeSpec(),
225 EventSortStartDate,
226 SortDirectionAscending );
227 if ( events.count() ) {
228 *ts << "<table>";
229 Event::List::ConstIterator it;
230 for ( it = events.constBegin(); it != events.constEnd(); ++it ) {
231 if ( checkSecrecy( *it ) ) {
232 createEvent( ts, *it, start, false );
233 }
234 }
235 *ts << "</table>";
236 } else {
237 *ts << "&nbsp;";
238 }
239 }
240
241 *ts << "</td></tr></table></td>" << endl;
242 start = start.addDays( 1 );
243 }
244 *ts << " </tr>" << endl;
245 }
246 *ts << "</table>" << endl;
247 startmonth += 1;
248 if ( startmonth > 12 ) {
249 startyear += 1;
250 startmonth = 1;
251 }
252 start.setYMD( startyear, startmonth, 1 );
253 end.setYMD( start.year(), start.month(), start.daysInMonth() );
254 }
255}
256
257void HtmlExport::createEventList( QTextStream *ts )
258{
259 int columns = 3;
260 *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">" << endl;
261 *ts << " <tr>" << endl;
262 *ts << " <th class=\"sum\">" << i18nc( "@title:column event start time",
263 "Start Time" ) << "</th>" << endl;
264 *ts << " <th>" << i18nc( "@title:column event end time",
265 "End Time" ) << "</th>" << endl;
266 *ts << " <th>" << i18nc( "@title:column event description",
267 "Event" ) << "</th>" << endl;
268 if ( d->mSettings->eventLocation() ) {
269 *ts << " <th>" << i18nc( "@title:column event location",
270 "Location" ) << "</th>" << endl;
271 ++columns;
272 }
273 if ( d->mSettings->eventCategories() ) {
274 *ts << " <th>" << i18nc( "@title:column event categories",
275 "Categories" ) << "</th>" << endl;
276 ++columns;
277 }
278 if ( d->mSettings->eventAttendees() ) {
279 *ts << " <th>" << i18nc( "@title:column event attendees",
280 "Attendees" ) << "</th>" << endl;
281 ++columns;
282 }
283
284 *ts << " </tr>" << endl;
285
286 for ( QDate dt = fromDate(); dt <= toDate(); dt = dt.addDays(1) ) {
287 kDebug() << "Getting events for" << dt.toString();
288 Event::List events = d->mCalendar->events( dt, d->mCalendar->timeSpec(),
289 EventSortStartDate,
290 SortDirectionAscending );
291 if ( events.count() ) {
292 *ts << " <tr><td colspan=\"" << QString::number( columns )
293 << "\" class=\"datehead\"><i>"
294 << KGlobal::locale()->formatDate( dt )
295 << "</i></td></tr>" << endl;
296
297 Event::List::ConstIterator it;
298 for ( it = events.constBegin(); it != events.constEnd(); ++it ) {
299 if ( checkSecrecy( *it ) ) {
300 createEvent( ts, *it, dt );
301 }
302 }
303 }
304 }
305
306 *ts << "</table>" << endl;
307}
308
309void HtmlExport::createEvent ( QTextStream *ts, Event *event,
310 QDate date, bool withDescription )
311{
312 kDebug() << event->summary();
313 *ts << " <tr>" << endl;
314
315 if ( !event->allDay() ) {
316 if ( event->isMultiDay( d->mCalendar->timeSpec() ) && ( event->dtStart().date() != date ) ) {
317 *ts << " <td>&nbsp;</td>" << endl;
318 } else {
319 *ts << " <td valign=\"top\">"
320 << IncidenceFormatter::timeToString( event->dtStart(), true, d->mCalendar->timeSpec() )
321 << "</td>" << endl;
322 }
323 if ( event->isMultiDay( d->mCalendar->timeSpec() ) && ( event->dtEnd().date() != date ) ) {
324 *ts << " <td>&nbsp;</td>" << endl;
325 } else {
326 *ts << " <td valign=\"top\">"
327 << IncidenceFormatter::timeToString( event->dtEnd(), true, d->mCalendar->timeSpec() )
328 << "</td>" << endl;
329 }
330 } else {
331 *ts << " <td>&nbsp;</td><td>&nbsp;</td>" << endl;
332 }
333
334 *ts << " <td class=\"sum\">" << endl;
335 *ts << " <b>" << cleanChars( event->summary() ) << "</b>" << endl;
336 if ( withDescription && !event->description().isEmpty() ) {
337 *ts << " <p>" << breakString( cleanChars( event->description() ) ) << "</p>" << endl;
338 }
339 *ts << " </td>" << endl;
340
341 if ( d->mSettings->eventLocation() ) {
342 *ts << " <td>" << endl;
343 formatLocation( ts, event );
344 *ts << " </td>" << endl;
345 }
346
347 if ( d->mSettings->eventCategories() ) {
348 *ts << " <td>" << endl;
349 formatCategories( ts, event );
350 *ts << " </td>" << endl;
351 }
352
353 if ( d->mSettings->eventAttendees() ) {
354 *ts << " <td>" << endl;
355 formatAttendees( ts, event );
356 *ts << " </td>" << endl;
357 }
358
359 *ts << " </tr>" << endl;
360}
361
362void HtmlExport::createTodoList ( QTextStream *ts )
363{
364 Todo::List rawTodoList = d->mCalendar->todos();
365
366 int index = 0;
367 while ( index < rawTodoList.count() ) {
368 Todo *ev = rawTodoList[ index ];
369 Todo *subev = ev;
370 if ( ev->relatedTo() ) {
371 if ( ev->relatedTo()->type() == "Todo" ) {
372 if ( !rawTodoList.contains( static_cast<Todo *>( ev->relatedTo() ) ) ) {
373 rawTodoList.append( static_cast<Todo *>( ev->relatedTo() ) );
374 }
375 }
376 }
377 index = rawTodoList.indexOf( subev );
378 ++index;
379 }
380
381 // FIXME: Sort list by priorities. This is brute force and should be
382 // replaced by a real sorting algorithm.
383 Todo::List todoList;
384 Todo::List::ConstIterator it;
385 for ( int i = 1; i <= 9; ++i ) {
386 for ( it = rawTodoList.constBegin(); it != rawTodoList.constEnd(); ++it ) {
387 if ( (*it)->priority() == i && checkSecrecy( *it ) ) {
388 todoList.append( *it );
389 }
390 }
391 }
392 for ( it = rawTodoList.constBegin(); it != rawTodoList.constEnd(); ++it ) {
393 if ( (*it)->priority() == 0 && checkSecrecy( *it ) ) {
394 todoList.append( *it );
395 }
396 }
397
398 int columns = 3;
399 *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">" << endl;
400 *ts << " <tr>" << endl;
401 *ts << " <th class=\"sum\">" << i18nc( "@title:column", "To-do" ) << "</th>" << endl;
402 *ts << " <th>" << i18nc( "@title:column to-do priority", "Priority" ) << "</th>" << endl;
403 *ts << " <th>" << i18nc( "@title:column to-do percent completed",
404 "Completed" ) << "</th>" << endl;
405 if ( d->mSettings->taskDueDate() ) {
406 *ts << " <th>" << i18nc( "@title:column to-do due date", "Due Date" ) << "</th>" << endl;
407 ++columns;
408 }
409 if ( d->mSettings->taskLocation() ) {
410 *ts << " <th>" << i18nc( "@title:column to-do location", "Location" ) << "</th>" << endl;
411 ++columns;
412 }
413 if ( d->mSettings->taskCategories() ) {
414 *ts << " <th>" << i18nc( "@title:column to-do categories", "Categories" ) << "</th>" << endl;
415 ++columns;
416 }
417 if ( d->mSettings->taskAttendees() ) {
418 *ts << " <th>" << i18nc( "@title:column to-do attendees", "Attendees" ) << "</th>" << endl;
419 ++columns;
420 }
421 *ts << " </tr>" << endl;
422
423 // Create top-level list.
424 for ( it = todoList.constBegin(); it != todoList.constEnd(); ++it ) {
425 if ( !(*it)->relatedTo() ) {
426 createTodo( ts, *it );
427 }
428 }
429
430 // Create sub-level lists
431 for ( it = todoList.constBegin(); it != todoList.constEnd(); ++it ) {
432 Incidence::List relations = (*it)->relations();
433 if ( relations.count() ) {
434 // Generate sub-to-do list
435 *ts << " <tr>" << endl;
436 *ts << " <td class=\"subhead\" colspan=";
437 *ts << "\"" << QString::number(columns) << "\"";
438 *ts << "><a name=\"sub" << (*it)->uid() << "\"></a>"
439 << i18nc( "@title:column sub-to-dos of the parent to-do",
440 "Sub-To-dos of: " ) << "<a href=\"#"
441 << (*it)->uid() << "\"><b>" << cleanChars( (*it)->summary() )
442 << "</b></a></td>" << endl;
443 *ts << " </tr>" << endl;
444
445 Todo::List sortedList;
446 // FIXME: Sort list by priorities. This is brute force and should be
447 // replaced by a real sorting algorithm.
448 for ( int i = 1; i <= 9; ++i ) {
449 Incidence::List::ConstIterator it2;
450 for ( it2 = relations.constBegin(); it2 != relations.constEnd(); ++it2 ) {
451 Todo *ev3 = dynamic_cast<Todo *>( *it2 );
452 if ( ev3 && ev3->priority() == i ) {
453 sortedList.append( ev3 );
454 }
455 }
456 }
457 Incidence::List::ConstIterator it2;
458 for ( it2 = relations.constBegin(); it2 != relations.constEnd(); ++it2 ) {
459 Todo *ev3 = dynamic_cast<Todo *>( *it2 );
460 if ( ev3 && ev3->priority() == 0 ) {
461 sortedList.append( ev3 );
462 }
463 }
464
465 Todo::List::ConstIterator it3;
466 for ( it3 = sortedList.constBegin(); it3 != sortedList.constEnd(); ++it3 ) {
467 createTodo( ts, *it3 );
468 }
469 }
470 }
471
472 *ts << "</table>" << endl;
473}
474
475void HtmlExport::createTodo( QTextStream *ts, Todo *todo )
476{
477 kDebug();
478
479 bool completed = todo->isCompleted();
480 Incidence::List relations = todo->relations();
481
482 *ts << "<tr>" << endl;
483
484 *ts << " <td class=\"sum";
485 if (completed) *ts << "done";
486 *ts << "\">" << endl;
487 *ts << " <a name=\"" << todo->uid() << "\"></a>" << endl;
488 *ts << " <b>" << cleanChars( todo->summary() ) << "</b>" << endl;
489 if ( !todo->description().isEmpty() ) {
490 *ts << " <p>" << breakString( cleanChars( todo->description() ) ) << "</p>" << endl;
491 }
492 if ( relations.count() ) {
493 *ts << " <div align=\"right\"><a href=\"#sub" << todo->uid()
494 << "\">" << i18nc( "@title:column sub-to-dos of the parent to-do",
495 "Sub-To-dos" ) << "</a></div>" << endl;
496 }
497 *ts << " </td>" << endl;
498
499 *ts << " <td";
500 if ( completed ) {
501 *ts << " class=\"done\"";
502 }
503 *ts << ">" << endl;
504 *ts << " " << todo->priority() << endl;
505 *ts << " </td>" << endl;
506
507 *ts << " <td";
508 if ( completed ) {
509 *ts << " class=\"done\"";
510 }
511 *ts << ">" << endl;
512 *ts << " " << i18nc( "@info/plain to-do percent complete",
513 "%1 %", todo->percentComplete() ) << endl;
514 *ts << " </td>" << endl;
515
516 if ( d->mSettings->taskDueDate() ) {
517 *ts << " <td";
518 if ( completed ) {
519 *ts << " class=\"done\"";
520 }
521 *ts << ">" << endl;
522 if ( todo->hasDueDate() ) {
523 *ts << " " << IncidenceFormatter::dateToString( todo->dtDue( true ) ) << endl;
524 } else {
525 *ts << " &nbsp;" << endl;
526 }
527 *ts << " </td>" << endl;
528 }
529
530 if ( d->mSettings->taskLocation() ) {
531 *ts << " <td";
532 if ( completed ) {
533 *ts << " class=\"done\"";
534 }
535 *ts << ">" << endl;
536 formatLocation( ts, todo );
537 *ts << " </td>" << endl;
538 }
539
540 if ( d->mSettings->taskCategories() ) {
541 *ts << " <td";
542 if ( completed ) {
543 *ts << " class=\"done\"";
544 }
545 *ts << ">" << endl;
546 formatCategories( ts, todo );
547 *ts << " </td>" << endl;
548 }
549
550 if ( d->mSettings->taskAttendees() ) {
551 *ts << " <td";
552 if ( completed ) {
553 *ts << " class=\"done\"";
554 }
555 *ts << ">" << endl;
556 formatAttendees( ts, todo );
557 *ts << " </td>" << endl;
558 }
559
560 *ts << "</tr>" << endl;
561}
562
563void HtmlExport::createWeekView( QTextStream *ts )
564{
565 Q_UNUSED( ts );
566 // FIXME: Implement this!
567}
568
569void HtmlExport::createJournalView( QTextStream *ts )
570{
571 Q_UNUSED( ts );
572// Journal::List rawJournalList = d->mCalendar->journals();
573 // FIXME: Implement this!
574}
575
576void HtmlExport::createFreeBusyView( QTextStream *ts )
577{
578 Q_UNUSED( ts );
579 // FIXME: Implement this!
580}
581
582bool HtmlExport::checkSecrecy( Incidence *incidence )
583{
584 int secrecy = incidence->secrecy();
585 if ( secrecy == Incidence::SecrecyPublic ) {
586 return true;
587 }
588 if ( secrecy == Incidence::SecrecyPrivate && !d->mSettings->excludePrivate() ) {
589 return true;
590 }
591 if ( secrecy == Incidence::SecrecyConfidential &&
592 !d->mSettings->excludeConfidential() ) {
593 return true;
594 }
595 return false;
596}
597
598void HtmlExport::formatLocation( QTextStream *ts, Incidence *incidence )
599{
600 if ( !incidence->location().isEmpty() ) {
601 *ts << " " << cleanChars( incidence->location() ) << endl;
602 } else {
603 *ts << " &nbsp;" << endl;
604 }
605}
606
607void HtmlExport::formatCategories( QTextStream *ts, Incidence *incidence )
608{
609 if ( !incidence->categoriesStr().isEmpty() ) {
610 *ts << " " << cleanChars( incidence->categoriesStr() ) << endl;
611 } else {
612 *ts << " &nbsp;" << endl;
613 }
614}
615
616void HtmlExport::formatAttendees( QTextStream *ts, Incidence *incidence )
617{
618 Attendee::List attendees = incidence->attendees();
619 if ( attendees.count() ) {
620 *ts << "<em>";
621#if !defined(KORG_NOKABC) && !defined(KDEPIM_NO_KRESOURCES)
622 KABC::AddressBook *add_book = KABC::StdAddressBook::self( true );
623 KABC::Addressee::List addressList;
624 addressList = add_book->findByEmail( incidence->organizer().email() );
625 if ( !addressList.isEmpty() ) {
626 KABC::Addressee o = addressList.first();
627 if ( !o.isEmpty() && addressList.size() < 2 ) {
628 *ts << "<a href=\"mailto:" << incidence->organizer().email() << "\">";
629 *ts << cleanChars( o.formattedName() ) << "</a>" << endl;
630 } else {
631 *ts << incidence->organizer().fullName();
632 }
633 }
634#else
635 *ts << incidence->organizer().fullName();
636#endif
637 *ts << "</em><br />";
638 Attendee::List::ConstIterator it;
639 for ( it = attendees.constBegin(); it != attendees.constEnd(); ++it ) {
640 Attendee *a = *it;
641 if ( !a->email().isEmpty() ) {
642 *ts << "<a href=\"mailto:" << a->email();
643 *ts << "\">" << cleanChars( a->name() ) << "</a>";
644 } else {
645 *ts << " " << cleanChars( a->name() );
646 }
647 *ts << "<br />" << endl;
648 }
649 } else {
650 *ts << " &nbsp;" << endl;
651 }
652}
653
654QString HtmlExport::breakString( const QString &text )
655{
656 int number = text.count( "\n" );
657 if ( number <= 0 ) {
658 return text;
659 } else {
660 QString out;
661 QString tmpText = text;
662 int pos = 0;
663 QString tmp;
664 for ( int i = 0; i <= number; ++i ) {
665 pos = tmpText.indexOf( "\n" );
666 tmp = tmpText.left( pos );
667 tmpText = tmpText.right( tmpText.length() - pos - 1 );
668 out += tmp + "<br />";
669 }
670 return out;
671 }
672}
673
674void HtmlExport::createFooter( QTextStream *ts )
675{
676 // FIXME: Implement this in a translatable way!
677 QString trailer = i18nc( "@info/plain", "This page was created " );
678
679/* bool hasPerson = false;
680 bool hasCredit = false;
681 bool hasCreditURL = false;
682 QString mail, name, credit, creditURL;*/
683 if ( !d->mSettings->eMail().isEmpty() ) {
684 if ( !d->mSettings->name().isEmpty() ) {
685 trailer += i18nc( "@info/plain page creator email link with name",
686 "by <link url='mailto:%1'>%2</link> ",
687 d->mSettings->eMail(), d->mSettings->name() );
688 } else {
689 trailer += i18nc( "@info/plain page creator email link",
690 "by <link url='mailto:%1'>%2</link> ",
691 d->mSettings->eMail(), d->mSettings->eMail() );
692 }
693 } else {
694 if ( !d->mSettings->name().isEmpty() ) {
695 trailer += i18nc( "@info/plain page creator name only",
696 "by %1 ", d->mSettings->name() );
697 }
698 }
699 if ( !d->mSettings->creditName().isEmpty() ) {
700 if ( !d->mSettings->creditURL().isEmpty() ) {
701 trailer += i18nc( "@info/plain page credit with name and link",
702 "with <link url='%1'>%2</link>",
703 d->mSettings->creditURL(), d->mSettings->creditName() );
704 } else {
705 trailer += i18nc( "@info/plain page credit name only",
706 "with %1", d->mSettings->creditName() );
707 }
708 }
709 *ts << "<p>" << trailer << "</p>" << endl;
710}
711
712QString cleanChars( const QString &text )
713{
714 QString txt = text;
715 txt = txt.replace( '&', "&amp;" );
716 txt = txt.replace( '<', "&lt;" );
717 txt = txt.replace( '>', "&gt;" );
718 txt = txt.replace( '\"', "&quot;" );
719 txt = txt.replace( QString::fromUtf8( "ä" ), "&auml;" );
720 txt = txt.replace( QString::fromUtf8( "Ä" ), "&Auml;" );
721 txt = txt.replace( QString::fromUtf8( "ö" ), "&ouml;" );
722 txt = txt.replace( QString::fromUtf8( "Ö" ), "&Ouml;" );
723 txt = txt.replace( QString::fromUtf8( "ü" ), "&uuml;" );
724 txt = txt.replace( QString::fromUtf8( "Ü" ), "&Uuml;" );
725 txt = txt.replace( QString::fromUtf8( "ß" ), "&szlig;" );
726 txt = txt.replace( QString::fromUtf8( "€" ), "&euro;" );
727 txt = txt.replace( QString::fromUtf8( "é" ), "&eacute;" );
728
729 return txt;
730}
731
732QString HtmlExport::styleSheet() const
733{
734 if ( !d->mSettings->styleSheet().isEmpty() ) {
735 return d->mSettings->styleSheet();
736 }
737
738 QString css;
739
740 if ( QApplication::isRightToLeft() ) {
741 css += " body { background-color:white; color:black; direction: rtl }\n";
742 css += " td { text-align:center; background-color:#eee }\n";
743 css += " th { text-align:center; background-color:#228; color:white }\n";
744 css += " td.sumdone { background-color:#ccc }\n";
745 css += " td.done { background-color:#ccc }\n";
746 css += " td.subhead { text-align:center; background-color:#ccf }\n";
747 css += " td.datehead { text-align:center; background-color:#ccf }\n";
748 css += " td.space { background-color:white }\n";
749 css += " td.dateholiday { color:red }\n";
750 } else {
751 css += " body { background-color:white; color:black }\n";
752 css += " td { text-align:center; background-color:#eee }\n";
753 css += " th { text-align:center; background-color:#228; color:white }\n";
754 css += " td.sum { text-align:left }\n";
755 css += " td.sumdone { text-align:left; background-color:#ccc }\n";
756 css += " td.done { background-color:#ccc }\n";
757 css += " td.subhead { text-align:center; background-color:#ccf }\n";
758 css += " td.datehead { text-align:center; background-color:#ccf }\n";
759 css += " td.space { background-color:white }\n";
760 css += " td.date { text-align:left }\n";
761 css += " td.dateholiday { text-align:left; color:red }\n";
762 }
763
764 return css;
765}
766
767void HtmlExport::addHoliday( const QDate &date, const QString &name )
768{
769 if ( d->mHolidayMap[date].isEmpty() ) {
770 d->mHolidayMap[date] = name;
771 } else {
772 d->mHolidayMap[date] = i18nc( "@info/plain holiday by date and name",
773 "%1, %2", d->mHolidayMap[date], name );
774 }
775}
776
777QDate HtmlExport::fromDate() const
778{
779 return d->mSettings->dateStart().date();
780}
781
782QDate HtmlExport::toDate() const
783{
784 return d->mSettings->dateEnd().date();
785}
calendar.h
This file is part of the API for handling calendar data and defines the Calendar class.
KCal::Attendee
Represents information related to an attendee of an Calendar Incidence, typically a meeting or task (...
Definition: attendee.h:59
KCal::Attendee::email
QString email() const
Returns the email address for this person.
Definition: person.cpp:144
KCal::Attendee::name
QString name() const
Returns the person name string.
Definition: person.cpp:139
KCal::Calendar
Represents the main calendar class.
Definition: calendar.h:121
KCal::Event
This class provides an Event in the sense of RFC2445.
Definition: event.h:42
KCal::Event::isMultiDay
bool isMultiDay(const KDateTime::Spec &spec=KDateTime::Spec()) const
Returns true if the event spans multiple days, otherwise return false.
Definition: event.cpp:231
KCal::Event::dtEnd
virtual KDateTime dtEnd() const
Returns the event end date and time.
Definition: event.cpp:132
KCal::HtmlExport::save
bool save(const QString &fileName=QString())
Writes out the calendar in HTML format.
Definition: htmlexport.cpp:74
KCal::HtmlExport::HtmlExport
HtmlExport(Calendar *calendar, HTMLExportSettings *settings)
Create new HTML exporter for calendar.
Definition: htmlexport.cpp:64
KCal::IncidenceBase::allDay
bool allDay() const
Returns true or false depending on whether the incidence is all-day.
Definition: incidencebase.cpp:310
KCal::IncidenceBase::type
virtual QByteArray type() const =0
Prints the type of Incidence as a string.
KCal::IncidenceBase::dtStart
virtual KDateTime dtStart() const
Returns an incidence's starting date/time as a KDateTime.
Definition: incidencebase.cpp:248
KCal::IncidenceBase::attendees
const Attendee::List & attendees() const
Returns a list of incidence attendees.
Definition: incidencebase.cpp:378
KCal::IncidenceBase::organizer
Person organizer() const
Returns the Person associated with this incidence.
Definition: incidencebase.cpp:230
KCal::IncidenceBase::uid
QString uid() const
Returns the unique id (uid) for the incidence.
Definition: incidencebase.cpp:184
KCal::Incidence
Provides the abstract base class common to non-FreeBusy (Events, To-dos, Journals) calendar component...
Definition: incidence.h:70
KCal::Incidence::categoriesStr
QString categoriesStr() const
Returns the incidence categories as a comma separated string.
Definition: incidence.cpp:478
KCal::Incidence::relatedTo
Incidence * relatedTo() const
Returns a pointer for the incidence that is related to this one.
Definition: incidence.cpp:516
KCal::Incidence::description
QString description() const
Returns the incidence description.
Definition: incidence.cpp:390
KCal::Incidence::priority
int priority() const
Returns the incidence priority.
Definition: incidence.cpp:795
KCal::Incidence::SecrecyPrivate
@ SecrecyPrivate
Secret to the owner.
Definition: incidence.h:164
KCal::Incidence::SecrecyConfidential
@ SecrecyConfidential
Secret to the owner and some others.
Definition: incidence.h:165
KCal::Incidence::SecrecyPublic
@ SecrecyPublic
Not secret (default)
Definition: incidence.h:163
KCal::Incidence::relations
Incidence::List relations() const
Returns a list of all incidences related to this one.
Definition: incidence.cpp:521
KCal::Incidence::summary
QString summary() const
Returns the incidence summary.
Definition: incidence.cpp:424
KCal::Incidence::secrecy
Secrecy secrecy() const
Returns the incidence Secrecy.
Definition: incidence.cpp:872
KCal::Incidence::location
QString location() const
Returns the incidence location.
Definition: incidence.cpp:962
KCal::ListBase
This class provides a template for lists of pointers.
Definition: listbase.h:45
KCal::Person::email
QString email() const
Returns the email address for this person.
Definition: person.cpp:144
KCal::Person::fullName
QString fullName() const
Returns the full name of this person.
Definition: person.cpp:114
KCal::Todo
Provides a To-do in the sense of RFC2445.
Definition: todo.h:45
KCal::Todo::dtDue
KDateTime dtDue(bool first=false) const
Returns due date and time.
Definition: todo.cpp:181
KCal::Todo::hasDueDate
bool hasDueDate() const
Returns true if the todo has a due date, otherwise return false.
Definition: todo.cpp:252
KCal::Todo::isCompleted
bool isCompleted() const
Returns true if the todo is 100% completed, otherwise return false.
Definition: todo.cpp:411
KCal::Todo::percentComplete
int percentComplete() const
Returns what percentage of the to-do is completed.
Definition: todo.cpp:463
event.h
This file is part of the API for handling calendar data and defines the Event class.
incidenceformatter.h
This file is part of the API for handling calendar data and provides static functions for formatting ...
KCal::IncidenceFormatter::timeToString
KCAL_DEPRECATED_EXPORT QString timeToString(const KDateTime &date, bool shortfmt=true, const KDateTime::Spec &spec=KDateTime::Spec())
Build a QString time representation of a KDateTime object.
Definition: incidenceformatter.cpp:3720
KCal::IncidenceFormatter::dateToString
KCAL_DEPRECATED_EXPORT QString dateToString(const KDateTime &date, bool shortfmt=true, const KDateTime::Spec &spec=KDateTime::Spec())
Build a QString date representation of a KDateTime object.
Definition: incidenceformatter.cpp:3737
todo.h
This file is part of the API for handling calendar data and defines the Todo class.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jul 21 2022 00:00:00 by doxygen 1.9.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCal Library

Skip menu "KCal Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal