You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
714 lines
21 KiB
714 lines
21 KiB
15 years ago
|
/*
|
||
|
This file is part of libkcal.
|
||
|
|
||
|
Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
|
||
|
Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Library General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2 of the License, or (at your option) any later version.
|
||
|
|
||
|
This library is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
Library General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Library General Public License
|
||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#include <qapplication.h>
|
||
|
#include <qfile.h>
|
||
|
#include <qtextstream.h>
|
||
|
#include <qtextcodec.h>
|
||
|
#include <qregexp.h>
|
||
|
|
||
|
#include <kcharsets.h>
|
||
|
#include <kglobal.h>
|
||
|
#include <klocale.h>
|
||
|
#include <kdebug.h>
|
||
|
#include <kcalendarsystem.h>
|
||
|
|
||
|
#include <libkcal/calendar.h>
|
||
|
#include <libkcal/event.h>
|
||
|
#include <libkcal/todo.h>
|
||
|
|
||
|
#ifndef KORG_NOKABC
|
||
|
#include <kabc/stdaddressbook.h>
|
||
|
#endif
|
||
|
#include "htmlexport.h"
|
||
|
#include "htmlexportsettings.h"
|
||
|
|
||
|
using namespace KCal;
|
||
|
|
||
|
HtmlExport::HtmlExport( Calendar *calendar, HTMLExportSettings *settings ) :
|
||
|
mCalendar( calendar ), mSettings( settings )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
bool HtmlExport::save( const QString &fileName )
|
||
|
{
|
||
|
QString fn( fileName );
|
||
|
if ( fn.isEmpty() && mSettings ) {
|
||
|
fn = mSettings->outputFile();
|
||
|
}
|
||
|
if ( !mSettings || fn.isEmpty() ) {
|
||
|
return false;
|
||
|
}
|
||
|
QFile f( fileName );
|
||
|
if ( !f.open(IO_WriteOnly)) {
|
||
|
return false;
|
||
|
}
|
||
|
QTextStream ts(&f);
|
||
|
bool success = save(&ts);
|
||
|
f.close();
|
||
|
return success;
|
||
|
}
|
||
|
|
||
|
bool HtmlExport::save(QTextStream *ts)
|
||
|
{
|
||
|
if ( !mSettings ) return false;
|
||
|
ts->setEncoding( QTextStream::UnicodeUTF8 );
|
||
|
|
||
|
// Write HTML header
|
||
|
*ts << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" ";
|
||
|
*ts << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
|
||
|
|
||
|
*ts << "<html><head>" << endl;
|
||
|
*ts << " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=";
|
||
|
*ts << "UTF-8\" />\n";
|
||
|
if ( !mSettings->pageTitle().isEmpty())
|
||
|
*ts << " <title>" << mSettings->pageTitle() << "</title>\n";
|
||
|
*ts << " <style type=\"text/css\">\n";
|
||
|
*ts << styleSheet();
|
||
|
*ts << " </style>\n";
|
||
|
*ts << "</head><body>\n";
|
||
|
|
||
|
// FIXME: Write header
|
||
|
// (Heading, Calendar-Owner, Calendar-Date, ...)
|
||
|
|
||
|
if ( mSettings->eventView() || mSettings->monthView() || mSettings->weekView() ) {
|
||
|
if (!mSettings->eventTitle().isEmpty())
|
||
|
*ts << "<h1>" << mSettings->eventTitle() << "</h1>\n";
|
||
|
|
||
|
// Write Week View
|
||
|
if ( mSettings->weekView() )
|
||
|
createWeekView( ts );
|
||
|
// Write Month View
|
||
|
if ( mSettings->monthView() )
|
||
|
createMonthView( ts );
|
||
|
// Write Event List
|
||
|
if ( mSettings->eventView() )
|
||
|
createEventList( ts );
|
||
|
}
|
||
|
|
||
|
// Write Todo List
|
||
|
if ( mSettings->todoView() ) {
|
||
|
if ( !mSettings->todoListTitle().isEmpty())
|
||
|
*ts << "<h1>" << mSettings->todoListTitle() << "</h1>\n";
|
||
|
createTodoList(ts);
|
||
|
}
|
||
|
|
||
|
// Write Journals
|
||
|
if ( mSettings->journalView() ) {
|
||
|
if ( !mSettings->journalTitle().isEmpty())
|
||
|
*ts << "<h1>" << mSettings->journalTitle() << "</h1>\n";
|
||
|
createJournalView(ts);
|
||
|
}
|
||
|
|
||
|
// Write Free/Busy
|
||
|
if ( mSettings->freeBusyView() ) {
|
||
|
if ( !mSettings->freeBusyTitle().isEmpty())
|
||
|
*ts << "<h1>" << mSettings->freeBusyTitle() << "</h1>\n";
|
||
|
createFreeBusyView(ts);
|
||
|
}
|
||
|
|
||
|
createFooter( ts );
|
||
|
|
||
|
// Write HTML trailer
|
||
|
*ts << "</body></html>\n";
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void HtmlExport::createMonthView(QTextStream *ts)
|
||
|
{
|
||
|
QDate start = fromDate();
|
||
|
start.setYMD( start.year(), start.month(), 1 ); // go back to first day in month
|
||
|
|
||
|
QDate end( start.year(), start.month(), start.daysInMonth() );
|
||
|
|
||
|
int startmonth = start.month();
|
||
|
int startyear = start.year();
|
||
|
|
||
|
while ( start < toDate() ) {
|
||
|
// Write header
|
||
|
*ts << "<h2>" << (i18n("month_year","%1 %2").arg(KGlobal::locale()->calendar()->monthName(start))
|
||
|
.arg(start.year())) << "</h2>\n";
|
||
|
if ( KGlobal::locale()->weekStartDay() == 1 ) {
|
||
|
start = start.addDays(1 - start.dayOfWeek());
|
||
|
} else {
|
||
|
if (start.dayOfWeek() != 7) {
|
||
|
start = start.addDays(-start.dayOfWeek());
|
||
|
}
|
||
|
}
|
||
|
*ts << "<table border=\"1\">\n";
|
||
|
|
||
|
// Write table header
|
||
|
*ts << " <tr>";
|
||
|
for(int i=0; i<7; ++i) {
|
||
|
*ts << "<th>" << KGlobal::locale()->calendar()->weekDayName( start.addDays(i) ) << "</th>";
|
||
|
}
|
||
|
*ts << "</tr>\n";
|
||
|
|
||
|
// Write days
|
||
|
while (start <= end) {
|
||
|
*ts << " <tr>\n";
|
||
|
for(int i=0;i<7;++i) {
|
||
|
*ts << " <td valign=\"top\"><table border=\"0\">";
|
||
|
|
||
|
*ts << "<tr><td ";
|
||
|
if (mHolidayMap.contains(start) || start.dayOfWeek() == 7) {
|
||
|
*ts << "class=\"dateholiday\"";
|
||
|
} else {
|
||
|
*ts << "class=\"date\"";
|
||
|
}
|
||
|
*ts << ">" << QString::number(start.day());
|
||
|
|
||
|
if (mHolidayMap.contains(start)) {
|
||
|
*ts << " <em>" << mHolidayMap[start] << "</em>";
|
||
|
}
|
||
|
|
||
|
*ts << "</td></tr><tr><td valign=\"top\">";
|
||
|
|
||
|
Event::List events = mCalendar->events( start,
|
||
|
EventSortStartDate,
|
||
|
SortDirectionAscending );
|
||
|
if (events.count()) {
|
||
|
*ts << "<table>";
|
||
|
Event::List::ConstIterator it;
|
||
|
for( it = events.begin(); it != events.end(); ++it ) {
|
||
|
if ( checkSecrecy( *it ) ) {
|
||
|
createEvent( ts, *it, start, false );
|
||
|
}
|
||
|
}
|
||
|
*ts << "</table>";
|
||
|
} else {
|
||
|
*ts << " ";
|
||
|
}
|
||
|
|
||
|
*ts << "</td></tr></table></td>\n";
|
||
|
start = start.addDays(1);
|
||
|
}
|
||
|
*ts << " </tr>\n";
|
||
|
}
|
||
|
*ts << "</table>\n";
|
||
|
startmonth += 1;
|
||
|
if ( startmonth > 12 ) {
|
||
|
startyear += 1;
|
||
|
startmonth = 1;
|
||
|
}
|
||
|
start.setYMD( startyear, startmonth, 1 );
|
||
|
end.setYMD(start.year(),start.month(),start.daysInMonth());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void HtmlExport::createEventList (QTextStream *ts)
|
||
|
{
|
||
|
int columns = 3;
|
||
|
*ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">\n";
|
||
|
*ts << " <tr>\n";
|
||
|
*ts << " <th class=\"sum\">" << i18n("Start Time") << "</th>\n";
|
||
|
*ts << " <th>" << i18n("End Time") << "</th>\n";
|
||
|
*ts << " <th>" << i18n("Event") << "</th>\n";
|
||
|
if ( mSettings->eventLocation() ) {
|
||
|
*ts << " <th>" << i18n("Location") << "</th>\n";
|
||
|
++columns;
|
||
|
}
|
||
|
if ( mSettings->eventCategories() ) {
|
||
|
*ts << " <th>" << i18n("Categories") << "</th>\n";
|
||
|
++columns;
|
||
|
}
|
||
|
if ( mSettings->eventAttendees() ) {
|
||
|
*ts << " <th>" << i18n("Attendees") << "</th>\n";
|
||
|
++columns;
|
||
|
}
|
||
|
|
||
|
*ts << " </tr>\n";
|
||
|
|
||
|
for ( QDate dt = fromDate(); dt <= toDate(); dt = dt.addDays(1) ) {
|
||
|
kdDebug(5850) << "Getting events for " << dt.toString() << endl;
|
||
|
Event::List events = mCalendar->events(dt,
|
||
|
EventSortStartDate,
|
||
|
SortDirectionAscending );
|
||
|
if (events.count()) {
|
||
|
Event::List::ConstIterator it;
|
||
|
bool first = true;
|
||
|
for( it = events.begin(); it != events.end(); ++it ) {
|
||
|
if ( checkSecrecy( *it ) ) {
|
||
|
if ( first ) {
|
||
|
*ts << " <tr><td colspan=\"" << QString::number(columns)
|
||
|
<< "\" class=\"datehead\"><i>"
|
||
|
<< KGlobal::locale()->formatDate(dt)
|
||
|
<< "</i></td></tr>\n";
|
||
|
first = false;
|
||
|
}
|
||
|
createEvent( ts, *it, dt );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*ts << "</table>\n";
|
||
|
}
|
||
|
|
||
|
void HtmlExport::createEvent (QTextStream *ts, Event *event,
|
||
|
QDate date,bool withDescription)
|
||
|
{
|
||
|
kdDebug(5850) << "HtmlExport::createEvent(): " << event->summary() << endl;
|
||
|
*ts << " <tr>\n";
|
||
|
|
||
|
if (!event->doesFloat()) {
|
||
|
if (event->isMultiDay() && (event->dtStart().date() != date)) {
|
||
|
*ts << " <td> </td>\n";
|
||
|
} else {
|
||
|
*ts << " <td valign=\"top\">" << event->dtStartTimeStr() << "</td>\n";
|
||
|
}
|
||
|
if (event->isMultiDay() && (event->dtEnd().date() != date)) {
|
||
|
*ts << " <td> </td>\n";
|
||
|
} else {
|
||
|
*ts << " <td valign=\"top\">" << event->dtEndTimeStr() << "</td>\n";
|
||
|
}
|
||
|
} else {
|
||
|
*ts << " <td> </td><td> </td>\n";
|
||
|
}
|
||
|
|
||
|
*ts << " <td class=\"sum\">\n";
|
||
|
*ts << " <b>" << cleanChars(event->summary()) << "</b>\n";
|
||
|
if ( withDescription && !event->description().isEmpty() ) {
|
||
|
*ts << " <p>" << breakString( cleanChars( event->description() ) ) << "</p>\n";
|
||
|
}
|
||
|
*ts << " </td>\n";
|
||
|
|
||
|
if ( mSettings->eventLocation() ) {
|
||
|
*ts << " <td>\n";
|
||
|
formatLocation( ts, event );
|
||
|
*ts << " </td>\n";
|
||
|
}
|
||
|
|
||
|
if ( mSettings->eventCategories() ) {
|
||
|
*ts << " <td>\n";
|
||
|
formatCategories( ts, event );
|
||
|
*ts << " </td>\n";
|
||
|
}
|
||
|
|
||
|
if ( mSettings->eventAttendees() ) {
|
||
|
*ts << " <td>\n";
|
||
|
formatAttendees( ts, event );
|
||
|
*ts << " </td>\n";
|
||
|
}
|
||
|
|
||
|
*ts << " </tr>\n";
|
||
|
}
|
||
|
|
||
|
void HtmlExport::createTodoList ( QTextStream *ts )
|
||
|
{
|
||
|
Todo::List rawTodoList = mCalendar->todos();
|
||
|
|
||
|
Todo::List::Iterator it = rawTodoList.begin();
|
||
|
while ( it != rawTodoList.end() ) {
|
||
|
Todo *ev = *it;
|
||
|
Todo *subev = ev;
|
||
|
if ( ev->relatedTo() ) {
|
||
|
if ( ev->relatedTo()->type()=="Todo" ) {
|
||
|
if ( rawTodoList.find( static_cast<Todo *>( ev->relatedTo() ) ) ==
|
||
|
rawTodoList.end() ) {
|
||
|
rawTodoList.append( static_cast<Todo *>( ev->relatedTo() ) );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
it = rawTodoList.find( subev );
|
||
|
++it;
|
||
|
}
|
||
|
|
||
|
// FIXME: Sort list by priorities. This is brute force and should be
|
||
|
// replaced by a real sorting algorithm.
|
||
|
Todo::List todoList;
|
||
|
for ( int i = 1; i <= 9; ++i ) {
|
||
|
for( it = rawTodoList.begin(); it != rawTodoList.end(); ++it ) {
|
||
|
if ( (*it)->priority() == i && checkSecrecy( *it ) ) {
|
||
|
todoList.append( *it );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
for( it = rawTodoList.begin(); it != rawTodoList.end(); ++it ) {
|
||
|
if ( (*it)->priority() == 0 && checkSecrecy( *it ) ) {
|
||
|
todoList.append( *it );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int columns = 3;
|
||
|
*ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">\n";
|
||
|
*ts << " <tr>\n";
|
||
|
*ts << " <th class=\"sum\">" << i18n("Task") << "</th>\n";
|
||
|
*ts << " <th>" << i18n("Priority") << "</th>\n";
|
||
|
*ts << " <th>" << i18n("Completed") << "</th>\n";
|
||
|
if ( mSettings->taskDueDate() ) {
|
||
|
*ts << " <th>" << i18n("Due Date") << "</th>\n";
|
||
|
++columns;
|
||
|
}
|
||
|
if ( mSettings->taskLocation() ) {
|
||
|
*ts << " <th>" << i18n("Location") << "</th>\n";
|
||
|
++columns;
|
||
|
}
|
||
|
if ( mSettings->taskCategories() ) {
|
||
|
*ts << " <th>" << i18n("Categories") << "</th>\n";
|
||
|
++columns;
|
||
|
}
|
||
|
if ( mSettings->taskAttendees() ) {
|
||
|
*ts << " <th>" << i18n("Attendees") << "</th>\n";
|
||
|
++columns;
|
||
|
}
|
||
|
*ts << " </tr>\n";
|
||
|
|
||
|
// Create top-level list.
|
||
|
for( it = todoList.begin(); it != todoList.end(); ++it ) {
|
||
|
if ( !(*it)->relatedTo() ) createTodo( ts, *it );
|
||
|
}
|
||
|
|
||
|
// Create sub-level lists
|
||
|
for( it = todoList.begin(); it != todoList.end(); ++it ) {
|
||
|
Incidence::List relations = (*it)->relations();
|
||
|
if (relations.count()) {
|
||
|
// Generate sub-task list of event ev
|
||
|
*ts << " <tr>\n";
|
||
|
*ts << " <td class=\"subhead\" colspan=";
|
||
|
*ts << "\"" << QString::number(columns) << "\"";
|
||
|
*ts << "><a name=\"sub" << (*it)->uid() << "\"></a>"
|
||
|
<< i18n("Sub-Tasks of: ") << "<a href=\"#"
|
||
|
<< (*it)->uid() << "\"><b>" << cleanChars( (*it)->summary())
|
||
|
<< "</b></a></td>\n";
|
||
|
*ts << " </tr>\n";
|
||
|
|
||
|
Todo::List sortedList;
|
||
|
// FIXME: Sort list by priorities. This is brute force and should be
|
||
|
// replaced by a real sorting algorithm.
|
||
|
for ( int i = 1; i <= 9; ++i ) {
|
||
|
Incidence::List::ConstIterator it2;
|
||
|
for( it2 = relations.begin(); it2 != relations.end(); ++it2 ) {
|
||
|
Todo *ev3 = dynamic_cast<Todo *>( *it2 );
|
||
|
if ( ev3 && ev3->priority() == i ) sortedList.append( ev3 );
|
||
|
}
|
||
|
}
|
||
|
Incidence::List::ConstIterator it2;
|
||
|
for( it2 = relations.begin(); it2 != relations.end(); ++it2 ) {
|
||
|
Todo *ev3 = dynamic_cast<Todo *>( *it2 );
|
||
|
if ( ev3 && ev3->priority() == 0 ) sortedList.append( ev3 );
|
||
|
}
|
||
|
|
||
|
Todo::List::ConstIterator it3;
|
||
|
for( it3 = sortedList.begin(); it3 != sortedList.end(); ++it3 ) {
|
||
|
createTodo( ts, *it3 );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*ts << "</table>\n";
|
||
|
}
|
||
|
|
||
|
void HtmlExport::createTodo (QTextStream *ts,Todo *todo)
|
||
|
{
|
||
|
kdDebug(5850) << "HtmlExport::createTodo()" << endl;
|
||
|
|
||
|
bool completed = todo->isCompleted();
|
||
|
Incidence::List relations = todo->relations();
|
||
|
|
||
|
*ts << "<tr>\n";
|
||
|
|
||
|
*ts << " <td class=\"sum";
|
||
|
if (completed) *ts << "done";
|
||
|
*ts << "\">\n";
|
||
|
*ts << " <a name=\"" << todo->uid() << "\"></a>\n";
|
||
|
*ts << " <b>" << cleanChars(todo->summary()) << "</b>\n";
|
||
|
if (!todo->description().isEmpty()) {
|
||
|
*ts << " <p>" << breakString(cleanChars(todo->description())) << "</p>\n";
|
||
|
}
|
||
|
if (relations.count()) {
|
||
|
*ts << " <div align=\"right\"><a href=\"#sub" << todo->uid()
|
||
|
<< "\">" << i18n("Sub-Tasks") << "</a></div>\n";
|
||
|
}
|
||
|
*ts << " </td>\n";
|
||
|
|
||
|
*ts << " <td";
|
||
|
if (completed) *ts << " class=\"done\"";
|
||
|
*ts << ">\n";
|
||
|
*ts << " " << todo->priority() << "\n";
|
||
|
*ts << " </td>\n";
|
||
|
|
||
|
*ts << " <td";
|
||
|
if (completed) *ts << " class=\"done\"";
|
||
|
*ts << ">\n";
|
||
|
*ts << " " << i18n("%1 %").arg(todo->percentComplete()) << "\n";
|
||
|
*ts << " </td>\n";
|
||
|
|
||
|
if ( mSettings->taskDueDate() ) {
|
||
|
*ts << " <td";
|
||
|
if (completed) *ts << " class=\"done\"";
|
||
|
*ts << ">\n";
|
||
|
if (todo->hasDueDate()) {
|
||
|
*ts << " " << todo->dtDueDateStr() << "\n";
|
||
|
} else {
|
||
|
*ts << " \n";
|
||
|
}
|
||
|
*ts << " </td>\n";
|
||
|
}
|
||
|
|
||
|
if ( mSettings->taskLocation() ) {
|
||
|
*ts << " <td";
|
||
|
if (completed) *ts << " class=\"done\"";
|
||
|
*ts << ">\n";
|
||
|
formatLocation(ts,todo);
|
||
|
*ts << " </td>\n";
|
||
|
}
|
||
|
|
||
|
if ( mSettings->taskCategories() ) {
|
||
|
*ts << " <td";
|
||
|
if (completed) *ts << " class=\"done\"";
|
||
|
*ts << ">\n";
|
||
|
formatCategories(ts,todo);
|
||
|
*ts << " </td>\n";
|
||
|
}
|
||
|
|
||
|
if ( mSettings->taskAttendees() ) {
|
||
|
*ts << " <td";
|
||
|
if (completed) *ts << " class=\"done\"";
|
||
|
*ts << ">\n";
|
||
|
formatAttendees(ts,todo);
|
||
|
*ts << " </td>\n";
|
||
|
}
|
||
|
|
||
|
*ts << "</tr>\n";
|
||
|
}
|
||
|
|
||
|
void HtmlExport::createWeekView( QTextStream */*ts*/ )
|
||
|
{
|
||
|
// FIXME: Implement this!
|
||
|
}
|
||
|
|
||
|
void HtmlExport::createJournalView( QTextStream */*ts*/ )
|
||
|
{
|
||
|
// Journal::List rawJournalList = mCalendar->journals();
|
||
|
// FIXME: Implement this!
|
||
|
}
|
||
|
|
||
|
void HtmlExport::createFreeBusyView( QTextStream */*ts*/ )
|
||
|
{
|
||
|
// FIXME: Implement this!
|
||
|
}
|
||
|
|
||
|
bool HtmlExport::checkSecrecy( Incidence *incidence )
|
||
|
{
|
||
|
int secrecy = incidence->secrecy();
|
||
|
if ( secrecy == Incidence::SecrecyPublic ) {
|
||
|
return true;
|
||
|
}
|
||
|
if ( secrecy == Incidence::SecrecyPrivate && !mSettings->excludePrivate() ) {
|
||
|
return true;
|
||
|
}
|
||
|
if ( secrecy == Incidence::SecrecyConfidential &&
|
||
|
!mSettings->excludeConfidential() ) {
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void HtmlExport::formatLocation (QTextStream *ts,Incidence *event)
|
||
|
{
|
||
|
if (!event->location().isEmpty()) {
|
||
|
*ts << " " << cleanChars(event->location()) << "\n";
|
||
|
} else {
|
||
|
*ts << " \n";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void HtmlExport::formatCategories (QTextStream *ts,Incidence *event)
|
||
|
{
|
||
|
if (!event->categoriesStr().isEmpty()) {
|
||
|
*ts << " " << cleanChars(event->categoriesStr()) << "\n";
|
||
|
} else {
|
||
|
*ts << " \n";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void HtmlExport::formatAttendees( QTextStream *ts, Incidence *event )
|
||
|
{
|
||
|
Attendee::List attendees = event->attendees();
|
||
|
if (attendees.count()) {
|
||
|
*ts << "<em>";
|
||
|
#ifndef KORG_NOKABC
|
||
|
KABC::AddressBook *add_book = KABC::StdAddressBook::self( true );
|
||
|
KABC::Addressee::List addressList;
|
||
|
addressList = add_book->findByEmail(event->organizer().email());
|
||
|
KABC::Addressee o = addressList.first();
|
||
|
if (!o.isEmpty() && addressList.size()<2) {
|
||
|
*ts << "<a href=\"mailto:" << event->organizer().email() << "\">";
|
||
|
*ts << cleanChars(o.formattedName()) << "</a>\n";
|
||
|
}
|
||
|
else *ts << event->organizer().fullName();
|
||
|
#else
|
||
|
*ts << event->organizer().fullName();
|
||
|
#endif
|
||
|
*ts << "</em><br />";
|
||
|
Attendee::List::ConstIterator it;
|
||
|
for( it = attendees.begin(); it != attendees.end(); ++it ) {
|
||
|
Attendee *a = *it;
|
||
|
if (!a->email().isEmpty()) {
|
||
|
*ts << "<a href=\"mailto:" << a->email();
|
||
|
*ts << "\">" << cleanChars(a->name()) << "</a>";
|
||
|
}
|
||
|
else {
|
||
|
*ts << " " << cleanChars(a->name());
|
||
|
}
|
||
|
*ts << "<br />" << "\n";
|
||
|
}
|
||
|
} else {
|
||
|
*ts << " \n";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QString HtmlExport::breakString(const QString &text)
|
||
|
{
|
||
|
int number = text.contains("\n");
|
||
|
if(number < 0) {
|
||
|
return text;
|
||
|
} else {
|
||
|
QString out;
|
||
|
QString tmpText = text;
|
||
|
int pos = 0;
|
||
|
QString tmp;
|
||
|
for(int i=0;i<=number;i++) {
|
||
|
pos = tmpText.find("\n");
|
||
|
tmp = tmpText.left(pos);
|
||
|
tmpText = tmpText.right(tmpText.length() - pos - 1);
|
||
|
out += tmp + "<br />";
|
||
|
}
|
||
|
return out;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void HtmlExport::createFooter( QTextStream *ts )
|
||
|
{
|
||
|
// FIXME: Implement this in a translatable way!
|
||
|
QString trailer = i18n("This page was created ");
|
||
|
|
||
|
/* bool hasPerson = false;
|
||
|
bool hasCredit = false;
|
||
|
bool hasCreditURL = false;
|
||
|
QString mail, name, credit, creditURL;*/
|
||
|
if (!mSettings->eMail().isEmpty()) {
|
||
|
if (!mSettings->name().isEmpty())
|
||
|
trailer += i18n("by <a href=\"mailto:%1\">%2</a> ").arg( mSettings->eMail() ).arg( mSettings->name() );
|
||
|
else
|
||
|
trailer += i18n("by <a href=\"mailto:%1\">%2</a> ").arg( mSettings->eMail() ).arg( mSettings->eMail() );
|
||
|
} else {
|
||
|
if (!mSettings->name().isEmpty())
|
||
|
trailer += i18n("by %1 ").arg( mSettings->name() );
|
||
|
}
|
||
|
if (!mSettings->creditName().isEmpty()) {
|
||
|
if (!mSettings->creditURL().isEmpty())
|
||
|
trailer += i18n("with <a href=\"%1\">%2</a>")
|
||
|
.arg( mSettings->creditURL() )
|
||
|
.arg( mSettings->creditName() );
|
||
|
else
|
||
|
trailer += i18n("with %1").arg( mSettings->creditName() );
|
||
|
}
|
||
|
*ts << "<p>" << trailer << "</p>\n";
|
||
|
}
|
||
|
|
||
|
|
||
|
QString HtmlExport::cleanChars(const QString &text)
|
||
|
{
|
||
|
QString txt = text;
|
||
|
txt = txt.replace( "&", "&" );
|
||
|
txt = txt.replace( "<", "<" );
|
||
|
txt = txt.replace( ">", ">" );
|
||
|
txt = txt.replace( "\"", """ );
|
||
|
txt = txt.replace( QString::fromUtf8("ä"), "ä" );
|
||
|
txt = txt.replace( QString::fromUtf8("á"), "á" );
|
||
|
txt = txt.replace( QString::fromUtf8("à"), "à" );
|
||
|
txt = txt.replace( QString::fromUtf8("â"), "â" );
|
||
|
txt = txt.replace( QString::fromUtf8("Ä"), "Ä" );
|
||
|
txt = txt.replace( QString::fromUtf8("ó"), "ó" );
|
||
|
txt = txt.replace( QString::fromUtf8("ô"), "ô" );
|
||
|
txt = txt.replace( QString::fromUtf8("ö"), "ö" );
|
||
|
txt = txt.replace( QString::fromUtf8("Ö"), "Ö" );
|
||
|
txt = txt.replace( QString::fromUtf8("ü"), "ü" );
|
||
|
txt = txt.replace( QString::fromUtf8("Ü"), "Ü" );
|
||
|
txt = txt.replace( QString::fromUtf8("ß"), "ß" );
|
||
|
txt = txt.replace( QString::fromUtf8("€"), "€" );
|
||
|
txt = txt.replace( QString::fromUtf8("é"), "é" );
|
||
|
txt = txt.replace( QString::fromUtf8("ë"), "ë" );
|
||
|
txt = txt.replace( QString::fromUtf8("è"), "è" );
|
||
|
txt = txt.replace( QString::fromUtf8("ñ"), "ñ" );
|
||
|
txt = txt.replace( QString::fromUtf8("ç"), "ç" );
|
||
|
|
||
|
return txt;
|
||
|
}
|
||
|
|
||
|
QString HtmlExport::styleSheet() const
|
||
|
{
|
||
|
if ( !mSettings->styleSheet().isEmpty() )
|
||
|
return mSettings->styleSheet();
|
||
|
|
||
|
QString css;
|
||
|
|
||
|
if ( QApplication::reverseLayout() ) {
|
||
|
css += " body { background-color:white; color:black; direction: rtl }\n";
|
||
|
css += " td { text-align:center; background-color:#eee }\n";
|
||
|
css += " th { text-align:center; background-color:#228; color:white }\n";
|
||
|
css += " td.sumdone { background-color:#ccc }\n";
|
||
|
css += " td.done { background-color:#ccc }\n";
|
||
|
css += " td.subhead { text-align:center; background-color:#ccf }\n";
|
||
|
css += " td.datehead { text-align:center; background-color:#ccf }\n";
|
||
|
css += " td.space { background-color:white }\n";
|
||
|
css += " td.dateholiday { color:red }\n";
|
||
|
} else {
|
||
|
css += " body { background-color:white; color:black }\n";
|
||
|
css += " td { text-align:center; background-color:#eee }\n";
|
||
|
css += " th { text-align:center; background-color:#228; color:white }\n";
|
||
|
css += " td.sum { text-align:left }\n";
|
||
|
css += " td.sumdone { text-align:left; background-color:#ccc }\n";
|
||
|
css += " td.done { background-color:#ccc }\n";
|
||
|
css += " td.subhead { text-align:center; background-color:#ccf }\n";
|
||
|
css += " td.datehead { text-align:center; background-color:#ccf }\n";
|
||
|
css += " td.space { background-color:white }\n";
|
||
|
css += " td.date { text-align:left }\n";
|
||
|
css += " td.dateholiday { text-align:left; color:red }\n";
|
||
|
}
|
||
|
|
||
|
return css;
|
||
|
}
|
||
|
|
||
|
|
||
|
void HtmlExport::addHoliday( const QDate &date, const QString &name)
|
||
|
{
|
||
|
if ( mHolidayMap[date].isEmpty() ) {
|
||
|
mHolidayMap[date] = name;
|
||
|
} else {
|
||
|
mHolidayMap[date] = i18n("list of holidays", "%1, %2").arg(mHolidayMap[date]).arg(name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QDate HtmlExport::fromDate() const
|
||
|
{
|
||
|
return mSettings->dateStart().date();
|
||
|
}
|
||
|
|
||
|
QDate HtmlExport::toDate() const
|
||
|
{
|
||
|
return mSettings->dateEnd().date();
|
||
|
}
|