author | zecke <zecke> | 2002-09-22 22:21:51 (UTC) |
---|---|---|
committer | zecke <zecke> | 2002-09-22 22:21:51 (UTC) |
commit | e49230a12104b718c46a34c81b6c0e608c9d40be (patch) (unidiff) | |
tree | 4ef2e58c366a8cf7c4abe04838e255b38613fbcb /libopie2/opiepim/backend | |
parent | 3049d9418b882283814ca71baa98420b2a6745db (diff) | |
download | opie-e49230a12104b718c46a34c81b6c0e608c9d40be.zip opie-e49230a12104b718c46a34c81b6c0e608c9d40be.tar.gz opie-e49230a12104b718c46a34c81b6c0e608c9d40be.tar.bz2 |
Add XML resources for todolist and compile fixes for RecordList
-rw-r--r-- | libopie2/opiepim/backend/opimaccessbackend.h | 28 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccessbackend.cpp | 10 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccessbackend.h | 18 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccessxml.cpp | 362 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccessxml.h | 53 |
5 files changed, 457 insertions, 14 deletions
diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h index 5707b58..c27acbb 100644 --- a/libopie2/opiepim/backend/opimaccessbackend.h +++ b/libopie2/opiepim/backend/opimaccessbackend.h | |||
@@ -20,21 +20,21 @@ public: | |||
20 | OPimAccessBackend(); | 20 | OPimAccessBackend(); |
21 | virtual ~OPimAccessBackend(); | 21 | virtual ~OPimAccessBackend(); |
22 | 22 | ||
23 | /** | 23 | /** |
24 | * load the resource | 24 | * load the resource |
25 | */ | 25 | */ |
26 | virtual void load() = 0; | 26 | virtual bool load() = 0; |
27 | 27 | ||
28 | /** | 28 | /** |
29 | * reload the resource | 29 | * reload the resource |
30 | */ | 30 | */ |
31 | virtual void reload() = 0; | 31 | virtual bool reload() = 0; |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * save the resource and | 34 | * save the resource and |
35 | * all it's changes | 35 | * all it's changes |
36 | */ | 36 | */ |
37 | virtual void save() = 0; | 37 | virtual bool save() = 0; |
38 | 38 | ||
39 | /** | 39 | /** |
40 | * return an array of | 40 | * return an array of |
@@ -42,5 +42,5 @@ public: | |||
42 | */ | 42 | */ |
43 | virtual QArray<int> allRecords()const = 0; | 43 | virtual QArray<int> allRecords()const = 0; |
44 | 44 | ||
45 | /** | 45 | /** |
46 | * queryByExample for T with the SortOrder | 46 | * queryByExample for T with the SortOrder |
@@ -48,26 +48,26 @@ public: | |||
48 | */ | 48 | */ |
49 | virtual QArray<int> queryByExample( const T& t, int sort ) = 0; | 49 | virtual QArray<int> queryByExample( const T& t, int sort ) = 0; |
50 | 50 | ||
51 | /** | 51 | /** |
52 | * find the OPimRecord with uid @param uid | 52 | * find the OPimRecord with uid @param uid |
53 | * returns T and T.isEmpty() if nothing was found | 53 | * returns T and T.isEmpty() if nothing was found |
54 | */ | 54 | */ |
55 | virtual T find(int uid ) = 0; | 55 | virtual T find(int uid )const = 0; |
56 | 56 | ||
57 | /** | 57 | /** |
58 | * clear the back end | 58 | * clear the back end |
59 | */ | 59 | */ |
60 | virtual void clear() = 0; | 60 | virtual void clear() = 0; |
61 | 61 | ||
62 | /** | 62 | /** |
63 | * add T | 63 | * add T |
64 | */ | 64 | */ |
65 | virtual bool add( const T& t ) = 0; | 65 | virtual bool add( const T& t ) = 0; |
66 | 66 | ||
67 | /** | 67 | /** |
68 | * remove | 68 | * remove |
69 | */ | 69 | */ |
70 | virtual bool remove( int uid ) = 0; | 70 | virtual bool remove( int uid ) = 0; |
71 | 71 | ||
72 | /** | 72 | /** |
73 | * replace a record with T.uid() | 73 | * replace a record with T.uid() |
diff --git a/libopie2/opiepim/backend/otodoaccessbackend.cpp b/libopie2/opiepim/backend/otodoaccessbackend.cpp new file mode 100644 index 0000000..baaeecc --- a/dev/null +++ b/libopie2/opiepim/backend/otodoaccessbackend.cpp | |||
@@ -0,0 +1,10 @@ | |||
1 | |||
2 | #include "otodoaccessbackend.h" | ||
3 | |||
4 | OTodoAccessBackend::OTodoAccessBackend() | ||
5 | : OPimAccessBackend<OTodo>() | ||
6 | { | ||
7 | } | ||
8 | OTodoAccessBackend::~OTodoAccessBackend() { | ||
9 | |||
10 | } | ||
diff --git a/libopie2/opiepim/backend/otodoaccessbackend.h b/libopie2/opiepim/backend/otodoaccessbackend.h new file mode 100644 index 0000000..ebe2189 --- a/dev/null +++ b/libopie2/opiepim/backend/otodoaccessbackend.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef OPIE_TODO_ACCESS_BACKEND_H | ||
2 | #define OPIE_TODO_ACCESS_BACKEND_H | ||
3 | |||
4 | #include "otodo.h" | ||
5 | #include "opimaccessbackend.h" | ||
6 | |||
7 | class OTodoAccessBackend : public OPimAccessBackend<OTodo> { | ||
8 | public: | ||
9 | OTodoAccessBackend(); | ||
10 | ~OTodoAccessBackend(); | ||
11 | virtual QArray<int> effectiveToDos( const QDate& start, | ||
12 | const QDate& end, | ||
13 | bool includeNoDates ) = 0; | ||
14 | virtual QArray<int> overDue() = 0; | ||
15 | |||
16 | }; | ||
17 | |||
18 | #endif | ||
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp new file mode 100644 index 0000000..21756c9 --- a/dev/null +++ b/libopie2/opiepim/backend/otodoaccessxml.cpp | |||
@@ -0,0 +1,362 @@ | |||
1 | #include <qfile.h> | ||
2 | |||
3 | #include <qpe/global.h> | ||
4 | #include <qpe/stringutil.h> | ||
5 | #include <qpe/timeconversion.h> | ||
6 | |||
7 | #include <opie/xmltree.h> | ||
8 | |||
9 | #include "otodoaccessxml.h" | ||
10 | |||
11 | OTodoAccessXML::OTodoAccessXML( const QString& appName, | ||
12 | const QString& fileName ) | ||
13 | : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) | ||
14 | { | ||
15 | if (!fileName.isEmpty() ) | ||
16 | m_file = fileName; | ||
17 | else | ||
18 | m_file = Global::applicationFileName( "todolist", "todolist.xml" ); | ||
19 | } | ||
20 | OTodoAccessXML::~OTodoAccessXML() { | ||
21 | |||
22 | } | ||
23 | bool OTodoAccessXML::load() { | ||
24 | m_opened = false; | ||
25 | m_changed = false; | ||
26 | /* initialize dict */ | ||
27 | /* | ||
28 | * UPDATE dict if you change anything!!! | ||
29 | */ | ||
30 | QAsciiDict<int> dict(15); | ||
31 | dict.setAutoDelete( TRUE ); | ||
32 | dict.insert("Categories" , new int(OTodo::Category) ); | ||
33 | dict.insert("Uid" , new int(OTodo::Uid) ); | ||
34 | dict.insert("HasDate" , new int(OTodo::HasDate) ); | ||
35 | dict.insert("Completed" , new int(OTodo::Completed) ); | ||
36 | dict.insert("Description" , new int(OTodo::Description) ); | ||
37 | dict.insert("Summary" , new int(OTodo::Summary) ); | ||
38 | dict.insert("Priority" , new int(OTodo::Priority) ); | ||
39 | dict.insert("DateDay" , new int(OTodo::DateDay) ); | ||
40 | dict.insert("DateMonth" , new int(OTodo::DateMonth) ); | ||
41 | dict.insert("DateYear" , new int(OTodo::DateYear) ); | ||
42 | dict.insert("Progress" , new int(OTodo::Progress) ); | ||
43 | dict.insert("Completed", new int(OTodo::Completed) ); | ||
44 | dict.insert("CrossReference", new int(OTodo::CrossReference) ); | ||
45 | dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); | ||
46 | dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); | ||
47 | |||
48 | Opie::XMLElement *root = Opie::XMLElement::load( m_file ); | ||
49 | int day, year, month; | ||
50 | day = year = month = -1; | ||
51 | |||
52 | /* if opened */ | ||
53 | if ( root != 0l ) { | ||
54 | Opie::XMLElement *element = root->firstChild(); | ||
55 | if ( element == 0l ) | ||
56 | return false; | ||
57 | |||
58 | element = element->firstChild(); | ||
59 | |||
60 | while ( element ) { | ||
61 | if ( element->tagName() != QString::fromLatin1("Task") ) { | ||
62 | element = element->nextChild(); | ||
63 | continue; | ||
64 | } | ||
65 | /* here is the right element for a task */ | ||
66 | OTodo ev = todo( &dict, element ); | ||
67 | m_events.insert( ev.uid(), ev ); | ||
68 | |||
69 | element = element->nextChild(); | ||
70 | } | ||
71 | return true; | ||
72 | }else { | ||
73 | qWarning("could not parse"); | ||
74 | return false;; | ||
75 | } | ||
76 | delete root; | ||
77 | |||
78 | m_opened = true; | ||
79 | return true; | ||
80 | } | ||
81 | bool OTodoAccessXML::reload() { | ||
82 | return load(); | ||
83 | } | ||
84 | bool OTodoAccessXML::save() { | ||
85 | if (!m_opened || !m_changed ) | ||
86 | return true; | ||
87 | QString strNewFile = m_file + ".new"; | ||
88 | QFile f( strNewFile ); | ||
89 | if (!f.open( IO_WriteOnly|IO_Raw ) ) | ||
90 | return false; | ||
91 | |||
92 | int written; | ||
93 | QString out; | ||
94 | out = "<!DOCTYPE Tasks>\n<Tasks>\n"; | ||
95 | |||
96 | // for all todos | ||
97 | QMap<int, OTodo>::Iterator it; | ||
98 | for (it = m_events.begin(); it != m_events.end(); ++it ) { | ||
99 | out+= "<Task " + toString( (*it) ) + " />\n"; | ||
100 | QCString cstr = out.utf8(); | ||
101 | written = f.writeBlock( cstr.data(), cstr.length() ); | ||
102 | |||
103 | /* less written then we wanted */ | ||
104 | if ( written != (int)cstr.length() ) { | ||
105 | f.close(); | ||
106 | QFile::remove( strNewFile ); | ||
107 | return false; | ||
108 | } | ||
109 | out = QString::null; | ||
110 | } | ||
111 | |||
112 | out += "</Tasks>"; | ||
113 | QCString cstr = out.utf8(); | ||
114 | written = f.writeBlock( cstr.data(), cstr.length() ); | ||
115 | |||
116 | if ( written != (int)cstr.length() ) { | ||
117 | f.close(); | ||
118 | QFile::remove( strNewFile ); | ||
119 | return false; | ||
120 | } | ||
121 | /* flush before renaming */ | ||
122 | f.close(); | ||
123 | |||
124 | if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { | ||
125 | qWarning("error renaming"); | ||
126 | QFile::remove( strNewFile ); | ||
127 | } | ||
128 | |||
129 | m_changed = false; | ||
130 | return true; | ||
131 | } | ||
132 | QArray<int> OTodoAccessXML::allRecords()const { | ||
133 | QArray<int> ids( m_events.count() ); | ||
134 | QMap<int, OTodo>::ConstIterator it; | ||
135 | int i = 0; | ||
136 | |||
137 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | ||
138 | ids[i] = it.key(); | ||
139 | i++; | ||
140 | } | ||
141 | return ids; | ||
142 | } | ||
143 | QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int sort ) { | ||
144 | QArray<int> ids(0); | ||
145 | return ids; | ||
146 | } | ||
147 | OTodo OTodoAccessXML::find( int uid )const { | ||
148 | OTodo todo; | ||
149 | todo.setUid( 0 ); // isEmpty() | ||
150 | QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); | ||
151 | if ( it != m_events.end() ) | ||
152 | todo = it.data(); | ||
153 | |||
154 | return todo; | ||
155 | } | ||
156 | void OTodoAccessXML::clear() { | ||
157 | if (m_opened ) | ||
158 | m_changed = true; | ||
159 | |||
160 | m_events.clear(); | ||
161 | } | ||
162 | bool OTodoAccessXML::add( const OTodo& todo ) { | ||
163 | m_changed = true; | ||
164 | m_events.insert( todo.uid(), todo ); | ||
165 | |||
166 | return true; | ||
167 | } | ||
168 | bool OTodoAccessXML::remove( int uid ) { | ||
169 | m_changed = true; | ||
170 | m_events.remove( uid ); | ||
171 | |||
172 | return true; | ||
173 | } | ||
174 | bool OTodoAccessXML::replace( const OTodo& todo) { | ||
175 | m_changed = true; | ||
176 | m_events.replace( todo.uid(), todo ); | ||
177 | |||
178 | return true; | ||
179 | } | ||
180 | QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, | ||
181 | const QDate& end, | ||
182 | bool includeNoDates ) { | ||
183 | QArray<int> ids( m_events.count() ); | ||
184 | QMap<int, OTodo>::Iterator it; | ||
185 | |||
186 | int i = 0; | ||
187 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | ||
188 | if ( !it.data().hasDueDate() ) { | ||
189 | if ( includeNoDates ) { | ||
190 | ids[i] = it.key(); | ||
191 | i++; | ||
192 | } | ||
193 | }else if ( it.data().dueDate() >= start && | ||
194 | it.data().dueDate() <= end ) { | ||
195 | ids[i] = it.key(); | ||
196 | i++; | ||
197 | } | ||
198 | } | ||
199 | ids.resize( i ); | ||
200 | return ids; | ||
201 | } | ||
202 | QArray<int> OTodoAccessXML::overDue() { | ||
203 | QArray<int> ids( m_events.count() ); | ||
204 | int i = 0; | ||
205 | |||
206 | QMap<int, OTodo>::Iterator it; | ||
207 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | ||
208 | if ( it.data().isOverdue() ) { | ||
209 | ids[i] = it.key(); | ||
210 | i++; | ||
211 | } | ||
212 | } | ||
213 | ids.resize( i ); | ||
214 | return ids; | ||
215 | } | ||
216 | |||
217 | |||
218 | /* private */ | ||
219 | OTodo OTodoAccessXML::todo( QAsciiDict<int>* dict, Opie::XMLElement* element)const { | ||
220 | qWarning("parse to do from XMLElement" ); | ||
221 | OTodo ev; | ||
222 | QMap<QString, QString> attributes = element->attributes(); | ||
223 | QMap<QString, QString>::Iterator it; | ||
224 | |||
225 | int *find=0; | ||
226 | int day, month, year; | ||
227 | day = month = year = -1; | ||
228 | for ( it = attributes.begin(); it != attributes.end(); ++it ) { | ||
229 | find = (*dict)[ it.key() ]; | ||
230 | if (!find ) { | ||
231 | qWarning("Unknown option" + it.key() ); | ||
232 | ev.setCustomField( it.key(), it.data() ); | ||
233 | continue; | ||
234 | } | ||
235 | |||
236 | switch( *find ) { | ||
237 | case OTodo::Uid: | ||
238 | ev.setUid( it.data().toInt() ); | ||
239 | break; | ||
240 | case OTodo::Category: | ||
241 | ev.setCategories( ev.idsFromString( it.data() ) ); | ||
242 | break; | ||
243 | case OTodo::HasDate: | ||
244 | ev.setHasDueDate( it.data().toInt() ); | ||
245 | break; | ||
246 | case OTodo::Completed: | ||
247 | ev.setCompleted( it.data().toInt() ); | ||
248 | break; | ||
249 | case OTodo::Description: | ||
250 | ev.setDescription( it.data() ); | ||
251 | break; | ||
252 | case OTodo::Summary: | ||
253 | ev.setSummary( it.data() ); | ||
254 | break; | ||
255 | case OTodo::Priority: | ||
256 | ev.setPriority( it.data().toInt() ); | ||
257 | break; | ||
258 | case OTodo::DateDay: | ||
259 | day = it.data().toInt(); | ||
260 | break; | ||
261 | case OTodo::DateMonth: | ||
262 | month = it.data().toInt(); | ||
263 | break; | ||
264 | case OTodo::DateYear: | ||
265 | year = it.data().toInt(); | ||
266 | break; | ||
267 | case OTodo::Progress: | ||
268 | ev.setProgress( it.data().toInt() ); | ||
269 | break; | ||
270 | case OTodo::CrossReference: | ||
271 | { | ||
272 | /* | ||
273 | * A cross refernce looks like | ||
274 | * appname,id;appname,id | ||
275 | * we need to split it up | ||
276 | */ | ||
277 | QStringList refs = QStringList::split(';', it.data() ); | ||
278 | QStringList::Iterator strIt; | ||
279 | for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { | ||
280 | int pos = (*strIt).find(','); | ||
281 | if ( pos > -1 ) | ||
282 | ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); | ||
283 | |||
284 | } | ||
285 | break; | ||
286 | } | ||
287 | case OTodo::HasAlarmDateTime: | ||
288 | ev.setHasAlarmDateTime( it.data().toInt() ); | ||
289 | break; | ||
290 | case OTodo::AlarmDateTime: { | ||
291 | /* this sounds better ;) zecke */ | ||
292 | ev.setAlarmDateTime( TimeConversion::fromISO8601( it.data().local8Bit() ) ); | ||
293 | break; | ||
294 | } | ||
295 | default: | ||
296 | break; | ||
297 | } | ||
298 | } | ||
299 | if ( ev.hasDueDate() ) { | ||
300 | QDate date( year, month, day ); | ||
301 | ev.setDueDate( date ); | ||
302 | } | ||
303 | |||
304 | return ev; | ||
305 | } | ||
306 | QString OTodoAccessXML::toString( const OTodo& ev )const { | ||
307 | QString str; | ||
308 | |||
309 | str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; | ||
310 | str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; | ||
311 | str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; | ||
312 | str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; | ||
313 | |||
314 | str += "Categories=\"" + toString( ev.categories() ) + "\" "; | ||
315 | str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; | ||
316 | str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; | ||
317 | |||
318 | if ( ev.hasDueDate() ) { | ||
319 | str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; | ||
320 | str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; | ||
321 | str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; | ||
322 | } | ||
323 | str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; | ||
324 | |||
325 | // append the extra options | ||
326 | /* FIXME Qtopia::Record this is currently not | ||
327 | * possible you can set custom fields | ||
328 | * but don' iterate over the list | ||
329 | * I may do #define private protected | ||
330 | * for this case - cough --zecke | ||
331 | */ | ||
332 | /* | ||
333 | QMap<QString, QString> extras = ev.extras(); | ||
334 | QMap<QString, QString>::Iterator extIt; | ||
335 | for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) | ||
336 | str += extIt.key() + "=\"" + extIt.data() + "\" "; | ||
337 | */ | ||
338 | // cross refernce | ||
339 | QStringList list = ev.relatedApps(); | ||
340 | QStringList::Iterator listIt; | ||
341 | QString refs; | ||
342 | str += "CrossReference=\""; | ||
343 | bool added = false; | ||
344 | for ( listIt = list.begin(); listIt != list.end(); ++listIt ) { | ||
345 | added = true; | ||
346 | QArray<int> ints = ev.relations( (*listIt) ); | ||
347 | for ( uint i = 0; i< ints.count(); i++ ) { | ||
348 | str += (*listIt) + "," + QString::number( i ) + ";"; | ||
349 | } | ||
350 | } | ||
351 | if ( added ) | ||
352 | str = str.remove( str.length()-1, 1 ); | ||
353 | |||
354 | str += "\" "; | ||
355 | |||
356 | str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" "; | ||
357 | |||
358 | return str; | ||
359 | } | ||
360 | QString OTodoAccessXML::toString( const QArray<int>& ints ) const { | ||
361 | return Qtopia::Record::idsToString( ints ); | ||
362 | } | ||
diff --git a/libopie2/opiepim/backend/otodoaccessxml.h b/libopie2/opiepim/backend/otodoaccessxml.h new file mode 100644 index 0000000..be9109d --- a/dev/null +++ b/libopie2/opiepim/backend/otodoaccessxml.h | |||
@@ -0,0 +1,53 @@ | |||
1 | #ifndef OPIE_TODO_ACCESS_XML_H | ||
2 | #define OPIE_TODO_ACCESS_XML_H | ||
3 | |||
4 | #include <qasciidict.h> | ||
5 | #include <qmap.h> | ||
6 | |||
7 | #include "otodoaccessbackend.h" | ||
8 | |||
9 | namespace Opie { | ||
10 | class XMLElement; | ||
11 | }; | ||
12 | |||
13 | class OTodoAccessXML : public OTodoAccessBackend { | ||
14 | public: | ||
15 | /** | ||
16 | * fileName if Empty we will use the default path | ||
17 | */ | ||
18 | OTodoAccessXML( const QString& appName, | ||
19 | const QString& fileName = QString::null ); | ||
20 | ~OTodoAccessXML(); | ||
21 | |||
22 | bool load(); | ||
23 | bool reload(); | ||
24 | bool save(); | ||
25 | |||
26 | QArray<int> allRecords()const; | ||
27 | QArray<int> queryByExample( const OTodo&, int sort ); | ||
28 | OTodo find( int uid )const; | ||
29 | void clear(); | ||
30 | bool add( const OTodo& ); | ||
31 | bool remove( int uid ); | ||
32 | bool replace( const OTodo& ); | ||
33 | |||
34 | /* our functions */ | ||
35 | QArray<int> effectiveToDos( const QDate& start, | ||
36 | const QDate& end, | ||
37 | bool includeNoDates ); | ||
38 | QArray<int> overDue(); | ||
39 | private: | ||
40 | OTodo todo( QAsciiDict<int>*, Opie::XMLElement* )const; | ||
41 | QString toString( const OTodo& )const; | ||
42 | QString toString( const QArray<int>& ints ) const; | ||
43 | QMap<int, OTodo> m_events; | ||
44 | QString m_file; | ||
45 | QString m_app; | ||
46 | bool m_opened : 1; | ||
47 | bool m_changed : 1; | ||
48 | class OTodoAccessXMLPrivate; | ||
49 | OTodoAccessXMLPrivate* d; | ||
50 | |||
51 | }; | ||
52 | |||
53 | #endif | ||