libkcal

htmlexport.cpp

00001 /*
00002     This file is part of libkcal.
00003 
00004     Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
00005     Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
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   // Write HTML header
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   // FIXME: Write header
00090   // (Heading, Calendar-Owner, Calendar-Date, ...)
00091 
00092   if ( mSettings->eventView() || mSettings->monthView() || mSettings->weekView() ) {
00093     if (!mSettings->eventTitle().isEmpty())
00094       *ts << "<h1>" << mSettings->eventTitle() << "</h1>\n";
00095 
00096     // Write Week View
00097     if ( mSettings->weekView() )
00098       createWeekView( ts );
00099     // Write Month View
00100     if ( mSettings->monthView() )
00101       createMonthView( ts );
00102     // Write Event List
00103     if ( mSettings->eventView() )
00104       createEventList( ts );
00105   }
00106 
00107   // Write Todo List
00108   if ( mSettings->todoView() ) {
00109     if ( !mSettings->todoListTitle().isEmpty())
00110       *ts << "<h1>" << mSettings->todoListTitle() << "</h1>\n";
00111     createTodoList(ts);
00112   }
00113 
00114   // Write Journals
00115   if ( mSettings->journalView() ) {
00116     if ( !mSettings->journalTitle().isEmpty())
00117       *ts << "<h1>" << mSettings->journalTitle() << "</h1>\n";
00118     createJournalView(ts);
00119   }
00120 
00121   // Write Free/Busy
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   // Write HTML trailer
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 );  // go back to first day in month
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     // Write header
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     // Write table header
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     // Write days
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 << "&nbsp;";
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>&nbsp;</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>&nbsp;</td>\n";
00278     } else {
00279       *ts << "    <td valign=\"top\">" << event->dtEndTimeStr() << "</td>\n";
00280     }
00281   } else {
00282     *ts << "    <td>&nbsp;</td><td>&nbsp;</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   // FIXME: Sort list by priorities. This is brute force and should be
00334   // replaced by a real sorting algorithm.
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   // Create top-level list.
00374   for( it = todoList.begin(); it != todoList.end(); ++it ) {
00375     if ( !(*it)->relatedTo() ) createTodo( ts, *it );
00376   }
00377 
00378   // Create sub-level lists
00379   for( it = todoList.begin(); it != todoList.end(); ++it ) {
00380     Incidence::List relations = (*it)->relations();
00381     if (relations.count()) {
00382       // Generate sub-task list of event ev
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       // FIXME: Sort list by priorities. This is brute force and should be
00394       // replaced by a real sorting algorithm.
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 << "    &nbsp;\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 */*ts*/ )
00496 {
00497   // FIXME: Implement this!
00498 }
00499 
00500 void HtmlExport::createJournalView( QTextStream */*ts*/ )
00501 {
00502 //   Journal::List rawJournalList = mCalendar->journals();
00503   // FIXME: Implement this!
00504 }
00505 
00506 void HtmlExport::createFreeBusyView( QTextStream */*ts*/ )
00507 {
00508   // FIXME: Implement this!
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 << "    &nbsp;\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 << "    &nbsp;\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 << "    &nbsp;\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   // FIXME: Implement this in a translatable way!
00604   QString trailer = i18n("This page was created ");
00605 
00606 /*  bool hasPerson = false;
00607   bool hasCredit = false;
00608   bool hasCreditURL = false;
00609   QString mail, name, credit, creditURL;*/
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( "&", "&amp;" );
00635   txt = txt.replace( "<", "&lt;" );
00636   txt = txt.replace( ">", "&gt;" );
00637   txt = txt.replace( "\"", "&quot;" );
00638   txt = txt.replace( "ä", "&auml;" );
00639   txt = txt.replace( "Ä", "&Auml;" );
00640   txt = txt.replace( "ö", "&ouml;" );
00641   txt = txt.replace( "Ö", "&Ouml;" );
00642   txt = txt.replace( "ü", "&uuml;" );
00643   txt = txt.replace( "Ü", "&Uuml;" );
00644   txt = txt.replace( "ß", "&szlig;" );
00645   txt = txt.replace( "¤", "&euro;" );
00646   txt = txt.replace( "é", "&eacute;" );
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 }
KDE Home | KDE Accessibility Home | Description of Access Keys