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

KCal Library

  • sources
  • kde-4.12
  • kdepimlibs
  • 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 
45 using namespace KCal;
46 
47 static QString cleanChars( const QString &txt );
48 
49 //@cond PRIVATE
50 class 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 
64 HtmlExport::HtmlExport( Calendar *calendar, HTMLExportSettings *settings )
65  : d( new Private( calendar, settings ) )
66 {
67 }
68 
69 HtmlExport::~HtmlExport()
70 {
71  delete d;
72 }
73 
74 bool 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 
93 bool 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 
168 void 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 
257 void 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 
309 void 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 
362 void 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 
475 void 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 
563 void HtmlExport::createWeekView( QTextStream *ts )
564 {
565  Q_UNUSED( ts );
566  // FIXME: Implement this!
567 }
568 
569 void HtmlExport::createJournalView( QTextStream *ts )
570 {
571  Q_UNUSED( ts );
572 // Journal::List rawJournalList = d->mCalendar->journals();
573  // FIXME: Implement this!
574 }
575 
576 void HtmlExport::createFreeBusyView( QTextStream *ts )
577 {
578  Q_UNUSED( ts );
579  // FIXME: Implement this!
580 }
581 
582 bool 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 
598 void 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 
607 void 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 
616 void 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 
654 QString 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 
674 void 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 
712 QString 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 
732 QString 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 
767 void 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 
777 QDate HtmlExport::fromDate() const
778 {
779  return d->mSettings->dateStart().date();
780 }
781 
782 QDate HtmlExport::toDate() const
783 {
784  return d->mSettings->dateEnd().date();
785 }
KCal::Incidence::description
QString description() const
Returns the incidence description.
Definition: incidence.cpp:390
KCal::Person::email
QString email() const
Returns the email address for this person.
Definition: person.cpp:144
KCal::Incidence::relatedTo
Incidence * relatedTo() const
Returns a pointer for the incidence that is related to this one.
Definition: incidence.cpp:516
KCal::IncidenceBase::attendees
const Attendee::List & attendees() const
Returns a list of incidence attendees.
Definition: incidencebase.cpp:378
KCal::Todo
Provides a To-do in the sense of RFC2445.
Definition: todo.h:44
KCal::Calendar
Represents the main calendar class.
Definition: calendar.h:119
KCal::HtmlExport::HtmlExport
HtmlExport(Calendar *calendar, HTMLExportSettings *settings)
Create new HTML exporter for calendar.
Definition: htmlexport.cpp:64
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::IncidenceBase::dtStart
virtual KDateTime dtStart() const
Returns an incidence's starting date/time as a KDateTime.
Definition: incidencebase.cpp:248
KCal::Attendee
Represents information related to an attendee of an Calendar Incidence, typically a meeting or task (...
Definition: attendee.h:58
KCal::Event
This class provides an Event in the sense of RFC2445.
Definition: event.h:41
KCal::Incidence::categoriesStr
QString categoriesStr() const
Returns the incidence categories as a comma separated string.
Definition: incidence.cpp:478
KCal::IncidenceBase::uid
QString uid() const
Returns the unique id (uid) for the incidence.
Definition: incidencebase.cpp:184
KCal::Todo::dtDue
KDateTime dtDue(bool first=false) const
Returns due date and time.
Definition: todo.cpp:181
KCal::Todo::isCompleted
bool isCompleted() const
Returns true if the todo is 100% completed, otherwise return false.
Definition: todo.cpp:411
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
incidenceformatter.h
This file is part of the API for handling calendar data and provides static functions for formatting ...
KCal::Incidence::SecrecyPrivate
Secret to the owner.
Definition: incidence.h:164
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.
todo.h
This file is part of the API for handling calendar data and defines the Todo class.
calendar.h
This file is part of the API for handling calendar data and defines the Calendar class.
KCal::Person::name
QString name() const
Returns the person name string.
Definition: person.cpp:139
KCal::IncidenceBase::organizer
Person organizer() const
Returns the Person associated with this incidence.
Definition: incidencebase.cpp:230
KCal::Incidence
Provides the abstract base class common to non-FreeBusy (Events, To-dos, Journals) calendar component...
Definition: incidence.h:68
KCal::ListBase
This class provides a template for lists of pointers.
Definition: listbase.h:44
KCal::Todo::hasDueDate
bool hasDueDate() const
Returns true if the todo has a due date, otherwise return false.
Definition: todo.cpp:252
KCal::Incidence::SecrecyConfidential
Secret to the owner and some others.
Definition: incidence.h:165
event.h
This file is part of the API for handling calendar data and defines the Event class.
KCal::Person::fullName
QString fullName() const
Returns the full name of this person.
Definition: person.cpp:114
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
KCal::Todo::percentComplete
int percentComplete() const
Returns what percentage of the to-do is completed.
Definition: todo.cpp:463
KCal::HtmlExport::save
bool save(const QString &fileName=QString())
Writes out the calendar in HTML format.
Definition: htmlexport.cpp:74
KCal::Incidence::priority
int priority() const
Returns the incidence priority.
Definition: incidence.cpp:795
KCal::Incidence::location
QString location() const
Returns the incidence location.
Definition: incidence.cpp:962
KCal::Incidence::secrecy
Secrecy secrecy() const
Returns the incidence Secrecy.
Definition: incidence.cpp:872
KCal::Incidence::relations
Incidence::List relations() const
Returns a list of all incidences related to this one.
Definition: incidence.cpp:521
KCal::Event::dtEnd
virtual KDateTime dtEnd() const
Returns the event end date and time.
Definition: event.cpp:132
KCal::Incidence::summary
QString summary() const
Returns the incidence summary.
Definition: incidence.cpp:424
KCal::Incidence::SecrecyPublic
Not secret (default)
Definition: incidence.h:163
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:57 by doxygen 1.8.7 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 API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



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