htmlexport.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qapplication.h>
00025 #include <qfile.h>
00026 #include <qtextstream.h>
00027 #include <qtextcodec.h>
00028 #include <qregexp.h>
00029
00030 #include <kglobal.h>
00031 #include <klocale.h>
00032 #include <kdebug.h>
00033
00034 #include <libkcal/calendar.h>
00035 #include <libkcal/event.h>
00036 #include <libkcal/todo.h>
00037
00038 #include "kocore.h"
00039 #include "koprefs.h"
00040 #ifndef KORG_NOKABC
00041 #include <kabc/stdaddressbook.h>
00042 #endif
00043 #include "htmlexport.h"
00044
00045 bool HtmlExport::save(const QString &fileName)
00046 {
00047 QFile f(fileName);
00048 if (!f.open(IO_WriteOnly)) {
00049 return false;
00050 }
00051 QTextStream ts(&f);
00052 bool success = save(&ts);
00053 f.close();
00054 return success;
00055 }
00056
00057 bool HtmlExport::save(QTextStream *ts)
00058 {
00059 ts->setEncoding(QTextStream::UnicodeUTF8);
00060
00061
00062 *ts << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" ";
00063 *ts << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
00064
00065 *ts << "<html><head>" << endl;
00066 *ts << " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=";
00067 *ts << "UTF-8\" />\n";
00068 *ts << " <title>" << i18n("KOrganizer To-Do List") << "</title>\n";
00069 *ts << " <style type=\"text/css\">\n";
00070 *ts << styleSheet();
00071 *ts << " </style>\n";
00072 *ts << "</head><body>\n";
00073
00074
00075
00076
00077 if (eventsEnabled() || monthViewEnabled()) {
00078 *ts << "<h1>" << i18n("KOrganizer Calendar") << "</h1>\n";
00079 }
00080
00081
00082 if (monthViewEnabled()) {
00083 createHtmlMonthView(ts);
00084 }
00085
00086
00087 if (eventsEnabled()) {
00088
00089 createHtmlEventList(ts);
00090 }
00091
00092
00093 if (todosEnabled()) {
00094 *ts << "<h1>" << i18n("KOrganizer To-Do List") << "</h1>\n";
00095
00096
00097 createHtmlTodoList(ts);
00098 }
00099
00100
00101 *ts << "<p>" << i18n("This page was created by ");
00102 *ts << "<a href=\"mailto:" << KOPrefs::instance()->email() << "\">";
00103 *ts << KOPrefs::instance()->fullName() << "</a>";
00104 *ts << i18n(" with <a href=\"http://korganizer.kde.org\">KOrganizer</a>");
00105 *ts << "</p>\n";
00106
00107
00108 *ts << "</body></html>\n";
00109
00110 return true;
00111 }
00112
00113 void HtmlExport::createHtmlMonthView(QTextStream *ts)
00114 {
00115 QDate start = fromDate();
00116 start.setYMD(start.year(),start.month(),1);
00117
00118 QDate end(start.year(),start.month(),start.daysInMonth());
00119
00120 int startmonth = start.month();
00121 int startyear = start.year();
00122
00123 while ( start < toDate() ) {
00124
00125 *ts << "<h2>" << (i18n("month_year","%1 %2").arg(KGlobal::locale()->monthName(start.month()))
00126 .arg(start.year())) << "</h2>\n";
00127 if (KGlobal::locale()->weekStartsMonday()) {
00128 start = start.addDays(1 - start.dayOfWeek());
00129 } else {
00130 if (start.dayOfWeek() != 7) {
00131 start = start.addDays(-start.dayOfWeek());
00132 }
00133 }
00134 *ts << "<table border=\"1\">\n";
00135
00136
00137 *ts << " <tr>";
00138 for(int i=0; i<7; ++i) {
00139 *ts << "<th>" << KGlobal::locale()->weekDayName(start.addDays(i).dayOfWeek()) << "</th>";
00140 }
00141 *ts << "</tr>\n";
00142
00143
00144 while (start <= end) {
00145 *ts << " <tr>\n";
00146 for(int i=0;i<7;++i) {
00147 *ts << " <td valign=\"top\"><table border=\"0\">";
00148
00149 QString holiday = KOCore::self()->holiday(start);
00150
00151 *ts << "<tr><td ";
00152 if (!holiday.isEmpty() || start.dayOfWeek() == 7) {
00153 *ts << "class=\"dateholiday\"";
00154 } else {
00155 *ts << "class=\"date\"";
00156 }
00157 *ts << ">" << QString::number(start.day());
00158
00159 if (!holiday.isEmpty()) {
00160 *ts << " <em>" << holiday << "</em>";
00161 }
00162
00163 *ts << "</td></tr><tr><td valign=\"top\">";
00164
00165 QPtrList<Event> events = mCalendar->events(start,true);
00166 if (events.count()) {
00167 *ts << "<table>";
00168 Event *ev;
00169 for(ev = events.first(); ev; ev = events.next()) {
00170 if ( checkSecrecy( ev ) ) {
00171 createHtmlEvent(ts,ev,start,false);
00172 }
00173 }
00174 *ts << "</table>";
00175 } else {
00176 *ts << " ";
00177 }
00178
00179 *ts << "</td></tr></table></td>\n";
00180 start = start.addDays(1);
00181 }
00182 *ts << " </tr>\n";
00183 }
00184 *ts << "</table>\n";
00185 startmonth += 1;
00186 if ( startmonth > 12 ) {
00187 startyear += 1;
00188 startmonth = 1;
00189 }
00190 start.setYMD( startyear, startmonth, 1 );
00191 end.setYMD(start.year(),start.month(),start.daysInMonth());
00192 }
00193 }
00194
00195 void HtmlExport::createHtmlEventList (QTextStream *ts)
00196 {
00197 *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">\n";
00198 *ts << " <tr>\n";
00199 *ts << " <th class=\"sum\">" << i18n("Start Time") << "</th>\n";
00200 *ts << " <th>" << i18n("End Time") << "</th>\n";
00201 *ts << " <th>" << i18n("Event") << "</th>\n";
00202 if (categoriesEventEnabled()) {
00203 *ts << " <th>" << i18n("Categories") << "</th>\n";
00204 }
00205 if (attendeesEventEnabled()) {
00206 *ts << " <th>" << i18n("Attendees") << "</th>\n";
00207 }
00208
00209 *ts << " </tr>\n";
00210
00211 int columns = 3;
00212 if (categoriesEventEnabled()) ++columns;
00213 if (attendeesEventEnabled()) ++columns;
00214
00215 for (QDate dt = fromDate(); dt <= toDate(); dt = dt.addDays(1)) {
00216 kdDebug() << "Getting events for " << dt.toString() << endl;
00217 QPtrList<Event> events = mCalendar->events(dt,true);
00218 if (events.count()) {
00219 *ts << " <tr><td colspan=\"" << QString::number(columns)
00220 << "\" class=\"datehead\"><i>"
00221 << KGlobal::locale()->formatDate(dt)
00222 << "</i></td></tr>\n";
00223 Event *ev;
00224 for(ev = events.first(); ev; ev = events.next()) {
00225 if ( checkSecrecy( ev ) ) {
00226 createHtmlEvent(ts,ev,dt);
00227 }
00228 }
00229 }
00230 }
00231
00232 *ts << "</table>\n";
00233 }
00234
00235 void HtmlExport::createHtmlEvent (QTextStream *ts, Event *event,
00236 QDate date,bool withDescription)
00237 {
00238 kdDebug() << "HtmlExport::createHtmlEvent(): " << event->summary() << endl;
00239 *ts << " <tr>\n";
00240
00241 if (!event->doesFloat()) {
00242 if (event->isMultiDay() && (event->dtStart().date() != date)) {
00243 *ts << " <td> </td>\n";
00244 } else {
00245 *ts << " <td valign=\"top\">" << event->dtStartTimeStr() << "</td>\n";
00246 }
00247 if (event->isMultiDay() && (event->dtEnd().date() != date)) {
00248 *ts << " <td> </td>\n";
00249 } else {
00250 *ts << " <td valign=\"top\">" << event->dtEndTimeStr() << "</td>\n";
00251 }
00252 } else {
00253 *ts << " <td> </td><td> </td>\n";
00254 }
00255
00256 *ts << " <td class=\"sum\">\n";
00257 *ts << " <b>" << cleanChars(event->summary()) << "</b>\n";
00258 if (withDescription && !event->description().isEmpty()) {
00259 *ts << " <p>" << breakString(cleanChars(event->description())) << "</p>\n";
00260 }
00261 *ts << " </td>\n";
00262
00263 if (categoriesEventEnabled()) {
00264 *ts << " <td>\n";
00265 formatHtmlCategories(ts,event);
00266 *ts << " </td>\n";
00267 }
00268
00269 if (attendeesEventEnabled()) {
00270 *ts << " <td>\n";
00271 formatHtmlAttendees(ts,event);
00272 *ts << " </td>\n";
00273 }
00274
00275 *ts << " </tr>\n";
00276 }
00277
00278 void HtmlExport::createHtmlTodoList (QTextStream *ts)
00279 {
00280 Todo *ev,*subev;
00281
00282 QPtrList<Todo> rawTodoList = mCalendar->todos();
00283 QPtrList<Todo> todoList;
00284
00285 ev = rawTodoList.first();
00286 while (ev) {
00287 subev = ev;
00288 if (ev->relatedTo()) {
00289 if (ev->relatedTo()->type()=="Todo") {
00290 if (rawTodoList.find(static_cast<Todo*>(ev->relatedTo()))<0) {
00291 rawTodoList.append(static_cast<Todo*>(ev->relatedTo()));
00292 }
00293 }
00294 }
00295 rawTodoList.find(subev);
00296 ev = rawTodoList.next();
00297 }
00298
00299
00300
00301 for (int i=1; i<=5; ++i) {
00302 for(ev=rawTodoList.first();ev;ev=rawTodoList.next()) {
00303 if (ev->priority()==i && checkSecrecy( ev )) todoList.append(ev);
00304 }
00305 }
00306
00307 *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">\n";
00308 *ts << " <tr>\n";
00309 *ts << " <th class=\"sum\">" << i18n("Task") << "</th>\n";
00310 *ts << " <th>" << i18n("Priority") << "</th>\n";
00311 *ts << " <th>" << i18n("Completed") << "</th>\n";
00312 if (dueDateEnabled()) {
00313 *ts << " <th>" << i18n("Due Date") << "</th>\n";
00314 }
00315 if (categoriesTodoEnabled()) {
00316 *ts << " <th>" << i18n("Categories") << "</th>\n";
00317 }
00318 if (attendeesTodoEnabled()) {
00319 *ts << " <th>" << i18n("Attendees") << "</th>\n";
00320 }
00321 *ts << " </tr>\n";
00322
00323
00324 for(ev=todoList.first();ev;ev=todoList.next()) {
00325 if (!ev->relatedTo()) createHtmlTodo(ts,ev);
00326 }
00327
00328
00329 for(ev=todoList.first();ev;ev=todoList.next()) {
00330 QPtrList<Incidence> relations = ev->relations();
00331 if (relations.count()) {
00332
00333 *ts << " <tr>\n";
00334 *ts << " <td class=\"subhead\" colspan=";
00335 int columns = 3;
00336 if (dueDateEnabled()) ++columns;
00337 if (categoriesTodoEnabled()) ++columns;
00338 if (attendeesTodoEnabled()) ++columns;
00339 *ts << "\"" << QString::number(columns) << "\"";
00340 *ts << "><a name=\"sub" << ev->uid() << "\"></a>"
00341 << i18n("Sub-Tasks of: ") << "<a href=\"#"
00342 << ev->uid() << "\"><b>" << cleanChars(ev->summary()) << "</b></a></td>\n";
00343 *ts << " </tr>\n";
00344
00345 QPtrList<Todo> sortedList;
00346 Incidence *ev2;
00347
00348
00349 for (int i=1; i<=5; ++i) {
00350 for(ev2=relations.first();ev2;ev2=relations.next()) {
00351 Todo *ev3 = dynamic_cast<Todo *>(ev2);
00352 if (ev3 && ev3->priority() == i) sortedList.append(ev3);
00353 }
00354 }
00355
00356 for(subev=sortedList.first();subev;subev=sortedList.next()) {
00357 createHtmlTodo(ts,subev);
00358 }
00359 }
00360 }
00361
00362 *ts << "</table>\n";
00363 }
00364
00365 void HtmlExport::createHtmlTodo (QTextStream *ts,Todo *todo)
00366 {
00367 kdDebug() << "HtmlExport::createHtmlTodo()" << endl;
00368
00369 bool completed = todo->isCompleted();
00370 QPtrList<Incidence> relations = todo->relations();
00371
00372 *ts << "<tr>\n";
00373
00374 *ts << " <td class=\"sum\"";
00375 if (completed) *ts << "done";
00376 *ts << ">\n";
00377 *ts << " <a name=\"" << todo->uid() << "\"></a>\n";
00378 *ts << " <b>" << cleanChars(todo->summary()) << "</b>\n";
00379 if (!todo->description().isEmpty()) {
00380 *ts << " <p>" << breakString(cleanChars(todo->description())) << "</p>\n";
00381 }
00382 if (relations.count()) {
00383 *ts << " <div align=\"right\"><a href=\"#sub" << todo->uid()
00384 << "\">" << i18n("Sub-Tasks") << "</a></div>\n";
00385 }
00386
00387 *ts << " </td";
00388 if (completed) *ts << " class=\"done\"";
00389 *ts << ">\n";
00390
00391 *ts << " <td";
00392 if (completed) *ts << " class=\"done\"";
00393 *ts << ">\n";
00394 *ts << " " << todo->priority() << "\n";
00395 *ts << " </td>\n";
00396
00397 *ts << " <td";
00398 if (completed) *ts << " class=\"done\"";
00399 *ts << ">\n";
00400 *ts << " " << i18n("%1 %").arg(todo->percentComplete()) << "\n";
00401 *ts << " </td>\n";
00402
00403 if (dueDateEnabled()) {
00404 *ts << " <td";
00405 if (completed) *ts << " class=\"done\"";
00406 *ts << ">\n";
00407 if (todo->hasDueDate()) {
00408 *ts << " " << todo->dtDueDateStr() << "\n";
00409 } else {
00410 *ts << " \n";
00411 }
00412 *ts << " </td>\n";
00413 }
00414
00415 if (categoriesTodoEnabled()) {
00416 *ts << " <td";
00417 if (completed) *ts << " class=\"done\"";
00418 *ts << ">\n";
00419 formatHtmlCategories(ts,todo);
00420 *ts << " </td>\n";
00421 }
00422
00423 if (attendeesTodoEnabled()) {
00424 *ts << " <td";
00425 if (completed) *ts << " class=\"done\"";
00426 *ts << ">\n";
00427 formatHtmlAttendees(ts,todo);
00428 *ts << " </td>\n";
00429 }
00430
00431 *ts << "</tr>\n";
00432 }
00433
00434 bool HtmlExport::checkSecrecy( Incidence *incidence )
00435 {
00436 int secrecy = incidence->secrecy();
00437 if ( secrecy == Incidence::SecrecyPublic ) {
00438 return true;
00439 }
00440 if ( secrecy == Incidence::SecrecyPrivate && !excludePrivateEventEnabled() ) {
00441 return true;
00442 }
00443 if ( secrecy == Incidence::SecrecyConfidential &&
00444 !excludeConfidentialEventEnabled() ) {
00445 return true;
00446 }
00447 return false;
00448 }
00449
00450 void HtmlExport::formatHtmlCategories (QTextStream *ts,Incidence *event)
00451 {
00452 if (!event->categoriesStr().isEmpty()) {
00453 *ts << " " << cleanChars(event->categoriesStr()) << "\n";
00454 } else {
00455 *ts << " \n";
00456 }
00457 }
00458
00459 void HtmlExport::formatHtmlAttendees (QTextStream *ts,Incidence *event)
00460 {
00461 QPtrList<Attendee> attendees = event->attendees();
00462 if (attendees.count()) {
00463 *ts << "<em>";
00464 #ifndef KORG_NOKABC
00465 KABC::AddressBook *add_book = KABC::StdAddressBook::self();
00466 KABC::Addressee::List addressList;
00467 addressList = add_book->findByEmail(event->organizer());
00468 KABC::Addressee o = addressList.first();
00469 if (!o.isEmpty() && addressList.size()<2) {
00470 *ts << "<a href=\"mailto:" << event->organizer() << "\">";
00471 *ts << cleanChars(o.formattedName()) << "</a>\n";
00472 }
00473 else *ts << event->organizer();
00474 #else
00475 *ts << event->organizer();
00476 #endif
00477 *ts << "</em><br />";
00478 Attendee *a;
00479 for(a=attendees.first();a;a=attendees.next()) {
00480 if (!a->email().isEmpty()) {
00481 *ts << "<a href=\"mailto:" << a->email();
00482 *ts << "\">" << cleanChars(a->name()) << "</a>";
00483 }
00484 else {
00485 *ts << " " << cleanChars(a->name());
00486 }
00487 *ts << "<br />" << "\n";
00488 }
00489 } else {
00490 *ts << " \n";
00491 }
00492 }
00493
00494 QString HtmlExport::breakString(const QString &text)
00495 {
00496 int number = text.contains("\n");
00497 if(number < 0) {
00498 return text;
00499 } else {
00500 QString out;
00501 QString tmpText = text;
00502 int pos = 0;
00503 QString tmp;
00504 for(int i=0;i<=number;i++) {
00505 pos = tmpText.find("\n");
00506 tmp = tmpText.left(pos);
00507 tmpText = tmpText.right(tmpText.length() - pos - 1);
00508 out += tmp + "<br />";
00509 }
00510 return out;
00511 }
00512 }
00513
00514 QString HtmlExport::cleanChars(const QString &text)
00515 {
00516 QString txt = text;
00517 txt = txt.replace( QRegExp("&"), "&" );
00518 txt = txt.replace( QRegExp("<"), "<" );
00519 txt = txt.replace( QRegExp(">"), ">" );
00520 txt = txt.replace( QRegExp("\""), """ );
00521 txt = txt.replace( QRegExp("ä"), "ä" );
00522 txt = txt.replace( QRegExp("Ä"), "Ä" );
00523 txt = txt.replace( QRegExp("ö"), "ö" );
00524 txt = txt.replace( QRegExp("Ö"), "Ö" );
00525 txt = txt.replace( QRegExp("ü"), "ü" );
00526 txt = txt.replace( QRegExp("Ü"), "Ü" );
00527 txt = txt.replace( QRegExp("ß"), "ß" );
00528 txt = txt.replace( QRegExp("¤"), "€" );
00529 txt = txt.replace( QRegExp("é"), "é" );
00530
00531 return txt;
00532 }
00533
00534 void HtmlExport::setStyleSheet( const QString &styleSheet )
00535 {
00536 mStyleSheet = styleSheet;
00537 }
00538
00539 QString HtmlExport::styleSheet()
00540 {
00541 if ( !mStyleSheet.isEmpty() ) return mStyleSheet;
00542
00543 QString css;
00544
00545 if ( QApplication::reverseLayout() ) {
00546 css += " body { background-color:white; color:black; direction: rtl }\n";
00547 css += " td { text-align:center; background-color:#eee }\n";
00548 css += " th { text-align:center; background-color:#228; color:white }\n";
00549 css += " td.sumdone { background-color:#ccc }\n";
00550 css += " td.done { background-color:#ccc }\n";
00551 css += " td.subhead { text-align:center; background-color:#ccf }\n";
00552 css += " td.datehead { text-align:center; background-color:#ccf }\n";
00553 css += " td.space { background-color:white }\n";
00554 css += " td.dateholiday { color:red }\n";
00555 } else {
00556 css += " body { background-color:white; color:black }\n";
00557 css += " td { text-align:center; background-color:#eee }\n";
00558 css += " th { text-align:center; background-color:#228; color:white }\n";
00559 css += " td.sum { text-align:left }\n";
00560 css += " td.sumdone { text-align:left; background-color:#ccc }\n";
00561 css += " td.done { background-color:#ccc }\n";
00562 css += " td.subhead { text-align:center; background-color:#ccf }\n";
00563 css += " td.datehead { text-align:center; background-color:#ccf }\n";
00564 css += " td.space { background-color:white }\n";
00565 css += " td.date { text-align:left }\n";
00566 css += " td.dateholiday { text-align:left; color:red }\n";
00567 }
00568
00569 return css;
00570 }
This file is part of the documentation for kdelibs Version 3.1.4.