summaryrefslogtreecommitdiff
authorerik <erik>2007-01-10 02:48:16 (UTC)
committer erik <erik>2007-01-10 02:48:16 (UTC)
commit3c4c894bcdb1e49ce4d3e8167c8a21b1c617037d (patch) (unidiff)
tree116c28349992668c69756a46fa90838889b21a6b
parent5e9659c695af1d1afb20a377775f1349b83eca53 (diff)
downloadopie-3c4c894bcdb1e49ce4d3e8167c8a21b1c617037d.zip
opie-3c4c894bcdb1e49ce4d3e8167c8a21b1c617037d.tar.gz
opie-3c4c894bcdb1e49ce4d3e8167c8a21b1c617037d.tar.bz2
BUG: The todo program was printing bad XML output of recurring items
because the code lacked a space between two entities. FIX: Add a space. NOTE: The code was additionally reworked to make the spaces more noticable to the author of the patch. Thanks goes to Paul Eggleton who provided the patch! This fixes Opie bug 1753: http://opie-bugs.oszine.de/view.php?id=1753
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp34
1 files changed, 17 insertions, 17 deletions
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp
index ab50604..7a08f12 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.cpp
+++ b/libopie2/opiepim/backend/otodoaccessxml.cpp
@@ -1,717 +1,717 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29 29
30/* OPIE */ 30/* OPIE */
31#include <opie2/opimdateconversion.h> 31#include <opie2/opimdateconversion.h>
32#include <opie2/opimstate.h> 32#include <opie2/opimstate.h>
33#include <opie2/opimtimezone.h> 33#include <opie2/opimtimezone.h>
34#include <opie2/opimnotifymanager.h> 34#include <opie2/opimnotifymanager.h>
35#include <opie2/opimrecurrence.h> 35#include <opie2/opimrecurrence.h>
36#include <opie2/otodoaccessxml.h> 36#include <opie2/otodoaccessxml.h>
37#include <opie2/otodoaccess.h> 37#include <opie2/otodoaccess.h>
38#include <opie2/odebug.h> 38#include <opie2/odebug.h>
39 39
40#include <opie2/private/opimtodosortvector.h> 40#include <opie2/private/opimtodosortvector.h>
41 41
42#include <qpe/global.h> 42#include <qpe/global.h>
43#include <qpe/stringutil.h> 43#include <qpe/stringutil.h>
44#include <qpe/timeconversion.h> 44#include <qpe/timeconversion.h>
45 45
46/* QT */ 46/* QT */
47#include <qfile.h> 47#include <qfile.h>
48#include <qvector.h> 48#include <qvector.h>
49 49
50/* STD */ 50/* STD */
51#include <errno.h> 51#include <errno.h>
52#include <fcntl.h> 52#include <fcntl.h>
53 53
54#include <sys/mman.h> 54#include <sys/mman.h>
55#include <sys/stat.h> 55#include <sys/stat.h>
56#include <sys/types.h> 56#include <sys/types.h>
57 57
58#include <unistd.h> 58#include <unistd.h>
59 59
60 60
61using namespace Opie; 61using namespace Opie;
62 62
63namespace { 63namespace {
64 time_t rp_end; 64 time_t rp_end;
65 OPimRecurrence* rec; 65 OPimRecurrence* rec;
66 OPimRecurrence *recur() { 66 OPimRecurrence *recur() {
67 if (!rec ) rec = new OPimRecurrence; 67 if (!rec ) rec = new OPimRecurrence;
68 return rec; 68 return rec;
69 } 69 }
70 int snd; 70 int snd;
71 enum MoreAttributes { 71 enum MoreAttributes {
72 FRType = OPimTodo::CompletedDate + 2, 72 FRType = OPimTodo::CompletedDate + 2,
73 FRWeekdays, 73 FRWeekdays,
74 FRPosition, 74 FRPosition,
75 FRFreq, 75 FRFreq,
76 FRHasEndDate, 76 FRHasEndDate,
77 FREndDate, 77 FREndDate,
78 FRStart, 78 FRStart,
79 FREnd 79 FREnd
80 }; 80 };
81 // FROM TT again 81 // FROM TT again
82char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) 82char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
83{ 83{
84 char needleChar; 84 char needleChar;
85 char haystackChar; 85 char haystackChar;
86 if (!needle || !haystack || !hLen || !nLen) 86 if (!needle || !haystack || !hLen || !nLen)
87 return 0; 87 return 0;
88 88
89 const char* hsearch = haystack; 89 const char* hsearch = haystack;
90 90
91 if ((needleChar = *needle++) != 0) { 91 if ((needleChar = *needle++) != 0) {
92 nLen--; //(to make up for needle++) 92 nLen--; //(to make up for needle++)
93 do { 93 do {
94 do { 94 do {
95 if ((haystackChar = *hsearch++) == 0) 95 if ((haystackChar = *hsearch++) == 0)
96 return (0); 96 return (0);
97 if (hsearch >= haystack + hLen) 97 if (hsearch >= haystack + hLen)
98 return (0); 98 return (0);
99 } while (haystackChar != needleChar); 99 } while (haystackChar != needleChar);
100 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); 100 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
101 hsearch--; 101 hsearch--;
102 } 102 }
103 return ((char *)hsearch); 103 return ((char *)hsearch);
104} 104}
105} 105}
106 106
107namespace Opie { 107namespace Opie {
108 108
109OPimTodoAccessXML::OPimTodoAccessXML( const QString& appName, 109OPimTodoAccessXML::OPimTodoAccessXML( const QString& appName,
110 const QString& fileName ) 110 const QString& fileName )
111 : OPimTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) 111 : OPimTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
112{ 112{
113 if (!fileName.isEmpty() ) 113 if (!fileName.isEmpty() )
114 m_file = fileName; 114 m_file = fileName;
115 else 115 else
116 m_file = Global::applicationFileName( "todolist", "todolist.xml" ); 116 m_file = Global::applicationFileName( "todolist", "todolist.xml" );
117} 117}
118OPimTodoAccessXML::~OPimTodoAccessXML() { 118OPimTodoAccessXML::~OPimTodoAccessXML() {
119 119
120} 120}
121bool OPimTodoAccessXML::load() { 121bool OPimTodoAccessXML::load() {
122 rec = 0; 122 rec = 0;
123 m_opened = true; 123 m_opened = true;
124 m_changed = false; 124 m_changed = false;
125 /* initialize dict */ 125 /* initialize dict */
126 /* 126 /*
127 * UPDATE dict if you change anything!!! 127 * UPDATE dict if you change anything!!!
128 */ 128 */
129 QAsciiDict<int> dict(26); 129 QAsciiDict<int> dict(26);
130 dict.setAutoDelete( TRUE ); 130 dict.setAutoDelete( TRUE );
131 dict.insert("Categories" , new int(OPimTodo::Category) ); 131 dict.insert("Categories" , new int(OPimTodo::Category) );
132 dict.insert("Uid" , new int(OPimTodo::Uid) ); 132 dict.insert("Uid" , new int(OPimTodo::Uid) );
133 dict.insert("HasDate" , new int(OPimTodo::HasDate) ); 133 dict.insert("HasDate" , new int(OPimTodo::HasDate) );
134 dict.insert("Completed" , new int(OPimTodo::Completed) ); 134 dict.insert("Completed" , new int(OPimTodo::Completed) );
135 dict.insert("Description" , new int(OPimTodo::Description) ); 135 dict.insert("Description" , new int(OPimTodo::Description) );
136 dict.insert("Summary" , new int(OPimTodo::Summary) ); 136 dict.insert("Summary" , new int(OPimTodo::Summary) );
137 dict.insert("Priority" , new int(OPimTodo::Priority) ); 137 dict.insert("Priority" , new int(OPimTodo::Priority) );
138 dict.insert("DateDay" , new int(OPimTodo::DateDay) ); 138 dict.insert("DateDay" , new int(OPimTodo::DateDay) );
139 dict.insert("DateMonth" , new int(OPimTodo::DateMonth) ); 139 dict.insert("DateMonth" , new int(OPimTodo::DateMonth) );
140 dict.insert("DateYear" , new int(OPimTodo::DateYear) ); 140 dict.insert("DateYear" , new int(OPimTodo::DateYear) );
141 dict.insert("Progress" , new int(OPimTodo::Progress) ); 141 dict.insert("Progress" , new int(OPimTodo::Progress) );
142 dict.insert("CompletedDate", new int(OPimTodo::CompletedDate) ); 142 dict.insert("CompletedDate", new int(OPimTodo::CompletedDate) );
143 dict.insert("StartDate", new int(OPimTodo::StartDate) ); 143 dict.insert("StartDate", new int(OPimTodo::StartDate) );
144 dict.insert("CrossReference", new int(OPimTodo::CrossReference) ); 144 dict.insert("CrossReference", new int(OPimTodo::CrossReference) );
145 dict.insert("State", new int(OPimTodo::State) ); 145 dict.insert("State", new int(OPimTodo::State) );
146 dict.insert("Alarms", new int(OPimTodo::Alarms) ); 146 dict.insert("Alarms", new int(OPimTodo::Alarms) );
147 dict.insert("Reminders", new int(OPimTodo::Reminders) ); 147 dict.insert("Reminders", new int(OPimTodo::Reminders) );
148 dict.insert("Maintainer", new int(OPimTodo::Maintainer) ); 148 dict.insert("Maintainer", new int(OPimTodo::Maintainer) );
149 dict.insert("rtype", new int(FRType) ); 149 dict.insert("rtype", new int(FRType) );
150 dict.insert("rweekdays", new int(FRWeekdays) ); 150 dict.insert("rweekdays", new int(FRWeekdays) );
151 dict.insert("rposition", new int(FRPosition) ); 151 dict.insert("rposition", new int(FRPosition) );
152 dict.insert("rfreq", new int(FRFreq) ); 152 dict.insert("rfreq", new int(FRFreq) );
153 dict.insert("start", new int(FRStart) ); 153 dict.insert("start", new int(FRStart) );
154 dict.insert("rhasenddate", new int(FRHasEndDate) ); 154 dict.insert("rhasenddate", new int(FRHasEndDate) );
155 dict.insert("enddt", new int(FREndDate) ); 155 dict.insert("enddt", new int(FREndDate) );
156 156
157 // here the custom XML parser from TT it's GPL 157 // here the custom XML parser from TT it's GPL
158 // but we want to push OpiePIM... to TT..... 158 // but we want to push OpiePIM... to TT.....
159 // mmap part from zecke :) 159 // mmap part from zecke :)
160 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); 160 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
161 struct stat attribut; 161 struct stat attribut;
162 if ( fd < 0 ) return false; 162 if ( fd < 0 ) return false;
163 163
164 if ( fstat(fd, &attribut ) == -1 ) { 164 if ( fstat(fd, &attribut ) == -1 ) {
165 ::close( fd ); 165 ::close( fd );
166 return false; 166 return false;
167 } 167 }
168 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 168 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
169 if ( map_addr == ( (caddr_t)-1) ) { 169 if ( map_addr == ( (caddr_t)-1) ) {
170 ::close(fd ); 170 ::close(fd );
171 return false; 171 return false;
172 } 172 }
173 /* advise the kernel who we want to read it */ 173 /* advise the kernel who we want to read it */
174 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); 174 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
175 /* we do not the file any more */ 175 /* we do not the file any more */
176 ::close( fd ); 176 ::close( fd );
177 177
178 char* dt = (char*)map_addr; 178 char* dt = (char*)map_addr;
179 int len = attribut.st_size; 179 int len = attribut.st_size;
180 int i = 0; 180 int i = 0;
181 char *point; 181 char *point;
182 const char* collectionString = "<Task "; 182 const char* collectionString = "<Task ";
183 int strLen = strlen(collectionString); 183 int strLen = strlen(collectionString);
184 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { 184 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) {
185 i = point -dt; 185 i = point -dt;
186 i+= strLen; 186 i+= strLen;
187 187
188 OPimTodo ev; 188 OPimTodo ev;
189 m_year = m_month = m_day = 0; 189 m_year = m_month = m_day = 0;
190 190
191 while ( TRUE ) { 191 while ( TRUE ) {
192 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 192 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
193 ++i; 193 ++i;
194 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 194 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
195 break; 195 break;
196 196
197 // we have another attribute, read it. 197 // we have another attribute, read it.
198 int j = i; 198 int j = i;
199 while ( j < len && dt[j] != '=' ) 199 while ( j < len && dt[j] != '=' )
200 ++j; 200 ++j;
201 QCString attr( dt+i, j-i+1); 201 QCString attr( dt+i, j-i+1);
202 202
203 i = ++j; // skip = 203 i = ++j; // skip =
204 204
205 // find the start of quotes 205 // find the start of quotes
206 while ( i < len && dt[i] != '"' ) 206 while ( i < len && dt[i] != '"' )
207 ++i; 207 ++i;
208 j = ++i; 208 j = ++i;
209 209
210 bool haveUtf = FALSE; 210 bool haveUtf = FALSE;
211 bool haveEnt = FALSE; 211 bool haveEnt = FALSE;
212 while ( j < len && dt[j] != '"' ) { 212 while ( j < len && dt[j] != '"' ) {
213 if ( ((unsigned char)dt[j]) > 0x7f ) 213 if ( ((unsigned char)dt[j]) > 0x7f )
214 haveUtf = TRUE; 214 haveUtf = TRUE;
215 if ( dt[j] == '&' ) 215 if ( dt[j] == '&' )
216 haveEnt = TRUE; 216 haveEnt = TRUE;
217 ++j; 217 ++j;
218 } 218 }
219 if ( i == j ) { 219 if ( i == j ) {
220 // empty value 220 // empty value
221 i = j + 1; 221 i = j + 1;
222 continue; 222 continue;
223 } 223 }
224 224
225 QCString value( dt+i, j-i+1 ); 225 QCString value( dt+i, j-i+1 );
226 i = j + 1; 226 i = j + 1;
227 227
228 QString str = (haveUtf ? QString::fromUtf8( value ) 228 QString str = (haveUtf ? QString::fromUtf8( value )
229 : QString::fromLatin1( value ) ); 229 : QString::fromLatin1( value ) );
230 if ( haveEnt ) 230 if ( haveEnt )
231 str = Qtopia::plainString( str ); 231 str = Qtopia::plainString( str );
232 232
233 /* 233 /*
234 * add key + value 234 * add key + value
235 */ 235 */
236 todo( &dict, ev, attr, str ); 236 todo( &dict, ev, attr, str );
237 237
238 } 238 }
239 /* 239 /*
240 * now add it 240 * now add it
241 */ 241 */
242 if (m_events.contains( ev.uid() ) || ev.uid() == 0) { 242 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
243 ev.setUid( 1 ); 243 ev.setUid( 1 );
244 m_changed = true; 244 m_changed = true;
245 } 245 }
246 if ( ev.hasDueDate() ) { 246 if ( ev.hasDueDate() ) {
247 ev.setDueDate( QDate(m_year, m_month, m_day) ); 247 ev.setDueDate( QDate(m_year, m_month, m_day) );
248 } 248 }
249 if ( rec && rec->doesRecur() ) { 249 if ( rec && rec->doesRecur() ) {
250 OPimTimeZone utc = OPimTimeZone::utc(); 250 OPimTimeZone utc = OPimTimeZone::utc();
251 OPimRecurrence recu( *rec ); // call copy c'tor 251 OPimRecurrence recu( *rec ); // call copy c'tor
252 recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() ); 252 recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() );
253 recu.setStart( ev.dueDate() ); 253 recu.setStart( ev.dueDate() );
254 ev.setRecurrence( recu ); 254 ev.setRecurrence( recu );
255 } 255 }
256 m_events.insert(ev.uid(), ev ); 256 m_events.insert(ev.uid(), ev );
257 m_year = m_month = m_day = -1; 257 m_year = m_month = m_day = -1;
258 delete rec; 258 delete rec;
259 rec = 0; 259 rec = 0;
260 } 260 }
261 261
262 munmap(map_addr, attribut.st_size ); 262 munmap(map_addr, attribut.st_size );
263 263
264 return true; 264 return true;
265} 265}
266bool OPimTodoAccessXML::reload() { 266bool OPimTodoAccessXML::reload() {
267 m_events.clear(); 267 m_events.clear();
268 return load(); 268 return load();
269} 269}
270bool OPimTodoAccessXML::save() { 270bool OPimTodoAccessXML::save() {
271 if (!m_opened || !m_changed ) { 271 if (!m_opened || !m_changed ) {
272 return true; 272 return true;
273 } 273 }
274 QString strNewFile = m_file + ".new"; 274 QString strNewFile = m_file + ".new";
275 QFile f( strNewFile ); 275 QFile f( strNewFile );
276 if (!f.open( IO_WriteOnly|IO_Raw ) ) 276 if (!f.open( IO_WriteOnly|IO_Raw ) )
277 return false; 277 return false;
278 278
279 int written; 279 int written;
280 QString out; 280 QString out;
281 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 281 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
282 282
283 // for all todos 283 // for all todos
284 QMap<int, OPimTodo>::Iterator it; 284 QMap<int, OPimTodo>::Iterator it;
285 for (it = m_events.begin(); it != m_events.end(); ++it ) { 285 for (it = m_events.begin(); it != m_events.end(); ++it ) {
286 out+= "<Task " + toString( (*it) ) + " />\n"; 286 out+= "<Task " + toString( (*it) ) + " />\n";
287 QCString cstr = out.utf8(); 287 QCString cstr = out.utf8();
288 written = f.writeBlock( cstr.data(), cstr.length() ); 288 written = f.writeBlock( cstr.data(), cstr.length() );
289 289
290 /* less written then we wanted */ 290 /* less written then we wanted */
291 if ( written != (int)cstr.length() ) { 291 if ( written != (int)cstr.length() ) {
292 f.close(); 292 f.close();
293 QFile::remove( strNewFile ); 293 QFile::remove( strNewFile );
294 return false; 294 return false;
295 } 295 }
296 out = QString::null; 296 out = QString::null;
297 } 297 }
298 298
299 out += "</Tasks>"; 299 out += "</Tasks>";
300 QCString cstr = out.utf8(); 300 QCString cstr = out.utf8();
301 written = f.writeBlock( cstr.data(), cstr.length() ); 301 written = f.writeBlock( cstr.data(), cstr.length() );
302 302
303 if ( written != (int)cstr.length() ) { 303 if ( written != (int)cstr.length() ) {
304 f.close(); 304 f.close();
305 QFile::remove( strNewFile ); 305 QFile::remove( strNewFile );
306 return false; 306 return false;
307 } 307 }
308 /* flush before renaming */ 308 /* flush before renaming */
309 f.close(); 309 f.close();
310 310
311 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 311 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
312 QFile::remove( strNewFile ); 312 QFile::remove( strNewFile );
313 } 313 }
314 314
315 m_changed = false; 315 m_changed = false;
316 return true; 316 return true;
317} 317}
318QArray<int> OPimTodoAccessXML::allRecords()const { 318QArray<int> OPimTodoAccessXML::allRecords()const {
319 QArray<int> ids( m_events.count() ); 319 QArray<int> ids( m_events.count() );
320 QMap<int, OPimTodo>::ConstIterator it; 320 QMap<int, OPimTodo>::ConstIterator it;
321 int i = 0; 321 int i = 0;
322 322
323 for ( it = m_events.begin(); it != m_events.end(); ++it ) 323 for ( it = m_events.begin(); it != m_events.end(); ++it )
324 ids[i++] = it.key(); 324 ids[i++] = it.key();
325 325
326 326
327 return ids; 327 return ids;
328} 328}
329 329
330OPimTodo OPimTodoAccessXML::find( int uid )const { 330OPimTodo OPimTodoAccessXML::find( int uid )const {
331 OPimTodo todo; 331 OPimTodo todo;
332 todo.setUid( 0 ); // isEmpty() 332 todo.setUid( 0 ); // isEmpty()
333 QMap<int, OPimTodo>::ConstIterator it = m_events.find( uid ); 333 QMap<int, OPimTodo>::ConstIterator it = m_events.find( uid );
334 if ( it != m_events.end() ) 334 if ( it != m_events.end() )
335 todo = it.data(); 335 todo = it.data();
336 336
337 return todo; 337 return todo;
338} 338}
339void OPimTodoAccessXML::clear() { 339void OPimTodoAccessXML::clear() {
340 if (m_opened ) 340 if (m_opened )
341 m_changed = true; 341 m_changed = true;
342 342
343 m_events.clear(); 343 m_events.clear();
344} 344}
345bool OPimTodoAccessXML::add( const OPimTodo& todo ) { 345bool OPimTodoAccessXML::add( const OPimTodo& todo ) {
346 m_changed = true; 346 m_changed = true;
347 m_events.insert( todo.uid(), todo ); 347 m_events.insert( todo.uid(), todo );
348 348
349 return true; 349 return true;
350} 350}
351bool OPimTodoAccessXML::remove( int uid ) { 351bool OPimTodoAccessXML::remove( int uid ) {
352 m_changed = true; 352 m_changed = true;
353 m_events.remove( uid ); 353 m_events.remove( uid );
354 354
355 return true; 355 return true;
356} 356}
357bool OPimTodoAccessXML::replace( const OPimTodo& todo) { 357bool OPimTodoAccessXML::replace( const OPimTodo& todo) {
358 m_changed = true; 358 m_changed = true;
359 m_events.replace( todo.uid(), todo ); 359 m_events.replace( todo.uid(), todo );
360 360
361 return true; 361 return true;
362} 362}
363QArray<int> OPimTodoAccessXML::effectiveToDos( const QDate& start, 363QArray<int> OPimTodoAccessXML::effectiveToDos( const QDate& start,
364 const QDate& end, 364 const QDate& end,
365 bool includeNoDates )const { 365 bool includeNoDates )const {
366 QArray<int> ids( m_events.count() ); 366 QArray<int> ids( m_events.count() );
367 QMap<int, OPimTodo>::ConstIterator it; 367 QMap<int, OPimTodo>::ConstIterator it;
368 368
369 int i = 0; 369 int i = 0;
370 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 370 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
371 if ( !it.data().hasDueDate() && includeNoDates) { 371 if ( !it.data().hasDueDate() && includeNoDates) {
372 ids[i++] = it.key(); 372 ids[i++] = it.key();
373 }else if ( it.data().dueDate() >= start && 373 }else if ( it.data().dueDate() >= start &&
374 it.data().dueDate() <= end ) { 374 it.data().dueDate() <= end ) {
375 ids[i++] = it.key(); 375 ids[i++] = it.key();
376 } 376 }
377 } 377 }
378 ids.resize( i ); 378 ids.resize( i );
379 return ids; 379 return ids;
380} 380}
381QArray<int> OPimTodoAccessXML::overDue()const { 381QArray<int> OPimTodoAccessXML::overDue()const {
382 QArray<int> ids( m_events.count() ); 382 QArray<int> ids( m_events.count() );
383 int i = 0; 383 int i = 0;
384 384
385 QMap<int, OPimTodo>::ConstIterator it; 385 QMap<int, OPimTodo>::ConstIterator it;
386 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 386 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
387 if ( it.data().isOverdue() ) { 387 if ( it.data().isOverdue() ) {
388 ids[i] = it.key(); 388 ids[i] = it.key();
389 i++; 389 i++;
390 } 390 }
391 } 391 }
392 ids.resize( i ); 392 ids.resize( i );
393 return ids; 393 return ids;
394} 394}
395 395
396 396
397/* private */ 397/* private */
398void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev, 398void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev,
399 const QCString& attr, const QString& val) { 399 const QCString& attr, const QString& val) {
400 400
401 int *find=0; 401 int *find=0;
402 402
403 find = (*dict)[ attr.data() ]; 403 find = (*dict)[ attr.data() ];
404 if (!find ) { 404 if (!find ) {
405 ev.setCustomField( attr, val ); 405 ev.setCustomField( attr, val );
406 return; 406 return;
407 } 407 }
408 408
409 switch( *find ) { 409 switch( *find ) {
410 case OPimTodo::Uid: 410 case OPimTodo::Uid:
411 ev.setUid( val.toInt() ); 411 ev.setUid( val.toInt() );
412 break; 412 break;
413 case OPimTodo::Category: 413 case OPimTodo::Category:
414 ev.setCategories( ev.idsFromString( val ) ); 414 ev.setCategories( ev.idsFromString( val ) );
415 break; 415 break;
416 case OPimTodo::HasDate: 416 case OPimTodo::HasDate:
417 ev.setHasDueDate( val.toInt() ); 417 ev.setHasDueDate( val.toInt() );
418 break; 418 break;
419 case OPimTodo::Completed: 419 case OPimTodo::Completed:
420 ev.setCompleted( val.toInt() ); 420 ev.setCompleted( val.toInt() );
421 break; 421 break;
422 case OPimTodo::Description: 422 case OPimTodo::Description:
423 ev.setDescription( val ); 423 ev.setDescription( val );
424 break; 424 break;
425 case OPimTodo::Summary: 425 case OPimTodo::Summary:
426 ev.setSummary( val ); 426 ev.setSummary( val );
427 break; 427 break;
428 case OPimTodo::Priority: 428 case OPimTodo::Priority:
429 ev.setPriority( val.toInt() ); 429 ev.setPriority( val.toInt() );
430 break; 430 break;
431 case OPimTodo::DateDay: 431 case OPimTodo::DateDay:
432 m_day = val.toInt(); 432 m_day = val.toInt();
433 break; 433 break;
434 case OPimTodo::DateMonth: 434 case OPimTodo::DateMonth:
435 m_month = val.toInt(); 435 m_month = val.toInt();
436 break; 436 break;
437 case OPimTodo::DateYear: 437 case OPimTodo::DateYear:
438 m_year = val.toInt(); 438 m_year = val.toInt();
439 break; 439 break;
440 case OPimTodo::Progress: 440 case OPimTodo::Progress:
441 ev.setProgress( val.toInt() ); 441 ev.setProgress( val.toInt() );
442 break; 442 break;
443 case OPimTodo::CompletedDate: 443 case OPimTodo::CompletedDate:
444 ev.setCompletedDate( OPimDateConversion::dateFromString( val ) ); 444 ev.setCompletedDate( OPimDateConversion::dateFromString( val ) );
445 break; 445 break;
446 case OPimTodo::StartDate: 446 case OPimTodo::StartDate:
447 ev.setStartDate( OPimDateConversion::dateFromString( val ) ); 447 ev.setStartDate( OPimDateConversion::dateFromString( val ) );
448 break; 448 break;
449 case OPimTodo::State: 449 case OPimTodo::State:
450 ev.setState( val.toInt() ); 450 ev.setState( val.toInt() );
451 break; 451 break;
452 case OPimTodo::Alarms:{ 452 case OPimTodo::Alarms:{
453 OPimNotifyManager &manager = ev.notifiers(); 453 OPimNotifyManager &manager = ev.notifiers();
454 QStringList als = QStringList::split(";", val ); 454 QStringList als = QStringList::split(";", val );
455 for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) { 455 for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) {
456 QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty 456 QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty
457 OPimAlarm al( alarm[2].toInt(), OPimDateConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() ); 457 OPimAlarm al( alarm[2].toInt(), OPimDateConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() );
458 manager.add( al ); 458 manager.add( al );
459 } 459 }
460 } 460 }
461 break; 461 break;
462 case OPimTodo::Reminders:{ 462 case OPimTodo::Reminders:{
463 OPimNotifyManager &manager = ev.notifiers(); 463 OPimNotifyManager &manager = ev.notifiers();
464 QStringList rems = QStringList::split(";", val ); 464 QStringList rems = QStringList::split(";", val );
465 for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) { 465 for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) {
466 OPimReminder rem( (*it).toInt() ); 466 OPimReminder rem( (*it).toInt() );
467 manager.add( rem ); 467 manager.add( rem );
468 } 468 }
469 } 469 }
470 break; 470 break;
471 case OPimTodo::CrossReference: 471 case OPimTodo::CrossReference:
472 { 472 {
473 /* 473 /*
474 * A cross refernce looks like 474 * A cross refernce looks like
475 * appname,id;appname,id 475 * appname,id;appname,id
476 * we need to split it up 476 * we need to split it up
477 */ 477 */
478 QStringList refs = QStringList::split(';', val ); 478 QStringList refs = QStringList::split(';', val );
479 QStringList::Iterator strIt; 479 QStringList::Iterator strIt;
480 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 480 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
481 int pos = (*strIt).find(','); 481 int pos = (*strIt).find(',');
482 if ( pos > -1 ) 482 if ( pos > -1 )
483 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 483 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
484 484
485 } 485 }
486 break; 486 break;
487 } 487 }
488 /* Recurrence stuff below + post processing later */ 488 /* Recurrence stuff below + post processing later */
489 case FRType: 489 case FRType:
490 if ( val == "Daily" ) 490 if ( val == "Daily" )
491 recur()->setType( OPimRecurrence::Daily ); 491 recur()->setType( OPimRecurrence::Daily );
492 else if ( val == "Weekly" ) 492 else if ( val == "Weekly" )
493 recur()->setType( OPimRecurrence::Weekly); 493 recur()->setType( OPimRecurrence::Weekly);
494 else if ( val == "MonthlyDay" ) 494 else if ( val == "MonthlyDay" )
495 recur()->setType( OPimRecurrence::MonthlyDay ); 495 recur()->setType( OPimRecurrence::MonthlyDay );
496 else if ( val == "MonthlyDate" ) 496 else if ( val == "MonthlyDate" )
497 recur()->setType( OPimRecurrence::MonthlyDate ); 497 recur()->setType( OPimRecurrence::MonthlyDate );
498 else if ( val == "Yearly" ) 498 else if ( val == "Yearly" )
499 recur()->setType( OPimRecurrence::Yearly ); 499 recur()->setType( OPimRecurrence::Yearly );
500 else 500 else
501 recur()->setType( OPimRecurrence::NoRepeat ); 501 recur()->setType( OPimRecurrence::NoRepeat );
502 break; 502 break;
503 case FRWeekdays: 503 case FRWeekdays:
504 recur()->setDays( val.toInt() ); 504 recur()->setDays( val.toInt() );
505 break; 505 break;
506 case FRPosition: 506 case FRPosition:
507 recur()->setPosition( val.toInt() ); 507 recur()->setPosition( val.toInt() );
508 break; 508 break;
509 case FRFreq: 509 case FRFreq:
510 recur()->setFrequency( val.toInt() ); 510 recur()->setFrequency( val.toInt() );
511 break; 511 break;
512 case FRHasEndDate: 512 case FRHasEndDate:
513 recur()->setHasEndDate( val.toInt() ); 513 recur()->setHasEndDate( val.toInt() );
514 break; 514 break;
515 case FREndDate: { 515 case FREndDate: {
516 rp_end = (time_t) val.toLong(); 516 rp_end = (time_t) val.toLong();
517 break; 517 break;
518 } 518 }
519 default: 519 default:
520 ev.setCustomField( attr, val ); 520 ev.setCustomField( attr, val );
521 break; 521 break;
522 } 522 }
523} 523}
524 524
525// from PalmtopRecord... GPL ### FIXME 525// from PalmtopRecord... GPL ### FIXME
526namespace { 526namespace {
527QString customToXml(const QMap<QString, QString>& customMap ) 527QString customToXml(const QMap<QString, QString>& customMap )
528{ 528{
529 QString buf(" "); 529 QString buf(" ");
530 for ( QMap<QString, QString>::ConstIterator cit = customMap.begin(); 530 for ( QMap<QString, QString>::ConstIterator cit = customMap.begin();
531 cit != customMap.end(); ++cit) { 531 cit != customMap.end(); ++cit) {
532 buf += cit.key(); 532 buf += cit.key();
533 buf += "=\""; 533 buf += "=\"";
534 buf += Qtopia::escapeString(cit.data()); 534 buf += Qtopia::escapeString(cit.data());
535 buf += "\" "; 535 buf += "\" ";
536 } 536 }
537 return buf; 537 return buf;
538} 538}
539 539
540 540
541} 541}
542 542
543QString OPimTodoAccessXML::toString( const OPimTodo& ev )const { 543QString OPimTodoAccessXML::toString( const OPimTodo& ev )const {
544 QString str; 544 QString str;
545 545
546 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 546 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\"";
547 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 547 str += " HasDate=\"" + QString::number( ev.hasDueDate() ) + "\"";
548 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 548 str += " Priority=\"" + QString::number( ev.priority() ) + "\"";
549 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 549 str += " Progress=\"" + QString::number(ev.progress() ) + "\"";
550 550
551 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 551 str += " Categories=\"" + toString( ev.categories() ) + "\"";
552 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 552 str += " Description=\"" + Qtopia::escapeString( ev.description() ) + "\"";
553 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 553 str += " Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\"";
554 554
555 if ( ev.hasDueDate() ) { 555 if ( ev.hasDueDate() ) {
556 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 556 str += " DateYear=\"" + QString::number( ev.dueDate().year() ) + "\"";
557 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 557 str += " DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\"";
558 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 558 str += " DateDay=\"" + QString::number( ev.dueDate().day() ) + "\"";
559 } 559 }
560 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 560 str += " Uid=\"" + QString::number( ev.uid() ) + "\"";
561 561
562// append the extra options 562// append the extra options
563 /* FIXME Qtopia::Record this is currently not 563 /* FIXME Qtopia::Record this is currently not
564 * possible you can set custom fields 564 * possible you can set custom fields
565 * but don' iterate over the list 565 * but don' iterate over the list
566 * I may do #define private protected 566 * I may do #define private protected
567 * for this case - cough --zecke 567 * for this case - cough --zecke
568 */ 568 */
569 /* 569 /*
570 QMap<QString, QString> extras = ev.extras(); 570 QMap<QString, QString> extras = ev.extras();
571 QMap<QString, QString>::Iterator extIt; 571 QMap<QString, QString>::Iterator extIt;
572 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 572 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
573 str += extIt.key() + "=\"" + extIt.data() + "\" "; 573 str += " " + extIt.key() + "=\"" + extIt.data() + "\"";
574 */ 574 */
575 // cross refernce 575 // cross refernce
576 if ( ev.hasRecurrence() ) { 576 if ( ev.hasRecurrence() ) {
577 str += ev.recurrence().toString(); 577 str += ev.recurrence().toString();
578 } 578 }
579 if ( ev.hasStartDate() ) 579 if ( ev.hasStartDate() )
580 str += "StartDate=\""+ OPimDateConversion::dateToString( ev.startDate() ) +"\" "; 580 str += " StartDate=\""+ OPimDateConversion::dateToString( ev.startDate() ) +"\"";
581 if ( ev.hasCompletedDate() ) 581 if ( ev.hasCompletedDate() )
582 str += "CompletedDate=\""+ OPimDateConversion::dateToString( ev.completedDate() ) +"\" "; 582 str += " CompletedDate=\""+ OPimDateConversion::dateToString( ev.completedDate() ) +"\"";
583 if ( ev.hasState() ) 583 if ( ev.hasState() )
584 str += "State=\""+QString::number( ev.state().state() )+"\" "; 584 str += " State=\""+QString::number( ev.state().state() )+"\"";
585 585
586 /* 586 /*
587 * save reminders and notifiers! 587 * save reminders and notifiers!
588 * DATE_TIME:DURATION:SOUND:NOT_USED_YET;OTHER_DATE_TIME:OTHER_DURATION:SOUND:.... 588 * DATE_TIME:DURATION:SOUND:NOT_USED_YET;OTHER_DATE_TIME:OTHER_DURATION:SOUND:....
589 */ 589 */
590 if ( ev.hasNotifiers() ) { 590 if ( ev.hasNotifiers() ) {
591 OPimNotifyManager manager = ev.notifiers(); 591 OPimNotifyManager manager = ev.notifiers();
592 OPimNotifyManager::Alarms alarms = manager.alarms(); 592 OPimNotifyManager::Alarms alarms = manager.alarms();
593 if (!alarms.isEmpty() ) { 593 if (!alarms.isEmpty() ) {
594 QStringList als; 594 QStringList als;
595 OPimNotifyManager::Alarms::Iterator it = alarms.begin(); 595 OPimNotifyManager::Alarms::Iterator it = alarms.begin();
596 for ( ; it != alarms.end(); ++it ) { 596 for ( ; it != alarms.end(); ++it ) {
597 /* only if time is valid */ 597 /* only if time is valid */
598 if ( (*it).dateTime().isValid() ) { 598 if ( (*it).dateTime().isValid() ) {
599 als << OPimDateConversion::dateTimeToString( (*it).dateTime() ) 599 als << OPimDateConversion::dateTimeToString( (*it).dateTime() )
600 + ":" + QString::number( (*it).duration() ) 600 + ":" + QString::number( (*it).duration() )
601 + ":" + QString::number( (*it).sound() ) 601 + ":" + QString::number( (*it).sound() )
602 + ":"; 602 + ":";
603 } 603 }
604 } 604 }
605 // now write the list 605 // now write the list
606 str += "Alarms=\""+als.join(";") +"\" "; 606 str += " Alarms=\""+als.join(";") +"\"";
607 } 607 }
608 608
609 /* 609 /*
610 * now the same for reminders but more easy. We just save the uid of the OPimEvent. 610 * now the same for reminders but more easy. We just save the uid of the OPimEvent.
611 */ 611 */
612 OPimNotifyManager::Reminders reminders = manager.reminders(); 612 OPimNotifyManager::Reminders reminders = manager.reminders();
613 if (!reminders.isEmpty() ) { 613 if (!reminders.isEmpty() ) {
614 OPimNotifyManager::Reminders::Iterator it = reminders.begin(); 614 OPimNotifyManager::Reminders::Iterator it = reminders.begin();
615 QStringList records; 615 QStringList records;
616 for ( ; it != reminders.end(); ++it ) { 616 for ( ; it != reminders.end(); ++it ) {
617 records << QString::number( (*it).recordUid() ); 617 records << QString::number( (*it).recordUid() );
618 } 618 }
619 str += "Reminders=\""+ records.join(";") +"\" "; 619 str += " Reminders=\""+ records.join(";") +"\"";
620 } 620 }
621 } 621 }
622 str += customToXml( ev.toExtraMap() ); 622 str += customToXml( ev.toExtraMap() );
623 623
624 624
625 return str; 625 return str;
626} 626}
627QString OPimTodoAccessXML::toString( const QArray<int>& ints ) const { 627QString OPimTodoAccessXML::toString( const QArray<int>& ints ) const {
628 return Qtopia::Record::idsToString( ints ); 628 return Qtopia::Record::idsToString( ints );
629} 629}
630 630
631 631
632QArray<int> OPimTodoAccessXML::sorted( const UIDArray& events, bool asc, 632QArray<int> OPimTodoAccessXML::sorted( const UIDArray& events, bool asc,
633 int sortOrder,int sortFilter, 633 int sortOrder,int sortFilter,
634 const QArray<int>& categories )const { 634 const QArray<int>& categories )const {
635 Internal::OPimTodoSortVector vector(events.count(), asc,sortOrder ); 635 Internal::OPimTodoSortVector vector(events.count(), asc,sortOrder );
636 int item = 0; 636 int item = 0;
637 637
638 bool bCat = sortFilter & OPimTodoAccess::FilterCategory ? true : false; 638 bool bCat = sortFilter & OPimTodoAccess::FilterCategory ? true : false;
639 bool bOnly = sortFilter & OPimTodoAccess::OnlyOverDue ? true : false; 639 bool bOnly = sortFilter & OPimTodoAccess::OnlyOverDue ? true : false;
640 bool comp = sortFilter & OPimTodoAccess::DoNotShowCompleted ? true : false; 640 bool comp = sortFilter & OPimTodoAccess::DoNotShowCompleted ? true : false;
641 bool catPassed = false; 641 bool catPassed = false;
642 int cat; 642 int cat;
643 643
644 for ( uint i = 0; i < events.count(); ++i ) { 644 for ( uint i = 0; i < events.count(); ++i ) {
645 /* Guard against creating a new item... */ 645 /* Guard against creating a new item... */
646 if ( !m_events.contains( events[i] ) ) 646 if ( !m_events.contains( events[i] ) )
647 continue; 647 continue;
648 648
649 OPimTodo todo = m_events[events[i]]; 649 OPimTodo todo = m_events[events[i]];
650 650
651 /* show category */ 651 /* show category */
652 /* -1 == unfiled */ 652 /* -1 == unfiled */
653 catPassed = false; 653 catPassed = false;
654 for ( uint cat_nu = 0; cat_nu < categories.count(); ++cat_nu ) { 654 for ( uint cat_nu = 0; cat_nu < categories.count(); ++cat_nu ) {
655 cat = categories[cat_nu]; 655 cat = categories[cat_nu];
656 if ( bCat && cat == -1 ) { 656 if ( bCat && cat == -1 ) {
657 if(!todo.categories().isEmpty() ) 657 if(!todo.categories().isEmpty() )
658 continue; 658 continue;
659 } else if ( bCat && cat != 0) 659 } else if ( bCat && cat != 0)
660 if (!todo.categories().contains( cat ) ) 660 if (!todo.categories().contains( cat ) )
661 continue; 661 continue;
662 catPassed = true; 662 catPassed = true;
663 break; 663 break;
664 } 664 }
665 665
666 /* 666 /*
667 * If none of the Categories matched 667 * If none of the Categories matched
668 * continue 668 * continue
669 */ 669 */
670 if ( !catPassed ) 670 if ( !catPassed )
671 continue; 671 continue;
672 if ( !todo.isOverdue() && bOnly ) 672 if ( !todo.isOverdue() && bOnly )
673 continue; 673 continue;
674 if (todo.isCompleted() && comp ) 674 if (todo.isCompleted() && comp )
675 continue; 675 continue;
676 676
677 vector.insert(item++, todo ); 677 vector.insert(item++, todo );
678 } 678 }
679 679
680 vector.resize( item ); 680 vector.resize( item );
681 /* sort it now */ 681 /* sort it now */
682 vector.sort(); 682 vector.sort();
683 /* now get the uids */ 683 /* now get the uids */
684 UIDArray array( vector.count() ); 684 UIDArray array( vector.count() );
685 for (uint i= 0; i < vector.count(); i++ ) 685 for (uint i= 0; i < vector.count(); i++ )
686 array[i] = vector.uidAt( i ); 686 array[i] = vector.uidAt( i );
687 687
688 return array; 688 return array;
689} 689}
690 690
691void OPimTodoAccessXML::removeAllCompleted() { 691void OPimTodoAccessXML::removeAllCompleted() {
692 QMap<int, OPimTodo> events = m_events; 692 QMap<int, OPimTodo> events = m_events;
693 for ( QMap<int, OPimTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { 693 for ( QMap<int, OPimTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
694 if ( (*it).isCompleted() ) 694 if ( (*it).isCompleted() )
695 events.remove( it.key() ); 695 events.remove( it.key() );
696 } 696 }
697 m_events = events; 697 m_events = events;
698} 698}
699 699
700QArray<int> OPimTodoAccessXML::matchRegexp( const QRegExp &r ) const 700QArray<int> OPimTodoAccessXML::matchRegexp( const QRegExp &r ) const
701{ 701{
702 QArray<int> currentQuery( m_events.count() ); 702 QArray<int> currentQuery( m_events.count() );
703 uint arraycounter = 0; 703 uint arraycounter = 0;
704 704
705 QMap<int, OPimTodo>::ConstIterator it; 705 QMap<int, OPimTodo>::ConstIterator it;
706 for (it = m_events.begin(); it != m_events.end(); ++it ) { 706 for (it = m_events.begin(); it != m_events.end(); ++it ) {
707 if ( it.data().match( r ) ) 707 if ( it.data().match( r ) )
708 currentQuery[arraycounter++] = it.data().uid(); 708 currentQuery[arraycounter++] = it.data().uid();
709 709
710 } 710 }
711 // Shrink to fit.. 711 // Shrink to fit..
712 currentQuery.resize(arraycounter); 712 currentQuery.resize(arraycounter);
713 713
714 return currentQuery; 714 return currentQuery;
715} 715}
716 716
717} 717}