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 
46 using namespace KCal;
47 
48 HtmlExport::HtmlExport( Calendar *calendar, HTMLExportSettings *settings ) :
49  mCalendar( calendar ), mSettings( settings )
50 {
51 }
52 
53 bool 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 
72 bool 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 
138 void 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 
223 void 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 
272 void 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 
325 void 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 
430 void 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 
504 void HtmlExport::createWeekView( TQTextStream */*ts*/ )
505 {
506  // FIXME: Implement this!
507 }
508 
509 void HtmlExport::createJournalView( TQTextStream */*ts*/ )
510 {
511 // Journal::List rawJournalList = mCalendar->journals();
512  // FIXME: Implement this!
513 }
514 
515 void HtmlExport::createFreeBusyView( TQTextStream */*ts*/ )
516 {
517  // FIXME: Implement this!
518 }
519 
520 bool 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 
536 void 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 
545 void 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 
554 void 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 
590 TQString 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 
610 void 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 
640 TQString 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 
669 TQString 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 
704 void 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 
713 TQDate HtmlExport::fromDate() const
714 {
715  return mSettings->dateStart().date();
716 }
717 
718 TQDate 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
HtmlExport(Calendar *calendar, HTMLExportSettings *settings)
Create new HTML exporter for calendar.
Definition: htmlexport.cpp:48
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