00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qapplication.h>
00024 #include <qfile.h>
00025 #include <qtextstream.h>
00026 #include <qtextcodec.h>
00027 #include <qregexp.h>
00028
00029 #include <kglobal.h>
00030 #include <klocale.h>
00031 #include <kdebug.h>
00032 #include <kcalendarsystem.h>
00033
00034 #include <libkcal/calendar.h>
00035 #include <libkcal/event.h>
00036 #include <libkcal/todo.h>
00037
00038 #ifndef KORG_NOKABC
00039 #include <kabc/stdaddressbook.h>
00040 #endif
00041 #include "htmlexport.h"
00042 #include "htmlexportsettings.h"
00043
00044 using namespace KCal;
00045
00046 HtmlExport::HtmlExport( Calendar *calendar, HTMLExportSettings *settings ) :
00047 mCalendar( calendar ), mSettings( settings )
00048 {
00049 }
00050
00051 bool HtmlExport::save( const QString &fileName )
00052 {
00053 QString fn( fileName );
00054 if ( fn.isEmpty() && mSettings ) {
00055 fn = mSettings->outputFile();
00056 }
00057 if ( !mSettings || fn.isEmpty() ) {
00058 return false;
00059 }
00060 QFile f( fileName );
00061 if ( !f.open(IO_WriteOnly)) {
00062 return false;
00063 }
00064 QTextStream ts(&f);
00065 bool success = save(&ts);
00066 f.close();
00067 return success;
00068 }
00069
00070 bool HtmlExport::save(QTextStream *ts)
00071 {
00072 if ( !mSettings ) return false;
00073 ts->setEncoding( QTextStream::UnicodeUTF8 );
00074
00075
00076 *ts << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" ";
00077 *ts << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
00078
00079 *ts << "<html><head>" << endl;
00080 *ts << " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=";
00081 *ts << "UTF-8\" />\n";
00082 if ( !mSettings->pageTitle().isEmpty())
00083 *ts << " <title>" << mSettings->pageTitle() << "</title>\n";
00084 *ts << " <style type=\"text/css\">\n";
00085 *ts << styleSheet();
00086 *ts << " </style>\n";
00087 *ts << "</head><body>\n";
00088
00089
00090
00091
00092 if ( mSettings->eventView() || mSettings->monthView() || mSettings->weekView() ) {
00093 if (!mSettings->eventTitle().isEmpty())
00094 *ts << "<h1>" << mSettings->eventTitle() << "</h1>\n";
00095
00096
00097 if ( mSettings->weekView() )
00098 createWeekView( ts );
00099
00100 if ( mSettings->monthView() )
00101 createMonthView( ts );
00102
00103 if ( mSettings->eventView() )
00104 createEventList( ts );
00105 }
00106
00107
00108 if ( mSettings->todoView() ) {
00109 if ( !mSettings->todoListTitle().isEmpty())
00110 *ts << "<h1>" << mSettings->todoListTitle() << "</h1>\n";
00111 createTodoList(ts);
00112 }
00113
00114
00115 if ( mSettings->journalView() ) {
00116 if ( !mSettings->journalTitle().isEmpty())
00117 *ts << "<h1>" << mSettings->journalTitle() << "</h1>\n";
00118 createJournalView(ts);
00119 }
00120
00121
00122 if ( mSettings->freeBusyView() ) {
00123 if ( !mSettings->freeBusyTitle().isEmpty())
00124 *ts << "<h1>" << mSettings->freeBusyTitle() << "</h1>\n";
00125 createFreeBusyView(ts);
00126 }
00127
00128 createFooter( ts );
00129
00130
00131 *ts << "</body></html>\n";
00132
00133 return true;
00134 }
00135
00136 void HtmlExport::createMonthView(QTextStream *ts)
00137 {
00138 QDate start = fromDate();
00139 start.setYMD( start.year(), start.month(), 1 );
00140
00141 QDate end( start.year(), start.month(), start.daysInMonth() );
00142
00143 int startmonth = start.month();
00144 int startyear = start.year();
00145
00146 while ( start < toDate() ) {
00147
00148 *ts << "<h2>" << (i18n("month_year","%1 %2").arg(KGlobal::locale()->calendar()->monthName(start))
00149 .arg(start.year())) << "</h2>\n";
00150 if ( KGlobal::locale()->weekStartDay() == 1 ) {
00151 start = start.addDays(1 - start.dayOfWeek());
00152 } else {
00153 if (start.dayOfWeek() != 7) {
00154 start = start.addDays(-start.dayOfWeek());
00155 }
00156 }
00157 *ts << "<table border=\"1\">\n";
00158
00159
00160 *ts << " <tr>";
00161 for(int i=0; i<7; ++i) {
00162 *ts << "<th>" << KGlobal::locale()->calendar()->weekDayName( start.addDays(i) ) << "</th>";
00163 }
00164 *ts << "</tr>\n";
00165
00166
00167 while (start <= end) {
00168 *ts << " <tr>\n";
00169 for(int i=0;i<7;++i) {
00170 *ts << " <td valign=\"top\"><table border=\"0\">";
00171
00172 *ts << "<tr><td ";
00173 if (mHolidayMap.contains(start) || start.dayOfWeek() == 7) {
00174 *ts << "class=\"dateholiday\"";
00175 } else {
00176 *ts << "class=\"date\"";
00177 }
00178 *ts << ">" << QString::number(start.day());
00179
00180 if (mHolidayMap.contains(start)) {
00181 *ts << " <em>" << mHolidayMap[start] << "</em>";
00182 }
00183
00184 *ts << "</td></tr><tr><td valign=\"top\">";
00185
00186 Event::List events = mCalendar->events( start,
00187 EventSortStartDate,
00188 SortDirectionAscending );
00189 if (events.count()) {
00190 *ts << "<table>";
00191 Event::List::ConstIterator it;
00192 for( it = events.begin(); it != events.end(); ++it ) {
00193 if ( checkSecrecy( *it ) ) {
00194 createEvent( ts, *it, start, false );
00195 }
00196 }
00197 *ts << "</table>";
00198 } else {
00199 *ts << " ";
00200 }
00201
00202 *ts << "</td></tr></table></td>\n";
00203 start = start.addDays(1);
00204 }
00205 *ts << " </tr>\n";
00206 }
00207 *ts << "</table>\n";
00208 startmonth += 1;
00209 if ( startmonth > 12 ) {
00210 startyear += 1;
00211 startmonth = 1;
00212 }
00213 start.setYMD( startyear, startmonth, 1 );
00214 end.setYMD(start.year(),start.month(),start.daysInMonth());
00215 }
00216 }
00217
00218 void HtmlExport::createEventList (QTextStream *ts)
00219 {
00220 int columns = 3;
00221 *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">\n";
00222 *ts << " <tr>\n";
00223 *ts << " <th class=\"sum\">" << i18n("Start Time") << "</th>\n";
00224 *ts << " <th>" << i18n("End Time") << "</th>\n";
00225 *ts << " <th>" << i18n("Event") << "</th>\n";
00226 if ( mSettings->eventLocation() ) {
00227 *ts << " <th>" << i18n("Location") << "</th>\n";
00228 ++columns;
00229 }
00230 if ( mSettings->eventCategories() ) {
00231 *ts << " <th>" << i18n("Categories") << "</th>\n";
00232 ++columns;
00233 }
00234 if ( mSettings->eventAttendees() ) {
00235 *ts << " <th>" << i18n("Attendees") << "</th>\n";
00236 ++columns;
00237 }
00238
00239 *ts << " </tr>\n";
00240
00241 for ( QDate dt = fromDate(); dt <= toDate(); dt = dt.addDays(1) ) {
00242 kdDebug(5850) << "Getting events for " << dt.toString() << endl;
00243 Event::List events = mCalendar->events(dt,
00244 EventSortStartDate,
00245 SortDirectionAscending );
00246 if (events.count()) {
00247 *ts << " <tr><td colspan=\"" << QString::number(columns)
00248 << "\" class=\"datehead\"><i>"
00249 << KGlobal::locale()->formatDate(dt)
00250 << "</i></td></tr>\n";
00251
00252 Event::List::ConstIterator it;
00253 for( it = events.begin(); it != events.end(); ++it ) {
00254 if ( checkSecrecy( *it ) ) {
00255 createEvent( ts, *it, dt );
00256 }
00257 }
00258 }
00259 }
00260
00261 *ts << "</table>\n";
00262 }
00263
00264 void HtmlExport::createEvent (QTextStream *ts, Event *event,
00265 QDate date,bool withDescription)
00266 {
00267 kdDebug(5850) << "HtmlExport::createEvent(): " << event->summary() << endl;
00268 *ts << " <tr>\n";
00269
00270 if (!event->doesFloat()) {
00271 if (event->isMultiDay() && (event->dtStart().date() != date)) {
00272 *ts << " <td> </td>\n";
00273 } else {
00274 *ts << " <td valign=\"top\">" << event->dtStartTimeStr() << "</td>\n";
00275 }
00276 if (event->isMultiDay() && (event->dtEnd().date() != date)) {
00277 *ts << " <td> </td>\n";
00278 } else {
00279 *ts << " <td valign=\"top\">" << event->dtEndTimeStr() << "</td>\n";
00280 }
00281 } else {
00282 *ts << " <td> </td><td> </td>\n";
00283 }
00284
00285 *ts << " <td class=\"sum\">\n";
00286 *ts << " <b>" << cleanChars(event->summary()) << "</b>\n";
00287 if ( withDescription && !event->description().isEmpty() ) {
00288 *ts << " <p>" << breakString( cleanChars( event->description() ) ) << "</p>\n";
00289 }
00290 *ts << " </td>\n";
00291
00292 if ( mSettings->eventLocation() ) {
00293 *ts << " <td>\n";
00294 formatLocation( ts, event );
00295 *ts << " </td>\n";
00296 }
00297
00298 if ( mSettings->eventCategories() ) {
00299 *ts << " <td>\n";
00300 formatCategories( ts, event );
00301 *ts << " </td>\n";
00302 }
00303
00304 if ( mSettings->eventAttendees() ) {
00305 *ts << " <td>\n";
00306 formatAttendees( ts, event );
00307 *ts << " </td>\n";
00308 }
00309
00310 *ts << " </tr>\n";
00311 }
00312
00313 void HtmlExport::createTodoList ( QTextStream *ts )
00314 {
00315 Todo::List rawTodoList = mCalendar->todos();
00316
00317 Todo::List::Iterator it = rawTodoList.begin();
00318 while ( it != rawTodoList.end() ) {
00319 Todo *ev = *it;
00320 Todo *subev = ev;
00321 if ( ev->relatedTo() ) {
00322 if ( ev->relatedTo()->type()=="Todo" ) {
00323 if ( rawTodoList.find( static_cast<Todo *>( ev->relatedTo() ) ) ==
00324 rawTodoList.end() ) {
00325 rawTodoList.append( static_cast<Todo *>( ev->relatedTo() ) );
00326 }
00327 }
00328 }
00329 it = rawTodoList.find( subev );
00330 ++it;
00331 }
00332
00333
00334
00335 Todo::List todoList;
00336 for ( int i = 1; i <= 9; ++i ) {
00337 for( it = rawTodoList.begin(); it != rawTodoList.end(); ++it ) {
00338 if ( (*it)->priority() == i && checkSecrecy( *it ) ) {
00339 todoList.append( *it );
00340 }
00341 }
00342 }
00343 for( it = rawTodoList.begin(); it != rawTodoList.end(); ++it ) {
00344 if ( (*it)->priority() == 0 && checkSecrecy( *it ) ) {
00345 todoList.append( *it );
00346 }
00347 }
00348
00349 int columns = 3;
00350 *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">\n";
00351 *ts << " <tr>\n";
00352 *ts << " <th class=\"sum\">" << i18n("Task") << "</th>\n";
00353 *ts << " <th>" << i18n("Priority") << "</th>\n";
00354 *ts << " <th>" << i18n("Completed") << "</th>\n";
00355 if ( mSettings->taskDueDate() ) {
00356 *ts << " <th>" << i18n("Due Date") << "</th>\n";
00357 ++columns;
00358 }
00359 if ( mSettings->taskLocation() ) {
00360 *ts << " <th>" << i18n("Location") << "</th>\n";
00361 ++columns;
00362 }
00363 if ( mSettings->taskCategories() ) {
00364 *ts << " <th>" << i18n("Categories") << "</th>\n";
00365 ++columns;
00366 }
00367 if ( mSettings->taskAttendees() ) {
00368 *ts << " <th>" << i18n("Attendees") << "</th>\n";
00369 ++columns;
00370 }
00371 *ts << " </tr>\n";
00372
00373
00374 for( it = todoList.begin(); it != todoList.end(); ++it ) {
00375 if ( !(*it)->relatedTo() ) createTodo( ts, *it );
00376 }
00377
00378
00379 for( it = todoList.begin(); it != todoList.end(); ++it ) {
00380 Incidence::List relations = (*it)->relations();
00381 if (relations.count()) {
00382
00383 *ts << " <tr>\n";
00384 *ts << " <td class=\"subhead\" colspan=";
00385 *ts << "\"" << QString::number(columns) << "\"";
00386 *ts << "><a name=\"sub" << (*it)->uid() << "\"></a>"
00387 << i18n("Sub-Tasks of: ") << "<a href=\"#"
00388 << (*it)->uid() << "\"><b>" << cleanChars( (*it)->summary())
00389 << "</b></a></td>\n";
00390 *ts << " </tr>\n";
00391
00392 Todo::List sortedList;
00393
00394
00395 for ( int i = 1; i <= 9; ++i ) {
00396 Incidence::List::ConstIterator it2;
00397 for( it2 = relations.begin(); it2 != relations.end(); ++it2 ) {
00398 Todo *ev3 = dynamic_cast<Todo *>( *it2 );
00399 if ( ev3 && ev3->priority() == i ) sortedList.append( ev3 );
00400 }
00401 }
00402 Incidence::List::ConstIterator it2;
00403 for( it2 = relations.begin(); it2 != relations.end(); ++it2 ) {
00404 Todo *ev3 = dynamic_cast<Todo *>( *it2 );
00405 if ( ev3 && ev3->priority() == 0 ) sortedList.append( ev3 );
00406 }
00407
00408 Todo::List::ConstIterator it3;
00409 for( it3 = sortedList.begin(); it3 != sortedList.end(); ++it3 ) {
00410 createTodo( ts, *it3 );
00411 }
00412 }
00413 }
00414
00415 *ts << "</table>\n";
00416 }
00417
00418 void HtmlExport::createTodo (QTextStream *ts,Todo *todo)
00419 {
00420 kdDebug(5850) << "HtmlExport::createTodo()" << endl;
00421
00422 bool completed = todo->isCompleted();
00423 Incidence::List relations = todo->relations();
00424
00425 *ts << "<tr>\n";
00426
00427 *ts << " <td class=\"sum\"";
00428 if (completed) *ts << "done";
00429 *ts << ">\n";
00430 *ts << " <a name=\"" << todo->uid() << "\"></a>\n";
00431 *ts << " <b>" << cleanChars(todo->summary()) << "</b>\n";
00432 if (!todo->description().isEmpty()) {
00433 *ts << " <p>" << breakString(cleanChars(todo->description())) << "</p>\n";
00434 }
00435 if (relations.count()) {
00436 *ts << " <div align=\"right\"><a href=\"#sub" << todo->uid()
00437 << "\">" << i18n("Sub-Tasks") << "</a></div>\n";
00438 }
00439
00440 *ts << " </td";
00441 if (completed) *ts << " class=\"done\"";
00442 *ts << ">\n";
00443
00444 *ts << " <td";
00445 if (completed) *ts << " class=\"done\"";
00446 *ts << ">\n";
00447 *ts << " " << todo->priority() << "\n";
00448 *ts << " </td>\n";
00449
00450 *ts << " <td";
00451 if (completed) *ts << " class=\"done\"";
00452 *ts << ">\n";
00453 *ts << " " << i18n("%1 %").arg(todo->percentComplete()) << "\n";
00454 *ts << " </td>\n";
00455
00456 if ( mSettings->taskDueDate() ) {
00457 *ts << " <td";
00458 if (completed) *ts << " class=\"done\"";
00459 *ts << ">\n";
00460 if (todo->hasDueDate()) {
00461 *ts << " " << todo->dtDueDateStr() << "\n";
00462 } else {
00463 *ts << " \n";
00464 }
00465 *ts << " </td>\n";
00466 }
00467
00468 if ( mSettings->taskLocation() ) {
00469 *ts << " <td";
00470 if (completed) *ts << " class=\"done\"";
00471 *ts << ">\n";
00472 formatLocation(ts,todo);
00473 *ts << " </td>\n";
00474 }
00475
00476 if ( mSettings->taskCategories() ) {
00477 *ts << " <td";
00478 if (completed) *ts << " class=\"done\"";
00479 *ts << ">\n";
00480 formatCategories(ts,todo);
00481 *ts << " </td>\n";
00482 }
00483
00484 if ( mSettings->taskAttendees() ) {
00485 *ts << " <td";
00486 if (completed) *ts << " class=\"done\"";
00487 *ts << ">\n";
00488 formatAttendees(ts,todo);
00489 *ts << " </td>\n";
00490 }
00491
00492 *ts << "</tr>\n";
00493 }
00494
00495 void HtmlExport::createWeekView( QTextStream * )
00496 {
00497
00498 }
00499
00500 void HtmlExport::createJournalView( QTextStream * )
00501 {
00502
00503
00504 }
00505
00506 void HtmlExport::createFreeBusyView( QTextStream * )
00507 {
00508
00509 }
00510
00511 bool HtmlExport::checkSecrecy( Incidence *incidence )
00512 {
00513 int secrecy = incidence->secrecy();
00514 if ( secrecy == Incidence::SecrecyPublic ) {
00515 return true;
00516 }
00517 if ( secrecy == Incidence::SecrecyPrivate && !mSettings->excludePrivate() ) {
00518 return true;
00519 }
00520 if ( secrecy == Incidence::SecrecyConfidential &&
00521 !mSettings->excludeConfidential() ) {
00522 return true;
00523 }
00524 return false;
00525 }
00526
00527 void HtmlExport::formatLocation (QTextStream *ts,Incidence *event)
00528 {
00529 if (!event->location().isEmpty()) {
00530 *ts << " " << cleanChars(event->location()) << "\n";
00531 } else {
00532 *ts << " \n";
00533 }
00534 }
00535
00536 void HtmlExport::formatCategories (QTextStream *ts,Incidence *event)
00537 {
00538 if (!event->categoriesStr().isEmpty()) {
00539 *ts << " " << cleanChars(event->categoriesStr()) << "\n";
00540 } else {
00541 *ts << " \n";
00542 }
00543 }
00544
00545 void HtmlExport::formatAttendees( QTextStream *ts, Incidence *event )
00546 {
00547 Attendee::List attendees = event->attendees();
00548 if (attendees.count()) {
00549 *ts << "<em>";
00550 #ifndef KORG_NOKABC
00551 KABC::AddressBook *add_book = KABC::StdAddressBook::self( true );
00552 KABC::Addressee::List addressList;
00553 addressList = add_book->findByEmail(event->organizer().email());
00554 KABC::Addressee o = addressList.first();
00555 if (!o.isEmpty() && addressList.size()<2) {
00556 *ts << "<a href=\"mailto:" << event->organizer().email() << "\">";
00557 *ts << cleanChars(o.formattedName()) << "</a>\n";
00558 }
00559 else *ts << event->organizer().fullName();
00560 #else
00561 *ts << event->organizer().fullName();
00562 #endif
00563 *ts << "</em><br />";
00564 Attendee::List::ConstIterator it;
00565 for( it = attendees.begin(); it != attendees.end(); ++it ) {
00566 Attendee *a = *it;
00567 if (!a->email().isEmpty()) {
00568 *ts << "<a href=\"mailto:" << a->email();
00569 *ts << "\">" << cleanChars(a->name()) << "</a>";
00570 }
00571 else {
00572 *ts << " " << cleanChars(a->name());
00573 }
00574 *ts << "<br />" << "\n";
00575 }
00576 } else {
00577 *ts << " \n";
00578 }
00579 }
00580
00581 QString HtmlExport::breakString(const QString &text)
00582 {
00583 int number = text.contains("\n");
00584 if(number < 0) {
00585 return text;
00586 } else {
00587 QString out;
00588 QString tmpText = text;
00589 int pos = 0;
00590 QString tmp;
00591 for(int i=0;i<=number;i++) {
00592 pos = tmpText.find("\n");
00593 tmp = tmpText.left(pos);
00594 tmpText = tmpText.right(tmpText.length() - pos - 1);
00595 out += tmp + "<br />";
00596 }
00597 return out;
00598 }
00599 }
00600
00601 void HtmlExport::createFooter( QTextStream *ts )
00602 {
00603
00604 QString trailer = i18n("This page was created ");
00605
00606
00607
00608
00609
00610 if (!mSettings->eMail().isEmpty()) {
00611 if (!mSettings->name().isEmpty())
00612 trailer += i18n("by <a href=\"mailto:%1\">%2</a> ").arg( mSettings->eMail() ).arg( mSettings->name() );
00613 else
00614 trailer += i18n("by <a href=\"mailto:%1\">%2</a> ").arg( mSettings->eMail() ).arg( mSettings->eMail() );
00615 } else {
00616 if (!mSettings->name().isEmpty())
00617 trailer += i18n("by %1 ").arg( mSettings->name() );
00618 }
00619 if (!mSettings->creditName().isEmpty()) {
00620 if (!mSettings->creditURL().isEmpty())
00621 trailer += i18n("with <a href=\"%1\">%2</a>")
00622 .arg( mSettings->creditURL() )
00623 .arg( mSettings->creditName() );
00624 else
00625 trailer += i18n("with %1").arg( mSettings->creditName() );
00626 }
00627 *ts << "<p>" << trailer << "</p>\n";
00628 }
00629
00630
00631 QString HtmlExport::cleanChars(const QString &text)
00632 {
00633 QString txt = text;
00634 txt = txt.replace( "&", "&" );
00635 txt = txt.replace( "<", "<" );
00636 txt = txt.replace( ">", ">" );
00637 txt = txt.replace( "\"", """ );
00638 txt = txt.replace( "ä", "ä" );
00639 txt = txt.replace( "Ä", "Ä" );
00640 txt = txt.replace( "ö", "ö" );
00641 txt = txt.replace( "Ö", "Ö" );
00642 txt = txt.replace( "ü", "ü" );
00643 txt = txt.replace( "Ü", "Ü" );
00644 txt = txt.replace( "ß", "ß" );
00645 txt = txt.replace( "¤", "€" );
00646 txt = txt.replace( "é", "é" );
00647
00648 return txt;
00649 }
00650
00651 QString HtmlExport::styleSheet() const
00652 {
00653 if ( !mSettings->styleSheet().isEmpty() )
00654 return mSettings->styleSheet();
00655
00656 QString css;
00657
00658 if ( QApplication::reverseLayout() ) {
00659 css += " body { background-color:white; color:black; direction: rtl }\n";
00660 css += " td { text-align:center; background-color:#eee }\n";
00661 css += " th { text-align:center; background-color:#228; color:white }\n";
00662 css += " td.sumdone { background-color:#ccc }\n";
00663 css += " td.done { background-color:#ccc }\n";
00664 css += " td.subhead { text-align:center; background-color:#ccf }\n";
00665 css += " td.datehead { text-align:center; background-color:#ccf }\n";
00666 css += " td.space { background-color:white }\n";
00667 css += " td.dateholiday { color:red }\n";
00668 } else {
00669 css += " body { background-color:white; color:black }\n";
00670 css += " td { text-align:center; background-color:#eee }\n";
00671 css += " th { text-align:center; background-color:#228; color:white }\n";
00672 css += " td.sum { text-align:left }\n";
00673 css += " td.sumdone { text-align:left; background-color:#ccc }\n";
00674 css += " td.done { background-color:#ccc }\n";
00675 css += " td.subhead { text-align:center; background-color:#ccf }\n";
00676 css += " td.datehead { text-align:center; background-color:#ccf }\n";
00677 css += " td.space { background-color:white }\n";
00678 css += " td.date { text-align:left }\n";
00679 css += " td.dateholiday { text-align:left; color:red }\n";
00680 }
00681
00682 return css;
00683 }
00684
00685
00686 void HtmlExport::addHoliday( const QDate &date, const QString &name)
00687 {
00688 mHolidayMap[date] = name;
00689 }
00690
00691 QDate HtmlExport::fromDate() const
00692 {
00693 return mSettings->dateStart().date();
00694 }
00695
00696 QDate HtmlExport::toDate() const
00697 {
00698 return mSettings->dateEnd().date();
00699 }