• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • KDE Home
  • Contact Us
 

KCalUtils Library

htmlexport.cpp

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

KCalUtils Library

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • 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.3
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