• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

KCal Library

htmlexport.cpp

00001 /*
00002   This file is part of the kcal library.
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 "htmlexport.h"
00024 #include "htmlexportsettings.h"
00025 #include "incidenceformatter.h"
00026 #include "calendar.h"
00027 #include "event.h"
00028 #include "todo.h"
00029 #ifndef KORG_NOKABC
00030  #include "kabc/stdaddressbook.h"
00031 #endif
00032 
00033 #include <kglobal.h>
00034 #include <klocale.h>
00035 #include <kdebug.h>
00036 #include <kcalendarsystem.h>
00037 
00038 #include <QtCore/QFile>
00039 #include <QtCore/QTextStream>
00040 #include <QtCore/QTextCodec>
00041 #include <QtCore/QRegExp>
00042 #include <QtCore/QMap>
00043 #include <QtGui/QApplication>
00044 
00045 using namespace KCal;
00046 
00047 static QString cleanChars( const QString &txt );
00048 
00049 //@cond PRIVATE
00050 class KCal::HtmlExport::Private
00051 {
00052   public:
00053     Private( Calendar *calendar, HTMLExportSettings *settings )
00054       : mCalendar( calendar ),
00055         mSettings( settings )
00056     {}
00057 
00058     Calendar *mCalendar;
00059     HTMLExportSettings *mSettings;
00060     QMap<QDate,QString> mHolidayMap;
00061 };
00062 //@endcond
00063 
00064 HtmlExport::HtmlExport( Calendar *calendar, HTMLExportSettings *settings )
00065   : d( new Private( calendar, settings ) )
00066 {
00067 }
00068 
00069 HtmlExport::~HtmlExport()
00070 {
00071   delete d;
00072 }
00073 
00074 bool HtmlExport::save( const QString &fileName )
00075 {
00076   QString fn( fileName );
00077   if ( fn.isEmpty() && d->mSettings ) {
00078     fn = d->mSettings->outputFile();
00079   }
00080   if ( !d->mSettings || fn.isEmpty() ) {
00081     return false;
00082   }
00083   QFile f( fileName );
00084   if ( !f.open( QIODevice::WriteOnly ) ) {
00085     return false;
00086   }
00087   QTextStream ts( &f );
00088   bool success = save( &ts );
00089   f.close();
00090   return success;
00091 }
00092 
00093 bool HtmlExport::save( QTextStream *ts )
00094 {
00095   if ( !d->mSettings ) {
00096     return false;
00097   }
00098   ts->setCodec( "UTF-8" );
00099 
00100   // Write HTML header
00101   *ts << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" ";
00102   *ts << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
00103 
00104   *ts << "<html><head>" << endl;
00105   *ts << "  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=";
00106   *ts << "UTF-8\" />\n";
00107   if ( !d->mSettings->pageTitle().isEmpty() ) {
00108     *ts << "  <title>" << d->mSettings->pageTitle() << "</title>\n";
00109   }
00110   *ts << "  <style type=\"text/css\">\n";
00111   *ts << styleSheet();
00112   *ts << "  </style>\n";
00113   *ts << "</head><body>\n";
00114 
00115   // FIXME: Write header
00116   // (Heading, Calendar-Owner, Calendar-Date, ...)
00117 
00118   if ( d->mSettings->eventView() || d->mSettings->monthView() || d->mSettings->weekView() ) {
00119     if ( !d->mSettings->eventTitle().isEmpty() ) {
00120       *ts << "<h1>" << d->mSettings->eventTitle() << "</h1>\n";
00121     }
00122 
00123     // Write Week View
00124     if ( d->mSettings->weekView() ) {
00125       createWeekView( ts );
00126     }
00127     // Write Month View
00128     if ( d->mSettings->monthView() ) {
00129       createMonthView( ts );
00130     }
00131     // Write Event List
00132     if ( d->mSettings->eventView() ) {
00133       createEventList( ts );
00134     }
00135   }
00136 
00137   // Write Todo List
00138   if ( d->mSettings->todoView() ) {
00139     if ( !d->mSettings->todoListTitle().isEmpty() ) {
00140       *ts << "<h1>" << d->mSettings->todoListTitle() << "</h1>\n";
00141     }
00142     createTodoList( ts );
00143   }
00144 
00145   // Write Journals
00146   if ( d->mSettings->journalView() ) {
00147     if ( !d->mSettings->journalTitle().isEmpty() ) {
00148       *ts << "<h1>" << d->mSettings->journalTitle() << "</h1>\n";
00149     }
00150     createJournalView( ts );
00151   }
00152 
00153   // Write Free/Busy
00154   if ( d->mSettings->freeBusyView() ) {
00155     if ( !d->mSettings->freeBusyTitle().isEmpty() ) {
00156       *ts << "<h1>" << d->mSettings->freeBusyTitle() << "</h1>\n";
00157     }
00158     createFreeBusyView( ts );
00159   }
00160 
00161   createFooter( ts );
00162 
00163   // Write HTML trailer
00164   *ts << "</body></html>\n";
00165 
00166   return true;
00167 }
00168 
00169 void HtmlExport::createMonthView( QTextStream *ts )
00170 {
00171   QDate start = fromDate();
00172   start.setYMD( start.year(), start.month(), 1 );  // go back to first day in month
00173 
00174   QDate end( start.year(), start.month(), start.daysInMonth() );
00175 
00176   int startmonth = start.month();
00177   int startyear = start.year();
00178 
00179   while ( start < toDate() ) {
00180     // Write header
00181     QDate hDate( start.year(), start.month(), 1 );
00182     QString hMon = hDate.toString( "MMMM" );
00183     QString hYear = hDate.toString( "yyyy" );
00184     *ts << "<h2>"
00185         << i18nc( "@title month and year", "%1 %2", hMon, hYear )
00186         << "</h2>\n";
00187     if ( KGlobal::locale()->weekStartDay() == 1 ) {
00188       start = start.addDays( 1 - start.dayOfWeek() );
00189     } else {
00190       if ( start.dayOfWeek() != 7 ) {
00191         start = start.addDays( -start.dayOfWeek() );
00192       }
00193     }
00194     *ts << "<table border=\"1\">\n";
00195 
00196     // Write table header
00197     *ts << "  <tr>";
00198     for ( int i=0; i < 7; ++i ) {
00199       *ts << "<th>" << KGlobal::locale()->calendar()->weekDayName( start.addDays(i) ) << "</th>";
00200     }
00201     *ts << "</tr>\n";
00202 
00203     // Write days
00204     while ( start <= end ) {
00205       *ts << "  <tr>\n";
00206       for ( int i=0; i < 7; ++i ) {
00207         *ts << "    <td valign=\"top\"><table border=\"0\">";
00208 
00209         *ts << "<tr><td ";
00210         if ( d->mHolidayMap.contains( start ) || start.dayOfWeek() == 7 ) {
00211           *ts << "class=\"dateholiday\"";
00212         } else {
00213           *ts << "class=\"date\"";
00214         }
00215         *ts << ">" << QString::number( start.day() );
00216 
00217         if ( d->mHolidayMap.contains( start ) ) {
00218           *ts << " <em>" << d->mHolidayMap[start] << "</em>";
00219         }
00220 
00221         *ts << "</td></tr><tr><td valign=\"top\">";
00222 
00223         Event::List events = d->mCalendar->events( start, d->mCalendar->timeSpec(),
00224                                                    EventSortStartDate,
00225                                                    SortDirectionAscending );
00226         if ( events.count() ) {
00227           *ts << "<table>";
00228           Event::List::ConstIterator it;
00229           for ( it = events.constBegin(); it != events.constEnd(); ++it ) {
00230             if ( checkSecrecy( *it ) ) {
00231               createEvent( ts, *it, start, false );
00232             }
00233           }
00234           *ts << "</table>";
00235         } else {
00236           *ts << "&nbsp;";
00237         }
00238 
00239         *ts << "</td></tr></table></td>\n";
00240         start = start.addDays( 1 );
00241       }
00242       *ts << "  </tr>\n";
00243     }
00244     *ts << "</table>\n";
00245     startmonth += 1;
00246     if ( startmonth > 12 ) {
00247       startyear += 1;
00248       startmonth = 1;
00249     }
00250     start.setYMD( startyear, startmonth, 1 );
00251     end.setYMD( start.year(), start.month(), start.daysInMonth() );
00252   }
00253 }
00254 
00255 void HtmlExport::createEventList( QTextStream *ts )
00256 {
00257   int columns = 3;
00258   *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">\n";
00259   *ts << "  <tr>\n";
00260   *ts << "    <th class=\"sum\">" << i18nc( "@title:column event start time",
00261                                             "Start Time" ) << "</th>\n";
00262   *ts << "    <th>" << i18nc( "@title:column event end time",
00263                               "End Time" ) << "</th>\n";
00264   *ts << "    <th>" << i18nc( "@title:column event description",
00265                               "Event" ) << "</th>\n";
00266   if ( d->mSettings->eventLocation() ) {
00267     *ts << "    <th>" << i18nc( "@title:column event locatin",
00268                                 "Location" ) << "</th>\n";
00269     ++columns;
00270   }
00271   if ( d->mSettings->eventCategories() ) {
00272     *ts << "    <th>" << i18nc( "@title:column event categories",
00273                                 "Categories" ) << "</th>\n";
00274     ++columns;
00275   }
00276   if ( d->mSettings->eventAttendees() ) {
00277     *ts << "    <th>" << i18nc( "@title:column event attendees",
00278                                 "Attendees" ) << "</th>\n";
00279     ++columns;
00280   }
00281 
00282   *ts << "  </tr>\n";
00283 
00284   for ( QDate dt = fromDate(); dt <= toDate(); dt = dt.addDays(1) ) {
00285     kDebug() << "Getting events for" << dt.toString();
00286     Event::List events = d->mCalendar->events( dt, d->mCalendar->timeSpec(),
00287                                                EventSortStartDate,
00288                                                SortDirectionAscending );
00289     if ( events.count() ) {
00290       *ts << "  <tr><td colspan=\"" << QString::number( columns )
00291           << "\" class=\"datehead\"><i>"
00292           << KGlobal::locale()->formatDate( dt )
00293           << "</i></td></tr>\n";
00294 
00295       Event::List::ConstIterator it;
00296       for ( it = events.constBegin(); it != events.constEnd(); ++it ) {
00297         if ( checkSecrecy( *it ) ) {
00298           createEvent( ts, *it, dt );
00299         }
00300       }
00301     }
00302   }
00303 
00304   *ts << "</table>\n";
00305 }
00306 
00307 void HtmlExport::createEvent ( QTextStream *ts, Event *event,
00308                                QDate date, bool withDescription )
00309 {
00310   kDebug() << event->summary();
00311   *ts << "  <tr>\n";
00312 
00313   if ( !event->allDay() ) {
00314     if ( event->isMultiDay( d->mCalendar->timeSpec() ) && ( event->dtStart().date() != date ) ) {
00315       *ts << "    <td>&nbsp;</td>\n";
00316     } else {
00317       *ts << "    <td valign=\"top\">"
00318           << IncidenceFormatter::timeToString( event->dtStart(), true, d->mCalendar->timeSpec() )
00319           << "</td>\n";
00320     }
00321     if ( event->isMultiDay( d->mCalendar->timeSpec() ) && ( event->dtEnd().date() != date ) ) {
00322       *ts << "    <td>&nbsp;</td>\n";
00323     } else {
00324       *ts << "    <td valign=\"top\">"
00325           << IncidenceFormatter::timeToString( event->dtEnd(), true, d->mCalendar->timeSpec() )
00326           << "</td>\n";
00327     }
00328   } else {
00329     *ts << "    <td>&nbsp;</td><td>&nbsp;</td>\n";
00330   }
00331 
00332   *ts << "    <td class=\"sum\">\n";
00333   *ts << "      <b>" << cleanChars( event->summary() ) << "</b>\n";
00334   if ( withDescription && !event->description().isEmpty() ) {
00335     *ts << "      <p>" << breakString( cleanChars( event->description() ) ) << "</p>\n";
00336   }
00337   *ts << "    </td>\n";
00338 
00339   if ( d->mSettings->eventLocation() ) {
00340     *ts << "  <td>\n";
00341     formatLocation( ts, event );
00342     *ts << "  </td>\n";
00343   }
00344 
00345   if ( d->mSettings->eventCategories() ) {
00346     *ts << "  <td>\n";
00347     formatCategories( ts, event );
00348     *ts << "  </td>\n";
00349   }
00350 
00351   if ( d->mSettings->eventAttendees() ) {
00352     *ts << "  <td>\n";
00353     formatAttendees( ts, event );
00354     *ts << "  </td>\n";
00355   }
00356 
00357   *ts << "  </tr>\n";
00358 }
00359 
00360 void HtmlExport::createTodoList ( QTextStream *ts )
00361 {
00362   Todo::List rawTodoList = d->mCalendar->todos();
00363 
00364   int index = 0;
00365   while ( index < rawTodoList.count() ) {
00366     Todo *ev = rawTodoList[ index ];
00367     Todo *subev = ev;
00368     if ( ev->relatedTo() ) {
00369       if ( ev->relatedTo()->type() == "Todo" ) {
00370         if ( !rawTodoList.contains( static_cast<Todo *>( ev->relatedTo() ) ) ) {
00371           rawTodoList.append( static_cast<Todo *>( ev->relatedTo() ) );
00372         }
00373       }
00374     }
00375     index = rawTodoList.indexOf( subev );
00376     ++index;
00377   }
00378 
00379   // FIXME: Sort list by priorities. This is brute force and should be
00380   // replaced by a real sorting algorithm.
00381   Todo::List todoList;
00382   Todo::List::ConstIterator it;
00383   for ( int i = 1; i <= 9; ++i ) {
00384     for ( it = rawTodoList.constBegin(); it != rawTodoList.constEnd(); ++it ) {
00385       if ( (*it)->priority() == i && checkSecrecy( *it ) ) {
00386         todoList.append( *it );
00387       }
00388     }
00389   }
00390   for ( it = rawTodoList.constBegin(); it != rawTodoList.constEnd(); ++it ) {
00391     if ( (*it)->priority() == 0 && checkSecrecy( *it ) ) {
00392       todoList.append( *it );
00393     }
00394   }
00395 
00396   int columns = 3;
00397   *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">\n";
00398   *ts << "  <tr>\n";
00399   *ts << "    <th class=\"sum\">" << i18nc( "@title:column", "To-do" ) << "</th>\n";
00400   *ts << "    <th>" << i18nc( "@title:column to-do priority", "Priority" ) << "</th>\n";
00401   *ts << "    <th>" << i18nc( "@title:column to-do percent completed", "Completed" ) << "</th>\n";
00402   if ( d->mSettings->taskDueDate() ) {
00403     *ts << "    <th>" << i18nc( "@title:column to-do due date", "Due Date" ) << "</th>\n";
00404     ++columns;
00405   }
00406   if ( d->mSettings->taskLocation() ) {
00407     *ts << "    <th>" << i18nc( "@title:column to-do location", "Location" ) << "</th>\n";
00408     ++columns;
00409   }
00410   if ( d->mSettings->taskCategories() ) {
00411     *ts << "    <th>" << i18nc( "@title:column to-do categories", "Categories" ) << "</th>\n";
00412     ++columns;
00413   }
00414   if ( d->mSettings->taskAttendees() ) {
00415     *ts << "    <th>" << i18nc( "@title:column to-do attendees", "Attendees" ) << "</th>\n";
00416     ++columns;
00417   }
00418   *ts << "  </tr>\n";
00419 
00420   // Create top-level list.
00421   for ( it = todoList.constBegin(); it != todoList.constEnd(); ++it ) {
00422     if ( !(*it)->relatedTo() ) {
00423       createTodo( ts, *it );
00424     }
00425   }
00426 
00427   // Create sub-level lists
00428   for ( it = todoList.constBegin(); it != todoList.constEnd(); ++it ) {
00429     Incidence::List relations = (*it)->relations();
00430     if ( relations.count() ) {
00431       // Generate sub-to-do list
00432       *ts << "  <tr>\n";
00433       *ts << "    <td class=\"subhead\" colspan=";
00434       *ts << "\"" << QString::number(columns) << "\"";
00435       *ts << "><a name=\"sub" << (*it)->uid() << "\"></a>"
00436           << i18nc( "@title:column sub-to-dos of the parent to-do",
00437                     "Sub-To-dos of: " ) << "<a href=\"#"
00438           << (*it)->uid() << "\"><b>" << cleanChars( (*it)->summary() )
00439           << "</b></a></td>\n";
00440       *ts << "  </tr>\n";
00441 
00442       Todo::List sortedList;
00443       // FIXME: Sort list by priorities. This is brute force and should be
00444       // replaced by a real sorting algorithm.
00445       for ( int i = 1; i <= 9; ++i ) {
00446         Incidence::List::ConstIterator it2;
00447         for ( it2 = relations.constBegin(); it2 != relations.constEnd(); ++it2 ) {
00448           Todo *ev3 = dynamic_cast<Todo *>( *it2 );
00449           if ( ev3 && ev3->priority() == i ) {
00450             sortedList.append( ev3 );
00451           }
00452         }
00453       }
00454       Incidence::List::ConstIterator it2;
00455       for ( it2 = relations.constBegin(); it2 != relations.constEnd(); ++it2 ) {
00456         Todo *ev3 = dynamic_cast<Todo *>( *it2 );
00457         if ( ev3 && ev3->priority() == 0 ) {
00458           sortedList.append( ev3 );
00459         }
00460       }
00461 
00462       Todo::List::ConstIterator it3;
00463       for ( it3 = sortedList.constBegin(); it3 != sortedList.constEnd(); ++it3 ) {
00464         createTodo( ts, *it3 );
00465       }
00466     }
00467   }
00468 
00469   *ts << "</table>\n";
00470 }
00471 
00472 void HtmlExport::createTodo( QTextStream *ts, Todo *todo )
00473 {
00474   kDebug();
00475 
00476   bool completed = todo->isCompleted();
00477   Incidence::List relations = todo->relations();
00478 
00479   *ts << "<tr>\n";
00480 
00481   *ts << "  <td class=\"sum";
00482   if (completed) *ts << "done";
00483   *ts << "\">\n";
00484   *ts << "    <a name=\"" << todo->uid() << "\"></a>\n";
00485   *ts << "    <b>" << cleanChars( todo->summary() ) << "</b>\n";
00486   if ( !todo->description().isEmpty() ) {
00487     *ts << "    <p>" << breakString( cleanChars( todo->description() ) ) << "</p>\n";
00488   }
00489   if ( relations.count() ) {
00490     *ts << "    <div align=\"right\"><a href=\"#sub" << todo->uid()
00491         << "\">" << i18nc( "@title:column sub-to-dos of the parent to-do",
00492                            "Sub-To-dos" ) << "</a></div>\n";
00493   }
00494   *ts << "  </td>\n";
00495 
00496   *ts << "  <td";
00497   if ( completed ) {
00498     *ts << " class=\"done\"";
00499   }
00500   *ts << ">\n";
00501   *ts << "    " << todo->priority() << "\n";
00502   *ts << "  </td>\n";
00503 
00504   *ts << "  <td";
00505   if ( completed ) {
00506     *ts << " class=\"done\"";
00507   }
00508   *ts << ">\n";
00509   *ts << "    " << i18nc( "@info/plain to-do percent complete",
00510                           "%1 %", todo->percentComplete() ) << "\n";
00511   *ts << "  </td>\n";
00512 
00513   if ( d->mSettings->taskDueDate() ) {
00514     *ts << "  <td";
00515     if ( completed ) {
00516       *ts << " class=\"done\"";
00517     }
00518     *ts << ">\n";
00519     if ( todo->hasDueDate() ) {
00520       *ts << "    " << IncidenceFormatter::dateToString(todo->dtDue(true)) << "\n";
00521     } else {
00522       *ts << "    &nbsp;\n";
00523     }
00524     *ts << "  </td>\n";
00525   }
00526 
00527   if ( d->mSettings->taskLocation() ) {
00528     *ts << "  <td";
00529     if ( completed ) {
00530       *ts << " class=\"done\"";
00531     }
00532     *ts << ">\n";
00533     formatLocation( ts, todo );
00534     *ts << "  </td>\n";
00535   }
00536 
00537   if ( d->mSettings->taskCategories() ) {
00538     *ts << "  <td";
00539     if ( completed ) {
00540       *ts << " class=\"done\"";
00541     }
00542     *ts << ">\n";
00543     formatCategories( ts, todo );
00544     *ts << "  </td>\n";
00545   }
00546 
00547   if ( d->mSettings->taskAttendees() ) {
00548     *ts << "  <td";
00549     if ( completed ) {
00550       *ts << " class=\"done\"";
00551     }
00552     *ts << ">\n";
00553     formatAttendees( ts, todo );
00554     *ts << "  </td>\n";
00555   }
00556 
00557   *ts << "</tr>\n";
00558 }
00559 
00560 void HtmlExport::createWeekView( QTextStream *ts )
00561 {
00562   Q_UNUSED( ts );
00563   // FIXME: Implement this!
00564 }
00565 
00566 void HtmlExport::createJournalView( QTextStream *ts )
00567 {
00568   Q_UNUSED( ts );
00569 //   Journal::List rawJournalList = d->mCalendar->journals();
00570   // FIXME: Implement this!
00571 }
00572 
00573 void HtmlExport::createFreeBusyView( QTextStream *ts )
00574 {
00575   Q_UNUSED( ts );
00576   // FIXME: Implement this!
00577 }
00578 
00579 bool HtmlExport::checkSecrecy( Incidence *incidence )
00580 {
00581   int secrecy = incidence->secrecy();
00582   if ( secrecy == Incidence::SecrecyPublic ) {
00583     return true;
00584   }
00585   if ( secrecy == Incidence::SecrecyPrivate && !d->mSettings->excludePrivate() ) {
00586     return true;
00587   }
00588   if ( secrecy == Incidence::SecrecyConfidential &&
00589        !d->mSettings->excludeConfidential() ) {
00590     return true;
00591   }
00592   return false;
00593 }
00594 
00595 void HtmlExport::formatLocation( QTextStream *ts, Incidence *incidence )
00596 {
00597   if ( !incidence->location().isEmpty() ) {
00598     *ts << "    " << cleanChars( incidence->location() ) << "\n";
00599   } else {
00600     *ts << "    &nbsp;\n";
00601   }
00602 }
00603 
00604 void HtmlExport::formatCategories( QTextStream *ts, Incidence *incidence )
00605 {
00606   if ( !incidence->categoriesStr().isEmpty() ) {
00607     *ts << "    " << cleanChars( incidence->categoriesStr() ) << "\n";
00608   } else {
00609     *ts << "    &nbsp;\n";
00610   }
00611 }
00612 
00613 void HtmlExport::formatAttendees( QTextStream *ts, Incidence *incidence )
00614 {
00615   Attendee::List attendees = incidence->attendees();
00616   if ( attendees.count() ) {
00617     *ts << "<em>";
00618 #ifndef KORG_NOKABC
00619     KABC::AddressBook *add_book = KABC::StdAddressBook::self( true );
00620     KABC::Addressee::List addressList;
00621     addressList = add_book->findByEmail( incidence->organizer().email() );
00622     if ( !addressList.isEmpty() ) {
00623       KABC::Addressee o = addressList.first();
00624       if ( !o.isEmpty() && addressList.size() < 2 ) {
00625         *ts << "<a href=\"mailto:" << incidence->organizer().email() << "\">";
00626         *ts << cleanChars( o.formattedName() ) << "</a>\n";
00627       } else {
00628         *ts << incidence->organizer().fullName();
00629       }
00630     }
00631 #else
00632     *ts << incidence->organizer().fullName();
00633 #endif
00634     *ts << "</em><br />";
00635     Attendee::List::ConstIterator it;
00636     for ( it = attendees.constBegin(); it != attendees.constEnd(); ++it ) {
00637       Attendee *a = *it;
00638       if ( !a->email().isEmpty() ) {
00639         *ts << "<a href=\"mailto:" << a->email();
00640         *ts << "\">" << cleanChars( a->name() ) << "</a>";
00641       } else {
00642         *ts << "    " << cleanChars( a->name() );
00643       }
00644       *ts << "<br />" << "\n";
00645     }
00646   } else {
00647     *ts << "    &nbsp;\n";
00648   }
00649 }
00650 
00651 QString HtmlExport::breakString( const QString &text )
00652 {
00653   int number = text.count( "\n" );
00654   if ( number <= 0 ) {
00655     return text;
00656   } else {
00657     QString out;
00658     QString tmpText = text;
00659     int pos = 0;
00660     QString tmp;
00661     for ( int i = 0; i <= number; ++i ) {
00662       pos = tmpText.indexOf( "\n" );
00663       tmp = tmpText.left( pos );
00664       tmpText = tmpText.right( tmpText.length() - pos - 1 );
00665       out += tmp + "<br />";
00666     }
00667     return out;
00668   }
00669 }
00670 
00671 void HtmlExport::createFooter( QTextStream *ts )
00672 {
00673   // FIXME: Implement this in a translatable way!
00674   QString trailer = i18nc( "@info/plain", "This page was created " );
00675 
00676 /*  bool hasPerson = false;
00677   bool hasCredit = false;
00678   bool hasCreditURL = false;
00679   QString mail, name, credit, creditURL;*/
00680   if ( !d->mSettings->eMail().isEmpty() ) {
00681     if ( !d->mSettings->name().isEmpty() ) {
00682       trailer += i18nc( "@info/plain page creator email link with name",
00683                         "by <link url='mailto:%1'>%2</link>",
00684                         d->mSettings->eMail(), d->mSettings->name() );
00685     } else {
00686       trailer += i18nc( "@info/plain page creator email link",
00687                         "by <link url='mailto:%1'>%2</link>",
00688                         d->mSettings->eMail(), d->mSettings->eMail() );
00689     }
00690   } else {
00691     if ( !d->mSettings->name().isEmpty() ) {
00692       trailer += i18nc( "@info/plain page creator name only",
00693                         "by %1 ", d->mSettings->name() );
00694     }
00695   }
00696   if ( !d->mSettings->creditName().isEmpty() ) {
00697     if ( !d->mSettings->creditURL().isEmpty() ) {
00698       trailer += i18nc( "@info/plain page credit with name and link",
00699                         "with <link url='%1'>%2</link>",
00700                         d->mSettings->creditURL(), d->mSettings->creditName() );
00701     } else {
00702       trailer += i18nc( "@info/plain page credit name only",
00703                         "with %1", d->mSettings->creditName() );
00704     }
00705   }
00706   *ts << "<p>" << trailer << "</p>\n";
00707 }
00708 
00709 QString cleanChars( const QString &text )
00710 {
00711   QString txt = text;
00712   txt = txt.replace( '&', "&amp;" );
00713   txt = txt.replace( '<', "&lt;" );
00714   txt = txt.replace( '>', "&gt;" );
00715   txt = txt.replace( '\"', "&quot;" );
00716   txt = txt.replace( QString::fromUtf8( "ä" ), "&auml;" );
00717   txt = txt.replace( QString::fromUtf8( "Ä" ), "&Auml;" );
00718   txt = txt.replace( QString::fromUtf8( "ö" ), "&ouml;" );
00719   txt = txt.replace( QString::fromUtf8( "Ö" ), "&Ouml;" );
00720   txt = txt.replace( QString::fromUtf8( "ü" ), "&uuml;" );
00721   txt = txt.replace( QString::fromUtf8( "Ü" ), "&Uuml;" );
00722   txt = txt.replace( QString::fromUtf8( "ß" ), "&szlig;" );
00723   txt = txt.replace( QString::fromUtf8( "€" ), "&euro;" );
00724   txt = txt.replace( QString::fromUtf8( "é" ), "&eacute;" );
00725 
00726   return txt;
00727 }
00728 
00729 QString HtmlExport::styleSheet() const
00730 {
00731   if ( !d->mSettings->styleSheet().isEmpty() ) {
00732     return d->mSettings->styleSheet();
00733   }
00734 
00735   QString css;
00736 
00737   if ( QApplication::isRightToLeft() ) {
00738     css += "    body { background-color:white; color:black; direction: rtl }\n";
00739     css += "    td { text-align:center; background-color:#eee }\n";
00740     css += "    th { text-align:center; background-color:#228; color:white }\n";
00741     css += "    td.sumdone { background-color:#ccc }\n";
00742     css += "    td.done { background-color:#ccc }\n";
00743     css += "    td.subhead { text-align:center; background-color:#ccf }\n";
00744     css += "    td.datehead { text-align:center; background-color:#ccf }\n";
00745     css += "    td.space { background-color:white }\n";
00746     css += "    td.dateholiday { color:red }\n";
00747   } else {
00748     css += "    body { background-color:white; color:black }\n";
00749     css += "    td { text-align:center; background-color:#eee }\n";
00750     css += "    th { text-align:center; background-color:#228; color:white }\n";
00751     css += "    td.sum { text-align:left }\n";
00752     css += "    td.sumdone { text-align:left; background-color:#ccc }\n";
00753     css += "    td.done { background-color:#ccc }\n";
00754     css += "    td.subhead { text-align:center; background-color:#ccf }\n";
00755     css += "    td.datehead { text-align:center; background-color:#ccf }\n";
00756     css += "    td.space { background-color:white }\n";
00757     css += "    td.date { text-align:left }\n";
00758     css += "    td.dateholiday { text-align:left; color:red }\n";
00759   }
00760 
00761   return css;
00762 }
00763 
00764 void HtmlExport::addHoliday( const QDate &date, const QString &name )
00765 {
00766   if ( d->mHolidayMap[date].isEmpty() ) {
00767     d->mHolidayMap[date] = name;
00768   } else {
00769     d->mHolidayMap[date] = i18nc( "@info/plain holiday by date and name",
00770                                   "%1, %2", d->mHolidayMap[date], name );
00771   }
00772 }
00773 
00774 QDate HtmlExport::fromDate() const
00775 {
00776   return d->mSettings->dateStart().date();
00777 }
00778 
00779 QDate HtmlExport::toDate() const
00780 {
00781   return d->mSettings->dateEnd().date();
00782 }

KCal Library

Skip menu "KCal Library"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.8
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal