• 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.14
  • 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 }
QTextStream::setCodec
void setCodec(QTextCodec *codec)
KCal::Incidence::description
QString description() const
Returns the incidence description.
Definition: incidence.cpp:390
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KCal::Person::email
QString email() const
Returns the email address for this person.
Definition: person.cpp:144
QApplication::isRightToLeft
bool isRightToLeft()
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
QDate::daysInMonth
int daysInMonth() const
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
QMap
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
QDate::month
int month() const
QFile
QTextStream
KCal::Todo::dtDue
KDateTime dtDue(bool first=false) const
Returns due date and time.
Definition: todo.cpp:181
QList::indexOf
int indexOf(const T &value, int from) const
KCal::Todo::isCompleted
bool isCompleted() const
Returns true if the todo is 100% completed, otherwise return false.
Definition: todo.cpp:411
QDate::dayOfWeek
int dayOfWeek() const
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 ...
QString::number
QString number(int n, int base)
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
QString::fromUtf8
QString fromUtf8(const char *str, int size)
KCal::Incidence::SecrecyPrivate
Secret to the owner.
Definition: incidence.h:164
QDate::setYMD
bool setYMD(int y, int m, int d)
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.
QString::isEmpty
bool isEmpty() const
QDate::day
int day() const
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
QDate
KCal::ListBase
This class provides a template for lists of pointers.
Definition: listbase.h:44
QDate::year
int year() const
QString
KCal::Todo::hasDueDate
bool hasDueDate() const
Returns true if the todo has a due date, otherwise return false.
Definition: todo.cpp:252
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QString::right
QString right(int n) const
QList::contains
bool contains(const T &value) const
QFile::close
virtual void close()
QString::replace
QString & replace(int position, int n, QChar after)
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
QString::count
int count() const
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
QList< T * >::ConstIterator
typedef ConstIterator
QString::length
int length() const
QString::left
QString left(int n) const
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
QDate::addDays
QDate addDays(int ndays) const
KCal::Incidence::location
QString location() const
Returns the incidence location.
Definition: incidence.cpp:962
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
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-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:38:29 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
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2

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