summaryrefslogtreecommitdiff
path: root/libopie
Unidiff
Diffstat (limited to 'libopie') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.h57
1 files changed, 39 insertions, 18 deletions
diff --git a/libopie/pim/ocontactaccessbackend_xml.h b/libopie/pim/ocontactaccessbackend_xml.h
index c6e6cbc..6a1c91d 100644
--- a/libopie/pim/ocontactaccessbackend_xml.h
+++ b/libopie/pim/ocontactaccessbackend_xml.h
@@ -1,524 +1,545 @@
1/* 1/*
2 * XML Backend for the OPIE-Contact Database. 2 * XML Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed... 12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 * 13 *
14 * 14 *
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.11 2003/01/03 12:31:28 eilers
21 * Bugfix for calculating data diffs..
22 *
20 * Revision 1.10 2003/01/02 14:27:12 eilers 23 * Revision 1.10 2003/01/02 14:27:12 eilers
21 * Improved query by example: Search by date is possible.. First step 24 * Improved query by example: Search by date is possible.. First step
22 * for a today plugin for birthdays.. 25 * for a today plugin for birthdays..
23 * 26 *
24 * Revision 1.9 2002/12/08 12:48:57 eilers 27 * Revision 1.9 2002/12/08 12:48:57 eilers
25 * Moved journal-enum from ocontact into i the xml-backend.. 28 * Moved journal-enum from ocontact into i the xml-backend..
26 * 29 *
27 * Revision 1.8 2002/11/14 17:04:24 eilers 30 * Revision 1.8 2002/11/14 17:04:24 eilers
28 * Sorting will now work if fullname is identical on some entries 31 * Sorting will now work if fullname is identical on some entries
29 * 32 *
30 * Revision 1.7 2002/11/13 15:02:46 eilers 33 * Revision 1.7 2002/11/13 15:02:46 eilers
31 * Small Bug in sorted fixed 34 * Small Bug in sorted fixed
32 * 35 *
33 * Revision 1.6 2002/11/13 14:14:51 eilers 36 * Revision 1.6 2002/11/13 14:14:51 eilers
34 * Added sorted for Contacts.. 37 * Added sorted for Contacts..
35 * 38 *
36 * Revision 1.5 2002/11/01 15:10:42 eilers 39 * Revision 1.5 2002/11/01 15:10:42 eilers
37 * Added regExp-search in database for all fields in a contact. 40 * Added regExp-search in database for all fields in a contact.
38 * 41 *
39 * Revision 1.4 2002/10/16 10:52:40 eilers 42 * Revision 1.4 2002/10/16 10:52:40 eilers
40 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 43 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
41 * 44 *
42 * Revision 1.3 2002/10/14 16:21:54 eilers 45 * Revision 1.3 2002/10/14 16:21:54 eilers
43 * Some minor interface updates 46 * Some minor interface updates
44 * 47 *
45 * Revision 1.2 2002/10/07 17:34:24 eilers 48 * Revision 1.2 2002/10/07 17:34:24 eilers
46 * added OBackendFactory for advanced backend access 49 * added OBackendFactory for advanced backend access
47 * 50 *
48 * Revision 1.1 2002/09/27 17:11:44 eilers 51 * Revision 1.1 2002/09/27 17:11:44 eilers
49 * Added API for accessing the Contact-Database ! It is compiling, but 52 * Added API for accessing the Contact-Database ! It is compiling, but
50 * please do not expect that anything is working ! 53 * please do not expect that anything is working !
51 * I will debug that stuff in the next time .. 54 * I will debug that stuff in the next time ..
52 * Please read README_COMPILE for compiling ! 55 * Please read README_COMPILE for compiling !
53 * 56 *
54 * 57 *
55 */ 58 */
56 59
57#ifndef _OContactAccessBackend_XML_ 60#ifndef _OContactAccessBackend_XML_
58#define _OContactAccessBackend_XML_ 61#define _OContactAccessBackend_XML_
59 62
60#include <qasciidict.h> 63#include <qasciidict.h>
61#include <qdatetime.h> 64#include <qdatetime.h>
62#include <qfile.h> 65#include <qfile.h>
63#include <qfileinfo.h> 66#include <qfileinfo.h>
64#include <qregexp.h> 67#include <qregexp.h>
65#include <qarray.h> 68#include <qarray.h>
66#include <qmap.h> 69#include <qmap.h>
67#include <qdatetime.h> 70#include <qdatetime.h>
68 71
69#include <qpe/global.h> 72#include <qpe/global.h>
70 73
71#include <opie/xmltree.h> 74#include <opie/xmltree.h>
72#include "ocontactaccessbackend.h" 75#include "ocontactaccessbackend.h"
73#include "ocontactaccess.h" 76#include "ocontactaccess.h"
74 77
75#include <stdlib.h> 78#include <stdlib.h>
76#include <errno.h> 79#include <errno.h>
77 80
78using namespace Opie; 81using namespace Opie;
79 82
80/* the default xml implementation */ 83/* the default xml implementation */
81class OContactAccessBackend_XML : public OContactAccessBackend { 84class OContactAccessBackend_XML : public OContactAccessBackend {
82 public: 85 public:
83 OContactAccessBackend_XML ( QString appname, QString filename = 0l ): 86 OContactAccessBackend_XML ( QString appname, QString filename = 0l ):
84 m_changed( false ) 87 m_changed( false )
85 { 88 {
86 m_appName = appname; 89 m_appName = appname;
87 90
88 /* Set journalfile name ... */ 91 /* Set journalfile name ... */
89 m_journalName = getenv("HOME"); 92 m_journalName = getenv("HOME");
90 m_journalName +="/.abjournal" + appname; 93 m_journalName +="/.abjournal" + appname;
91 94
92 /* Expecting to access the default filename if nothing else is set */ 95 /* Expecting to access the default filename if nothing else is set */
93 if ( filename.isEmpty() ){ 96 if ( filename.isEmpty() ){
94 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 97 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
95 } else 98 } else
96 m_fileName = filename; 99 m_fileName = filename;
97 100
98 /* Load Database now */ 101 /* Load Database now */
99 load (); 102 load ();
100 } 103 }
101 104
102 bool save() { 105 bool save() {
103 106
104 if ( !m_changed ) 107 if ( !m_changed )
105 return true; 108 return true;
106 109
107 QString strNewFile = m_fileName + ".new"; 110 QString strNewFile = m_fileName + ".new";
108 QFile f( strNewFile ); 111 QFile f( strNewFile );
109 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 112 if ( !f.open( IO_WriteOnly|IO_Raw ) )
110 return false; 113 return false;
111 114
112 int total_written; 115 int total_written;
113 QString out; 116 QString out;
114 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 117 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
115 " <Groups>\n" 118 " <Groups>\n"
116 " </Groups>\n" 119 " </Groups>\n"
117 " <Contacts>\n"; 120 " <Contacts>\n";
118 //QValueList<Contact>::iterator it; 121 //QValueList<Contact>::iterator it;
119 QValueListConstIterator<OContact> it; 122 QValueListConstIterator<OContact> it;
120 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) { 123 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) {
121 out += "<Contact "; 124 out += "<Contact ";
122 (*it).save( out ); 125 (*it).save( out );
123 out += "/>\n"; 126 out += "/>\n";
124 QCString cstr = out.utf8(); 127 QCString cstr = out.utf8();
125 total_written = f.writeBlock( cstr.data(), cstr.length() ); 128 total_written = f.writeBlock( cstr.data(), cstr.length() );
126 if ( total_written != int(cstr.length()) ) { 129 if ( total_written != int(cstr.length()) ) {
127 f.close(); 130 f.close();
128 QFile::remove( strNewFile ); 131 QFile::remove( strNewFile );
129 return false; 132 return false;
130 } 133 }
131 out = ""; 134 out = "";
132 } 135 }
133 out += " </Contacts>\n</AddressBook>\n"; 136 out += " </Contacts>\n</AddressBook>\n";
134 137
135 QCString cstr = out.utf8(); 138 QCString cstr = out.utf8();
136 total_written = f.writeBlock( cstr.data(), cstr.length() ); 139 total_written = f.writeBlock( cstr.data(), cstr.length() );
137 if ( total_written != int( cstr.length() ) ) { 140 if ( total_written != int( cstr.length() ) ) {
138 f.close(); 141 f.close();
139 QFile::remove( strNewFile ); 142 QFile::remove( strNewFile );
140 return false; 143 return false;
141 } 144 }
142 f.close(); 145 f.close();
143 146
144 // move the file over, I'm just going to use the system call 147 // move the file over, I'm just going to use the system call
145 // because, I don't feel like using QDir. 148 // because, I don't feel like using QDir.
146 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 149 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
147 qWarning( "problem renaming file %s to %s, errno: %d", 150 qWarning( "problem renaming file %s to %s, errno: %d",
148 strNewFile.latin1(), m_journalName.latin1(), errno ); 151 strNewFile.latin1(), m_journalName.latin1(), errno );
149 // remove the tmp file... 152 // remove the tmp file...
150 QFile::remove( strNewFile ); 153 QFile::remove( strNewFile );
151 } 154 }
152 155
153 /* The journalfile should be removed now... */ 156 /* The journalfile should be removed now... */
154 removeJournal(); 157 removeJournal();
155 158
156 m_changed = false; 159 m_changed = false;
157 return true; 160 return true;
158 } 161 }
159 162
160 bool load () { 163 bool load () {
161 m_contactList.clear(); 164 m_contactList.clear();
162 165
163 /* Load XML-File and journal if it exists */ 166 /* Load XML-File and journal if it exists */
164 if ( !load ( m_fileName, false ) ) 167 if ( !load ( m_fileName, false ) )
165 return false; 168 return false;
166 /* The returncode of the journalfile is ignored due to the 169 /* The returncode of the journalfile is ignored due to the
167 * fact that it does not exist when this class is instantiated ! 170 * fact that it does not exist when this class is instantiated !
168 * But there may such a file exist, if the application crashed. 171 * But there may such a file exist, if the application crashed.
169 * Therefore we try to load it to get the changes before the # 172 * Therefore we try to load it to get the changes before the #
170 * crash happened... 173 * crash happened...
171 */ 174 */
172 load (m_journalName, true); 175 load (m_journalName, true);
173 176
174 return true; 177 return true;
175 } 178 }
176 179
177 void clear () { 180 void clear () {
178 m_contactList.clear(); 181 m_contactList.clear();
179 m_changed = false; 182 m_changed = false;
180 183
181 } 184 }
182 185
183 bool wasChangedExternally() 186 bool wasChangedExternally()
184 { 187 {
185 QFileInfo fi( m_fileName ); 188 QFileInfo fi( m_fileName );
186 189
187 QDateTime lastmod = fi.lastModified (); 190 QDateTime lastmod = fi.lastModified ();
188 191
189 return (lastmod != m_readtime); 192 return (lastmod != m_readtime);
190 } 193 }
191 194
192 QArray<int> allRecords() const { 195 QArray<int> allRecords() const {
193 QArray<int> uid_list( m_contactList.count() ); 196 QArray<int> uid_list( m_contactList.count() );
194 197
195 uint counter = 0; 198 uint counter = 0;
196 QValueListConstIterator<OContact> it; 199 QValueListConstIterator<OContact> it;
197 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 200 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
198 uid_list[counter++] = (*it).uid(); 201 uid_list[counter++] = (*it).uid();
199 } 202 }
200 203
201 return ( uid_list ); 204 return ( uid_list );
202 } 205 }
203 206
204 OContact find ( int uid ) const 207 OContact find ( int uid ) const
205 { 208 {
206 bool found = false; 209 bool found = false;
207 OContact foundContact; //Create empty contact 210 OContact foundContact; //Create empty contact
208 211
209 QValueListConstIterator<OContact> it; 212 QValueListConstIterator<OContact> it;
210 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 213 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
211 if ((*it).uid() == uid){ 214 if ((*it).uid() == uid){
212 found = true; 215 found = true;
213 break; 216 break;
214 } 217 }
215 } 218 }
216 if ( found ){ 219 if ( found ){
217 foundContact = *it; 220 foundContact = *it;
218 } 221 }
219 222
220 return ( foundContact ); 223 return ( foundContact );
221 } 224 }
222 225
223 QArray<int> queryByExample ( const OContact &query, int settings ){ 226 QArray<int> queryByExample ( const OContact &query, int settings ){
224 227
225 QArray<int> m_currentQuery( m_contactList.count() ); 228 QArray<int> m_currentQuery( m_contactList.count() );
226 QValueListConstIterator<OContact> it; 229 QValueListConstIterator<OContact> it;
227 uint arraycounter = 0; 230 uint arraycounter = 0;
228 231
229 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 232 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
230 /* Search all fields and compare them with query object. Store them into list 233 /* Search all fields and compare them with query object. Store them into list
231 * if all fields matches. 234 * if all fields matches.
232 */ 235 */
233 QDate* queryDate = 0l; 236 QDate* queryDate = 0l;
234 QDate* checkDate = 0l; 237 QDate* checkDate = 0l;
235 bool allcorrect = true; 238 bool allcorrect = true;
236 for ( int i = 0; i < Qtopia::Groups; i++ ) { 239 for ( int i = 0; i < Qtopia::Groups; i++ ) {
237 // Birthday and anniversary are special nonstring fields and should 240 // Birthday and anniversary are special nonstring fields and should
238 // be handled especially 241 // be handled specially
239 switch ( i ){ 242 switch ( i ){
240 case Qtopia::Birthday: 243 case Qtopia::Birthday:
241 queryDate = new QDate( query.birthday() ); 244 queryDate = new QDate( query.birthday() );
242 checkDate = new QDate( (*it).birthday() ); 245 checkDate = new QDate( (*it).birthday() );
243 case Qtopia::Anniversary: 246 case Qtopia::Anniversary:
244 if ( queryDate == 0l ){ 247 if ( queryDate == 0l ){
245 queryDate = new QDate( query.anniversary() ); 248 queryDate = new QDate( query.anniversary() );
246 checkDate = new QDate( (*it).anniversary() ); 249 checkDate = new QDate( (*it).anniversary() );
247 } 250 }
248 251
249 if ( queryDate->isValid() ){ 252 if ( queryDate->isValid() ){
250 if ( settings & OContactAccess::DateYear ){ 253 if( checkDate->isValid() ){
251 if ( queryDate->year() != checkDate->year() ) 254 if ( settings & OContactAccess::DateYear ){
252 allcorrect = false; 255 if ( queryDate->year() != checkDate->year() )
253 } 256 allcorrect = false;
254 if ( settings & OContactAccess::DateMonth ){ 257 }
255 if ( queryDate->month() != checkDate->month() ) 258 if ( settings & OContactAccess::DateMonth ){
256 allcorrect = false; 259 if ( queryDate->month() != checkDate->month() )
257 } 260 allcorrect = false;
258 if ( settings & OContactAccess::DateDay ){ 261 }
259 if ( queryDate->day() != checkDate->day() ) 262 if ( settings & OContactAccess::DateDay ){
260 allcorrect = false; 263 if ( queryDate->day() != checkDate->day() )
261 }
262 if ( settings & OContactAccess::DateDiff ) {
263 QDate current = QDate::currentDate();
264 if ( current.daysTo( *queryDate ) > 0 ){
265 if ( !( ( *checkDate >= current ) &&
266 ( *checkDate <= *queryDate ) ) )
267 allcorrect = false; 264 allcorrect = false;
265 }
266 if ( settings & OContactAccess::DateDiff ) {
267 QDate current = QDate::currentDate();
268 // We have to equalize the year, otherwise
269 // the search will fail..
270 checkDate->setYMD( current.year(), checkDate->month(), checkDate->day() );
271 if ( *checkDate < current )
272 checkDate->setYMD( current.year()+1,
273 checkDate->month(),
274 checkDate->day() );
275 // qWarning("Checking if %s is between %s and %s ! ",
276 // checkDate->toString().latin1(),
277 // current.toString().latin1(),
278 // queryDate->toString().latin1() );
279 if ( current.daysTo( *queryDate ) > 0 ){
280 if ( !( ( *checkDate >= current ) &&
281 ( *checkDate <= *queryDate ) ) ){
282 allcorrect = false;
283 //qWarning (" Nope!..");
284 }
285 }
268 } 286 }
287 } else{
288 // checkDate is invalid. Therfore this entry is always rejected
289 allcorrect = false;
269 } 290 }
270 } 291 }
271 292
272 delete queryDate; 293 delete queryDate;
273 queryDate = 0l; 294 queryDate = 0l;
274 delete checkDate; 295 delete checkDate;
275 checkDate = 0l; 296 checkDate = 0l;
276 break; 297 break;
277 default: 298 default:
278 /* Just compare fields which are not empty in the query object */ 299 /* Just compare fields which are not empty in the query object */
279 if ( !query.field(i).isEmpty() ){ 300 if ( !query.field(i).isEmpty() ){
280 switch ( settings & ~( OContactAccess::IgnoreCase 301 switch ( settings & ~( OContactAccess::IgnoreCase
281 | OContactAccess::DateDiff 302 | OContactAccess::DateDiff
282 | OContactAccess::DateYear 303 | OContactAccess::DateYear
283 | OContactAccess::DateMonth 304 | OContactAccess::DateMonth
284 | OContactAccess::DateDay 305 | OContactAccess::DateDay
285 | OContactAccess::MatchOne 306 | OContactAccess::MatchOne
286 ) ){ 307 ) ){
287 308
288 case OContactAccess::RegExp:{ 309 case OContactAccess::RegExp:{
289 QRegExp expr ( query.field(i), 310 QRegExp expr ( query.field(i),
290 !(settings & OContactAccess::IgnoreCase), 311 !(settings & OContactAccess::IgnoreCase),
291 false ); 312 false );
292 if ( expr.find ( (*it).field(i), 0 ) == -1 ) 313 if ( expr.find ( (*it).field(i), 0 ) == -1 )
293 allcorrect = false; 314 allcorrect = false;
294 } 315 }
295 break; 316 break;
296 case OContactAccess::WildCards:{ 317 case OContactAccess::WildCards:{
297 QRegExp expr ( query.field(i), 318 QRegExp expr ( query.field(i),
298 !(settings & OContactAccess::IgnoreCase), 319 !(settings & OContactAccess::IgnoreCase),
299 true ); 320 true );
300 if ( expr.find ( (*it).field(i), 0 ) == -1 ) 321 if ( expr.find ( (*it).field(i), 0 ) == -1 )
301 allcorrect = false; 322 allcorrect = false;
302 } 323 }
303 break; 324 break;
304 case OContactAccess::ExactMatch:{ 325 case OContactAccess::ExactMatch:{
305 if (settings & OContactAccess::IgnoreCase){ 326 if (settings & OContactAccess::IgnoreCase){
306 if ( query.field(i).upper() != 327 if ( query.field(i).upper() !=
307 (*it).field(i).upper() ) 328 (*it).field(i).upper() )
308 allcorrect = false; 329 allcorrect = false;
309 }else{ 330 }else{
310 if ( query.field(i) != (*it).field(i) ) 331 if ( query.field(i) != (*it).field(i) )
311 allcorrect = false; 332 allcorrect = false;
312 } 333 }
313 } 334 }
314 break; 335 break;
315 } 336 }
316 } 337 }
317 } 338 }
318 } 339 }
319 if ( allcorrect ){ 340 if ( allcorrect ){
320 m_currentQuery[arraycounter++] = (*it).uid(); 341 m_currentQuery[arraycounter++] = (*it).uid();
321 } 342 }
322 } 343 }
323 344
324 // Shrink to fit.. 345 // Shrink to fit..
325 m_currentQuery.resize(arraycounter); 346 m_currentQuery.resize(arraycounter);
326 347
327 return m_currentQuery; 348 return m_currentQuery;
328 } 349 }
329 350
330 QArray<int> matchRegexp( const QRegExp &r ) const{ 351 QArray<int> matchRegexp( const QRegExp &r ) const{
331 QArray<int> m_currentQuery( m_contactList.count() ); 352 QArray<int> m_currentQuery( m_contactList.count() );
332 QValueListConstIterator<OContact> it; 353 QValueListConstIterator<OContact> it;
333 uint arraycounter = 0; 354 uint arraycounter = 0;
334 355
335 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 356 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
336 if ( (*it).match( r ) ){ 357 if ( (*it).match( r ) ){
337 m_currentQuery[arraycounter++] = (*it).uid(); 358 m_currentQuery[arraycounter++] = (*it).uid();
338 } 359 }
339 360
340 } 361 }
341 // Shrink to fit.. 362 // Shrink to fit..
342 m_currentQuery.resize(arraycounter); 363 m_currentQuery.resize(arraycounter);
343 364
344 return m_currentQuery; 365 return m_currentQuery;
345 } 366 }
346 367
347 const uint querySettings() 368 const uint querySettings()
348 { 369 {
349 return ( OContactAccess::WildCards 370 return ( OContactAccess::WildCards
350 | OContactAccess::IgnoreCase 371 | OContactAccess::IgnoreCase
351 | OContactAccess::RegExp 372 | OContactAccess::RegExp
352 | OContactAccess::ExactMatch 373 | OContactAccess::ExactMatch
353 | OContactAccess::DateDiff 374 | OContactAccess::DateDiff
354 | OContactAccess::DateYear 375 | OContactAccess::DateYear
355 | OContactAccess::DateMonth 376 | OContactAccess::DateMonth
356 | OContactAccess::DateDay 377 | OContactAccess::DateDay
357 ); 378 );
358 } 379 }
359 380
360 bool hasQuerySettings (uint querySettings) const 381 bool hasQuerySettings (uint querySettings) const
361 { 382 {
362 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 383 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
363 * may be added with any of the other settings. IgnoreCase should never used alone. 384 * may be added with any of the other settings. IgnoreCase should never used alone.
364 * Wildcards, RegExp, ExactMatch should never used at the same time... 385 * Wildcards, RegExp, ExactMatch should never used at the same time...
365 */ 386 */
366 387
367 if ( querySettings == OContactAccess::IgnoreCase ) 388 if ( querySettings == OContactAccess::IgnoreCase )
368 return false; 389 return false;
369 390
370 switch ( querySettings & ~( OContactAccess::IgnoreCase 391 switch ( querySettings & ~( OContactAccess::IgnoreCase
371 | OContactAccess::DateDiff 392 | OContactAccess::DateDiff
372 | OContactAccess::DateYear 393 | OContactAccess::DateYear
373 | OContactAccess::DateMonth 394 | OContactAccess::DateMonth
374 | OContactAccess::DateDay 395 | OContactAccess::DateDay
375 ) 396 )
376 ){ 397 ){
377 case OContactAccess::RegExp: 398 case OContactAccess::RegExp:
378 return ( true ); 399 return ( true );
379 case OContactAccess::WildCards: 400 case OContactAccess::WildCards:
380 return ( true ); 401 return ( true );
381 case OContactAccess::ExactMatch: 402 case OContactAccess::ExactMatch:
382 return ( true ); 403 return ( true );
383 default: 404 default:
384 return ( false ); 405 return ( false );
385 } 406 }
386 } 407 }
387 408
388 // Currently only asc implemented.. 409 // Currently only asc implemented..
389 QArray<int> sorted( bool asc, int , int , int ) 410 QArray<int> sorted( bool asc, int , int , int )
390 { 411 {
391 QMap<QString, int> nameToUid; 412 QMap<QString, int> nameToUid;
392 QStringList names; 413 QStringList names;
393 QArray<int> m_currentQuery( m_contactList.count() ); 414 QArray<int> m_currentQuery( m_contactList.count() );
394 415
395 // First fill map and StringList with all Names 416 // First fill map and StringList with all Names
396 // Afterwards sort namelist and use map to fill array to return.. 417 // Afterwards sort namelist and use map to fill array to return..
397 QValueListConstIterator<OContact> it; 418 QValueListConstIterator<OContact> it;
398 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 419 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
399 names.append( (*it).fileAs() + QString::number( (*it).uid() ) ); 420 names.append( (*it).fileAs() + QString::number( (*it).uid() ) );
400 nameToUid.insert( (*it).fileAs() + QString::number( (*it).uid() ), (*it).uid() ); 421 nameToUid.insert( (*it).fileAs() + QString::number( (*it).uid() ), (*it).uid() );
401 } 422 }
402 names.sort(); 423 names.sort();
403 424
404 int i = 0; 425 int i = 0;
405 if ( asc ){ 426 if ( asc ){
406 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 427 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
407 m_currentQuery[i++] = nameToUid[ (*it) ]; 428 m_currentQuery[i++] = nameToUid[ (*it) ];
408 }else{ 429 }else{
409 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 430 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
410 m_currentQuery[i++] = nameToUid[ (*it) ]; 431 m_currentQuery[i++] = nameToUid[ (*it) ];
411 } 432 }
412 433
413 return m_currentQuery; 434 return m_currentQuery;
414 435
415 } 436 }
416 bool add ( const OContact &newcontact ) 437 bool add ( const OContact &newcontact )
417 { 438 {
418 //qWarning("odefaultbackend: ACTION::ADD"); 439 //qWarning("odefaultbackend: ACTION::ADD");
419 updateJournal (newcontact, ACTION_ADD); 440 updateJournal (newcontact, ACTION_ADD);
420 addContact_p( newcontact ); 441 addContact_p( newcontact );
421 442
422 m_changed = true; 443 m_changed = true;
423 444
424 return true; 445 return true;
425 } 446 }
426 447
427 bool replace ( const OContact &contact ) 448 bool replace ( const OContact &contact )
428 { 449 {
429 m_changed = true; 450 m_changed = true;
430 451
431 bool found = false; 452 bool found = false;
432 453
433 QValueListIterator<OContact> it; 454 QValueListIterator<OContact> it;
434 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 455 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
435 if ( (*it).uid() == contact.uid() ){ 456 if ( (*it).uid() == contact.uid() ){
436 found = true; 457 found = true;
437 break; 458 break;
438 } 459 }
439 } 460 }
440 if (found) { 461 if (found) {
441 updateJournal (contact, ACTION_REPLACE); 462 updateJournal (contact, ACTION_REPLACE);
442 m_contactList.remove (it); 463 m_contactList.remove (it);
443 m_contactList.append (contact); 464 m_contactList.append (contact);
444 return true; 465 return true;
445 } else 466 } else
446 return false; 467 return false;
447 } 468 }
448 469
449 bool remove ( int uid ) 470 bool remove ( int uid )
450 { 471 {
451 m_changed = true; 472 m_changed = true;
452 473
453 bool found = false; 474 bool found = false;
454 QValueListIterator<OContact> it; 475 QValueListIterator<OContact> it;
455 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 476 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
456 if ((*it).uid() == uid){ 477 if ((*it).uid() == uid){
457 found = true; 478 found = true;
458 break; 479 break;
459 } 480 }
460 } 481 }
461 if (found) { 482 if (found) {
462 updateJournal ( *it, ACTION_REMOVE); 483 updateJournal ( *it, ACTION_REMOVE);
463 m_contactList.remove (it); 484 m_contactList.remove (it);
464 return true; 485 return true;
465 } else 486 } else
466 return false; 487 return false;
467 } 488 }
468 489
469 bool reload(){ 490 bool reload(){
470 /* Reload is the same as load in this implementation */ 491 /* Reload is the same as load in this implementation */
471 return ( load() ); 492 return ( load() );
472 } 493 }
473 494
474 private: 495 private:
475 496
476 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; 497 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
477 498
478 void addContact_p( const OContact &newcontact ){ 499 void addContact_p( const OContact &newcontact ){
479 m_contactList.append (newcontact); 500 m_contactList.append (newcontact);
480 } 501 }
481 502
482 /* This function loads the xml-database and the journalfile */ 503 /* This function loads the xml-database and the journalfile */
483 bool load( const QString filename, bool isJournal ) { 504 bool load( const QString filename, bool isJournal ) {
484 505
485 /* We use the time of the last read to check if the file was 506 /* We use the time of the last read to check if the file was
486 * changed externally. 507 * changed externally.
487 */ 508 */
488 if ( !isJournal ){ 509 if ( !isJournal ){
489 QFileInfo fi( filename ); 510 QFileInfo fi( filename );
490 m_readtime = fi.lastModified (); 511 m_readtime = fi.lastModified ();
491 } 512 }
492 513
493 const int JOURNALACTION = Qtopia::Notes + 1; 514 const int JOURNALACTION = Qtopia::Notes + 1;
494 const int JOURNALROW = JOURNALACTION + 1; 515 const int JOURNALROW = JOURNALACTION + 1;
495 516
496 bool foundAction = false; 517 bool foundAction = false;
497 journal_action action = ACTION_ADD; 518 journal_action action = ACTION_ADD;
498 int journalKey = 0; 519 int journalKey = 0;
499 QMap<int, QString> contactMap; 520 QMap<int, QString> contactMap;
500 QMap<QString, QString> customMap; 521 QMap<QString, QString> customMap;
501 QMap<QString, QString>::Iterator customIt; 522 QMap<QString, QString>::Iterator customIt;
502 QAsciiDict<int> dict( 47 ); 523 QAsciiDict<int> dict( 47 );
503 524
504 dict.setAutoDelete( TRUE ); 525 dict.setAutoDelete( TRUE );
505 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 526 dict.insert( "Uid", new int(Qtopia::AddressUid) );
506 dict.insert( "Title", new int(Qtopia::Title) ); 527 dict.insert( "Title", new int(Qtopia::Title) );
507 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 528 dict.insert( "FirstName", new int(Qtopia::FirstName) );
508 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 529 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
509 dict.insert( "LastName", new int(Qtopia::LastName) ); 530 dict.insert( "LastName", new int(Qtopia::LastName) );
510 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 531 dict.insert( "Suffix", new int(Qtopia::Suffix) );
511 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 532 dict.insert( "FileAs", new int(Qtopia::FileAs) );
512 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 533 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
513 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 534 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
514 dict.insert( "Emails", new int(Qtopia::Emails) ); 535 dict.insert( "Emails", new int(Qtopia::Emails) );
515 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 536 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
516 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 537 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
517 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 538 dict.insert( "HomeState", new int(Qtopia::HomeState) );
518 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 539 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
519 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 540 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
520 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 541 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
521 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 542 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
522 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 543 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
523 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 544 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
524 dict.insert( "Company", new int(Qtopia::Company) ); 545 dict.insert( "Company", new int(Qtopia::Company) );