-rw-r--r-- | libopie2/opiepim/backend/otodoaccessxml.cpp | 240 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccessxml.h | 3 | ||||
-rw-r--r-- | libopie2/opiepim/otodo.cpp | 1 |
3 files changed, 140 insertions, 104 deletions
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp index 692483e..31822d4 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.cpp +++ b/libopie2/opiepim/backend/otodoaccessxml.cpp | |||
@@ -37,54 +37,97 @@ bool OTodoAccessXML::load() { | |||
37 | dict.insert("Description" , new int(OTodo::Description) ); | 37 | dict.insert("Description" , new int(OTodo::Description) ); |
38 | dict.insert("Summary" , new int(OTodo::Summary) ); | 38 | dict.insert("Summary" , new int(OTodo::Summary) ); |
39 | dict.insert("Priority" , new int(OTodo::Priority) ); | 39 | dict.insert("Priority" , new int(OTodo::Priority) ); |
40 | dict.insert("DateDay" , new int(OTodo::DateDay) ); | 40 | dict.insert("DateDay" , new int(OTodo::DateDay) ); |
41 | dict.insert("DateMonth" , new int(OTodo::DateMonth) ); | 41 | dict.insert("DateMonth" , new int(OTodo::DateMonth) ); |
42 | dict.insert("DateYear" , new int(OTodo::DateYear) ); | 42 | dict.insert("DateYear" , new int(OTodo::DateYear) ); |
43 | dict.insert("Progress" , new int(OTodo::Progress) ); | 43 | dict.insert("Progress" , new int(OTodo::Progress) ); |
44 | dict.insert("Completed", new int(OTodo::Completed) ); | 44 | dict.insert("Completed", new int(OTodo::Completed) ); |
45 | dict.insert("CrossReference", new int(OTodo::CrossReference) ); | 45 | dict.insert("CrossReference", new int(OTodo::CrossReference) ); |
46 | dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); | 46 | dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); |
47 | dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); | 47 | dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); |
48 | 48 | ||
49 | Opie::XMLElement *root = Opie::XMLElement::load( m_file ); | 49 | // here the custom XML parser from TT it's GPL |
50 | int day, year, month; | 50 | // but we want to push that to TT..... |
51 | day = year = month = -1; | 51 | QFile f(m_file ); |
52 | 52 | if (!f.open(IO_ReadOnly) ) | |
53 | /* if opened */ | 53 | return false; |
54 | if ( root != 0l ) { | ||
55 | Opie::XMLElement *element = root->firstChild(); | ||
56 | if ( element == 0l ) | ||
57 | return false; | ||
58 | |||
59 | element = element->firstChild(); | ||
60 | 54 | ||
61 | while ( element ) { | 55 | QByteArray ba = f.readAll(); |
62 | if ( element->tagName() != QString::fromLatin1("Task") ) { | 56 | f.close(); |
63 | element = element->nextChild(); | 57 | char* dt = ba.data(); |
64 | continue; | 58 | int len = ba.size(); |
65 | } | 59 | int i = 0; |
66 | /* here is the right element for a task */ | 60 | char *point; |
67 | OTodo ev = todo( &dict, element ); | 61 | const char* collectionString = "<Task "; |
68 | m_events.insert( ev.uid(), ev ); | 62 | while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) { |
63 | i = point -dt; | ||
64 | i+= strlen(collectionString); | ||
65 | OTodo ev; | ||
66 | m_year = m_month = m_day = 0; | ||
67 | |||
68 | while ( TRUE ) { | ||
69 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | ||
70 | ++i; | ||
71 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | ||
72 | break; | ||
73 | |||
74 | // we have another attribute, read it. | ||
75 | int j = i; | ||
76 | while ( j < len && dt[j] != '=' ) | ||
77 | ++j; | ||
78 | QCString attr( dt+i, j-i+1); | ||
79 | |||
80 | i = ++j; // skip = | ||
81 | |||
82 | // find the start of quotes | ||
83 | while ( i < len && dt[i] != '"' ) | ||
84 | ++i; | ||
85 | j = ++i; | ||
86 | |||
87 | bool haveUtf = FALSE; | ||
88 | bool haveEnt = FALSE; | ||
89 | while ( j < len && dt[j] != '"' ) { | ||
90 | if ( ((unsigned char)dt[j]) > 0x7f ) | ||
91 | haveUtf = TRUE; | ||
92 | if ( dt[j] == '&' ) | ||
93 | haveEnt = TRUE; | ||
94 | ++j; | ||
95 | } | ||
96 | if ( i == j ) { | ||
97 | // empty value | ||
98 | i = j + 1; | ||
99 | continue; | ||
100 | } | ||
101 | |||
102 | QCString value( dt+i, j-i+1 ); | ||
103 | i = j + 1; | ||
104 | |||
105 | QString str = (haveUtf ? QString::fromUtf8( value ) | ||
106 | : QString::fromLatin1( value ) ); | ||
107 | if ( haveEnt ) | ||
108 | str = Qtopia::plainString( str ); | ||
109 | |||
110 | /* | ||
111 | * add key + value | ||
112 | */ | ||
113 | todo( &dict, ev, attr, str ); | ||
69 | 114 | ||
70 | element = element->nextChild(); | ||
71 | } | 115 | } |
72 | }else { | 116 | /* |
73 | // qWarning("could not parse"); | 117 | * now add it |
74 | return false;; | 118 | */ |
119 | m_events.insert(ev.uid(), ev ); | ||
75 | } | 120 | } |
76 | delete root; | ||
77 | 121 | ||
78 | // qWarning("Access %d" + m_events.count() ); | ||
79 | return true; | 122 | return true; |
80 | } | 123 | } |
81 | bool OTodoAccessXML::reload() { | 124 | bool OTodoAccessXML::reload() { |
82 | return load(); | 125 | return load(); |
83 | } | 126 | } |
84 | bool OTodoAccessXML::save() { | 127 | bool OTodoAccessXML::save() { |
85 | // qWarning("saving"); | 128 | // qWarning("saving"); |
86 | if (!m_opened || !m_changed ) { | 129 | if (!m_opened || !m_changed ) { |
87 | // qWarning("not saving"); | 130 | // qWarning("not saving"); |
88 | return true; | 131 | return true; |
89 | } | 132 | } |
90 | QString strNewFile = m_file + ".new"; | 133 | QString strNewFile = m_file + ".new"; |
@@ -211,111 +254,104 @@ QArray<int> OTodoAccessXML::overDue() { | |||
211 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | 254 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { |
212 | if ( it.data().isOverdue() ) { | 255 | if ( it.data().isOverdue() ) { |
213 | ids[i] = it.key(); | 256 | ids[i] = it.key(); |
214 | i++; | 257 | i++; |
215 | } | 258 | } |
216 | } | 259 | } |
217 | ids.resize( i ); | 260 | ids.resize( i ); |
218 | return ids; | 261 | return ids; |
219 | } | 262 | } |
220 | 263 | ||
221 | 264 | ||
222 | /* private */ | 265 | /* private */ |
223 | OTodo OTodoAccessXML::todo( QAsciiDict<int>* dict, Opie::XMLElement* element)const { | 266 | void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, |
267 | const QCString& attr, const QString& val) { | ||
224 | // qWarning("parse to do from XMLElement" ); | 268 | // qWarning("parse to do from XMLElement" ); |
225 | OTodo ev; | ||
226 | QMap<QString, QString> attributes = element->attributes(); | ||
227 | QMap<QString, QString>::Iterator it; | ||
228 | 269 | ||
229 | int *find=0; | 270 | int *find=0; |
230 | int day, month, year; | 271 | |
231 | day = month = year = -1; | 272 | find = (*dict)[ attr.data() ]; |
232 | for ( it = attributes.begin(); it != attributes.end(); ++it ) { | 273 | if (!find ) { |
233 | find = (*dict)[ it.key() ]; | ||
234 | if (!find ) { | ||
235 | // qWarning("Unknown option" + it.key() ); | 274 | // qWarning("Unknown option" + it.key() ); |
236 | ev.setCustomField( it.key(), it.data() ); | 275 | ev.setCustomField( attr, val ); |
237 | continue; | 276 | return; |
238 | } | 277 | } |
239 | 278 | ||
240 | switch( *find ) { | 279 | switch( *find ) { |
241 | case OTodo::Uid: | 280 | case OTodo::Uid: |
242 | ev.setUid( it.data().toInt() ); | 281 | ev.setUid( val.toInt() ); |
243 | break; | 282 | break; |
244 | case OTodo::Category: | 283 | case OTodo::Category: |
245 | ev.setCategories( ev.idsFromString( it.data() ) ); | 284 | ev.setCategories( ev.idsFromString( val ) ); |
246 | break; | 285 | break; |
247 | case OTodo::HasDate: | 286 | case OTodo::HasDate: |
248 | ev.setHasDueDate( it.data().toInt() ); | 287 | ev.setHasDueDate( val.toInt() ); |
249 | break; | 288 | break; |
250 | case OTodo::Completed: | 289 | case OTodo::Completed: |
251 | ev.setCompleted( it.data().toInt() ); | 290 | ev.setCompleted( val.toInt() ); |
252 | break; | 291 | break; |
253 | case OTodo::Description: | 292 | case OTodo::Description: |
254 | ev.setDescription( it.data() ); | 293 | ev.setDescription( val ); |
255 | break; | 294 | break; |
256 | case OTodo::Summary: | 295 | case OTodo::Summary: |
257 | ev.setSummary( it.data() ); | 296 | ev.setSummary( val ); |
258 | break; | 297 | break; |
259 | case OTodo::Priority: | 298 | case OTodo::Priority: |
260 | qWarning("ParsePriority " + it.data() ); | 299 | ev.setPriority( val.toInt() ); |
261 | ev.setPriority( it.data().toInt() ); | 300 | break; |
262 | break; | 301 | case OTodo::DateDay: |
263 | case OTodo::DateDay: | 302 | m_day = val.toInt(); |
264 | day = it.data().toInt(); | 303 | break; |
265 | break; | 304 | case OTodo::DateMonth: |
266 | case OTodo::DateMonth: | 305 | m_month = val.toInt(); |
267 | month = it.data().toInt(); | 306 | break; |
268 | break; | 307 | case OTodo::DateYear: |
269 | case OTodo::DateYear: | 308 | m_year = val.toInt(); |
270 | year = it.data().toInt(); | 309 | break; |
271 | break; | 310 | case OTodo::Progress: |
272 | case OTodo::Progress: | 311 | ev.setProgress( val.toInt() ); |
273 | ev.setProgress( it.data().toInt() ); | 312 | break; |
274 | break; | 313 | case OTodo::CrossReference: |
275 | case OTodo::CrossReference: | 314 | { |
276 | { | 315 | /* |
277 | /* | 316 | * A cross refernce looks like |
278 | * A cross refernce looks like | 317 | * appname,id;appname,id |
279 | * appname,id;appname,id | 318 | * we need to split it up |
280 | * we need to split it up | 319 | */ |
281 | */ | 320 | QStringList refs = QStringList::split(';', val ); |
282 | QStringList refs = QStringList::split(';', it.data() ); | 321 | QStringList::Iterator strIt; |
283 | QStringList::Iterator strIt; | 322 | for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { |
284 | for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { | 323 | int pos = (*strIt).find(','); |
285 | int pos = (*strIt).find(','); | 324 | if ( pos > -1 ) |
286 | if ( pos > -1 ) | 325 | ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); |
287 | ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); | ||
288 | 326 | ||
289 | } | ||
290 | break; | ||
291 | } | ||
292 | case OTodo::HasAlarmDateTime: | ||
293 | ev.setHasAlarmDateTime( it.data().toInt() ); | ||
294 | break; | ||
295 | case OTodo::AlarmDateTime: { | ||
296 | /* this sounds better ;) zecke */ | ||
297 | ev.setAlarmDateTime( TimeConversion::fromISO8601( it.data().local8Bit() ) ); | ||
298 | break; | ||
299 | } | ||
300 | default: | ||
301 | break; | ||
302 | } | 327 | } |
328 | break; | ||
303 | } | 329 | } |
330 | case OTodo::HasAlarmDateTime: | ||
331 | ev.setHasAlarmDateTime( val.toInt() ); | ||
332 | break; | ||
333 | case OTodo::AlarmDateTime: { | ||
334 | /* this sounds better ;) zecke */ | ||
335 | ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) ); | ||
336 | break; | ||
337 | } | ||
338 | default: | ||
339 | break; | ||
340 | } | ||
341 | |||
304 | if ( ev.hasDueDate() ) { | 342 | if ( ev.hasDueDate() ) { |
305 | QDate date( year, month, day ); | 343 | QDate date( m_year, m_month, m_day ); |
306 | ev.setDueDate( date ); | 344 | ev.setDueDate( date ); |
307 | } | 345 | } |
308 | |||
309 | return ev; | ||
310 | } | 346 | } |
311 | QString OTodoAccessXML::toString( const OTodo& ev )const { | 347 | QString OTodoAccessXML::toString( const OTodo& ev )const { |
312 | QString str; | 348 | QString str; |
313 | 349 | ||
314 | str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; | 350 | str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; |
315 | str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; | 351 | str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; |
316 | str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; | 352 | str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; |
317 | str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; | 353 | str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; |
318 | 354 | ||
319 | str += "Categories=\"" + toString( ev.categories() ) + "\" "; | 355 | str += "Categories=\"" + toString( ev.categories() ) + "\" "; |
320 | str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; | 356 | str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; |
321 | str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; | 357 | str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; |
@@ -471,25 +507,25 @@ public: | |||
471 | int m_sort; | 507 | int m_sort; |
472 | 508 | ||
473 | }; | 509 | }; |
474 | 510 | ||
475 | QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, | 511 | QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, |
476 | int sortFilter, int cat ) { | 512 | int sortFilter, int cat ) { |
477 | OTodoXMLVector vector(m_events.count(), asc,sortOrder ); | 513 | OTodoXMLVector vector(m_events.count(), asc,sortOrder ); |
478 | QMap<int, OTodo>::Iterator it; | 514 | QMap<int, OTodo>::Iterator it; |
479 | int item = 0; | 515 | int item = 0; |
480 | 516 | ||
481 | bool bCat = sortFilter & 1 ? true : false; | 517 | bool bCat = sortFilter & 1 ? true : false; |
482 | bool bOver = sortFilter & 0 ? true : false; | 518 | bool bOver = sortFilter & 0 ? true : false; |
483 | bool bOnly = split & 2 ? true : false; | 519 | bool bOnly = sortFilter & 2 ? true : false; |
484 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | 520 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { |
485 | 521 | ||
486 | /* show category */ | 522 | /* show category */ |
487 | if ( bCat ) | 523 | if ( bCat ) |
488 | if (!(*it).categories().contains( cat ) ) | 524 | if (!(*it).categories().contains( cat ) ) |
489 | continue; | 525 | continue; |
490 | /* isOverdue but we should not show overdue */ | 526 | /* isOverdue but we should not show overdue */ |
491 | if ( (*it).isOverdue() && ( !bOver || !bOnly ) ) | 527 | if ( (*it).isOverdue() && ( !bOver || !bOnly ) ) |
492 | continue; | 528 | continue; |
493 | if ( !(*it).isOverdue() && bOnly ) | 529 | if ( !(*it).isOverdue() && bOnly ) |
494 | continue; | 530 | continue; |
495 | 531 | ||
diff --git a/libopie2/opiepim/backend/otodoaccessxml.h b/libopie2/opiepim/backend/otodoaccessxml.h index 6886bab..1e7e371 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.h +++ b/libopie2/opiepim/backend/otodoaccessxml.h | |||
@@ -30,26 +30,27 @@ public: | |||
30 | bool add( const OTodo& ); | 30 | bool add( const OTodo& ); |
31 | bool remove( int uid ); | 31 | bool remove( int uid ); |
32 | bool replace( const OTodo& ); | 32 | bool replace( const OTodo& ); |
33 | 33 | ||
34 | /* our functions */ | 34 | /* our functions */ |
35 | QArray<int> effectiveToDos( const QDate& start, | 35 | QArray<int> effectiveToDos( const QDate& start, |
36 | const QDate& end, | 36 | const QDate& end, |
37 | bool includeNoDates ); | 37 | bool includeNoDates ); |
38 | QArray<int> overDue(); | 38 | QArray<int> overDue(); |
39 | QArray<int> sorted( bool asc, int sortOrder, | 39 | QArray<int> sorted( bool asc, int sortOrder, |
40 | int sortFilter, int cat ); | 40 | int sortFilter, int cat ); |
41 | private: | 41 | private: |
42 | OTodo todo( QAsciiDict<int>*, Opie::XMLElement* )const; | 42 | void todo( QAsciiDict<int>*, OTodo&,const QCString&,const QString& ); |
43 | QString toString( const OTodo& )const; | 43 | QString toString( const OTodo& )const; |
44 | QString toString( const QArray<int>& ints ) const; | 44 | QString toString( const QArray<int>& ints ) const; |
45 | QMap<int, OTodo> m_events; | 45 | QMap<int, OTodo> m_events; |
46 | QString m_file; | 46 | QString m_file; |
47 | QString m_app; | 47 | QString m_app; |
48 | bool m_opened : 1; | 48 | bool m_opened : 1; |
49 | bool m_changed : 1; | 49 | bool m_changed : 1; |
50 | class OTodoAccessXMLPrivate; | 50 | class OTodoAccessXMLPrivate; |
51 | OTodoAccessXMLPrivate* d; | 51 | OTodoAccessXMLPrivate* d; |
52 | int m_year, m_month, m_day; | ||
52 | 53 | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | #endif | 56 | #endif |
diff --git a/libopie2/opiepim/otodo.cpp b/libopie2/opiepim/otodo.cpp index eb9dad3..6dd4c0e 100644 --- a/libopie2/opiepim/otodo.cpp +++ b/libopie2/opiepim/otodo.cpp | |||
@@ -163,25 +163,24 @@ void OTodo::setDescription(const QString &desc ) | |||
163 | { | 163 | { |
164 | // qWarning( "desc " + desc ); | 164 | // qWarning( "desc " + desc ); |
165 | changeOrModify(); | 165 | changeOrModify(); |
166 | data->desc = Qtopia::simplifyMultiLineSpace(desc ); | 166 | data->desc = Qtopia::simplifyMultiLineSpace(desc ); |
167 | } | 167 | } |
168 | void OTodo::setSummary( const QString& sum ) | 168 | void OTodo::setSummary( const QString& sum ) |
169 | { | 169 | { |
170 | changeOrModify(); | 170 | changeOrModify(); |
171 | data->sum = sum; | 171 | data->sum = sum; |
172 | } | 172 | } |
173 | void OTodo::setPriority(int prio ) | 173 | void OTodo::setPriority(int prio ) |
174 | { | 174 | { |
175 | qWarning("set priority %d", prio); | ||
176 | changeOrModify(); | 175 | changeOrModify(); |
177 | data->priority = prio; | 176 | data->priority = prio; |
178 | } | 177 | } |
179 | void OTodo::setDueDate( QDate date ) | 178 | void OTodo::setDueDate( QDate date ) |
180 | { | 179 | { |
181 | changeOrModify(); | 180 | changeOrModify(); |
182 | data->date = date; | 181 | data->date = date; |
183 | } | 182 | } |
184 | void OTodo::setAlarmDateTime( const QDateTime& alarm ) | 183 | void OTodo::setAlarmDateTime( const QDateTime& alarm ) |
185 | { | 184 | { |
186 | changeOrModify(); | 185 | changeOrModify(); |
187 | data->alarmDateTime = alarm; | 186 | data->alarmDateTime = alarm; |