summaryrefslogtreecommitdiff
path: root/libopie2
Unidiff
Diffstat (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp240
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.h3
-rw-r--r--libopie2/opiepim/otodo.cpp1
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
@@ -1,142 +1,185 @@
1#include <qfile.h> 1#include <qfile.h>
2#include <qvector.h> 2#include <qvector.h>
3 3
4#include <qpe/global.h> 4#include <qpe/global.h>
5#include <qpe/stringutil.h> 5#include <qpe/stringutil.h>
6#include <qpe/timeconversion.h> 6#include <qpe/timeconversion.h>
7 7
8#include <opie/xmltree.h> 8#include <opie/xmltree.h>
9 9
10#include "otodoaccessxml.h" 10#include "otodoaccessxml.h"
11 11
12OTodoAccessXML::OTodoAccessXML( const QString& appName, 12OTodoAccessXML::OTodoAccessXML( const QString& appName,
13 const QString& fileName ) 13 const QString& fileName )
14 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) 14 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
15{ 15{
16 if (!fileName.isEmpty() ) 16 if (!fileName.isEmpty() )
17 m_file = fileName; 17 m_file = fileName;
18 else 18 else
19 m_file = Global::applicationFileName( "todolist", "todolist.xml" ); 19 m_file = Global::applicationFileName( "todolist", "todolist.xml" );
20} 20}
21OTodoAccessXML::~OTodoAccessXML() { 21OTodoAccessXML::~OTodoAccessXML() {
22 22
23} 23}
24bool OTodoAccessXML::load() { 24bool OTodoAccessXML::load() {
25 m_opened = true; 25 m_opened = true;
26 m_changed = false; 26 m_changed = false;
27 /* initialize dict */ 27 /* initialize dict */
28 /* 28 /*
29 * UPDATE dict if you change anything!!! 29 * UPDATE dict if you change anything!!!
30 */ 30 */
31 QAsciiDict<int> dict(15); 31 QAsciiDict<int> dict(15);
32 dict.setAutoDelete( TRUE ); 32 dict.setAutoDelete( TRUE );
33 dict.insert("Categories" , new int(OTodo::Category) ); 33 dict.insert("Categories" , new int(OTodo::Category) );
34 dict.insert("Uid" , new int(OTodo::Uid) ); 34 dict.insert("Uid" , new int(OTodo::Uid) );
35 dict.insert("HasDate" , new int(OTodo::HasDate) ); 35 dict.insert("HasDate" , new int(OTodo::HasDate) );
36 dict.insert("Completed" , new int(OTodo::Completed) ); 36 dict.insert("Completed" , new int(OTodo::Completed) );
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}
81bool OTodoAccessXML::reload() { 124bool OTodoAccessXML::reload() {
82 return load(); 125 return load();
83} 126}
84bool OTodoAccessXML::save() { 127bool 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";
91 QFile f( strNewFile ); 134 QFile f( strNewFile );
92 if (!f.open( IO_WriteOnly|IO_Raw ) ) 135 if (!f.open( IO_WriteOnly|IO_Raw ) )
93 return false; 136 return false;
94 137
95 int written; 138 int written;
96 QString out; 139 QString out;
97 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 140 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
98 141
99 // for all todos 142 // for all todos
100 QMap<int, OTodo>::Iterator it; 143 QMap<int, OTodo>::Iterator it;
101 for (it = m_events.begin(); it != m_events.end(); ++it ) { 144 for (it = m_events.begin(); it != m_events.end(); ++it ) {
102 out+= "<Task " + toString( (*it) ) + " />\n"; 145 out+= "<Task " + toString( (*it) ) + " />\n";
103 QCString cstr = out.utf8(); 146 QCString cstr = out.utf8();
104 written = f.writeBlock( cstr.data(), cstr.length() ); 147 written = f.writeBlock( cstr.data(), cstr.length() );
105 148
106 /* less written then we wanted */ 149 /* less written then we wanted */
107 if ( written != (int)cstr.length() ) { 150 if ( written != (int)cstr.length() ) {
108 f.close(); 151 f.close();
109 QFile::remove( strNewFile ); 152 QFile::remove( strNewFile );
110 return false; 153 return false;
111 } 154 }
112 out = QString::null; 155 out = QString::null;
113 } 156 }
114 157
115 out += "</Tasks>"; 158 out += "</Tasks>";
116 QCString cstr = out.utf8(); 159 QCString cstr = out.utf8();
117 written = f.writeBlock( cstr.data(), cstr.length() ); 160 written = f.writeBlock( cstr.data(), cstr.length() );
118 161
119 if ( written != (int)cstr.length() ) { 162 if ( written != (int)cstr.length() ) {
120 f.close(); 163 f.close();
121 QFile::remove( strNewFile ); 164 QFile::remove( strNewFile );
122 return false; 165 return false;
123 } 166 }
124 /* flush before renaming */ 167 /* flush before renaming */
125 f.close(); 168 f.close();
126 169
127 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 170 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
128// qWarning("error renaming"); 171// qWarning("error renaming");
129 QFile::remove( strNewFile ); 172 QFile::remove( strNewFile );
130 } 173 }
131 174
132 m_changed = false; 175 m_changed = false;
133 return true; 176 return true;
134} 177}
135QArray<int> OTodoAccessXML::allRecords()const { 178QArray<int> OTodoAccessXML::allRecords()const {
136 QArray<int> ids( m_events.count() ); 179 QArray<int> ids( m_events.count() );
137 QMap<int, OTodo>::ConstIterator it; 180 QMap<int, OTodo>::ConstIterator it;
138 int i = 0; 181 int i = 0;
139 182
140 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 183 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
141 ids[i] = it.key(); 184 ids[i] = it.key();
142 i++; 185 i++;
@@ -159,215 +202,208 @@ OTodo OTodoAccessXML::find( int uid )const {
159void OTodoAccessXML::clear() { 202void OTodoAccessXML::clear() {
160 if (m_opened ) 203 if (m_opened )
161 m_changed = true; 204 m_changed = true;
162 205
163 m_events.clear(); 206 m_events.clear();
164} 207}
165bool OTodoAccessXML::add( const OTodo& todo ) { 208bool OTodoAccessXML::add( const OTodo& todo ) {
166// qWarning("add"); 209// qWarning("add");
167 m_changed = true; 210 m_changed = true;
168 m_events.insert( todo.uid(), todo ); 211 m_events.insert( todo.uid(), todo );
169 212
170 return true; 213 return true;
171} 214}
172bool OTodoAccessXML::remove( int uid ) { 215bool OTodoAccessXML::remove( int uid ) {
173 m_changed = true; 216 m_changed = true;
174 m_events.remove( uid ); 217 m_events.remove( uid );
175 218
176 return true; 219 return true;
177} 220}
178bool OTodoAccessXML::replace( const OTodo& todo) { 221bool OTodoAccessXML::replace( const OTodo& todo) {
179 m_changed = true; 222 m_changed = true;
180 m_events.replace( todo.uid(), todo ); 223 m_events.replace( todo.uid(), todo );
181 224
182 return true; 225 return true;
183} 226}
184QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, 227QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
185 const QDate& end, 228 const QDate& end,
186 bool includeNoDates ) { 229 bool includeNoDates ) {
187 QArray<int> ids( m_events.count() ); 230 QArray<int> ids( m_events.count() );
188 QMap<int, OTodo>::Iterator it; 231 QMap<int, OTodo>::Iterator it;
189 232
190 int i = 0; 233 int i = 0;
191 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 234 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
192 if ( !it.data().hasDueDate() ) { 235 if ( !it.data().hasDueDate() ) {
193 if ( includeNoDates ) { 236 if ( includeNoDates ) {
194 ids[i] = it.key(); 237 ids[i] = it.key();
195 i++; 238 i++;
196 } 239 }
197 }else if ( it.data().dueDate() >= start && 240 }else if ( it.data().dueDate() >= start &&
198 it.data().dueDate() <= end ) { 241 it.data().dueDate() <= end ) {
199 ids[i] = it.key(); 242 ids[i] = it.key();
200 i++; 243 i++;
201 } 244 }
202 } 245 }
203 ids.resize( i ); 246 ids.resize( i );
204 return ids; 247 return ids;
205} 248}
206QArray<int> OTodoAccessXML::overDue() { 249QArray<int> OTodoAccessXML::overDue() {
207 QArray<int> ids( m_events.count() ); 250 QArray<int> ids( m_events.count() );
208 int i = 0; 251 int i = 0;
209 252
210 QMap<int, OTodo>::Iterator it; 253 QMap<int, OTodo>::Iterator it;
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 */
223OTodo OTodoAccessXML::todo( QAsciiDict<int>* dict, Opie::XMLElement* element)const { 266void 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}
311QString OTodoAccessXML::toString( const OTodo& ev )const { 347QString 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() ) + "\" ";
322 358
323 if ( ev.hasDueDate() ) { 359 if ( ev.hasDueDate() ) {
324 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 360 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
325 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 361 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
326 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 362 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
327 } 363 }
328// qWarning( "Uid %d", ev.uid() ); 364// qWarning( "Uid %d", ev.uid() );
329 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 365 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
330 366
331// append the extra options 367// append the extra options
332 /* FIXME Qtopia::Record this is currently not 368 /* FIXME Qtopia::Record this is currently not
333 * possible you can set custom fields 369 * possible you can set custom fields
334 * but don' iterate over the list 370 * but don' iterate over the list
335 * I may do #define private protected 371 * I may do #define private protected
336 * for this case - cough --zecke 372 * for this case - cough --zecke
337 */ 373 */
338 /* 374 /*
339 QMap<QString, QString> extras = ev.extras(); 375 QMap<QString, QString> extras = ev.extras();
340 QMap<QString, QString>::Iterator extIt; 376 QMap<QString, QString>::Iterator extIt;
341 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 377 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
342 str += extIt.key() + "=\"" + extIt.data() + "\" "; 378 str += extIt.key() + "=\"" + extIt.data() + "\" ";
343 */ 379 */
344 // cross refernce 380 // cross refernce
345 QStringList list = ev.relatedApps(); 381 QStringList list = ev.relatedApps();
346 QStringList::Iterator listIt; 382 QStringList::Iterator listIt;
347 QString refs; 383 QString refs;
348 str += "CrossReference=\""; 384 str += "CrossReference=\"";
349 bool added = false; 385 bool added = false;
350 for ( listIt = list.begin(); listIt != list.end(); ++listIt ) { 386 for ( listIt = list.begin(); listIt != list.end(); ++listIt ) {
351 added = true; 387 added = true;
352 QArray<int> ints = ev.relations( (*listIt) ); 388 QArray<int> ints = ev.relations( (*listIt) );
353 for ( uint i = 0; i< ints.count(); i++ ) { 389 for ( uint i = 0; i< ints.count(); i++ ) {
354 str += (*listIt) + "," + QString::number( i ) + ";"; 390 str += (*listIt) + "," + QString::number( i ) + ";";
355 } 391 }
356 } 392 }
357 if ( added ) 393 if ( added )
358 str = str.remove( str.length()-1, 1 ); 394 str = str.remove( str.length()-1, 1 );
359 395
360 str += "\" "; 396 str += "\" ";
361 397
362 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" "; 398 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" ";
363 399
364 return str; 400 return str;
365} 401}
366QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 402QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
367 return Qtopia::Record::idsToString( ints ); 403 return Qtopia::Record::idsToString( ints );
368} 404}
369 405
370/* internal class for sorting */ 406/* internal class for sorting */
371 407
372struct OTodoXMLContainer { 408struct OTodoXMLContainer {
373 OTodo todo; 409 OTodo todo;
@@ -419,93 +455,93 @@ public:
419 qWarning("m_sort %d", m_sort ); 455 qWarning("m_sort %d", m_sort );
420 456
421 switch ( m_sort ) { 457 switch ( m_sort ) {
422 /* completed */ 458 /* completed */
423 case 0: { 459 case 0: {
424 ret = 0; 460 ret = 0;
425 if ( con1->todo.isCompleted() ) ret++; 461 if ( con1->todo.isCompleted() ) ret++;
426 if ( con2->todo.isCompleted() ) ret--; 462 if ( con2->todo.isCompleted() ) ret--;
427 break; 463 break;
428 } 464 }
429 /* priority */ 465 /* priority */
430 case 1: { 466 case 1: {
431 ret = con1->todo.priority() - con2->todo.priority(); 467 ret = con1->todo.priority() - con2->todo.priority();
432 qWarning(" priority %d %d %d", ret, 468 qWarning(" priority %d %d %d", ret,
433 con1->todo.priority(), 469 con1->todo.priority(),
434 con2->todo.priority() 470 con2->todo.priority()
435 ); 471 );
436 break; 472 break;
437 } 473 }
438 /* description */ 474 /* description */
439 case 2: { 475 case 2: {
440 QString str1 = string( con1->todo ); 476 QString str1 = string( con1->todo );
441 QString str2 = string( con2->todo ); 477 QString str2 = string( con2->todo );
442 ret = QString::compare( str1, str2 ); 478 ret = QString::compare( str1, str2 );
443 break; 479 break;
444 } 480 }
445 /* deadline */ 481 /* deadline */
446 case 3: { 482 case 3: {
447 /* either bot got a dueDate 483 /* either bot got a dueDate
448 * or one of them got one 484 * or one of them got one
449 */ 485 */
450 if ( con1->todo.hasDueDate() && 486 if ( con1->todo.hasDueDate() &&
451 con2->todo.hasDueDate() ) 487 con2->todo.hasDueDate() )
452 ret = con1->todo.dueDate().daysTo( con2->todo.dueDate() ); 488 ret = con1->todo.dueDate().daysTo( con2->todo.dueDate() );
453 else if ( con1->todo.hasDueDate() ) 489 else if ( con1->todo.hasDueDate() )
454 ret = -1; 490 ret = -1;
455 else if ( con2->todo.hasDueDate() ) 491 else if ( con2->todo.hasDueDate() )
456 ret = 0; 492 ret = 0;
457 break; 493 break;
458 } 494 }
459 default: 495 default:
460 ret = 0; 496 ret = 0;
461 break; 497 break;
462 }; 498 };
463 499
464 /* twist it we're not ascending*/ 500 /* twist it we're not ascending*/
465 if (!m_asc) 501 if (!m_asc)
466 ret = ret * -1; 502 ret = ret * -1;
467 return ret; 503 return ret;
468 } 504 }
469 private: 505 private:
470 bool m_asc; 506 bool m_asc;
471 int m_sort; 507 int m_sort;
472 508
473}; 509};
474 510
475QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, 511QArray<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
496 532
497 OTodoXMLContainer* con = new OTodoXMLContainer(); 533 OTodoXMLContainer* con = new OTodoXMLContainer();
498 con->todo = (*it); 534 con->todo = (*it);
499 vector.insert(item, con ); 535 vector.insert(item, con );
500 item++; 536 item++;
501 } 537 }
502 vector.resize( item ); 538 vector.resize( item );
503 /* sort it now */ 539 /* sort it now */
504 vector.sort(); 540 vector.sort();
505 /* now get the uids */ 541 /* now get the uids */
506 QArray<int> array( vector.count() ); 542 QArray<int> array( vector.count() );
507 for (uint i= 0; i < vector.count(); i++ ) { 543 for (uint i= 0; i < vector.count(); i++ ) {
508 array[i] = ( vector.at(i) )->todo.uid(); 544 array[i] = ( vector.at(i) )->todo.uid();
509 } 545 }
510 return array; 546 return array;
511}; 547};
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
@@ -1,55 +1,56 @@
1#ifndef OPIE_TODO_ACCESS_XML_H 1#ifndef OPIE_TODO_ACCESS_XML_H
2#define OPIE_TODO_ACCESS_XML_H 2#define OPIE_TODO_ACCESS_XML_H
3 3
4#include <qasciidict.h> 4#include <qasciidict.h>
5#include <qmap.h> 5#include <qmap.h>
6 6
7#include "otodoaccessbackend.h" 7#include "otodoaccessbackend.h"
8 8
9namespace Opie { 9namespace Opie {
10 class XMLElement; 10 class XMLElement;
11}; 11};
12 12
13class OTodoAccessXML : public OTodoAccessBackend { 13class OTodoAccessXML : public OTodoAccessBackend {
14public: 14public:
15 /** 15 /**
16 * fileName if Empty we will use the default path 16 * fileName if Empty we will use the default path
17 */ 17 */
18 OTodoAccessXML( const QString& appName, 18 OTodoAccessXML( const QString& appName,
19 const QString& fileName = QString::null ); 19 const QString& fileName = QString::null );
20 ~OTodoAccessXML(); 20 ~OTodoAccessXML();
21 21
22 bool load(); 22 bool load();
23 bool reload(); 23 bool reload();
24 bool save(); 24 bool save();
25 25
26 QArray<int> allRecords()const; 26 QArray<int> allRecords()const;
27 QArray<int> queryByExample( const OTodo&, int sort ); 27 QArray<int> queryByExample( const OTodo&, int sort );
28 OTodo find( int uid )const; 28 OTodo find( int uid )const;
29 void clear(); 29 void clear();
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 );
41private: 41private:
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
@@ -111,129 +111,128 @@ bool OTodo::isCompleted() const
111 return data->isCompleted; 111 return data->isCompleted;
112} 112}
113bool OTodo::hasDueDate() const 113bool OTodo::hasDueDate() const
114{ 114{
115 return data->hasDate; 115 return data->hasDate;
116} 116}
117bool OTodo::hasAlarmDateTime() const 117bool OTodo::hasAlarmDateTime() const
118{ 118{
119 return data->hasAlarmDateTime; 119 return data->hasAlarmDateTime;
120} 120}
121int OTodo::priority()const 121int OTodo::priority()const
122{ 122{
123 return data->priority; 123 return data->priority;
124} 124}
125QString OTodo::summary() const 125QString OTodo::summary() const
126{ 126{
127 return data->sum; 127 return data->sum;
128} 128}
129ushort OTodo::progress() const 129ushort OTodo::progress() const
130{ 130{
131 return data->prog; 131 return data->prog;
132} 132}
133QDate OTodo::dueDate()const 133QDate OTodo::dueDate()const
134{ 134{
135 return data->date; 135 return data->date;
136} 136}
137 137
138QDateTime OTodo::alarmDateTime() const 138QDateTime OTodo::alarmDateTime() const
139{ 139{
140 return data->alarmDateTime; 140 return data->alarmDateTime;
141} 141}
142 142
143QString OTodo::description()const 143QString OTodo::description()const
144{ 144{
145 return data->desc; 145 return data->desc;
146} 146}
147void OTodo::setCompleted( bool completed ) 147void OTodo::setCompleted( bool completed )
148{ 148{
149 changeOrModify(); 149 changeOrModify();
150 data->isCompleted = completed; 150 data->isCompleted = completed;
151} 151}
152void OTodo::setHasDueDate( bool hasDate ) 152void OTodo::setHasDueDate( bool hasDate )
153{ 153{
154 changeOrModify(); 154 changeOrModify();
155 data->hasDate = hasDate; 155 data->hasDate = hasDate;
156} 156}
157void OTodo::setHasAlarmDateTime( bool hasAlarmDateTime ) 157void OTodo::setHasAlarmDateTime( bool hasAlarmDateTime )
158{ 158{
159 changeOrModify(); 159 changeOrModify();
160 data->hasAlarmDateTime = hasAlarmDateTime; 160 data->hasAlarmDateTime = hasAlarmDateTime;
161} 161}
162void OTodo::setDescription(const QString &desc ) 162void 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}
168void OTodo::setSummary( const QString& sum ) 168void OTodo::setSummary( const QString& sum )
169{ 169{
170 changeOrModify(); 170 changeOrModify();
171 data->sum = sum; 171 data->sum = sum;
172} 172}
173void OTodo::setPriority(int prio ) 173void 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}
179void OTodo::setDueDate( QDate date ) 178void OTodo::setDueDate( QDate date )
180{ 179{
181 changeOrModify(); 180 changeOrModify();
182 data->date = date; 181 data->date = date;
183} 182}
184void OTodo::setAlarmDateTime( const QDateTime& alarm ) 183void OTodo::setAlarmDateTime( const QDateTime& alarm )
185{ 184{
186 changeOrModify(); 185 changeOrModify();
187 data->alarmDateTime = alarm; 186 data->alarmDateTime = alarm;
188} 187}
189bool OTodo::isOverdue( ) 188bool OTodo::isOverdue( )
190{ 189{
191 if( data->hasDate ) 190 if( data->hasDate )
192 return QDate::currentDate() > data->date; 191 return QDate::currentDate() > data->date;
193 return false; 192 return false;
194} 193}
195void OTodo::setProgress(ushort progress ) 194void OTodo::setProgress(ushort progress )
196{ 195{
197 changeOrModify(); 196 changeOrModify();
198 data->prog = progress; 197 data->prog = progress;
199} 198}
200QString OTodo::toShortText() const { 199QString OTodo::toShortText() const {
201 return summary(); 200 return summary();
202} 201}
203/*! 202/*!
204 Returns a richt text string 203 Returns a richt text string
205*/ 204*/
206QString OTodo::toRichText() const 205QString OTodo::toRichText() const
207{ 206{
208 QString text; 207 QString text;
209 QStringList catlist; 208 QStringList catlist;
210 209
211 // Description of the todo 210 // Description of the todo
212 if ( !summary().isEmpty() ) { 211 if ( !summary().isEmpty() ) {
213 text += "<b>" + QObject::tr( "Summary:") + "</b><br>"; 212 text += "<b>" + QObject::tr( "Summary:") + "</b><br>";
214 text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; 213 text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
215 } 214 }
216 if( !description().isEmpty() ){ 215 if( !description().isEmpty() ){
217 text += "<b>" + QObject::tr( "Description:" ) + "</b><br>"; 216 text += "<b>" + QObject::tr( "Description:" ) + "</b><br>";
218 text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) ; 217 text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) ;
219 } 218 }
220 text += "<br><br><br>"; 219 text += "<br><br><br>";
221 220
222 text += "<b>" + QObject::tr( "Priority:") +" </b>" 221 text += "<b>" + QObject::tr( "Priority:") +" </b>"
223 + QString::number( priority() ) + " <br>"; 222 + QString::number( priority() ) + " <br>";
224 text += "<b>" + QObject::tr( "Progress:") + " </b>" 223 text += "<b>" + QObject::tr( "Progress:") + " </b>"
225 + QString::number( progress() ) + " %<br>"; 224 + QString::number( progress() ) + " %<br>";
226 if (hasDueDate() ){ 225 if (hasDueDate() ){
227 text += "<b>" + QObject::tr( "Deadline:") + " </b>"; 226 text += "<b>" + QObject::tr( "Deadline:") + " </b>";
228 text += dueDate().toString(); 227 text += dueDate().toString();
229 text += "<br>"; 228 text += "<br>";
230 } 229 }
231 if (hasAlarmDateTime() ){ 230 if (hasAlarmDateTime() ){
232 text += "<b>" + QObject::tr( "Alarmed Notification:") + " </b>"; 231 text += "<b>" + QObject::tr( "Alarmed Notification:") + " </b>";
233 text += alarmDateTime().toString(); 232 text += alarmDateTime().toString();
234 text += "<br>"; 233 text += "<br>";
235 } 234 }
236 235
237 text += "<b>" + QObject::tr( "Category:") + "</b> "; 236 text += "<b>" + QObject::tr( "Category:") + "</b> ";
238 text += categoryNames().join(", "); 237 text += categoryNames().join(", ");
239 text += "<br>"; 238 text += "<br>";