summaryrefslogtreecommitdiffabout
path: root/libkcal
authorzautrix <zautrix>2004-10-15 14:26:07 (UTC)
committer zautrix <zautrix>2004-10-15 14:26:07 (UTC)
commit4f276d80bd977401d656851515474cc00c661e5b (patch) (unidiff)
tree0d3a747bef0431ef791b69876f5bda554f9ca83f /libkcal
parentc2fb960297c4b08980921c818a4d347057732390 (diff)
downloadkdepimpi-4f276d80bd977401d656851515474cc00c661e5b.zip
kdepimpi-4f276d80bd977401d656851515474cc00c661e5b.tar.gz
kdepimpi-4f276d80bd977401d656851515474cc00c661e5b.tar.bz2
many phone and sync fixes
Diffstat (limited to 'libkcal') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/event.cpp46
-rw-r--r--libkcal/event.h2
-rw-r--r--libkcal/phoneformat.cpp104
-rw-r--r--libkcal/phoneformat.h2
-rw-r--r--libkcal/todo.cpp58
-rw-r--r--libkcal/todo.h1
-rw-r--r--libkcal/vcalformat.cpp141
7 files changed, 227 insertions, 127 deletions
diff --git a/libkcal/event.cpp b/libkcal/event.cpp
index dfa265b..7256f05 100644
--- a/libkcal/event.cpp
+++ b/libkcal/event.cpp
@@ -1,177 +1,223 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21#include <kglobal.h> 21#include <kglobal.h>
22#include <klocale.h> 22#include <klocale.h>
23#include <kdebug.h> 23#include <kdebug.h>
24 24
25#include "event.h" 25#include "event.h"
26 26
27using namespace KCal; 27using namespace KCal;
28 28
29Event::Event() : 29Event::Event() :
30 mHasEndDate( false ), mTransparency( Opaque ) 30 mHasEndDate( false ), mTransparency( Opaque )
31{ 31{
32} 32}
33 33
34Event::Event(const Event &e) : Incidence(e) 34Event::Event(const Event &e) : Incidence(e)
35{ 35{
36 mDtEnd = e.mDtEnd; 36 mDtEnd = e.mDtEnd;
37 mHasEndDate = e.mHasEndDate; 37 mHasEndDate = e.mHasEndDate;
38 mTransparency = e.mTransparency; 38 mTransparency = e.mTransparency;
39} 39}
40 40
41Event::~Event() 41Event::~Event()
42{ 42{
43} 43}
44 44
45Incidence *Event::clone() 45Incidence *Event::clone()
46{ 46{
47 return new Event(*this); 47 return new Event(*this);
48} 48}
49 49
50bool KCal::operator==( const Event& e1, const Event& e2 ) 50bool KCal::operator==( const Event& e1, const Event& e2 )
51{ 51{
52 return operator==( (const Incidence&)e1, (const Incidence&)e2 ) && 52 return operator==( (const Incidence&)e1, (const Incidence&)e2 ) &&
53 e1.dtEnd() == e2.dtEnd() && 53 e1.dtEnd() == e2.dtEnd() &&
54 e1.hasEndDate() == e2.hasEndDate() && 54 e1.hasEndDate() == e2.hasEndDate() &&
55 e1.transparency() == e2.transparency(); 55 e1.transparency() == e2.transparency();
56} 56}
57 57
58 58
59bool Event::contains ( Event* from )
60{
61
62 if ( !from->summary().isEmpty() )
63 if ( !summary().startsWith( from->summary() ))
64 return false;
65 if ( from->dtStart().isValid() )
66 if (dtStart() != from->dtStart() )
67 return false;
68 if ( from->dtEnd().isValid() )
69 if ( dtEnd() != from->dtEnd() )
70 return false;
71 if ( !from->location().isEmpty() )
72 if ( !location().startsWith( from->location() ) )
73 return false;
74 if ( !from->description().isEmpty() )
75 if ( !description().startsWith( from->description() ))
76 return false;
77 if ( from->alarms().count() ) {
78 Alarm *a = from->alarms().first();
79 if ( a->enabled() ){
80 if ( !alarms().count() )
81 return false;
82 Alarm *b = alarms().first();
83 if( ! b->enabled() )
84 return false;
85 if ( ! (a->offset() == b->offset() ))
86 return false;
87 }
88 }
89 QStringList cat = categories();
90 QStringList catFrom = from->categories();
91 QString nCat;
92 int iii;
93 for ( iii = 0; iii < catFrom.count();++iii ) {
94 nCat = catFrom[iii];
95 if ( !nCat.isEmpty() )
96 if ( !cat.contains( nCat )) {
97 return false;
98 }
99 }
100 if ( from->doesRecur() )
101 if ( from->doesRecur() != doesRecur() && ! (from->doesRecur()== Recurrence::rYearlyMonth && doesRecur()== Recurrence::rYearlyDay) )
102 return false;
103 return true;
104}
59 105
60void Event::setDtEnd(const QDateTime &dtEnd) 106void Event::setDtEnd(const QDateTime &dtEnd)
61{ 107{
62 if (mReadOnly) return; 108 if (mReadOnly) return;
63 109
64 mDtEnd = getEvenTime( dtEnd ); 110 mDtEnd = getEvenTime( dtEnd );
65 111
66 setHasEndDate(true); 112 setHasEndDate(true);
67 setHasDuration(false); 113 setHasDuration(false);
68 114
69 updated(); 115 updated();
70} 116}
71 117
72QDateTime Event::dtEnd() const 118QDateTime Event::dtEnd() const
73{ 119{
74 if (hasEndDate()) return mDtEnd; 120 if (hasEndDate()) return mDtEnd;
75 if (hasDuration()) return dtStart().addSecs(duration()); 121 if (hasDuration()) return dtStart().addSecs(duration());
76 122
77 kdDebug(5800) << "Warning! Event '" << summary() 123 kdDebug(5800) << "Warning! Event '" << summary()
78 << "' does have neither end date nor duration." << endl; 124 << "' does have neither end date nor duration." << endl;
79 return dtStart(); 125 return dtStart();
80} 126}
81 127
82QString Event::dtEndTimeStr() const 128QString Event::dtEndTimeStr() const
83{ 129{
84 return KGlobal::locale()->formatTime(mDtEnd.time()); 130 return KGlobal::locale()->formatTime(mDtEnd.time());
85} 131}
86 132
87QString Event::dtEndDateStr(bool shortfmt) const 133QString Event::dtEndDateStr(bool shortfmt) const
88{ 134{
89 return KGlobal::locale()->formatDate(mDtEnd.date(),shortfmt); 135 return KGlobal::locale()->formatDate(mDtEnd.date(),shortfmt);
90} 136}
91 137
92QString Event::dtEndStr(bool shortfmt) const 138QString Event::dtEndStr(bool shortfmt) const
93{ 139{
94 return KGlobal::locale()->formatDateTime(mDtEnd, shortfmt); 140 return KGlobal::locale()->formatDateTime(mDtEnd, shortfmt);
95} 141}
96 142
97void Event::setHasEndDate(bool b) 143void Event::setHasEndDate(bool b)
98{ 144{
99 mHasEndDate = b; 145 mHasEndDate = b;
100} 146}
101 147
102bool Event::hasEndDate() const 148bool Event::hasEndDate() const
103{ 149{
104 return mHasEndDate; 150 return mHasEndDate;
105} 151}
106 152
107bool Event::isMultiDay() const 153bool Event::isMultiDay() const
108{ 154{
109 bool multi = !(dtStart().date() == dtEnd().date()); 155 bool multi = !(dtStart().date() == dtEnd().date());
110 return multi; 156 return multi;
111} 157}
112 158
113void Event::setTransparency(Event::Transparency transparency) 159void Event::setTransparency(Event::Transparency transparency)
114{ 160{
115 if (mReadOnly) return; 161 if (mReadOnly) return;
116 mTransparency = transparency; 162 mTransparency = transparency;
117 updated(); 163 updated();
118} 164}
119 165
120Event::Transparency Event::transparency() const 166Event::Transparency Event::transparency() const
121{ 167{
122 return mTransparency; 168 return mTransparency;
123} 169}
124 170
125void Event::setDuration(int seconds) 171void Event::setDuration(int seconds)
126{ 172{
127 setHasEndDate(false); 173 setHasEndDate(false);
128 Incidence::setDuration(seconds); 174 Incidence::setDuration(seconds);
129} 175}
130QDateTime Event::getNextAlarmDateTime( bool * ok, int * offset ) const 176QDateTime Event::getNextAlarmDateTime( bool * ok, int * offset ) const
131{ 177{
132 178
133 bool yes; 179 bool yes;
134 QDateTime incidenceStart = getNextOccurence( QDateTime::currentDateTime(), &yes ); 180 QDateTime incidenceStart = getNextOccurence( QDateTime::currentDateTime(), &yes );
135 if ( ! yes || cancelled() ) { 181 if ( ! yes || cancelled() ) {
136 *ok = false; 182 *ok = false;
137 return QDateTime (); 183 return QDateTime ();
138 } 184 }
139 185
140 bool enabled = false; 186 bool enabled = false;
141 Alarm* alarm; 187 Alarm* alarm;
142 int off; 188 int off;
143 QDateTime alarmStart = QDateTime::currentDateTime().addDays( 3650 );; 189 QDateTime alarmStart = QDateTime::currentDateTime().addDays( 3650 );;
144 // if ( QDateTime::currentDateTime() > incidenceStart ){ 190 // if ( QDateTime::currentDateTime() > incidenceStart ){
145// *ok = false; 191// *ok = false;
146// return incidenceStart; 192// return incidenceStart;
147// } 193// }
148 for (QPtrListIterator<Alarm> it(mAlarms); (alarm = it.current()) != 0; ++it) { 194 for (QPtrListIterator<Alarm> it(mAlarms); (alarm = it.current()) != 0; ++it) {
149 if (alarm->enabled()) { 195 if (alarm->enabled()) {
150 if ( alarm->hasTime () ) { 196 if ( alarm->hasTime () ) {
151 if ( alarm->time() < alarmStart ) { 197 if ( alarm->time() < alarmStart ) {
152 alarmStart = alarm->time(); 198 alarmStart = alarm->time();
153 enabled = true; 199 enabled = true;
154 off = alarmStart.secsTo( incidenceStart ); 200 off = alarmStart.secsTo( incidenceStart );
155 } 201 }
156 202
157 } else { 203 } else {
158 int secs = alarm->startOffset().asSeconds(); 204 int secs = alarm->startOffset().asSeconds();
159 if ( incidenceStart.addSecs( secs ) < alarmStart ) { 205 if ( incidenceStart.addSecs( secs ) < alarmStart ) {
160 alarmStart = incidenceStart.addSecs( secs ); 206 alarmStart = incidenceStart.addSecs( secs );
161 enabled = true; 207 enabled = true;
162 off = -secs; 208 off = -secs;
163 } 209 }
164 } 210 }
165 } 211 }
166 } 212 }
167 if ( enabled ) { 213 if ( enabled ) {
168 if ( alarmStart > QDateTime::currentDateTime() ) { 214 if ( alarmStart > QDateTime::currentDateTime() ) {
169 *ok = true; 215 *ok = true;
170 * offset = off; 216 * offset = off;
171 return alarmStart; 217 return alarmStart;
172 } 218 }
173 } 219 }
174 *ok = false; 220 *ok = false;
175 return QDateTime (); 221 return QDateTime ();
176 222
177} 223}
diff --git a/libkcal/event.h b/libkcal/event.h
index 2a8bd95..3bc8adc 100644
--- a/libkcal/event.h
+++ b/libkcal/event.h
@@ -1,88 +1,90 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21#ifndef EVENT_H 21#ifndef EVENT_H
22#define EVENT_H 22#define EVENT_H
23// 23//
24// Event component, representing a VEVENT object 24// Event component, representing a VEVENT object
25// 25//
26 26
27#include "incidence.h" 27#include "incidence.h"
28namespace KCal { 28namespace KCal {
29 29
30/** 30/**
31 This class provides an Event in the sense of RFC2445. 31 This class provides an Event in the sense of RFC2445.
32*/ 32*/
33class Event : public Incidence 33class Event : public Incidence
34{ 34{
35 public: 35 public:
36 enum Transparency { Opaque, Transparent }; 36 enum Transparency { Opaque, Transparent };
37 typedef ListBase<Event> List; 37 typedef ListBase<Event> List;
38 Event(); 38 Event();
39 Event(const Event &); 39 Event(const Event &);
40 ~Event(); 40 ~Event();
41 41
42 QCString type() const { return "Event"; } 42 QCString type() const { return "Event"; }
43 43
44 Incidence *clone(); 44 Incidence *clone();
45 QDateTime getNextAlarmDateTime( bool * ok, int * offset ) const; 45 QDateTime getNextAlarmDateTime( bool * ok, int * offset ) const;
46 46
47 /** for setting an event's ending date/time with a QDateTime. */ 47 /** for setting an event's ending date/time with a QDateTime. */
48 void setDtEnd(const QDateTime &dtEnd); 48 void setDtEnd(const QDateTime &dtEnd);
49 /** Return the event's ending date/time as a QDateTime. */ 49 /** Return the event's ending date/time as a QDateTime. */
50 virtual QDateTime dtEnd() const; 50 virtual QDateTime dtEnd() const;
51 /** returns an event's end time as a string formatted according to the 51 /** returns an event's end time as a string formatted according to the
52 users locale settings */ 52 users locale settings */
53 QString dtEndTimeStr() const; 53 QString dtEndTimeStr() const;
54 /** returns an event's end date as a string formatted according to the 54 /** returns an event's end date as a string formatted according to the
55 users locale settings */ 55 users locale settings */
56 QString dtEndDateStr(bool shortfmt=true) const; 56 QString dtEndDateStr(bool shortfmt=true) const;
57 /** returns an event's end date and time as a string formatted according 57 /** returns an event's end date and time as a string formatted according
58 to the users locale settings */ 58 to the users locale settings */
59 QString dtEndStr(bool shortfmt=true) const; 59 QString dtEndStr(bool shortfmt=true) const;
60 void setHasEndDate(bool); 60 void setHasEndDate(bool);
61 /** Return whether the event has an end date/time. */ 61 /** Return whether the event has an end date/time. */
62 bool hasEndDate() const; 62 bool hasEndDate() const;
63 63
64 /** Return true if the event spans multiple days, otherwise return false. */ 64 /** Return true if the event spans multiple days, otherwise return false. */
65 bool isMultiDay() const; 65 bool isMultiDay() const;
66 66
67 /** set the event's time transparency level. */ 67 /** set the event's time transparency level. */
68 void setTransparency(Transparency transparency); 68 void setTransparency(Transparency transparency);
69 /** get the event's time transparency level. */ 69 /** get the event's time transparency level. */
70 Transparency transparency() const; 70 Transparency transparency() const;
71 71
72 void setDuration(int seconds); 72 void setDuration(int seconds);
73 73
74 bool contains ( Event*);
75
74 private: 76 private:
75 bool accept(Visitor &v) { return v.visit(this); } 77 bool accept(Visitor &v) { return v.visit(this); }
76 78
77 QDateTime mDtEnd; 79 QDateTime mDtEnd;
78 bool mHasEndDate; 80 bool mHasEndDate;
79 Transparency mTransparency; 81 Transparency mTransparency;
80}; 82};
81 83
82bool operator==( const Event&, const Event& ); 84bool operator==( const Event&, const Event& );
83 85
84 86
85} 87}
86 88
87 89
88#endif 90#endif
diff --git a/libkcal/phoneformat.cpp b/libkcal/phoneformat.cpp
index 281434e..101db57 100644
--- a/libkcal/phoneformat.cpp
+++ b/libkcal/phoneformat.cpp
@@ -187,448 +187,434 @@ ulong PhoneFormat::getCsumEvent( Event* event )
187 if ( weekDays[i-1] ) { 187 if ( weekDays[i-1] ) {
188 days += 1 << (i-1); 188 days += 1 << (i-1);
189 } 189 }
190 } 190 }
191 list.append( QString::number( days ) ); 191 list.append( QString::number( days ) );
192 } 192 }
193 //pending weekdays 193 //pending weekdays
194 writeEndDate = true; 194 writeEndDate = true;
195 195
196 break; 196 break;
197 case Recurrence::rMonthlyPos:// 2 197 case Recurrence::rMonthlyPos:// 2
198 list.append( "2" ); 198 list.append( "2" );
199 list.append( QString::number( rec->frequency()) );//12 199 list.append( QString::number( rec->frequency()) );//12
200 200
201 writeEndDate = true; 201 writeEndDate = true;
202 { 202 {
203 int count = 1; 203 int count = 1;
204 QPtrList<Recurrence::rMonthPos> rmp; 204 QPtrList<Recurrence::rMonthPos> rmp;
205 rmp = rec->monthPositions(); 205 rmp = rec->monthPositions();
206 if ( rmp.first()->negative ) 206 if ( rmp.first()->negative )
207 count = 5 - rmp.first()->rPos - 1; 207 count = 5 - rmp.first()->rPos - 1;
208 else 208 else
209 count = rmp.first()->rPos - 1; 209 count = rmp.first()->rPos - 1;
210 list.append( QString::number( count ) ); 210 list.append( QString::number( count ) );
211 211
212 } 212 }
213 213
214 list.append( "0" ); 214 list.append( "0" );
215 break; 215 break;
216 case Recurrence::rMonthlyDay:// 3 216 case Recurrence::rMonthlyDay:// 3
217 list.append( "3" ); 217 list.append( "3" );
218 list.append( QString::number( rec->frequency()) );//12 218 list.append( QString::number( rec->frequency()) );//12
219 list.append( "0" ); 219 list.append( "0" );
220 list.append( "0" ); 220 list.append( "0" );
221 writeEndDate = true; 221 writeEndDate = true;
222 break; 222 break;
223 case Recurrence::rYearlyMonth://4 223 case Recurrence::rYearlyMonth://4
224 list.append( "4" ); 224 list.append( "4" );
225 list.append( QString::number( rec->frequency()) );//12 225 list.append( QString::number( rec->frequency()) );//12
226 list.append( "0" ); 226 list.append( "0" );
227 list.append( "0" ); 227 list.append( "0" );
228 writeEndDate = true; 228 writeEndDate = true;
229 break; 229 break;
230 230
231 default: 231 default:
232 list.append( "255" ); 232 list.append( "255" );
233 list.append( QString() ); 233 list.append( QString() );
234 list.append( "0" ); 234 list.append( "0" );
235 list.append( QString() ); 235 list.append( QString() );
236 list.append( "0" ); 236 list.append( "0" );
237 list.append( "20991231T000000" ); 237 list.append( "20991231T000000" );
238 break; 238 break;
239 } 239 }
240 if ( writeEndDate ) { 240 if ( writeEndDate ) {
241 241
242 if ( rec->endDate().isValid() ) { // 15 + 16 242 if ( rec->endDate().isValid() ) { // 15 + 16
243 list.append( "1" ); 243 list.append( "1" );
244 list.append( PhoneParser::dtToString( rec->endDate()) ); 244 list.append( PhoneParser::dtToString( rec->endDate()) );
245 } else { 245 } else {
246 list.append( "0" ); 246 list.append( "0" );
247 list.append( "20991231T000000" ); 247 list.append( "20991231T000000" );
248 } 248 }
249 249
250 } 250 }
251 attList << list.join(""); 251 attList << list.join("");
252 attList << event->categoriesStr(); 252 attList << event->categoriesStr();
253 //qDebug("csum cat %s", event->categoriesStr().latin1()); 253 //qDebug("csum cat %s", event->categoriesStr().latin1());
254 254
255 attList << event->secrecyStr(); 255 attList << event->secrecyStr();
256 return PhoneFormat::getCsum(attList ); 256 return PhoneFormat::getCsum(attList );
257} 257}
258ulong PhoneFormat::getCsum( const QStringList & attList) 258ulong PhoneFormat::getCsum( const QStringList & attList)
259{ 259{
260 int max = attList.count(); 260 int max = attList.count();
261 ulong cSum = 0; 261 ulong cSum = 0;
262 int j,k,i; 262 int j,k,i;
263 int add; 263 int add;
264 for ( i = 0; i < max ; ++i ) { 264 for ( i = 0; i < max ; ++i ) {
265 QString s = attList[i]; 265 QString s = attList[i];
266 if ( ! s.isEmpty() ){ 266 if ( ! s.isEmpty() ){
267 j = s.length(); 267 j = s.length();
268 for ( k = 0; k < j; ++k ) { 268 for ( k = 0; k < j; ++k ) {
269 int mul = k +1; 269 int mul = k +1;
270 add = s[k].unicode (); 270 add = s[k].unicode ();
271 if ( k < 16 ) 271 if ( k < 16 )
272 mul = mul * mul; 272 mul = mul * mul;
273 int ii = i+1; 273 int ii = i+1;
274 add = add * mul *ii*ii*ii; 274 add = add * mul *ii*ii*ii;
275 cSum += add; 275 cSum += add;
276 } 276 }
277 } 277 }
278 278
279 } 279 }
280 //QString dump = attList.join(","); 280 //QString dump = attList.join(",");
281 //qDebug("csum: %d %s", cSum,dump.latin1()); 281 //qDebug("csum: %d %s", cSum,dump.latin1());
282 282
283 return cSum; 283 return cSum;
284 284
285} 285}
286//extern "C" GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum); 286//extern "C" GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum);
287#include <stdlib.h> 287#include <stdlib.h>
288#define DEBUGMODE false 288#define DEBUGMODE false
289bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal) 289bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal)
290{ 290{
291 291
292 QString fileName; 292 QString fileName;
293#ifdef _WIN32_ 293#ifdef _WIN32_
294 fileName = locateLocal("tmp", "phonefile.vcs"); 294 fileName = locateLocal("tmp", "phonefile.vcs");
295#else 295#else
296 fileName = "/tmp/phonefile.vcs"; 296 fileName = "/tmp/phonefile.vcs";
297#endif 297#endif
298 QString command; 298 QString command;
299 if ( ! PhoneAccess::readFromPhone( fileName )) { 299 if ( ! PhoneAccess::readFromPhone( fileName )) {
300 return false; 300 return false;
301 } 301 }
302 VCalFormat vfload; 302 VCalFormat vfload;
303 vfload.setLocalTime ( true ); 303 vfload.setLocalTime ( true );
304 qDebug("loading file ..."); 304 qDebug("loading file ...");
305 305
306 if ( ! vfload.load( calendar, fileName ) ) 306 if ( ! vfload.load( calendar, fileName ) )
307 return false; 307 return false;
308 QPtrList<Event> er = calendar->rawEvents(); 308 QPtrList<Event> er = calendar->rawEvents();
309 Event* ev = er.first(); 309 Event* ev = er.first();
310 qDebug("reading events... "); 310 qDebug("reading events... ");
311 while ( ev ) { 311 while ( ev ) {
312 QStringList cat = ev->categories(); 312 QStringList cat = ev->categories();
313 if ( cat.contains( "MeetingDEF" )) { 313 if ( cat.contains( "MeetingDEF" )) {
314 ev->setCategories( QStringList() ); 314 ev->setCategories( QStringList() );
315 } else
316 if ( cat.contains( "Birthday" )) {
317 ev->setFloats( true );
318 QDate da = ev->dtStart().date();
319 ev->setDtStart( QDateTime( da) );
320 ev->setDtEnd( QDateTime( da.addDays(1)) );
321
315 } 322 }
323 uint cSum;
324 cSum = PhoneFormat::getCsumEvent( ev );
316 int id = ev->pilotId(); 325 int id = ev->pilotId();
317 Event *event; 326 Event *event;
318 event = existingCal->event( mProfileName ,QString::number( id ) ); 327 event = existingCal->event( mProfileName ,QString::number( id ) );
319 if ( event ) { 328 if ( event ) {
320 event = (Event*)event->clone(); 329 event = (Event*)event->clone();
321 copyEvent( event, ev ); 330 copyEvent( event, ev );
322 calendar->deleteEvent( ev ); 331 calendar->deleteEvent( ev );
323 calendar->addEvent( event); 332 calendar->addEvent( event);
324 } 333 }
325 else 334 else
326 event = ev; 335 event = ev;
327 uint cSum;
328 cSum = PhoneFormat::getCsumEvent( event );
329 event->setCsum( mProfileName, QString::number( cSum )); 336 event->setCsum( mProfileName, QString::number( cSum ));
330 event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); 337 event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL );
331 event->setID( mProfileName,QString::number( id ) ); 338 event->setID( mProfileName,QString::number( id ) );
332 ev = er.next(); 339 ev = er.next();
333 } 340 }
334 { 341 {
335 qDebug("reading todos... "); 342 qDebug("reading todos... ");
336 QPtrList<Todo> tr = calendar->rawTodos(); 343 QPtrList<Todo> tr = calendar->rawTodos();
337 Todo* ev = tr.first(); 344 Todo* ev = tr.first();
338 while ( ev ) { 345 while ( ev ) {
339 346
340 QStringList cat = ev->categories(); 347 QStringList cat = ev->categories();
341 if ( cat.contains( "MeetingDEF" )) { 348 if ( cat.contains( "MeetingDEF" )) {
342 ev->setCategories( QStringList() ); 349 ev->setCategories( QStringList() );
343 } 350 }
344 int id = ev->pilotId(); 351 int id = ev->pilotId();
352 uint cSum;
353 cSum = PhoneFormat::getCsumTodo( ev );
345 Todo *event; 354 Todo *event;
346 event = existingCal->todo( mProfileName ,QString::number( id ) ); 355 event = existingCal->todo( mProfileName ,QString::number( id ) );
347 if ( event ) { 356 if ( event ) {
348 //qDebug("copy todo %s ", event->summary().latin1()); 357 //qDebug("copy todo %s ", event->summary().latin1());
349 358
350 event = (Todo*)event->clone(); 359 event = (Todo*)event->clone();
351 copyTodo( event, ev ); 360 copyTodo( event, ev );
352 calendar->deleteTodo( ev ); 361 calendar->deleteTodo( ev );
353 calendar->addTodo( event); 362 calendar->addTodo( event);
354 } 363 }
355 else 364 else
356 event = ev; 365 event = ev;
357 uint cSum;
358 cSum = PhoneFormat::getCsumTodo( event );
359 event->setCsum( mProfileName, QString::number( cSum )); 366 event->setCsum( mProfileName, QString::number( cSum ));
360 event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); 367 event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL );
361 event->setID( mProfileName,QString::number( id ) ); 368 event->setID( mProfileName,QString::number( id ) );
362 ev = tr.next(); 369 ev = tr.next();
363 } 370 }
364 } 371 }
365 return true; 372 return true;
366} 373}
367void PhoneFormat::copyEvent( Event* to, Event* from ) 374void PhoneFormat::copyEvent( Event* to, Event* from )
368{ 375{
369 if ( from->dtStart().isValid() ) 376 if ( from->dtStart().isValid() )
370 to->setDtStart( from->dtStart() ); 377 to->setDtStart( from->dtStart() );
371 if ( from->dtEnd().isValid() ) 378 if ( from->dtEnd().isValid() )
372 to->setDtEnd( from->dtEnd() ); 379 to->setDtEnd( from->dtEnd() );
373 if ( !from->location().isEmpty() ) 380 if ( !from->location().isEmpty() )
374 to->setLocation( from->location() ); 381 to->setLocation( from->location() );
375 if ( !from->description().isEmpty() ) 382 if ( !from->description().isEmpty() )
376 to->setDescription( from->description() ); 383 to->setDescription( from->description() );
377 if ( !from->summary().isEmpty() ) 384 if ( !from->summary().isEmpty() )
378 to->setSummary( from->summary() ); 385 to->setSummary( from->summary() );
379 386
380 if ( from->alarms().count() ) { 387 if ( from->alarms().count() ) {
381 to->clearAlarms(); 388 to->clearAlarms();
382 Alarm *a = from->alarms().first(); 389 Alarm *a = from->alarms().first();
383 Alarm *b = to->newAlarm( ); 390 Alarm *b = to->newAlarm( );
384 b->setEnabled( a->enabled() ); 391 b->setEnabled( a->enabled() );
385 if ( a->hasStartOffset() ) { 392 b->setStartOffset(Duration( a->offset() ) );
386 b->setStartOffset( a->startOffset() );
387 }
388 if ( a->hasTime() )
389 b->setTime( a->time() );
390 393
391 } 394 }
392 QStringList cat = to->categories(); 395 QStringList cat = to->categories();
393 QStringList catFrom = from->categories(); 396 QStringList catFrom = from->categories();
394 QString nCat; 397 QString nCat;
395 int iii; 398 int iii;
396 for ( iii = 0; iii < catFrom.count();++iii ) { 399 for ( iii = 0; iii < catFrom.count();++iii ) {
397 nCat = catFrom[iii]; 400 nCat = catFrom[iii];
398 if ( !nCat.isEmpty() ) 401 if ( !nCat.isEmpty() )
399 if ( !cat.contains( nCat )) { 402 if ( !cat.contains( nCat )) {
400 cat << nCat; 403 cat << nCat;
401 } 404 }
402 } 405 }
403 to->setCategories( cat ); 406 to->setCategories( cat );
404 Recurrence * r = new Recurrence( *from->recurrence(),to); 407 if ( from->doesRecur() ) {
405 to->setRecurrence( r ) ; 408 Recurrence * r = new Recurrence( *from->recurrence(),to);
409 to->setRecurrence( r ) ;
410 }
406 411
407 412
408} 413}
409void PhoneFormat::copyTodo( Todo* to, Todo* from ) 414void PhoneFormat::copyTodo( Todo* to, Todo* from )
410{ 415{
411 if ( from->dtStart().isValid() ) 416 if ( from->hasStartDate() ) {
417 to->setHasStartDate( true );
412 to->setDtStart( from->dtStart() ); 418 to->setDtStart( from->dtStart() );
413 if ( from->dtDue().isValid() ) 419 }
420 if ( from->hasDueDate() ){
421 to->setHasDueDate( true );
414 to->setDtDue( from->dtDue() ); 422 to->setDtDue( from->dtDue() );
423 }
415 if ( !from->location().isEmpty() ) 424 if ( !from->location().isEmpty() )
416 to->setLocation( from->location() ); 425 to->setLocation( from->location() );
417 if ( !from->description().isEmpty() ) 426 if ( !from->description().isEmpty() )
418 to->setDescription( from->description() ); 427 to->setDescription( from->description() );
419 if ( !from->summary().isEmpty() ) 428 if ( !from->summary().isEmpty() )
420 to->setSummary( from->summary() ); 429 to->setSummary( from->summary() );
421 430
422 if ( from->alarms().count() ) { 431 if ( from->alarms().count() ) {
423 to->clearAlarms(); 432 to->clearAlarms();
424 Alarm *a = from->alarms().first(); 433 Alarm *a = from->alarms().first();
425 Alarm *b = to->newAlarm( ); 434 Alarm *b = to->newAlarm( );
426 b->setEnabled( a->enabled() ); 435 b->setEnabled( a->enabled() );
427 if ( a->hasStartOffset() ) 436 b->setStartOffset(Duration( a->offset() ) );
428 b->setStartOffset( a->startOffset() );
429 if ( a->hasTime() )
430 b->setTime( a->time() );
431 } 437 }
432 438
433 QStringList cat = to->categories(); 439 QStringList cat = to->categories();
434 QStringList catFrom = from->categories(); 440 QStringList catFrom = from->categories();
435 QString nCat; 441 QString nCat;
436 int iii; 442 int iii;
437 for ( iii = 0; iii < catFrom.count();++iii ) { 443 for ( iii = 0; iii < catFrom.count();++iii ) {
438 nCat = catFrom[iii]; 444 nCat = catFrom[iii];
439 if ( !nCat.isEmpty() ) 445 if ( !nCat.isEmpty() )
440 if ( !cat.contains( nCat )) { 446 if ( !cat.contains( nCat )) {
441 cat << nCat; 447 cat << nCat;
442 } 448 }
443 } 449 }
444 to->setCategories( cat ); 450 to->setCategories( cat );
445 if ( from->isCompleted() ) { 451 if ( from->isCompleted() ) {
446 to->setCompleted( true ); 452 to->setCompleted( true );
447 if( from->completed().isValid() ) 453 if( from->completed().isValid() )
448 to->setCompleted( from->completed() ); 454 to->setCompleted( from->completed() );
449 } else { 455 } else {
450 // set percentcomplete only, if to->isCompleted() 456 // set percentcomplete only, if to->isCompleted()
451 if ( to->isCompleted() ) 457 if ( to->isCompleted() )
452 to->setPercentComplete(from->percentComplete()); 458 to->setPercentComplete(from->percentComplete());
453 } 459 }
454 if( to->priority() == 2 && from->priority() == 1 ) 460 if( to->priority() == 2 && from->priority() == 1 )
455 ; //skip 461 ; //skip
456 else if (to->priority() == 4 && from->priority() == 5 ) 462 else if (to->priority() == 4 && from->priority() == 5 )
457 ; 463 ;
458 else 464 else
459 to->setPriority(from->priority()); 465 to->setPriority(from->priority());
460 466
461} 467}
462#include <qcstring.h> 468#include <qcstring.h>
463 469
464void PhoneFormat::afterSave( Incidence* inc) 470void PhoneFormat::afterSave( Incidence* inc,const QString& id ,const QString& csum)
465{ 471{
466 uint csum; 472 inc->setID( mProfileName, id );
467 inc->removeID( mProfileName ); 473 inc->setCsum( mProfileName, csum);
468 if ( inc->type() == "Event")
469 csum = PhoneFormat::getCsumEvent( (Event*) inc );
470 else
471 csum = PhoneFormat::getCsumTodo( (Todo*) inc );
472 inc->setCsum( mProfileName, QString::number( csum ));
473
474 inc->setTempSyncStat( SYNC_TEMPSTATE_NEW_ID ); 474 inc->setTempSyncStat( SYNC_TEMPSTATE_NEW_ID );
475 475
476} 476}
477 477
478bool PhoneFormat::writeToPhone( Calendar * calendar) 478bool PhoneFormat::writeToPhone( Calendar * calendar)
479{ 479{
480#ifdef _WIN32_ 480#ifdef _WIN32_
481 QString fileName = locateLocal("tmp", "tempfile.vcs"); 481 QString fileName = locateLocal("tmp", "phonefile.vcs");
482#else 482#else
483 QString fileName = "/tmp/kdepimtemp.vcs"; 483 QString fileName = "/tmp/phonefile.vcs";
484#endif 484#endif
485 485
486 VCalFormat vfsave; 486 VCalFormat vfsave;
487 vfsave.setLocalTime ( true ); 487 vfsave.setLocalTime ( true );
488 QString id = calendar->timeZoneId(); 488 QString id = calendar->timeZoneId();
489 calendar->setLocalTime(); 489 calendar->setLocalTime();
490 if ( ! vfsave.save( calendar, fileName ) ) 490 if ( ! vfsave.save( calendar, fileName ) )
491 return false; 491 return false;
492 calendar->setTimeZoneId( id ); 492 calendar->setTimeZoneId( id );
493 return PhoneAccess::writeToPhone( fileName ); 493 return PhoneAccess::writeToPhone( fileName );
494} 494}
495bool PhoneFormat::save( Calendar *calendar) 495bool PhoneFormat::save( Calendar *calendar)
496{ 496{
497 QLabel status ( i18n(" Opening device ..."), 0 ); 497
498 int w = status.sizeHint().width()+20 ;
499 if ( w < 200 ) w = 230;
500 int h = status.sizeHint().height()+20 ;
501 int dw = QApplication::desktop()->width();
502 int dh = QApplication::desktop()->height();
503 status.setCaption(i18n("Writing to phone...") );
504 status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
505 status.show();
506 status.raise();
507 qApp->processEvents();
508 QString message;
509 498
510 // 1 remove events which should be deleted 499 // 1 remove events which should be deleted
511 QPtrList<Event> er = calendar->rawEvents(); 500 QPtrList<Event> er = calendar->rawEvents();
512 Event* ev = er.first(); 501 Event* ev = er.first();
513 while ( ev ) { 502 while ( ev ) {
514 if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { 503 if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) {
515 calendar->deleteEvent( ev ); 504 calendar->deleteEvent( ev );
516 } else { 505 } else {
517 506
518 } 507 }
519 ev = er.next(); 508 ev = er.next();
520 } 509 }
521 // 2 remove todos which should be deleted 510 // 2 remove todos which should be deleted
522 QPtrList<Todo> tl = calendar->rawTodos(); 511 QPtrList<Todo> tl = calendar->rawTodos();
523 Todo* to = tl.first(); 512 Todo* to = tl.first();
524 while ( to ) { 513 while ( to ) {
525 if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { 514 if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) {
526 calendar->deleteTodo( to ); 515 calendar->deleteTodo( to );
527 } else { 516 } else {
528 if ( to->isCompleted()) { 517 if ( to->isCompleted()) {
529 calendar->deleteTodo( to ); 518 calendar->deleteTodo( to );
530 } 519 }
531 } 520 }
532 to = tl.next(); 521 to = tl.next();
533 } 522 }
534 // 3 save file 523 // 3 save file
535 if ( !writeToPhone( calendar ) ) 524 if ( !writeToPhone( calendar ) )
536 return false; 525 return false;
537 526 QLabel status ( i18n(" Opening device ..."), 0 );
527 int w = status.sizeHint().width()+20 ;
528 if ( w < 200 ) w = 230;
529 int h = status.sizeHint().height()+20 ;
530 int dw = QApplication::desktop()->width();
531 int dh = QApplication::desktop()->height();
532 status.setCaption(i18n("Writing to phone...") );
533 status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
534 QString message;
535 status.show();
536 status.raise();
537 qApp->processEvents();
538 // 5 reread data 538 // 5 reread data
539 message = i18n(" Rereading all data ... "); 539 message = i18n(" Rereading all data ... ");
540 status.setText ( message ); 540 status.setText ( message );
541 qApp->processEvents(); 541 qApp->processEvents();
542 CalendarLocal* calendarTemp = new CalendarLocal(); 542 CalendarLocal* calendarTemp = new CalendarLocal();
543 calendarTemp->setTimeZoneId( calendar->timeZoneId()); 543 calendarTemp->setTimeZoneId( calendar->timeZoneId());
544 if ( ! load( calendarTemp,calendar) ){ 544 if ( ! load( calendarTemp,calendar) ){
545 qDebug("error reloading calendar "); 545 qDebug("error reloading calendar ");
546 delete calendarTemp; 546 delete calendarTemp;
547 return false; 547 return false;
548 } 548 }
549 // 6 compare data 549 // 6 compare data
550 550
551//algo 6 compare event 551//algo 6 compare event
552 er = calendar->rawEvents(); 552 er = calendar->rawEvents();
553 ev = er.first(); 553 ev = er.first();
554 message = i18n(" Comparing event # "); 554 message = i18n(" Comparing event # ");
555 QPtrList<Event> er1 = calendarTemp->rawEvents(); 555 QPtrList<Event> er1 = calendarTemp->rawEvents();
556 Event* ev1; 556 Event* ev1;
557 int procCount = 0; 557 int procCount = 0;
558 while ( ev ) { 558 while ( ev ) {
559 //qDebug("event new ID %s",ev->summary().latin1()); 559 //qDebug("event new ID %s",ev->summary().latin1());
560 status.setText ( message + QString::number ( ++procCount ) ); 560 status.setText ( message + QString::number ( ++procCount ) );
561 qApp->processEvents(); 561 qApp->processEvents();
562 uint csum;
563 csum = PhoneFormat::getCsumEvent( ev );
564 QString cSum = QString::number( csum );
565 //ev->setCsum( mProfileName, cSum );
566 //qDebug("Event cSum %s ", cSum.latin1());
567 ev1 = er1.first(); 562 ev1 = er1.first();
568 while ( ev1 ) { 563 while ( ev1 ) {
569 if ( ev1->getCsum( mProfileName ) == cSum ) { 564 if ( ev->contains( ev1 ) ) {
565 afterSave( ev ,ev1->getID(mProfileName),ev1->getCsum(mProfileName));
570 er1.remove( ev1 ); 566 er1.remove( ev1 );
571 afterSave( ev );
572 ev->setID(mProfileName, ev1->getID(mProfileName) );
573 //qDebug("Event found on phone for %s ", ev->summary().latin1());
574
575 break; 567 break;
576 } 568 }
577 ev1 = er1.next(); 569 ev1 = er1.next();
578 } 570 }
579 if ( ! ev1 ) { 571 if ( ! ev1 ) {
580 // ev->removeID(mProfileName); 572 // ev->removeID(mProfileName);
581 qDebug("ERROR: No event found on phone for %s ", ev->summary().latin1()); 573 qDebug("ERROR: No event found on phone for %s ", ev->summary().latin1());
582 } 574 }
583 575
584 576
585 ev = er.next(); 577 ev = er.next();
586 } 578 }
587 //algo 6 compare todo 579 //algo 6 compare todo
588 tl = calendar->rawTodos(); 580 tl = calendar->rawTodos();
589 to = tl.first(); 581 to = tl.first();
590 procCount = 0; 582 procCount = 0;
591 QPtrList<Todo> tl1 = calendarTemp->rawTodos(); 583 QPtrList<Todo> tl1 = calendarTemp->rawTodos();
592 Todo* to1 ; 584 Todo* to1 ;
593 message = i18n(" Comparing todo # "); 585 message = i18n(" Comparing todo # ");
594 while ( to ) { 586 while ( to ) {
595 status.setText ( message + QString::number ( ++procCount ) ); 587 status.setText ( message + QString::number ( ++procCount ) );
596 qApp->processEvents(); 588 qApp->processEvents();
597 uint csum;
598 csum = PhoneFormat::getCsumTodo( to );
599 QString cSum = QString::number( csum );
600 //to->setCsum( mProfileName, cSum );
601 //qDebug("Todo cSum %s ", cSum.latin1());
602 Todo* to1 = tl1.first(); 589 Todo* to1 = tl1.first();
603 while ( to1 ) { 590 while ( to1 ) {
604 if ( to1->getCsum( mProfileName ) == cSum ) { 591 if ( to->contains( to1 ) ) {
592 afterSave( to ,to1->getID(mProfileName),to1->getCsum(mProfileName));
605 tl1.remove( to1 ); 593 tl1.remove( to1 );
606 afterSave( to );
607 to->setID(mProfileName, to1->getID(mProfileName) );
608 break; 594 break;
609 } 595 }
610 to1 = tl1.next(); 596 to1 = tl1.next();
611 } 597 }
612 if ( ! to1 ) { 598 if ( ! to1 ) {
613 //to->removeID(mProfileName); 599 //to->removeID(mProfileName);
614 qDebug("ERROR: No todo found on phone for %s ", to->summary().latin1()); 600 qDebug("ERROR: No todo found on phone for %s ", to->summary().latin1());
615 } 601 }
616 602
617 to = tl.next(); 603 to = tl.next();
618 } 604 }
619 delete calendarTemp; 605 delete calendarTemp;
620 return true; 606 return true;
621 607
622 608
623 609
624} 610}
625 611
626 612
627QString PhoneFormat::toString( Calendar * ) 613QString PhoneFormat::toString( Calendar * )
628{ 614{
629 return QString::null; 615 return QString::null;
630} 616}
631bool PhoneFormat::fromString( Calendar *calendar, const QString & text) 617bool PhoneFormat::fromString( Calendar *calendar, const QString & text)
632{ 618{
633 return false; 619 return false;
634} 620}
diff --git a/libkcal/phoneformat.h b/libkcal/phoneformat.h
index 001fd81..d11f68b 100644
--- a/libkcal/phoneformat.h
+++ b/libkcal/phoneformat.h
@@ -1,62 +1,62 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 3
4 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> 4 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
5 5
6 This library is free software; you can redistribute it and/or 6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public 7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either 8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version. 9 version 2 of the License, or (at your option) any later version.
10 10
11 This library is distributed in the hope that it will be useful, 11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details. 14 Library General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public License 16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to 17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. 19 Boston, MA 02111-1307, USA.
20*/ 20*/
21#ifndef PHONEFORMAT_H 21#ifndef PHONEFORMAT_H
22#define PHONEFORMAT_H 22#define PHONEFORMAT_H
23 23
24#include <qstring.h> 24#include <qstring.h>
25 25
26#include "scheduler.h" 26#include "scheduler.h"
27 27
28#include "vcalformat.h" 28#include "vcalformat.h"
29#include "calformat.h" 29#include "calformat.h"
30 30
31namespace KCal { 31namespace KCal {
32 32
33/** 33/**
34 This class implements the calendar format used by Phone. 34 This class implements the calendar format used by Phone.
35*/ 35*/
36 class Event; 36 class Event;
37 class Todo; 37 class Todo;
38class PhoneFormat : public QObject { 38class PhoneFormat : public QObject {
39 public: 39 public:
40 /** Create new iCalendar format. */ 40 /** Create new iCalendar format. */
41 PhoneFormat(QString profileName, QString device,QString connection, QString model); 41 PhoneFormat(QString profileName, QString device,QString connection, QString model);
42 virtual ~PhoneFormat(); 42 virtual ~PhoneFormat();
43 43
44 bool load( Calendar * ,Calendar * ); 44 bool load( Calendar * ,Calendar * );
45 bool save( Calendar * ); 45 bool save( Calendar * );
46 bool fromString( Calendar *, const QString & ); 46 bool fromString( Calendar *, const QString & );
47 QString toString( Calendar * ); 47 QString toString( Calendar * );
48 static ulong getCsum( const QStringList & ); 48 static ulong getCsum( const QStringList & );
49 static ulong getCsumTodo( Todo* to ); 49 static ulong getCsumTodo( Todo* to );
50 static ulong getCsumEvent( Event* ev ); 50 static ulong getCsumEvent( Event* ev );
51 static bool writeToPhone( Calendar * ); 51 static bool writeToPhone( Calendar * );
52 private: 52 private:
53 void copyEvent( Event* to, Event* from ); 53 void copyEvent( Event* to, Event* from );
54 void copyTodo( Todo* to, Todo* from ); 54 void copyTodo( Todo* to, Todo* from );
55 //int initDevice(GSM_StateMachine *s); 55 //int initDevice(GSM_StateMachine *s);
56 QString mProfileName; 56 QString mProfileName;
57 void afterSave( Incidence* ); 57 void afterSave( Incidence* ,const QString&,const QString&);
58}; 58};
59 59
60} 60}
61 61
62#endif 62#endif
diff --git a/libkcal/todo.cpp b/libkcal/todo.cpp
index 0c1e3e4..3d2de61 100644
--- a/libkcal/todo.cpp
+++ b/libkcal/todo.cpp
@@ -1,187 +1,245 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21#include <kglobal.h> 21#include <kglobal.h>
22#include <klocale.h> 22#include <klocale.h>
23#include <kdebug.h> 23#include <kdebug.h>
24 24
25#include "todo.h" 25#include "todo.h"
26 26
27using namespace KCal; 27using namespace KCal;
28 28
29Todo::Todo(): Incidence() 29Todo::Todo(): Incidence()
30{ 30{
31// mStatus = TENTATIVE; 31// mStatus = TENTATIVE;
32 32
33 mHasDueDate = false; 33 mHasDueDate = false;
34 setHasStartDate( false ); 34 setHasStartDate( false );
35 mCompleted = getEvenTime(QDateTime::currentDateTime()); 35 mCompleted = getEvenTime(QDateTime::currentDateTime());
36 mHasCompletedDate = false; 36 mHasCompletedDate = false;
37 mPercentComplete = 0; 37 mPercentComplete = 0;
38} 38}
39 39
40Todo::Todo(const Todo &t) : Incidence(t) 40Todo::Todo(const Todo &t) : Incidence(t)
41{ 41{
42 mDtDue = t.mDtDue; 42 mDtDue = t.mDtDue;
43 mHasDueDate = t.mHasDueDate; 43 mHasDueDate = t.mHasDueDate;
44 mCompleted = t.mCompleted; 44 mCompleted = t.mCompleted;
45 mHasCompletedDate = t.mHasCompletedDate; 45 mHasCompletedDate = t.mHasCompletedDate;
46 mPercentComplete = t.mPercentComplete; 46 mPercentComplete = t.mPercentComplete;
47} 47}
48 48
49Todo::~Todo() 49Todo::~Todo()
50{ 50{
51 51
52} 52}
53 53
54Incidence *Todo::clone() 54Incidence *Todo::clone()
55{ 55{
56 return new Todo(*this); 56 return new Todo(*this);
57} 57}
58 58
59bool Todo::contains ( Todo* from )
60{
59 61
62 if ( !from->summary().isEmpty() )
63 if ( !summary().startsWith( from->summary() ))
64 return false;
65 if ( from->hasStartDate() ) {
66 if ( !hasStartDate() )
67 return false;
68 if ( from->dtStart() != dtStart())
69 return false;
70 }
71 if ( from->hasDueDate() ){
72 if ( !hasDueDate() )
73 return false;
74 if ( from->dtDue() != dtDue())
75 return false;
76 }
77 if ( !from->location().isEmpty() )
78 if ( !location().startsWith( from->location() ) )
79 return false;
80 if ( !from->description().isEmpty() )
81 if ( !description().startsWith( from->description() ))
82 return false;
83 if ( from->alarms().count() ) {
84 Alarm *a = from->alarms().first();
85 if ( a->enabled() ){
86 if ( !alarms().count() )
87 return false;
88 Alarm *b = alarms().first();
89 if( ! b->enabled() )
90 return false;
91 if ( ! (a->offset() == b->offset() ))
92 return false;
93 }
94 }
95
96 QStringList cat = categories();
97 QStringList catFrom = from->categories();
98 QString nCat;
99 int iii;
100 for ( iii = 0; iii < catFrom.count();++iii ) {
101 nCat = catFrom[iii];
102 if ( !nCat.isEmpty() )
103 if ( !cat.contains( nCat )) {
104 return false;
105 }
106 }
107 if ( from->isCompleted() ) {
108 if ( !isCompleted() )
109 return false;
110 }
111 if( priority() != from->priority() )
112 return false;
113
114
115 return true;
116
117}
60bool KCal::operator==( const Todo& t1, const Todo& t2 ) 118bool KCal::operator==( const Todo& t1, const Todo& t2 )
61{ 119{
62 120
63 bool ret = operator==( (const Incidence&)t1, (const Incidence&)t2 ); 121 bool ret = operator==( (const Incidence&)t1, (const Incidence&)t2 );
64 if ( ! ret ) 122 if ( ! ret )
65 return false; 123 return false;
66 if ( t1.hasDueDate() == t2.hasDueDate() ) { 124 if ( t1.hasDueDate() == t2.hasDueDate() ) {
67 if ( t1.hasDueDate() ) { 125 if ( t1.hasDueDate() ) {
68 if ( t1.doesFloat() == t2.doesFloat() ) { 126 if ( t1.doesFloat() == t2.doesFloat() ) {
69 if ( t1.doesFloat() ) { 127 if ( t1.doesFloat() ) {
70 if ( t1.dtDue().date() != t2.dtDue().date() ) 128 if ( t1.dtDue().date() != t2.dtDue().date() )
71 return false; 129 return false;
72 } else 130 } else
73 if ( t1.dtDue() != t2.dtDue() ) 131 if ( t1.dtDue() != t2.dtDue() )
74 return false; 132 return false;
75 } else 133 } else
76 return false;// float != 134 return false;// float !=
77 } 135 }
78 136
79 } else 137 } else
80 return false; 138 return false;
81 if ( t1.percentComplete() != t2.percentComplete() ) 139 if ( t1.percentComplete() != t2.percentComplete() )
82 return false; 140 return false;
83 if ( t1.isCompleted() ) { 141 if ( t1.isCompleted() ) {
84 if ( t1.hasCompletedDate() == t2.hasCompletedDate() ) { 142 if ( t1.hasCompletedDate() == t2.hasCompletedDate() ) {
85 if ( t1.hasCompletedDate() ) { 143 if ( t1.hasCompletedDate() ) {
86 if ( t1.completed() != t2.completed() ) 144 if ( t1.completed() != t2.completed() )
87 return false; 145 return false;
88 } 146 }
89 147
90 } else 148 } else
91 return false; 149 return false;
92 } 150 }
93 return true; 151 return true;
94 152
95} 153}
96 154
97void Todo::setDtDue(const QDateTime &dtDue) 155void Todo::setDtDue(const QDateTime &dtDue)
98{ 156{
99 //int diffsecs = mDtDue.secsTo(dtDue); 157 //int diffsecs = mDtDue.secsTo(dtDue);
100 158
101 /*if (mReadOnly) return; 159 /*if (mReadOnly) return;
102 const QPtrList<Alarm>& alarms = alarms(); 160 const QPtrList<Alarm>& alarms = alarms();
103 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) { 161 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) {
104 if (alarm->enabled()) { 162 if (alarm->enabled()) {
105 alarm->setTime(alarm->time().addSecs(diffsecs)); 163 alarm->setTime(alarm->time().addSecs(diffsecs));
106 } 164 }
107 }*/ 165 }*/
108 mDtDue = getEvenTime(dtDue); 166 mDtDue = getEvenTime(dtDue);
109 167
110 //kdDebug(5800) << "setDtDue says date is " << mDtDue.toString() << endl; 168 //kdDebug(5800) << "setDtDue says date is " << mDtDue.toString() << endl;
111 169
112 /*const QPtrList<Alarm>& alarms = alarms(); 170 /*const QPtrList<Alarm>& alarms = alarms();
113 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) 171 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next())
114 alarm->setAlarmStart(mDtDue);*/ 172 alarm->setAlarmStart(mDtDue);*/
115 173
116 updated(); 174 updated();
117} 175}
118 176
119QDateTime Todo::dtDue() const 177QDateTime Todo::dtDue() const
120{ 178{
121 return mDtDue; 179 return mDtDue;
122} 180}
123 181
124QString Todo::dtDueTimeStr() const 182QString Todo::dtDueTimeStr() const
125{ 183{
126 return KGlobal::locale()->formatTime(mDtDue.time()); 184 return KGlobal::locale()->formatTime(mDtDue.time());
127} 185}
128 186
129QString Todo::dtDueDateStr(bool shortfmt) const 187QString Todo::dtDueDateStr(bool shortfmt) const
130{ 188{
131 return KGlobal::locale()->formatDate(mDtDue.date(),shortfmt); 189 return KGlobal::locale()->formatDate(mDtDue.date(),shortfmt);
132} 190}
133 191
134QString Todo::dtDueStr(bool shortfmt) const 192QString Todo::dtDueStr(bool shortfmt) const
135{ 193{
136 return KGlobal::locale()->formatDateTime(mDtDue, shortfmt); 194 return KGlobal::locale()->formatDateTime(mDtDue, shortfmt);
137} 195}
138 196
139bool Todo::hasDueDate() const 197bool Todo::hasDueDate() const
140{ 198{
141 return mHasDueDate; 199 return mHasDueDate;
142} 200}
143 201
144void Todo::setHasDueDate(bool f) 202void Todo::setHasDueDate(bool f)
145{ 203{
146 if (mReadOnly) return; 204 if (mReadOnly) return;
147 mHasDueDate = f; 205 mHasDueDate = f;
148 updated(); 206 updated();
149} 207}
150 208
151 209
152#if 0 210#if 0
153void Todo::setStatus(const QString &statStr) 211void Todo::setStatus(const QString &statStr)
154{ 212{
155 if (mReadOnly) return; 213 if (mReadOnly) return;
156 QString ss(statStr.upper()); 214 QString ss(statStr.upper());
157 215
158 if (ss == "X-ACTION") 216 if (ss == "X-ACTION")
159 mStatus = NEEDS_ACTION; 217 mStatus = NEEDS_ACTION;
160 else if (ss == "NEEDS ACTION") 218 else if (ss == "NEEDS ACTION")
161 mStatus = NEEDS_ACTION; 219 mStatus = NEEDS_ACTION;
162 else if (ss == "ACCEPTED") 220 else if (ss == "ACCEPTED")
163 mStatus = ACCEPTED; 221 mStatus = ACCEPTED;
164 else if (ss == "SENT") 222 else if (ss == "SENT")
165 mStatus = SENT; 223 mStatus = SENT;
166 else if (ss == "TENTATIVE") 224 else if (ss == "TENTATIVE")
167 mStatus = TENTATIVE; 225 mStatus = TENTATIVE;
168 else if (ss == "CONFIRMED") 226 else if (ss == "CONFIRMED")
169 mStatus = CONFIRMED; 227 mStatus = CONFIRMED;
170 else if (ss == "DECLINED") 228 else if (ss == "DECLINED")
171 mStatus = DECLINED; 229 mStatus = DECLINED;
172 else if (ss == "COMPLETED") 230 else if (ss == "COMPLETED")
173 mStatus = COMPLETED; 231 mStatus = COMPLETED;
174 else if (ss == "DELEGATED") 232 else if (ss == "DELEGATED")
175 mStatus = DELEGATED; 233 mStatus = DELEGATED;
176 234
177 updated(); 235 updated();
178} 236}
179 237
180void Todo::setStatus(int status) 238void Todo::setStatus(int status)
181{ 239{
182 if (mReadOnly) return; 240 if (mReadOnly) return;
183 mStatus = status; 241 mStatus = status;
184 updated(); 242 updated();
185} 243}
186 244
187int Todo::status() const 245int Todo::status() const
diff --git a/libkcal/todo.h b/libkcal/todo.h
index 9aa92f8..0f22c59 100644
--- a/libkcal/todo.h
+++ b/libkcal/todo.h
@@ -1,121 +1,122 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20#ifndef TODO_H 20#ifndef TODO_H
21#define TODO_H 21#define TODO_H
22// 22//
23// Todo component, representing a VTODO object 23// Todo component, representing a VTODO object
24// 24//
25 25
26#include "incidence.h" 26#include "incidence.h"
27 27
28namespace KCal { 28namespace KCal {
29 29
30/** 30/**
31 This class provides a Todo in the sense of RFC2445. 31 This class provides a Todo in the sense of RFC2445.
32*/ 32*/
33class Todo : public Incidence 33class Todo : public Incidence
34{ 34{
35 public: 35 public:
36 Todo(); 36 Todo();
37 Todo(const Todo &); 37 Todo(const Todo &);
38 ~Todo(); 38 ~Todo();
39 typedef ListBase<Todo> List; 39 typedef ListBase<Todo> List;
40 QCString type() const { return "Todo"; } 40 QCString type() const { return "Todo"; }
41 41
42 /** Return an exact copy of this todo. */ 42 /** Return an exact copy of this todo. */
43 Incidence *clone(); 43 Incidence *clone();
44 QDateTime getNextAlarmDateTime( bool * ok, int * offset ) const; 44 QDateTime getNextAlarmDateTime( bool * ok, int * offset ) const;
45 45
46 /** for setting the todo's due date/time with a QDateTime. */ 46 /** for setting the todo's due date/time with a QDateTime. */
47 void setDtDue(const QDateTime &dtDue); 47 void setDtDue(const QDateTime &dtDue);
48 /** returns an event's Due date/time as a QDateTime. */ 48 /** returns an event's Due date/time as a QDateTime. */
49 QDateTime dtDue() const; 49 QDateTime dtDue() const;
50 /** returns an event's due time as a string formatted according to the 50 /** returns an event's due time as a string formatted according to the
51 users locale settings */ 51 users locale settings */
52 QString dtDueTimeStr() const; 52 QString dtDueTimeStr() const;
53 /** returns an event's due date as a string formatted according to the 53 /** returns an event's due date as a string formatted according to the
54 users locale settings */ 54 users locale settings */
55 QString dtDueDateStr(bool shortfmt=true) const; 55 QString dtDueDateStr(bool shortfmt=true) const;
56 /** returns an event's due date and time as a string formatted according 56 /** returns an event's due date and time as a string formatted according
57 to the users locale settings */ 57 to the users locale settings */
58 QString dtDueStr(bool shortfmt=true) const; 58 QString dtDueStr(bool shortfmt=true) const;
59 59
60 /** returns TRUE or FALSE depending on whether the todo has a due date */ 60 /** returns TRUE or FALSE depending on whether the todo has a due date */
61 bool hasDueDate() const; 61 bool hasDueDate() const;
62 /** sets the event's hasDueDate value. */ 62 /** sets the event's hasDueDate value. */
63 void setHasDueDate(bool f); 63 void setHasDueDate(bool f);
64 64
65 65
66 /** sets the event's status to the string specified. The string 66 /** sets the event's status to the string specified. The string
67 * must be a recognized value for the status field, i.e. a string 67 * must be a recognized value for the status field, i.e. a string
68 * equivalent of the possible status enumerations previously described. */ 68 * equivalent of the possible status enumerations previously described. */
69// void setStatus(const QString &statStr); 69// void setStatus(const QString &statStr);
70 /** sets the event's status to the value specified. See the enumeration 70 /** sets the event's status to the value specified. See the enumeration
71 * above for possible values. */ 71 * above for possible values. */
72// void setStatus(int); 72// void setStatus(int);
73 /** return the event's status. */ 73 /** return the event's status. */
74// int status() const; 74// int status() const;
75 /** return the event's status in string format. */ 75 /** return the event's status in string format. */
76// QString statusStr() const; 76// QString statusStr() const;
77 77
78 /** return, if this todo is completed */ 78 /** return, if this todo is completed */
79 bool isCompleted() const; 79 bool isCompleted() const;
80 /** set completed state of this todo */ 80 /** set completed state of this todo */
81 void setCompleted(bool); 81 void setCompleted(bool);
82 82
83 /** 83 /**
84 Return how many percent of the task are completed. Returns a value 84 Return how many percent of the task are completed. Returns a value
85 between 0 and 100. 85 between 0 and 100.
86 */ 86 */
87 int percentComplete() const; 87 int percentComplete() const;
88 /** 88 /**
89 Set how many percent of the task are completed. Valid values are in the 89 Set how many percent of the task are completed. Valid values are in the
90 range from 0 to 100. 90 range from 0 to 100.
91 */ 91 */
92 void setPercentComplete(int); 92 void setPercentComplete(int);
93 93
94 /** return date and time when todo was completed */ 94 /** return date and time when todo was completed */
95 QDateTime completed() const; 95 QDateTime completed() const;
96 QString completedStr() const; 96 QString completedStr() const;
97 /** set date and time of completion */ 97 /** set date and time of completion */
98 void setCompleted(const QDateTime &completed); 98 void setCompleted(const QDateTime &completed);
99 99
100 /** Return true, if todo has a date associated with completion */ 100 /** Return true, if todo has a date associated with completion */
101 bool hasCompletedDate() const; 101 bool hasCompletedDate() const;
102 bool contains ( Todo*);
102 103
103 private: 104 private:
104 bool accept(Visitor &v) { return v.visit(this); } 105 bool accept(Visitor &v) { return v.visit(this); }
105 106
106 QDateTime mDtDue; // due date of todo 107 QDateTime mDtDue; // due date of todo
107 108
108 bool mHasDueDate; // if todo has associated due date 109 bool mHasDueDate; // if todo has associated due date
109 110
110// int mStatus; // confirmed/delegated/tentative/etc 111// int mStatus; // confirmed/delegated/tentative/etc
111 112
112 QDateTime mCompleted; 113 QDateTime mCompleted;
113 bool mHasCompletedDate; 114 bool mHasCompletedDate;
114 115
115 int mPercentComplete; 116 int mPercentComplete;
116}; 117};
117 118
118 bool operator==( const Todo&, const Todo& ); 119 bool operator==( const Todo&, const Todo& );
119} 120}
120 121
121#endif 122#endif
diff --git a/libkcal/vcalformat.cpp b/libkcal/vcalformat.cpp
index a6ae1bc..df93209 100644
--- a/libkcal/vcalformat.cpp
+++ b/libkcal/vcalformat.cpp
@@ -1,221 +1,223 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 1998 Preston Brwon 3 Copyright (c) 1998 Preston Brwon
4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5 5
6 This library is free software; you can redistribute it and/or 6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public 7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either 8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version. 9 version 2 of the License, or (at your option) any later version.
10 10
11 This library is distributed in the hope that it will be useful, 11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details. 14 Library General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public License 16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to 17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. 19 Boston, MA 02111-1307, USA.
20*/ 20*/
21 21
22#include <qapplication.h> 22#include <qapplication.h>
23#include <qdatetime.h> 23#include <qdatetime.h>
24#include <qstring.h> 24#include <qstring.h>
25#include <qptrlist.h> 25#include <qptrlist.h>
26#include <qregexp.h> 26#include <qregexp.h>
27#include <qclipboard.h> 27#include <qclipboard.h>
28#include <qdialog.h> 28#include <qdialog.h>
29#include <qfile.h> 29#include <qfile.h>
30 30
31#include <kdebug.h> 31#include <kdebug.h>
32#include <kglobal.h> 32#include <kglobal.h>
33#include <kmessagebox.h> 33#include <kmessagebox.h>
34#include <kiconloader.h> 34#include <kiconloader.h>
35#include <klocale.h> 35#include <klocale.h>
36 36
37#include "vcc.h" 37#include "vcc.h"
38#include "vobject.h" 38#include "vobject.h"
39 39
40#include "vcaldrag.h" 40#include "vcaldrag.h"
41#include "calendar.h" 41#include "calendar.h"
42 42
43#include "vcalformat.h" 43#include "vcalformat.h"
44 44
45using namespace KCal; 45using namespace KCal;
46 46
47VCalFormat::VCalFormat() 47VCalFormat::VCalFormat()
48{ 48{
49 mCalendar = 0; 49 mCalendar = 0;
50 useLocalTime = false; 50 useLocalTime = false;
51} 51}
52 52
53VCalFormat::~VCalFormat() 53VCalFormat::~VCalFormat()
54{ 54{
55} 55}
56 56
57void VCalFormat::setLocalTime ( bool b ) 57void VCalFormat::setLocalTime ( bool b )
58{ 58{
59 useLocalTime = b; 59 useLocalTime = b;
60} 60}
61bool VCalFormat::load(Calendar *calendar, const QString &fileName) 61bool VCalFormat::load(Calendar *calendar, const QString &fileName)
62{ 62{
63 mCalendar = calendar; 63 mCalendar = calendar;
64 clearException(); 64 clearException();
65 useLocalTime = mCalendar->isLocalTime(); 65 if ( ! useLocalTime )
66 useLocalTime = mCalendar->isLocalTime();
66 VObject *vcal = 0; 67 VObject *vcal = 0;
67 68
68 // this is not necessarily only 1 vcal. Could be many vcals, or include 69 // this is not necessarily only 1 vcal. Could be many vcals, or include
69 // a vcard... 70 // a vcard...
70 vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data())); 71 vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data()));
71 72
72 if (!vcal) { 73 if (!vcal) {
73 setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); 74 setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
74 return FALSE; 75 return FALSE;
75 } 76 }
76 77
77 // any other top-level calendar stuff should be added/initialized here 78 // any other top-level calendar stuff should be added/initialized here
78 79
79 // put all vobjects into their proper places 80 // put all vobjects into their proper places
80 populate(vcal); 81 populate(vcal);
81 82
82 // clean up from vcal API stuff 83 // clean up from vcal API stuff
83 cleanVObjects(vcal); 84 cleanVObjects(vcal);
84 cleanStrTbl(); 85 cleanStrTbl();
85 86
86 return true; 87 return true;
87} 88}
88 89
89 90
90bool VCalFormat::save(Calendar *calendar, const QString &fileName) 91bool VCalFormat::save(Calendar *calendar, const QString &fileName)
91{ 92{
92 mCalendar = calendar; 93 mCalendar = calendar;
93 useLocalTime = mCalendar->isLocalTime(); 94 if ( ! useLocalTime )
95 useLocalTime = mCalendar->isLocalTime();
94 96
95 QString tmpStr; 97 QString tmpStr;
96 VObject *vcal, *vo; 98 VObject *vcal, *vo;
97 99
98 100
99 vcal = newVObject(VCCalProp); 101 vcal = newVObject(VCCalProp);
100 102
101 // addPropValue(vcal,VCLocationProp, "0.0"); 103 // addPropValue(vcal,VCLocationProp, "0.0");
102 addPropValue(vcal,VCProdIdProp, productId()); 104 addPropValue(vcal,VCProdIdProp, productId());
103 tmpStr = mCalendar->getTimeZoneStr(); 105 tmpStr = mCalendar->getTimeZoneStr();
104 //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() ); 106 //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() );
105 addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); 107 addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit());
106 addPropValue(vcal,VCVersionProp, _VCAL_VERSION); 108 addPropValue(vcal,VCVersionProp, _VCAL_VERSION);
107 109
108 // TODO STUFF 110 // TODO STUFF
109 QPtrList<Todo> todoList = mCalendar->rawTodos(); 111 QPtrList<Todo> todoList = mCalendar->rawTodos();
110 QPtrListIterator<Todo> qlt(todoList); 112 QPtrListIterator<Todo> qlt(todoList);
111 for (; qlt.current(); ++qlt) { 113 for (; qlt.current(); ++qlt) {
112 vo = eventToVTodo(qlt.current()); 114 vo = eventToVTodo(qlt.current());
113 addVObjectProp(vcal, vo); 115 addVObjectProp(vcal, vo);
114 } 116 }
115 117
116 // EVENT STUFF 118 // EVENT STUFF
117 QPtrList<Event> events = mCalendar->rawEvents(); 119 QPtrList<Event> events = mCalendar->rawEvents();
118 Event *ev; 120 Event *ev;
119 for(ev=events.first();ev;ev=events.next()) { 121 for(ev=events.first();ev;ev=events.next()) {
120 vo = eventToVEvent(ev); 122 vo = eventToVEvent(ev);
121 addVObjectProp(vcal, vo); 123 addVObjectProp(vcal, vo);
122 } 124 }
123 125
124 writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal); 126 writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal);
125 cleanVObjects(vcal); 127 cleanVObjects(vcal);
126 cleanStrTbl(); 128 cleanStrTbl();
127 129
128 if (QFile::exists(fileName)) { 130 if (QFile::exists(fileName)) {
129 return true; 131 return true;
130 } else { 132 } else {
131 return false; // error 133 return false; // error
132 } 134 }
133} 135}
134 136
135bool VCalFormat::fromString( Calendar *calendar, const QString &text ) 137bool VCalFormat::fromString( Calendar *calendar, const QString &text )
136{ 138{
137 // TODO: Factor out VCalFormat::fromString() 139 // TODO: Factor out VCalFormat::fromString()
138 140
139 QCString data = text.utf8(); 141 QCString data = text.utf8();
140 142
141 if ( !data.size() ) return false; 143 if ( !data.size() ) return false;
142 144
143 VObject *vcal = Parse_MIME( data.data(), data.size()); 145 VObject *vcal = Parse_MIME( data.data(), data.size());
144 if ( !vcal ) return false; 146 if ( !vcal ) return false;
145 147
146 VObjectIterator i; 148 VObjectIterator i;
147 VObject *curvo; 149 VObject *curvo;
148 initPropIterator( &i, vcal ); 150 initPropIterator( &i, vcal );
149 151
150 // we only take the first object. TODO: parse all incidences. 152 // we only take the first object. TODO: parse all incidences.
151 do { 153 do {
152 curvo = nextVObject( &i ); 154 curvo = nextVObject( &i );
153 } while ( strcmp( vObjectName( curvo ), VCEventProp ) && 155 } while ( strcmp( vObjectName( curvo ), VCEventProp ) &&
154 strcmp( vObjectName( curvo ), VCTodoProp ) ); 156 strcmp( vObjectName( curvo ), VCTodoProp ) );
155 157
156 if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) { 158 if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) {
157 Event *event = VEventToEvent( curvo ); 159 Event *event = VEventToEvent( curvo );
158 calendar->addEvent( event ); 160 calendar->addEvent( event );
159 } else { 161 } else {
160 qDebug("VCalFormat::fromString(): Unknown object type. "); 162 qDebug("VCalFormat::fromString(): Unknown object type. ");
161 deleteVObject( vcal ); 163 deleteVObject( vcal );
162 return false; 164 return false;
163 } 165 }
164 166
165 deleteVObject( vcal ); 167 deleteVObject( vcal );
166 168
167 return true; 169 return true;
168} 170}
169 171
170QString VCalFormat::eventToString( Event * event, Calendar *calendar, bool useLocal) 172QString VCalFormat::eventToString( Event * event, Calendar *calendar, bool useLocal)
171{ 173{
172 174
173 if ( !event ) return QString::null; 175 if ( !event ) return QString::null;
174 bool useL = useLocalTime; 176 bool useL = useLocalTime;
175 useLocalTime = useLocal; 177 useLocalTime = useLocal;
176 mCalendar = calendar; 178 mCalendar = calendar;
177 VObject *vevent = eventToVEvent( event ); 179 VObject *vevent = eventToVEvent( event );
178 char *buf = writeMemVObject( 0, 0, vevent ); 180 char *buf = writeMemVObject( 0, 0, vevent );
179 QString result( buf ); 181 QString result( buf );
180 cleanVObject( vevent ); 182 cleanVObject( vevent );
181 useLocalTime = useL; 183 useLocalTime = useL;
182 return result; 184 return result;
183} 185}
184QString VCalFormat::todoToString( Todo * todo, Calendar *calendar, bool useLocal ) 186QString VCalFormat::todoToString( Todo * todo, Calendar *calendar, bool useLocal )
185{ 187{
186 188
187 if ( !todo ) return QString::null; 189 if ( !todo ) return QString::null;
188 bool useL = useLocalTime; 190 bool useL = useLocalTime;
189 useLocalTime = useLocal; 191 useLocalTime = useLocal;
190 mCalendar = calendar; 192 mCalendar = calendar;
191 VObject *vevent = eventToVTodo( todo ); 193 VObject *vevent = eventToVTodo( todo );
192 char *buf = writeMemVObject( 0, 0, vevent ); 194 char *buf = writeMemVObject( 0, 0, vevent );
193 QString result( buf ); 195 QString result( buf );
194 cleanVObject( vevent ); 196 cleanVObject( vevent );
195 useLocalTime = useL; 197 useLocalTime = useL;
196 return result; 198 return result;
197} 199}
198 200
199QString VCalFormat::toString( Calendar *calendar ) 201QString VCalFormat::toString( Calendar *calendar )
200{ 202{
201 // TODO: Factor out VCalFormat::asString() 203 // TODO: Factor out VCalFormat::asString()
202 204
203 VObject *vcal = newVObject(VCCalProp); 205 VObject *vcal = newVObject(VCCalProp);
204 206
205 addPropValue( vcal, VCProdIdProp, CalFormat::productId() ); 207 addPropValue( vcal, VCProdIdProp, CalFormat::productId() );
206 QString tmpStr = mCalendar->getTimeZoneStr(); 208 QString tmpStr = mCalendar->getTimeZoneStr();
207 addPropValue( vcal, VCTimeZoneProp, tmpStr.local8Bit() ); 209 addPropValue( vcal, VCTimeZoneProp, tmpStr.local8Bit() );
208 addPropValue( vcal, VCVersionProp, _VCAL_VERSION ); 210 addPropValue( vcal, VCVersionProp, _VCAL_VERSION );
209 211
210 // TODO: Use all data. 212 // TODO: Use all data.
211 QPtrList<Event> events = calendar->events(); 213 QPtrList<Event> events = calendar->events();
212 Event *event = events.first(); 214 Event *event = events.first();
213 if ( !event ) return QString::null; 215 if ( !event ) return QString::null;
214 216
215 VObject *vevent = eventToVEvent( event ); 217 VObject *vevent = eventToVEvent( event );
216 218
217 addVObjectProp( vcal, vevent ); 219 addVObjectProp( vcal, vevent );
218 220
219 char *buf = writeMemVObject( 0, 0, vcal ); 221 char *buf = writeMemVObject( 0, 0, vcal );
220 222
221 QString result( buf ); 223 QString result( buf );
@@ -1047,322 +1049,326 @@ Event* VCalFormat::VEventToEvent(VObject *vevent)
1047 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1049 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1048 if (rDuration == 0) // VEvents set this to 0 forever, we use -1 1050 if (rDuration == 0) // VEvents set this to 0 forever, we use -1
1049 anEvent->recurrence()->setDaily(rFreq, -1); 1051 anEvent->recurrence()->setDaily(rFreq, -1);
1050 else 1052 else
1051 anEvent->recurrence()->setDaily(rFreq, rDuration); 1053 anEvent->recurrence()->setDaily(rFreq, rDuration);
1052 } 1054 }
1053 } 1055 }
1054 /********************************* WEEKLY ******************************/ 1056 /********************************* WEEKLY ******************************/
1055 else if (tmpStr.left(1) == "W") { 1057 else if (tmpStr.left(1) == "W") {
1056 int index = tmpStr.find(' '); 1058 int index = tmpStr.find(' ');
1057 int last = tmpStr.findRev(' ') + 1; 1059 int last = tmpStr.findRev(' ') + 1;
1058 int rFreq = tmpStr.mid(1, (index-1)).toInt(); 1060 int rFreq = tmpStr.mid(1, (index-1)).toInt();
1059 index += 1; // advance to beginning of stuff after freq 1061 index += 1; // advance to beginning of stuff after freq
1060 QBitArray qba(7); 1062 QBitArray qba(7);
1061 QString dayStr; 1063 QString dayStr;
1062 if( index == last ) { 1064 if( index == last ) {
1063 // e.g. W1 #0 1065 // e.g. W1 #0
1064 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); 1066 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
1065 } 1067 }
1066 else { 1068 else {
1067 // e.g. W1 SU #0 1069 // e.g. W1 SU #0
1068 while (index < last) { 1070 while (index < last) {
1069 dayStr = tmpStr.mid(index, 3); 1071 dayStr = tmpStr.mid(index, 3);
1070 int dayNum = numFromDay(dayStr); 1072 int dayNum = numFromDay(dayStr);
1071 qba.setBit(dayNum); 1073 qba.setBit(dayNum);
1072 index += 3; // advance to next day, or possibly "#" 1074 index += 3; // advance to next day, or possibly "#"
1073 } 1075 }
1074 } 1076 }
1075 index = last; if (tmpStr.mid(index,1) == "#") index++; 1077 index = last; if (tmpStr.mid(index,1) == "#") index++;
1076 if (tmpStr.find('T', index) != -1) { 1078 if (tmpStr.find('T', index) != -1) {
1077 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1079 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1078 anEvent->recurrence()->setWeekly(rFreq, qba, rEndDate); 1080 anEvent->recurrence()->setWeekly(rFreq, qba, rEndDate);
1079 } else { 1081 } else {
1080 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1082 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1081 if (rDuration == 0) 1083 if (rDuration == 0)
1082 anEvent->recurrence()->setWeekly(rFreq, qba, -1); 1084 anEvent->recurrence()->setWeekly(rFreq, qba, -1);
1083 else 1085 else
1084 anEvent->recurrence()->setWeekly(rFreq, qba, rDuration); 1086 anEvent->recurrence()->setWeekly(rFreq, qba, rDuration);
1085 } 1087 }
1086 } 1088 }
1087 /**************************** MONTHLY-BY-POS ***************************/ 1089 /**************************** MONTHLY-BY-POS ***************************/
1088 else if (tmpStr.left(2) == "MP") { 1090 else if (tmpStr.left(2) == "MP") {
1089 int index = tmpStr.find(' '); 1091 int index = tmpStr.find(' ');
1090 int last = tmpStr.findRev(' ') + 1; 1092 int last = tmpStr.findRev(' ') + 1;
1091 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1093 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1092 index += 1; // advance to beginning of stuff after freq 1094 index += 1; // advance to beginning of stuff after freq
1093 QBitArray qba(7); 1095 QBitArray qba(7);
1094 short tmpPos; 1096 short tmpPos;
1095 if( index == last ) { 1097 if( index == last ) {
1096 // e.g. MP1 #0 1098 // e.g. MP1 #0
1097 tmpPos = anEvent->dtStart().date().day()/7 + 1; 1099 tmpPos = anEvent->dtStart().date().day()/7 + 1;
1098 if( tmpPos == 5 ) 1100 if( tmpPos == 5 )
1099 tmpPos = -1; 1101 tmpPos = -1;
1100 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); 1102 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
1101 anEvent->recurrence()->addMonthlyPos(tmpPos, qba); 1103 anEvent->recurrence()->addMonthlyPos(tmpPos, qba);
1102 } 1104 }
1103 else { 1105 else {
1104 // e.g. MP1 1+ SU #0 1106 // e.g. MP1 1+ SU #0
1105 while (index < last) { 1107 while (index < last) {
1106 tmpPos = tmpStr.mid(index,1).toShort(); 1108 tmpPos = tmpStr.mid(index,1).toShort();
1107 index += 1; 1109 index += 1;
1108 if (tmpStr.mid(index,1) == "-") 1110 if (tmpStr.mid(index,1) == "-")
1109 // convert tmpPos to negative 1111 // convert tmpPos to negative
1110 tmpPos = 0 - tmpPos; 1112 tmpPos = 0 - tmpPos;
1111 index += 2; // advance to day(s) 1113 index += 2; // advance to day(s)
1112 while (numFromDay(tmpStr.mid(index,3)) >= 0) { 1114 while (numFromDay(tmpStr.mid(index,3)) >= 0) {
1113 int dayNum = numFromDay(tmpStr.mid(index,3)); 1115 int dayNum = numFromDay(tmpStr.mid(index,3));
1114 qba.setBit(dayNum); 1116 qba.setBit(dayNum);
1115 index += 3; // advance to next day, or possibly pos or "#" 1117 index += 3; // advance to next day, or possibly pos or "#"
1116 } 1118 }
1117 anEvent->recurrence()->addMonthlyPos(tmpPos, qba); 1119 anEvent->recurrence()->addMonthlyPos(tmpPos, qba);
1118 qba.detach(); 1120 qba.detach();
1119 qba.fill(FALSE); // clear out 1121 qba.fill(FALSE); // clear out
1120 } // while != "#" 1122 } // while != "#"
1121 } 1123 }
1122 index = last; if (tmpStr.mid(index,1) == "#") index++; 1124 index = last; if (tmpStr.mid(index,1) == "#") index++;
1123 if (tmpStr.find('T', index) != -1) { 1125 if (tmpStr.find('T', index) != -1) {
1124 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length() - 1126 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length() -
1125 index))).date(); 1127 index))).date();
1126 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rEndDate); 1128 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rEndDate);
1127 } else { 1129 } else {
1128 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1130 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1129 if (rDuration == 0) 1131 if (rDuration == 0)
1130 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, -1); 1132 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, -1);
1131 else 1133 else
1132 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rDuration); 1134 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rDuration);
1133 } 1135 }
1134 } 1136 }
1135 1137
1136 /**************************** MONTHLY-BY-DAY ***************************/ 1138 /**************************** MONTHLY-BY-DAY ***************************/
1137 else if (tmpStr.left(2) == "MD") { 1139 else if (tmpStr.left(2) == "MD") {
1138 int index = tmpStr.find(' '); 1140 int index = tmpStr.find(' ');
1139 int last = tmpStr.findRev(' ') + 1; 1141 int last = tmpStr.findRev(' ') + 1;
1140 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1142 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1141 index += 1; 1143 index += 1;
1142 short tmpDay; 1144 short tmpDay;
1143 if( index == last ) { 1145 if( index == last ) {
1144 // e.g. MD1 #0 1146 // e.g. MD1 #0
1145 tmpDay = anEvent->dtStart().date().day(); 1147 tmpDay = anEvent->dtStart().date().day();
1146 anEvent->recurrence()->addMonthlyDay(tmpDay); 1148 anEvent->recurrence()->addMonthlyDay(tmpDay);
1147 } 1149 }
1148 else { 1150 else {
1149 // e.g. MD1 3 #0 1151 // e.g. MD1 3 #0
1150 while (index < last) { 1152 while (index < last) {
1151 int index2 = tmpStr.find(' ', index); 1153 int index2 = tmpStr.find(' ', index);
1152 tmpDay = tmpStr.mid(index, (index2-index)).toShort(); 1154 tmpDay = tmpStr.mid(index, (index2-index)).toShort();
1153 index = index2-1; 1155 index = index2-1;
1154 if (tmpStr.mid(index, 1) == "-") 1156 if (tmpStr.mid(index, 1) == "-")
1155 tmpDay = 0 - tmpDay; 1157 tmpDay = 0 - tmpDay;
1156 index += 2; // advance the index; 1158 index += 2; // advance the index;
1157 anEvent->recurrence()->addMonthlyDay(tmpDay); 1159 anEvent->recurrence()->addMonthlyDay(tmpDay);
1158 } // while != # 1160 } // while != #
1159 } 1161 }
1160 index = last; if (tmpStr.mid(index,1) == "#") index++; 1162 index = last; if (tmpStr.mid(index,1) == "#") index++;
1161 if (tmpStr.find('T', index) != -1) { 1163 if (tmpStr.find('T', index) != -1) {
1162 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1164 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1163 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate); 1165 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate);
1164 } else { 1166 } else {
1165 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1167 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1166 if (rDuration == 0) 1168 if (rDuration == 0)
1167 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1); 1169 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1);
1168 else 1170 else
1169 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration); 1171 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration);
1170 } 1172 }
1171 } 1173 }
1172 1174
1173 /*********************** YEARLY-BY-MONTH *******************************/ 1175 /*********************** YEARLY-BY-MONTH *******************************/
1174 else if (tmpStr.left(2) == "YM") { 1176 else if (tmpStr.left(2) == "YM") {
1175 int index = tmpStr.find(' '); 1177 // we have to set this such that recurrence accepts addYearlyNum(tmpDay);
1176 int last = tmpStr.findRev(' ') + 1; 1178 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, 1, -1);
1177 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1179 int index = tmpStr.find(' ');
1178 index += 1; 1180 int last = tmpStr.findRev(' ') + 1;
1179 short tmpMonth; 1181 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1180 if( index == last ) { 1182 index += 1;
1181 // e.g. YM1 #0 1183 short tmpMonth;
1182 tmpMonth = anEvent->dtStart().date().month(); 1184 if( index == last ) {
1183 anEvent->recurrence()->addYearlyNum(tmpMonth); 1185 // e.g. YM1 #0
1184 } 1186 tmpMonth = anEvent->dtStart().date().month();
1185 else { 1187 anEvent->recurrence()->addYearlyNum(tmpMonth);
1186 // e.g. YM1 3 #0 1188 }
1187 while (index < last) { 1189 else {
1188 int index2 = tmpStr.find(' ', index); 1190 // e.g. YM1 3 #0
1189 tmpMonth = tmpStr.mid(index, (index2-index)).toShort(); 1191 while (index < last) {
1190 index = index2+1; 1192 int index2 = tmpStr.find(' ', index);
1191 anEvent->recurrence()->addYearlyNum(tmpMonth); 1193 tmpMonth = tmpStr.mid(index, (index2-index)).toShort();
1192 } // while != # 1194 index = index2+1;
1193 } 1195 anEvent->recurrence()->addYearlyNum(tmpMonth);
1194 index = last; if (tmpStr.mid(index,1) == "#") index++; 1196 } // while != #
1195 if (tmpStr.find('T', index) != -1) { 1197 }
1196 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1198 index = last; if (tmpStr.mid(index,1) == "#") index++;
1197 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate); 1199 if (tmpStr.find('T', index) != -1) {
1198 } else { 1200 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1199 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1201 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate);
1200 if (rDuration == 0) 1202 } else {
1201 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1); 1203 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1202 else 1204 if (rDuration == 0)
1203 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration); 1205 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1);
1204 } 1206 else
1207 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration);
1208 }
1205 } 1209 }
1206 1210
1207 /*********************** YEARLY-BY-DAY *********************************/ 1211 /*********************** YEARLY-BY-DAY *********************************/
1208 else if (tmpStr.left(2) == "YD") { 1212 else if (tmpStr.left(2) == "YD") {
1209 int index = tmpStr.find(' '); 1213 // we have to set this such that recurrence accepts addYearlyNum(tmpDay);
1210 int last = tmpStr.findRev(' ') + 1; 1214 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, 1, -1);
1211 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1215 int index = tmpStr.find(' ');
1212 index += 1; 1216 int last = tmpStr.findRev(' ') + 1;
1213 short tmpDay; 1217 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1214 if( index == last ) { 1218 index += 1;
1215 // e.g. YD1 #0 1219 short tmpDay;
1216 tmpDay = anEvent->dtStart().date().dayOfYear(); 1220 if( index == last ) {
1217 anEvent->recurrence()->addYearlyNum(tmpDay); 1221 // e.g. YD1 #0
1218 } 1222 tmpDay = anEvent->dtStart().date().dayOfYear();
1219 else { 1223 anEvent->recurrence()->addYearlyNum(tmpDay);
1220 // e.g. YD1 123 #0 1224 }
1221 while (index < last) { 1225 else {
1222 int index2 = tmpStr.find(' ', index); 1226 // e.g. YD1 123 #0
1223 tmpDay = tmpStr.mid(index, (index2-index)).toShort(); 1227 while (index < last) {
1224 index = index2+1; 1228 int index2 = tmpStr.find(' ', index);
1225 anEvent->recurrence()->addYearlyNum(tmpDay); 1229 tmpDay = tmpStr.mid(index, (index2-index)).toShort();
1226 } // while != # 1230 index = index2+1;
1227 } 1231 anEvent->recurrence()->addYearlyNum(tmpDay);
1228 index = last; if (tmpStr.mid(index,1) == "#") index++; 1232 } // while != #
1229 if (tmpStr.find('T', index) != -1) { 1233 }
1230 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1234 index = last; if (tmpStr.mid(index,1) == "#") index++;
1231 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate); 1235 if (tmpStr.find('T', index) != -1) {
1232 } else { 1236 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1233 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1237 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate);
1234 if (rDuration == 0) 1238 } else {
1235 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1); 1239 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1236 else 1240 if (rDuration == 0)
1237 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration); 1241 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1);
1238 } 1242 else
1243 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration);
1244 }
1239 } else { 1245 } else {
1240 kdDebug(5800) << "we don't understand this type of recurrence!" << endl; 1246 kdDebug(5800) << "we don't understand this type of recurrence!" << endl;
1241 } // if 1247 } // if
1242 } // repeats 1248 } // repeats
1243 1249
1244 1250
1245 // recurrence exceptions 1251 // recurrence exceptions
1246 if ((vo = isAPropertyOf(vevent, VCExpDateProp)) != 0) { 1252 if ((vo = isAPropertyOf(vevent, VCExpDateProp)) != 0) {
1247 s = fakeCString(vObjectUStringZValue(vo)); 1253 s = fakeCString(vObjectUStringZValue(vo));
1248 QStringList exDates = QStringList::split(",",s); 1254 QStringList exDates = QStringList::split(",",s);
1249 QStringList::ConstIterator it; 1255 QStringList::ConstIterator it;
1250 for(it = exDates.begin(); it != exDates.end(); ++it ) { 1256 for(it = exDates.begin(); it != exDates.end(); ++it ) {
1251 anEvent->addExDate(ISOToQDate(*it)); 1257 anEvent->addExDate(ISOToQDate(*it));
1252 } 1258 }
1253 deleteStr(s); 1259 deleteStr(s);
1254 } 1260 }
1255 1261
1256 // summary 1262 // summary
1257 if ((vo = isAPropertyOf(vevent, VCSummaryProp))) { 1263 if ((vo = isAPropertyOf(vevent, VCSummaryProp))) {
1258 s = fakeCString(vObjectUStringZValue(vo)); 1264 s = fakeCString(vObjectUStringZValue(vo));
1259 anEvent->setSummary(QString::fromLocal8Bit(s)); 1265 anEvent->setSummary(QString::fromLocal8Bit(s));
1260 deleteStr(s); 1266 deleteStr(s);
1261 } 1267 }
1262 if ((vo = isAPropertyOf(vevent, VCLocationProp))) { 1268 if ((vo = isAPropertyOf(vevent, VCLocationProp))) {
1263 s = fakeCString(vObjectUStringZValue(vo)); 1269 s = fakeCString(vObjectUStringZValue(vo));
1264 anEvent->setLocation(QString::fromLocal8Bit(s)); 1270 anEvent->setLocation(QString::fromLocal8Bit(s));
1265 deleteStr(s); 1271 deleteStr(s);
1266 } 1272 }
1267 1273
1268 // description 1274 // description
1269 if ((vo = isAPropertyOf(vevent, VCDescriptionProp)) != 0) { 1275 if ((vo = isAPropertyOf(vevent, VCDescriptionProp)) != 0) {
1270 s = fakeCString(vObjectUStringZValue(vo)); 1276 s = fakeCString(vObjectUStringZValue(vo));
1271 if (!anEvent->description().isEmpty()) { 1277 if (!anEvent->description().isEmpty()) {
1272 anEvent->setDescription(anEvent->description() + "\n" + 1278 anEvent->setDescription(anEvent->description() + "\n" +
1273 QString::fromLocal8Bit(s)); 1279 QString::fromLocal8Bit(s));
1274 } else { 1280 } else {
1275 anEvent->setDescription(QString::fromLocal8Bit(s)); 1281 anEvent->setDescription(QString::fromLocal8Bit(s));
1276 } 1282 }
1277 deleteStr(s); 1283 deleteStr(s);
1278 } 1284 }
1279 1285
1280 // some stupid vCal exporters ignore the standard and use Description 1286 // some stupid vCal exporters ignore the standard and use Description
1281 // instead of Summary for the default field. Correct for this. 1287 // instead of Summary for the default field. Correct for this.
1282 if (anEvent->summary().isEmpty() && 1288 if (anEvent->summary().isEmpty() &&
1283 !(anEvent->description().isEmpty())) { 1289 !(anEvent->description().isEmpty())) {
1284 QString tmpStr = anEvent->description().simplifyWhiteSpace(); 1290 QString tmpStr = anEvent->description().simplifyWhiteSpace();
1285 anEvent->setDescription(""); 1291 anEvent->setDescription("");
1286 anEvent->setSummary(tmpStr); 1292 anEvent->setSummary(tmpStr);
1287 } 1293 }
1288 1294
1289#if 0 1295#if 0
1290 // status 1296 // status
1291 if ((vo = isAPropertyOf(vevent, VCStatusProp)) != 0) { 1297 if ((vo = isAPropertyOf(vevent, VCStatusProp)) != 0) {
1292 QString tmpStr(s = fakeCString(vObjectUStringZValue(vo))); 1298 QString tmpStr(s = fakeCString(vObjectUStringZValue(vo)));
1293 deleteStr(s); 1299 deleteStr(s);
1294// TODO: Define Event status 1300// TODO: Define Event status
1295// anEvent->setStatus(tmpStr); 1301// anEvent->setStatus(tmpStr);
1296 } 1302 }
1297 else 1303 else
1298// anEvent->setStatus("NEEDS ACTION"); 1304// anEvent->setStatus("NEEDS ACTION");
1299#endif 1305#endif
1300 1306
1301 // secrecy 1307 // secrecy
1302 int secrecy = Incidence::SecrecyPublic; 1308 int secrecy = Incidence::SecrecyPublic;
1303 if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) { 1309 if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) {
1304 s = fakeCString(vObjectUStringZValue(vo)); 1310 s = fakeCString(vObjectUStringZValue(vo));
1305 if (strcmp(s,"PRIVATE") == 0) { 1311 if (strcmp(s,"PRIVATE") == 0) {
1306 secrecy = Incidence::SecrecyPrivate; 1312 secrecy = Incidence::SecrecyPrivate;
1307 } else if (strcmp(s,"CONFIDENTIAL") == 0) { 1313 } else if (strcmp(s,"CONFIDENTIAL") == 0) {
1308 secrecy = Incidence::SecrecyConfidential; 1314 secrecy = Incidence::SecrecyConfidential;
1309 } 1315 }
1310 deleteStr(s); 1316 deleteStr(s);
1311 } 1317 }
1312 anEvent->setSecrecy(secrecy); 1318 anEvent->setSecrecy(secrecy);
1313 1319
1314 // categories 1320 // categories
1315 QStringList tmpStrList; 1321 QStringList tmpStrList;
1316 int index1 = 0; 1322 int index1 = 0;
1317 int index2 = 0; 1323 int index2 = 0;
1318 if ((vo = isAPropertyOf(vevent, VCCategoriesProp)) != 0) { 1324 if ((vo = isAPropertyOf(vevent, VCCategoriesProp)) != 0) {
1319 s = fakeCString(vObjectUStringZValue(vo)); 1325 s = fakeCString(vObjectUStringZValue(vo));
1320 QString categories = QString::fromLocal8Bit(s); 1326 QString categories = QString::fromLocal8Bit(s);
1321 deleteStr(s); 1327 deleteStr(s);
1322 //const char* category; 1328 //const char* category;
1323 QString category; 1329 QString category;
1324 while ((index2 = categories.find(',', index1)) != -1) { 1330 while ((index2 = categories.find(',', index1)) != -1) {
1325 //category = (const char *) categories.mid(index1, (index2 - index1)); 1331 //category = (const char *) categories.mid(index1, (index2 - index1));
1326 category = categories.mid(index1, (index2 - index1)); 1332 category = categories.mid(index1, (index2 - index1));
1327 tmpStrList.append(category); 1333 tmpStrList.append(category);
1328 index1 = index2+1; 1334 index1 = index2+1;
1329 } 1335 }
1330 // get last category 1336 // get last category
1331 category = categories.mid(index1, (categories.length()-index1)); 1337 category = categories.mid(index1, (categories.length()-index1));
1332 tmpStrList.append(category); 1338 tmpStrList.append(category);
1333 anEvent->setCategories(tmpStrList); 1339 anEvent->setCategories(tmpStrList);
1334 } 1340 }
1335 1341
1336 // attachments 1342 // attachments
1337 tmpStrList.clear(); 1343 tmpStrList.clear();
1338 initPropIterator(&voi, vevent); 1344 initPropIterator(&voi, vevent);
1339 while (moreIteration(&voi)) { 1345 while (moreIteration(&voi)) {
1340 vo = nextVObject(&voi); 1346 vo = nextVObject(&voi);
1341 if (strcmp(vObjectName(vo), VCAttachProp) == 0) { 1347 if (strcmp(vObjectName(vo), VCAttachProp) == 0) {
1342 s = fakeCString(vObjectUStringZValue(vo)); 1348 s = fakeCString(vObjectUStringZValue(vo));
1343 anEvent->addAttachment(new Attachment(QString(s))); 1349 anEvent->addAttachment(new Attachment(QString(s)));
1344 deleteStr(s); 1350 deleteStr(s);
1345 } 1351 }
1346 } 1352 }
1347 1353
1348 // resources 1354 // resources
1349 if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) { 1355 if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) {
1350 QString resources = (s = fakeCString(vObjectUStringZValue(vo))); 1356 QString resources = (s = fakeCString(vObjectUStringZValue(vo)));
1351 deleteStr(s); 1357 deleteStr(s);
1352 tmpStrList.clear(); 1358 tmpStrList.clear();
1353 index1 = 0; 1359 index1 = 0;
1354 index2 = 0; 1360 index2 = 0;
1355 QString resource; 1361 QString resource;
1356 while ((index2 = resources.find(';', index1)) != -1) { 1362 while ((index2 = resources.find(';', index1)) != -1) {
1357 resource = resources.mid(index1, (index2 - index1)); 1363 resource = resources.mid(index1, (index2 - index1));
1358 tmpStrList.append(resource); 1364 tmpStrList.append(resource);
1359 index1 = index2; 1365 index1 = index2;
1360 } 1366 }
1361 anEvent->setResources(tmpStrList); 1367 anEvent->setResources(tmpStrList);
1362 } 1368 }
1363 1369
1364 /* alarm stuff */ 1370 /* alarm stuff */
1365 if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) { 1371 if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) {
1366 Alarm* alarm = anEvent->newAlarm(); 1372 Alarm* alarm = anEvent->newAlarm();
1367 VObject *a; 1373 VObject *a;
1368 if ((a = isAPropertyOf(vo, VCRunTimeProp))) { 1374 if ((a = isAPropertyOf(vo, VCRunTimeProp))) {
@@ -1411,262 +1417,263 @@ Event* VCalFormat::VEventToEvent(VObject *vevent)
1411 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 1417 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo))));
1412 deleteStr(s); 1418 deleteStr(s);
1413 } 1419 }
1414 else 1420 else
1415 anEvent->setPilotId(0); 1421 anEvent->setPilotId(0);
1416 1422
1417 if ((vo = isAPropertyOf(vevent, XPilotStatusProp))) { 1423 if ((vo = isAPropertyOf(vevent, XPilotStatusProp))) {
1418 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 1424 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo))));
1419 deleteStr(s); 1425 deleteStr(s);
1420 } 1426 }
1421 else 1427 else
1422 anEvent->setSyncStatus(Event::SYNCMOD); 1428 anEvent->setSyncStatus(Event::SYNCMOD);
1423 1429
1424 return anEvent; 1430 return anEvent;
1425} 1431}
1426 1432
1427 1433
1428QString VCalFormat::qDateToISO(const QDate &qd) 1434QString VCalFormat::qDateToISO(const QDate &qd)
1429{ 1435{
1430 QString tmpStr; 1436 QString tmpStr;
1431 1437
1432 ASSERT(qd.isValid()); 1438 ASSERT(qd.isValid());
1433 1439
1434 tmpStr.sprintf("%.2d%.2d%.2d", 1440 tmpStr.sprintf("%.2d%.2d%.2d",
1435 qd.year(), qd.month(), qd.day()); 1441 qd.year(), qd.month(), qd.day());
1436 return tmpStr; 1442 return tmpStr;
1437 1443
1438} 1444}
1439 1445
1440QString VCalFormat::qDateTimeToISO(const QDateTime &qdt, bool zulu) 1446QString VCalFormat::qDateTimeToISO(const QDateTime &qdt, bool zulu)
1441{ 1447{
1442 QString tmpStr; 1448 QString tmpStr;
1443 1449
1444 ASSERT(qdt.date().isValid()); 1450 ASSERT(qdt.date().isValid());
1445 ASSERT(qdt.time().isValid()); 1451 ASSERT(qdt.time().isValid());
1446 if (zulu && !useLocalTime ) { 1452 if (zulu && !useLocalTime ) {
1447 QDateTime tmpDT = qdt.addSecs ( -KGlobal::locale()->localTimeOffset( qdt )*60); 1453 QDateTime tmpDT = qdt.addSecs ( -KGlobal::locale()->localTimeOffset( qdt )*60);
1448 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2dZ", 1454 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2dZ",
1449 tmpDT.date().year(), tmpDT.date().month(), 1455 tmpDT.date().year(), tmpDT.date().month(),
1450 tmpDT.date().day(), tmpDT.time().hour(), 1456 tmpDT.date().day(), tmpDT.time().hour(),
1451 tmpDT.time().minute(), tmpDT.time().second()); 1457 tmpDT.time().minute(), tmpDT.time().second());
1452 } else { 1458 } else {
1453 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2d", 1459 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2d",
1454 qdt.date().year(), qdt.date().month(), 1460 qdt.date().year(), qdt.date().month(),
1455 qdt.date().day(), qdt.time().hour(), 1461 qdt.date().day(), qdt.time().hour(),
1456 qdt.time().minute(), qdt.time().second()); 1462 qdt.time().minute(), qdt.time().second());
1457 } 1463 }
1458 return tmpStr; 1464 return tmpStr;
1459} 1465}
1460 1466
1461QDateTime VCalFormat::ISOToQDateTime(const QString & dtStr) 1467QDateTime VCalFormat::ISOToQDateTime(const QString & dtStr)
1462{ 1468{
1463 QDate tmpDate; 1469 QDate tmpDate;
1464 QTime tmpTime; 1470 QTime tmpTime;
1465 QString tmpStr; 1471 QString tmpStr;
1466 int year, month, day, hour, minute, second; 1472 int year, month, day, hour, minute, second;
1467 1473
1468 tmpStr = dtStr; 1474 tmpStr = dtStr;
1469 year = tmpStr.left(4).toInt(); 1475 year = tmpStr.left(4).toInt();
1470 month = tmpStr.mid(4,2).toInt(); 1476 month = tmpStr.mid(4,2).toInt();
1471 day = tmpStr.mid(6,2).toInt(); 1477 day = tmpStr.mid(6,2).toInt();
1472 hour = tmpStr.mid(9,2).toInt(); 1478 hour = tmpStr.mid(9,2).toInt();
1473 minute = tmpStr.mid(11,2).toInt(); 1479 minute = tmpStr.mid(11,2).toInt();
1474 second = tmpStr.mid(13,2).toInt(); 1480 second = tmpStr.mid(13,2).toInt();
1475 tmpDate.setYMD(year, month, day); 1481 tmpDate.setYMD(year, month, day);
1476 tmpTime.setHMS(hour, minute, second); 1482 tmpTime.setHMS(hour, minute, second);
1477 1483
1478 ASSERT(tmpDate.isValid()); 1484 ASSERT(tmpDate.isValid());
1479 ASSERT(tmpTime.isValid()); 1485 ASSERT(tmpTime.isValid());
1480 QDateTime tmpDT(tmpDate, tmpTime); 1486 QDateTime tmpDT(tmpDate, tmpTime);
1481 // correct for GMT if string is in Zulu format 1487 // correct for GMT if string is in Zulu format
1482 if (dtStr.at(dtStr.length()-1) == 'Z') 1488 if (dtStr.at(dtStr.length()-1) == 'Z')
1483 tmpDT = tmpDT.addSecs (KGlobal::locale()->localTimeOffset( tmpDT )*60); 1489 tmpDT = tmpDT.addSecs (KGlobal::locale()->localTimeOffset( tmpDT )*60);
1484 return tmpDT; 1490 return tmpDT;
1485} 1491}
1486 1492
1487QDate VCalFormat::ISOToQDate(const QString &dateStr) 1493QDate VCalFormat::ISOToQDate(const QString &dateStr)
1488{ 1494{
1489 int year, month, day; 1495 int year, month, day;
1490 1496
1491 year = dateStr.left(4).toInt(); 1497 year = dateStr.left(4).toInt();
1492 month = dateStr.mid(4,2).toInt(); 1498 month = dateStr.mid(4,2).toInt();
1493 day = dateStr.mid(6,2).toInt(); 1499 day = dateStr.mid(6,2).toInt();
1494 1500
1495 return(QDate(year, month, day)); 1501 return(QDate(year, month, day));
1496} 1502}
1497 1503
1498// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc. 1504// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc.
1499// and break it down from it's tree-like format into the dictionary format 1505// and break it down from it's tree-like format into the dictionary format
1500// that is used internally in the VCalFormat. 1506// that is used internally in the VCalFormat.
1501void VCalFormat::populate(VObject *vcal) 1507void VCalFormat::populate(VObject *vcal)
1502{ 1508{
1503 // this function will populate the caldict dictionary and other event 1509 // this function will populate the caldict dictionary and other event
1504 // lists. It turns vevents into Events and then inserts them. 1510 // lists. It turns vevents into Events and then inserts them.
1505 1511
1506 VObjectIterator i; 1512 VObjectIterator i;
1507 VObject *curVO, *curVOProp; 1513 VObject *curVO, *curVOProp;
1508 Event *anEvent; 1514 Event *anEvent;
1509 1515
1510 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) { 1516 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
1511 char *methodType = 0; 1517 char *methodType = 0;
1512 methodType = fakeCString(vObjectUStringZValue(curVO)); 1518 methodType = fakeCString(vObjectUStringZValue(curVO));
1513 kdDebug() << "This calendar is an iTIP transaction of type '" 1519 kdDebug() << "This calendar is an iTIP transaction of type '"
1514 << methodType << "'" << endl; 1520 << methodType << "'" << endl;
1515 delete methodType; 1521 delete methodType;
1516 } 1522 }
1517 1523
1518 // warn the user that we might have trouble reading non-known calendar. 1524 // warn the user that we might have trouble reading non-known calendar.
1519 if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) { 1525 if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) {
1520 char *s = fakeCString(vObjectUStringZValue(curVO)); 1526 char *s = fakeCString(vObjectUStringZValue(curVO));
1521 if (strcmp(productId().local8Bit(), s) != 0) 1527 if (strcmp(productId().local8Bit(), s) != 0)
1522 kdDebug() << "This vCalendar file was not created by KOrganizer " 1528 kdDebug() << "This vCalendar file was not created by KOrganizer "
1523 "or any other product we support. Loading anyway..." << endl; 1529 "or any other product we support. Loading anyway..." << endl;
1524 mLoadedProductId = s; 1530 mLoadedProductId = s;
1525 deleteStr(s); 1531 deleteStr(s);
1526 } 1532 }
1527 1533
1528 // warn the user we might have trouble reading this unknown version. 1534 // warn the user we might have trouble reading this unknown version.
1529 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { 1535 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
1530 char *s = fakeCString(vObjectUStringZValue(curVO)); 1536 char *s = fakeCString(vObjectUStringZValue(curVO));
1531 if (strcmp(_VCAL_VERSION, s) != 0) 1537 if (strcmp(_VCAL_VERSION, s) != 0)
1532 kdDebug() << "This vCalendar file has version " << s 1538 kdDebug() << "This vCalendar file has version " << s
1533 << "We only support " << _VCAL_VERSION << endl; 1539 << "We only support " << _VCAL_VERSION << endl;
1534 deleteStr(s); 1540 deleteStr(s);
1535 } 1541 }
1536 1542
1537 // set the time zone 1543 // set the time zone
1538 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { 1544 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
1539 char *s = fakeCString(vObjectUStringZValue(curVO)); 1545 if ( vObjectUStringZValue(curVO) != 0 ) {
1540 mCalendar->setTimeZone(s); 1546 char *s = fakeCString(vObjectUStringZValue(curVO));
1541 deleteStr(s); 1547 mCalendar->setTimeZone(s);
1548 deleteStr(s);
1549 }
1542 } 1550 }
1543 1551
1544
1545 // Store all events with a relatedTo property in a list for post-processing 1552 // Store all events with a relatedTo property in a list for post-processing
1546 mEventsRelate.clear(); 1553 mEventsRelate.clear();
1547 mTodosRelate.clear(); 1554 mTodosRelate.clear();
1548 1555
1549 initPropIterator(&i, vcal); 1556 initPropIterator(&i, vcal);
1550 1557
1551 // go through all the vobjects in the vcal 1558 // go through all the vobjects in the vcal
1552 while (moreIteration(&i)) { 1559 while (moreIteration(&i)) {
1553 curVO = nextVObject(&i); 1560 curVO = nextVObject(&i);
1554 1561
1555 /************************************************************************/ 1562 /************************************************************************/
1556 1563
1557 // now, check to see that the object is an event or todo. 1564 // now, check to see that the object is an event or todo.
1558 if (strcmp(vObjectName(curVO), VCEventProp) == 0) { 1565 if (strcmp(vObjectName(curVO), VCEventProp) == 0) {
1559 1566
1560 if ((curVOProp = isAPropertyOf(curVO, XPilotStatusProp)) != 0) { 1567 if ((curVOProp = isAPropertyOf(curVO, XPilotStatusProp)) != 0) {
1561 char *s; 1568 char *s;
1562 s = fakeCString(vObjectUStringZValue(curVOProp)); 1569 s = fakeCString(vObjectUStringZValue(curVOProp));
1563 // check to see if event was deleted by the kpilot conduit 1570 // check to see if event was deleted by the kpilot conduit
1564 if (atoi(s) == Event::SYNCDEL) { 1571 if (atoi(s) == Event::SYNCDEL) {
1565 deleteStr(s); 1572 deleteStr(s);
1566 kdDebug(5800) << "skipping pilot-deleted event" << endl; 1573 kdDebug(5800) << "skipping pilot-deleted event" << endl;
1567 goto SKIP; 1574 goto SKIP;
1568 } 1575 }
1569 deleteStr(s); 1576 deleteStr(s);
1570 } 1577 }
1571 1578
1572 // this code checks to see if we are trying to read in an event 1579 // this code checks to see if we are trying to read in an event
1573 // that we already find to be in the calendar. If we find this 1580 // that we already find to be in the calendar. If we find this
1574 // to be the case, we skip the event. 1581 // to be the case, we skip the event.
1575 if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) { 1582 if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) {
1576 char *s = fakeCString(vObjectUStringZValue(curVOProp)); 1583 char *s = fakeCString(vObjectUStringZValue(curVOProp));
1577 QString tmpStr(s); 1584 QString tmpStr(s);
1578 deleteStr(s); 1585 deleteStr(s);
1579 1586
1580 if (mCalendar->event(tmpStr)) { 1587 if (mCalendar->event(tmpStr)) {
1581 goto SKIP; 1588 goto SKIP;
1582 } 1589 }
1583 if (mCalendar->todo(tmpStr)) { 1590 if (mCalendar->todo(tmpStr)) {
1584 goto SKIP; 1591 goto SKIP;
1585 } 1592 }
1586 } 1593 }
1587 1594
1588 if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) && 1595 if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) &&
1589 (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) { 1596 (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) {
1590 kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl; 1597 kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl;
1591 goto SKIP; 1598 goto SKIP;
1592 } 1599 }
1593 1600
1594 anEvent = VEventToEvent(curVO); 1601 anEvent = VEventToEvent(curVO);
1595 // we now use addEvent instead of insertEvent so that the 1602 // we now use addEvent instead of insertEvent so that the
1596 // signal/slot get connected. 1603 // signal/slot get connected.
1597 if (anEvent) { 1604 if (anEvent) {
1598 if ( !anEvent->dtStart().isValid() || !anEvent->dtEnd().isValid() ) { 1605 if ( !anEvent->dtStart().isValid() || !anEvent->dtEnd().isValid() ) {
1599 kdDebug() << "VCalFormat::populate(): Event has invalid dates." 1606 kdDebug() << "VCalFormat::populate(): Event has invalid dates."
1600 << endl; 1607 << endl;
1601 } else { 1608 } else {
1602 mCalendar->addEvent(anEvent); 1609 mCalendar->addEvent(anEvent);
1603 } 1610 }
1604 } else { 1611 } else {
1605 // some sort of error must have occurred while in translation. 1612 // some sort of error must have occurred while in translation.
1606 goto SKIP; 1613 goto SKIP;
1607 } 1614 }
1608 } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) { 1615 } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) {
1609 Todo *aTodo = VTodoToEvent(curVO); 1616 Todo *aTodo = VTodoToEvent(curVO);
1610 mCalendar->addTodo(aTodo); 1617 mCalendar->addTodo(aTodo);
1611 } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) || 1618 } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) ||
1612 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) || 1619 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) ||
1613 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) { 1620 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) {
1614 // do nothing, we know these properties and we want to skip them. 1621 // do nothing, we know these properties and we want to skip them.
1615 // we have either already processed them or are ignoring them. 1622 // we have either already processed them or are ignoring them.
1616 ; 1623 ;
1617 } else { 1624 } else {
1618 kdDebug(5800) << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl; 1625 kdDebug(5800) << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl;
1619 } 1626 }
1620 SKIP: 1627 SKIP:
1621 ; 1628 ;
1622 } // while 1629 } // while
1623 1630
1624 // Post-Process list of events with relations, put Event objects in relation 1631 // Post-Process list of events with relations, put Event objects in relation
1625 Event *ev; 1632 Event *ev;
1626 for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) { 1633 for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) {
1627 ev->setRelatedTo(mCalendar->event(ev->relatedToUid())); 1634 ev->setRelatedTo(mCalendar->event(ev->relatedToUid()));
1628 } 1635 }
1629 Todo *todo; 1636 Todo *todo;
1630 for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) { 1637 for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) {
1631 todo->setRelatedTo(mCalendar->todo(todo->relatedToUid())); 1638 todo->setRelatedTo(mCalendar->todo(todo->relatedToUid()));
1632 } 1639 }
1633} 1640}
1634 1641
1635const char *VCalFormat::dayFromNum(int day) 1642const char *VCalFormat::dayFromNum(int day)
1636{ 1643{
1637 const char *days[7] = { "MO ", "TU ", "WE ", "TH ", "FR ", "SA ", "SU " }; 1644 const char *days[7] = { "MO ", "TU ", "WE ", "TH ", "FR ", "SA ", "SU " };
1638 1645
1639 return days[day]; 1646 return days[day];
1640} 1647}
1641 1648
1642int VCalFormat::numFromDay(const QString &day) 1649int VCalFormat::numFromDay(const QString &day)
1643{ 1650{
1644 if (day == "MO ") return 0; 1651 if (day == "MO ") return 0;
1645 if (day == "TU ") return 1; 1652 if (day == "TU ") return 1;
1646 if (day == "WE ") return 2; 1653 if (day == "WE ") return 2;
1647 if (day == "TH ") return 3; 1654 if (day == "TH ") return 3;
1648 if (day == "FR ") return 4; 1655 if (day == "FR ") return 4;
1649 if (day == "SA ") return 5; 1656 if (day == "SA ") return 5;
1650 if (day == "SU ") return 6; 1657 if (day == "SU ") return 6;
1651 1658
1652 return -1; // something bad happened. :) 1659 return -1; // something bad happened. :)
1653} 1660}
1654 1661
1655Attendee::PartStat VCalFormat::readStatus(const char *s) const 1662Attendee::PartStat VCalFormat::readStatus(const char *s) const
1656{ 1663{
1657 QString statStr = s; 1664 QString statStr = s;
1658 statStr = statStr.upper(); 1665 statStr = statStr.upper();
1659 Attendee::PartStat status; 1666 Attendee::PartStat status;
1660 1667
1661 if (statStr == "X-ACTION") 1668 if (statStr == "X-ACTION")
1662 status = Attendee::NeedsAction; 1669 status = Attendee::NeedsAction;
1663 else if (statStr == "NEEDS ACTION") 1670 else if (statStr == "NEEDS ACTION")
1664 status = Attendee::NeedsAction; 1671 status = Attendee::NeedsAction;
1665 else if (statStr== "ACCEPTED") 1672 else if (statStr== "ACCEPTED")
1666 status = Attendee::Accepted; 1673 status = Attendee::Accepted;
1667 else if (statStr== "SENT") 1674 else if (statStr== "SENT")
1668 status = Attendee::NeedsAction; 1675 status = Attendee::NeedsAction;
1669 else if (statStr== "TENTATIVE") 1676 else if (statStr== "TENTATIVE")
1670 status = Attendee::Tentative; 1677 status = Attendee::Tentative;
1671 else if (statStr== "CONFIRMED") 1678 else if (statStr== "CONFIRMED")
1672 status = Attendee::Accepted; 1679 status = Attendee::Accepted;