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

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
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.7.1
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