author | zecke <zecke> | 2003-02-22 16:11:16 (UTC) |
---|---|---|
committer | zecke <zecke> | 2003-02-22 16:11:16 (UTC) |
commit | 397a7b1635488deda02b36df70692e27f59bb3e0 (patch) (unidiff) | |
tree | 1232b1b7e8ac84c5d48df79b635ba61acbdf0f62 | |
parent | e7981098a5c373748d98158e8a6c59750bb0d7dc (diff) | |
download | opie-397a7b1635488deda02b36df70692e27f59bb3e0.zip opie-397a7b1635488deda02b36df70692e27f59bb3e0.tar.gz opie-397a7b1635488deda02b36df70692e27f59bb3e0.tar.bz2 |
Implement saving of events
Implement the ExceptionList
Add Children and parent to OEvent
Make ORecur honor exceptions
Extend the test app to add and save
-rw-r--r-- | libopie/pim/odatebookaccessbackend_xml.cpp | 184 | ||||
-rw-r--r-- | libopie/pim/oevent.cpp | 64 | ||||
-rw-r--r-- | libopie/pim/oevent.h | 10 | ||||
-rw-r--r-- | libopie/pim/orecur.cpp | 66 | ||||
-rw-r--r-- | libopie/pim/orecur.h | 4 | ||||
-rw-r--r-- | libopie/pim/test/oevent_test.cpp | 10 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp | 184 | ||||
-rw-r--r-- | libopie2/opiepim/core/orecur.cpp | 66 | ||||
-rw-r--r-- | libopie2/opiepim/core/orecur.h | 4 | ||||
-rw-r--r-- | libopie2/opiepim/oevent.cpp | 64 | ||||
-rw-r--r-- | libopie2/opiepim/oevent.h | 10 |
11 files changed, 631 insertions, 35 deletions
diff --git a/libopie/pim/odatebookaccessbackend_xml.cpp b/libopie/pim/odatebookaccessbackend_xml.cpp index a4c514b..5239d84 100644 --- a/libopie/pim/odatebookaccessbackend_xml.cpp +++ b/libopie/pim/odatebookaccessbackend_xml.cpp | |||
@@ -1,395 +1,557 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <fcntl.h> | 2 | #include <fcntl.h> |
3 | 3 | ||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | |||
4 | #include <sys/types.h> | 7 | #include <sys/types.h> |
5 | #include <sys/mman.h> | 8 | #include <sys/mman.h> |
6 | #include <sys/stat.h> | 9 | #include <sys/stat.h> |
7 | 10 | ||
8 | #include <unistd.h> | 11 | #include <unistd.h> |
9 | 12 | ||
10 | #include <qasciidict.h> | 13 | #include <qasciidict.h> |
11 | #include <qfile.h> | 14 | #include <qfile.h> |
12 | 15 | ||
13 | #include <qtopia/global.h> | 16 | #include <qtopia/global.h> |
14 | #include <qtopia/stringutil.h> | 17 | #include <qtopia/stringutil.h> |
18 | #include <qtopia/timeconversion.h> | ||
15 | 19 | ||
16 | #include "opimnotifymanager.h" | 20 | #include "opimnotifymanager.h" |
17 | #include "orecur.h" | 21 | #include "orecur.h" |
18 | #include "otimezone.h" | 22 | #include "otimezone.h" |
19 | #include "odatebookaccessbackend_xml.h" | 23 | #include "odatebookaccessbackend_xml.h" |
20 | 24 | ||
21 | namespace { | 25 | namespace { |
22 | time_t start, end, created, rp_end; | 26 | time_t start, end, created, rp_end; |
23 | ORecur* rec; | 27 | ORecur* rec; |
24 | ORecur* recur() { | 28 | ORecur* recur() { |
25 | if (!rec) | 29 | if (!rec) |
26 | rec = new ORecur; | 30 | rec = new ORecur; |
27 | 31 | ||
28 | return rec; | 32 | return rec; |
29 | } | 33 | } |
30 | int alarmTime; | 34 | int alarmTime; |
31 | int snd; | 35 | int snd; |
32 | enum Attribute{ | 36 | enum Attribute{ |
33 | FDescription = 0, | 37 | FDescription = 0, |
34 | FLocation, | 38 | FLocation, |
35 | FCategories, | 39 | FCategories, |
36 | FUid, | 40 | FUid, |
37 | FType, | 41 | FType, |
38 | FAlarm, | 42 | FAlarm, |
39 | FSound, | 43 | FSound, |
40 | FRType, | 44 | FRType, |
41 | FRWeekdays, | 45 | FRWeekdays, |
42 | FRPosition, | 46 | FRPosition, |
43 | FRFreq, | 47 | FRFreq, |
44 | FRHasEndDate, | 48 | FRHasEndDate, |
45 | FREndDate, | 49 | FREndDate, |
46 | FRStart, | 50 | FRStart, |
47 | FREnd, | 51 | FREnd, |
48 | FNote, | 52 | FNote, |
49 | FCreated | 53 | FCreated, |
54 | FTimeZone, | ||
55 | FRecParent, | ||
56 | FRecChildren, | ||
57 | FExceptions | ||
50 | }; | 58 | }; |
59 | inline void save( const OEvent& ev, QString& buf ) { | ||
60 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; | ||
61 | if (!ev.location().isEmpty() ) | ||
62 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; | ||
63 | |||
64 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; | ||
65 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; | ||
66 | |||
67 | if (ev.isAllDay() ) | ||
68 | buf += " type=\"AllDay\""; | ||
69 | |||
70 | if (ev.hasNotifiers() ) { | ||
71 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first | ||
72 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; | ||
73 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; | ||
74 | if ( alarm.sound() == OPimAlarm::Loud ) | ||
75 | buf += "loud"; | ||
76 | else | ||
77 | buf += "silent"; | ||
78 | buf += "\""; | ||
79 | } | ||
80 | if ( ev.hasRecurrence() ) { | ||
81 | buf += ev.recurrence().toString(); | ||
82 | } | ||
83 | |||
84 | /* | ||
85 | * fscking timezones :) well, we'll first convert | ||
86 | * the QDateTime to a QDateTime in UTC time | ||
87 | * and then we'll create a nice time_t | ||
88 | */ | ||
89 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | ||
90 | buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; | ||
91 | buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; | ||
92 | if (!ev.note().isEmpty() ) { | ||
93 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; | ||
94 | } | ||
95 | |||
96 | buf += " timezone=\""; | ||
97 | if ( ev.timeZone().isEmpty() ) | ||
98 | buf += "None"; | ||
99 | else | ||
100 | buf += ev.timeZone(); | ||
101 | |||
102 | if (ev.parent() != 0 ) { | ||
103 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; | ||
104 | } | ||
105 | |||
106 | if (ev.children().count() != 0 ) { | ||
107 | QArray<int> children = ev.children(); | ||
108 | buf += " recchildren=\""; | ||
109 | for ( uint i = 0; i < children.count(); i++ ) { | ||
110 | if ( i != 0 ) buf += " "; | ||
111 | buf += QString::number( children[i] ); | ||
112 | } | ||
113 | buf+= "\""; | ||
114 | } | ||
115 | |||
116 | // skip custom writing | ||
117 | } | ||
118 | |||
119 | inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) { | ||
120 | QMap<int, OEvent>::ConstIterator it; | ||
121 | QString buf; | ||
122 | QCString str; | ||
123 | int total_written; | ||
124 | for ( it = list.begin(); it != list.end(); ++it ) { | ||
125 | buf = "<event"; | ||
126 | save( it.data(), buf ); | ||
127 | buf += " />\n"; | ||
128 | str = buf.utf8(); | ||
129 | |||
130 | total_written = file.writeBlock(str.data(), str.length() ); | ||
131 | if ( total_written != int(str.length() ) ) | ||
132 | return false; | ||
133 | } | ||
134 | return true; | ||
135 | } | ||
51 | } | 136 | } |
52 | 137 | ||
53 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , | 138 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , |
54 | const QString& fileName ) | 139 | const QString& fileName ) |
55 | : ODateBookAccessBackend() { | 140 | : ODateBookAccessBackend() { |
56 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; | 141 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; |
57 | m_changed = false; | 142 | m_changed = false; |
58 | } | 143 | } |
59 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { | 144 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { |
60 | } | 145 | } |
61 | bool ODateBookAccessBackend_XML::load() { | 146 | bool ODateBookAccessBackend_XML::load() { |
62 | return loadFile(); | 147 | return loadFile(); |
63 | } | 148 | } |
64 | bool ODateBookAccessBackend_XML::reload() { | 149 | bool ODateBookAccessBackend_XML::reload() { |
65 | clear(); | 150 | clear(); |
66 | return load(); | 151 | return load(); |
67 | } | 152 | } |
68 | bool ODateBookAccessBackend_XML::save() { | 153 | bool ODateBookAccessBackend_XML::save() { |
69 | if (!m_changed) return true; | 154 | qWarning("going to save now"); |
70 | m_changed = false; | 155 | // if (!m_changed) return true; |
156 | |||
157 | int total_written; | ||
158 | QString strFileNew = m_name + ".new"; | ||
159 | |||
160 | QFile f( strFileNew ); | ||
161 | if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; | ||
162 | |||
163 | QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); | ||
164 | buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; | ||
165 | buf += "<events>\n"; | ||
166 | QCString str = buf.utf8(); | ||
167 | total_written = f.writeBlock( str.data(), str.length() ); | ||
168 | if ( total_written != int(str.length() ) ) { | ||
169 | f.close(); | ||
170 | QFile::remove( strFileNew ); | ||
171 | return false; | ||
172 | } | ||
71 | 173 | ||
174 | if (!forAll( m_raw, f ) ) { | ||
175 | f.close(); | ||
176 | QFile::remove( strFileNew ); | ||
177 | return false; | ||
178 | } | ||
179 | if (!forAll( m_rep, f ) ) { | ||
180 | f.close(); | ||
181 | QFile::remove( strFileNew ); | ||
182 | return false; | ||
183 | } | ||
184 | |||
185 | buf = "</events>\n</DATEBOOK>\n"; | ||
186 | str = buf.utf8(); | ||
187 | total_written = f.writeBlock( str.data(), str.length() ); | ||
188 | if ( total_written != int(str.length() ) ) { | ||
189 | f.close(); | ||
190 | QFile::remove( strFileNew ); | ||
191 | return false; | ||
192 | } | ||
193 | f.close(); | ||
194 | |||
195 | exit(0); | ||
196 | if ( ::rename( strFileNew, m_name ) < 0 ) { | ||
197 | QFile::remove( strFileNew ); | ||
198 | return false; | ||
199 | } | ||
200 | |||
201 | m_changed = false; | ||
72 | return true; | 202 | return true; |
73 | } | 203 | } |
74 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { | 204 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { |
75 | QArray<int> ints( m_raw.count()+ m_rep.count() ); | 205 | QArray<int> ints( m_raw.count()+ m_rep.count() ); |
76 | uint i = 0; | 206 | uint i = 0; |
77 | QMap<int, OEvent>::ConstIterator it; | 207 | QMap<int, OEvent>::ConstIterator it; |
78 | 208 | ||
79 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 209 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
80 | ints[i] = it.key(); | 210 | ints[i] = it.key(); |
81 | i++; | 211 | i++; |
82 | } | 212 | } |
83 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 213 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
84 | ints[i] = it.key(); | 214 | ints[i] = it.key(); |
85 | i++; | 215 | i++; |
86 | } | 216 | } |
87 | 217 | ||
88 | return ints; | 218 | return ints; |
89 | } | 219 | } |
90 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int ) { | 220 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int ) { |
91 | return QArray<int>(); | 221 | return QArray<int>(); |
92 | } | 222 | } |
93 | void ODateBookAccessBackend_XML::clear() { | 223 | void ODateBookAccessBackend_XML::clear() { |
94 | m_raw.clear(); | 224 | m_raw.clear(); |
95 | m_rep.clear(); | 225 | m_rep.clear(); |
96 | } | 226 | } |
97 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ | 227 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ |
98 | if ( m_raw.contains( uid ) ) | 228 | if ( m_raw.contains( uid ) ) |
99 | return m_raw[uid]; | 229 | return m_raw[uid]; |
100 | else | 230 | else |
101 | return m_rep[uid]; | 231 | return m_rep[uid]; |
102 | } | 232 | } |
103 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { | 233 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { |
104 | m_changed = true; | 234 | m_changed = true; |
105 | if (ev.hasRecurrence() ) | 235 | if (ev.hasRecurrence() ) |
106 | m_rep.insert( ev.uid(), ev ); | 236 | m_rep.insert( ev.uid(), ev ); |
107 | else | 237 | else |
108 | m_raw.insert( ev.uid(), ev ); | 238 | m_raw.insert( ev.uid(), ev ); |
109 | 239 | ||
110 | return true; | 240 | return true; |
111 | } | 241 | } |
112 | bool ODateBookAccessBackend_XML::remove( int uid ) { | 242 | bool ODateBookAccessBackend_XML::remove( int uid ) { |
113 | m_changed = true; | 243 | m_changed = true; |
114 | m_rep.remove( uid ); | 244 | m_rep.remove( uid ); |
115 | m_rep.remove( uid ); | 245 | m_rep.remove( uid ); |
116 | 246 | ||
117 | return true; | 247 | return true; |
118 | } | 248 | } |
119 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { | 249 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { |
120 | replace( ev.uid() ); | 250 | replace( ev.uid() ); |
121 | return add( ev ); | 251 | return add( ev ); |
122 | } | 252 | } |
123 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { | 253 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { |
124 | return allRecords(); | 254 | return allRecords(); |
125 | } | 255 | } |
126 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { | 256 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { |
127 | QArray<int> ints( m_rep.count() ); | 257 | QArray<int> ints( m_rep.count() ); |
128 | uint i = 0; | 258 | uint i = 0; |
129 | QMap<int, OEvent>::ConstIterator it; | 259 | QMap<int, OEvent>::ConstIterator it; |
130 | 260 | ||
131 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 261 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
132 | ints[i] = it.key(); | 262 | ints[i] = it.key(); |
133 | i++; | 263 | i++; |
134 | } | 264 | } |
135 | 265 | ||
136 | return ints; | 266 | return ints; |
137 | } | 267 | } |
138 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { | 268 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { |
139 | QArray<int> ints( m_raw.count() ); | 269 | QArray<int> ints( m_raw.count() ); |
140 | uint i = 0; | 270 | uint i = 0; |
141 | QMap<int, OEvent>::ConstIterator it; | 271 | QMap<int, OEvent>::ConstIterator it; |
142 | 272 | ||
143 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 273 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
144 | ints[i] = it.key(); | 274 | ints[i] = it.key(); |
145 | i++; | 275 | i++; |
146 | } | 276 | } |
147 | 277 | ||
148 | return ints; | 278 | return ints; |
149 | } | 279 | } |
150 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { | 280 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { |
151 | OEvent::ValueList list; | 281 | OEvent::ValueList list; |
152 | QMap<int, OEvent>::ConstIterator it; | 282 | QMap<int, OEvent>::ConstIterator it; |
153 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) | 283 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) |
154 | list.append( it.data() ); | 284 | list.append( it.data() ); |
155 | 285 | ||
156 | return list; | 286 | return list; |
157 | } | 287 | } |
158 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { | 288 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { |
159 | OEvent::ValueList list; | 289 | OEvent::ValueList list; |
160 | QMap<int, OEvent>::ConstIterator it; | 290 | QMap<int, OEvent>::ConstIterator it; |
161 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) | 291 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) |
162 | list.append( it.data() ); | 292 | list.append( it.data() ); |
163 | 293 | ||
164 | return list; | 294 | return list; |
165 | } | 295 | } |
166 | bool ODateBookAccessBackend_XML::loadFile() { | 296 | bool ODateBookAccessBackend_XML::loadFile() { |
167 | m_changed = false; | 297 | m_changed = false; |
168 | 298 | ||
169 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); | 299 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); |
170 | if ( fd < 0 ) return false; | 300 | if ( fd < 0 ) return false; |
171 | 301 | ||
172 | struct stat attribute; | 302 | struct stat attribute; |
173 | if ( ::fstat(fd, &attribute ) == -1 ) { | 303 | if ( ::fstat(fd, &attribute ) == -1 ) { |
174 | ::close( fd ); | 304 | ::close( fd ); |
175 | return false; | 305 | return false; |
176 | } | 306 | } |
177 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 307 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
178 | if ( map_addr == ( (caddr_t)-1) ) { | 308 | if ( map_addr == ( (caddr_t)-1) ) { |
179 | ::close( fd ); | 309 | ::close( fd ); |
180 | return false; | 310 | return false; |
181 | } | 311 | } |
182 | 312 | ||
183 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); | 313 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); |
184 | ::close( fd ); | 314 | ::close( fd ); |
185 | 315 | ||
186 | QAsciiDict<int> dict(FCreated+1); | 316 | QAsciiDict<int> dict(FExceptions+1); |
187 | dict.setAutoDelete( true ); | 317 | dict.setAutoDelete( true ); |
188 | dict.insert( "description", new int(FDescription) ); | 318 | dict.insert( "description", new int(FDescription) ); |
189 | dict.insert( "location", new int(FLocation) ); | 319 | dict.insert( "location", new int(FLocation) ); |
190 | dict.insert( "categories", new int(FCategories) ); | 320 | dict.insert( "categories", new int(FCategories) ); |
191 | dict.insert( "uid", new int(FUid) ); | 321 | dict.insert( "uid", new int(FUid) ); |
192 | dict.insert( "type", new int(FType) ); | 322 | dict.insert( "type", new int(FType) ); |
193 | dict.insert( "alarm", new int(FAlarm) ); | 323 | dict.insert( "alarm", new int(FAlarm) ); |
194 | dict.insert( "sound", new int(FSound) ); | 324 | dict.insert( "sound", new int(FSound) ); |
195 | dict.insert( "rtype", new int(FRType) ); | 325 | dict.insert( "rtype", new int(FRType) ); |
196 | dict.insert( "rweekdays", new int(FRWeekdays) ); | 326 | dict.insert( "rweekdays", new int(FRWeekdays) ); |
197 | dict.insert( "rposition", new int(FRPosition) ); | 327 | dict.insert( "rposition", new int(FRPosition) ); |
198 | dict.insert( "rfreq", new int(FRFreq) ); | 328 | dict.insert( "rfreq", new int(FRFreq) ); |
199 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); | 329 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); |
200 | dict.insert( "enddt", new int(FREndDate) ); | 330 | dict.insert( "enddt", new int(FREndDate) ); |
201 | dict.insert( "start", new int(FRStart) ); | 331 | dict.insert( "start", new int(FRStart) ); |
202 | dict.insert( "end", new int(FREnd) ); | 332 | dict.insert( "end", new int(FREnd) ); |
203 | dict.insert( "note", new int(FNote) ); | 333 | dict.insert( "note", new int(FNote) ); |
204 | dict.insert( "created", new int(FCreated) ); | 334 | dict.insert( "created", new int(FCreated) ); |
335 | dict.insert( "recparent", new int(FRecParent) ); | ||
336 | dict.insert( "recchildren", new int(FRecChildren) ); | ||
337 | dict.insert( "exceptions", new int(FExceptions) ); | ||
338 | dict.insert( "timezone", new int(FTimeZone) ); | ||
205 | 339 | ||
206 | char* dt = (char*)map_addr; | 340 | char* dt = (char*)map_addr; |
207 | int len = attribute.st_size; | 341 | int len = attribute.st_size; |
208 | int i = 0; | 342 | int i = 0; |
209 | char* point; | 343 | char* point; |
210 | const char* collectionString = "<event "; | 344 | const char* collectionString = "<event "; |
211 | int strLen = ::strlen(collectionString); | 345 | int strLen = ::strlen(collectionString); |
212 | int *find; | 346 | int *find; |
213 | while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) { | 347 | while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) { |
214 | i = point -dt; | 348 | i = point -dt; |
215 | i+= strLen; | 349 | i+= strLen; |
216 | 350 | ||
217 | alarmTime = -1; | 351 | alarmTime = -1; |
218 | snd = 0; // silent | 352 | snd = 0; // silent |
219 | 353 | ||
220 | OEvent ev; | 354 | OEvent ev; |
221 | rec = 0; | 355 | rec = 0; |
222 | 356 | ||
223 | while ( TRUE ) { | 357 | while ( TRUE ) { |
224 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 358 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
225 | ++i; | 359 | ++i; |
226 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 360 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
227 | break; | 361 | break; |
228 | 362 | ||
229 | 363 | ||
230 | // we have another attribute, read it. | 364 | // we have another attribute, read it. |
231 | int j = i; | 365 | int j = i; |
232 | while ( j < len && dt[j] != '=' ) | 366 | while ( j < len && dt[j] != '=' ) |
233 | ++j; | 367 | ++j; |
234 | QCString attr( dt+i, j-i+1); | 368 | QCString attr( dt+i, j-i+1); |
235 | 369 | ||
236 | i = ++j; // skip = | 370 | i = ++j; // skip = |
237 | 371 | ||
238 | // find the start of quotes | 372 | // find the start of quotes |
239 | while ( i < len && dt[i] != '"' ) | 373 | while ( i < len && dt[i] != '"' ) |
240 | ++i; | 374 | ++i; |
241 | j = ++i; | 375 | j = ++i; |
242 | 376 | ||
243 | bool haveUtf = FALSE; | 377 | bool haveUtf = FALSE; |
244 | bool haveEnt = FALSE; | 378 | bool haveEnt = FALSE; |
245 | while ( j < len && dt[j] != '"' ) { | 379 | while ( j < len && dt[j] != '"' ) { |
246 | if ( ((unsigned char)dt[j]) > 0x7f ) | 380 | if ( ((unsigned char)dt[j]) > 0x7f ) |
247 | haveUtf = TRUE; | 381 | haveUtf = TRUE; |
248 | if ( dt[j] == '&' ) | 382 | if ( dt[j] == '&' ) |
249 | haveEnt = TRUE; | 383 | haveEnt = TRUE; |
250 | ++j; | 384 | ++j; |
251 | } | 385 | } |
252 | if ( i == j ) { | 386 | if ( i == j ) { |
253 | // empty value | 387 | // empty value |
254 | i = j + 1; | 388 | i = j + 1; |
255 | continue; | 389 | continue; |
256 | } | 390 | } |
257 | 391 | ||
258 | QCString value( dt+i, j-i+1 ); | 392 | QCString value( dt+i, j-i+1 ); |
259 | i = j + 1; | 393 | i = j + 1; |
260 | 394 | ||
261 | QString str = (haveUtf ? QString::fromUtf8( value ) | 395 | QString str = (haveUtf ? QString::fromUtf8( value ) |
262 | : QString::fromLatin1( value ) ); | 396 | : QString::fromLatin1( value ) ); |
263 | if ( haveEnt ) | 397 | if ( haveEnt ) |
264 | str = Qtopia::plainString( str ); | 398 | str = Qtopia::plainString( str ); |
265 | 399 | ||
266 | /* | 400 | /* |
267 | * add key + value | 401 | * add key + value |
268 | */ | 402 | */ |
269 | find = dict[attr.data()]; | 403 | find = dict[attr.data()]; |
270 | if (!find) | 404 | if (!find) |
271 | ev.setCustomField( attr, value ); | 405 | ev.setCustomField( attr, value ); |
272 | else { | 406 | else { |
273 | setField( ev, *find, value ); | 407 | setField( ev, *find, value ); |
274 | } | 408 | } |
275 | } | 409 | } |
276 | /* time to finalize */ | 410 | /* time to finalize */ |
277 | finalizeRecord( ev ); | 411 | finalizeRecord( ev ); |
278 | add( ev ); | 412 | add( ev ); |
279 | delete rec; | 413 | delete rec; |
280 | } | 414 | } |
281 | ::munmap(map_addr, attribute.st_size ); | 415 | ::munmap(map_addr, attribute.st_size ); |
282 | m_changed = false; // changed during add | 416 | m_changed = false; // changed during add |
283 | 417 | ||
284 | return true; | 418 | return true; |
285 | } | 419 | } |
286 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { | 420 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { |
287 | /* AllDay is alway in UTC */ | 421 | /* AllDay is alway in UTC */ |
288 | if ( ev.isAllDay() ) { | 422 | if ( ev.isAllDay() ) { |
289 | OTimeZone utc = OTimeZone::utc(); | 423 | OTimeZone utc = OTimeZone::utc(); |
290 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); | 424 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); |
291 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); | 425 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); |
426 | ev.setTimeZone( "UTC"); // make sure it is really utc | ||
292 | }else { | 427 | }else { |
428 | /* to current date time */ | ||
293 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | 429 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); |
294 | ev.setStartDateTime( zone.toDateTime( start ) ); | 430 | QDateTime date = zone.toDateTime( start ); |
295 | ev.setEndDateTime ( zone.toDateTime( end ) ); | 431 | ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); |
432 | |||
433 | date = zone.toDateTime( end ); | ||
434 | ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); | ||
296 | } | 435 | } |
297 | if ( rec && rec->doesRecur() ) { | 436 | if ( rec && rec->doesRecur() ) { |
298 | OTimeZone utc = OTimeZone::utc(); | 437 | OTimeZone utc = OTimeZone::utc(); |
299 | ORecur recu( *rec ); // call copy c'tor; | 438 | ORecur recu( *rec ); // call copy c'tor; |
300 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); | 439 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); |
301 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); | 440 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); |
302 | recu.setStart( ev.startDateTime().date() ); | 441 | recu.setStart( ev.startDateTime().date() ); |
303 | ev.setRecurrence( recu ); | 442 | ev.setRecurrence( recu ); |
304 | } | 443 | } |
305 | 444 | ||
306 | if (alarmTime != -1 ) { | 445 | if (alarmTime != -1 ) { |
307 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); | 446 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); |
308 | OPimAlarm al( snd , dt ); | 447 | OPimAlarm al( snd , dt ); |
309 | ev.notifiers().add( al ); | 448 | ev.notifiers().add( al ); |
310 | } | 449 | } |
311 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { | 450 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { |
312 | ev.setUid( 1 ); | 451 | ev.setUid( 1 ); |
313 | } | 452 | } |
314 | if ( ev.hasRecurrence() ) | 453 | if ( ev.hasRecurrence() ) |
315 | m_rep.insert( ev.uid(), ev ); | 454 | m_rep.insert( ev.uid(), ev ); |
316 | else | 455 | else |
317 | m_raw.insert( ev.uid(), ev ); | 456 | m_raw.insert( ev.uid(), ev ); |
318 | 457 | ||
319 | } | 458 | } |
320 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { | 459 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { |
321 | // qWarning(" setting %s", value.latin1() ); | 460 | // qWarning(" setting %s", value.latin1() ); |
322 | switch( id ) { | 461 | switch( id ) { |
323 | case FDescription: | 462 | case FDescription: |
324 | e.setDescription( value ); | 463 | e.setDescription( value ); |
325 | break; | 464 | break; |
326 | case FLocation: | 465 | case FLocation: |
327 | e.setLocation( value ); | 466 | e.setLocation( value ); |
328 | break; | 467 | break; |
329 | case FCategories: | 468 | case FCategories: |
330 | e.setCategories( e.idsFromString( value ) ); | 469 | e.setCategories( e.idsFromString( value ) ); |
331 | break; | 470 | break; |
332 | case FUid: | 471 | case FUid: |
333 | e.setUid( value.toInt() ); | 472 | e.setUid( value.toInt() ); |
334 | break; | 473 | break; |
335 | case FType: | 474 | case FType: |
336 | if ( value == "AllDay" ) { | 475 | if ( value == "AllDay" ) { |
337 | e.setAllDay( true ); | 476 | e.setAllDay( true ); |
338 | e.setTimeZone( "UTC" ); | 477 | e.setTimeZone( "UTC" ); |
339 | } | 478 | } |
340 | break; | 479 | break; |
341 | case FAlarm: | 480 | case FAlarm: |
342 | alarmTime = value.toInt(); | 481 | alarmTime = value.toInt(); |
343 | break; | 482 | break; |
344 | case FSound: | 483 | case FSound: |
345 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; | 484 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; |
346 | break; | 485 | break; |
347 | // recurrence stuff | 486 | // recurrence stuff |
348 | case FRType: | 487 | case FRType: |
349 | if ( value == "Daily" ) | 488 | if ( value == "Daily" ) |
350 | recur()->setType( ORecur::Daily ); | 489 | recur()->setType( ORecur::Daily ); |
351 | else if ( value == "Weekly" ) | 490 | else if ( value == "Weekly" ) |
352 | recur()->setType( ORecur::Weekly); | 491 | recur()->setType( ORecur::Weekly); |
353 | else if ( value == "MonthlyDay" ) | 492 | else if ( value == "MonthlyDay" ) |
354 | recur()->setType( ORecur::MonthlyDay ); | 493 | recur()->setType( ORecur::MonthlyDay ); |
355 | else if ( value == "MonthlyDate" ) | 494 | else if ( value == "MonthlyDate" ) |
356 | recur()->setType( ORecur::MonthlyDate ); | 495 | recur()->setType( ORecur::MonthlyDate ); |
357 | else if ( value == "Yearly" ) | 496 | else if ( value == "Yearly" ) |
358 | recur()->setType( ORecur::Yearly ); | 497 | recur()->setType( ORecur::Yearly ); |
359 | else | 498 | else |
360 | recur()->setType( ORecur::NoRepeat ); | 499 | recur()->setType( ORecur::NoRepeat ); |
361 | break; | 500 | break; |
362 | case FRWeekdays: | 501 | case FRWeekdays: |
363 | recur()->setDays( value.toInt() ); | 502 | recur()->setDays( value.toInt() ); |
364 | break; | 503 | break; |
365 | case FRPosition: | 504 | case FRPosition: |
366 | recur()->setPosition( value.toInt() ); | 505 | recur()->setPosition( value.toInt() ); |
367 | break; | 506 | break; |
368 | case FRFreq: | 507 | case FRFreq: |
369 | recur()->setFrequency( value.toInt() ); | 508 | recur()->setFrequency( value.toInt() ); |
370 | break; | 509 | break; |
371 | case FRHasEndDate: | 510 | case FRHasEndDate: |
372 | recur()->setHasEndDate( value.toInt() ); | 511 | recur()->setHasEndDate( value.toInt() ); |
373 | break; | 512 | break; |
374 | case FREndDate: { | 513 | case FREndDate: { |
375 | rp_end = (time_t) value.toLong(); | 514 | rp_end = (time_t) value.toLong(); |
376 | break; | 515 | break; |
377 | } | 516 | } |
378 | case FRStart: { | 517 | case FRStart: { |
379 | start = (time_t) value.toLong(); | 518 | start = (time_t) value.toLong(); |
380 | break; | 519 | break; |
381 | } | 520 | } |
382 | case FREnd: { | 521 | case FREnd: { |
383 | end = ( (time_t) value.toLong() ); | 522 | end = ( (time_t) value.toLong() ); |
384 | break; | 523 | break; |
385 | } | 524 | } |
386 | case FNote: | 525 | case FNote: |
387 | e.setNote( value ); | 526 | e.setNote( value ); |
388 | break; | 527 | break; |
389 | case FCreated: | 528 | case FCreated: |
390 | created = value.toInt(); | 529 | created = value.toInt(); |
391 | break; | 530 | break; |
531 | case FRecParent: | ||
532 | e.setParent( value.toInt() ); | ||
533 | break; | ||
534 | case FRecChildren:{ | ||
535 | QStringList list = QStringList::split(' ', value ); | ||
536 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | ||
537 | e.addChild( (*it).toInt() ); | ||
538 | } | ||
539 | } | ||
540 | break; | ||
541 | case FExceptions:{ | ||
542 | QStringList list = QStringList::split(' ', value ); | ||
543 | for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | ||
544 | QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); | ||
545 | qWarning("adding exception %s", date.toString().latin1() ); | ||
546 | recur()->exceptions().append( date ); | ||
547 | } | ||
548 | } | ||
549 | break; | ||
550 | case FTimeZone: | ||
551 | if ( value != "None" ) | ||
552 | e.setTimeZone( value ); | ||
553 | break; | ||
392 | default: | 554 | default: |
393 | break; | 555 | break; |
394 | } | 556 | } |
395 | } | 557 | } |
diff --git a/libopie/pim/oevent.cpp b/libopie/pim/oevent.cpp index ada596c..c3eeee2 100644 --- a/libopie/pim/oevent.cpp +++ b/libopie/pim/oevent.cpp | |||
@@ -1,431 +1,489 @@ | |||
1 | #include <qshared.h> | 1 | #include <qshared.h> |
2 | 2 | ||
3 | #include <qpe/palmtopuidgen.h> | 3 | #include <qpe/palmtopuidgen.h> |
4 | #include <qpe/categories.h> | 4 | #include <qpe/categories.h> |
5 | 5 | ||
6 | #include "orecur.h" | 6 | #include "orecur.h" |
7 | #include "opimresolver.h" | 7 | #include "opimresolver.h" |
8 | #include "opimnotifymanager.h" | 8 | #include "opimnotifymanager.h" |
9 | 9 | ||
10 | #include "oevent.h" | 10 | #include "oevent.h" |
11 | 11 | ||
12 | int OCalendarHelper::week( const QDate& date) { | 12 | int OCalendarHelper::week( const QDate& date) { |
13 | // Calculates the week this date is in within that | 13 | // Calculates the week this date is in within that |
14 | // month. Equals the "row" is is in in the month view | 14 | // month. Equals the "row" is is in in the month view |
15 | int week = 1; | 15 | int week = 1; |
16 | QDate tmp( date.year(), date.month(), 1 ); | 16 | QDate tmp( date.year(), date.month(), 1 ); |
17 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) | 17 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) |
18 | ++week; | 18 | ++week; |
19 | 19 | ||
20 | week += ( date.day() - 1 ) / 7; | 20 | week += ( date.day() - 1 ) / 7; |
21 | 21 | ||
22 | return week; | 22 | return week; |
23 | } | 23 | } |
24 | int OCalendarHelper::ocurrence( const QDate& date) { | 24 | int OCalendarHelper::ocurrence( const QDate& date) { |
25 | // calculates the number of occurrances of this day of the | 25 | // calculates the number of occurrances of this day of the |
26 | // week till the given date (e.g 3rd Wednesday of the month) | 26 | // week till the given date (e.g 3rd Wednesday of the month) |
27 | return ( date.day() - 1 ) / 7 + 1; | 27 | return ( date.day() - 1 ) / 7 + 1; |
28 | } | 28 | } |
29 | int OCalendarHelper::dayOfWeek( char day ) { | 29 | int OCalendarHelper::dayOfWeek( char day ) { |
30 | int dayOfWeek = 1; | 30 | int dayOfWeek = 1; |
31 | char i = ORecur::MON; | 31 | char i = ORecur::MON; |
32 | while ( !( i & day ) && i <= ORecur::SUN ) { | 32 | while ( !( i & day ) && i <= ORecur::SUN ) { |
33 | i <<= 1; | 33 | i <<= 1; |
34 | ++dayOfWeek; | 34 | ++dayOfWeek; |
35 | } | 35 | } |
36 | return dayOfWeek; | 36 | return dayOfWeek; |
37 | } | 37 | } |
38 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { | 38 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { |
39 | return ( second.year() - first.year() ) * 12 + | 39 | return ( second.year() - first.year() ) * 12 + |
40 | second.month() - first.month(); | 40 | second.month() - first.month(); |
41 | } | 41 | } |
42 | 42 | ||
43 | struct OEvent::Data : public QShared { | 43 | struct OEvent::Data : public QShared { |
44 | Data() : QShared() { | 44 | Data() : QShared() { |
45 | child = 0; | ||
45 | recur = 0; | 46 | recur = 0; |
46 | manager = 0; | 47 | manager = 0; |
47 | isAllDay = false; | 48 | isAllDay = false; |
49 | parent = 0; | ||
48 | } | 50 | } |
49 | ~Data() { | 51 | ~Data() { |
50 | delete manager; | 52 | delete manager; |
51 | delete recur; | 53 | delete recur; |
52 | } | 54 | } |
53 | QString description; | 55 | QString description; |
54 | QString location; | 56 | QString location; |
55 | OPimNotifyManager* manager; | 57 | OPimNotifyManager* manager; |
56 | ORecur* recur; | 58 | ORecur* recur; |
57 | QString note; | 59 | QString note; |
58 | QDateTime created; | 60 | QDateTime created; |
59 | QDateTime start; | 61 | QDateTime start; |
60 | QDateTime end; | 62 | QDateTime end; |
61 | bool isAllDay : 1; | 63 | bool isAllDay : 1; |
62 | QString timezone; | 64 | QString timezone; |
65 | QArray<int>* child; | ||
66 | int parent; | ||
63 | }; | 67 | }; |
64 | 68 | ||
65 | OEvent::OEvent( int uid ) | 69 | OEvent::OEvent( int uid ) |
66 | : OPimRecord( uid ) { | 70 | : OPimRecord( uid ) { |
67 | data = new Data; | 71 | data = new Data; |
68 | } | 72 | } |
69 | OEvent::OEvent( const OEvent& ev) | 73 | OEvent::OEvent( const OEvent& ev) |
70 | : OPimRecord( ev ), data( ev.data ) | 74 | : OPimRecord( ev ), data( ev.data ) |
71 | { | 75 | { |
72 | data->ref(); | 76 | data->ref(); |
73 | } | 77 | } |
74 | OEvent::~OEvent() { | 78 | OEvent::~OEvent() { |
75 | if ( data->deref() ) { | 79 | if ( data->deref() ) { |
76 | delete data; | 80 | delete data; |
77 | data = 0; | 81 | data = 0; |
78 | } | 82 | } |
79 | } | 83 | } |
80 | OEvent& OEvent::operator=( const OEvent& ev) { | 84 | OEvent& OEvent::operator=( const OEvent& ev) { |
81 | if ( *this == ev ) return *this; | 85 | if ( *this == ev ) return *this; |
82 | 86 | ||
83 | OPimRecord::operator=( ev ); | 87 | OPimRecord::operator=( ev ); |
84 | ev.data->ref(); | 88 | ev.data->ref(); |
85 | deref(); | 89 | deref(); |
86 | data = ev.data; | 90 | data = ev.data; |
87 | 91 | ||
88 | 92 | ||
89 | return *this; | 93 | return *this; |
90 | } | 94 | } |
91 | QString OEvent::description()const { | 95 | QString OEvent::description()const { |
92 | return data->description; | 96 | return data->description; |
93 | } | 97 | } |
94 | void OEvent::setDescription( const QString& description ) { | 98 | void OEvent::setDescription( const QString& description ) { |
95 | changeOrModify(); | 99 | changeOrModify(); |
96 | data->description = description; | 100 | data->description = description; |
97 | } | 101 | } |
98 | void OEvent::setLocation( const QString& loc ) { | 102 | void OEvent::setLocation( const QString& loc ) { |
99 | changeOrModify(); | 103 | changeOrModify(); |
100 | data->location = loc; | 104 | data->location = loc; |
101 | } | 105 | } |
102 | QString OEvent::location()const { | 106 | QString OEvent::location()const { |
103 | return data->location; | 107 | return data->location; |
104 | } | 108 | } |
105 | OPimNotifyManager &OEvent::notifiers() { | 109 | OPimNotifyManager &OEvent::notifiers()const { |
106 | // I hope we can skip the changeOrModify here | 110 | // I hope we can skip the changeOrModify here |
107 | // the notifier should take care of it | 111 | // the notifier should take care of it |
108 | // and OPimNotify is shared too | 112 | // and OPimNotify is shared too |
109 | if (!data->manager ) | 113 | if (!data->manager ) |
110 | data->manager = new OPimNotifyManager; | 114 | data->manager = new OPimNotifyManager; |
111 | 115 | ||
112 | return *data->manager; | 116 | return *data->manager; |
113 | } | 117 | } |
114 | bool OEvent::hasNotifiers()const { | 118 | bool OEvent::hasNotifiers()const { |
115 | return ( data->manager); | 119 | if (!data->manager ) |
120 | return false; | ||
121 | if (data->manager->reminders().isEmpty() && | ||
122 | data->manager->alarms().isEmpty() ) | ||
123 | return false; | ||
124 | |||
125 | return true; | ||
116 | } | 126 | } |
117 | ORecur OEvent::recurrence()const { | 127 | ORecur OEvent::recurrence()const { |
118 | if (!data->recur) | 128 | if (!data->recur) |
119 | data->recur = new ORecur; | 129 | data->recur = new ORecur; |
120 | 130 | ||
121 | return *data->recur; | 131 | return *data->recur; |
122 | } | 132 | } |
123 | void OEvent::setRecurrence( const ORecur& rec) { | 133 | void OEvent::setRecurrence( const ORecur& rec) { |
124 | changeOrModify(); | 134 | changeOrModify(); |
125 | if (data->recur ) | 135 | if (data->recur ) |
126 | (*data->recur) = rec; | 136 | (*data->recur) = rec; |
127 | else | 137 | else |
128 | data->recur = new ORecur( rec ); | 138 | data->recur = new ORecur( rec ); |
129 | } | 139 | } |
130 | bool OEvent::hasRecurrence()const { | 140 | bool OEvent::hasRecurrence()const { |
131 | if (!data->recur ) return false; | 141 | if (!data->recur ) return false; |
132 | return data->recur->doesRecur(); | 142 | return data->recur->doesRecur(); |
133 | } | 143 | } |
134 | QString OEvent::note()const { | 144 | QString OEvent::note()const { |
135 | return data->note; | 145 | return data->note; |
136 | } | 146 | } |
137 | void OEvent::setNote( const QString& note ) { | 147 | void OEvent::setNote( const QString& note ) { |
138 | changeOrModify(); | 148 | changeOrModify(); |
139 | data->note = note; | 149 | data->note = note; |
140 | } | 150 | } |
141 | QDateTime OEvent::createdDateTime()const { | 151 | QDateTime OEvent::createdDateTime()const { |
142 | return data->created; | 152 | return data->created; |
143 | } | 153 | } |
144 | void OEvent::setCreatedDateTime( const QDateTime& time ) { | 154 | void OEvent::setCreatedDateTime( const QDateTime& time ) { |
145 | changeOrModify(); | 155 | changeOrModify(); |
146 | data->created = time; | 156 | data->created = time; |
147 | } | 157 | } |
148 | QDateTime OEvent::startDateTime()const { | 158 | QDateTime OEvent::startDateTime()const { |
149 | if ( data->isAllDay ) | 159 | if ( data->isAllDay ) |
150 | return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); | 160 | return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); |
151 | return data->start; | 161 | return data->start; |
152 | } | 162 | } |
153 | QDateTime OEvent::startDateTimeInZone()const { | 163 | QDateTime OEvent::startDateTimeInZone()const { |
154 | /* if no timezone, or all day event or if the current and this timeZone match... */ | 164 | /* if no timezone, or all day event or if the current and this timeZone match... */ |
155 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); | 165 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); |
156 | 166 | ||
157 | OTimeZone zone(data->timezone ); | 167 | OTimeZone zone(data->timezone ); |
158 | return zone.toDateTime( data->start, OTimeZone::current() ); | 168 | return zone.toDateTime( data->start, OTimeZone::current() ); |
159 | } | 169 | } |
160 | void OEvent::setStartDateTime( const QDateTime& dt ) { | 170 | void OEvent::setStartDateTime( const QDateTime& dt ) { |
161 | changeOrModify(); | 171 | changeOrModify(); |
162 | data->start = dt; | 172 | data->start = dt; |
163 | } | 173 | } |
164 | QDateTime OEvent::endDateTime()const { | 174 | QDateTime OEvent::endDateTime()const { |
165 | /* | 175 | /* |
166 | * if all Day event the end time needs | 176 | * if all Day event the end time needs |
167 | * to be on the same day as the start | 177 | * to be on the same day as the start |
168 | */ | 178 | */ |
169 | if ( data->isAllDay ) | 179 | if ( data->isAllDay ) |
170 | return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); | 180 | return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); |
171 | return data->end; | 181 | return data->end; |
172 | } | 182 | } |
173 | QDateTime OEvent::endDateTimeInZone()const { | 183 | QDateTime OEvent::endDateTimeInZone()const { |
174 | /* if no timezone, or all day event or if the current and this timeZone match... */ | 184 | /* if no timezone, or all day event or if the current and this timeZone match... */ |
175 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); | 185 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); |
176 | 186 | ||
177 | OTimeZone zone(data->timezone ); | 187 | OTimeZone zone(data->timezone ); |
178 | return zone.toDateTime( data->end, OTimeZone::current() ); | 188 | return zone.toDateTime( data->end, OTimeZone::current() ); |
179 | } | 189 | } |
180 | void OEvent::setEndDateTime( const QDateTime& dt ) { | 190 | void OEvent::setEndDateTime( const QDateTime& dt ) { |
181 | changeOrModify(); | 191 | changeOrModify(); |
182 | data->end = dt; | 192 | data->end = dt; |
183 | } | 193 | } |
184 | bool OEvent::isMultipleDay()const { | 194 | bool OEvent::isMultipleDay()const { |
185 | return data->end.date().day() - data->start.date().day(); | 195 | return data->end.date().day() - data->start.date().day(); |
186 | } | 196 | } |
187 | bool OEvent::isAllDay()const { | 197 | bool OEvent::isAllDay()const { |
188 | return data->isAllDay; | 198 | return data->isAllDay; |
189 | } | 199 | } |
190 | void OEvent::setAllDay( bool allDay ) { | 200 | void OEvent::setAllDay( bool allDay ) { |
191 | changeOrModify(); | 201 | changeOrModify(); |
192 | data->isAllDay = allDay; | 202 | data->isAllDay = allDay; |
193 | if (allDay ) data->timezone = "UTC"; | 203 | if (allDay ) data->timezone = "UTC"; |
194 | } | 204 | } |
195 | void OEvent::setTimeZone( const QString& tz ) { | 205 | void OEvent::setTimeZone( const QString& tz ) { |
196 | changeOrModify(); | 206 | changeOrModify(); |
197 | data->timezone = tz; | 207 | data->timezone = tz; |
198 | } | 208 | } |
199 | QString OEvent::timeZone()const { | 209 | QString OEvent::timeZone()const { |
210 | if (data->isAllDay ) return QString::fromLatin1("UTC"); | ||
200 | return data->timezone; | 211 | return data->timezone; |
201 | } | 212 | } |
202 | bool OEvent::match( const QRegExp& )const { | 213 | bool OEvent::match( const QRegExp& )const { |
203 | // FIXME | 214 | // FIXME |
204 | return false; | 215 | return false; |
205 | } | 216 | } |
206 | QString OEvent::toRichText()const { | 217 | QString OEvent::toRichText()const { |
207 | // FIXME | 218 | // FIXME |
208 | return "OEvent test"; | 219 | return "OEvent test"; |
209 | } | 220 | } |
210 | QString OEvent::toShortText()const { | 221 | QString OEvent::toShortText()const { |
211 | return "OEvent shotText"; | 222 | return "OEvent shotText"; |
212 | } | 223 | } |
213 | QString OEvent::type()const { | 224 | QString OEvent::type()const { |
214 | return QString::fromLatin1("OEvent"); | 225 | return QString::fromLatin1("OEvent"); |
215 | } | 226 | } |
216 | QString OEvent::recordField( int /*id */ )const { | 227 | QString OEvent::recordField( int /*id */ )const { |
217 | return QString::null; | 228 | return QString::null; |
218 | } | 229 | } |
219 | int OEvent::rtti() { | 230 | int OEvent::rtti() { |
220 | return OPimResolver::DateBook; | 231 | return OPimResolver::DateBook; |
221 | } | 232 | } |
222 | bool OEvent::loadFromStream( QDataStream& ) { | 233 | bool OEvent::loadFromStream( QDataStream& ) { |
223 | return true; | 234 | return true; |
224 | } | 235 | } |
225 | bool OEvent::saveToStream( QDataStream& )const { | 236 | bool OEvent::saveToStream( QDataStream& )const { |
226 | return true; | 237 | return true; |
227 | } | 238 | } |
228 | void OEvent::changeOrModify() { | 239 | void OEvent::changeOrModify() { |
229 | if ( data->count != 1 ) { | 240 | if ( data->count != 1 ) { |
230 | data->deref(); | 241 | data->deref(); |
231 | Data* d2 = new Data; | 242 | Data* d2 = new Data; |
232 | d2->description = data->description; | 243 | d2->description = data->description; |
233 | d2->location = data->location; | 244 | d2->location = data->location; |
234 | d2->manager = data->manager; | 245 | d2->manager = data->manager; |
235 | d2->recur = data->recur; | 246 | d2->recur = data->recur; |
236 | d2->note = data->note; | 247 | d2->note = data->note; |
237 | d2->created = data->created; | 248 | d2->created = data->created; |
238 | d2->start = data->start; | 249 | d2->start = data->start; |
239 | d2->end = data->end; | 250 | d2->end = data->end; |
240 | d2->isAllDay = data->isAllDay; | 251 | d2->isAllDay = data->isAllDay; |
241 | d2->timezone = data->timezone; | 252 | d2->timezone = data->timezone; |
253 | d2->parent = data->parent; | ||
254 | d2->child = data->child; | ||
255 | |||
256 | if (d2->child ) | ||
257 | d2->child->detach(); | ||
242 | 258 | ||
243 | data = d2; | 259 | data = d2; |
244 | } | 260 | } |
245 | } | 261 | } |
246 | void OEvent::deref() { | 262 | void OEvent::deref() { |
247 | if ( data->deref() ) { | 263 | if ( data->deref() ) { |
248 | delete data; | 264 | delete data; |
249 | data = 0; | 265 | data = 0; |
250 | } | 266 | } |
251 | } | 267 | } |
252 | // FIXME | 268 | // FIXME |
253 | QMap<int, QString> OEvent::toMap()const { | 269 | QMap<int, QString> OEvent::toMap()const { |
254 | return QMap<int, QString>(); | 270 | return QMap<int, QString>(); |
255 | } | 271 | } |
256 | QMap<QString, QString> OEvent::toExtraMap()const { | 272 | QMap<QString, QString> OEvent::toExtraMap()const { |
257 | return QMap<QString, QString>(); | 273 | return QMap<QString, QString>(); |
258 | } | 274 | } |
275 | int OEvent::parent()const { | ||
276 | return data->parent; | ||
277 | } | ||
278 | void OEvent::setParent( int uid ) { | ||
279 | changeOrModify(); | ||
280 | data->parent = uid; | ||
281 | } | ||
282 | QArray<int> OEvent::children() const{ | ||
283 | if (!data->child) return QArray<int>(); | ||
284 | else | ||
285 | return data->child->copy(); | ||
286 | } | ||
287 | void OEvent::setChildren( const QArray<int>& arr ) { | ||
288 | changeOrModify(); | ||
289 | if (data->child) delete data->child; | ||
259 | 290 | ||
260 | 291 | data->child = new QArray<int>( arr ); | |
292 | data->child->detach(); | ||
293 | } | ||
294 | void OEvent::addChild( int uid ) { | ||
295 | changeOrModify(); | ||
296 | if (!data->child ) { | ||
297 | data->child = new QArray<int>(1); | ||
298 | (*data->child)[0] = uid; | ||
299 | }else{ | ||
300 | int count = data->child->count(); | ||
301 | data->child->resize( count + 1 ); | ||
302 | (*data->child)[count] = uid; | ||
303 | } | ||
304 | } | ||
305 | void OEvent::removeChild( int uid ) { | ||
306 | if (!data->child || !data->child->contains( uid ) ) return; | ||
307 | changeOrModify(); | ||
308 | QArray<int> newAr( data->child->count() - 1 ); | ||
309 | int j = 0; | ||
310 | uint count = data->child->count(); | ||
311 | for ( uint i = 0; i < count; i++ ) { | ||
312 | if ( (*data->child)[i] != uid ) { | ||
313 | newAr[j] = (*data->child)[i]; | ||
314 | j++; | ||
315 | } | ||
316 | } | ||
317 | (*data->child) = newAr; | ||
318 | } | ||
261 | struct OEffectiveEvent::Data : public QShared { | 319 | struct OEffectiveEvent::Data : public QShared { |
262 | Data() : QShared() { | 320 | Data() : QShared() { |
263 | } | 321 | } |
264 | OEvent event; | 322 | OEvent event; |
265 | QDate date; | 323 | QDate date; |
266 | QTime start, end; | 324 | QTime start, end; |
267 | QDate startDate, endDate; | 325 | QDate startDate, endDate; |
268 | bool dates : 1; | 326 | bool dates : 1; |
269 | }; | 327 | }; |
270 | 328 | ||
271 | OEffectiveEvent::OEffectiveEvent() { | 329 | OEffectiveEvent::OEffectiveEvent() { |
272 | data = new Data; | 330 | data = new Data; |
273 | data->date = QDate::currentDate(); | 331 | data->date = QDate::currentDate(); |
274 | data->start = data->end = QTime::currentTime(); | 332 | data->start = data->end = QTime::currentTime(); |
275 | data->dates = false; | 333 | data->dates = false; |
276 | } | 334 | } |
277 | OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, | 335 | OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, |
278 | Position pos ) { | 336 | Position pos ) { |
279 | data = new Data; | 337 | data = new Data; |
280 | data->event = ev; | 338 | data->event = ev; |
281 | data->date = startDate; | 339 | data->date = startDate; |
282 | if ( pos & Start ) | 340 | if ( pos & Start ) |
283 | data->start = ev.startDateTime().time(); | 341 | data->start = ev.startDateTime().time(); |
284 | else | 342 | else |
285 | data->start = QTime( 0, 0, 0 ); | 343 | data->start = QTime( 0, 0, 0 ); |
286 | 344 | ||
287 | if ( pos & End ) | 345 | if ( pos & End ) |
288 | data->end = ev.endDateTime().time(); | 346 | data->end = ev.endDateTime().time(); |
289 | else | 347 | else |
290 | data->end = QTime( 23, 59, 59 ); | 348 | data->end = QTime( 23, 59, 59 ); |
291 | 349 | ||
292 | data->dates = false; | 350 | data->dates = false; |
293 | } | 351 | } |
294 | OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { | 352 | OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { |
295 | data = ev.data; | 353 | data = ev.data; |
296 | data->ref(); | 354 | data->ref(); |
297 | } | 355 | } |
298 | OEffectiveEvent::~OEffectiveEvent() { | 356 | OEffectiveEvent::~OEffectiveEvent() { |
299 | if ( data->deref() ) { | 357 | if ( data->deref() ) { |
300 | delete data; | 358 | delete data; |
301 | data = 0; | 359 | data = 0; |
302 | } | 360 | } |
303 | } | 361 | } |
304 | OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { | 362 | OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { |
305 | if ( *this == ev ) return *this; | 363 | if ( *this == ev ) return *this; |
306 | 364 | ||
307 | ev.data->ref(); | 365 | ev.data->ref(); |
308 | deref(); | 366 | deref(); |
309 | data = ev.data; | 367 | data = ev.data; |
310 | 368 | ||
311 | return *this; | 369 | return *this; |
312 | } | 370 | } |
313 | 371 | ||
314 | void OEffectiveEvent::setStartTime( const QTime& ti) { | 372 | void OEffectiveEvent::setStartTime( const QTime& ti) { |
315 | changeOrModify(); | 373 | changeOrModify(); |
316 | data->start = ti; | 374 | data->start = ti; |
317 | } | 375 | } |
318 | void OEffectiveEvent::setEndTime( const QTime& en) { | 376 | void OEffectiveEvent::setEndTime( const QTime& en) { |
319 | changeOrModify(); | 377 | changeOrModify(); |
320 | data->end = en; | 378 | data->end = en; |
321 | } | 379 | } |
322 | void OEffectiveEvent::setEvent( const OEvent& ev) { | 380 | void OEffectiveEvent::setEvent( const OEvent& ev) { |
323 | changeOrModify(); | 381 | changeOrModify(); |
324 | data->event = ev; | 382 | data->event = ev; |
325 | } | 383 | } |
326 | void OEffectiveEvent::setDate( const QDate& da) { | 384 | void OEffectiveEvent::setDate( const QDate& da) { |
327 | changeOrModify(); | 385 | changeOrModify(); |
328 | data->date = da; | 386 | data->date = da; |
329 | } | 387 | } |
330 | void OEffectiveEvent::setEffectiveDates( const QDate& from, | 388 | void OEffectiveEvent::setEffectiveDates( const QDate& from, |
331 | const QDate& to ) { | 389 | const QDate& to ) { |
332 | if (!from.isValid() ) { | 390 | if (!from.isValid() ) { |
333 | data->dates = false; | 391 | data->dates = false; |
334 | return; | 392 | return; |
335 | } | 393 | } |
336 | 394 | ||
337 | data->startDate = from; | 395 | data->startDate = from; |
338 | data->endDate = to; | 396 | data->endDate = to; |
339 | } | 397 | } |
340 | QString OEffectiveEvent::description()const { | 398 | QString OEffectiveEvent::description()const { |
341 | return data->event.description(); | 399 | return data->event.description(); |
342 | } | 400 | } |
343 | QString OEffectiveEvent::location()const { | 401 | QString OEffectiveEvent::location()const { |
344 | return data->event.location(); | 402 | return data->event.location(); |
345 | } | 403 | } |
346 | QString OEffectiveEvent::note()const { | 404 | QString OEffectiveEvent::note()const { |
347 | return data->event.note(); | 405 | return data->event.note(); |
348 | } | 406 | } |
349 | OEvent OEffectiveEvent::event()const { | 407 | OEvent OEffectiveEvent::event()const { |
350 | return data->event; | 408 | return data->event; |
351 | } | 409 | } |
352 | QTime OEffectiveEvent::startTime()const { | 410 | QTime OEffectiveEvent::startTime()const { |
353 | return data->start; | 411 | return data->start; |
354 | } | 412 | } |
355 | QTime OEffectiveEvent::endTime()const { | 413 | QTime OEffectiveEvent::endTime()const { |
356 | return data->end; | 414 | return data->end; |
357 | } | 415 | } |
358 | QDate OEffectiveEvent::date()const { | 416 | QDate OEffectiveEvent::date()const { |
359 | return data->date; | 417 | return data->date; |
360 | } | 418 | } |
361 | int OEffectiveEvent::length()const { | 419 | int OEffectiveEvent::length()const { |
362 | return (data->end.hour() * 60 - data->start.hour() * 60) | 420 | return (data->end.hour() * 60 - data->start.hour() * 60) |
363 | + QABS(data->start.minute() - data->end.minute() ); | 421 | + QABS(data->start.minute() - data->end.minute() ); |
364 | } | 422 | } |
365 | int OEffectiveEvent::size()const { | 423 | int OEffectiveEvent::size()const { |
366 | return ( data->end.hour() - data->start.hour() ) * 3600 | 424 | return ( data->end.hour() - data->start.hour() ) * 3600 |
367 | + (data->end.minute() - data->start.minute() * 60 | 425 | + (data->end.minute() - data->start.minute() * 60 |
368 | + data->end.second() - data->start.second() ); | 426 | + data->end.second() - data->start.second() ); |
369 | } | 427 | } |
370 | QDate OEffectiveEvent::startDate()const { | 428 | QDate OEffectiveEvent::startDate()const { |
371 | if ( data->dates ) | 429 | if ( data->dates ) |
372 | return data->startDate; | 430 | return data->startDate; |
373 | else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer | 431 | else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer |
374 | return data->date; | 432 | return data->date; |
375 | else | 433 | else |
376 | return data->event.startDateTime().date(); | 434 | return data->event.startDateTime().date(); |
377 | } | 435 | } |
378 | QDate OEffectiveEvent::endDate()const { | 436 | QDate OEffectiveEvent::endDate()const { |
379 | if ( data->dates ) | 437 | if ( data->dates ) |
380 | return data->endDate; | 438 | return data->endDate; |
381 | else if ( data->event.hasRecurrence() ) | 439 | else if ( data->event.hasRecurrence() ) |
382 | return data->date; | 440 | return data->date; |
383 | else | 441 | else |
384 | return data->event.endDateTime().date(); | 442 | return data->event.endDateTime().date(); |
385 | } | 443 | } |
386 | void OEffectiveEvent::deref() { | 444 | void OEffectiveEvent::deref() { |
387 | if ( data->deref() ) { | 445 | if ( data->deref() ) { |
388 | delete data; | 446 | delete data; |
389 | data = 0; | 447 | data = 0; |
390 | } | 448 | } |
391 | } | 449 | } |
392 | void OEffectiveEvent::changeOrModify() { | 450 | void OEffectiveEvent::changeOrModify() { |
393 | if ( data->count != 1 ) { | 451 | if ( data->count != 1 ) { |
394 | data->deref(); | 452 | data->deref(); |
395 | Data* d2 = new Data; | 453 | Data* d2 = new Data; |
396 | d2->event = data->event; | 454 | d2->event = data->event; |
397 | d2->date = data->date; | 455 | d2->date = data->date; |
398 | d2->start = data->start; | 456 | d2->start = data->start; |
399 | d2->end = data->end; | 457 | d2->end = data->end; |
400 | d2->startDate = data->startDate; | 458 | d2->startDate = data->startDate; |
401 | d2->endDate = data->endDate; | 459 | d2->endDate = data->endDate; |
402 | d2->dates = data->dates; | 460 | d2->dates = data->dates; |
403 | data = d2; | 461 | data = d2; |
404 | } | 462 | } |
405 | } | 463 | } |
406 | bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{ | 464 | bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{ |
407 | if ( data->date < e.date() ) | 465 | if ( data->date < e.date() ) |
408 | return TRUE; | 466 | return TRUE; |
409 | if ( data->date == e.date() ) | 467 | if ( data->date == e.date() ) |
410 | return ( startTime() < e.startTime() ); | 468 | return ( startTime() < e.startTime() ); |
411 | else | 469 | else |
412 | return FALSE; | 470 | return FALSE; |
413 | } | 471 | } |
414 | bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const{ | 472 | bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const{ |
415 | return (data->date <= e.date() ); | 473 | return (data->date <= e.date() ); |
416 | } | 474 | } |
417 | bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const { | 475 | bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const { |
418 | return ( date() == e.date() | 476 | return ( date() == e.date() |
419 | && startTime() == e.startTime() | 477 | && startTime() == e.startTime() |
420 | && endTime()== e.endTime() | 478 | && endTime()== e.endTime() |
421 | && event() == e.event() ); | 479 | && event() == e.event() ); |
422 | } | 480 | } |
423 | bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const { | 481 | bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const { |
424 | return !(*this == e ); | 482 | return !(*this == e ); |
425 | } | 483 | } |
426 | bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const { | 484 | bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const { |
427 | return !(*this <= e ); | 485 | return !(*this <= e ); |
428 | } | 486 | } |
429 | bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const { | 487 | bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const { |
430 | return !(*this < e); | 488 | return !(*this < e); |
431 | } | 489 | } |
diff --git a/libopie/pim/oevent.h b/libopie/pim/oevent.h index c718e2e..585515c 100644 --- a/libopie/pim/oevent.h +++ b/libopie/pim/oevent.h | |||
@@ -1,198 +1,206 @@ | |||
1 | // CONTAINS GPLed code of TT | 1 | // CONTAINS GPLed code of TT |
2 | 2 | ||
3 | #ifndef OPIE_PIM_EVENT_H | 3 | #ifndef OPIE_PIM_EVENT_H |
4 | #define OPIE_PIM_EVENT_H | 4 | #define OPIE_PIM_EVENT_H |
5 | 5 | ||
6 | #include <qstring.h> | 6 | #include <qstring.h> |
7 | #include <qdatetime.h> | 7 | #include <qdatetime.h> |
8 | #include <qvaluelist.h> | 8 | #include <qvaluelist.h> |
9 | 9 | ||
10 | #include <qpe/recordfields.h> | 10 | #include <qpe/recordfields.h> |
11 | #include <qpe/palmtopuidgen.h> | 11 | #include <qpe/palmtopuidgen.h> |
12 | 12 | ||
13 | #include "otimezone.h" | 13 | #include "otimezone.h" |
14 | #include "opimrecord.h" | 14 | #include "opimrecord.h" |
15 | 15 | ||
16 | struct OCalendarHelper { | 16 | struct OCalendarHelper { |
17 | /** calculate the week number of the date */ | 17 | /** calculate the week number of the date */ |
18 | static int week( const QDate& ); | 18 | static int week( const QDate& ); |
19 | /** calculate the occurence of week days since the start of the month */ | 19 | /** calculate the occurence of week days since the start of the month */ |
20 | static int ocurrence( const QDate& ); | 20 | static int ocurrence( const QDate& ); |
21 | 21 | ||
22 | // returns the dayOfWeek for the *first* day it finds (ignores | 22 | // returns the dayOfWeek for the *first* day it finds (ignores |
23 | // any further days!). Returns 1 (Monday) if there isn't any day found | 23 | // any further days!). Returns 1 (Monday) if there isn't any day found |
24 | static int dayOfWeek( char day ); | 24 | static int dayOfWeek( char day ); |
25 | 25 | ||
26 | /** returns the diff of month */ | 26 | /** returns the diff of month */ |
27 | static int monthDiff( const QDate& first, const QDate& second ); | 27 | static int monthDiff( const QDate& first, const QDate& second ); |
28 | 28 | ||
29 | }; | 29 | }; |
30 | 30 | ||
31 | class OPimNotifyManager; | 31 | class OPimNotifyManager; |
32 | class ORecur; | 32 | class ORecur; |
33 | class OEvent : public OPimRecord { | 33 | class OEvent : public OPimRecord { |
34 | public: | 34 | public: |
35 | typedef QValueList<OEvent> ValueList; | 35 | typedef QValueList<OEvent> ValueList; |
36 | enum RecordFields { | 36 | enum RecordFields { |
37 | Uid = Qtopia::UID_ID, | 37 | Uid = Qtopia::UID_ID, |
38 | Category = Qtopia::CATEGORY_ID, | 38 | Category = Qtopia::CATEGORY_ID, |
39 | Description, | 39 | Description, |
40 | Location, | 40 | Location, |
41 | Alarm, | 41 | Alarm, |
42 | Reminder, | 42 | Reminder, |
43 | Recurrence, | 43 | Recurrence, |
44 | Note, | 44 | Note, |
45 | Created, | 45 | Created, |
46 | StartDate, | 46 | StartDate, |
47 | EndDate, | 47 | EndDate, |
48 | AllDay, | 48 | AllDay, |
49 | TimeZone | 49 | TimeZone |
50 | }; | 50 | }; |
51 | 51 | ||
52 | OEvent(int uid = 0); | 52 | OEvent(int uid = 0); |
53 | OEvent( const OEvent& ); | 53 | OEvent( const OEvent& ); |
54 | ~OEvent(); | 54 | ~OEvent(); |
55 | OEvent &operator=( const OEvent& ); | 55 | OEvent &operator=( const OEvent& ); |
56 | 56 | ||
57 | QString description()const; | 57 | QString description()const; |
58 | void setDescription( const QString& description ); | 58 | void setDescription( const QString& description ); |
59 | 59 | ||
60 | QString location()const; | 60 | QString location()const; |
61 | void setLocation( const QString& loc ); | 61 | void setLocation( const QString& loc ); |
62 | 62 | ||
63 | bool hasNotifiers()const; | 63 | bool hasNotifiers()const; |
64 | OPimNotifyManager ¬ifiers(); | 64 | OPimNotifyManager ¬ifiers()const; |
65 | 65 | ||
66 | ORecur recurrence()const; | 66 | ORecur recurrence()const; |
67 | void setRecurrence( const ORecur& ); | 67 | void setRecurrence( const ORecur& ); |
68 | bool hasRecurrence()const; | 68 | bool hasRecurrence()const; |
69 | 69 | ||
70 | QString note()const; | 70 | QString note()const; |
71 | void setNote( const QString& note ); | 71 | void setNote( const QString& note ); |
72 | 72 | ||
73 | 73 | ||
74 | QDateTime createdDateTime()const; | 74 | QDateTime createdDateTime()const; |
75 | void setCreatedDateTime( const QDateTime& dt); | 75 | void setCreatedDateTime( const QDateTime& dt); |
76 | 76 | ||
77 | /** set the date to dt. dt is the QDateTime in localtime */ | 77 | /** set the date to dt. dt is the QDateTime in localtime */ |
78 | void setStartDateTime( const QDateTime& ); | 78 | void setStartDateTime( const QDateTime& ); |
79 | /** returns the datetime in the local timeZone */ | 79 | /** returns the datetime in the local timeZone */ |
80 | QDateTime startDateTime()const; | 80 | QDateTime startDateTime()const; |
81 | 81 | ||
82 | /** returns the start datetime in the current zone */ | 82 | /** returns the start datetime in the current zone */ |
83 | QDateTime startDateTimeInZone()const; | 83 | QDateTime startDateTimeInZone()const; |
84 | 84 | ||
85 | /** in current timezone */ | 85 | /** in current timezone */ |
86 | void setEndDateTime( const QDateTime& ); | 86 | void setEndDateTime( const QDateTime& ); |
87 | /** in current timezone */ | 87 | /** in current timezone */ |
88 | QDateTime endDateTime()const; | 88 | QDateTime endDateTime()const; |
89 | QDateTime endDateTimeInZone()const; | 89 | QDateTime endDateTimeInZone()const; |
90 | 90 | ||
91 | bool isMultipleDay()const; | 91 | bool isMultipleDay()const; |
92 | bool isAllDay()const; | 92 | bool isAllDay()const; |
93 | void setAllDay( bool isAllDay ); | 93 | void setAllDay( bool isAllDay ); |
94 | 94 | ||
95 | /* pin this event to a timezone! FIXME */ | 95 | /* pin this event to a timezone! FIXME */ |
96 | void setTimeZone( const QString& timeZone ); | 96 | void setTimeZone( const QString& timeZone ); |
97 | QString timeZone()const; | 97 | QString timeZone()const; |
98 | 98 | ||
99 | 99 | ||
100 | bool match( const QRegExp& )const; | 100 | bool match( const QRegExp& )const; |
101 | 101 | ||
102 | /** For exception to recurrence here is a list of children... */ | ||
103 | QArray<int> children()const; | ||
104 | void setChildren( const QArray<int>& ); | ||
105 | void addChild( int uid ); | ||
106 | void removeChild( int uid ); | ||
102 | 107 | ||
108 | /** return the parent OEvent */ | ||
109 | int parent()const; | ||
110 | void setParent( int uid ); | ||
103 | 111 | ||
104 | 112 | ||
105 | /* needed reimp */ | 113 | /* needed reimp */ |
106 | QString toRichText()const; | 114 | QString toRichText()const; |
107 | QString toShortText()const; | 115 | QString toShortText()const; |
108 | QString type()const; | 116 | QString type()const; |
109 | 117 | ||
110 | QMap<int, QString> toMap()const; | 118 | QMap<int, QString> toMap()const; |
111 | QMap<QString, QString> toExtraMap()const; | 119 | QMap<QString, QString> toExtraMap()const; |
112 | QString recordField(int )const; | 120 | QString recordField(int )const; |
113 | 121 | ||
114 | static int rtti(); | 122 | static int rtti(); |
115 | 123 | ||
116 | bool loadFromStream( QDataStream& ); | 124 | bool loadFromStream( QDataStream& ); |
117 | bool saveToStream( QDataStream& )const; | 125 | bool saveToStream( QDataStream& )const; |
118 | 126 | ||
119 | /* bool operator==( const OEvent& ); | 127 | /* bool operator==( const OEvent& ); |
120 | bool operator!=( const OEvent& ); | 128 | bool operator!=( const OEvent& ); |
121 | bool operator<( const OEvent& ); | 129 | bool operator<( const OEvent& ); |
122 | bool operator<=( const OEvent& ); | 130 | bool operator<=( const OEvent& ); |
123 | bool operator>( const OEvent& ); | 131 | bool operator>( const OEvent& ); |
124 | bool operator>=(const OEvent& ); | 132 | bool operator>=(const OEvent& ); |
125 | */ | 133 | */ |
126 | private: | 134 | private: |
127 | inline void changeOrModify(); | 135 | inline void changeOrModify(); |
128 | void deref(); | 136 | void deref(); |
129 | struct Data; | 137 | struct Data; |
130 | Data* data; | 138 | Data* data; |
131 | class Private; | 139 | class Private; |
132 | Private* priv; | 140 | Private* priv; |
133 | 141 | ||
134 | }; | 142 | }; |
135 | 143 | ||
136 | /** | 144 | /** |
137 | * AN Event can span through multiple days. We split up a multiday eve | 145 | * AN Event can span through multiple days. We split up a multiday eve |
138 | */ | 146 | */ |
139 | 147 | ||
140 | class OEffectiveEvent { | 148 | class OEffectiveEvent { |
141 | public: | 149 | public: |
142 | typedef QValueList<OEffectiveEvent> ValueList; | 150 | typedef QValueList<OEffectiveEvent> ValueList; |
143 | enum Position { MidWay, Start, End, StartEnd }; | 151 | enum Position { MidWay, Start, End, StartEnd }; |
144 | // If we calculate the effective event of a multi-day event | 152 | // If we calculate the effective event of a multi-day event |
145 | // we have to figure out whether we are at the first day, | 153 | // we have to figure out whether we are at the first day, |
146 | // at the end, or anywhere else ("middle"). This is important | 154 | // at the end, or anywhere else ("middle"). This is important |
147 | // for the start/end times (00:00/23:59) | 155 | // for the start/end times (00:00/23:59) |
148 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- | 156 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- |
149 | // day event | 157 | // day event |
150 | // Start: start time -> 23:59 | 158 | // Start: start time -> 23:59 |
151 | // End: 00:00 -> end time | 159 | // End: 00:00 -> end time |
152 | // Start | End == StartEnd: for single-day events (default) | 160 | // Start | End == StartEnd: for single-day events (default) |
153 | // here we draw start time -> end time | 161 | // here we draw start time -> end time |
154 | OEffectiveEvent(); | 162 | OEffectiveEvent(); |
155 | OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); | 163 | OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); |
156 | OEffectiveEvent( const OEffectiveEvent& ); | 164 | OEffectiveEvent( const OEffectiveEvent& ); |
157 | OEffectiveEvent &operator=(const OEffectiveEvent& ); | 165 | OEffectiveEvent &operator=(const OEffectiveEvent& ); |
158 | ~OEffectiveEvent(); | 166 | ~OEffectiveEvent(); |
159 | 167 | ||
160 | void setStartTime( const QTime& ); | 168 | void setStartTime( const QTime& ); |
161 | void setEndTime( const QTime& ); | 169 | void setEndTime( const QTime& ); |
162 | void setEvent( const OEvent& ); | 170 | void setEvent( const OEvent& ); |
163 | void setDate( const QDate& ); | 171 | void setDate( const QDate& ); |
164 | 172 | ||
165 | void setEffectiveDates( const QDate& from, const QDate& to ); | 173 | void setEffectiveDates( const QDate& from, const QDate& to ); |
166 | 174 | ||
167 | QString description()const; | 175 | QString description()const; |
168 | QString location()const; | 176 | QString location()const; |
169 | QString note()const; | 177 | QString note()const; |
170 | OEvent event()const; | 178 | OEvent event()const; |
171 | QTime startTime()const; | 179 | QTime startTime()const; |
172 | QTime endTime()const; | 180 | QTime endTime()const; |
173 | QDate date()const; | 181 | QDate date()const; |
174 | 182 | ||
175 | /* return the length in hours */ | 183 | /* return the length in hours */ |
176 | int length()const; | 184 | int length()const; |
177 | int size()const; | 185 | int size()const; |
178 | 186 | ||
179 | QDate startDate()const; | 187 | QDate startDate()const; |
180 | QDate endDate()const; | 188 | QDate endDate()const; |
181 | 189 | ||
182 | bool operator<( const OEffectiveEvent &e ) const; | 190 | bool operator<( const OEffectiveEvent &e ) const; |
183 | bool operator<=( const OEffectiveEvent &e ) const; | 191 | bool operator<=( const OEffectiveEvent &e ) const; |
184 | bool operator==( const OEffectiveEvent &e ) const; | 192 | bool operator==( const OEffectiveEvent &e ) const; |
185 | bool operator!=( const OEffectiveEvent &e ) const; | 193 | bool operator!=( const OEffectiveEvent &e ) const; |
186 | bool operator>( const OEffectiveEvent &e ) const; | 194 | bool operator>( const OEffectiveEvent &e ) const; |
187 | bool operator>= ( const OEffectiveEvent &e ) const; | 195 | bool operator>= ( const OEffectiveEvent &e ) const; |
188 | 196 | ||
189 | private: | 197 | private: |
190 | void deref(); | 198 | void deref(); |
191 | inline void changeOrModify(); | 199 | inline void changeOrModify(); |
192 | class Private; | 200 | class Private; |
193 | Private* priv; | 201 | Private* priv; |
194 | struct Data; | 202 | struct Data; |
195 | Data* data; | 203 | Data* data; |
196 | 204 | ||
197 | }; | 205 | }; |
198 | #endif | 206 | #endif |
diff --git a/libopie/pim/orecur.cpp b/libopie/pim/orecur.cpp index e6a4787..e3b45b4 100644 --- a/libopie/pim/orecur.cpp +++ b/libopie/pim/orecur.cpp | |||
@@ -1,446 +1,510 @@ | |||
1 | #include <time.h> | ||
2 | |||
1 | #include <qshared.h> | 3 | #include <qshared.h> |
2 | 4 | ||
3 | #include <qtopia/timeconversion.h> | 5 | #include <qtopia/timeconversion.h> |
4 | 6 | ||
7 | #include "otimezone.h" | ||
5 | #include "orecur.h" | 8 | #include "orecur.h" |
6 | 9 | ||
7 | struct ORecur::Data : public QShared { | 10 | struct ORecur::Data : public QShared { |
8 | Data() : QShared() { | 11 | Data() : QShared() { |
9 | type = ORecur::NoRepeat; | 12 | type = ORecur::NoRepeat; |
10 | freq = -1; | 13 | freq = -1; |
11 | days = 0; | 14 | days = 0; |
12 | pos = 0; | 15 | pos = 0; |
13 | create = QDateTime::currentDateTime(); | 16 | create = QDateTime::currentDateTime(); |
14 | hasEnd = FALSE; | 17 | hasEnd = FALSE; |
15 | end = QDate::currentDate(); | 18 | end = QDate::currentDate(); |
16 | } | 19 | } |
17 | char days; // Q_UINT8 for 8 seven days;) | 20 | char days; // Q_UINT8 for 8 seven days;) |
18 | ORecur::RepeatType type; | 21 | ORecur::RepeatType type; |
19 | int freq; | 22 | int freq; |
20 | int pos; | 23 | int pos; |
21 | bool hasEnd : 1; | 24 | bool hasEnd : 1; |
22 | QDate end; | 25 | QDate end; |
23 | QDateTime create; | 26 | QDateTime create; |
24 | int rep; | 27 | int rep; |
25 | QString app; | 28 | QString app; |
26 | ExceptionList list; | 29 | ExceptionList list; |
27 | QDate start; | 30 | QDate start; |
28 | }; | 31 | }; |
29 | 32 | ||
30 | 33 | ||
31 | ORecur::ORecur() { | 34 | ORecur::ORecur() { |
32 | data = new Data; | 35 | data = new Data; |
33 | } | 36 | } |
34 | ORecur::ORecur( const ORecur& rec) | 37 | ORecur::ORecur( const ORecur& rec) |
35 | : data( rec.data ) | 38 | : data( rec.data ) |
36 | { | 39 | { |
37 | data->ref(); | 40 | data->ref(); |
38 | } | 41 | } |
39 | ORecur::~ORecur() { | 42 | ORecur::~ORecur() { |
40 | if ( data->deref() ) { | 43 | if ( data->deref() ) { |
41 | delete data; | 44 | delete data; |
42 | data = 0l; | 45 | data = 0l; |
43 | } | 46 | } |
44 | } | 47 | } |
45 | void ORecur::deref() { | 48 | void ORecur::deref() { |
46 | if ( data->deref() ) { | 49 | if ( data->deref() ) { |
47 | delete data; | 50 | delete data; |
48 | data = 0l; | 51 | data = 0l; |
49 | } | 52 | } |
50 | } | 53 | } |
51 | bool ORecur::operator==( const ORecur& )const { | 54 | bool ORecur::operator==( const ORecur& )const { |
52 | return false; | 55 | return false; |
53 | } | 56 | } |
54 | ORecur &ORecur::operator=( const ORecur& re) { | 57 | ORecur &ORecur::operator=( const ORecur& re) { |
55 | if ( *this == re ) return *this; | 58 | if ( *this == re ) return *this; |
56 | 59 | ||
57 | re.data->ref(); | 60 | re.data->ref(); |
58 | deref(); | 61 | deref(); |
59 | data = re.data; | 62 | data = re.data; |
60 | 63 | ||
61 | return *this; | 64 | return *this; |
62 | } | 65 | } |
63 | bool ORecur::doesRecur()const { | 66 | bool ORecur::doesRecur()const { |
64 | return !( type() == NoRepeat ); | 67 | return !( type() == NoRepeat ); |
65 | } | 68 | } |
66 | /* | 69 | /* |
67 | * we try to be smart here | 70 | * we try to be smart here |
68 | * | 71 | * |
69 | */ | 72 | */ |
70 | bool ORecur::doesRecur( const QDate& date ) { | 73 | bool ORecur::doesRecur( const QDate& date ) { |
71 | /* the day before the recurrance */ | 74 | /* the day before the recurrance */ |
72 | QDate da = date.addDays(-1); | 75 | QDate da = date.addDays(-1); |
73 | 76 | ||
74 | QDate recur; | 77 | QDate recur; |
75 | if (!nextOcurrence( da, recur ) ) | 78 | if (!nextOcurrence( da, recur ) ) |
76 | return false; | 79 | return false; |
77 | 80 | ||
78 | return (recur == date); | 81 | return (recur == date); |
79 | } | 82 | } |
80 | // FIXME unuglify! | 83 | // FIXME unuglify! |
81 | // GPL from Datebookdb.cpp | 84 | // GPL from Datebookdb.cpp |
82 | // FIXME exception list! | 85 | // FIXME exception list! |
83 | bool ORecur::nextOcurrence( const QDate& from, QDate& next ) { | 86 | bool ORecur::nextOcurrence( const QDate& from, QDate& next ) { |
87 | bool stillLooking; | ||
88 | stillLooking = p_nextOccurrence( from, next ); | ||
89 | while ( stillLooking && data->list.contains(next) ) | ||
90 | stillLooking = p_nextOccurrence( next.addDays(1), next ); | ||
91 | |||
92 | return stillLooking; | ||
93 | } | ||
94 | bool ORecur::p_nextOccurrence( const QDate& from, QDate& next ) { | ||
84 | 95 | ||
85 | // easy checks, first are we too far in the future or too far in the past? | 96 | // easy checks, first are we too far in the future or too far in the past? |
86 | QDate tmpDate; | 97 | QDate tmpDate; |
87 | int freq = frequency(); | 98 | int freq = frequency(); |
88 | int diff, diff2, a; | 99 | int diff, diff2, a; |
89 | int iday, imonth, iyear; | 100 | int iday, imonth, iyear; |
90 | int dayOfWeek = 0; | 101 | int dayOfWeek = 0; |
91 | int firstOfWeek = 0; | 102 | int firstOfWeek = 0; |
92 | int weekOfMonth; | 103 | int weekOfMonth; |
93 | 104 | ||
94 | 105 | ||
95 | if (hasEndDate() && endDate() < from) | 106 | if (hasEndDate() && endDate() < from) |
96 | return FALSE; | 107 | return FALSE; |
97 | 108 | ||
98 | if (start() >= from) { | 109 | if (start() >= from ) { |
99 | next = start(); | 110 | next = start(); |
100 | return TRUE; | 111 | return TRUE; |
101 | } | 112 | } |
102 | 113 | ||
103 | switch ( type() ) { | 114 | switch ( type() ) { |
104 | case Weekly: | 115 | case Weekly: |
105 | /* weekly is just daily by 7 */ | 116 | /* weekly is just daily by 7 */ |
106 | /* first convert the repeatPattern.Days() mask to the next | 117 | /* first convert the repeatPattern.Days() mask to the next |
107 | day of week valid after from */ | 118 | day of week valid after from */ |
108 | dayOfWeek = from.dayOfWeek(); | 119 | dayOfWeek = from.dayOfWeek(); |
109 | dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ | 120 | dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ |
110 | 121 | ||
111 | /* this is done in case freq > 1 and from in week not | 122 | /* this is done in case freq > 1 and from in week not |
112 | for this round */ | 123 | for this round */ |
113 | // firstOfWeek = 0; this is already done at decl. | 124 | // firstOfWeek = 0; this is already done at decl. |
114 | while(!((1 << firstOfWeek) & days() )) | 125 | while(!((1 << firstOfWeek) & days() )) |
115 | firstOfWeek++; | 126 | firstOfWeek++; |
116 | 127 | ||
117 | /* there is at least one 'day', or there would be no event */ | 128 | /* there is at least one 'day', or there would be no event */ |
118 | while(!((1 << (dayOfWeek % 7)) & days() )) | 129 | while(!((1 << (dayOfWeek % 7)) & days() )) |
119 | dayOfWeek++; | 130 | dayOfWeek++; |
120 | 131 | ||
121 | dayOfWeek = dayOfWeek % 7; /* the actual day of week */ | 132 | dayOfWeek = dayOfWeek % 7; /* the actual day of week */ |
122 | dayOfWeek -= start().dayOfWeek() -1; | 133 | dayOfWeek -= start().dayOfWeek() -1; |
123 | 134 | ||
124 | firstOfWeek = firstOfWeek % 7; /* the actual first of week */ | 135 | firstOfWeek = firstOfWeek % 7; /* the actual first of week */ |
125 | firstOfWeek -= start().dayOfWeek() -1; | 136 | firstOfWeek -= start().dayOfWeek() -1; |
126 | 137 | ||
127 | // dayOfWeek may be negitive now | 138 | // dayOfWeek may be negitive now |
128 | // day of week is number of days to add to start day | 139 | // day of week is number of days to add to start day |
129 | 140 | ||
130 | freq *= 7; | 141 | freq *= 7; |
131 | // FALL-THROUGH !!!!! | 142 | // FALL-THROUGH !!!!! |
132 | case Daily: | 143 | case Daily: |
133 | // the add is for the possible fall through from weekly */ | 144 | // the add is for the possible fall through from weekly */ |
134 | if(start().addDays(dayOfWeek) > from) { | 145 | if(start().addDays(dayOfWeek) > from) { |
135 | /* first week exception */ | 146 | /* first week exception */ |
136 | next = QDate(start().addDays(dayOfWeek) ); | 147 | next = QDate(start().addDays(dayOfWeek) ); |
137 | if ((next > endDate()) | 148 | if ((next > endDate()) |
138 | && hasEndDate() ) | 149 | && hasEndDate() ) |
139 | return FALSE; | 150 | return FALSE; |
140 | return TRUE; | 151 | return TRUE; |
141 | } | 152 | } |
142 | /* if from is middle of a non-week */ | 153 | /* if from is middle of a non-week */ |
143 | 154 | ||
144 | diff = start().addDays(dayOfWeek).daysTo(from) % freq; | 155 | diff = start().addDays(dayOfWeek).daysTo(from) % freq; |
145 | diff2 = start().addDays(firstOfWeek).daysTo(from) % freq; | 156 | diff2 = start().addDays(firstOfWeek).daysTo(from) % freq; |
146 | 157 | ||
147 | if(diff != 0) | 158 | if(diff != 0) |
148 | diff = freq - diff; | 159 | diff = freq - diff; |
149 | if(diff2 != 0) | 160 | if(diff2 != 0) |
150 | diff2 = freq - diff2; | 161 | diff2 = freq - diff2; |
151 | diff = QMIN(diff, diff2); | 162 | diff = QMIN(diff, diff2); |
152 | 163 | ||
153 | next = QDate(from.addDays(diff)); | 164 | next = QDate(from.addDays(diff)); |
154 | if ( (next > endDate()) | 165 | if ( (next > endDate()) |
155 | && hasEndDate() ) | 166 | && hasEndDate() ) |
156 | return FALSE; | 167 | return FALSE; |
157 | return TRUE; | 168 | return TRUE; |
158 | case MonthlyDay: | 169 | case MonthlyDay: |
159 | iday = from.day(); | 170 | iday = from.day(); |
160 | iyear = from.year(); | 171 | iyear = from.year(); |
161 | imonth = from.month(); | 172 | imonth = from.month(); |
162 | /* find equivelent day of month for this month */ | 173 | /* find equivelent day of month for this month */ |
163 | dayOfWeek = start().dayOfWeek(); | 174 | dayOfWeek = start().dayOfWeek(); |
164 | weekOfMonth = (start().day() - 1) / 7; | 175 | weekOfMonth = (start().day() - 1) / 7; |
165 | 176 | ||
166 | /* work out when the next valid month is */ | 177 | /* work out when the next valid month is */ |
167 | a = from.year() - start().year(); | 178 | a = from.year() - start().year(); |
168 | a *= 12; | 179 | a *= 12; |
169 | a = a + (imonth - start().month()); | 180 | a = a + (imonth - start().month()); |
170 | /* a is e.start()monthsFrom(from); */ | 181 | /* a is e.start()monthsFrom(from); */ |
171 | if(a % freq) { | 182 | if(a % freq) { |
172 | a = freq - (a % freq); | 183 | a = freq - (a % freq); |
173 | imonth = from.month() + a; | 184 | imonth = from.month() + a; |
174 | if (imonth > 12) { | 185 | if (imonth > 12) { |
175 | imonth--; | 186 | imonth--; |
176 | iyear += imonth / 12; | 187 | iyear += imonth / 12; |
177 | imonth = imonth % 12; | 188 | imonth = imonth % 12; |
178 | imonth++; | 189 | imonth++; |
179 | } | 190 | } |
180 | } | 191 | } |
181 | /* imonth is now the first month after or on | 192 | /* imonth is now the first month after or on |
182 | from that matches the frequency given */ | 193 | from that matches the frequency given */ |
183 | 194 | ||
184 | /* find for this month */ | 195 | /* find for this month */ |
185 | tmpDate = QDate( iyear, imonth, 1 ); | 196 | tmpDate = QDate( iyear, imonth, 1 ); |
186 | 197 | ||
187 | iday = 1; | 198 | iday = 1; |
188 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 199 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
189 | iday += 7 * weekOfMonth; | 200 | iday += 7 * weekOfMonth; |
190 | while (iday > tmpDate.daysInMonth()) { | 201 | while (iday > tmpDate.daysInMonth()) { |
191 | imonth += freq; | 202 | imonth += freq; |
192 | if (imonth > 12) { | 203 | if (imonth > 12) { |
193 | imonth--; | 204 | imonth--; |
194 | iyear += imonth / 12; | 205 | iyear += imonth / 12; |
195 | imonth = imonth % 12; | 206 | imonth = imonth % 12; |
196 | imonth++; | 207 | imonth++; |
197 | } | 208 | } |
198 | tmpDate = QDate( iyear, imonth, 1 ); | 209 | tmpDate = QDate( iyear, imonth, 1 ); |
199 | /* these loops could go for a while, check end case now */ | 210 | /* these loops could go for a while, check end case now */ |
200 | if ((tmpDate > endDate()) && hasEndDate() ) | 211 | if ((tmpDate > endDate()) && hasEndDate() ) |
201 | return FALSE; | 212 | return FALSE; |
202 | iday = 1; | 213 | iday = 1; |
203 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 214 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
204 | iday += 7 * weekOfMonth; | 215 | iday += 7 * weekOfMonth; |
205 | } | 216 | } |
206 | tmpDate = QDate(iyear, imonth, iday); | 217 | tmpDate = QDate(iyear, imonth, iday); |
207 | 218 | ||
208 | if (tmpDate >= from) { | 219 | if (tmpDate >= from) { |
209 | next = tmpDate; | 220 | next = tmpDate; |
210 | if ((next > endDate() ) && hasEndDate() ) | 221 | if ((next > endDate() ) && hasEndDate() ) |
211 | return FALSE; | 222 | return FALSE; |
212 | return TRUE; | 223 | return TRUE; |
213 | } | 224 | } |
214 | 225 | ||
215 | /* need to find the next iteration */ | 226 | /* need to find the next iteration */ |
216 | do { | 227 | do { |
217 | imonth += freq; | 228 | imonth += freq; |
218 | if (imonth > 12) { | 229 | if (imonth > 12) { |
219 | imonth--; | 230 | imonth--; |
220 | iyear += imonth / 12; | 231 | iyear += imonth / 12; |
221 | imonth = imonth % 12; | 232 | imonth = imonth % 12; |
222 | imonth++; | 233 | imonth++; |
223 | } | 234 | } |
224 | tmpDate = QDate( iyear, imonth, 1 ); | 235 | tmpDate = QDate( iyear, imonth, 1 ); |
225 | /* these loops could go for a while, check end case now */ | 236 | /* these loops could go for a while, check end case now */ |
226 | if ((tmpDate > endDate()) && hasEndDate() ) | 237 | if ((tmpDate > endDate()) && hasEndDate() ) |
227 | return FALSE; | 238 | return FALSE; |
228 | iday = 1; | 239 | iday = 1; |
229 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 240 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
230 | iday += 7 * weekOfMonth; | 241 | iday += 7 * weekOfMonth; |
231 | } while (iday > tmpDate.daysInMonth()); | 242 | } while (iday > tmpDate.daysInMonth()); |
232 | tmpDate = QDate(iyear, imonth, iday); | 243 | tmpDate = QDate(iyear, imonth, iday); |
233 | 244 | ||
234 | next = tmpDate; | 245 | next = tmpDate; |
235 | if ((next > endDate()) && hasEndDate() ) | 246 | if ((next > endDate()) && hasEndDate() ) |
236 | return FALSE; | 247 | return FALSE; |
237 | return TRUE; | 248 | return TRUE; |
238 | case MonthlyDate: | 249 | case MonthlyDate: |
239 | iday = start().day(); | 250 | iday = start().day(); |
240 | iyear = from.year(); | 251 | iyear = from.year(); |
241 | imonth = from.month(); | 252 | imonth = from.month(); |
242 | 253 | ||
243 | a = from.year() - start().year(); | 254 | a = from.year() - start().year(); |
244 | a *= 12; | 255 | a *= 12; |
245 | a = a + (imonth - start().month()); | 256 | a = a + (imonth - start().month()); |
246 | /* a is e.start()monthsFrom(from); */ | 257 | /* a is e.start()monthsFrom(from); */ |
247 | if(a % freq) { | 258 | if(a % freq) { |
248 | a = freq - (a % freq); | 259 | a = freq - (a % freq); |
249 | imonth = from.month() + a; | 260 | imonth = from.month() + a; |
250 | if (imonth > 12) { | 261 | if (imonth > 12) { |
251 | imonth--; | 262 | imonth--; |
252 | iyear += imonth / 12; | 263 | iyear += imonth / 12; |
253 | imonth = imonth % 12; | 264 | imonth = imonth % 12; |
254 | imonth++; | 265 | imonth++; |
255 | } | 266 | } |
256 | } | 267 | } |
257 | /* imonth is now the first month after or on | 268 | /* imonth is now the first month after or on |
258 | from that matches the frequencey given */ | 269 | from that matches the frequencey given */ |
259 | 270 | ||
260 | /* this could go for a while, worse case, 4*12 iterations, probably */ | 271 | /* this could go for a while, worse case, 4*12 iterations, probably */ |
261 | while(!QDate::isValid(iyear, imonth, iday) ) { | 272 | while(!QDate::isValid(iyear, imonth, iday) ) { |
262 | imonth += freq; | 273 | imonth += freq; |
263 | if (imonth > 12) { | 274 | if (imonth > 12) { |
264 | imonth--; | 275 | imonth--; |
265 | iyear += imonth / 12; | 276 | iyear += imonth / 12; |
266 | imonth = imonth % 12; | 277 | imonth = imonth % 12; |
267 | imonth++; | 278 | imonth++; |
268 | } | 279 | } |
269 | /* these loops could go for a while, check end case now */ | 280 | /* these loops could go for a while, check end case now */ |
270 | if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) | 281 | if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) |
271 | return FALSE; | 282 | return FALSE; |
272 | } | 283 | } |
273 | 284 | ||
274 | if(QDate(iyear, imonth, iday) >= from) { | 285 | if(QDate(iyear, imonth, iday) >= from) { |
275 | /* done */ | 286 | /* done */ |
276 | next = QDate(iyear, imonth, iday); | 287 | next = QDate(iyear, imonth, iday); |
277 | if ((next > endDate()) && hasEndDate() ) | 288 | if ((next > endDate()) && hasEndDate() ) |
278 | return FALSE; | 289 | return FALSE; |
279 | return TRUE; | 290 | return TRUE; |
280 | } | 291 | } |
281 | 292 | ||
282 | /* ok, need to cycle */ | 293 | /* ok, need to cycle */ |
283 | imonth += freq; | 294 | imonth += freq; |
284 | imonth--; | 295 | imonth--; |
285 | iyear += imonth / 12; | 296 | iyear += imonth / 12; |
286 | imonth = imonth % 12; | 297 | imonth = imonth % 12; |
287 | imonth++; | 298 | imonth++; |
288 | 299 | ||
289 | while(!QDate::isValid(iyear, imonth, iday) ) { | 300 | while(!QDate::isValid(iyear, imonth, iday) ) { |
290 | imonth += freq; | 301 | imonth += freq; |
291 | imonth--; | 302 | imonth--; |
292 | iyear += imonth / 12; | 303 | iyear += imonth / 12; |
293 | imonth = imonth % 12; | 304 | imonth = imonth % 12; |
294 | imonth++; | 305 | imonth++; |
295 | if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) | 306 | if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) |
296 | return FALSE; | 307 | return FALSE; |
297 | } | 308 | } |
298 | 309 | ||
299 | next = QDate(iyear, imonth, iday); | 310 | next = QDate(iyear, imonth, iday); |
300 | if ((next > endDate()) && hasEndDate() ) | 311 | if ((next > endDate()) && hasEndDate() ) |
301 | return FALSE; | 312 | return FALSE; |
302 | return TRUE; | 313 | return TRUE; |
303 | case Yearly: | 314 | case Yearly: |
304 | iday = start().day(); | 315 | iday = start().day(); |
305 | imonth = start().month(); | 316 | imonth = start().month(); |
306 | iyear = from.year(); // after all, we want to start in this year | 317 | iyear = from.year(); // after all, we want to start in this year |
307 | 318 | ||
308 | diff = 1; | 319 | diff = 1; |
309 | if(imonth == 2 && iday > 28) { | 320 | if(imonth == 2 && iday > 28) { |
310 | /* leap year, and it counts, calculate actual frequency */ | 321 | /* leap year, and it counts, calculate actual frequency */ |
311 | if(freq % 4) | 322 | if(freq % 4) |
312 | if (freq % 2) | 323 | if (freq % 2) |
313 | freq = freq * 4; | 324 | freq = freq * 4; |
314 | else | 325 | else |
315 | freq = freq * 2; | 326 | freq = freq * 2; |
316 | /* else divides by 4 already, leave freq alone */ | 327 | /* else divides by 4 already, leave freq alone */ |
317 | diff = 4; | 328 | diff = 4; |
318 | } | 329 | } |
319 | 330 | ||
320 | a = from.year() - start().year(); | 331 | a = from.year() - start().year(); |
321 | if(a % freq) { | 332 | if(a % freq) { |
322 | a = freq - (a % freq); | 333 | a = freq - (a % freq); |
323 | iyear = iyear + a; | 334 | iyear = iyear + a; |
324 | } | 335 | } |
325 | 336 | ||
326 | /* under the assumption we won't hit one of the special not-leap years twice */ | 337 | /* under the assumption we won't hit one of the special not-leap years twice */ |
327 | if(!QDate::isValid(iyear, imonth, iday)) { | 338 | if(!QDate::isValid(iyear, imonth, iday)) { |
328 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ | 339 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ |
329 | iyear += freq; | 340 | iyear += freq; |
330 | } | 341 | } |
331 | 342 | ||
332 | if(QDate(iyear, imonth, iday) >= from) { | 343 | if(QDate(iyear, imonth, iday) >= from) { |
333 | next = QDate(iyear, imonth, iday); | 344 | next = QDate(iyear, imonth, iday); |
334 | 345 | ||
335 | if ((next > endDate()) && hasEndDate() ) | 346 | if ((next > endDate()) && hasEndDate() ) |
336 | return FALSE; | 347 | return FALSE; |
337 | return TRUE; | 348 | return TRUE; |
338 | } | 349 | } |
339 | /* iyear == from.year(), need to advance again */ | 350 | /* iyear == from.year(), need to advance again */ |
340 | iyear += freq; | 351 | iyear += freq; |
341 | /* under the assumption we won't hit one of the special not-leap years twice */ | 352 | /* under the assumption we won't hit one of the special not-leap years twice */ |
342 | if(!QDate::isValid(iyear, imonth, iday)) { | 353 | if(!QDate::isValid(iyear, imonth, iday)) { |
343 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ | 354 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ |
344 | iyear += freq; | 355 | iyear += freq; |
345 | } | 356 | } |
346 | 357 | ||
347 | next = QDate(iyear, imonth, iday); | 358 | next = QDate(iyear, imonth, iday); |
348 | if ((next > endDate()) && hasEndDate() ) | 359 | if ((next > endDate()) && hasEndDate() ) |
349 | return FALSE; | 360 | return FALSE; |
350 | return TRUE; | 361 | return TRUE; |
351 | default: | 362 | default: |
352 | return FALSE; | 363 | return FALSE; |
353 | } | 364 | } |
354 | } | 365 | } |
355 | ORecur::RepeatType ORecur::type()const{ | 366 | ORecur::RepeatType ORecur::type()const{ |
356 | return data->type; | 367 | return data->type; |
357 | } | 368 | } |
358 | int ORecur::frequency()const { | 369 | int ORecur::frequency()const { |
359 | return data->freq; | 370 | return data->freq; |
360 | } | 371 | } |
361 | int ORecur::position()const { | 372 | int ORecur::position()const { |
362 | return data->pos; | 373 | return data->pos; |
363 | } | 374 | } |
364 | char ORecur::days() const{ | 375 | char ORecur::days() const{ |
365 | return data->days; | 376 | return data->days; |
366 | } | 377 | } |
367 | bool ORecur::hasEndDate()const { | 378 | bool ORecur::hasEndDate()const { |
368 | return data->hasEnd; | 379 | return data->hasEnd; |
369 | } | 380 | } |
370 | QDate ORecur::endDate()const { | 381 | QDate ORecur::endDate()const { |
371 | return data->end; | 382 | return data->end; |
372 | } | 383 | } |
373 | QDate ORecur::start()const{ | 384 | QDate ORecur::start()const{ |
374 | return data->start; | 385 | return data->start; |
375 | } | 386 | } |
376 | QDateTime ORecur::createdDateTime()const { | 387 | QDateTime ORecur::createdDateTime()const { |
377 | return data->create; | 388 | return data->create; |
378 | } | 389 | } |
379 | int ORecur::repetition()const { | 390 | int ORecur::repetition()const { |
380 | return data->rep; | 391 | return data->rep; |
381 | } | 392 | } |
382 | QString ORecur::service()const { | 393 | QString ORecur::service()const { |
383 | return data->app; | 394 | return data->app; |
384 | } | 395 | } |
385 | ORecur::ExceptionList& ORecur::exceptions() { | 396 | ORecur::ExceptionList& ORecur::exceptions() { |
386 | return data->list; | 397 | return data->list; |
387 | } | 398 | } |
388 | void ORecur::setType( const RepeatType& z) { | 399 | void ORecur::setType( const RepeatType& z) { |
389 | checkOrModify(); | 400 | checkOrModify(); |
390 | data->type = z; | 401 | data->type = z; |
391 | } | 402 | } |
392 | void ORecur::setFrequency( int freq ) { | 403 | void ORecur::setFrequency( int freq ) { |
393 | checkOrModify(); | 404 | checkOrModify(); |
394 | data->freq = freq; | 405 | data->freq = freq; |
395 | } | 406 | } |
396 | void ORecur::setPosition( int pos ) { | 407 | void ORecur::setPosition( int pos ) { |
397 | checkOrModify(); | 408 | checkOrModify(); |
398 | data->pos = pos; | 409 | data->pos = pos; |
399 | } | 410 | } |
400 | void ORecur::setDays( char c ) { | 411 | void ORecur::setDays( char c ) { |
401 | checkOrModify(); | 412 | checkOrModify(); |
402 | data->days = c; | 413 | data->days = c; |
403 | } | 414 | } |
404 | void ORecur::setEndDate( const QDate& dt) { | 415 | void ORecur::setEndDate( const QDate& dt) { |
405 | checkOrModify(); | 416 | checkOrModify(); |
406 | data->end = dt; | 417 | data->end = dt; |
407 | } | 418 | } |
408 | void ORecur::setCreatedDateTime( const QDateTime& t) { | 419 | void ORecur::setCreatedDateTime( const QDateTime& t) { |
409 | checkOrModify(); | 420 | checkOrModify(); |
410 | data->create = t; | 421 | data->create = t; |
411 | } | 422 | } |
412 | void ORecur::setHasEndDate( bool b) { | 423 | void ORecur::setHasEndDate( bool b) { |
413 | checkOrModify(); | 424 | checkOrModify(); |
414 | data->hasEnd = b; | 425 | data->hasEnd = b; |
415 | } | 426 | } |
416 | void ORecur::setRepitition( int rep ) { | 427 | void ORecur::setRepitition( int rep ) { |
417 | checkOrModify(); | 428 | checkOrModify(); |
418 | data->rep = rep; | 429 | data->rep = rep; |
419 | } | 430 | } |
420 | void ORecur::setService( const QString& app ) { | 431 | void ORecur::setService( const QString& app ) { |
421 | checkOrModify(); | 432 | checkOrModify(); |
422 | data->app = app; | 433 | data->app = app; |
423 | } | 434 | } |
424 | void ORecur::setStart( const QDate& dt ) { | 435 | void ORecur::setStart( const QDate& dt ) { |
425 | checkOrModify(); | 436 | checkOrModify(); |
426 | data->start = dt; | 437 | data->start = dt; |
427 | } | 438 | } |
428 | void ORecur::checkOrModify() { | 439 | void ORecur::checkOrModify() { |
429 | if ( data->count != 1 ) { | 440 | if ( data->count != 1 ) { |
430 | data->deref(); | 441 | data->deref(); |
431 | Data* d2 = new Data; | 442 | Data* d2 = new Data; |
432 | d2->days = data->days; | 443 | d2->days = data->days; |
433 | d2->type = data->type; | 444 | d2->type = data->type; |
434 | d2->freq = data->freq; | 445 | d2->freq = data->freq; |
435 | d2->pos = data->pos; | 446 | d2->pos = data->pos; |
436 | d2->hasEnd = data->hasEnd; | 447 | d2->hasEnd = data->hasEnd; |
437 | d2->end = data->end; | 448 | d2->end = data->end; |
438 | d2->create = data->create; | 449 | d2->create = data->create; |
439 | d2->rep = data->rep; | 450 | d2->rep = data->rep; |
440 | d2->app = data->app; | 451 | d2->app = data->app; |
441 | d2->list = data->list; | 452 | d2->list = data->list; |
442 | d2->start = data->start; | 453 | d2->start = data->start; |
443 | data = d2; | 454 | data = d2; |
444 | } | 455 | } |
445 | } | 456 | } |
457 | QString ORecur::toString()const { | ||
458 | QString buf; | ||
459 | |||
460 | buf += " rtype=\""; | ||
461 | switch ( data->type ) { | ||
462 | case ORecur::Daily: | ||
463 | buf += "Daily"; | ||
464 | break; | ||
465 | case ORecur::Weekly: | ||
466 | buf += "Weekly"; | ||
467 | break; | ||
468 | case ORecur::MonthlyDay: | ||
469 | buf += "MonthlyDay"; | ||
470 | break; | ||
471 | case ORecur::MonthlyDate: | ||
472 | buf += "MonthlyDate"; | ||
473 | break; | ||
474 | case ORecur::Yearly: | ||
475 | buf += "Yearly"; | ||
476 | break; | ||
477 | default: | ||
478 | buf += "NoRepeat"; | ||
479 | break; | ||
480 | } | ||
481 | buf += "\""; | ||
482 | if (data->days > 0 ) | ||
483 | buf += " rweekdays=\"" + QString::number( static_cast<int>( data->days ) ) + "\""; | ||
484 | if ( data->pos != 0 ) | ||
485 | buf += " rposition=\"" + QString::number(data->pos ) + "\""; | ||
486 | |||
487 | buf += " rfreq=\"" + QString::number( data->freq ) + "\""; | ||
488 | buf += " rhasenddate=\"" + QString::number( static_cast<int>( data->hasEnd ) ) + "\""; | ||
489 | if ( data->hasEnd ) | ||
490 | buf += " enddt=\"" | ||
491 | + QString::number( OTimeZone::utc().fromUTCDateTime( QDateTime( data->end, QTime(12,0,0) ) ) ) | ||
492 | + "\""; | ||
493 | buf += " created=\"" + QString::number( OTimeZone::utc().fromUTCDateTime( data->create ) ) + "\""; | ||
494 | |||
495 | if ( data->list.isEmpty() ) return buf; | ||
496 | // save exceptions list here!! | ||
497 | ExceptionList::ConstIterator it; | ||
498 | ExceptionList list = data->list; | ||
499 | buf += " exceptions=\""; | ||
500 | QDate date; | ||
501 | for ( it = list.begin(); it != list.end(); ++it ) { | ||
502 | date = (*it); | ||
503 | if ( it != list.begin() ) buf += " "; | ||
504 | |||
505 | buf += QCString().sprintf("%04d%02d%02d", date.year(), date.month(), date.day() ); | ||
506 | } | ||
507 | buf += "\""; | ||
446 | 508 | ||
509 | return buf; | ||
510 | } | ||
diff --git a/libopie/pim/orecur.h b/libopie/pim/orecur.h index 1e0014b..b214b3f 100644 --- a/libopie/pim/orecur.h +++ b/libopie/pim/orecur.h | |||
@@ -1,87 +1,91 @@ | |||
1 | /* | 1 | /* |
2 | * GPL from TT | 2 | * GPL from TT |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #ifndef OPIE_RECUR_H | 5 | #ifndef OPIE_RECUR_H |
6 | #define OPIE_RECUR_H | 6 | #define OPIE_RECUR_H |
7 | 7 | ||
8 | #include <sys/types.h> | 8 | #include <sys/types.h> |
9 | 9 | ||
10 | #include <qdatetime.h> | 10 | #include <qdatetime.h> |
11 | #include <qvaluelist.h> | 11 | #include <qvaluelist.h> |
12 | 12 | ||
13 | 13 | ||
14 | class ORecur { | 14 | class ORecur { |
15 | public: | 15 | public: |
16 | typedef QValueList<QDate> ExceptionList; | 16 | typedef QValueList<QDate> ExceptionList; |
17 | enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, | 17 | enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, |
18 | MonthlyDate, Yearly }; | 18 | MonthlyDate, Yearly }; |
19 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, | 19 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, |
20 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; | 20 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; |
21 | ORecur(); | 21 | ORecur(); |
22 | ORecur( const ORecur& ); | 22 | ORecur( const ORecur& ); |
23 | ~ORecur(); | 23 | ~ORecur(); |
24 | 24 | ||
25 | ORecur &operator=( const ORecur& ); | 25 | ORecur &operator=( const ORecur& ); |
26 | bool operator==(const ORecur& )const; | 26 | bool operator==(const ORecur& )const; |
27 | 27 | ||
28 | bool doesRecur()const; | 28 | bool doesRecur()const; |
29 | /* if it recurrs on that day */ | 29 | /* if it recurrs on that day */ |
30 | bool doesRecur( const QDate& ); | 30 | bool doesRecur( const QDate& ); |
31 | RepeatType type()const; | 31 | RepeatType type()const; |
32 | int frequency()const; | 32 | int frequency()const; |
33 | int position()const; | 33 | int position()const; |
34 | char days()const; | 34 | char days()const; |
35 | bool hasEndDate()const; | 35 | bool hasEndDate()const; |
36 | QDate start()const; | 36 | QDate start()const; |
37 | QDate endDate()const; | 37 | QDate endDate()const; |
38 | QDateTime createdDateTime()const; | 38 | QDateTime createdDateTime()const; |
39 | /** | 39 | /** |
40 | * starting on monday=0, sunday=6 | 40 | * starting on monday=0, sunday=6 |
41 | * for convience | 41 | * for convience |
42 | */ | 42 | */ |
43 | bool repeatOnWeekDay( int day )const; | 43 | bool repeatOnWeekDay( int day )const; |
44 | 44 | ||
45 | /** | 45 | /** |
46 | * FromWhereToStart is not included!!! | 46 | * FromWhereToStart is not included!!! |
47 | */ | 47 | */ |
48 | bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); | 48 | bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); |
49 | 49 | ||
50 | /** | 50 | /** |
51 | * The module this ORecur belongs to | 51 | * The module this ORecur belongs to |
52 | */ | 52 | */ |
53 | QString service()const; | 53 | QString service()const; |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * reference to the exception list | 56 | * reference to the exception list |
57 | */ | 57 | */ |
58 | ExceptionList &exceptions(); | 58 | ExceptionList &exceptions(); |
59 | 59 | ||
60 | /** | 60 | /** |
61 | * the current repetition | 61 | * the current repetition |
62 | */ | 62 | */ |
63 | int repetition()const; | 63 | int repetition()const; |
64 | 64 | ||
65 | void setType( const RepeatType& ); | 65 | void setType( const RepeatType& ); |
66 | void setFrequency( int freq ); | 66 | void setFrequency( int freq ); |
67 | void setPosition( int pos ); | 67 | void setPosition( int pos ); |
68 | void setDays( char c); | 68 | void setDays( char c); |
69 | void setEndDate( const QDate& dt ); | 69 | void setEndDate( const QDate& dt ); |
70 | void setStart( const QDate& dt ); | 70 | void setStart( const QDate& dt ); |
71 | void setCreatedDateTime( const QDateTime& ); | 71 | void setCreatedDateTime( const QDateTime& ); |
72 | void setHasEndDate( bool b ); | 72 | void setHasEndDate( bool b ); |
73 | void setRepitition(int ); | 73 | void setRepitition(int ); |
74 | 74 | ||
75 | void setService( const QString& ser ); | 75 | void setService( const QString& ser ); |
76 | |||
77 | /* almost internal */ | ||
78 | QString toString()const; | ||
76 | private: | 79 | private: |
80 | bool p_nextOccurrence( const QDate& from, QDate& next ); | ||
77 | void deref(); | 81 | void deref(); |
78 | inline void checkOrModify(); | 82 | inline void checkOrModify(); |
79 | 83 | ||
80 | 84 | ||
81 | class Data; | 85 | class Data; |
82 | Data* data; | 86 | Data* data; |
83 | class ORecurPrivate; | 87 | class ORecurPrivate; |
84 | ORecurPrivate *d; | 88 | ORecurPrivate *d; |
85 | }; | 89 | }; |
86 | 90 | ||
87 | #endif | 91 | #endif |
diff --git a/libopie/pim/test/oevent_test.cpp b/libopie/pim/test/oevent_test.cpp index 6f04995..247b83b 100644 --- a/libopie/pim/test/oevent_test.cpp +++ b/libopie/pim/test/oevent_test.cpp | |||
@@ -1,50 +1,54 @@ | |||
1 | #include <qdatetime.h> | 1 | #include <qdatetime.h> |
2 | 2 | ||
3 | #include "../oevent.h" | 3 | #include "../oevent.h" |
4 | #include "../odatebookaccess.h" | 4 | #include "../odatebookaccess.h" |
5 | 5 | ||
6 | int main(int argc, char* argv ) { | 6 | int main(int argc, char* argv ) { |
7 | OEvent ev; | 7 | OEvent ev; |
8 | ev.setUid( 20 ); | 8 | // ev.setUid( 20 ); |
9 | 9 | ||
10 | ev.setDescription( "Foo" ); | 10 | ev.setDescription( "Foo Descsfewrf" ); |
11 | 11 | ||
12 | OEvent ev2 = ev; | 12 | OEvent ev2 = ev; |
13 | ev2.setDescription("Foo2"); | 13 | ev2.setDescription("Foo3"); |
14 | qWarning("%s", ev2.description().latin1() ); | 14 | qWarning("%s", ev2.description().latin1() ); |
15 | qWarning("%s", ev.description().latin1() ); | 15 | qWarning("%s", ev.description().latin1() ); |
16 | 16 | ||
17 | QDateTime time = QDateTime::currentDateTime(); | 17 | QDateTime time = QDateTime::currentDateTime(); |
18 | ev2.setStartDateTime( time ); | 18 | ev2.setStartDateTime( time ); |
19 | ev2.setTimeZone( "Europe/London" ); | 19 | ev2.setTimeZone( "Europe/London" ); |
20 | 20 | ||
21 | qWarning("%s", ev2.startDateTime().toString().latin1() ); | 21 | qWarning("%s", ev2.startDateTime().toString().latin1() ); |
22 | qWarning("%s", ev2.startDateTimeInZone().toString().latin1() ); | 22 | qWarning("%s", ev2.startDateTimeInZone().toString().latin1() ); |
23 | qWarning("%d %d", ev.isAllDay(), ev2.isAllDay() ); | ||
23 | 24 | ||
24 | ODateBookAccess acc; | 25 | ODateBookAccess acc; |
25 | if(!acc.load() ) qWarning("could not load"); | 26 | if(!acc.load() ) qWarning("could not load"); |
26 | 27 | ||
27 | ODateBookAccess::List::Iterator it; | 28 | ODateBookAccess::List::Iterator it; |
28 | ODateBookAccess::List list = acc.allRecords(); | 29 | ODateBookAccess::List list = acc.allRecords(); |
29 | 30 | ||
30 | for( it = list.begin(); it != list.end(); ++it ){ | 31 | for( it = list.begin(); it != list.end(); ++it ){ |
31 | OEvent ev = (*it); | 32 | OEvent ev = (*it); |
32 | qWarning("Summary: %s",ev.description().latin1() ); | 33 | qWarning("Summary: %s",ev.description().latin1() ); |
33 | qWarning("Start: %s End: %s",ev.startDateTime().toString().latin1(), ev.endDateTime().toString().latin1() ); | 34 | qWarning("Start: %s End: %s",ev.startDateTime().toString().latin1(), ev.endDateTime().toString().latin1() ); |
34 | qWarning("All Day: %d",ev.isAllDay() ); | 35 | qWarning("All Day: %d",ev.isAllDay() ); |
35 | 36 | ||
36 | } | 37 | } |
37 | QDate date1(2003,02,01 ); | 38 | QDate date1(2003,02,01 ); |
38 | QDate date2(2003,03,01 ); | 39 | QDate date2(2003,03,01 ); |
39 | 40 | ||
40 | OEffectiveEvent::ValueList effList = acc.effectiveEvents( date1,date2 ); | 41 | OEffectiveEvent::ValueList effList = acc.effectiveEvents( date1,date2 ); |
41 | OEffectiveEvent::ValueList::Iterator effIt; | 42 | OEffectiveEvent::ValueList::Iterator effIt; |
42 | 43 | ||
43 | for( effIt = effList.begin(); effIt != effList.end(); ++effIt ){ | 44 | for( effIt = effList.begin(); effIt != effList.end(); ++effIt ){ |
44 | OEffectiveEvent ef = (*effIt); | 45 | OEffectiveEvent ef = (*effIt); |
45 | qWarning("Summary: %s", ef.description().latin1() ); | 46 | qWarning("Summary: %s", ef.description().latin1() ); |
46 | qWarning("Date: %s", ef.date().toString().latin1() ); | 47 | qWarning("Date: %s", ef.date().toString().latin1() ); |
47 | } | 48 | } |
49 | ev.setUid( 1 ); | ||
50 | acc.add( ev ); | ||
51 | acc.save(); | ||
48 | 52 | ||
49 | return 0; | 53 | return 0; |
50 | } | 54 | } |
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp index a4c514b..5239d84 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp | |||
@@ -1,395 +1,557 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <fcntl.h> | 2 | #include <fcntl.h> |
3 | 3 | ||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | |||
4 | #include <sys/types.h> | 7 | #include <sys/types.h> |
5 | #include <sys/mman.h> | 8 | #include <sys/mman.h> |
6 | #include <sys/stat.h> | 9 | #include <sys/stat.h> |
7 | 10 | ||
8 | #include <unistd.h> | 11 | #include <unistd.h> |
9 | 12 | ||
10 | #include <qasciidict.h> | 13 | #include <qasciidict.h> |
11 | #include <qfile.h> | 14 | #include <qfile.h> |
12 | 15 | ||
13 | #include <qtopia/global.h> | 16 | #include <qtopia/global.h> |
14 | #include <qtopia/stringutil.h> | 17 | #include <qtopia/stringutil.h> |
18 | #include <qtopia/timeconversion.h> | ||
15 | 19 | ||
16 | #include "opimnotifymanager.h" | 20 | #include "opimnotifymanager.h" |
17 | #include "orecur.h" | 21 | #include "orecur.h" |
18 | #include "otimezone.h" | 22 | #include "otimezone.h" |
19 | #include "odatebookaccessbackend_xml.h" | 23 | #include "odatebookaccessbackend_xml.h" |
20 | 24 | ||
21 | namespace { | 25 | namespace { |
22 | time_t start, end, created, rp_end; | 26 | time_t start, end, created, rp_end; |
23 | ORecur* rec; | 27 | ORecur* rec; |
24 | ORecur* recur() { | 28 | ORecur* recur() { |
25 | if (!rec) | 29 | if (!rec) |
26 | rec = new ORecur; | 30 | rec = new ORecur; |
27 | 31 | ||
28 | return rec; | 32 | return rec; |
29 | } | 33 | } |
30 | int alarmTime; | 34 | int alarmTime; |
31 | int snd; | 35 | int snd; |
32 | enum Attribute{ | 36 | enum Attribute{ |
33 | FDescription = 0, | 37 | FDescription = 0, |
34 | FLocation, | 38 | FLocation, |
35 | FCategories, | 39 | FCategories, |
36 | FUid, | 40 | FUid, |
37 | FType, | 41 | FType, |
38 | FAlarm, | 42 | FAlarm, |
39 | FSound, | 43 | FSound, |
40 | FRType, | 44 | FRType, |
41 | FRWeekdays, | 45 | FRWeekdays, |
42 | FRPosition, | 46 | FRPosition, |
43 | FRFreq, | 47 | FRFreq, |
44 | FRHasEndDate, | 48 | FRHasEndDate, |
45 | FREndDate, | 49 | FREndDate, |
46 | FRStart, | 50 | FRStart, |
47 | FREnd, | 51 | FREnd, |
48 | FNote, | 52 | FNote, |
49 | FCreated | 53 | FCreated, |
54 | FTimeZone, | ||
55 | FRecParent, | ||
56 | FRecChildren, | ||
57 | FExceptions | ||
50 | }; | 58 | }; |
59 | inline void save( const OEvent& ev, QString& buf ) { | ||
60 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; | ||
61 | if (!ev.location().isEmpty() ) | ||
62 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; | ||
63 | |||
64 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; | ||
65 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; | ||
66 | |||
67 | if (ev.isAllDay() ) | ||
68 | buf += " type=\"AllDay\""; | ||
69 | |||
70 | if (ev.hasNotifiers() ) { | ||
71 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first | ||
72 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; | ||
73 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; | ||
74 | if ( alarm.sound() == OPimAlarm::Loud ) | ||
75 | buf += "loud"; | ||
76 | else | ||
77 | buf += "silent"; | ||
78 | buf += "\""; | ||
79 | } | ||
80 | if ( ev.hasRecurrence() ) { | ||
81 | buf += ev.recurrence().toString(); | ||
82 | } | ||
83 | |||
84 | /* | ||
85 | * fscking timezones :) well, we'll first convert | ||
86 | * the QDateTime to a QDateTime in UTC time | ||
87 | * and then we'll create a nice time_t | ||
88 | */ | ||
89 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | ||
90 | buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; | ||
91 | buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; | ||
92 | if (!ev.note().isEmpty() ) { | ||
93 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; | ||
94 | } | ||
95 | |||
96 | buf += " timezone=\""; | ||
97 | if ( ev.timeZone().isEmpty() ) | ||
98 | buf += "None"; | ||
99 | else | ||
100 | buf += ev.timeZone(); | ||
101 | |||
102 | if (ev.parent() != 0 ) { | ||
103 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; | ||
104 | } | ||
105 | |||
106 | if (ev.children().count() != 0 ) { | ||
107 | QArray<int> children = ev.children(); | ||
108 | buf += " recchildren=\""; | ||
109 | for ( uint i = 0; i < children.count(); i++ ) { | ||
110 | if ( i != 0 ) buf += " "; | ||
111 | buf += QString::number( children[i] ); | ||
112 | } | ||
113 | buf+= "\""; | ||
114 | } | ||
115 | |||
116 | // skip custom writing | ||
117 | } | ||
118 | |||
119 | inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) { | ||
120 | QMap<int, OEvent>::ConstIterator it; | ||
121 | QString buf; | ||
122 | QCString str; | ||
123 | int total_written; | ||
124 | for ( it = list.begin(); it != list.end(); ++it ) { | ||
125 | buf = "<event"; | ||
126 | save( it.data(), buf ); | ||
127 | buf += " />\n"; | ||
128 | str = buf.utf8(); | ||
129 | |||
130 | total_written = file.writeBlock(str.data(), str.length() ); | ||
131 | if ( total_written != int(str.length() ) ) | ||
132 | return false; | ||
133 | } | ||
134 | return true; | ||
135 | } | ||
51 | } | 136 | } |
52 | 137 | ||
53 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , | 138 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , |
54 | const QString& fileName ) | 139 | const QString& fileName ) |
55 | : ODateBookAccessBackend() { | 140 | : ODateBookAccessBackend() { |
56 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; | 141 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; |
57 | m_changed = false; | 142 | m_changed = false; |
58 | } | 143 | } |
59 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { | 144 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { |
60 | } | 145 | } |
61 | bool ODateBookAccessBackend_XML::load() { | 146 | bool ODateBookAccessBackend_XML::load() { |
62 | return loadFile(); | 147 | return loadFile(); |
63 | } | 148 | } |
64 | bool ODateBookAccessBackend_XML::reload() { | 149 | bool ODateBookAccessBackend_XML::reload() { |
65 | clear(); | 150 | clear(); |
66 | return load(); | 151 | return load(); |
67 | } | 152 | } |
68 | bool ODateBookAccessBackend_XML::save() { | 153 | bool ODateBookAccessBackend_XML::save() { |
69 | if (!m_changed) return true; | 154 | qWarning("going to save now"); |
70 | m_changed = false; | 155 | // if (!m_changed) return true; |
156 | |||
157 | int total_written; | ||
158 | QString strFileNew = m_name + ".new"; | ||
159 | |||
160 | QFile f( strFileNew ); | ||
161 | if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; | ||
162 | |||
163 | QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); | ||
164 | buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; | ||
165 | buf += "<events>\n"; | ||
166 | QCString str = buf.utf8(); | ||
167 | total_written = f.writeBlock( str.data(), str.length() ); | ||
168 | if ( total_written != int(str.length() ) ) { | ||
169 | f.close(); | ||
170 | QFile::remove( strFileNew ); | ||
171 | return false; | ||
172 | } | ||
71 | 173 | ||
174 | if (!forAll( m_raw, f ) ) { | ||
175 | f.close(); | ||
176 | QFile::remove( strFileNew ); | ||
177 | return false; | ||
178 | } | ||
179 | if (!forAll( m_rep, f ) ) { | ||
180 | f.close(); | ||
181 | QFile::remove( strFileNew ); | ||
182 | return false; | ||
183 | } | ||
184 | |||
185 | buf = "</events>\n</DATEBOOK>\n"; | ||
186 | str = buf.utf8(); | ||
187 | total_written = f.writeBlock( str.data(), str.length() ); | ||
188 | if ( total_written != int(str.length() ) ) { | ||
189 | f.close(); | ||
190 | QFile::remove( strFileNew ); | ||
191 | return false; | ||
192 | } | ||
193 | f.close(); | ||
194 | |||
195 | exit(0); | ||
196 | if ( ::rename( strFileNew, m_name ) < 0 ) { | ||
197 | QFile::remove( strFileNew ); | ||
198 | return false; | ||
199 | } | ||
200 | |||
201 | m_changed = false; | ||
72 | return true; | 202 | return true; |
73 | } | 203 | } |
74 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { | 204 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { |
75 | QArray<int> ints( m_raw.count()+ m_rep.count() ); | 205 | QArray<int> ints( m_raw.count()+ m_rep.count() ); |
76 | uint i = 0; | 206 | uint i = 0; |
77 | QMap<int, OEvent>::ConstIterator it; | 207 | QMap<int, OEvent>::ConstIterator it; |
78 | 208 | ||
79 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 209 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
80 | ints[i] = it.key(); | 210 | ints[i] = it.key(); |
81 | i++; | 211 | i++; |
82 | } | 212 | } |
83 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 213 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
84 | ints[i] = it.key(); | 214 | ints[i] = it.key(); |
85 | i++; | 215 | i++; |
86 | } | 216 | } |
87 | 217 | ||
88 | return ints; | 218 | return ints; |
89 | } | 219 | } |
90 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int ) { | 220 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int ) { |
91 | return QArray<int>(); | 221 | return QArray<int>(); |
92 | } | 222 | } |
93 | void ODateBookAccessBackend_XML::clear() { | 223 | void ODateBookAccessBackend_XML::clear() { |
94 | m_raw.clear(); | 224 | m_raw.clear(); |
95 | m_rep.clear(); | 225 | m_rep.clear(); |
96 | } | 226 | } |
97 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ | 227 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ |
98 | if ( m_raw.contains( uid ) ) | 228 | if ( m_raw.contains( uid ) ) |
99 | return m_raw[uid]; | 229 | return m_raw[uid]; |
100 | else | 230 | else |
101 | return m_rep[uid]; | 231 | return m_rep[uid]; |
102 | } | 232 | } |
103 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { | 233 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { |
104 | m_changed = true; | 234 | m_changed = true; |
105 | if (ev.hasRecurrence() ) | 235 | if (ev.hasRecurrence() ) |
106 | m_rep.insert( ev.uid(), ev ); | 236 | m_rep.insert( ev.uid(), ev ); |
107 | else | 237 | else |
108 | m_raw.insert( ev.uid(), ev ); | 238 | m_raw.insert( ev.uid(), ev ); |
109 | 239 | ||
110 | return true; | 240 | return true; |
111 | } | 241 | } |
112 | bool ODateBookAccessBackend_XML::remove( int uid ) { | 242 | bool ODateBookAccessBackend_XML::remove( int uid ) { |
113 | m_changed = true; | 243 | m_changed = true; |
114 | m_rep.remove( uid ); | 244 | m_rep.remove( uid ); |
115 | m_rep.remove( uid ); | 245 | m_rep.remove( uid ); |
116 | 246 | ||
117 | return true; | 247 | return true; |
118 | } | 248 | } |
119 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { | 249 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { |
120 | replace( ev.uid() ); | 250 | replace( ev.uid() ); |
121 | return add( ev ); | 251 | return add( ev ); |
122 | } | 252 | } |
123 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { | 253 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { |
124 | return allRecords(); | 254 | return allRecords(); |
125 | } | 255 | } |
126 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { | 256 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { |
127 | QArray<int> ints( m_rep.count() ); | 257 | QArray<int> ints( m_rep.count() ); |
128 | uint i = 0; | 258 | uint i = 0; |
129 | QMap<int, OEvent>::ConstIterator it; | 259 | QMap<int, OEvent>::ConstIterator it; |
130 | 260 | ||
131 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 261 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
132 | ints[i] = it.key(); | 262 | ints[i] = it.key(); |
133 | i++; | 263 | i++; |
134 | } | 264 | } |
135 | 265 | ||
136 | return ints; | 266 | return ints; |
137 | } | 267 | } |
138 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { | 268 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { |
139 | QArray<int> ints( m_raw.count() ); | 269 | QArray<int> ints( m_raw.count() ); |
140 | uint i = 0; | 270 | uint i = 0; |
141 | QMap<int, OEvent>::ConstIterator it; | 271 | QMap<int, OEvent>::ConstIterator it; |
142 | 272 | ||
143 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 273 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
144 | ints[i] = it.key(); | 274 | ints[i] = it.key(); |
145 | i++; | 275 | i++; |
146 | } | 276 | } |
147 | 277 | ||
148 | return ints; | 278 | return ints; |
149 | } | 279 | } |
150 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { | 280 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { |
151 | OEvent::ValueList list; | 281 | OEvent::ValueList list; |
152 | QMap<int, OEvent>::ConstIterator it; | 282 | QMap<int, OEvent>::ConstIterator it; |
153 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) | 283 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) |
154 | list.append( it.data() ); | 284 | list.append( it.data() ); |
155 | 285 | ||
156 | return list; | 286 | return list; |
157 | } | 287 | } |
158 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { | 288 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { |
159 | OEvent::ValueList list; | 289 | OEvent::ValueList list; |
160 | QMap<int, OEvent>::ConstIterator it; | 290 | QMap<int, OEvent>::ConstIterator it; |
161 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) | 291 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) |
162 | list.append( it.data() ); | 292 | list.append( it.data() ); |
163 | 293 | ||
164 | return list; | 294 | return list; |
165 | } | 295 | } |
166 | bool ODateBookAccessBackend_XML::loadFile() { | 296 | bool ODateBookAccessBackend_XML::loadFile() { |
167 | m_changed = false; | 297 | m_changed = false; |
168 | 298 | ||
169 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); | 299 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); |
170 | if ( fd < 0 ) return false; | 300 | if ( fd < 0 ) return false; |
171 | 301 | ||
172 | struct stat attribute; | 302 | struct stat attribute; |
173 | if ( ::fstat(fd, &attribute ) == -1 ) { | 303 | if ( ::fstat(fd, &attribute ) == -1 ) { |
174 | ::close( fd ); | 304 | ::close( fd ); |
175 | return false; | 305 | return false; |
176 | } | 306 | } |
177 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 307 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
178 | if ( map_addr == ( (caddr_t)-1) ) { | 308 | if ( map_addr == ( (caddr_t)-1) ) { |
179 | ::close( fd ); | 309 | ::close( fd ); |
180 | return false; | 310 | return false; |
181 | } | 311 | } |
182 | 312 | ||
183 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); | 313 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); |
184 | ::close( fd ); | 314 | ::close( fd ); |
185 | 315 | ||
186 | QAsciiDict<int> dict(FCreated+1); | 316 | QAsciiDict<int> dict(FExceptions+1); |
187 | dict.setAutoDelete( true ); | 317 | dict.setAutoDelete( true ); |
188 | dict.insert( "description", new int(FDescription) ); | 318 | dict.insert( "description", new int(FDescription) ); |
189 | dict.insert( "location", new int(FLocation) ); | 319 | dict.insert( "location", new int(FLocation) ); |
190 | dict.insert( "categories", new int(FCategories) ); | 320 | dict.insert( "categories", new int(FCategories) ); |
191 | dict.insert( "uid", new int(FUid) ); | 321 | dict.insert( "uid", new int(FUid) ); |
192 | dict.insert( "type", new int(FType) ); | 322 | dict.insert( "type", new int(FType) ); |
193 | dict.insert( "alarm", new int(FAlarm) ); | 323 | dict.insert( "alarm", new int(FAlarm) ); |
194 | dict.insert( "sound", new int(FSound) ); | 324 | dict.insert( "sound", new int(FSound) ); |
195 | dict.insert( "rtype", new int(FRType) ); | 325 | dict.insert( "rtype", new int(FRType) ); |
196 | dict.insert( "rweekdays", new int(FRWeekdays) ); | 326 | dict.insert( "rweekdays", new int(FRWeekdays) ); |
197 | dict.insert( "rposition", new int(FRPosition) ); | 327 | dict.insert( "rposition", new int(FRPosition) ); |
198 | dict.insert( "rfreq", new int(FRFreq) ); | 328 | dict.insert( "rfreq", new int(FRFreq) ); |
199 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); | 329 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); |
200 | dict.insert( "enddt", new int(FREndDate) ); | 330 | dict.insert( "enddt", new int(FREndDate) ); |
201 | dict.insert( "start", new int(FRStart) ); | 331 | dict.insert( "start", new int(FRStart) ); |
202 | dict.insert( "end", new int(FREnd) ); | 332 | dict.insert( "end", new int(FREnd) ); |
203 | dict.insert( "note", new int(FNote) ); | 333 | dict.insert( "note", new int(FNote) ); |
204 | dict.insert( "created", new int(FCreated) ); | 334 | dict.insert( "created", new int(FCreated) ); |
335 | dict.insert( "recparent", new int(FRecParent) ); | ||
336 | dict.insert( "recchildren", new int(FRecChildren) ); | ||
337 | dict.insert( "exceptions", new int(FExceptions) ); | ||
338 | dict.insert( "timezone", new int(FTimeZone) ); | ||
205 | 339 | ||
206 | char* dt = (char*)map_addr; | 340 | char* dt = (char*)map_addr; |
207 | int len = attribute.st_size; | 341 | int len = attribute.st_size; |
208 | int i = 0; | 342 | int i = 0; |
209 | char* point; | 343 | char* point; |
210 | const char* collectionString = "<event "; | 344 | const char* collectionString = "<event "; |
211 | int strLen = ::strlen(collectionString); | 345 | int strLen = ::strlen(collectionString); |
212 | int *find; | 346 | int *find; |
213 | while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) { | 347 | while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) { |
214 | i = point -dt; | 348 | i = point -dt; |
215 | i+= strLen; | 349 | i+= strLen; |
216 | 350 | ||
217 | alarmTime = -1; | 351 | alarmTime = -1; |
218 | snd = 0; // silent | 352 | snd = 0; // silent |
219 | 353 | ||
220 | OEvent ev; | 354 | OEvent ev; |
221 | rec = 0; | 355 | rec = 0; |
222 | 356 | ||
223 | while ( TRUE ) { | 357 | while ( TRUE ) { |
224 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 358 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
225 | ++i; | 359 | ++i; |
226 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 360 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
227 | break; | 361 | break; |
228 | 362 | ||
229 | 363 | ||
230 | // we have another attribute, read it. | 364 | // we have another attribute, read it. |
231 | int j = i; | 365 | int j = i; |
232 | while ( j < len && dt[j] != '=' ) | 366 | while ( j < len && dt[j] != '=' ) |
233 | ++j; | 367 | ++j; |
234 | QCString attr( dt+i, j-i+1); | 368 | QCString attr( dt+i, j-i+1); |
235 | 369 | ||
236 | i = ++j; // skip = | 370 | i = ++j; // skip = |
237 | 371 | ||
238 | // find the start of quotes | 372 | // find the start of quotes |
239 | while ( i < len && dt[i] != '"' ) | 373 | while ( i < len && dt[i] != '"' ) |
240 | ++i; | 374 | ++i; |
241 | j = ++i; | 375 | j = ++i; |
242 | 376 | ||
243 | bool haveUtf = FALSE; | 377 | bool haveUtf = FALSE; |
244 | bool haveEnt = FALSE; | 378 | bool haveEnt = FALSE; |
245 | while ( j < len && dt[j] != '"' ) { | 379 | while ( j < len && dt[j] != '"' ) { |
246 | if ( ((unsigned char)dt[j]) > 0x7f ) | 380 | if ( ((unsigned char)dt[j]) > 0x7f ) |
247 | haveUtf = TRUE; | 381 | haveUtf = TRUE; |
248 | if ( dt[j] == '&' ) | 382 | if ( dt[j] == '&' ) |
249 | haveEnt = TRUE; | 383 | haveEnt = TRUE; |
250 | ++j; | 384 | ++j; |
251 | } | 385 | } |
252 | if ( i == j ) { | 386 | if ( i == j ) { |
253 | // empty value | 387 | // empty value |
254 | i = j + 1; | 388 | i = j + 1; |
255 | continue; | 389 | continue; |
256 | } | 390 | } |
257 | 391 | ||
258 | QCString value( dt+i, j-i+1 ); | 392 | QCString value( dt+i, j-i+1 ); |
259 | i = j + 1; | 393 | i = j + 1; |
260 | 394 | ||
261 | QString str = (haveUtf ? QString::fromUtf8( value ) | 395 | QString str = (haveUtf ? QString::fromUtf8( value ) |
262 | : QString::fromLatin1( value ) ); | 396 | : QString::fromLatin1( value ) ); |
263 | if ( haveEnt ) | 397 | if ( haveEnt ) |
264 | str = Qtopia::plainString( str ); | 398 | str = Qtopia::plainString( str ); |
265 | 399 | ||
266 | /* | 400 | /* |
267 | * add key + value | 401 | * add key + value |
268 | */ | 402 | */ |
269 | find = dict[attr.data()]; | 403 | find = dict[attr.data()]; |
270 | if (!find) | 404 | if (!find) |
271 | ev.setCustomField( attr, value ); | 405 | ev.setCustomField( attr, value ); |
272 | else { | 406 | else { |
273 | setField( ev, *find, value ); | 407 | setField( ev, *find, value ); |
274 | } | 408 | } |
275 | } | 409 | } |
276 | /* time to finalize */ | 410 | /* time to finalize */ |
277 | finalizeRecord( ev ); | 411 | finalizeRecord( ev ); |
278 | add( ev ); | 412 | add( ev ); |
279 | delete rec; | 413 | delete rec; |
280 | } | 414 | } |
281 | ::munmap(map_addr, attribute.st_size ); | 415 | ::munmap(map_addr, attribute.st_size ); |
282 | m_changed = false; // changed during add | 416 | m_changed = false; // changed during add |
283 | 417 | ||
284 | return true; | 418 | return true; |
285 | } | 419 | } |
286 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { | 420 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { |
287 | /* AllDay is alway in UTC */ | 421 | /* AllDay is alway in UTC */ |
288 | if ( ev.isAllDay() ) { | 422 | if ( ev.isAllDay() ) { |
289 | OTimeZone utc = OTimeZone::utc(); | 423 | OTimeZone utc = OTimeZone::utc(); |
290 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); | 424 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); |
291 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); | 425 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); |
426 | ev.setTimeZone( "UTC"); // make sure it is really utc | ||
292 | }else { | 427 | }else { |
428 | /* to current date time */ | ||
293 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | 429 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); |
294 | ev.setStartDateTime( zone.toDateTime( start ) ); | 430 | QDateTime date = zone.toDateTime( start ); |
295 | ev.setEndDateTime ( zone.toDateTime( end ) ); | 431 | ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); |
432 | |||
433 | date = zone.toDateTime( end ); | ||
434 | ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); | ||
296 | } | 435 | } |
297 | if ( rec && rec->doesRecur() ) { | 436 | if ( rec && rec->doesRecur() ) { |
298 | OTimeZone utc = OTimeZone::utc(); | 437 | OTimeZone utc = OTimeZone::utc(); |
299 | ORecur recu( *rec ); // call copy c'tor; | 438 | ORecur recu( *rec ); // call copy c'tor; |
300 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); | 439 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); |
301 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); | 440 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); |
302 | recu.setStart( ev.startDateTime().date() ); | 441 | recu.setStart( ev.startDateTime().date() ); |
303 | ev.setRecurrence( recu ); | 442 | ev.setRecurrence( recu ); |
304 | } | 443 | } |
305 | 444 | ||
306 | if (alarmTime != -1 ) { | 445 | if (alarmTime != -1 ) { |
307 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); | 446 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); |
308 | OPimAlarm al( snd , dt ); | 447 | OPimAlarm al( snd , dt ); |
309 | ev.notifiers().add( al ); | 448 | ev.notifiers().add( al ); |
310 | } | 449 | } |
311 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { | 450 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { |
312 | ev.setUid( 1 ); | 451 | ev.setUid( 1 ); |
313 | } | 452 | } |
314 | if ( ev.hasRecurrence() ) | 453 | if ( ev.hasRecurrence() ) |
315 | m_rep.insert( ev.uid(), ev ); | 454 | m_rep.insert( ev.uid(), ev ); |
316 | else | 455 | else |
317 | m_raw.insert( ev.uid(), ev ); | 456 | m_raw.insert( ev.uid(), ev ); |
318 | 457 | ||
319 | } | 458 | } |
320 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { | 459 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { |
321 | // qWarning(" setting %s", value.latin1() ); | 460 | // qWarning(" setting %s", value.latin1() ); |
322 | switch( id ) { | 461 | switch( id ) { |
323 | case FDescription: | 462 | case FDescription: |
324 | e.setDescription( value ); | 463 | e.setDescription( value ); |
325 | break; | 464 | break; |
326 | case FLocation: | 465 | case FLocation: |
327 | e.setLocation( value ); | 466 | e.setLocation( value ); |
328 | break; | 467 | break; |
329 | case FCategories: | 468 | case FCategories: |
330 | e.setCategories( e.idsFromString( value ) ); | 469 | e.setCategories( e.idsFromString( value ) ); |
331 | break; | 470 | break; |
332 | case FUid: | 471 | case FUid: |
333 | e.setUid( value.toInt() ); | 472 | e.setUid( value.toInt() ); |
334 | break; | 473 | break; |
335 | case FType: | 474 | case FType: |
336 | if ( value == "AllDay" ) { | 475 | if ( value == "AllDay" ) { |
337 | e.setAllDay( true ); | 476 | e.setAllDay( true ); |
338 | e.setTimeZone( "UTC" ); | 477 | e.setTimeZone( "UTC" ); |
339 | } | 478 | } |
340 | break; | 479 | break; |
341 | case FAlarm: | 480 | case FAlarm: |
342 | alarmTime = value.toInt(); | 481 | alarmTime = value.toInt(); |
343 | break; | 482 | break; |
344 | case FSound: | 483 | case FSound: |
345 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; | 484 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; |
346 | break; | 485 | break; |
347 | // recurrence stuff | 486 | // recurrence stuff |
348 | case FRType: | 487 | case FRType: |
349 | if ( value == "Daily" ) | 488 | if ( value == "Daily" ) |
350 | recur()->setType( ORecur::Daily ); | 489 | recur()->setType( ORecur::Daily ); |
351 | else if ( value == "Weekly" ) | 490 | else if ( value == "Weekly" ) |
352 | recur()->setType( ORecur::Weekly); | 491 | recur()->setType( ORecur::Weekly); |
353 | else if ( value == "MonthlyDay" ) | 492 | else if ( value == "MonthlyDay" ) |
354 | recur()->setType( ORecur::MonthlyDay ); | 493 | recur()->setType( ORecur::MonthlyDay ); |
355 | else if ( value == "MonthlyDate" ) | 494 | else if ( value == "MonthlyDate" ) |
356 | recur()->setType( ORecur::MonthlyDate ); | 495 | recur()->setType( ORecur::MonthlyDate ); |
357 | else if ( value == "Yearly" ) | 496 | else if ( value == "Yearly" ) |
358 | recur()->setType( ORecur::Yearly ); | 497 | recur()->setType( ORecur::Yearly ); |
359 | else | 498 | else |
360 | recur()->setType( ORecur::NoRepeat ); | 499 | recur()->setType( ORecur::NoRepeat ); |
361 | break; | 500 | break; |
362 | case FRWeekdays: | 501 | case FRWeekdays: |
363 | recur()->setDays( value.toInt() ); | 502 | recur()->setDays( value.toInt() ); |
364 | break; | 503 | break; |
365 | case FRPosition: | 504 | case FRPosition: |
366 | recur()->setPosition( value.toInt() ); | 505 | recur()->setPosition( value.toInt() ); |
367 | break; | 506 | break; |
368 | case FRFreq: | 507 | case FRFreq: |
369 | recur()->setFrequency( value.toInt() ); | 508 | recur()->setFrequency( value.toInt() ); |
370 | break; | 509 | break; |
371 | case FRHasEndDate: | 510 | case FRHasEndDate: |
372 | recur()->setHasEndDate( value.toInt() ); | 511 | recur()->setHasEndDate( value.toInt() ); |
373 | break; | 512 | break; |
374 | case FREndDate: { | 513 | case FREndDate: { |
375 | rp_end = (time_t) value.toLong(); | 514 | rp_end = (time_t) value.toLong(); |
376 | break; | 515 | break; |
377 | } | 516 | } |
378 | case FRStart: { | 517 | case FRStart: { |
379 | start = (time_t) value.toLong(); | 518 | start = (time_t) value.toLong(); |
380 | break; | 519 | break; |
381 | } | 520 | } |
382 | case FREnd: { | 521 | case FREnd: { |
383 | end = ( (time_t) value.toLong() ); | 522 | end = ( (time_t) value.toLong() ); |
384 | break; | 523 | break; |
385 | } | 524 | } |
386 | case FNote: | 525 | case FNote: |
387 | e.setNote( value ); | 526 | e.setNote( value ); |
388 | break; | 527 | break; |
389 | case FCreated: | 528 | case FCreated: |
390 | created = value.toInt(); | 529 | created = value.toInt(); |
391 | break; | 530 | break; |
531 | case FRecParent: | ||
532 | e.setParent( value.toInt() ); | ||
533 | break; | ||
534 | case FRecChildren:{ | ||
535 | QStringList list = QStringList::split(' ', value ); | ||
536 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | ||
537 | e.addChild( (*it).toInt() ); | ||
538 | } | ||
539 | } | ||
540 | break; | ||
541 | case FExceptions:{ | ||
542 | QStringList list = QStringList::split(' ', value ); | ||
543 | for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | ||
544 | QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); | ||
545 | qWarning("adding exception %s", date.toString().latin1() ); | ||
546 | recur()->exceptions().append( date ); | ||
547 | } | ||
548 | } | ||
549 | break; | ||
550 | case FTimeZone: | ||
551 | if ( value != "None" ) | ||
552 | e.setTimeZone( value ); | ||
553 | break; | ||
392 | default: | 554 | default: |
393 | break; | 555 | break; |
394 | } | 556 | } |
395 | } | 557 | } |
diff --git a/libopie2/opiepim/core/orecur.cpp b/libopie2/opiepim/core/orecur.cpp index e6a4787..e3b45b4 100644 --- a/libopie2/opiepim/core/orecur.cpp +++ b/libopie2/opiepim/core/orecur.cpp | |||
@@ -1,446 +1,510 @@ | |||
1 | #include <time.h> | ||
2 | |||
1 | #include <qshared.h> | 3 | #include <qshared.h> |
2 | 4 | ||
3 | #include <qtopia/timeconversion.h> | 5 | #include <qtopia/timeconversion.h> |
4 | 6 | ||
7 | #include "otimezone.h" | ||
5 | #include "orecur.h" | 8 | #include "orecur.h" |
6 | 9 | ||
7 | struct ORecur::Data : public QShared { | 10 | struct ORecur::Data : public QShared { |
8 | Data() : QShared() { | 11 | Data() : QShared() { |
9 | type = ORecur::NoRepeat; | 12 | type = ORecur::NoRepeat; |
10 | freq = -1; | 13 | freq = -1; |
11 | days = 0; | 14 | days = 0; |
12 | pos = 0; | 15 | pos = 0; |
13 | create = QDateTime::currentDateTime(); | 16 | create = QDateTime::currentDateTime(); |
14 | hasEnd = FALSE; | 17 | hasEnd = FALSE; |
15 | end = QDate::currentDate(); | 18 | end = QDate::currentDate(); |
16 | } | 19 | } |
17 | char days; // Q_UINT8 for 8 seven days;) | 20 | char days; // Q_UINT8 for 8 seven days;) |
18 | ORecur::RepeatType type; | 21 | ORecur::RepeatType type; |
19 | int freq; | 22 | int freq; |
20 | int pos; | 23 | int pos; |
21 | bool hasEnd : 1; | 24 | bool hasEnd : 1; |
22 | QDate end; | 25 | QDate end; |
23 | QDateTime create; | 26 | QDateTime create; |
24 | int rep; | 27 | int rep; |
25 | QString app; | 28 | QString app; |
26 | ExceptionList list; | 29 | ExceptionList list; |
27 | QDate start; | 30 | QDate start; |
28 | }; | 31 | }; |
29 | 32 | ||
30 | 33 | ||
31 | ORecur::ORecur() { | 34 | ORecur::ORecur() { |
32 | data = new Data; | 35 | data = new Data; |
33 | } | 36 | } |
34 | ORecur::ORecur( const ORecur& rec) | 37 | ORecur::ORecur( const ORecur& rec) |
35 | : data( rec.data ) | 38 | : data( rec.data ) |
36 | { | 39 | { |
37 | data->ref(); | 40 | data->ref(); |
38 | } | 41 | } |
39 | ORecur::~ORecur() { | 42 | ORecur::~ORecur() { |
40 | if ( data->deref() ) { | 43 | if ( data->deref() ) { |
41 | delete data; | 44 | delete data; |
42 | data = 0l; | 45 | data = 0l; |
43 | } | 46 | } |
44 | } | 47 | } |
45 | void ORecur::deref() { | 48 | void ORecur::deref() { |
46 | if ( data->deref() ) { | 49 | if ( data->deref() ) { |
47 | delete data; | 50 | delete data; |
48 | data = 0l; | 51 | data = 0l; |
49 | } | 52 | } |
50 | } | 53 | } |
51 | bool ORecur::operator==( const ORecur& )const { | 54 | bool ORecur::operator==( const ORecur& )const { |
52 | return false; | 55 | return false; |
53 | } | 56 | } |
54 | ORecur &ORecur::operator=( const ORecur& re) { | 57 | ORecur &ORecur::operator=( const ORecur& re) { |
55 | if ( *this == re ) return *this; | 58 | if ( *this == re ) return *this; |
56 | 59 | ||
57 | re.data->ref(); | 60 | re.data->ref(); |
58 | deref(); | 61 | deref(); |
59 | data = re.data; | 62 | data = re.data; |
60 | 63 | ||
61 | return *this; | 64 | return *this; |
62 | } | 65 | } |
63 | bool ORecur::doesRecur()const { | 66 | bool ORecur::doesRecur()const { |
64 | return !( type() == NoRepeat ); | 67 | return !( type() == NoRepeat ); |
65 | } | 68 | } |
66 | /* | 69 | /* |
67 | * we try to be smart here | 70 | * we try to be smart here |
68 | * | 71 | * |
69 | */ | 72 | */ |
70 | bool ORecur::doesRecur( const QDate& date ) { | 73 | bool ORecur::doesRecur( const QDate& date ) { |
71 | /* the day before the recurrance */ | 74 | /* the day before the recurrance */ |
72 | QDate da = date.addDays(-1); | 75 | QDate da = date.addDays(-1); |
73 | 76 | ||
74 | QDate recur; | 77 | QDate recur; |
75 | if (!nextOcurrence( da, recur ) ) | 78 | if (!nextOcurrence( da, recur ) ) |
76 | return false; | 79 | return false; |
77 | 80 | ||
78 | return (recur == date); | 81 | return (recur == date); |
79 | } | 82 | } |
80 | // FIXME unuglify! | 83 | // FIXME unuglify! |
81 | // GPL from Datebookdb.cpp | 84 | // GPL from Datebookdb.cpp |
82 | // FIXME exception list! | 85 | // FIXME exception list! |
83 | bool ORecur::nextOcurrence( const QDate& from, QDate& next ) { | 86 | bool ORecur::nextOcurrence( const QDate& from, QDate& next ) { |
87 | bool stillLooking; | ||
88 | stillLooking = p_nextOccurrence( from, next ); | ||
89 | while ( stillLooking && data->list.contains(next) ) | ||
90 | stillLooking = p_nextOccurrence( next.addDays(1), next ); | ||
91 | |||
92 | return stillLooking; | ||
93 | } | ||
94 | bool ORecur::p_nextOccurrence( const QDate& from, QDate& next ) { | ||
84 | 95 | ||
85 | // easy checks, first are we too far in the future or too far in the past? | 96 | // easy checks, first are we too far in the future or too far in the past? |
86 | QDate tmpDate; | 97 | QDate tmpDate; |
87 | int freq = frequency(); | 98 | int freq = frequency(); |
88 | int diff, diff2, a; | 99 | int diff, diff2, a; |
89 | int iday, imonth, iyear; | 100 | int iday, imonth, iyear; |
90 | int dayOfWeek = 0; | 101 | int dayOfWeek = 0; |
91 | int firstOfWeek = 0; | 102 | int firstOfWeek = 0; |
92 | int weekOfMonth; | 103 | int weekOfMonth; |
93 | 104 | ||
94 | 105 | ||
95 | if (hasEndDate() && endDate() < from) | 106 | if (hasEndDate() && endDate() < from) |
96 | return FALSE; | 107 | return FALSE; |
97 | 108 | ||
98 | if (start() >= from) { | 109 | if (start() >= from ) { |
99 | next = start(); | 110 | next = start(); |
100 | return TRUE; | 111 | return TRUE; |
101 | } | 112 | } |
102 | 113 | ||
103 | switch ( type() ) { | 114 | switch ( type() ) { |
104 | case Weekly: | 115 | case Weekly: |
105 | /* weekly is just daily by 7 */ | 116 | /* weekly is just daily by 7 */ |
106 | /* first convert the repeatPattern.Days() mask to the next | 117 | /* first convert the repeatPattern.Days() mask to the next |
107 | day of week valid after from */ | 118 | day of week valid after from */ |
108 | dayOfWeek = from.dayOfWeek(); | 119 | dayOfWeek = from.dayOfWeek(); |
109 | dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ | 120 | dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ |
110 | 121 | ||
111 | /* this is done in case freq > 1 and from in week not | 122 | /* this is done in case freq > 1 and from in week not |
112 | for this round */ | 123 | for this round */ |
113 | // firstOfWeek = 0; this is already done at decl. | 124 | // firstOfWeek = 0; this is already done at decl. |
114 | while(!((1 << firstOfWeek) & days() )) | 125 | while(!((1 << firstOfWeek) & days() )) |
115 | firstOfWeek++; | 126 | firstOfWeek++; |
116 | 127 | ||
117 | /* there is at least one 'day', or there would be no event */ | 128 | /* there is at least one 'day', or there would be no event */ |
118 | while(!((1 << (dayOfWeek % 7)) & days() )) | 129 | while(!((1 << (dayOfWeek % 7)) & days() )) |
119 | dayOfWeek++; | 130 | dayOfWeek++; |
120 | 131 | ||
121 | dayOfWeek = dayOfWeek % 7; /* the actual day of week */ | 132 | dayOfWeek = dayOfWeek % 7; /* the actual day of week */ |
122 | dayOfWeek -= start().dayOfWeek() -1; | 133 | dayOfWeek -= start().dayOfWeek() -1; |
123 | 134 | ||
124 | firstOfWeek = firstOfWeek % 7; /* the actual first of week */ | 135 | firstOfWeek = firstOfWeek % 7; /* the actual first of week */ |
125 | firstOfWeek -= start().dayOfWeek() -1; | 136 | firstOfWeek -= start().dayOfWeek() -1; |
126 | 137 | ||
127 | // dayOfWeek may be negitive now | 138 | // dayOfWeek may be negitive now |
128 | // day of week is number of days to add to start day | 139 | // day of week is number of days to add to start day |
129 | 140 | ||
130 | freq *= 7; | 141 | freq *= 7; |
131 | // FALL-THROUGH !!!!! | 142 | // FALL-THROUGH !!!!! |
132 | case Daily: | 143 | case Daily: |
133 | // the add is for the possible fall through from weekly */ | 144 | // the add is for the possible fall through from weekly */ |
134 | if(start().addDays(dayOfWeek) > from) { | 145 | if(start().addDays(dayOfWeek) > from) { |
135 | /* first week exception */ | 146 | /* first week exception */ |
136 | next = QDate(start().addDays(dayOfWeek) ); | 147 | next = QDate(start().addDays(dayOfWeek) ); |
137 | if ((next > endDate()) | 148 | if ((next > endDate()) |
138 | && hasEndDate() ) | 149 | && hasEndDate() ) |
139 | return FALSE; | 150 | return FALSE; |
140 | return TRUE; | 151 | return TRUE; |
141 | } | 152 | } |
142 | /* if from is middle of a non-week */ | 153 | /* if from is middle of a non-week */ |
143 | 154 | ||
144 | diff = start().addDays(dayOfWeek).daysTo(from) % freq; | 155 | diff = start().addDays(dayOfWeek).daysTo(from) % freq; |
145 | diff2 = start().addDays(firstOfWeek).daysTo(from) % freq; | 156 | diff2 = start().addDays(firstOfWeek).daysTo(from) % freq; |
146 | 157 | ||
147 | if(diff != 0) | 158 | if(diff != 0) |
148 | diff = freq - diff; | 159 | diff = freq - diff; |
149 | if(diff2 != 0) | 160 | if(diff2 != 0) |
150 | diff2 = freq - diff2; | 161 | diff2 = freq - diff2; |
151 | diff = QMIN(diff, diff2); | 162 | diff = QMIN(diff, diff2); |
152 | 163 | ||
153 | next = QDate(from.addDays(diff)); | 164 | next = QDate(from.addDays(diff)); |
154 | if ( (next > endDate()) | 165 | if ( (next > endDate()) |
155 | && hasEndDate() ) | 166 | && hasEndDate() ) |
156 | return FALSE; | 167 | return FALSE; |
157 | return TRUE; | 168 | return TRUE; |
158 | case MonthlyDay: | 169 | case MonthlyDay: |
159 | iday = from.day(); | 170 | iday = from.day(); |
160 | iyear = from.year(); | 171 | iyear = from.year(); |
161 | imonth = from.month(); | 172 | imonth = from.month(); |
162 | /* find equivelent day of month for this month */ | 173 | /* find equivelent day of month for this month */ |
163 | dayOfWeek = start().dayOfWeek(); | 174 | dayOfWeek = start().dayOfWeek(); |
164 | weekOfMonth = (start().day() - 1) / 7; | 175 | weekOfMonth = (start().day() - 1) / 7; |
165 | 176 | ||
166 | /* work out when the next valid month is */ | 177 | /* work out when the next valid month is */ |
167 | a = from.year() - start().year(); | 178 | a = from.year() - start().year(); |
168 | a *= 12; | 179 | a *= 12; |
169 | a = a + (imonth - start().month()); | 180 | a = a + (imonth - start().month()); |
170 | /* a is e.start()monthsFrom(from); */ | 181 | /* a is e.start()monthsFrom(from); */ |
171 | if(a % freq) { | 182 | if(a % freq) { |
172 | a = freq - (a % freq); | 183 | a = freq - (a % freq); |
173 | imonth = from.month() + a; | 184 | imonth = from.month() + a; |
174 | if (imonth > 12) { | 185 | if (imonth > 12) { |
175 | imonth--; | 186 | imonth--; |
176 | iyear += imonth / 12; | 187 | iyear += imonth / 12; |
177 | imonth = imonth % 12; | 188 | imonth = imonth % 12; |
178 | imonth++; | 189 | imonth++; |
179 | } | 190 | } |
180 | } | 191 | } |
181 | /* imonth is now the first month after or on | 192 | /* imonth is now the first month after or on |
182 | from that matches the frequency given */ | 193 | from that matches the frequency given */ |
183 | 194 | ||
184 | /* find for this month */ | 195 | /* find for this month */ |
185 | tmpDate = QDate( iyear, imonth, 1 ); | 196 | tmpDate = QDate( iyear, imonth, 1 ); |
186 | 197 | ||
187 | iday = 1; | 198 | iday = 1; |
188 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 199 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
189 | iday += 7 * weekOfMonth; | 200 | iday += 7 * weekOfMonth; |
190 | while (iday > tmpDate.daysInMonth()) { | 201 | while (iday > tmpDate.daysInMonth()) { |
191 | imonth += freq; | 202 | imonth += freq; |
192 | if (imonth > 12) { | 203 | if (imonth > 12) { |
193 | imonth--; | 204 | imonth--; |
194 | iyear += imonth / 12; | 205 | iyear += imonth / 12; |
195 | imonth = imonth % 12; | 206 | imonth = imonth % 12; |
196 | imonth++; | 207 | imonth++; |
197 | } | 208 | } |
198 | tmpDate = QDate( iyear, imonth, 1 ); | 209 | tmpDate = QDate( iyear, imonth, 1 ); |
199 | /* these loops could go for a while, check end case now */ | 210 | /* these loops could go for a while, check end case now */ |
200 | if ((tmpDate > endDate()) && hasEndDate() ) | 211 | if ((tmpDate > endDate()) && hasEndDate() ) |
201 | return FALSE; | 212 | return FALSE; |
202 | iday = 1; | 213 | iday = 1; |
203 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 214 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
204 | iday += 7 * weekOfMonth; | 215 | iday += 7 * weekOfMonth; |
205 | } | 216 | } |
206 | tmpDate = QDate(iyear, imonth, iday); | 217 | tmpDate = QDate(iyear, imonth, iday); |
207 | 218 | ||
208 | if (tmpDate >= from) { | 219 | if (tmpDate >= from) { |
209 | next = tmpDate; | 220 | next = tmpDate; |
210 | if ((next > endDate() ) && hasEndDate() ) | 221 | if ((next > endDate() ) && hasEndDate() ) |
211 | return FALSE; | 222 | return FALSE; |
212 | return TRUE; | 223 | return TRUE; |
213 | } | 224 | } |
214 | 225 | ||
215 | /* need to find the next iteration */ | 226 | /* need to find the next iteration */ |
216 | do { | 227 | do { |
217 | imonth += freq; | 228 | imonth += freq; |
218 | if (imonth > 12) { | 229 | if (imonth > 12) { |
219 | imonth--; | 230 | imonth--; |
220 | iyear += imonth / 12; | 231 | iyear += imonth / 12; |
221 | imonth = imonth % 12; | 232 | imonth = imonth % 12; |
222 | imonth++; | 233 | imonth++; |
223 | } | 234 | } |
224 | tmpDate = QDate( iyear, imonth, 1 ); | 235 | tmpDate = QDate( iyear, imonth, 1 ); |
225 | /* these loops could go for a while, check end case now */ | 236 | /* these loops could go for a while, check end case now */ |
226 | if ((tmpDate > endDate()) && hasEndDate() ) | 237 | if ((tmpDate > endDate()) && hasEndDate() ) |
227 | return FALSE; | 238 | return FALSE; |
228 | iday = 1; | 239 | iday = 1; |
229 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 240 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
230 | iday += 7 * weekOfMonth; | 241 | iday += 7 * weekOfMonth; |
231 | } while (iday > tmpDate.daysInMonth()); | 242 | } while (iday > tmpDate.daysInMonth()); |
232 | tmpDate = QDate(iyear, imonth, iday); | 243 | tmpDate = QDate(iyear, imonth, iday); |
233 | 244 | ||
234 | next = tmpDate; | 245 | next = tmpDate; |
235 | if ((next > endDate()) && hasEndDate() ) | 246 | if ((next > endDate()) && hasEndDate() ) |
236 | return FALSE; | 247 | return FALSE; |
237 | return TRUE; | 248 | return TRUE; |
238 | case MonthlyDate: | 249 | case MonthlyDate: |
239 | iday = start().day(); | 250 | iday = start().day(); |
240 | iyear = from.year(); | 251 | iyear = from.year(); |
241 | imonth = from.month(); | 252 | imonth = from.month(); |
242 | 253 | ||
243 | a = from.year() - start().year(); | 254 | a = from.year() - start().year(); |
244 | a *= 12; | 255 | a *= 12; |
245 | a = a + (imonth - start().month()); | 256 | a = a + (imonth - start().month()); |
246 | /* a is e.start()monthsFrom(from); */ | 257 | /* a is e.start()monthsFrom(from); */ |
247 | if(a % freq) { | 258 | if(a % freq) { |
248 | a = freq - (a % freq); | 259 | a = freq - (a % freq); |
249 | imonth = from.month() + a; | 260 | imonth = from.month() + a; |
250 | if (imonth > 12) { | 261 | if (imonth > 12) { |
251 | imonth--; | 262 | imonth--; |
252 | iyear += imonth / 12; | 263 | iyear += imonth / 12; |
253 | imonth = imonth % 12; | 264 | imonth = imonth % 12; |
254 | imonth++; | 265 | imonth++; |
255 | } | 266 | } |
256 | } | 267 | } |
257 | /* imonth is now the first month after or on | 268 | /* imonth is now the first month after or on |
258 | from that matches the frequencey given */ | 269 | from that matches the frequencey given */ |
259 | 270 | ||
260 | /* this could go for a while, worse case, 4*12 iterations, probably */ | 271 | /* this could go for a while, worse case, 4*12 iterations, probably */ |
261 | while(!QDate::isValid(iyear, imonth, iday) ) { | 272 | while(!QDate::isValid(iyear, imonth, iday) ) { |
262 | imonth += freq; | 273 | imonth += freq; |
263 | if (imonth > 12) { | 274 | if (imonth > 12) { |
264 | imonth--; | 275 | imonth--; |
265 | iyear += imonth / 12; | 276 | iyear += imonth / 12; |
266 | imonth = imonth % 12; | 277 | imonth = imonth % 12; |
267 | imonth++; | 278 | imonth++; |
268 | } | 279 | } |
269 | /* these loops could go for a while, check end case now */ | 280 | /* these loops could go for a while, check end case now */ |
270 | if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) | 281 | if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) |
271 | return FALSE; | 282 | return FALSE; |
272 | } | 283 | } |
273 | 284 | ||
274 | if(QDate(iyear, imonth, iday) >= from) { | 285 | if(QDate(iyear, imonth, iday) >= from) { |
275 | /* done */ | 286 | /* done */ |
276 | next = QDate(iyear, imonth, iday); | 287 | next = QDate(iyear, imonth, iday); |
277 | if ((next > endDate()) && hasEndDate() ) | 288 | if ((next > endDate()) && hasEndDate() ) |
278 | return FALSE; | 289 | return FALSE; |
279 | return TRUE; | 290 | return TRUE; |
280 | } | 291 | } |
281 | 292 | ||
282 | /* ok, need to cycle */ | 293 | /* ok, need to cycle */ |
283 | imonth += freq; | 294 | imonth += freq; |
284 | imonth--; | 295 | imonth--; |
285 | iyear += imonth / 12; | 296 | iyear += imonth / 12; |
286 | imonth = imonth % 12; | 297 | imonth = imonth % 12; |
287 | imonth++; | 298 | imonth++; |
288 | 299 | ||
289 | while(!QDate::isValid(iyear, imonth, iday) ) { | 300 | while(!QDate::isValid(iyear, imonth, iday) ) { |
290 | imonth += freq; | 301 | imonth += freq; |
291 | imonth--; | 302 | imonth--; |
292 | iyear += imonth / 12; | 303 | iyear += imonth / 12; |
293 | imonth = imonth % 12; | 304 | imonth = imonth % 12; |
294 | imonth++; | 305 | imonth++; |
295 | if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) | 306 | if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) |
296 | return FALSE; | 307 | return FALSE; |
297 | } | 308 | } |
298 | 309 | ||
299 | next = QDate(iyear, imonth, iday); | 310 | next = QDate(iyear, imonth, iday); |
300 | if ((next > endDate()) && hasEndDate() ) | 311 | if ((next > endDate()) && hasEndDate() ) |
301 | return FALSE; | 312 | return FALSE; |
302 | return TRUE; | 313 | return TRUE; |
303 | case Yearly: | 314 | case Yearly: |
304 | iday = start().day(); | 315 | iday = start().day(); |
305 | imonth = start().month(); | 316 | imonth = start().month(); |
306 | iyear = from.year(); // after all, we want to start in this year | 317 | iyear = from.year(); // after all, we want to start in this year |
307 | 318 | ||
308 | diff = 1; | 319 | diff = 1; |
309 | if(imonth == 2 && iday > 28) { | 320 | if(imonth == 2 && iday > 28) { |
310 | /* leap year, and it counts, calculate actual frequency */ | 321 | /* leap year, and it counts, calculate actual frequency */ |
311 | if(freq % 4) | 322 | if(freq % 4) |
312 | if (freq % 2) | 323 | if (freq % 2) |
313 | freq = freq * 4; | 324 | freq = freq * 4; |
314 | else | 325 | else |
315 | freq = freq * 2; | 326 | freq = freq * 2; |
316 | /* else divides by 4 already, leave freq alone */ | 327 | /* else divides by 4 already, leave freq alone */ |
317 | diff = 4; | 328 | diff = 4; |
318 | } | 329 | } |
319 | 330 | ||
320 | a = from.year() - start().year(); | 331 | a = from.year() - start().year(); |
321 | if(a % freq) { | 332 | if(a % freq) { |
322 | a = freq - (a % freq); | 333 | a = freq - (a % freq); |
323 | iyear = iyear + a; | 334 | iyear = iyear + a; |
324 | } | 335 | } |
325 | 336 | ||
326 | /* under the assumption we won't hit one of the special not-leap years twice */ | 337 | /* under the assumption we won't hit one of the special not-leap years twice */ |
327 | if(!QDate::isValid(iyear, imonth, iday)) { | 338 | if(!QDate::isValid(iyear, imonth, iday)) { |
328 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ | 339 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ |
329 | iyear += freq; | 340 | iyear += freq; |
330 | } | 341 | } |
331 | 342 | ||
332 | if(QDate(iyear, imonth, iday) >= from) { | 343 | if(QDate(iyear, imonth, iday) >= from) { |
333 | next = QDate(iyear, imonth, iday); | 344 | next = QDate(iyear, imonth, iday); |
334 | 345 | ||
335 | if ((next > endDate()) && hasEndDate() ) | 346 | if ((next > endDate()) && hasEndDate() ) |
336 | return FALSE; | 347 | return FALSE; |
337 | return TRUE; | 348 | return TRUE; |
338 | } | 349 | } |
339 | /* iyear == from.year(), need to advance again */ | 350 | /* iyear == from.year(), need to advance again */ |
340 | iyear += freq; | 351 | iyear += freq; |
341 | /* under the assumption we won't hit one of the special not-leap years twice */ | 352 | /* under the assumption we won't hit one of the special not-leap years twice */ |
342 | if(!QDate::isValid(iyear, imonth, iday)) { | 353 | if(!QDate::isValid(iyear, imonth, iday)) { |
343 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ | 354 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ |
344 | iyear += freq; | 355 | iyear += freq; |
345 | } | 356 | } |
346 | 357 | ||
347 | next = QDate(iyear, imonth, iday); | 358 | next = QDate(iyear, imonth, iday); |
348 | if ((next > endDate()) && hasEndDate() ) | 359 | if ((next > endDate()) && hasEndDate() ) |
349 | return FALSE; | 360 | return FALSE; |
350 | return TRUE; | 361 | return TRUE; |
351 | default: | 362 | default: |
352 | return FALSE; | 363 | return FALSE; |
353 | } | 364 | } |
354 | } | 365 | } |
355 | ORecur::RepeatType ORecur::type()const{ | 366 | ORecur::RepeatType ORecur::type()const{ |
356 | return data->type; | 367 | return data->type; |
357 | } | 368 | } |
358 | int ORecur::frequency()const { | 369 | int ORecur::frequency()const { |
359 | return data->freq; | 370 | return data->freq; |
360 | } | 371 | } |
361 | int ORecur::position()const { | 372 | int ORecur::position()const { |
362 | return data->pos; | 373 | return data->pos; |
363 | } | 374 | } |
364 | char ORecur::days() const{ | 375 | char ORecur::days() const{ |
365 | return data->days; | 376 | return data->days; |
366 | } | 377 | } |
367 | bool ORecur::hasEndDate()const { | 378 | bool ORecur::hasEndDate()const { |
368 | return data->hasEnd; | 379 | return data->hasEnd; |
369 | } | 380 | } |
370 | QDate ORecur::endDate()const { | 381 | QDate ORecur::endDate()const { |
371 | return data->end; | 382 | return data->end; |
372 | } | 383 | } |
373 | QDate ORecur::start()const{ | 384 | QDate ORecur::start()const{ |
374 | return data->start; | 385 | return data->start; |
375 | } | 386 | } |
376 | QDateTime ORecur::createdDateTime()const { | 387 | QDateTime ORecur::createdDateTime()const { |
377 | return data->create; | 388 | return data->create; |
378 | } | 389 | } |
379 | int ORecur::repetition()const { | 390 | int ORecur::repetition()const { |
380 | return data->rep; | 391 | return data->rep; |
381 | } | 392 | } |
382 | QString ORecur::service()const { | 393 | QString ORecur::service()const { |
383 | return data->app; | 394 | return data->app; |
384 | } | 395 | } |
385 | ORecur::ExceptionList& ORecur::exceptions() { | 396 | ORecur::ExceptionList& ORecur::exceptions() { |
386 | return data->list; | 397 | return data->list; |
387 | } | 398 | } |
388 | void ORecur::setType( const RepeatType& z) { | 399 | void ORecur::setType( const RepeatType& z) { |
389 | checkOrModify(); | 400 | checkOrModify(); |
390 | data->type = z; | 401 | data->type = z; |
391 | } | 402 | } |
392 | void ORecur::setFrequency( int freq ) { | 403 | void ORecur::setFrequency( int freq ) { |
393 | checkOrModify(); | 404 | checkOrModify(); |
394 | data->freq = freq; | 405 | data->freq = freq; |
395 | } | 406 | } |
396 | void ORecur::setPosition( int pos ) { | 407 | void ORecur::setPosition( int pos ) { |
397 | checkOrModify(); | 408 | checkOrModify(); |
398 | data->pos = pos; | 409 | data->pos = pos; |
399 | } | 410 | } |
400 | void ORecur::setDays( char c ) { | 411 | void ORecur::setDays( char c ) { |
401 | checkOrModify(); | 412 | checkOrModify(); |
402 | data->days = c; | 413 | data->days = c; |
403 | } | 414 | } |
404 | void ORecur::setEndDate( const QDate& dt) { | 415 | void ORecur::setEndDate( const QDate& dt) { |
405 | checkOrModify(); | 416 | checkOrModify(); |
406 | data->end = dt; | 417 | data->end = dt; |
407 | } | 418 | } |
408 | void ORecur::setCreatedDateTime( const QDateTime& t) { | 419 | void ORecur::setCreatedDateTime( const QDateTime& t) { |
409 | checkOrModify(); | 420 | checkOrModify(); |
410 | data->create = t; | 421 | data->create = t; |
411 | } | 422 | } |
412 | void ORecur::setHasEndDate( bool b) { | 423 | void ORecur::setHasEndDate( bool b) { |
413 | checkOrModify(); | 424 | checkOrModify(); |
414 | data->hasEnd = b; | 425 | data->hasEnd = b; |
415 | } | 426 | } |
416 | void ORecur::setRepitition( int rep ) { | 427 | void ORecur::setRepitition( int rep ) { |
417 | checkOrModify(); | 428 | checkOrModify(); |
418 | data->rep = rep; | 429 | data->rep = rep; |
419 | } | 430 | } |
420 | void ORecur::setService( const QString& app ) { | 431 | void ORecur::setService( const QString& app ) { |
421 | checkOrModify(); | 432 | checkOrModify(); |
422 | data->app = app; | 433 | data->app = app; |
423 | } | 434 | } |
424 | void ORecur::setStart( const QDate& dt ) { | 435 | void ORecur::setStart( const QDate& dt ) { |
425 | checkOrModify(); | 436 | checkOrModify(); |
426 | data->start = dt; | 437 | data->start = dt; |
427 | } | 438 | } |
428 | void ORecur::checkOrModify() { | 439 | void ORecur::checkOrModify() { |
429 | if ( data->count != 1 ) { | 440 | if ( data->count != 1 ) { |
430 | data->deref(); | 441 | data->deref(); |
431 | Data* d2 = new Data; | 442 | Data* d2 = new Data; |
432 | d2->days = data->days; | 443 | d2->days = data->days; |
433 | d2->type = data->type; | 444 | d2->type = data->type; |
434 | d2->freq = data->freq; | 445 | d2->freq = data->freq; |
435 | d2->pos = data->pos; | 446 | d2->pos = data->pos; |
436 | d2->hasEnd = data->hasEnd; | 447 | d2->hasEnd = data->hasEnd; |
437 | d2->end = data->end; | 448 | d2->end = data->end; |
438 | d2->create = data->create; | 449 | d2->create = data->create; |
439 | d2->rep = data->rep; | 450 | d2->rep = data->rep; |
440 | d2->app = data->app; | 451 | d2->app = data->app; |
441 | d2->list = data->list; | 452 | d2->list = data->list; |
442 | d2->start = data->start; | 453 | d2->start = data->start; |
443 | data = d2; | 454 | data = d2; |
444 | } | 455 | } |
445 | } | 456 | } |
457 | QString ORecur::toString()const { | ||
458 | QString buf; | ||
459 | |||
460 | buf += " rtype=\""; | ||
461 | switch ( data->type ) { | ||
462 | case ORecur::Daily: | ||
463 | buf += "Daily"; | ||
464 | break; | ||
465 | case ORecur::Weekly: | ||
466 | buf += "Weekly"; | ||
467 | break; | ||
468 | case ORecur::MonthlyDay: | ||
469 | buf += "MonthlyDay"; | ||
470 | break; | ||
471 | case ORecur::MonthlyDate: | ||
472 | buf += "MonthlyDate"; | ||
473 | break; | ||
474 | case ORecur::Yearly: | ||
475 | buf += "Yearly"; | ||
476 | break; | ||
477 | default: | ||
478 | buf += "NoRepeat"; | ||
479 | break; | ||
480 | } | ||
481 | buf += "\""; | ||
482 | if (data->days > 0 ) | ||
483 | buf += " rweekdays=\"" + QString::number( static_cast<int>( data->days ) ) + "\""; | ||
484 | if ( data->pos != 0 ) | ||
485 | buf += " rposition=\"" + QString::number(data->pos ) + "\""; | ||
486 | |||
487 | buf += " rfreq=\"" + QString::number( data->freq ) + "\""; | ||
488 | buf += " rhasenddate=\"" + QString::number( static_cast<int>( data->hasEnd ) ) + "\""; | ||
489 | if ( data->hasEnd ) | ||
490 | buf += " enddt=\"" | ||
491 | + QString::number( OTimeZone::utc().fromUTCDateTime( QDateTime( data->end, QTime(12,0,0) ) ) ) | ||
492 | + "\""; | ||
493 | buf += " created=\"" + QString::number( OTimeZone::utc().fromUTCDateTime( data->create ) ) + "\""; | ||
494 | |||
495 | if ( data->list.isEmpty() ) return buf; | ||
496 | // save exceptions list here!! | ||
497 | ExceptionList::ConstIterator it; | ||
498 | ExceptionList list = data->list; | ||
499 | buf += " exceptions=\""; | ||
500 | QDate date; | ||
501 | for ( it = list.begin(); it != list.end(); ++it ) { | ||
502 | date = (*it); | ||
503 | if ( it != list.begin() ) buf += " "; | ||
504 | |||
505 | buf += QCString().sprintf("%04d%02d%02d", date.year(), date.month(), date.day() ); | ||
506 | } | ||
507 | buf += "\""; | ||
446 | 508 | ||
509 | return buf; | ||
510 | } | ||
diff --git a/libopie2/opiepim/core/orecur.h b/libopie2/opiepim/core/orecur.h index 1e0014b..b214b3f 100644 --- a/libopie2/opiepim/core/orecur.h +++ b/libopie2/opiepim/core/orecur.h | |||
@@ -1,87 +1,91 @@ | |||
1 | /* | 1 | /* |
2 | * GPL from TT | 2 | * GPL from TT |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #ifndef OPIE_RECUR_H | 5 | #ifndef OPIE_RECUR_H |
6 | #define OPIE_RECUR_H | 6 | #define OPIE_RECUR_H |
7 | 7 | ||
8 | #include <sys/types.h> | 8 | #include <sys/types.h> |
9 | 9 | ||
10 | #include <qdatetime.h> | 10 | #include <qdatetime.h> |
11 | #include <qvaluelist.h> | 11 | #include <qvaluelist.h> |
12 | 12 | ||
13 | 13 | ||
14 | class ORecur { | 14 | class ORecur { |
15 | public: | 15 | public: |
16 | typedef QValueList<QDate> ExceptionList; | 16 | typedef QValueList<QDate> ExceptionList; |
17 | enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, | 17 | enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, |
18 | MonthlyDate, Yearly }; | 18 | MonthlyDate, Yearly }; |
19 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, | 19 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, |
20 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; | 20 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; |
21 | ORecur(); | 21 | ORecur(); |
22 | ORecur( const ORecur& ); | 22 | ORecur( const ORecur& ); |
23 | ~ORecur(); | 23 | ~ORecur(); |
24 | 24 | ||
25 | ORecur &operator=( const ORecur& ); | 25 | ORecur &operator=( const ORecur& ); |
26 | bool operator==(const ORecur& )const; | 26 | bool operator==(const ORecur& )const; |
27 | 27 | ||
28 | bool doesRecur()const; | 28 | bool doesRecur()const; |
29 | /* if it recurrs on that day */ | 29 | /* if it recurrs on that day */ |
30 | bool doesRecur( const QDate& ); | 30 | bool doesRecur( const QDate& ); |
31 | RepeatType type()const; | 31 | RepeatType type()const; |
32 | int frequency()const; | 32 | int frequency()const; |
33 | int position()const; | 33 | int position()const; |
34 | char days()const; | 34 | char days()const; |
35 | bool hasEndDate()const; | 35 | bool hasEndDate()const; |
36 | QDate start()const; | 36 | QDate start()const; |
37 | QDate endDate()const; | 37 | QDate endDate()const; |
38 | QDateTime createdDateTime()const; | 38 | QDateTime createdDateTime()const; |
39 | /** | 39 | /** |
40 | * starting on monday=0, sunday=6 | 40 | * starting on monday=0, sunday=6 |
41 | * for convience | 41 | * for convience |
42 | */ | 42 | */ |
43 | bool repeatOnWeekDay( int day )const; | 43 | bool repeatOnWeekDay( int day )const; |
44 | 44 | ||
45 | /** | 45 | /** |
46 | * FromWhereToStart is not included!!! | 46 | * FromWhereToStart is not included!!! |
47 | */ | 47 | */ |
48 | bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); | 48 | bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); |
49 | 49 | ||
50 | /** | 50 | /** |
51 | * The module this ORecur belongs to | 51 | * The module this ORecur belongs to |
52 | */ | 52 | */ |
53 | QString service()const; | 53 | QString service()const; |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * reference to the exception list | 56 | * reference to the exception list |
57 | */ | 57 | */ |
58 | ExceptionList &exceptions(); | 58 | ExceptionList &exceptions(); |
59 | 59 | ||
60 | /** | 60 | /** |
61 | * the current repetition | 61 | * the current repetition |
62 | */ | 62 | */ |
63 | int repetition()const; | 63 | int repetition()const; |
64 | 64 | ||
65 | void setType( const RepeatType& ); | 65 | void setType( const RepeatType& ); |
66 | void setFrequency( int freq ); | 66 | void setFrequency( int freq ); |
67 | void setPosition( int pos ); | 67 | void setPosition( int pos ); |
68 | void setDays( char c); | 68 | void setDays( char c); |
69 | void setEndDate( const QDate& dt ); | 69 | void setEndDate( const QDate& dt ); |
70 | void setStart( const QDate& dt ); | 70 | void setStart( const QDate& dt ); |
71 | void setCreatedDateTime( const QDateTime& ); | 71 | void setCreatedDateTime( const QDateTime& ); |
72 | void setHasEndDate( bool b ); | 72 | void setHasEndDate( bool b ); |
73 | void setRepitition(int ); | 73 | void setRepitition(int ); |
74 | 74 | ||
75 | void setService( const QString& ser ); | 75 | void setService( const QString& ser ); |
76 | |||
77 | /* almost internal */ | ||
78 | QString toString()const; | ||
76 | private: | 79 | private: |
80 | bool p_nextOccurrence( const QDate& from, QDate& next ); | ||
77 | void deref(); | 81 | void deref(); |
78 | inline void checkOrModify(); | 82 | inline void checkOrModify(); |
79 | 83 | ||
80 | 84 | ||
81 | class Data; | 85 | class Data; |
82 | Data* data; | 86 | Data* data; |
83 | class ORecurPrivate; | 87 | class ORecurPrivate; |
84 | ORecurPrivate *d; | 88 | ORecurPrivate *d; |
85 | }; | 89 | }; |
86 | 90 | ||
87 | #endif | 91 | #endif |
diff --git a/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp index ada596c..c3eeee2 100644 --- a/libopie2/opiepim/oevent.cpp +++ b/libopie2/opiepim/oevent.cpp | |||
@@ -1,431 +1,489 @@ | |||
1 | #include <qshared.h> | 1 | #include <qshared.h> |
2 | 2 | ||
3 | #include <qpe/palmtopuidgen.h> | 3 | #include <qpe/palmtopuidgen.h> |
4 | #include <qpe/categories.h> | 4 | #include <qpe/categories.h> |
5 | 5 | ||
6 | #include "orecur.h" | 6 | #include "orecur.h" |
7 | #include "opimresolver.h" | 7 | #include "opimresolver.h" |
8 | #include "opimnotifymanager.h" | 8 | #include "opimnotifymanager.h" |
9 | 9 | ||
10 | #include "oevent.h" | 10 | #include "oevent.h" |
11 | 11 | ||
12 | int OCalendarHelper::week( const QDate& date) { | 12 | int OCalendarHelper::week( const QDate& date) { |
13 | // Calculates the week this date is in within that | 13 | // Calculates the week this date is in within that |
14 | // month. Equals the "row" is is in in the month view | 14 | // month. Equals the "row" is is in in the month view |
15 | int week = 1; | 15 | int week = 1; |
16 | QDate tmp( date.year(), date.month(), 1 ); | 16 | QDate tmp( date.year(), date.month(), 1 ); |
17 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) | 17 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) |
18 | ++week; | 18 | ++week; |
19 | 19 | ||
20 | week += ( date.day() - 1 ) / 7; | 20 | week += ( date.day() - 1 ) / 7; |
21 | 21 | ||
22 | return week; | 22 | return week; |
23 | } | 23 | } |
24 | int OCalendarHelper::ocurrence( const QDate& date) { | 24 | int OCalendarHelper::ocurrence( const QDate& date) { |
25 | // calculates the number of occurrances of this day of the | 25 | // calculates the number of occurrances of this day of the |
26 | // week till the given date (e.g 3rd Wednesday of the month) | 26 | // week till the given date (e.g 3rd Wednesday of the month) |
27 | return ( date.day() - 1 ) / 7 + 1; | 27 | return ( date.day() - 1 ) / 7 + 1; |
28 | } | 28 | } |
29 | int OCalendarHelper::dayOfWeek( char day ) { | 29 | int OCalendarHelper::dayOfWeek( char day ) { |
30 | int dayOfWeek = 1; | 30 | int dayOfWeek = 1; |
31 | char i = ORecur::MON; | 31 | char i = ORecur::MON; |
32 | while ( !( i & day ) && i <= ORecur::SUN ) { | 32 | while ( !( i & day ) && i <= ORecur::SUN ) { |
33 | i <<= 1; | 33 | i <<= 1; |
34 | ++dayOfWeek; | 34 | ++dayOfWeek; |
35 | } | 35 | } |
36 | return dayOfWeek; | 36 | return dayOfWeek; |
37 | } | 37 | } |
38 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { | 38 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { |
39 | return ( second.year() - first.year() ) * 12 + | 39 | return ( second.year() - first.year() ) * 12 + |
40 | second.month() - first.month(); | 40 | second.month() - first.month(); |
41 | } | 41 | } |
42 | 42 | ||
43 | struct OEvent::Data : public QShared { | 43 | struct OEvent::Data : public QShared { |
44 | Data() : QShared() { | 44 | Data() : QShared() { |
45 | child = 0; | ||
45 | recur = 0; | 46 | recur = 0; |
46 | manager = 0; | 47 | manager = 0; |
47 | isAllDay = false; | 48 | isAllDay = false; |
49 | parent = 0; | ||
48 | } | 50 | } |
49 | ~Data() { | 51 | ~Data() { |
50 | delete manager; | 52 | delete manager; |
51 | delete recur; | 53 | delete recur; |
52 | } | 54 | } |
53 | QString description; | 55 | QString description; |
54 | QString location; | 56 | QString location; |
55 | OPimNotifyManager* manager; | 57 | OPimNotifyManager* manager; |
56 | ORecur* recur; | 58 | ORecur* recur; |
57 | QString note; | 59 | QString note; |
58 | QDateTime created; | 60 | QDateTime created; |
59 | QDateTime start; | 61 | QDateTime start; |
60 | QDateTime end; | 62 | QDateTime end; |
61 | bool isAllDay : 1; | 63 | bool isAllDay : 1; |
62 | QString timezone; | 64 | QString timezone; |
65 | QArray<int>* child; | ||
66 | int parent; | ||
63 | }; | 67 | }; |
64 | 68 | ||
65 | OEvent::OEvent( int uid ) | 69 | OEvent::OEvent( int uid ) |
66 | : OPimRecord( uid ) { | 70 | : OPimRecord( uid ) { |
67 | data = new Data; | 71 | data = new Data; |
68 | } | 72 | } |
69 | OEvent::OEvent( const OEvent& ev) | 73 | OEvent::OEvent( const OEvent& ev) |
70 | : OPimRecord( ev ), data( ev.data ) | 74 | : OPimRecord( ev ), data( ev.data ) |
71 | { | 75 | { |
72 | data->ref(); | 76 | data->ref(); |
73 | } | 77 | } |
74 | OEvent::~OEvent() { | 78 | OEvent::~OEvent() { |
75 | if ( data->deref() ) { | 79 | if ( data->deref() ) { |
76 | delete data; | 80 | delete data; |
77 | data = 0; | 81 | data = 0; |
78 | } | 82 | } |
79 | } | 83 | } |
80 | OEvent& OEvent::operator=( const OEvent& ev) { | 84 | OEvent& OEvent::operator=( const OEvent& ev) { |
81 | if ( *this == ev ) return *this; | 85 | if ( *this == ev ) return *this; |
82 | 86 | ||
83 | OPimRecord::operator=( ev ); | 87 | OPimRecord::operator=( ev ); |
84 | ev.data->ref(); | 88 | ev.data->ref(); |
85 | deref(); | 89 | deref(); |
86 | data = ev.data; | 90 | data = ev.data; |
87 | 91 | ||
88 | 92 | ||
89 | return *this; | 93 | return *this; |
90 | } | 94 | } |
91 | QString OEvent::description()const { | 95 | QString OEvent::description()const { |
92 | return data->description; | 96 | return data->description; |
93 | } | 97 | } |
94 | void OEvent::setDescription( const QString& description ) { | 98 | void OEvent::setDescription( const QString& description ) { |
95 | changeOrModify(); | 99 | changeOrModify(); |
96 | data->description = description; | 100 | data->description = description; |
97 | } | 101 | } |
98 | void OEvent::setLocation( const QString& loc ) { | 102 | void OEvent::setLocation( const QString& loc ) { |
99 | changeOrModify(); | 103 | changeOrModify(); |
100 | data->location = loc; | 104 | data->location = loc; |
101 | } | 105 | } |
102 | QString OEvent::location()const { | 106 | QString OEvent::location()const { |
103 | return data->location; | 107 | return data->location; |
104 | } | 108 | } |
105 | OPimNotifyManager &OEvent::notifiers() { | 109 | OPimNotifyManager &OEvent::notifiers()const { |
106 | // I hope we can skip the changeOrModify here | 110 | // I hope we can skip the changeOrModify here |
107 | // the notifier should take care of it | 111 | // the notifier should take care of it |
108 | // and OPimNotify is shared too | 112 | // and OPimNotify is shared too |
109 | if (!data->manager ) | 113 | if (!data->manager ) |
110 | data->manager = new OPimNotifyManager; | 114 | data->manager = new OPimNotifyManager; |
111 | 115 | ||
112 | return *data->manager; | 116 | return *data->manager; |
113 | } | 117 | } |
114 | bool OEvent::hasNotifiers()const { | 118 | bool OEvent::hasNotifiers()const { |
115 | return ( data->manager); | 119 | if (!data->manager ) |
120 | return false; | ||
121 | if (data->manager->reminders().isEmpty() && | ||
122 | data->manager->alarms().isEmpty() ) | ||
123 | return false; | ||
124 | |||
125 | return true; | ||
116 | } | 126 | } |
117 | ORecur OEvent::recurrence()const { | 127 | ORecur OEvent::recurrence()const { |
118 | if (!data->recur) | 128 | if (!data->recur) |
119 | data->recur = new ORecur; | 129 | data->recur = new ORecur; |
120 | 130 | ||
121 | return *data->recur; | 131 | return *data->recur; |
122 | } | 132 | } |
123 | void OEvent::setRecurrence( const ORecur& rec) { | 133 | void OEvent::setRecurrence( const ORecur& rec) { |
124 | changeOrModify(); | 134 | changeOrModify(); |
125 | if (data->recur ) | 135 | if (data->recur ) |
126 | (*data->recur) = rec; | 136 | (*data->recur) = rec; |
127 | else | 137 | else |
128 | data->recur = new ORecur( rec ); | 138 | data->recur = new ORecur( rec ); |
129 | } | 139 | } |
130 | bool OEvent::hasRecurrence()const { | 140 | bool OEvent::hasRecurrence()const { |
131 | if (!data->recur ) return false; | 141 | if (!data->recur ) return false; |
132 | return data->recur->doesRecur(); | 142 | return data->recur->doesRecur(); |
133 | } | 143 | } |
134 | QString OEvent::note()const { | 144 | QString OEvent::note()const { |
135 | return data->note; | 145 | return data->note; |
136 | } | 146 | } |
137 | void OEvent::setNote( const QString& note ) { | 147 | void OEvent::setNote( const QString& note ) { |
138 | changeOrModify(); | 148 | changeOrModify(); |
139 | data->note = note; | 149 | data->note = note; |
140 | } | 150 | } |
141 | QDateTime OEvent::createdDateTime()const { | 151 | QDateTime OEvent::createdDateTime()const { |
142 | return data->created; | 152 | return data->created; |
143 | } | 153 | } |
144 | void OEvent::setCreatedDateTime( const QDateTime& time ) { | 154 | void OEvent::setCreatedDateTime( const QDateTime& time ) { |
145 | changeOrModify(); | 155 | changeOrModify(); |
146 | data->created = time; | 156 | data->created = time; |
147 | } | 157 | } |
148 | QDateTime OEvent::startDateTime()const { | 158 | QDateTime OEvent::startDateTime()const { |
149 | if ( data->isAllDay ) | 159 | if ( data->isAllDay ) |
150 | return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); | 160 | return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); |
151 | return data->start; | 161 | return data->start; |
152 | } | 162 | } |
153 | QDateTime OEvent::startDateTimeInZone()const { | 163 | QDateTime OEvent::startDateTimeInZone()const { |
154 | /* if no timezone, or all day event or if the current and this timeZone match... */ | 164 | /* if no timezone, or all day event or if the current and this timeZone match... */ |
155 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); | 165 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); |
156 | 166 | ||
157 | OTimeZone zone(data->timezone ); | 167 | OTimeZone zone(data->timezone ); |
158 | return zone.toDateTime( data->start, OTimeZone::current() ); | 168 | return zone.toDateTime( data->start, OTimeZone::current() ); |
159 | } | 169 | } |
160 | void OEvent::setStartDateTime( const QDateTime& dt ) { | 170 | void OEvent::setStartDateTime( const QDateTime& dt ) { |
161 | changeOrModify(); | 171 | changeOrModify(); |
162 | data->start = dt; | 172 | data->start = dt; |
163 | } | 173 | } |
164 | QDateTime OEvent::endDateTime()const { | 174 | QDateTime OEvent::endDateTime()const { |
165 | /* | 175 | /* |
166 | * if all Day event the end time needs | 176 | * if all Day event the end time needs |
167 | * to be on the same day as the start | 177 | * to be on the same day as the start |
168 | */ | 178 | */ |
169 | if ( data->isAllDay ) | 179 | if ( data->isAllDay ) |
170 | return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); | 180 | return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); |
171 | return data->end; | 181 | return data->end; |
172 | } | 182 | } |
173 | QDateTime OEvent::endDateTimeInZone()const { | 183 | QDateTime OEvent::endDateTimeInZone()const { |
174 | /* if no timezone, or all day event or if the current and this timeZone match... */ | 184 | /* if no timezone, or all day event or if the current and this timeZone match... */ |
175 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); | 185 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); |
176 | 186 | ||
177 | OTimeZone zone(data->timezone ); | 187 | OTimeZone zone(data->timezone ); |
178 | return zone.toDateTime( data->end, OTimeZone::current() ); | 188 | return zone.toDateTime( data->end, OTimeZone::current() ); |
179 | } | 189 | } |
180 | void OEvent::setEndDateTime( const QDateTime& dt ) { | 190 | void OEvent::setEndDateTime( const QDateTime& dt ) { |
181 | changeOrModify(); | 191 | changeOrModify(); |
182 | data->end = dt; | 192 | data->end = dt; |
183 | } | 193 | } |
184 | bool OEvent::isMultipleDay()const { | 194 | bool OEvent::isMultipleDay()const { |
185 | return data->end.date().day() - data->start.date().day(); | 195 | return data->end.date().day() - data->start.date().day(); |
186 | } | 196 | } |
187 | bool OEvent::isAllDay()const { | 197 | bool OEvent::isAllDay()const { |
188 | return data->isAllDay; | 198 | return data->isAllDay; |
189 | } | 199 | } |
190 | void OEvent::setAllDay( bool allDay ) { | 200 | void OEvent::setAllDay( bool allDay ) { |
191 | changeOrModify(); | 201 | changeOrModify(); |
192 | data->isAllDay = allDay; | 202 | data->isAllDay = allDay; |
193 | if (allDay ) data->timezone = "UTC"; | 203 | if (allDay ) data->timezone = "UTC"; |
194 | } | 204 | } |
195 | void OEvent::setTimeZone( const QString& tz ) { | 205 | void OEvent::setTimeZone( const QString& tz ) { |
196 | changeOrModify(); | 206 | changeOrModify(); |
197 | data->timezone = tz; | 207 | data->timezone = tz; |
198 | } | 208 | } |
199 | QString OEvent::timeZone()const { | 209 | QString OEvent::timeZone()const { |
210 | if (data->isAllDay ) return QString::fromLatin1("UTC"); | ||
200 | return data->timezone; | 211 | return data->timezone; |
201 | } | 212 | } |
202 | bool OEvent::match( const QRegExp& )const { | 213 | bool OEvent::match( const QRegExp& )const { |
203 | // FIXME | 214 | // FIXME |
204 | return false; | 215 | return false; |
205 | } | 216 | } |
206 | QString OEvent::toRichText()const { | 217 | QString OEvent::toRichText()const { |
207 | // FIXME | 218 | // FIXME |
208 | return "OEvent test"; | 219 | return "OEvent test"; |
209 | } | 220 | } |
210 | QString OEvent::toShortText()const { | 221 | QString OEvent::toShortText()const { |
211 | return "OEvent shotText"; | 222 | return "OEvent shotText"; |
212 | } | 223 | } |
213 | QString OEvent::type()const { | 224 | QString OEvent::type()const { |
214 | return QString::fromLatin1("OEvent"); | 225 | return QString::fromLatin1("OEvent"); |
215 | } | 226 | } |
216 | QString OEvent::recordField( int /*id */ )const { | 227 | QString OEvent::recordField( int /*id */ )const { |
217 | return QString::null; | 228 | return QString::null; |
218 | } | 229 | } |
219 | int OEvent::rtti() { | 230 | int OEvent::rtti() { |
220 | return OPimResolver::DateBook; | 231 | return OPimResolver::DateBook; |
221 | } | 232 | } |
222 | bool OEvent::loadFromStream( QDataStream& ) { | 233 | bool OEvent::loadFromStream( QDataStream& ) { |
223 | return true; | 234 | return true; |
224 | } | 235 | } |
225 | bool OEvent::saveToStream( QDataStream& )const { | 236 | bool OEvent::saveToStream( QDataStream& )const { |
226 | return true; | 237 | return true; |
227 | } | 238 | } |
228 | void OEvent::changeOrModify() { | 239 | void OEvent::changeOrModify() { |
229 | if ( data->count != 1 ) { | 240 | if ( data->count != 1 ) { |
230 | data->deref(); | 241 | data->deref(); |
231 | Data* d2 = new Data; | 242 | Data* d2 = new Data; |
232 | d2->description = data->description; | 243 | d2->description = data->description; |
233 | d2->location = data->location; | 244 | d2->location = data->location; |
234 | d2->manager = data->manager; | 245 | d2->manager = data->manager; |
235 | d2->recur = data->recur; | 246 | d2->recur = data->recur; |
236 | d2->note = data->note; | 247 | d2->note = data->note; |
237 | d2->created = data->created; | 248 | d2->created = data->created; |
238 | d2->start = data->start; | 249 | d2->start = data->start; |
239 | d2->end = data->end; | 250 | d2->end = data->end; |
240 | d2->isAllDay = data->isAllDay; | 251 | d2->isAllDay = data->isAllDay; |
241 | d2->timezone = data->timezone; | 252 | d2->timezone = data->timezone; |
253 | d2->parent = data->parent; | ||
254 | d2->child = data->child; | ||
255 | |||
256 | if (d2->child ) | ||
257 | d2->child->detach(); | ||
242 | 258 | ||
243 | data = d2; | 259 | data = d2; |
244 | } | 260 | } |
245 | } | 261 | } |
246 | void OEvent::deref() { | 262 | void OEvent::deref() { |
247 | if ( data->deref() ) { | 263 | if ( data->deref() ) { |
248 | delete data; | 264 | delete data; |
249 | data = 0; | 265 | data = 0; |
250 | } | 266 | } |
251 | } | 267 | } |
252 | // FIXME | 268 | // FIXME |
253 | QMap<int, QString> OEvent::toMap()const { | 269 | QMap<int, QString> OEvent::toMap()const { |
254 | return QMap<int, QString>(); | 270 | return QMap<int, QString>(); |
255 | } | 271 | } |
256 | QMap<QString, QString> OEvent::toExtraMap()const { | 272 | QMap<QString, QString> OEvent::toExtraMap()const { |
257 | return QMap<QString, QString>(); | 273 | return QMap<QString, QString>(); |
258 | } | 274 | } |
275 | int OEvent::parent()const { | ||
276 | return data->parent; | ||
277 | } | ||
278 | void OEvent::setParent( int uid ) { | ||
279 | changeOrModify(); | ||
280 | data->parent = uid; | ||
281 | } | ||
282 | QArray<int> OEvent::children() const{ | ||
283 | if (!data->child) return QArray<int>(); | ||
284 | else | ||
285 | return data->child->copy(); | ||
286 | } | ||
287 | void OEvent::setChildren( const QArray<int>& arr ) { | ||
288 | changeOrModify(); | ||
289 | if (data->child) delete data->child; | ||
259 | 290 | ||
260 | 291 | data->child = new QArray<int>( arr ); | |
292 | data->child->detach(); | ||
293 | } | ||
294 | void OEvent::addChild( int uid ) { | ||
295 | changeOrModify(); | ||
296 | if (!data->child ) { | ||
297 | data->child = new QArray<int>(1); | ||
298 | (*data->child)[0] = uid; | ||
299 | }else{ | ||
300 | int count = data->child->count(); | ||
301 | data->child->resize( count + 1 ); | ||
302 | (*data->child)[count] = uid; | ||
303 | } | ||
304 | } | ||
305 | void OEvent::removeChild( int uid ) { | ||
306 | if (!data->child || !data->child->contains( uid ) ) return; | ||
307 | changeOrModify(); | ||
308 | QArray<int> newAr( data->child->count() - 1 ); | ||
309 | int j = 0; | ||
310 | uint count = data->child->count(); | ||
311 | for ( uint i = 0; i < count; i++ ) { | ||
312 | if ( (*data->child)[i] != uid ) { | ||
313 | newAr[j] = (*data->child)[i]; | ||
314 | j++; | ||
315 | } | ||
316 | } | ||
317 | (*data->child) = newAr; | ||
318 | } | ||
261 | struct OEffectiveEvent::Data : public QShared { | 319 | struct OEffectiveEvent::Data : public QShared { |
262 | Data() : QShared() { | 320 | Data() : QShared() { |
263 | } | 321 | } |
264 | OEvent event; | 322 | OEvent event; |
265 | QDate date; | 323 | QDate date; |
266 | QTime start, end; | 324 | QTime start, end; |
267 | QDate startDate, endDate; | 325 | QDate startDate, endDate; |
268 | bool dates : 1; | 326 | bool dates : 1; |
269 | }; | 327 | }; |
270 | 328 | ||
271 | OEffectiveEvent::OEffectiveEvent() { | 329 | OEffectiveEvent::OEffectiveEvent() { |
272 | data = new Data; | 330 | data = new Data; |
273 | data->date = QDate::currentDate(); | 331 | data->date = QDate::currentDate(); |
274 | data->start = data->end = QTime::currentTime(); | 332 | data->start = data->end = QTime::currentTime(); |
275 | data->dates = false; | 333 | data->dates = false; |
276 | } | 334 | } |
277 | OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, | 335 | OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, |
278 | Position pos ) { | 336 | Position pos ) { |
279 | data = new Data; | 337 | data = new Data; |
280 | data->event = ev; | 338 | data->event = ev; |
281 | data->date = startDate; | 339 | data->date = startDate; |
282 | if ( pos & Start ) | 340 | if ( pos & Start ) |
283 | data->start = ev.startDateTime().time(); | 341 | data->start = ev.startDateTime().time(); |
284 | else | 342 | else |
285 | data->start = QTime( 0, 0, 0 ); | 343 | data->start = QTime( 0, 0, 0 ); |
286 | 344 | ||
287 | if ( pos & End ) | 345 | if ( pos & End ) |
288 | data->end = ev.endDateTime().time(); | 346 | data->end = ev.endDateTime().time(); |
289 | else | 347 | else |
290 | data->end = QTime( 23, 59, 59 ); | 348 | data->end = QTime( 23, 59, 59 ); |
291 | 349 | ||
292 | data->dates = false; | 350 | data->dates = false; |
293 | } | 351 | } |
294 | OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { | 352 | OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { |
295 | data = ev.data; | 353 | data = ev.data; |
296 | data->ref(); | 354 | data->ref(); |
297 | } | 355 | } |
298 | OEffectiveEvent::~OEffectiveEvent() { | 356 | OEffectiveEvent::~OEffectiveEvent() { |
299 | if ( data->deref() ) { | 357 | if ( data->deref() ) { |
300 | delete data; | 358 | delete data; |
301 | data = 0; | 359 | data = 0; |
302 | } | 360 | } |
303 | } | 361 | } |
304 | OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { | 362 | OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { |
305 | if ( *this == ev ) return *this; | 363 | if ( *this == ev ) return *this; |
306 | 364 | ||
307 | ev.data->ref(); | 365 | ev.data->ref(); |
308 | deref(); | 366 | deref(); |
309 | data = ev.data; | 367 | data = ev.data; |
310 | 368 | ||
311 | return *this; | 369 | return *this; |
312 | } | 370 | } |
313 | 371 | ||
314 | void OEffectiveEvent::setStartTime( const QTime& ti) { | 372 | void OEffectiveEvent::setStartTime( const QTime& ti) { |
315 | changeOrModify(); | 373 | changeOrModify(); |
316 | data->start = ti; | 374 | data->start = ti; |
317 | } | 375 | } |
318 | void OEffectiveEvent::setEndTime( const QTime& en) { | 376 | void OEffectiveEvent::setEndTime( const QTime& en) { |
319 | changeOrModify(); | 377 | changeOrModify(); |
320 | data->end = en; | 378 | data->end = en; |
321 | } | 379 | } |
322 | void OEffectiveEvent::setEvent( const OEvent& ev) { | 380 | void OEffectiveEvent::setEvent( const OEvent& ev) { |
323 | changeOrModify(); | 381 | changeOrModify(); |
324 | data->event = ev; | 382 | data->event = ev; |
325 | } | 383 | } |
326 | void OEffectiveEvent::setDate( const QDate& da) { | 384 | void OEffectiveEvent::setDate( const QDate& da) { |
327 | changeOrModify(); | 385 | changeOrModify(); |
328 | data->date = da; | 386 | data->date = da; |
329 | } | 387 | } |
330 | void OEffectiveEvent::setEffectiveDates( const QDate& from, | 388 | void OEffectiveEvent::setEffectiveDates( const QDate& from, |
331 | const QDate& to ) { | 389 | const QDate& to ) { |
332 | if (!from.isValid() ) { | 390 | if (!from.isValid() ) { |
333 | data->dates = false; | 391 | data->dates = false; |
334 | return; | 392 | return; |
335 | } | 393 | } |
336 | 394 | ||
337 | data->startDate = from; | 395 | data->startDate = from; |
338 | data->endDate = to; | 396 | data->endDate = to; |
339 | } | 397 | } |
340 | QString OEffectiveEvent::description()const { | 398 | QString OEffectiveEvent::description()const { |
341 | return data->event.description(); | 399 | return data->event.description(); |
342 | } | 400 | } |
343 | QString OEffectiveEvent::location()const { | 401 | QString OEffectiveEvent::location()const { |
344 | return data->event.location(); | 402 | return data->event.location(); |
345 | } | 403 | } |
346 | QString OEffectiveEvent::note()const { | 404 | QString OEffectiveEvent::note()const { |
347 | return data->event.note(); | 405 | return data->event.note(); |
348 | } | 406 | } |
349 | OEvent OEffectiveEvent::event()const { | 407 | OEvent OEffectiveEvent::event()const { |
350 | return data->event; | 408 | return data->event; |
351 | } | 409 | } |
352 | QTime OEffectiveEvent::startTime()const { | 410 | QTime OEffectiveEvent::startTime()const { |
353 | return data->start; | 411 | return data->start; |
354 | } | 412 | } |
355 | QTime OEffectiveEvent::endTime()const { | 413 | QTime OEffectiveEvent::endTime()const { |
356 | return data->end; | 414 | return data->end; |
357 | } | 415 | } |
358 | QDate OEffectiveEvent::date()const { | 416 | QDate OEffectiveEvent::date()const { |
359 | return data->date; | 417 | return data->date; |
360 | } | 418 | } |
361 | int OEffectiveEvent::length()const { | 419 | int OEffectiveEvent::length()const { |
362 | return (data->end.hour() * 60 - data->start.hour() * 60) | 420 | return (data->end.hour() * 60 - data->start.hour() * 60) |
363 | + QABS(data->start.minute() - data->end.minute() ); | 421 | + QABS(data->start.minute() - data->end.minute() ); |
364 | } | 422 | } |
365 | int OEffectiveEvent::size()const { | 423 | int OEffectiveEvent::size()const { |
366 | return ( data->end.hour() - data->start.hour() ) * 3600 | 424 | return ( data->end.hour() - data->start.hour() ) * 3600 |
367 | + (data->end.minute() - data->start.minute() * 60 | 425 | + (data->end.minute() - data->start.minute() * 60 |
368 | + data->end.second() - data->start.second() ); | 426 | + data->end.second() - data->start.second() ); |
369 | } | 427 | } |
370 | QDate OEffectiveEvent::startDate()const { | 428 | QDate OEffectiveEvent::startDate()const { |
371 | if ( data->dates ) | 429 | if ( data->dates ) |
372 | return data->startDate; | 430 | return data->startDate; |
373 | else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer | 431 | else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer |
374 | return data->date; | 432 | return data->date; |
375 | else | 433 | else |
376 | return data->event.startDateTime().date(); | 434 | return data->event.startDateTime().date(); |
377 | } | 435 | } |
378 | QDate OEffectiveEvent::endDate()const { | 436 | QDate OEffectiveEvent::endDate()const { |
379 | if ( data->dates ) | 437 | if ( data->dates ) |
380 | return data->endDate; | 438 | return data->endDate; |
381 | else if ( data->event.hasRecurrence() ) | 439 | else if ( data->event.hasRecurrence() ) |
382 | return data->date; | 440 | return data->date; |
383 | else | 441 | else |
384 | return data->event.endDateTime().date(); | 442 | return data->event.endDateTime().date(); |
385 | } | 443 | } |
386 | void OEffectiveEvent::deref() { | 444 | void OEffectiveEvent::deref() { |
387 | if ( data->deref() ) { | 445 | if ( data->deref() ) { |
388 | delete data; | 446 | delete data; |
389 | data = 0; | 447 | data = 0; |
390 | } | 448 | } |
391 | } | 449 | } |
392 | void OEffectiveEvent::changeOrModify() { | 450 | void OEffectiveEvent::changeOrModify() { |
393 | if ( data->count != 1 ) { | 451 | if ( data->count != 1 ) { |
394 | data->deref(); | 452 | data->deref(); |
395 | Data* d2 = new Data; | 453 | Data* d2 = new Data; |
396 | d2->event = data->event; | 454 | d2->event = data->event; |
397 | d2->date = data->date; | 455 | d2->date = data->date; |
398 | d2->start = data->start; | 456 | d2->start = data->start; |
399 | d2->end = data->end; | 457 | d2->end = data->end; |
400 | d2->startDate = data->startDate; | 458 | d2->startDate = data->startDate; |
401 | d2->endDate = data->endDate; | 459 | d2->endDate = data->endDate; |
402 | d2->dates = data->dates; | 460 | d2->dates = data->dates; |
403 | data = d2; | 461 | data = d2; |
404 | } | 462 | } |
405 | } | 463 | } |
406 | bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{ | 464 | bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{ |
407 | if ( data->date < e.date() ) | 465 | if ( data->date < e.date() ) |
408 | return TRUE; | 466 | return TRUE; |
409 | if ( data->date == e.date() ) | 467 | if ( data->date == e.date() ) |
410 | return ( startTime() < e.startTime() ); | 468 | return ( startTime() < e.startTime() ); |
411 | else | 469 | else |
412 | return FALSE; | 470 | return FALSE; |
413 | } | 471 | } |
414 | bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const{ | 472 | bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const{ |
415 | return (data->date <= e.date() ); | 473 | return (data->date <= e.date() ); |
416 | } | 474 | } |
417 | bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const { | 475 | bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const { |
418 | return ( date() == e.date() | 476 | return ( date() == e.date() |
419 | && startTime() == e.startTime() | 477 | && startTime() == e.startTime() |
420 | && endTime()== e.endTime() | 478 | && endTime()== e.endTime() |
421 | && event() == e.event() ); | 479 | && event() == e.event() ); |
422 | } | 480 | } |
423 | bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const { | 481 | bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const { |
424 | return !(*this == e ); | 482 | return !(*this == e ); |
425 | } | 483 | } |
426 | bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const { | 484 | bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const { |
427 | return !(*this <= e ); | 485 | return !(*this <= e ); |
428 | } | 486 | } |
429 | bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const { | 487 | bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const { |
430 | return !(*this < e); | 488 | return !(*this < e); |
431 | } | 489 | } |
diff --git a/libopie2/opiepim/oevent.h b/libopie2/opiepim/oevent.h index c718e2e..585515c 100644 --- a/libopie2/opiepim/oevent.h +++ b/libopie2/opiepim/oevent.h | |||
@@ -1,198 +1,206 @@ | |||
1 | // CONTAINS GPLed code of TT | 1 | // CONTAINS GPLed code of TT |
2 | 2 | ||
3 | #ifndef OPIE_PIM_EVENT_H | 3 | #ifndef OPIE_PIM_EVENT_H |
4 | #define OPIE_PIM_EVENT_H | 4 | #define OPIE_PIM_EVENT_H |
5 | 5 | ||
6 | #include <qstring.h> | 6 | #include <qstring.h> |
7 | #include <qdatetime.h> | 7 | #include <qdatetime.h> |
8 | #include <qvaluelist.h> | 8 | #include <qvaluelist.h> |
9 | 9 | ||
10 | #include <qpe/recordfields.h> | 10 | #include <qpe/recordfields.h> |
11 | #include <qpe/palmtopuidgen.h> | 11 | #include <qpe/palmtopuidgen.h> |
12 | 12 | ||
13 | #include "otimezone.h" | 13 | #include "otimezone.h" |
14 | #include "opimrecord.h" | 14 | #include "opimrecord.h" |
15 | 15 | ||
16 | struct OCalendarHelper { | 16 | struct OCalendarHelper { |
17 | /** calculate the week number of the date */ | 17 | /** calculate the week number of the date */ |
18 | static int week( const QDate& ); | 18 | static int week( const QDate& ); |
19 | /** calculate the occurence of week days since the start of the month */ | 19 | /** calculate the occurence of week days since the start of the month */ |
20 | static int ocurrence( const QDate& ); | 20 | static int ocurrence( const QDate& ); |
21 | 21 | ||
22 | // returns the dayOfWeek for the *first* day it finds (ignores | 22 | // returns the dayOfWeek for the *first* day it finds (ignores |
23 | // any further days!). Returns 1 (Monday) if there isn't any day found | 23 | // any further days!). Returns 1 (Monday) if there isn't any day found |
24 | static int dayOfWeek( char day ); | 24 | static int dayOfWeek( char day ); |
25 | 25 | ||
26 | /** returns the diff of month */ | 26 | /** returns the diff of month */ |
27 | static int monthDiff( const QDate& first, const QDate& second ); | 27 | static int monthDiff( const QDate& first, const QDate& second ); |
28 | 28 | ||
29 | }; | 29 | }; |
30 | 30 | ||
31 | class OPimNotifyManager; | 31 | class OPimNotifyManager; |
32 | class ORecur; | 32 | class ORecur; |
33 | class OEvent : public OPimRecord { | 33 | class OEvent : public OPimRecord { |
34 | public: | 34 | public: |
35 | typedef QValueList<OEvent> ValueList; | 35 | typedef QValueList<OEvent> ValueList; |
36 | enum RecordFields { | 36 | enum RecordFields { |
37 | Uid = Qtopia::UID_ID, | 37 | Uid = Qtopia::UID_ID, |
38 | Category = Qtopia::CATEGORY_ID, | 38 | Category = Qtopia::CATEGORY_ID, |
39 | Description, | 39 | Description, |
40 | Location, | 40 | Location, |
41 | Alarm, | 41 | Alarm, |
42 | Reminder, | 42 | Reminder, |
43 | Recurrence, | 43 | Recurrence, |
44 | Note, | 44 | Note, |
45 | Created, | 45 | Created, |
46 | StartDate, | 46 | StartDate, |
47 | EndDate, | 47 | EndDate, |
48 | AllDay, | 48 | AllDay, |
49 | TimeZone | 49 | TimeZone |
50 | }; | 50 | }; |
51 | 51 | ||
52 | OEvent(int uid = 0); | 52 | OEvent(int uid = 0); |
53 | OEvent( const OEvent& ); | 53 | OEvent( const OEvent& ); |
54 | ~OEvent(); | 54 | ~OEvent(); |
55 | OEvent &operator=( const OEvent& ); | 55 | OEvent &operator=( const OEvent& ); |
56 | 56 | ||
57 | QString description()const; | 57 | QString description()const; |
58 | void setDescription( const QString& description ); | 58 | void setDescription( const QString& description ); |
59 | 59 | ||
60 | QString location()const; | 60 | QString location()const; |
61 | void setLocation( const QString& loc ); | 61 | void setLocation( const QString& loc ); |
62 | 62 | ||
63 | bool hasNotifiers()const; | 63 | bool hasNotifiers()const; |
64 | OPimNotifyManager ¬ifiers(); | 64 | OPimNotifyManager ¬ifiers()const; |
65 | 65 | ||
66 | ORecur recurrence()const; | 66 | ORecur recurrence()const; |
67 | void setRecurrence( const ORecur& ); | 67 | void setRecurrence( const ORecur& ); |
68 | bool hasRecurrence()const; | 68 | bool hasRecurrence()const; |
69 | 69 | ||
70 | QString note()const; | 70 | QString note()const; |
71 | void setNote( const QString& note ); | 71 | void setNote( const QString& note ); |
72 | 72 | ||
73 | 73 | ||
74 | QDateTime createdDateTime()const; | 74 | QDateTime createdDateTime()const; |
75 | void setCreatedDateTime( const QDateTime& dt); | 75 | void setCreatedDateTime( const QDateTime& dt); |
76 | 76 | ||
77 | /** set the date to dt. dt is the QDateTime in localtime */ | 77 | /** set the date to dt. dt is the QDateTime in localtime */ |
78 | void setStartDateTime( const QDateTime& ); | 78 | void setStartDateTime( const QDateTime& ); |
79 | /** returns the datetime in the local timeZone */ | 79 | /** returns the datetime in the local timeZone */ |
80 | QDateTime startDateTime()const; | 80 | QDateTime startDateTime()const; |
81 | 81 | ||
82 | /** returns the start datetime in the current zone */ | 82 | /** returns the start datetime in the current zone */ |
83 | QDateTime startDateTimeInZone()const; | 83 | QDateTime startDateTimeInZone()const; |
84 | 84 | ||
85 | /** in current timezone */ | 85 | /** in current timezone */ |
86 | void setEndDateTime( const QDateTime& ); | 86 | void setEndDateTime( const QDateTime& ); |
87 | /** in current timezone */ | 87 | /** in current timezone */ |
88 | QDateTime endDateTime()const; | 88 | QDateTime endDateTime()const; |
89 | QDateTime endDateTimeInZone()const; | 89 | QDateTime endDateTimeInZone()const; |
90 | 90 | ||
91 | bool isMultipleDay()const; | 91 | bool isMultipleDay()const; |
92 | bool isAllDay()const; | 92 | bool isAllDay()const; |
93 | void setAllDay( bool isAllDay ); | 93 | void setAllDay( bool isAllDay ); |
94 | 94 | ||
95 | /* pin this event to a timezone! FIXME */ | 95 | /* pin this event to a timezone! FIXME */ |
96 | void setTimeZone( const QString& timeZone ); | 96 | void setTimeZone( const QString& timeZone ); |
97 | QString timeZone()const; | 97 | QString timeZone()const; |
98 | 98 | ||
99 | 99 | ||
100 | bool match( const QRegExp& )const; | 100 | bool match( const QRegExp& )const; |
101 | 101 | ||
102 | /** For exception to recurrence here is a list of children... */ | ||
103 | QArray<int> children()const; | ||
104 | void setChildren( const QArray<int>& ); | ||
105 | void addChild( int uid ); | ||
106 | void removeChild( int uid ); | ||
102 | 107 | ||
108 | /** return the parent OEvent */ | ||
109 | int parent()const; | ||
110 | void setParent( int uid ); | ||
103 | 111 | ||
104 | 112 | ||
105 | /* needed reimp */ | 113 | /* needed reimp */ |
106 | QString toRichText()const; | 114 | QString toRichText()const; |
107 | QString toShortText()const; | 115 | QString toShortText()const; |
108 | QString type()const; | 116 | QString type()const; |
109 | 117 | ||
110 | QMap<int, QString> toMap()const; | 118 | QMap<int, QString> toMap()const; |
111 | QMap<QString, QString> toExtraMap()const; | 119 | QMap<QString, QString> toExtraMap()const; |
112 | QString recordField(int )const; | 120 | QString recordField(int )const; |
113 | 121 | ||
114 | static int rtti(); | 122 | static int rtti(); |
115 | 123 | ||
116 | bool loadFromStream( QDataStream& ); | 124 | bool loadFromStream( QDataStream& ); |
117 | bool saveToStream( QDataStream& )const; | 125 | bool saveToStream( QDataStream& )const; |
118 | 126 | ||
119 | /* bool operator==( const OEvent& ); | 127 | /* bool operator==( const OEvent& ); |
120 | bool operator!=( const OEvent& ); | 128 | bool operator!=( const OEvent& ); |
121 | bool operator<( const OEvent& ); | 129 | bool operator<( const OEvent& ); |
122 | bool operator<=( const OEvent& ); | 130 | bool operator<=( const OEvent& ); |
123 | bool operator>( const OEvent& ); | 131 | bool operator>( const OEvent& ); |
124 | bool operator>=(const OEvent& ); | 132 | bool operator>=(const OEvent& ); |
125 | */ | 133 | */ |
126 | private: | 134 | private: |
127 | inline void changeOrModify(); | 135 | inline void changeOrModify(); |
128 | void deref(); | 136 | void deref(); |
129 | struct Data; | 137 | struct Data; |
130 | Data* data; | 138 | Data* data; |
131 | class Private; | 139 | class Private; |
132 | Private* priv; | 140 | Private* priv; |
133 | 141 | ||
134 | }; | 142 | }; |
135 | 143 | ||
136 | /** | 144 | /** |
137 | * AN Event can span through multiple days. We split up a multiday eve | 145 | * AN Event can span through multiple days. We split up a multiday eve |
138 | */ | 146 | */ |
139 | 147 | ||
140 | class OEffectiveEvent { | 148 | class OEffectiveEvent { |
141 | public: | 149 | public: |
142 | typedef QValueList<OEffectiveEvent> ValueList; | 150 | typedef QValueList<OEffectiveEvent> ValueList; |
143 | enum Position { MidWay, Start, End, StartEnd }; | 151 | enum Position { MidWay, Start, End, StartEnd }; |
144 | // If we calculate the effective event of a multi-day event | 152 | // If we calculate the effective event of a multi-day event |
145 | // we have to figure out whether we are at the first day, | 153 | // we have to figure out whether we are at the first day, |
146 | // at the end, or anywhere else ("middle"). This is important | 154 | // at the end, or anywhere else ("middle"). This is important |
147 | // for the start/end times (00:00/23:59) | 155 | // for the start/end times (00:00/23:59) |
148 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- | 156 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- |
149 | // day event | 157 | // day event |
150 | // Start: start time -> 23:59 | 158 | // Start: start time -> 23:59 |
151 | // End: 00:00 -> end time | 159 | // End: 00:00 -> end time |
152 | // Start | End == StartEnd: for single-day events (default) | 160 | // Start | End == StartEnd: for single-day events (default) |
153 | // here we draw start time -> end time | 161 | // here we draw start time -> end time |
154 | OEffectiveEvent(); | 162 | OEffectiveEvent(); |
155 | OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); | 163 | OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); |
156 | OEffectiveEvent( const OEffectiveEvent& ); | 164 | OEffectiveEvent( const OEffectiveEvent& ); |
157 | OEffectiveEvent &operator=(const OEffectiveEvent& ); | 165 | OEffectiveEvent &operator=(const OEffectiveEvent& ); |
158 | ~OEffectiveEvent(); | 166 | ~OEffectiveEvent(); |
159 | 167 | ||
160 | void setStartTime( const QTime& ); | 168 | void setStartTime( const QTime& ); |
161 | void setEndTime( const QTime& ); | 169 | void setEndTime( const QTime& ); |
162 | void setEvent( const OEvent& ); | 170 | void setEvent( const OEvent& ); |
163 | void setDate( const QDate& ); | 171 | void setDate( const QDate& ); |
164 | 172 | ||
165 | void setEffectiveDates( const QDate& from, const QDate& to ); | 173 | void setEffectiveDates( const QDate& from, const QDate& to ); |
166 | 174 | ||
167 | QString description()const; | 175 | QString description()const; |
168 | QString location()const; | 176 | QString location()const; |
169 | QString note()const; | 177 | QString note()const; |
170 | OEvent event()const; | 178 | OEvent event()const; |
171 | QTime startTime()const; | 179 | QTime startTime()const; |
172 | QTime endTime()const; | 180 | QTime endTime()const; |
173 | QDate date()const; | 181 | QDate date()const; |
174 | 182 | ||
175 | /* return the length in hours */ | 183 | /* return the length in hours */ |
176 | int length()const; | 184 | int length()const; |
177 | int size()const; | 185 | int size()const; |
178 | 186 | ||
179 | QDate startDate()const; | 187 | QDate startDate()const; |
180 | QDate endDate()const; | 188 | QDate endDate()const; |
181 | 189 | ||
182 | bool operator<( const OEffectiveEvent &e ) const; | 190 | bool operator<( const OEffectiveEvent &e ) const; |
183 | bool operator<=( const OEffectiveEvent &e ) const; | 191 | bool operator<=( const OEffectiveEvent &e ) const; |
184 | bool operator==( const OEffectiveEvent &e ) const; | 192 | bool operator==( const OEffectiveEvent &e ) const; |
185 | bool operator!=( const OEffectiveEvent &e ) const; | 193 | bool operator!=( const OEffectiveEvent &e ) const; |
186 | bool operator>( const OEffectiveEvent &e ) const; | 194 | bool operator>( const OEffectiveEvent &e ) const; |
187 | bool operator>= ( const OEffectiveEvent &e ) const; | 195 | bool operator>= ( const OEffectiveEvent &e ) const; |
188 | 196 | ||
189 | private: | 197 | private: |
190 | void deref(); | 198 | void deref(); |
191 | inline void changeOrModify(); | 199 | inline void changeOrModify(); |
192 | class Private; | 200 | class Private; |
193 | Private* priv; | 201 | Private* priv; |
194 | struct Data; | 202 | struct Data; |
195 | Data* data; | 203 | Data* data; |
196 | 204 | ||
197 | }; | 205 | }; |
198 | #endif | 206 | #endif |