• Skip to content
  • Skip to link menu
KDE 4.8 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • KDE Home
  • 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   // 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\">" << endl;
00102 
00103   *ts << "<html><head>" << endl;
00104   *ts << "  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=";
00105   *ts << "UTF-8\" />" << endl;
00106   if ( !d->mSettings->pageTitle().isEmpty() ) {
00107     *ts << "  <title>" << d->mSettings->pageTitle() << "</title>" << endl;
00108   }
00109   *ts << "  <style type=\"text/css\">" << endl;
00110   *ts << styleSheet();
00111   *ts << "  </style>" << endl;
00112   *ts << "</head><body>" << endl;
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>" << endl;
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>" << endl;
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>" << endl;
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>" << endl;
00156     }
00157     createFreeBusyView( ts );
00158   }
00159 
00160   createFooter( ts );
00161 
00162   // Write HTML trailer
00163   *ts << "</body></html>" << endl;
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     QDate hDate( start.year(), start.month(), 1 );
00181     QString hMon = hDate.toString( "MMMM" );
00182     QString hYear = hDate.toString( "yyyy" );
00183     *ts << "<h2>"
00184         << i18nc( "@title month and year", "%1 %2", hMon, hYear )
00185         << "</h2>" << endl;
00186     if ( KGlobal::locale()->weekStartDay() == 1 ) {
00187       start = start.addDays( 1 - start.dayOfWeek() );
00188     } else {
00189       if ( start.dayOfWeek() != 7 ) {
00190         start = start.addDays( -start.dayOfWeek() );
00191       }
00192     }
00193     *ts << "<table border=\"1\">" << endl;
00194 
00195     // Write table header
00196     *ts << "  <tr>";
00197     for ( int i=0; i < 7; ++i ) {
00198       *ts << "<th>" << KGlobal::locale()->calendar()->weekDayName( start.addDays(i) ) << "</th>";
00199     }
00200     *ts << "</tr>" << endl;
00201 
00202     // Write days
00203     while ( start <= end ) {
00204       *ts << "  <tr>" << endl;
00205       for ( int i=0; i < 7; ++i ) {
00206         *ts << "    <td valign=\"top\"><table border=\"0\">";
00207 
00208         *ts << "<tr><td ";
00209         if ( d->mHolidayMap.contains( start ) || start.dayOfWeek() == 7 ) {
00210           *ts << "class=\"dateholiday\"";
00211         } else {
00212           *ts << "class=\"date\"";
00213         }
00214         *ts << ">" << QString::number( start.day() );
00215 
00216         if ( d->mHolidayMap.contains( start ) ) {
00217           *ts << " <em>" << d->mHolidayMap[start] << "</em>";
00218         }
00219 
00220         *ts << "</td></tr><tr><td valign=\"top\">";
00221 
00222         // Only print events within the from-to range
00223         if ( start >= fromDate() && start <= toDate() ) {
00224           Event::List events = d->mCalendar->events( start, d->mCalendar->timeSpec(),
00225                                                      EventSortStartDate,
00226                                                      SortDirectionAscending );
00227           if ( events.count() ) {
00228             *ts << "<table>";
00229             Event::List::ConstIterator it;
00230             for ( it = events.constBegin(); it != events.constEnd(); ++it ) {
00231               if ( checkSecrecy( *it ) ) {
00232                 createEvent( ts, *it, start, false );
00233               }
00234             }
00235             *ts << "</table>";
00236           } else {
00237             *ts << "&nbsp;";
00238           }
00239         }
00240 
00241         *ts << "</td></tr></table></td>" << endl;
00242         start = start.addDays( 1 );
00243       }
00244       *ts << "  </tr>" << endl;
00245     }
00246     *ts << "</table>" << endl;
00247     startmonth += 1;
00248     if ( startmonth > 12 ) {
00249       startyear += 1;
00250       startmonth = 1;
00251     }
00252     start.setYMD( startyear, startmonth, 1 );
00253     end.setYMD( start.year(), start.month(), start.daysInMonth() );
00254   }
00255 }
00256 
00257 void HtmlExport::createEventList( QTextStream *ts )
00258 {
00259   int columns = 3;
00260   *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">" << endl;
00261   *ts << "  <tr>" << endl;
00262   *ts << "    <th class=\"sum\">" << i18nc( "@title:column event start time",
00263                                             "Start Time" ) << "</th>" << endl;
00264   *ts << "    <th>" << i18nc( "@title:column event end time",
00265                               "End Time" ) << "</th>" << endl;
00266   *ts << "    <th>" << i18nc( "@title:column event description",
00267                               "Event" ) << "</th>" << endl;
00268   if ( d->mSettings->eventLocation() ) {
00269     *ts << "    <th>" << i18nc( "@title:column event location",
00270                                 "Location" ) << "</th>" << endl;
00271     ++columns;
00272   }
00273   if ( d->mSettings->eventCategories() ) {
00274     *ts << "    <th>" << i18nc( "@title:column event categories",
00275                                 "Categories" ) << "</th>" << endl;
00276     ++columns;
00277   }
00278   if ( d->mSettings->eventAttendees() ) {
00279     *ts << "    <th>" << i18nc( "@title:column event attendees",
00280                                 "Attendees" ) << "</th>" << endl;
00281     ++columns;
00282   }
00283 
00284   *ts << "  </tr>" << endl;
00285 
00286   for ( QDate dt = fromDate(); dt <= toDate(); dt = dt.addDays(1) ) {
00287     kDebug() << "Getting events for" << dt.toString();
00288     Event::List events = d->mCalendar->events( dt, d->mCalendar->timeSpec(),
00289                                                EventSortStartDate,
00290                                                SortDirectionAscending );
00291     if ( events.count() ) {
00292       *ts << "  <tr><td colspan=\"" << QString::number( columns )
00293           << "\" class=\"datehead\"><i>"
00294           << KGlobal::locale()->formatDate( dt )
00295           << "</i></td></tr>" << endl;
00296 
00297       Event::List::ConstIterator it;
00298       for ( it = events.constBegin(); it != events.constEnd(); ++it ) {
00299         if ( checkSecrecy( *it ) ) {
00300           createEvent( ts, *it, dt );
00301         }
00302       }
00303     }
00304   }
00305 
00306   *ts << "</table>" << endl;
00307 }
00308 
00309 void HtmlExport::createEvent ( QTextStream *ts, Event *event,
00310                                QDate date, bool withDescription )
00311 {
00312   kDebug() << event->summary();
00313   *ts << "  <tr>" << endl;
00314 
00315   if ( !event->allDay() ) {
00316     if ( event->isMultiDay( d->mCalendar->timeSpec() ) && ( event->dtStart().date() != date ) ) {
00317       *ts << "    <td>&nbsp;</td>" << endl;
00318     } else {
00319       *ts << "    <td valign=\"top\">"
00320           << IncidenceFormatter::timeToString( event->dtStart(), true, d->mCalendar->timeSpec() )
00321           << "</td>" << endl;
00322     }
00323     if ( event->isMultiDay( d->mCalendar->timeSpec() ) && ( event->dtEnd().date() != date ) ) {
00324       *ts << "    <td>&nbsp;</td>" << endl;
00325     } else {
00326       *ts << "    <td valign=\"top\">"
00327           << IncidenceFormatter::timeToString( event->dtEnd(), true, d->mCalendar->timeSpec() )
00328           << "</td>" << endl;
00329     }
00330   } else {
00331     *ts << "    <td>&nbsp;</td><td>&nbsp;</td>" << endl;
00332   }
00333 
00334   *ts << "    <td class=\"sum\">" << endl;
00335   *ts << "      <b>" << cleanChars( event->summary() ) << "</b>" << endl;
00336   if ( withDescription && !event->description().isEmpty() ) {
00337     *ts << "      <p>" << breakString( cleanChars( event->description() ) ) << "</p>" << endl;
00338   }
00339   *ts << "    </td>" << endl;
00340 
00341   if ( d->mSettings->eventLocation() ) {
00342     *ts << "  <td>" << endl;
00343     formatLocation( ts, event );
00344     *ts << "  </td>" << endl;
00345   }
00346 
00347   if ( d->mSettings->eventCategories() ) {
00348     *ts << "  <td>" << endl;
00349     formatCategories( ts, event );
00350     *ts << "  </td>" << endl;
00351   }
00352 
00353   if ( d->mSettings->eventAttendees() ) {
00354     *ts << "  <td>" << endl;
00355     formatAttendees( ts, event );
00356     *ts << "  </td>" << endl;
00357   }
00358 
00359   *ts << "  </tr>" << endl;
00360 }
00361 
00362 void HtmlExport::createTodoList ( QTextStream *ts )
00363 {
00364   Todo::List rawTodoList = d->mCalendar->todos();
00365 
00366   int index = 0;
00367   while ( index < rawTodoList.count() ) {
00368     Todo *ev = rawTodoList[ index ];
00369     Todo *subev = ev;
00370     if ( ev->relatedTo() ) {
00371       if ( ev->relatedTo()->type() == "Todo" ) {
00372         if ( !rawTodoList.contains( static_cast<Todo *>( ev->relatedTo() ) ) ) {
00373           rawTodoList.append( static_cast<Todo *>( ev->relatedTo() ) );
00374         }
00375       }
00376     }
00377     index = rawTodoList.indexOf( subev );
00378     ++index;
00379   }
00380 
00381   // FIXME: Sort list by priorities. This is brute force and should be
00382   // replaced by a real sorting algorithm.
00383   Todo::List todoList;
00384   Todo::List::ConstIterator it;
00385   for ( int i = 1; i <= 9; ++i ) {
00386     for ( it = rawTodoList.constBegin(); it != rawTodoList.constEnd(); ++it ) {
00387       if ( (*it)->priority() == i && checkSecrecy( *it ) ) {
00388         todoList.append( *it );
00389       }
00390     }
00391   }
00392   for ( it = rawTodoList.constBegin(); it != rawTodoList.constEnd(); ++it ) {
00393     if ( (*it)->priority() == 0 && checkSecrecy( *it ) ) {
00394       todoList.append( *it );
00395     }
00396   }
00397 
00398   int columns = 3;
00399   *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">" << endl;
00400   *ts << "  <tr>" << endl;
00401   *ts << "    <th class=\"sum\">" << i18nc( "@title:column", "To-do" ) << "</th>" << endl;
00402   *ts << "    <th>" << i18nc( "@title:column to-do priority", "Priority" ) << "</th>" << endl;
00403   *ts << "    <th>" << i18nc( "@title:column to-do percent completed",
00404                               "Completed" ) << "</th>" << endl;
00405   if ( d->mSettings->taskDueDate() ) {
00406     *ts << "    <th>" << i18nc( "@title:column to-do due date", "Due Date" ) << "</th>" << endl;
00407     ++columns;
00408   }
00409   if ( d->mSettings->taskLocation() ) {
00410     *ts << "    <th>" << i18nc( "@title:column to-do location", "Location" ) << "</th>" << endl;
00411     ++columns;
00412   }
00413   if ( d->mSettings->taskCategories() ) {
00414     *ts << "    <th>" << i18nc( "@title:column to-do categories", "Categories" ) << "</th>" << endl;
00415     ++columns;
00416   }
00417   if ( d->mSettings->taskAttendees() ) {
00418     *ts << "    <th>" << i18nc( "@title:column to-do attendees", "Attendees" ) << "</th>" << endl;
00419     ++columns;
00420   }
00421   *ts << "  </tr>" << endl;
00422 
00423   // Create top-level list.
00424   for ( it = todoList.constBegin(); it != todoList.constEnd(); ++it ) {
00425     if ( !(*it)->relatedTo() ) {
00426       createTodo( ts, *it );
00427     }
00428   }
00429 
00430   // Create sub-level lists
00431   for ( it = todoList.constBegin(); it != todoList.constEnd(); ++it ) {
00432     Incidence::List relations = (*it)->relations();
00433     if ( relations.count() ) {
00434       // Generate sub-to-do list
00435       *ts << "  <tr>" << endl;
00436       *ts << "    <td class=\"subhead\" colspan=";
00437       *ts << "\"" << QString::number(columns) << "\"";
00438       *ts << "><a name=\"sub" << (*it)->uid() << "\"></a>"
00439           << i18nc( "@title:column sub-to-dos of the parent to-do",
00440                     "Sub-To-dos of: " ) << "<a href=\"#"
00441           << (*it)->uid() << "\"><b>" << cleanChars( (*it)->summary() )
00442           << "</b></a></td>" << endl;
00443       *ts << "  </tr>" << endl;
00444 
00445       Todo::List sortedList;
00446       // FIXME: Sort list by priorities. This is brute force and should be
00447       // replaced by a real sorting algorithm.
00448       for ( int i = 1; i <= 9; ++i ) {
00449         Incidence::List::ConstIterator it2;
00450         for ( it2 = relations.constBegin(); it2 != relations.constEnd(); ++it2 ) {
00451           Todo *ev3 = dynamic_cast<Todo *>( *it2 );
00452           if ( ev3 && ev3->priority() == i ) {
00453             sortedList.append( ev3 );
00454           }
00455         }
00456       }
00457       Incidence::List::ConstIterator it2;
00458       for ( it2 = relations.constBegin(); it2 != relations.constEnd(); ++it2 ) {
00459         Todo *ev3 = dynamic_cast<Todo *>( *it2 );
00460         if ( ev3 && ev3->priority() == 0 ) {
00461           sortedList.append( ev3 );
00462         }
00463       }
00464 
00465       Todo::List::ConstIterator it3;
00466       for ( it3 = sortedList.constBegin(); it3 != sortedList.constEnd(); ++it3 ) {
00467         createTodo( ts, *it3 );
00468       }
00469     }
00470   }
00471 
00472   *ts << "</table>" << endl;
00473 }
00474 
00475 void HtmlExport::createTodo( QTextStream *ts, Todo *todo )
00476 {
00477   kDebug();
00478 
00479   bool completed = todo->isCompleted();
00480   Incidence::List relations = todo->relations();
00481 
00482   *ts << "<tr>" << endl;
00483 
00484   *ts << "  <td class=\"sum";
00485   if (completed) *ts << "done";
00486   *ts << "\">" << endl;
00487   *ts << "    <a name=\"" << todo->uid() << "\"></a>" << endl;
00488   *ts << "    <b>" << cleanChars( todo->summary() ) << "</b>" << endl;
00489   if ( !todo->description().isEmpty() ) {
00490     *ts << "    <p>" << breakString( cleanChars( todo->description() ) ) << "</p>" << endl;
00491   }
00492   if ( relations.count() ) {
00493     *ts << "    <div align=\"right\"><a href=\"#sub" << todo->uid()
00494         << "\">" << i18nc( "@title:column sub-to-dos of the parent to-do",
00495                            "Sub-To-dos" ) << "</a></div>" << endl;
00496   }
00497   *ts << "  </td>" << endl;
00498 
00499   *ts << "  <td";
00500   if ( completed ) {
00501     *ts << " class=\"done\"";
00502   }
00503   *ts << ">" << endl;
00504   *ts << "    " << todo->priority() << endl;
00505   *ts << "  </td>" << endl;
00506 
00507   *ts << "  <td";
00508   if ( completed ) {
00509     *ts << " class=\"done\"";
00510   }
00511   *ts << ">" << endl;
00512   *ts << "    " << i18nc( "@info/plain to-do percent complete",
00513                           "%1 %", todo->percentComplete() ) << endl;
00514   *ts << "  </td>" << endl;
00515 
00516   if ( d->mSettings->taskDueDate() ) {
00517     *ts << "  <td";
00518     if ( completed ) {
00519       *ts << " class=\"done\"";
00520     }
00521     *ts << ">" << endl;
00522     if ( todo->hasDueDate() ) {
00523       *ts << "    " << IncidenceFormatter::dateToString( todo->dtDue( true ) ) << endl;
00524     } else {
00525       *ts << "    &nbsp;" << endl;
00526     }
00527     *ts << "  </td>" << endl;
00528   }
00529 
00530   if ( d->mSettings->taskLocation() ) {
00531     *ts << "  <td";
00532     if ( completed ) {
00533       *ts << " class=\"done\"";
00534     }
00535     *ts << ">" << endl;
00536     formatLocation( ts, todo );
00537     *ts << "  </td>" << endl;
00538   }
00539 
00540   if ( d->mSettings->taskCategories() ) {
00541     *ts << "  <td";
00542     if ( completed ) {
00543       *ts << " class=\"done\"";
00544     }
00545     *ts << ">" << endl;
00546     formatCategories( ts, todo );
00547     *ts << "  </td>" << endl;
00548   }
00549 
00550   if ( d->mSettings->taskAttendees() ) {
00551     *ts << "  <td";
00552     if ( completed ) {
00553       *ts << " class=\"done\"";
00554     }
00555     *ts << ">" << endl;
00556     formatAttendees( ts, todo );
00557     *ts << "  </td>" << endl;
00558   }
00559 
00560   *ts << "</tr>" << endl;
00561 }
00562 
00563 void HtmlExport::createWeekView( QTextStream *ts )
00564 {
00565   Q_UNUSED( ts );
00566   // FIXME: Implement this!
00567 }
00568 
00569 void HtmlExport::createJournalView( QTextStream *ts )
00570 {
00571   Q_UNUSED( ts );
00572 //   Journal::List rawJournalList = d->mCalendar->journals();
00573   // FIXME: Implement this!
00574 }
00575 
00576 void HtmlExport::createFreeBusyView( QTextStream *ts )
00577 {
00578   Q_UNUSED( ts );
00579   // FIXME: Implement this!
00580 }
00581 
00582 bool HtmlExport::checkSecrecy( Incidence *incidence )
00583 {
00584   int secrecy = incidence->secrecy();
00585   if ( secrecy == Incidence::SecrecyPublic ) {
00586     return true;
00587   }
00588   if ( secrecy == Incidence::SecrecyPrivate && !d->mSettings->excludePrivate() ) {
00589     return true;
00590   }
00591   if ( secrecy == Incidence::SecrecyConfidential &&
00592        !d->mSettings->excludeConfidential() ) {
00593     return true;
00594   }
00595   return false;
00596 }
00597 
00598 void HtmlExport::formatLocation( QTextStream *ts, Incidence *incidence )
00599 {
00600   if ( !incidence->location().isEmpty() ) {
00601     *ts << "    " << cleanChars( incidence->location() ) << endl;
00602   } else {
00603     *ts << "    &nbsp;" << endl;
00604   }
00605 }
00606 
00607 void HtmlExport::formatCategories( QTextStream *ts, Incidence *incidence )
00608 {
00609   if ( !incidence->categoriesStr().isEmpty() ) {
00610     *ts << "    " << cleanChars( incidence->categoriesStr() ) << endl;
00611   } else {
00612     *ts << "    &nbsp;" << endl;
00613   }
00614 }
00615 
00616 void HtmlExport::formatAttendees( QTextStream *ts, Incidence *incidence )
00617 {
00618   Attendee::List attendees = incidence->attendees();
00619   if ( attendees.count() ) {
00620     *ts << "<em>";
00621 #if !defined(KORG_NOKABC) && !defined(KDEPIM_NO_KRESOURCES)
00622     KABC::AddressBook *add_book = KABC::StdAddressBook::self( true );
00623     KABC::Addressee::List addressList;
00624     addressList = add_book->findByEmail( incidence->organizer().email() );
00625     if ( !addressList.isEmpty() ) {
00626       KABC::Addressee o = addressList.first();
00627       if ( !o.isEmpty() && addressList.size() < 2 ) {
00628         *ts << "<a href=\"mailto:" << incidence->organizer().email() << "\">";
00629         *ts << cleanChars( o.formattedName() ) << "</a>" << endl;
00630       } else {
00631         *ts << incidence->organizer().fullName();
00632       }
00633     }
00634 #else
00635     *ts << incidence->organizer().fullName();
00636 #endif
00637     *ts << "</em><br />";
00638     Attendee::List::ConstIterator it;
00639     for ( it = attendees.constBegin(); it != attendees.constEnd(); ++it ) {
00640       Attendee *a = *it;
00641       if ( !a->email().isEmpty() ) {
00642         *ts << "<a href=\"mailto:" << a->email();
00643         *ts << "\">" << cleanChars( a->name() ) << "</a>";
00644       } else {
00645         *ts << "    " << cleanChars( a->name() );
00646       }
00647       *ts << "<br />" << endl;
00648     }
00649   } else {
00650     *ts << "    &nbsp;" << endl;
00651   }
00652 }
00653 
00654 QString HtmlExport::breakString( const QString &text )
00655 {
00656   int number = text.count( "\n" );
00657   if ( number <= 0 ) {
00658     return text;
00659   } else {
00660     QString out;
00661     QString tmpText = text;
00662     int pos = 0;
00663     QString tmp;
00664     for ( int i = 0; i <= number; ++i ) {
00665       pos = tmpText.indexOf( "\n" );
00666       tmp = tmpText.left( pos );
00667       tmpText = tmpText.right( tmpText.length() - pos - 1 );
00668       out += tmp + "<br />";
00669     }
00670     return out;
00671   }
00672 }
00673 
00674 void HtmlExport::createFooter( QTextStream *ts )
00675 {
00676   // FIXME: Implement this in a translatable way!
00677   QString trailer = i18nc( "@info/plain", "This page was created " );
00678 
00679 /*  bool hasPerson = false;
00680   bool hasCredit = false;
00681   bool hasCreditURL = false;
00682   QString mail, name, credit, creditURL;*/
00683   if ( !d->mSettings->eMail().isEmpty() ) {
00684     if ( !d->mSettings->name().isEmpty() ) {
00685       trailer += i18nc( "@info/plain page creator email link with name",
00686                         "by <link url='mailto:%1'>%2</link> ",
00687                         d->mSettings->eMail(), d->mSettings->name() );
00688     } else {
00689       trailer += i18nc( "@info/plain page creator email link",
00690                         "by <link url='mailto:%1'>%2</link> ",
00691                         d->mSettings->eMail(), d->mSettings->eMail() );
00692     }
00693   } else {
00694     if ( !d->mSettings->name().isEmpty() ) {
00695       trailer += i18nc( "@info/plain page creator name only",
00696                         "by %1 ", d->mSettings->name() );
00697     }
00698   }
00699   if ( !d->mSettings->creditName().isEmpty() ) {
00700     if ( !d->mSettings->creditURL().isEmpty() ) {
00701       trailer += i18nc( "@info/plain page credit with name and link",
00702                         "with <link url='%1'>%2</link>",
00703                         d->mSettings->creditURL(), d->mSettings->creditName() );
00704     } else {
00705       trailer += i18nc( "@info/plain page credit name only",
00706                         "with %1", d->mSettings->creditName() );
00707     }
00708   }
00709   *ts << "<p>" << trailer << "</p>" << endl;
00710 }
00711 
00712 QString cleanChars( const QString &text )
00713 {
00714   QString txt = text;
00715   txt = txt.replace( '&', "&amp;" );
00716   txt = txt.replace( '<', "&lt;" );
00717   txt = txt.replace( '>', "&gt;" );
00718   txt = txt.replace( '\"', "&quot;" );
00719   txt = txt.replace( QString::fromUtf8( "ä" ), "&auml;" );
00720   txt = txt.replace( QString::fromUtf8( "Ä" ), "&Auml;" );
00721   txt = txt.replace( QString::fromUtf8( "ö" ), "&ouml;" );
00722   txt = txt.replace( QString::fromUtf8( "Ö" ), "&Ouml;" );
00723   txt = txt.replace( QString::fromUtf8( "ü" ), "&uuml;" );
00724   txt = txt.replace( QString::fromUtf8( "Ü" ), "&Uuml;" );
00725   txt = txt.replace( QString::fromUtf8( "ß" ), "&szlig;" );
00726   txt = txt.replace( QString::fromUtf8( "€" ), "&euro;" );
00727   txt = txt.replace( QString::fromUtf8( "é" ), "&eacute;" );
00728 
00729   return txt;
00730 }
00731 
00732 QString HtmlExport::styleSheet() const
00733 {
00734   if ( !d->mSettings->styleSheet().isEmpty() ) {
00735     return d->mSettings->styleSheet();
00736   }
00737 
00738   QString css;
00739 
00740   if ( QApplication::isRightToLeft() ) {
00741     css += "    body { background-color:white; color:black; direction: rtl }\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.sumdone { background-color:#ccc }\n";
00745     css += "    td.done { background-color:#ccc }\n";
00746     css += "    td.subhead { text-align:center; background-color:#ccf }\n";
00747     css += "    td.datehead { text-align:center; background-color:#ccf }\n";
00748     css += "    td.space { background-color:white }\n";
00749     css += "    td.dateholiday { color:red }\n";
00750   } else {
00751     css += "    body { background-color:white; color:black }\n";
00752     css += "    td { text-align:center; background-color:#eee }\n";
00753     css += "    th { text-align:center; background-color:#228; color:white }\n";
00754     css += "    td.sum { text-align:left }\n";
00755     css += "    td.sumdone { text-align:left; background-color:#ccc }\n";
00756     css += "    td.done { background-color:#ccc }\n";
00757     css += "    td.subhead { text-align:center; background-color:#ccf }\n";
00758     css += "    td.datehead { text-align:center; background-color:#ccf }\n";
00759     css += "    td.space { background-color:white }\n";
00760     css += "    td.date { text-align:left }\n";
00761     css += "    td.dateholiday { text-align:left; color:red }\n";
00762   }
00763 
00764   return css;
00765 }
00766 
00767 void HtmlExport::addHoliday( const QDate &date, const QString &name )
00768 {
00769   if ( d->mHolidayMap[date].isEmpty() ) {
00770     d->mHolidayMap[date] = name;
00771   } else {
00772     d->mHolidayMap[date] = i18nc( "@info/plain holiday by date and name",
00773                                   "%1, %2", d->mHolidayMap[date], name );
00774   }
00775 }
00776 
00777 QDate HtmlExport::fromDate() const
00778 {
00779   return d->mSettings->dateStart().date();
00780 }
00781 
00782 QDate HtmlExport::toDate() const
00783 {
00784   return d->mSettings->dateEnd().date();
00785 }

KCal Library

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.6.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