summaryrefslogtreecommitdiff
path: root/libopie/pim
authorzecke <zecke>2002-09-25 11:59:24 (UTC)
committer zecke <zecke>2002-09-25 11:59:24 (UTC)
commit38240090027bd68d8dd15d7d46ecf17792edb732 (patch) (unidiff)
tree589ef486d7169c57592ed8667f6c84d43f882d48 /libopie/pim
parent5f2dd0a2340914b4983ebce3813187034e2cb9dc (diff)
downloadopie-38240090027bd68d8dd15d7d46ecf17792edb732.zip
opie-38240090027bd68d8dd15d7d46ecf17792edb732.tar.gz
opie-38240090027bd68d8dd15d7d46ecf17792edb732.tar.bz2
Add a sort function and filter function to TodoAccess
This would allow us todo a paint hack in QTable
Diffstat (limited to 'libopie/pim') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/orecordlist.h17
-rw-r--r--libopie/pim/otodo.cpp1
-rw-r--r--libopie/pim/otodoaccess.cpp8
-rw-r--r--libopie/pim/otodoaccess.h16
-rw-r--r--libopie/pim/otodoaccessbackend.h2
-rw-r--r--libopie/pim/otodoaccessxml.cpp145
-rw-r--r--libopie/pim/otodoaccessxml.h2
7 files changed, 183 insertions, 8 deletions
diff --git a/libopie/pim/orecordlist.h b/libopie/pim/orecordlist.h
index c63d813..1fd0741 100644
--- a/libopie/pim/orecordlist.h
+++ b/libopie/pim/orecordlist.h
@@ -37,35 +37,35 @@ public:
37 ORecordListIterator &operator=(const ORecordListIterator& ); 37 ORecordListIterator &operator=(const ORecordListIterator& );
38 38
39 /** 39 /**
40 * a * operator ;) 40 * a * operator ;)
41 * use it like this T = (*it); 41 * use it like this T = (*it);
42 */ 42 */
43 T operator*(); 43 T operator*();
44 ORecordListIterator &operator++(); 44 ORecordListIterator &operator++();
45 ORecordListIterator &operator--(); 45 ORecordListIterator &operator--();
46 46
47 bool operator==( const ORecordListIterator& it ); 47 bool operator==( const ORecordListIterator& it );
48 bool operator!=( const ORecordListIterator& it ); 48 bool operator!=( const ORecordListIterator& it );
49 49
50 /** 50 /**
51 * the current item 51 * the current item
52 */ 52 */
53 uint current()const; 53 uint current()const;
54 54
55 /** 55 /**
56 * the number of items 56 * the number of items
57 */ 57 */
58 uint count()const; 58 uint count()const;
59 59
60 /** 60 /**
61 * sets the current item 61 * sets the current item
62 */ 62 */
63 void setCurrent( uint cur ); 63 void setCurrent( uint cur );
64 64
65private: 65private:
66 QArray<int> m_uids; 66 QArray<int> m_uids;
67 uint m_current; 67 uint m_current;
68 const Base* m_temp; 68 const Base* m_temp;
69 bool m_end : 1; 69 bool m_end : 1;
70 T m_record; 70 T m_record;
71 71
@@ -92,30 +92,31 @@ public:
92 const Base* ); 92 const Base* );
93 ~ORecordList(); 93 ~ORecordList();
94 94
95 /** 95 /**
96 * the first iterator 96 * the first iterator
97 */ 97 */
98 Iterator begin(); 98 Iterator begin();
99 99
100 /** 100 /**
101 * the end 101 * the end
102 */ 102 */
103 Iterator end(); 103 Iterator end();
104 104
105 /** 105 /**
106 * the number of items in the list 106 * the number of items in the list
107 */ 107 */
108 uint count()const; 108 uint count()const;
109 109
110 T operator[]( uint i );
110 // FIXME implemenent remove 111 // FIXME implemenent remove
111 /* 112 /*
112 ConstIterator begin()const; 113 ConstIterator begin()const;
113 ConstIterator end()const; 114 ConstIterator end()const;
114 */ 115 */
115private: 116private:
116 QArray<int> m_ids; 117 QArray<int> m_ids;
117 const Base* m_acc; 118 const Base* m_acc;
118}; 119};
119 120
120/* ok now implement it */ 121/* ok now implement it */
121template <class T> 122template <class T>
@@ -137,25 +138,25 @@ ORecordListIterator<T>::ORecordListIterator( const ORecordListIterator<T>& it) {
137 m_current = it.m_current; 138 m_current = it.m_current;
138 m_temp = it.m_temp; 139 m_temp = it.m_temp;
139 m_end = it.m_end; 140 m_end = it.m_end;
140 m_record = it.m_record; 141 m_record = it.m_record;
141} 142}
142 143
143template <class T> 144template <class T>
144ORecordListIterator<T> &ORecordListIterator<T>::operator=( const ORecordListIterator<T>& it) { 145ORecordListIterator<T> &ORecordListIterator<T>::operator=( const ORecordListIterator<T>& it) {
145 m_uids = it.m_uids; 146 m_uids = it.m_uids;
146 m_current = it.m_current; 147 m_current = it.m_current;
147 m_temp = it.m_temp; 148 m_temp = it.m_temp;
148 m_end = it.m_end; 149 m_end = it.m_end;
149// m_record = it.m_record; 150 m_record = it.m_record;
150 151
151 return *this; 152 return *this;
152} 153}
153 154
154template <class T> 155template <class T>
155T ORecordListIterator<T>::operator*() { 156T ORecordListIterator<T>::operator*() {
156// qWarning("operator* %d %d", m_current, m_uids[m_current] ); 157// qWarning("operator* %d %d", m_current, m_uids[m_current] );
157 if (!m_end ) 158 if (!m_end )
158 /* FIXME 159 /* FIXME
159 * until the cache is in place 160 * until the cache is in place
160 * we do the uid match uid check 161 * we do the uid match uid check
161 */ 162 */
@@ -243,13 +244,17 @@ ORecordList<T>::Iterator ORecordList<T>::begin() {
243template <class T> 244template <class T>
244ORecordList<T>::Iterator ORecordList<T>::end() { 245ORecordList<T>::Iterator ORecordList<T>::end() {
245 Iterator it( m_ids, m_acc ); 246 Iterator it( m_ids, m_acc );
246 it.m_end = true; 247 it.m_end = true;
247 it.m_current = m_ids.count(); 248 it.m_current = m_ids.count();
248 249
249 return it; 250 return it;
250} 251}
251template <class T> 252template <class T>
252uint ORecordList<T>::count()const { 253uint ORecordList<T>::count()const {
253return m_ids.count(); 254return m_ids.count();
254} 255}
256template <class T>
257T ORecordList<T>::operator[]( uint i ) {
258 return m_acc->find( m_ids[i] );
259}
255#endif 260#endif
diff --git a/libopie/pim/otodo.cpp b/libopie/pim/otodo.cpp
index 6dd4c0e..eb9dad3 100644
--- a/libopie/pim/otodo.cpp
+++ b/libopie/pim/otodo.cpp
@@ -163,24 +163,25 @@ 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}
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);
175 changeOrModify(); 176 changeOrModify();
176 data->priority = prio; 177 data->priority = prio;
177} 178}
178void OTodo::setDueDate( QDate date ) 179void OTodo::setDueDate( QDate date )
179{ 180{
180 changeOrModify(); 181 changeOrModify();
181 data->date = date; 182 data->date = date;
182} 183}
183void OTodo::setAlarmDateTime( const QDateTime& alarm ) 184void OTodo::setAlarmDateTime( const QDateTime& alarm )
184{ 185{
185 changeOrModify(); 186 changeOrModify();
186 data->alarmDateTime = alarm; 187 data->alarmDateTime = alarm;
diff --git a/libopie/pim/otodoaccess.cpp b/libopie/pim/otodoaccess.cpp
index 8ec09bc..f51da29 100644
--- a/libopie/pim/otodoaccess.cpp
+++ b/libopie/pim/otodoaccess.cpp
@@ -59,13 +59,19 @@ void OTodoAccess::delAlarm( int uid) {
59 QDateTime schedule; // Create null DateTime 59 QDateTime schedule; // Create null DateTime
60 60
61 // I hope this will remove all scheduled alarms 61 // I hope this will remove all scheduled alarms
62 // with the given uid !? 62 // with the given uid !?
63 // If not: I have to rethink how to remove already 63 // If not: I have to rethink how to remove already
64 // scheduled events... (se) 64 // scheduled events... (se)
65 // it should be fine -zecke 65 // it should be fine -zecke
66// qWarning("Removing alarm for event with uid %d", uid ); 66// qWarning("Removing alarm for event with uid %d", uid );
67 AlarmServer::deleteAlarm( schedule , 67 AlarmServer::deleteAlarm( schedule ,
68 "QPE/Application/todolist", 68 "QPE/Application/todolist",
69 "alarm(QDateTime,int)", uid ); 69 "alarm(QDateTime,int)", uid );
70} 70}
71 71/* sort order */
72OTodoAccess::List OTodoAccess::sorted( bool ascending, int sort,int filter, int cat ) {
73 QArray<int> ints = m_todoBackEnd->sorted( ascending, sort,
74 filter, cat );
75 OTodoAccess::List list( ints, this );
76 return list;
77}
diff --git a/libopie/pim/otodoaccess.h b/libopie/pim/otodoaccess.h
index c43efe9..12997aa 100644
--- a/libopie/pim/otodoaccess.h
+++ b/libopie/pim/otodoaccess.h
@@ -8,28 +8,35 @@
8#include "otodoaccessbackend.h" 8#include "otodoaccessbackend.h"
9#include "opimaccesstemplate.h" 9#include "opimaccesstemplate.h"
10 10
11 11
12/** 12/**
13 * OTodoAccess 13 * OTodoAccess
14 * the class to get access to 14 * the class to get access to
15 * the todolist 15 * the todolist
16 */ 16 */
17class OTodoAccess : public QObject, public OPimAccessTemplate<OTodo> { 17class OTodoAccess : public QObject, public OPimAccessTemplate<OTodo> {
18 Q_OBJECT 18 Q_OBJECT
19public: 19public:
20 enum SortOrder { Completed = 0,
21 Priority,
22 Description,
23 Deadline };
24 enum SortFilter{ ShowOverdue = 0,
25 Category =1,
26 OnlyOverDue= 2 };
20 /** 27 /**
21 * if you use 0l 28 * if you use 0l
22 * the default resource will be 29 * the default resource will be
23 * icked up 30 * picked up
24 */ 31 */
25 OTodoAccess( OTodoAccessBackend* = 0l); 32 OTodoAccess( OTodoAccessBackend* = 0l);
26 ~OTodoAccess(); 33 ~OTodoAccess();
27 34
28 35
29 /* our functions here */ 36 /* our functions here */
30 /** 37 /**
31 * include todos from start to end 38 * include todos from start to end
32 * includeNoDates whether or not to include 39 * includeNoDates whether or not to include
33 * events with no dates 40 * events with no dates
34 */ 41 */
35 List effectiveToDos( const QDate& start, 42 List effectiveToDos( const QDate& start,
@@ -39,41 +46,48 @@ public:
39 /** 46 /**
40 * start 47 * start
41 * end date taken from the currentDate() 48 * end date taken from the currentDate()
42 */ 49 */
43 List effectiveToDos( const QDate& start, 50 List effectiveToDos( const QDate& start,
44 bool includeNoDates = true ); 51 bool includeNoDates = true );
45 52
46 53
47 /** 54 /**
48 * return overdue OTodos 55 * return overdue OTodos
49 */ 56 */
50 List overDue(); 57 List overDue();
58
59 /**
60 *
61 */
62 List sorted( bool ascending, int sortOrder, int sortFilter, int cat );
63
51 /** 64 /**
52 * merge a list of OTodos into 65 * merge a list of OTodos into
53 * the resource 66 * the resource
54 */ 67 */
55 void mergeWith( const QValueList<OTodo>& ); 68 void mergeWith( const QValueList<OTodo>& );
56 69
57 /** 70 /**
58 * add an Alarm to the AlarmServer 71 * add an Alarm to the AlarmServer
59 */ 72 */
60 void addAlarm( const OTodo& ); 73 void addAlarm( const OTodo& );
61 74
62 /** 75 /**
63 * delete an alarm with the uid from 76 * delete an alarm with the uid from
64 * the alarm server 77 * the alarm server
65 */ 78 */
66 void delAlarm( int uid ); 79 void delAlarm( int uid );
67 80
68signals: 81signals:
69 /** 82 /**
70 * if the OTodoAccess was changed 83 * if the OTodoAccess was changed
71 */ 84 */
72 void signalChanged( const OTodoAccess* ); 85 void signalChanged( const OTodoAccess* );
73private: 86private:
87 int m_cat;
74 OTodoAccessBackend* m_todoBackEnd; 88 OTodoAccessBackend* m_todoBackEnd;
75 class OTodoAccessPrivate; 89 class OTodoAccessPrivate;
76 OTodoAccessPrivate* d; 90 OTodoAccessPrivate* d;
77}; 91};
78 92
79#endif 93#endif
diff --git a/libopie/pim/otodoaccessbackend.h b/libopie/pim/otodoaccessbackend.h
index ebe2189..3bad6b7 100644
--- a/libopie/pim/otodoaccessbackend.h
+++ b/libopie/pim/otodoaccessbackend.h
@@ -3,16 +3,18 @@
3 3
4#include "otodo.h" 4#include "otodo.h"
5#include "opimaccessbackend.h" 5#include "opimaccessbackend.h"
6 6
7class OTodoAccessBackend : public OPimAccessBackend<OTodo> { 7class OTodoAccessBackend : public OPimAccessBackend<OTodo> {
8public: 8public:
9 OTodoAccessBackend(); 9 OTodoAccessBackend();
10 ~OTodoAccessBackend(); 10 ~OTodoAccessBackend();
11 virtual QArray<int> effectiveToDos( const QDate& start, 11 virtual QArray<int> effectiveToDos( const QDate& start,
12 const QDate& end, 12 const QDate& end,
13 bool includeNoDates ) = 0; 13 bool includeNoDates ) = 0;
14 virtual QArray<int> overDue() = 0; 14 virtual QArray<int> overDue() = 0;
15 virtual QArray<int> sorted( bool asc, int sortOrder, int sortFilter,
16 int cat ) = 0;
15 17
16}; 18};
17 19
18#endif 20#endif
diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp
index 5fe733c..692483e 100644
--- a/libopie/pim/otodoaccessxml.cpp
+++ b/libopie/pim/otodoaccessxml.cpp
@@ -1,13 +1,14 @@
1#include <qfile.h> 1#include <qfile.h>
2#include <qvector.h>
2 3
3#include <qpe/global.h> 4#include <qpe/global.h>
4#include <qpe/stringutil.h> 5#include <qpe/stringutil.h>
5#include <qpe/timeconversion.h> 6#include <qpe/timeconversion.h>
6 7
7#include <opie/xmltree.h> 8#include <opie/xmltree.h>
8 9
9#include "otodoaccessxml.h" 10#include "otodoaccessxml.h"
10 11
11OTodoAccessXML::OTodoAccessXML( const QString& appName, 12OTodoAccessXML::OTodoAccessXML( const QString& appName,
12 const QString& fileName ) 13 const QString& fileName )
13 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) 14 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
@@ -247,24 +248,25 @@ OTodo OTodoAccessXML::todo( QAsciiDict<int>* dict, Opie::XMLElement* element)con
247 ev.setHasDueDate( it.data().toInt() ); 248 ev.setHasDueDate( it.data().toInt() );
248 break; 249 break;
249 case OTodo::Completed: 250 case OTodo::Completed:
250 ev.setCompleted( it.data().toInt() ); 251 ev.setCompleted( it.data().toInt() );
251 break; 252 break;
252 case OTodo::Description: 253 case OTodo::Description:
253 ev.setDescription( it.data() ); 254 ev.setDescription( it.data() );
254 break; 255 break;
255 case OTodo::Summary: 256 case OTodo::Summary:
256 ev.setSummary( it.data() ); 257 ev.setSummary( it.data() );
257 break; 258 break;
258 case OTodo::Priority: 259 case OTodo::Priority:
260 qWarning("ParsePriority " + it.data() );
259 ev.setPriority( it.data().toInt() ); 261 ev.setPriority( it.data().toInt() );
260 break; 262 break;
261 case OTodo::DateDay: 263 case OTodo::DateDay:
262 day = it.data().toInt(); 264 day = it.data().toInt();
263 break; 265 break;
264 case OTodo::DateMonth: 266 case OTodo::DateMonth:
265 month = it.data().toInt(); 267 month = it.data().toInt();
266 break; 268 break;
267 case OTodo::DateYear: 269 case OTodo::DateYear:
268 year = it.data().toInt(); 270 year = it.data().toInt();
269 break; 271 break;
270 case OTodo::Progress: 272 case OTodo::Progress:
@@ -355,12 +357,155 @@ QString OTodoAccessXML::toString( const OTodo& ev )const {
355 if ( added ) 357 if ( added )
356 str = str.remove( str.length()-1, 1 ); 358 str = str.remove( str.length()-1, 1 );
357 359
358 str += "\" "; 360 str += "\" ";
359 361
360 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" "; 362 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" ";
361 363
362 return str; 364 return str;
363} 365}
364QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 366QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
365 return Qtopia::Record::idsToString( ints ); 367 return Qtopia::Record::idsToString( ints );
366} 368}
369
370/* internal class for sorting */
371
372struct OTodoXMLContainer {
373 OTodo todo;
374};
375 /*
376 * Returns:
377 * 0 if item1 == item2
378 *
379 * non-zero if item1 != item2
380 *
381 * This function returns int rather than bool so that reimplementations
382 * can return one of three values and use it to sort by:
383 *
384 * 0 if item1 == item2
385 *
386 * > 0 (positive integer) if item1 > item2
387 *
388 * < 0 (negative integer) if item1 < item2
389 *
390 */
391class OTodoXMLVector : public QVector<OTodoXMLContainer> {
392public:
393 OTodoXMLVector(int size, bool asc, int sort)
394 : QVector<OTodoXMLContainer>( size )
395 {
396 setAutoDelete( true );
397 m_asc = asc;
398 m_sort = sort;
399 }
400 /* return the summary/description */
401 QString string( const OTodo& todo) {
402 return todo.summary().isEmpty() ?
403 todo.description().left(20 ) :
404 todo.summary();
405 }
406 /**
407 * we take the sortorder( switch on it )
408 *
409 */
410 int compareItems( Item d1, Item d2 ) {
411 qWarning("compare items");
412 int ret =0;
413 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
414 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
415
416 /* same item */
417 if ( con1->todo.uid() == con2->todo.uid() )
418 return 0;
419 qWarning("m_sort %d", m_sort );
420
421 switch ( m_sort ) {
422 /* completed */
423 case 0: {
424 ret = 0;
425 if ( con1->todo.isCompleted() ) ret++;
426 if ( con2->todo.isCompleted() ) ret--;
427 break;
428 }
429 /* priority */
430 case 1: {
431 ret = con1->todo.priority() - con2->todo.priority();
432 qWarning(" priority %d %d %d", ret,
433 con1->todo.priority(),
434 con2->todo.priority()
435 );
436 break;
437 }
438 /* description */
439 case 2: {
440 QString str1 = string( con1->todo );
441 QString str2 = string( con2->todo );
442 ret = QString::compare( str1, str2 );
443 break;
444 }
445 /* deadline */
446 case 3: {
447 /* either bot got a dueDate
448 * or one of them got one
449 */
450 if ( con1->todo.hasDueDate() &&
451 con2->todo.hasDueDate() )
452 ret = con1->todo.dueDate().daysTo( con2->todo.dueDate() );
453 else if ( con1->todo.hasDueDate() )
454 ret = -1;
455 else if ( con2->todo.hasDueDate() )
456 ret = 0;
457 break;
458 }
459 default:
460 ret = 0;
461 break;
462 };
463
464 /* twist it we're not ascending*/
465 if (!m_asc)
466 ret = ret * -1;
467 return ret;
468 }
469 private:
470 bool m_asc;
471 int m_sort;
472
473};
474
475QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder,
476 int sortFilter, int cat ) {
477 OTodoXMLVector vector(m_events.count(), asc,sortOrder );
478 QMap<int, OTodo>::Iterator it;
479 int item = 0;
480
481 bool bCat = sortFilter & 1 ? true : false;
482 bool bOver = sortFilter & 0 ? true : false;
483 bool bOnly = split & 2 ? true : false;
484 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
485
486 /* show category */
487 if ( bCat )
488 if (!(*it).categories().contains( cat ) )
489 continue;
490 /* isOverdue but we should not show overdue */
491 if ( (*it).isOverdue() && ( !bOver || !bOnly ) )
492 continue;
493 if ( !(*it).isOverdue() && bOnly )
494 continue;
495
496
497 OTodoXMLContainer* con = new OTodoXMLContainer();
498 con->todo = (*it);
499 vector.insert(item, con );
500 item++;
501 }
502 vector.resize( item );
503 /* sort it now */
504 vector.sort();
505 /* now get the uids */
506 QArray<int> array( vector.count() );
507 for (uint i= 0; i < vector.count(); i++ ) {
508 array[i] = ( vector.at(i) )->todo.uid();
509 }
510 return array;
511};
diff --git a/libopie/pim/otodoaccessxml.h b/libopie/pim/otodoaccessxml.h
index be9109d..6886bab 100644
--- a/libopie/pim/otodoaccessxml.h
+++ b/libopie/pim/otodoaccessxml.h
@@ -27,24 +27,26 @@ public:
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,
40 int sortFilter, int cat );
39private: 41private:
40 OTodo todo( QAsciiDict<int>*, Opie::XMLElement* )const; 42 OTodo todo( QAsciiDict<int>*, Opie::XMLElement* )const;
41 QString toString( const OTodo& )const; 43 QString toString( const OTodo& )const;
42 QString toString( const QArray<int>& ints ) const; 44 QString toString( const QArray<int>& ints ) const;
43 QMap<int, OTodo> m_events; 45 QMap<int, OTodo> m_events;
44 QString m_file; 46 QString m_file;
45 QString m_app; 47 QString m_app;
46 bool m_opened : 1; 48 bool m_opened : 1;
47 bool m_changed : 1; 49 bool m_changed : 1;
48 class OTodoAccessXMLPrivate; 50 class OTodoAccessXMLPrivate;
49 OTodoAccessXMLPrivate* d; 51 OTodoAccessXMLPrivate* d;
50 52