libkcal

htmlexport.cpp
1/*
2 This file is part of libkcal.
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 <tqapplication.h>
24#include <tqfile.h>
25#include <tqtextstream.h>
26#include <tqtextcodec.h>
27#include <tqregexp.h>
28
29#include <kcharsets.h>
30#include <tdeglobal.h>
31#include <tdelocale.h>
32#include <kdebug.h>
33#include <kcalendarsystem.h>
34
35#include <libkcal/calendar.h>
36#include <libkcal/event.h>
37#include <libkcal/incidenceformatter.h>
38#include <libkcal/todo.h>
39
40#ifndef KORG_NOKABC
41 #include <tdeabc/stdaddressbook.h>
42#endif
43#include "htmlexport.h"
44#include "htmlexportsettings.h"
45
46using namespace KCal;
47
48HtmlExport::HtmlExport( Calendar *calendar, HTMLExportSettings *settings ) :
49 mCalendar( calendar ), mSettings( settings )
50{
51}
52
53bool HtmlExport::save( const TQString &fileName )
54{
55 TQString fn( fileName );
56 if ( fn.isEmpty() && mSettings ) {
57 fn = mSettings->outputFile();
58 }
59 if ( !mSettings || fn.isEmpty() ) {
60 return false;
61 }
62 TQFile f( fileName );
63 if ( !f.open(IO_WriteOnly)) {
64 return false;
65 }
66 TQTextStream ts(&f);
67 bool success = save(&ts);
68 f.close();
69 return success;
70}
71
72bool HtmlExport::save(TQTextStream *ts)
73{
74 if ( !mSettings ) return false;
75 ts->setEncoding( TQTextStream::UnicodeUTF8 );
76
77 // Write HTML header
78 *ts << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" ";
79 *ts << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
80
81 *ts << "<html><head>" << endl;
82 *ts << " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=";
83 *ts << "UTF-8\" />\n";
84 if ( !mSettings->pageTitle().isEmpty())
85 *ts << " <title>" << mSettings->pageTitle() << "</title>\n";
86 *ts << " <style type=\"text/css\">\n";
87 *ts << styleSheet();
88 *ts << " </style>\n";
89 *ts << "</head><body>\n";
90
91 // FIXME: Write header
92 // (Heading, Calendar-Owner, Calendar-Date, ...)
93
94 if ( mSettings->eventView() || mSettings->monthView() || mSettings->weekView() ) {
95 if (!mSettings->eventTitle().isEmpty())
96 *ts << "<h1>" << mSettings->eventTitle() << "</h1>\n";
97
98 // Write Week View
99 if ( mSettings->weekView() )
100 createWeekView( ts );
101 // Write Month View
102 if ( mSettings->monthView() )
103 createMonthView( ts );
104 // Write Event List
105 if ( mSettings->eventView() )
106 createEventList( ts );
107 }
108
109 // Write Todo List
110 if ( mSettings->todoView() ) {
111 if ( !mSettings->todoListTitle().isEmpty())
112 *ts << "<h1>" << mSettings->todoListTitle() << "</h1>\n";
113 createTodoList(ts);
114 }
115
116 // Write Journals
117 if ( mSettings->journalView() ) {
118 if ( !mSettings->journalTitle().isEmpty())
119 *ts << "<h1>" << mSettings->journalTitle() << "</h1>\n";
120 createJournalView(ts);
121 }
122
123 // Write Free/Busy
124 if ( mSettings->freeBusyView() ) {
125 if ( !mSettings->freeBusyTitle().isEmpty())
126 *ts << "<h1>" << mSettings->freeBusyTitle() << "</h1>\n";
127 createFreeBusyView(ts);
128 }
129
130 createFooter( ts );
131
132 // Write HTML trailer
133 *ts << "</body></html>\n";
134
135 return true;
136}
137
138void HtmlExport::createMonthView(TQTextStream *ts)
139{
140 TQDate start = fromDate();
141 start.setYMD( start.year(), start.month(), 1 ); // go back to first day in month
142
143 TQDate end( start.year(), start.month(), start.daysInMonth() );
144
145 int startmonth = start.month();
146 int startyear = start.year();
147
148 while ( start < toDate() ) {
149 // Write header
150 *ts << "<h2>" << (i18n("month_year","%1 %2").arg(TDEGlobal::locale()->calendar()->monthName(start))
151 .arg(start.year())) << "</h2>\n";
152 if ( TDEGlobal::locale()->weekStartDay() == 1 ) {
153 start = start.addDays(1 - start.dayOfWeek());
154 } else {
155 if (start.dayOfWeek() != 7) {
156 start = start.addDays(-start.dayOfWeek());
157 }
158 }
159 *ts << "<table border=\"1\">\n";
160
161 // Write table header
162 *ts << " <tr>";
163 for(int i=0; i<7; ++i) {
164 *ts << "<th>" << TDEGlobal::locale()->calendar()->weekDayName( start.addDays(i) ) << "</th>";
165 }
166 *ts << "</tr>\n";
167
168 // Write days
169 while (start <= end) {
170 *ts << " <tr>\n";
171 for(int i=0;i<7;++i) {
172 *ts << " <td valign=\"top\"><table border=\"0\">";
173
174 *ts << "<tr><td ";
175 if (mHolidayMap.contains(start) || start.dayOfWeek() == 7) {
176 *ts << "class=\"dateholiday\"";
177 } else {
178 *ts << "class=\"date\"";
179 }
180 *ts << ">" << TQString::number(start.day());
181
182 if (mHolidayMap.contains(start)) {
183 *ts << " <em>" << mHolidayMap[start] << "</em>";
184 }
185
186 *ts << "</td></tr><tr><td valign=\"top\">";
187
188 // Only print events within the from-to range
189 if ( start >= fromDate() && start <= toDate() ) {
190 Event::List events = mCalendar->events( start,
193 if (events.count()) {
194 *ts << "<table>";
195 Event::List::ConstIterator it;
196 for( it = events.begin(); it != events.end(); ++it ) {
197 if ( checkSecrecy( *it ) ) {
198 createEvent( ts, *it, start, false );
199 }
200 }
201 *ts << "</table>";
202 } else {
203 *ts << "&nbsp;";
204 }
205 }
206
207 *ts << "</td></tr></table></td>\n";
208 start = start.addDays(1);
209 }
210 *ts << " </tr>\n";
211 }
212 *ts << "</table>\n";
213 startmonth += 1;
214 if ( startmonth > 12 ) {
215 startyear += 1;
216 startmonth = 1;
217 }
218 start.setYMD( startyear, startmonth, 1 );
219 end.setYMD(start.year(),start.month(),start.daysInMonth());
220 }
221}
222
223void HtmlExport::createEventList (TQTextStream *ts)
224{
225 int columns = 3;
226 *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">\n";
227 *ts << " <tr>\n";
228 *ts << " <th class=\"sum\">" << i18n("Start Time") << "</th>\n";
229 *ts << " <th>" << i18n("End Time") << "</th>\n";
230 *ts << " <th>" << i18n("Event") << "</th>\n";
231 if ( mSettings->eventLocation() ) {
232 *ts << " <th>" << i18n("Location") << "</th>\n";
233 ++columns;
234 }
235 if ( mSettings->eventCategories() ) {
236 *ts << " <th>" << i18n("Categories") << "</th>\n";
237 ++columns;
238 }
239 if ( mSettings->eventAttendees() ) {
240 *ts << " <th>" << i18n("Attendees") << "</th>\n";
241 ++columns;
242 }
243
244 *ts << " </tr>\n";
245
246 for ( TQDate dt = fromDate(); dt <= toDate(); dt = dt.addDays(1) ) {
247 kdDebug(5850) << "Getting events for " << TQString(dt.toString()) << endl;
248 Event::List events = mCalendar->events(dt,
251 if (events.count()) {
252 Event::List::ConstIterator it;
253 bool first = true;
254 for( it = events.begin(); it != events.end(); ++it ) {
255 if ( checkSecrecy( *it ) ) {
256 if ( first ) {
257 *ts << " <tr><td colspan=\"" << TQString::number(columns)
258 << "\" class=\"datehead\"><i>"
259 << TDEGlobal::locale()->formatDate(dt)
260 << "</i></td></tr>\n";
261 first = false;
262 }
263 createEvent( ts, *it, dt );
264 }
265 }
266 }
267 }
268
269 *ts << "</table>\n";
270}
271
272void HtmlExport::createEvent (TQTextStream *ts, Event *event,
273 TQDate date,bool withDescription)
274{
275 kdDebug(5850) << "HtmlExport::createEvent(): " << event->summary() << endl;
276 *ts << " <tr>\n";
277
278 if (!event->doesFloat()) {
279 if (event->isMultiDay() && (event->dtStart().date() != date)) {
280 *ts << " <td>&nbsp;</td>\n";
281 } else {
282 *ts << " <td valign=\"top\">"
283 << IncidenceFormatter::timeToString( event->dtStart(), true )
284 << "</td>\n";
285 }
286 if (event->isMultiDay() && (event->dtEnd().date() != date)) {
287 *ts << " <td>&nbsp;</td>\n";
288 } else {
289 *ts << " <td valign=\"top\">"
290 << IncidenceFormatter::timeToString( event->dtEnd(), true )
291 << "</td>\n";
292 }
293 } else {
294 *ts << " <td>&nbsp;</td><td>&nbsp;</td>\n";
295 }
296
297 *ts << " <td class=\"sum\">\n";
298 *ts << " <b>" << cleanChars(event->summary()) << "</b>\n";
299 if ( withDescription && !event->description().isEmpty() ) {
300 *ts << " <p>" << breakString( cleanChars( event->description() ) ) << "</p>\n";
301 }
302 *ts << " </td>\n";
303
304 if ( mSettings->eventLocation() ) {
305 *ts << " <td>\n";
306 formatLocation( ts, event );
307 *ts << " </td>\n";
308 }
309
310 if ( mSettings->eventCategories() ) {
311 *ts << " <td>\n";
312 formatCategories( ts, event );
313 *ts << " </td>\n";
314 }
315
316 if ( mSettings->eventAttendees() ) {
317 *ts << " <td>\n";
318 formatAttendees( ts, event );
319 *ts << " </td>\n";
320 }
321
322 *ts << " </tr>\n";
323}
324
325void HtmlExport::createTodoList ( TQTextStream *ts )
326{
327 Todo::List rawTodoList = mCalendar->todos();
328
329 Todo::List::Iterator it = rawTodoList.begin();
330 while ( it != rawTodoList.end() ) {
331 Todo *ev = *it;
332 Todo *subev = ev;
333 if ( ev->relatedTo() ) {
334 if ( ev->relatedTo()->type()=="Todo" ) {
335 if ( rawTodoList.find( static_cast<Todo *>( ev->relatedTo() ) ) ==
336 rawTodoList.end() ) {
337 rawTodoList.append( static_cast<Todo *>( ev->relatedTo() ) );
338 }
339 }
340 }
341 it = rawTodoList.find( subev );
342 ++it;
343 }
344
345 // FIXME: Sort list by priorities. This is brute force and should be
346 // replaced by a real sorting algorithm.
347 Todo::List todoList;
348 for ( int i = 1; i <= 9; ++i ) {
349 for( it = rawTodoList.begin(); it != rawTodoList.end(); ++it ) {
350 if ( (*it)->priority() == i && checkSecrecy( *it ) ) {
351 todoList.append( *it );
352 }
353 }
354 }
355 for( it = rawTodoList.begin(); it != rawTodoList.end(); ++it ) {
356 if ( (*it)->priority() == 0 && checkSecrecy( *it ) ) {
357 todoList.append( *it );
358 }
359 }
360
361 int columns = 3;
362 *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">\n";
363 *ts << " <tr>\n";
364 *ts << " <th class=\"sum\">" << i18n("Task") << "</th>\n";
365 *ts << " <th>" << i18n("Priority") << "</th>\n";
366 *ts << " <th>" << i18n("Completed") << "</th>\n";
367 if ( mSettings->taskDueDate() ) {
368 *ts << " <th>" << i18n("Due Date") << "</th>\n";
369 ++columns;
370 }
371 if ( mSettings->taskLocation() ) {
372 *ts << " <th>" << i18n("Location") << "</th>\n";
373 ++columns;
374 }
375 if ( mSettings->taskCategories() ) {
376 *ts << " <th>" << i18n("Categories") << "</th>\n";
377 ++columns;
378 }
379 if ( mSettings->taskAttendees() ) {
380 *ts << " <th>" << i18n("Attendees") << "</th>\n";
381 ++columns;
382 }
383 *ts << " </tr>\n";
384
385 // Create top-level list.
386 for( it = todoList.begin(); it != todoList.end(); ++it ) {
387 if ( !(*it)->relatedTo() ) createTodo( ts, *it );
388 }
389
390 // Create sub-level lists
391 for( it = todoList.begin(); it != todoList.end(); ++it ) {
392 Incidence::List relations = (*it)->relations();
393 if (relations.count()) {
394 // Generate sub-task list of event ev
395 *ts << " <tr>\n";
396 *ts << " <td class=\"subhead\" colspan=";
397 *ts << "\"" << TQString::number(columns) << "\"";
398 *ts << "><a name=\"sub" << (*it)->uid() << "\"></a>"
399 << i18n("Sub-Tasks of: ") << "<a href=\"#"
400 << (*it)->uid() << "\"><b>" << cleanChars( (*it)->summary())
401 << "</b></a></td>\n";
402 *ts << " </tr>\n";
403
404 Todo::List sortedList;
405 // FIXME: Sort list by priorities. This is brute force and should be
406 // replaced by a real sorting algorithm.
407 for ( int i = 1; i <= 9; ++i ) {
408 Incidence::List::ConstIterator it2;
409 for( it2 = relations.begin(); it2 != relations.end(); ++it2 ) {
410 Todo *ev3 = dynamic_cast<Todo *>( *it2 );
411 if ( ev3 && ev3->priority() == i ) sortedList.append( ev3 );
412 }
413 }
414 Incidence::List::ConstIterator it2;
415 for( it2 = relations.begin(); it2 != relations.end(); ++it2 ) {
416 Todo *ev3 = dynamic_cast<Todo *>( *it2 );
417 if ( ev3 && ev3->priority() == 0 ) sortedList.append( ev3 );
418 }
419
420 Todo::List::ConstIterator it3;
421 for( it3 = sortedList.begin(); it3 != sortedList.end(); ++it3 ) {
422 createTodo( ts, *it3 );
423 }
424 }
425 }
426
427 *ts << "</table>\n";
428}
429
430void HtmlExport::createTodo (TQTextStream *ts,Todo *todo)
431{
432 kdDebug(5850) << "HtmlExport::createTodo()" << endl;
433
434 bool completed = todo->isCompleted();
435 Incidence::List relations = todo->relations();
436
437 *ts << "<tr>\n";
438
439 *ts << " <td class=\"sum";
440 if (completed) *ts << "done";
441 *ts << "\">\n";
442 *ts << " <a name=\"" << todo->uid() << "\"></a>\n";
443 *ts << " <b>" << cleanChars(todo->summary()) << "</b>\n";
444 if (!todo->description().isEmpty()) {
445 *ts << " <p>" << breakString(cleanChars(todo->description())) << "</p>\n";
446 }
447 if (relations.count()) {
448 *ts << " <div align=\"right\"><a href=\"#sub" << todo->uid()
449 << "\">" << i18n("Sub-Tasks") << "</a></div>\n";
450 }
451 *ts << " </td>\n";
452
453 *ts << " <td";
454 if (completed) *ts << " class=\"done\"";
455 *ts << ">\n";
456 *ts << " " << todo->priority() << "\n";
457 *ts << " </td>\n";
458
459 *ts << " <td";
460 if (completed) *ts << " class=\"done\"";
461 *ts << ">\n";
462 *ts << " " << i18n("%1 %").arg(todo->percentComplete()) << "\n";
463 *ts << " </td>\n";
464
465 if ( mSettings->taskDueDate() ) {
466 *ts << " <td";
467 if (completed) *ts << " class=\"done\"";
468 *ts << ">\n";
469 if (todo->hasDueDate()) {
470 *ts << " " << IncidenceFormatter::dateToString( todo->dtDue( true ) ) << "\n";
471 } else {
472 *ts << " &nbsp;\n";
473 }
474 *ts << " </td>\n";
475 }
476
477 if ( mSettings->taskLocation() ) {
478 *ts << " <td";
479 if (completed) *ts << " class=\"done\"";
480 *ts << ">\n";
481 formatLocation(ts,todo);
482 *ts << " </td>\n";
483 }
484
485 if ( mSettings->taskCategories() ) {
486 *ts << " <td";
487 if (completed) *ts << " class=\"done\"";
488 *ts << ">\n";
489 formatCategories(ts,todo);
490 *ts << " </td>\n";
491 }
492
493 if ( mSettings->taskAttendees() ) {
494 *ts << " <td";
495 if (completed) *ts << " class=\"done\"";
496 *ts << ">\n";
497 formatAttendees(ts,todo);
498 *ts << " </td>\n";
499 }
500
501 *ts << "</tr>\n";
502}
503
504void HtmlExport::createWeekView( TQTextStream */*ts*/ )
505{
506 // FIXME: Implement this!
507}
508
509void HtmlExport::createJournalView( TQTextStream */*ts*/ )
510{
511// Journal::List rawJournalList = mCalendar->journals();
512 // FIXME: Implement this!
513}
514
515void HtmlExport::createFreeBusyView( TQTextStream */*ts*/ )
516{
517 // FIXME: Implement this!
518}
519
520bool HtmlExport::checkSecrecy( Incidence *incidence )
521{
522 int secrecy = incidence->secrecy();
523 if ( secrecy == Incidence::SecrecyPublic ) {
524 return true;
525 }
526 if ( secrecy == Incidence::SecrecyPrivate && !mSettings->excludePrivate() ) {
527 return true;
528 }
529 if ( secrecy == Incidence::SecrecyConfidential &&
530 !mSettings->excludeConfidential() ) {
531 return true;
532 }
533 return false;
534}
535
536void HtmlExport::formatLocation (TQTextStream *ts,Incidence *event)
537{
538 if (!event->location().isEmpty()) {
539 *ts << " " << cleanChars(event->location()) << "\n";
540 } else {
541 *ts << " &nbsp;\n";
542 }
543}
544
545void HtmlExport::formatCategories (TQTextStream *ts,Incidence *event)
546{
547 if (!event->categoriesStr().isEmpty()) {
548 *ts << " " << cleanChars(event->categoriesStr()) << "\n";
549 } else {
550 *ts << " &nbsp;\n";
551 }
552}
553
554void HtmlExport::formatAttendees( TQTextStream *ts, Incidence *event )
555{
556 Attendee::List attendees = event->attendees();
557 if (attendees.count()) {
558 *ts << "<em>";
559#ifndef KORG_NOKABC
560 TDEABC::AddressBook *add_book = TDEABC::StdAddressBook::self( true );
561 TDEABC::Addressee::List addressList;
562 addressList = add_book->findByEmail(event->organizer().email());
563 TDEABC::Addressee o = addressList.first();
564 if (!o.isEmpty() && addressList.size()<2) {
565 *ts << "<a href=\"mailto:" << event->organizer().email() << "\">";
566 *ts << cleanChars(o.formattedName()) << "</a>\n";
567 }
568 else *ts << event->organizer().fullName();
569#else
570 *ts << event->organizer().fullName();
571#endif
572 *ts << "</em><br />";
573 Attendee::List::ConstIterator it;
574 for( it = attendees.begin(); it != attendees.end(); ++it ) {
575 Attendee *a = *it;
576 if (!a->email().isEmpty()) {
577 *ts << "<a href=\"mailto:" << a->email();
578 *ts << "\">" << cleanChars(a->name()) << "</a>";
579 }
580 else {
581 *ts << " " << cleanChars(a->name());
582 }
583 *ts << "<br />" << "\n";
584 }
585 } else {
586 *ts << " &nbsp;\n";
587 }
588}
589
590TQString HtmlExport::breakString(const TQString &text)
591{
592 int number = text.contains("\n");
593 if(number < 0) {
594 return text;
595 } else {
596 TQString out;
597 TQString tmpText = text;
598 int pos = 0;
599 TQString tmp;
600 for(int i=0;i<=number;i++) {
601 pos = tmpText.find("\n");
602 tmp = tmpText.left(pos);
603 tmpText = tmpText.right(tmpText.length() - pos - 1);
604 out += tmp + "<br />";
605 }
606 return out;
607 }
608}
609
610void HtmlExport::createFooter( TQTextStream *ts )
611{
612 // FIXME: Implement this in a translatable way!
613 TQString trailer = i18n("This page was created ");
614
615/* bool hasPerson = false;
616 bool hasCredit = false;
617 bool hasCreditURL = false;
618 TQString mail, name, credit, creditURL;*/
619 if (!mSettings->eMail().isEmpty()) {
620 if (!mSettings->name().isEmpty())
621 trailer += i18n("by <a href=\"mailto:%1\">%2</a> ").arg( mSettings->eMail() ).arg( mSettings->name() );
622 else
623 trailer += i18n("by <a href=\"mailto:%1\">%2</a> ").arg( mSettings->eMail() ).arg( mSettings->eMail() );
624 } else {
625 if (!mSettings->name().isEmpty())
626 trailer += i18n("by %1 ").arg( mSettings->name() );
627 }
628 if (!mSettings->creditName().isEmpty()) {
629 if (!mSettings->creditURL().isEmpty())
630 trailer += i18n("with <a href=\"%1\">%2</a>")
631 .arg( mSettings->creditURL() )
632 .arg( mSettings->creditName() );
633 else
634 trailer += i18n("with %1").arg( mSettings->creditName() );
635 }
636 *ts << "<p>" << trailer << "</p>\n";
637}
638
639
640TQString HtmlExport::cleanChars(const TQString &text)
641{
642 TQString txt = text;
643 txt = txt.replace( "&", "&amp;" );
644 txt = txt.replace( "<", "&lt;" );
645 txt = txt.replace( ">", "&gt;" );
646 txt = txt.replace( "\"", "&quot;" );
647 txt = txt.replace( TQString::fromUtf8("ä"), "&auml;" );
648 txt = txt.replace( TQString::fromUtf8("á"), "&aacute;" );
649 txt = txt.replace( TQString::fromUtf8("à"), "&agrave;" );
650 txt = txt.replace( TQString::fromUtf8("â"), "&acirc;" );
651 txt = txt.replace( TQString::fromUtf8("Ä"), "&Auml;" );
652 txt = txt.replace( TQString::fromUtf8("ó"), "&oacute;" );
653 txt = txt.replace( TQString::fromUtf8("ô"), "&ocirc;" );
654 txt = txt.replace( TQString::fromUtf8("ö"), "&ouml;" );
655 txt = txt.replace( TQString::fromUtf8("Ö"), "&Ouml;" );
656 txt = txt.replace( TQString::fromUtf8("ü"), "&uuml;" );
657 txt = txt.replace( TQString::fromUtf8("Ü"), "&Uuml;" );
658 txt = txt.replace( TQString::fromUtf8("ß"), "&szlig;" );
659 txt = txt.replace( TQString::fromUtf8("€"), "&euro;" );
660 txt = txt.replace( TQString::fromUtf8("é"), "&eacute;" );
661 txt = txt.replace( TQString::fromUtf8("ë"), "&euml;" );
662 txt = txt.replace( TQString::fromUtf8("è"), "&egrave;" );
663 txt = txt.replace( TQString::fromUtf8("ñ"), "&ntilde;" );
664 txt = txt.replace( TQString::fromUtf8("ç"), "&ccedil;" );
665
666 return txt;
667}
668
669TQString HtmlExport::styleSheet() const
670{
671 if ( !mSettings->styleSheet().isEmpty() )
672 return mSettings->styleSheet();
673
674 TQString css;
675
676 if ( TQApplication::reverseLayout() ) {
677 css += " body { background-color:white; color:black; direction: rtl }\n";
678 css += " td { text-align:center; background-color:#eee }\n";
679 css += " th { text-align:center; background-color:#228; color:white }\n";
680 css += " td.sumdone { background-color:#ccc }\n";
681 css += " td.done { background-color:#ccc }\n";
682 css += " td.subhead { text-align:center; background-color:#ccf }\n";
683 css += " td.datehead { text-align:center; background-color:#ccf }\n";
684 css += " td.space { background-color:white }\n";
685 css += " td.dateholiday { color:red }\n";
686 } else {
687 css += " body { background-color:white; color:black }\n";
688 css += " td { text-align:center; background-color:#eee }\n";
689 css += " th { text-align:center; background-color:#228; color:white }\n";
690 css += " td.sum { text-align:left }\n";
691 css += " td.sumdone { text-align:left; background-color:#ccc }\n";
692 css += " td.done { background-color:#ccc }\n";
693 css += " td.subhead { text-align:center; background-color:#ccf }\n";
694 css += " td.datehead { text-align:center; background-color:#ccf }\n";
695 css += " td.space { background-color:white }\n";
696 css += " td.date { text-align:left }\n";
697 css += " td.dateholiday { text-align:left; color:red }\n";
698 }
699
700 return css;
701}
702
703
704void HtmlExport::addHoliday( const TQDate &date, const TQString &name)
705{
706 if ( mHolidayMap[date].isEmpty() ) {
707 mHolidayMap[date] = name;
708 } else {
709 mHolidayMap[date] = i18n("list of holidays", "%1, %2").arg(mHolidayMap[date]).arg(name);
710 }
711}
712
713TQDate HtmlExport::fromDate() const
714{
715 return mSettings->dateStart().date();
716}
717
718TQDate HtmlExport::toDate() const
719{
720 return mSettings->dateEnd().date();
721}
Provides the main "calendar" object class.
This class represents information related to an attendee of an event.
Definition: attendee.h:37
This is the main "calendar" object class.
Definition: calendar.h:171
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Events for this Calendar.
Definition: calendar.cpp:458
virtual Todo::List todos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Todos for this Calendar.
Definition: calendar.cpp:755
This class provides an Event in the sense of RFC2445.
Definition: event.h:33
virtual TQDateTime dtEnd() const
Return end date and time.
Definition: event.cpp:85
bool isMultiDay() const
Return true if the event spans multiple days, otherwise return false.
Definition: event.cpp:126
bool save(const TQString &fileName=TQString())
Writes out the calendar in HTML format.
Definition: htmlexport.cpp:53
bool doesFloat() const
Return true or false depending on whether the incidence "floats," i.e.
TQString uid() const
Return the unique id for the event.
virtual TQDateTime dtStart() const
returns an event's starting date/time as a TQDateTime.
This class provides the base class common to all calendar components.
Definition: incidence.h:48
int secrecy() const
Return the event's secrecy.
Definition: incidence.cpp:793
TQString description() const
Return long description.
Definition: incidence.cpp:280
Incidence * relatedTo() const
What event does this one relate to?
Definition: incidence.cpp:360
int priority() const
Return priority.
Definition: incidence.cpp:736
Incidence::List relations() const
All events that are related to this event.
Definition: incidence.cpp:365
TQString location() const
Return the event's/todo's location.
Definition: incidence.cpp:875
TQString categoriesStr() const
Return categories as a comma separated string.
Definition: incidence.cpp:328
TQString summary() const
Return short summary.
Definition: incidence.cpp:293
This class provides a Todo in the sense of RFC2445.
Definition: todo.h:32
bool hasDueDate() const
Returns true if the todo has a due date, otherwise return false.
Definition: todo.cpp:144
bool isCompleted() const
Returns true if the todo is 100% completed, otherwise return false.
Definition: todo.cpp:217
int percentComplete() const
Returns how many percent of the task are completed.
Definition: todo.cpp:263
TQDateTime dtDue(bool first=false) const
Returns due date and time.
Definition: todo.cpp:117
Namespace KCal is for global classes, objects and/or functions in libkcal.
Definition: alarm.h:38
@ EventSortStartDate
Sort Events chronologically, by start date.
Definition: calendar.h:79
@ SortDirectionAscending
Sort in ascending order (first to last)
Definition: calendar.h:65