summaryrefslogtreecommitdiffabout
path: root/libkcal/vcalformat.cpp
Side-by-side diff
Diffstat (limited to 'libkcal/vcalformat.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/vcalformat.cpp19
1 files changed, 14 insertions, 5 deletions
diff --git a/libkcal/vcalformat.cpp b/libkcal/vcalformat.cpp
index 9307f12..0ebd7d1 100644
--- a/libkcal/vcalformat.cpp
+++ b/libkcal/vcalformat.cpp
@@ -1,282 +1,292 @@
/*
This file is part of libkcal.
Copyright (c) 1998 Preston Brwon
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
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., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include <qapplication.h>
#include <qdatetime.h>
#include <qstring.h>
#include <qptrlist.h>
#include <qregexp.h>
#include <qclipboard.h>
#include <qdialog.h>
#include <qfile.h>
#include <kdebug.h>
+#include <kglobal.h>
#include <kmessagebox.h>
#include <kiconloader.h>
#include <klocale.h>
#include "vcc.h"
#include "vobject.h"
#include "vcaldrag.h"
#include "calendar.h"
#include "vcalformat.h"
using namespace KCal;
VCalFormat::VCalFormat()
{
mCalendar = 0;
+ useLocalTime = false;
}
VCalFormat::~VCalFormat()
{
}
bool VCalFormat::load(Calendar *calendar, const QString &fileName)
{
mCalendar = calendar;
clearException();
kdDebug(5800) << "VCalFormat::load() " << fileName << endl;
VObject *vcal = 0;
// this is not necessarily only 1 vcal. Could be many vcals, or include
// a vcard...
vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data()));
if (!vcal) {
setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
return FALSE;
}
// any other top-level calendar stuff should be added/initialized here
// put all vobjects into their proper places
populate(vcal);
// clean up from vcal API stuff
cleanVObjects(vcal);
cleanStrTbl();
return true;
}
bool VCalFormat::save(Calendar *calendar, const QString &fileName)
{
mCalendar = calendar;
QString tmpStr;
VObject *vcal, *vo;
kdDebug(5800) << "VCalFormat::save(): " << fileName << endl;
vcal = newVObject(VCCalProp);
// addPropValue(vcal,VCLocationProp, "0.0");
addPropValue(vcal,VCProdIdProp, productId());
tmpStr = mCalendar->getTimeZoneStr();
//qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() );
addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit());
addPropValue(vcal,VCVersionProp, _VCAL_VERSION);
// TODO STUFF
QPtrList<Todo> todoList = mCalendar->rawTodos();
QPtrListIterator<Todo> qlt(todoList);
for (; qlt.current(); ++qlt) {
vo = eventToVTodo(qlt.current());
addVObjectProp(vcal, vo);
}
// EVENT STUFF
QPtrList<Event> events = mCalendar->rawEvents();
Event *ev;
for(ev=events.first();ev;ev=events.next()) {
vo = eventToVEvent(ev);
addVObjectProp(vcal, vo);
}
writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal);
cleanVObjects(vcal);
cleanStrTbl();
if (QFile::exists(fileName)) {
kdDebug(5800) << "No error" << endl;
return true;
} else {
kdDebug(5800) << "Error" << endl;
return false; // error
}
}
bool VCalFormat::fromString( Calendar *calendar, const QString &text )
{
// TODO: Factor out VCalFormat::fromString()
QCString data = text.utf8();
if ( !data.size() ) return false;
VObject *vcal = Parse_MIME( data.data(), data.size());
if ( !vcal ) return false;
VObjectIterator i;
VObject *curvo;
initPropIterator( &i, vcal );
// we only take the first object. TODO: parse all incidences.
do {
curvo = nextVObject( &i );
} while ( strcmp( vObjectName( curvo ), VCEventProp ) &&
strcmp( vObjectName( curvo ), VCTodoProp ) );
if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) {
Event *event = VEventToEvent( curvo );
calendar->addEvent( event );
} else {
kdDebug(5800) << "VCalFormat::fromString(): Unknown object type." << endl;
deleteVObject( vcal );
return false;
}
deleteVObject( vcal );
return true;
}
-QString VCalFormat::eventToString( Event * event, Calendar *calendar)
+QString VCalFormat::eventToString( Event * event, Calendar *calendar, bool useLocal)
{
+
if ( !event ) return QString::null;
+ bool useL = useLocalTime;
+ useLocalTime = useLocal;
mCalendar = calendar;
VObject *vevent = eventToVEvent( event );
char *buf = writeMemVObject( 0, 0, vevent );
QString result( buf );
cleanVObject( vevent );
+ useLocalTime = useL;
return result;
}
-QString VCalFormat::todoToString( Todo * todo, Calendar *calendar )
+QString VCalFormat::todoToString( Todo * todo, Calendar *calendar, bool useLocal )
{
+
if ( !todo ) return QString::null;
+ bool useL = useLocalTime;
+ useLocalTime = useLocal;
mCalendar = calendar;
VObject *vevent = eventToVTodo( todo );
char *buf = writeMemVObject( 0, 0, vevent );
QString result( buf );
cleanVObject( vevent );
+ useLocalTime = useL;
return result;
}
QString VCalFormat::toString( Calendar *calendar )
{
// TODO: Factor out VCalFormat::asString()
VObject *vcal = newVObject(VCCalProp);
addPropValue( vcal, VCProdIdProp, CalFormat::productId() );
QString tmpStr = mCalendar->getTimeZoneStr();
addPropValue( vcal, VCTimeZoneProp, tmpStr.local8Bit() );
addPropValue( vcal, VCVersionProp, _VCAL_VERSION );
// TODO: Use all data.
QPtrList<Event> events = calendar->events();
Event *event = events.first();
if ( !event ) return QString::null;
VObject *vevent = eventToVEvent( event );
addVObjectProp( vcal, vevent );
char *buf = writeMemVObject( 0, 0, vcal );
QString result( buf );
cleanVObject( vcal );
return result;
}
VObject *VCalFormat::eventToVTodo(const Todo *anEvent)
{
VObject *vtodo;
QString tmpStr;
QStringList tmpStrList;
vtodo = newVObject(VCTodoProp);
// due date
if (anEvent->hasDueDate()) {
tmpStr = qDateTimeToISO(anEvent->dtDue(),
!anEvent->doesFloat());
addPropValue(vtodo, VCDueProp, tmpStr.local8Bit());
}
// start date
if (anEvent->hasStartDate()) {
tmpStr = qDateTimeToISO(anEvent->dtStart(),
!anEvent->doesFloat());
addPropValue(vtodo, VCDTstartProp, tmpStr.local8Bit());
}
// creation date
tmpStr = qDateTimeToISO(anEvent->created());
addPropValue(vtodo, VCDCreatedProp, tmpStr.local8Bit());
// unique id
addPropValue(vtodo, VCUniqueStringProp,
anEvent->uid().local8Bit());
// revision
tmpStr.sprintf("%i", anEvent->revision());
addPropValue(vtodo, VCSequenceProp, tmpStr.local8Bit());
// last modification date
tmpStr = qDateTimeToISO(anEvent->lastModified());
addPropValue(vtodo, VCLastModifiedProp, tmpStr.local8Bit());
// organizer stuff
tmpStr = "MAILTO:" + anEvent->organizer();
addPropValue(vtodo, ICOrganizerProp, tmpStr.local8Bit());
// attendees
if (anEvent->attendeeCount() != 0) {
QPtrList<Attendee> al = anEvent->attendees();
QPtrListIterator<Attendee> ai(al);
Attendee *curAttendee;
for (; ai.current(); ++ai) {
curAttendee = ai.current();
if (!curAttendee->email().isEmpty() &&
!curAttendee->name().isEmpty())
tmpStr = "MAILTO:" + curAttendee->name() + " <" +
curAttendee->email() + ">";
else if (curAttendee->name().isEmpty())
tmpStr = "MAILTO: " + curAttendee->email();
else if (curAttendee->email().isEmpty())
tmpStr = "MAILTO: " + curAttendee->name();
else if (curAttendee->name().isEmpty() &&
curAttendee->email().isEmpty())
kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl;
VObject *aProp = addPropValue(vtodo, VCAttendeeProp, tmpStr.local8Bit());
addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");
addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status()));
@@ -1341,195 +1351,194 @@ Event* VCalFormat::VEventToEvent(VObject *vevent)
QString resources = (s = fakeCString(vObjectUStringZValue(vo)));
deleteStr(s);
tmpStrList.clear();
index1 = 0;
index2 = 0;
QString resource;
while ((index2 = resources.find(';', index1)) != -1) {
resource = resources.mid(index1, (index2 - index1));
tmpStrList.append(resource);
index1 = index2;
}
anEvent->setResources(tmpStrList);
}
/* alarm stuff */
if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) {
Alarm* alarm = anEvent->newAlarm();
VObject *a;
if ((a = isAPropertyOf(vo, VCRunTimeProp))) {
alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a))));
deleteStr(s);
}
alarm->setEnabled(true);
if ((vo = isAPropertyOf(vevent, VCPAlarmProp))) {
if ((a = isAPropertyOf(vo, VCProcedureNameProp))) {
s = fakeCString(vObjectUStringZValue(a));
alarm->setProcedureAlarm(QFile::decodeName(s));
deleteStr(s);
}
}
if ((vo = isAPropertyOf(vevent, VCAAlarmProp))) {
if ((a = isAPropertyOf(vo, VCAudioContentProp))) {
s = fakeCString(vObjectUStringZValue(a));
alarm->setAudioAlarm(QFile::decodeName(s));
deleteStr(s);
}
}
}
// priority
if ((vo = isAPropertyOf(vevent, VCPriorityProp))) {
anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo))));
deleteStr(s);
}
// transparency
if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) {
int i = atoi(s = fakeCString(vObjectUStringZValue(vo)));
anEvent->setTransparency( i == 1 ? Event::Transparent : Event::Opaque );
deleteStr(s);
}
// related event
if ((vo = isAPropertyOf(vevent, VCRelatedToProp)) != 0) {
anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo)));
deleteStr(s);
mEventsRelate.append(anEvent);
}
/* PILOT SYNC STUFF */
if ((vo = isAPropertyOf(vevent, XPilotIdProp))) {
anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo))));
deleteStr(s);
}
else
anEvent->setPilotId(0);
if ((vo = isAPropertyOf(vevent, XPilotStatusProp))) {
anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo))));
deleteStr(s);
}
else
anEvent->setSyncStatus(Event::SYNCMOD);
return anEvent;
}
QString VCalFormat::qDateToISO(const QDate &qd)
{
QString tmpStr;
ASSERT(qd.isValid());
tmpStr.sprintf("%.2d%.2d%.2d",
qd.year(), qd.month(), qd.day());
return tmpStr;
}
QString VCalFormat::qDateTimeToISO(const QDateTime &qdt, bool zulu)
{
QString tmpStr;
ASSERT(qdt.date().isValid());
ASSERT(qdt.time().isValid());
- if (zulu) {
- QDateTime tmpDT(qdt);
- tmpDT = tmpDT.addSecs(60*(-mCalendar->getTimeZone())); // correct to GMT.
+ if (zulu && !useLocalTime ) {
+ QDateTime tmpDT = qdt.addSecs ( -KGlobal::locale()->localTimeOffset( qdt )*60);
tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2dZ",
tmpDT.date().year(), tmpDT.date().month(),
tmpDT.date().day(), tmpDT.time().hour(),
tmpDT.time().minute(), tmpDT.time().second());
} else {
tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2d",
qdt.date().year(), qdt.date().month(),
qdt.date().day(), qdt.time().hour(),
qdt.time().minute(), qdt.time().second());
}
return tmpStr;
}
QDateTime VCalFormat::ISOToQDateTime(const QString & dtStr)
{
QDate tmpDate;
QTime tmpTime;
QString tmpStr;
int year, month, day, hour, minute, second;
tmpStr = dtStr;
year = tmpStr.left(4).toInt();
month = tmpStr.mid(4,2).toInt();
day = tmpStr.mid(6,2).toInt();
hour = tmpStr.mid(9,2).toInt();
minute = tmpStr.mid(11,2).toInt();
second = tmpStr.mid(13,2).toInt();
tmpDate.setYMD(year, month, day);
tmpTime.setHMS(hour, minute, second);
ASSERT(tmpDate.isValid());
ASSERT(tmpTime.isValid());
QDateTime tmpDT(tmpDate, tmpTime);
// correct for GMT if string is in Zulu format
if (dtStr.at(dtStr.length()-1) == 'Z')
tmpDT = tmpDT.addSecs(60*mCalendar->getTimeZone());
return tmpDT;
}
QDate VCalFormat::ISOToQDate(const QString &dateStr)
{
int year, month, day;
year = dateStr.left(4).toInt();
month = dateStr.mid(4,2).toInt();
day = dateStr.mid(6,2).toInt();
return(QDate(year, month, day));
}
// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc.
// and break it down from it's tree-like format into the dictionary format
// that is used internally in the VCalFormat.
void VCalFormat::populate(VObject *vcal)
{
// this function will populate the caldict dictionary and other event
// lists. It turns vevents into Events and then inserts them.
VObjectIterator i;
VObject *curVO, *curVOProp;
Event *anEvent;
if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
char *methodType = 0;
methodType = fakeCString(vObjectUStringZValue(curVO));
kdDebug() << "This calendar is an iTIP transaction of type '"
<< methodType << "'" << endl;
delete methodType;
}
// warn the user that we might have trouble reading non-known calendar.
if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) {
char *s = fakeCString(vObjectUStringZValue(curVO));
if (strcmp(productId().local8Bit(), s) != 0)
kdDebug() << "This vCalendar file was not created by KOrganizer "
"or any other product we support. Loading anyway..." << endl;
mLoadedProductId = s;
deleteStr(s);
}
// warn the user we might have trouble reading this unknown version.
if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
char *s = fakeCString(vObjectUStringZValue(curVO));
if (strcmp(_VCAL_VERSION, s) != 0)
kdDebug() << "This vCalendar file has version " << s
<< "We only support " << _VCAL_VERSION << endl;
deleteStr(s);
}
// set the time zone
if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
char *s = fakeCString(vObjectUStringZValue(curVO));
mCalendar->setTimeZone(s);
deleteStr(s);
}