summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.h7
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.h7
2 files changed, 10 insertions, 4 deletions
diff --git a/libopie/pim/ocontactaccessbackend_xml.h b/libopie/pim/ocontactaccessbackend_xml.h
index adc8dc3..ae6ec9e 100644
--- a/libopie/pim/ocontactaccessbackend_xml.h
+++ b/libopie/pim/ocontactaccessbackend_xml.h
@@ -1,147 +1,150 @@
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.8 2002/11/14 17:04:24 eilers
21 * Sorting will now work if fullname is identical on some entries
22 *
20 * Revision 1.7 2002/11/13 15:02:46 eilers 23 * Revision 1.7 2002/11/13 15:02:46 eilers
21 * Small Bug in sorted fixed 24 * Small Bug in sorted fixed
22 * 25 *
23 * Revision 1.6 2002/11/13 14:14:51 eilers 26 * Revision 1.6 2002/11/13 14:14:51 eilers
24 * Added sorted for Contacts.. 27 * Added sorted for Contacts..
25 * 28 *
26 * Revision 1.5 2002/11/01 15:10:42 eilers 29 * Revision 1.5 2002/11/01 15:10:42 eilers
27 * Added regExp-search in database for all fields in a contact. 30 * Added regExp-search in database for all fields in a contact.
28 * 31 *
29 * Revision 1.4 2002/10/16 10:52:40 eilers 32 * Revision 1.4 2002/10/16 10:52:40 eilers
30 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 33 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
31 * 34 *
32 * Revision 1.3 2002/10/14 16:21:54 eilers 35 * Revision 1.3 2002/10/14 16:21:54 eilers
33 * Some minor interface updates 36 * Some minor interface updates
34 * 37 *
35 * Revision 1.2 2002/10/07 17:34:24 eilers 38 * Revision 1.2 2002/10/07 17:34:24 eilers
36 * added OBackendFactory for advanced backend access 39 * added OBackendFactory for advanced backend access
37 * 40 *
38 * Revision 1.1 2002/09/27 17:11:44 eilers 41 * Revision 1.1 2002/09/27 17:11:44 eilers
39 * Added API for accessing the Contact-Database ! It is compiling, but 42 * Added API for accessing the Contact-Database ! It is compiling, but
40 * please do not expect that anything is working ! 43 * please do not expect that anything is working !
41 * I will debug that stuff in the next time .. 44 * I will debug that stuff in the next time ..
42 * Please read README_COMPILE for compiling ! 45 * Please read README_COMPILE for compiling !
43 * 46 *
44 * 47 *
45 */ 48 */
46 49
47#ifndef _OContactAccessBackend_XML_ 50#ifndef _OContactAccessBackend_XML_
48#define _OContactAccessBackend_XML_ 51#define _OContactAccessBackend_XML_
49 52
50#include <qasciidict.h> 53#include <qasciidict.h>
51#include <qdatetime.h> 54#include <qdatetime.h>
52#include <qfile.h> 55#include <qfile.h>
53#include <qfileinfo.h> 56#include <qfileinfo.h>
54#include <qregexp.h> 57#include <qregexp.h>
55#include <qarray.h> 58#include <qarray.h>
56#include <qmap.h> 59#include <qmap.h>
57 60
58#include <qpe/global.h> 61#include <qpe/global.h>
59 62
60#include <opie/xmltree.h> 63#include <opie/xmltree.h>
61#include "ocontactaccessbackend.h" 64#include "ocontactaccessbackend.h"
62#include "ocontactaccess.h" 65#include "ocontactaccess.h"
63 66
64#include <stdlib.h> 67#include <stdlib.h>
65#include <errno.h> 68#include <errno.h>
66 69
67using namespace Opie; 70using namespace Opie;
68 71
69/* the default xml implementation */ 72/* the default xml implementation */
70class OContactAccessBackend_XML : public OContactAccessBackend { 73class OContactAccessBackend_XML : public OContactAccessBackend {
71 public: 74 public:
72 OContactAccessBackend_XML ( QString appname, QString filename = 0l ): 75 OContactAccessBackend_XML ( QString appname, QString filename = 0l ):
73 m_changed( false ) 76 m_changed( false )
74 { 77 {
75 m_appName = appname; 78 m_appName = appname;
76 79
77 /* Set journalfile name ... */ 80 /* Set journalfile name ... */
78 m_journalName = getenv("HOME"); 81 m_journalName = getenv("HOME");
79 m_journalName +="/.abjournal" + appname; 82 m_journalName +="/.abjournal" + appname;
80 83
81 /* Expecting to access the default filename if nothing else is set */ 84 /* Expecting to access the default filename if nothing else is set */
82 if ( filename.isEmpty() ){ 85 if ( filename.isEmpty() ){
83 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 86 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
84 } else 87 } else
85 m_fileName = filename; 88 m_fileName = filename;
86 89
87 /* Load Database now */ 90 /* Load Database now */
88 load (); 91 load ();
89 } 92 }
90 93
91 bool save() { 94 bool save() {
92 95
93 if ( !m_changed ) 96 if ( !m_changed )
94 return true; 97 return true;
95 98
96 QString strNewFile = m_fileName + ".new"; 99 QString strNewFile = m_fileName + ".new";
97 QFile f( strNewFile ); 100 QFile f( strNewFile );
98 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 101 if ( !f.open( IO_WriteOnly|IO_Raw ) )
99 return false; 102 return false;
100 103
101 int total_written; 104 int total_written;
102 QString out; 105 QString out;
103 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 106 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
104 " <Groups>\n" 107 " <Groups>\n"
105 " </Groups>\n" 108 " </Groups>\n"
106 " <Contacts>\n"; 109 " <Contacts>\n";
107 //QValueList<Contact>::iterator it; 110 //QValueList<Contact>::iterator it;
108 QValueListConstIterator<OContact> it; 111 QValueListConstIterator<OContact> it;
109 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) { 112 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) {
110 out += "<Contact "; 113 out += "<Contact ";
111 (*it).save( out ); 114 (*it).save( out );
112 out += "/>\n"; 115 out += "/>\n";
113 QCString cstr = out.utf8(); 116 QCString cstr = out.utf8();
114 total_written = f.writeBlock( cstr.data(), cstr.length() ); 117 total_written = f.writeBlock( cstr.data(), cstr.length() );
115 if ( total_written != int(cstr.length()) ) { 118 if ( total_written != int(cstr.length()) ) {
116 f.close(); 119 f.close();
117 QFile::remove( strNewFile ); 120 QFile::remove( strNewFile );
118 return false; 121 return false;
119 } 122 }
120 out = ""; 123 out = "";
121 } 124 }
122 out += " </Contacts>\n</AddressBook>\n"; 125 out += " </Contacts>\n</AddressBook>\n";
123 126
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 f.close(); 134 f.close();
132 135
133 // move the file over, I'm just going to use the system call 136 // move the file over, I'm just going to use the system call
134 // because, I don't feel like using QDir. 137 // because, I don't feel like using QDir.
135 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 138 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
136 qWarning( "problem renaming file %s to %s, errno: %d", 139 qWarning( "problem renaming file %s to %s, errno: %d",
137 strNewFile.latin1(), m_journalName.latin1(), errno ); 140 strNewFile.latin1(), m_journalName.latin1(), errno );
138 // remove the tmp file... 141 // remove the tmp file...
139 QFile::remove( strNewFile ); 142 QFile::remove( strNewFile );
140 } 143 }
141 144
142 /* The journalfile should be removed now... */ 145 /* The journalfile should be removed now... */
143 removeJournal(); 146 removeJournal();
144 147
145 m_changed = false; 148 m_changed = false;
146 return true; 149 return true;
147 } 150 }
@@ -194,258 +197,258 @@ class OContactAccessBackend_XML : public OContactAccessBackend {
194 { 197 {
195 bool found = false; 198 bool found = false;
196 OContact foundContact; //Create empty contact 199 OContact foundContact; //Create empty contact
197 200
198 QValueListConstIterator<OContact> it; 201 QValueListConstIterator<OContact> it;
199 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 202 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
200 if ((*it).uid() == uid){ 203 if ((*it).uid() == uid){
201 found = true; 204 found = true;
202 break; 205 break;
203 } 206 }
204 } 207 }
205 if ( found ){ 208 if ( found ){
206 foundContact = *it; 209 foundContact = *it;
207 } 210 }
208 211
209 return ( foundContact ); 212 return ( foundContact );
210 } 213 }
211 214
212 QArray<int> queryByExample ( const OContact &query, int settings ){ 215 QArray<int> queryByExample ( const OContact &query, int settings ){
213 216
214 QArray<int> m_currentQuery( m_contactList.count() ); 217 QArray<int> m_currentQuery( m_contactList.count() );
215 QValueListConstIterator<OContact> it; 218 QValueListConstIterator<OContact> it;
216 uint arraycounter = 0; 219 uint arraycounter = 0;
217 220
218 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 221 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
219 /* Search all fields and compare them with query object. Store them into list 222 /* Search all fields and compare them with query object. Store them into list
220 * if all fields matches. 223 * if all fields matches.
221 */ 224 */
222 bool allcorrect = true; 225 bool allcorrect = true;
223 for ( int i = 0; i < Qtopia::rid; i++ ) { 226 for ( int i = 0; i < Qtopia::rid; i++ ) {
224 /* Just compare fields which are not empty in the query object */ 227 /* Just compare fields which are not empty in the query object */
225 if ( !query.field(i).isEmpty() ){ 228 if ( !query.field(i).isEmpty() ){
226 switch ( settings & ~OContactAccess::IgnoreCase ){ 229 switch ( settings & ~OContactAccess::IgnoreCase ){
227 case OContactAccess::RegExp:{ 230 case OContactAccess::RegExp:{
228 QRegExp expr ( query.field(i), 231 QRegExp expr ( query.field(i),
229 !(settings & OContactAccess::IgnoreCase), 232 !(settings & OContactAccess::IgnoreCase),
230 false ); 233 false );
231 if ( expr.find ( (*it).field(i), 0 ) == -1 ) 234 if ( expr.find ( (*it).field(i), 0 ) == -1 )
232 allcorrect = false; 235 allcorrect = false;
233 } 236 }
234 break; 237 break;
235 case OContactAccess::WildCards:{ 238 case OContactAccess::WildCards:{
236 QRegExp expr ( query.field(i), 239 QRegExp expr ( query.field(i),
237 !(settings & OContactAccess::IgnoreCase), 240 !(settings & OContactAccess::IgnoreCase),
238 true ); 241 true );
239 if ( expr.find ( (*it).field(i), 0 ) == -1 ) 242 if ( expr.find ( (*it).field(i), 0 ) == -1 )
240 allcorrect = false; 243 allcorrect = false;
241 } 244 }
242 break; 245 break;
243 case OContactAccess::ExactMatch:{ 246 case OContactAccess::ExactMatch:{
244 if (settings & OContactAccess::IgnoreCase){ 247 if (settings & OContactAccess::IgnoreCase){
245 if ( query.field(i).upper() != 248 if ( query.field(i).upper() !=
246 (*it).field(i).upper() ) 249 (*it).field(i).upper() )
247 allcorrect = false; 250 allcorrect = false;
248 }else{ 251 }else{
249 if ( query.field(i) != (*it).field(i) ) 252 if ( query.field(i) != (*it).field(i) )
250 allcorrect = false; 253 allcorrect = false;
251 } 254 }
252 } 255 }
253 break; 256 break;
254 } 257 }
255 } 258 }
256 } 259 }
257 if ( allcorrect ){ 260 if ( allcorrect ){
258 m_currentQuery[arraycounter++] = (*it).uid(); 261 m_currentQuery[arraycounter++] = (*it).uid();
259 } 262 }
260 } 263 }
261 264
262 // Shrink to fit.. 265 // Shrink to fit..
263 m_currentQuery.resize(arraycounter); 266 m_currentQuery.resize(arraycounter);
264 267
265 return m_currentQuery; 268 return m_currentQuery;
266 } 269 }
267 270
268 QArray<int> matchRegexp( const QRegExp &r ) const{ 271 QArray<int> matchRegexp( const QRegExp &r ) const{
269 QArray<int> m_currentQuery( m_contactList.count() ); 272 QArray<int> m_currentQuery( m_contactList.count() );
270 QValueListConstIterator<OContact> it; 273 QValueListConstIterator<OContact> it;
271 uint arraycounter = 0; 274 uint arraycounter = 0;
272 275
273 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 276 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
274 if ( (*it).match( r ) ){ 277 if ( (*it).match( r ) ){
275 m_currentQuery[arraycounter++] = (*it).uid(); 278 m_currentQuery[arraycounter++] = (*it).uid();
276 } 279 }
277 280
278 } 281 }
279 // Shrink to fit.. 282 // Shrink to fit..
280 m_currentQuery.resize(arraycounter); 283 m_currentQuery.resize(arraycounter);
281 284
282 return m_currentQuery; 285 return m_currentQuery;
283 } 286 }
284 287
285 const uint querySettings() 288 const uint querySettings()
286 { 289 {
287 return ( OContactAccess::WildCards 290 return ( OContactAccess::WildCards
288 & OContactAccess::IgnoreCase 291 & OContactAccess::IgnoreCase
289 & OContactAccess::RegExp 292 & OContactAccess::RegExp
290 & OContactAccess::ExactMatch ); 293 & OContactAccess::ExactMatch );
291 } 294 }
292 295
293 bool hasQuerySettings (uint querySettings) const 296 bool hasQuerySettings (uint querySettings) const
294 { 297 {
295 /* OContactAccess::IgnoreCase may be added with one 298 /* OContactAccess::IgnoreCase may be added with one
296 * of the other settings, but never used alone. 299 * of the other settings, but never used alone.
297 * The other settings are just valid alone... 300 * The other settings are just valid alone...
298 */ 301 */
299 switch ( querySettings & ~OContactAccess::IgnoreCase ){ 302 switch ( querySettings & ~OContactAccess::IgnoreCase ){
300 case OContactAccess::RegExp: 303 case OContactAccess::RegExp:
301 return ( true ); 304 return ( true );
302 case OContactAccess::WildCards: 305 case OContactAccess::WildCards:
303 return ( true ); 306 return ( true );
304 case OContactAccess::ExactMatch: 307 case OContactAccess::ExactMatch:
305 return ( true ); 308 return ( true );
306 default: 309 default:
307 return ( false ); 310 return ( false );
308 } 311 }
309 } 312 }
310 313
311 // Currently only asc implemented.. 314 // Currently only asc implemented..
312 QArray<int> sorted( bool asc, int , int , int ) 315 QArray<int> sorted( bool asc, int , int , int )
313 { 316 {
314 QMap<QString, int> nameToUid; 317 QMap<QString, int> nameToUid;
315 QStringList names; 318 QStringList names;
316 QArray<int> m_currentQuery( m_contactList.count() ); 319 QArray<int> m_currentQuery( m_contactList.count() );
317 320
318 // First fill map and StringList with all Names 321 // First fill map and StringList with all Names
319 // Afterwards sort namelist and use map to fill array to return.. 322 // Afterwards sort namelist and use map to fill array to return..
320 QValueListConstIterator<OContact> it; 323 QValueListConstIterator<OContact> it;
321 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 324 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
322 names.append( (*it).fileAs() ); 325 names.append( (*it).fileAs() + QString::number( (*it).uid() ) );
323 nameToUid.insert( (*it).fileAs(), (*it).uid() ); 326 nameToUid.insert( (*it).fileAs() + QString::number( (*it).uid() ), (*it).uid() );
324 } 327 }
325 names.sort(); 328 names.sort();
326 329
327 int i = 0; 330 int i = 0;
328 if ( asc ){ 331 if ( asc ){
329 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 332 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
330 m_currentQuery[i++] = nameToUid[ (*it) ]; 333 m_currentQuery[i++] = nameToUid[ (*it) ];
331 }else{ 334 }else{
332 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 335 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
333 m_currentQuery[i++] = nameToUid[ (*it) ]; 336 m_currentQuery[i++] = nameToUid[ (*it) ];
334 } 337 }
335 338
336 return m_currentQuery; 339 return m_currentQuery;
337 340
338 } 341 }
339 bool add ( const OContact &newcontact ) 342 bool add ( const OContact &newcontact )
340 { 343 {
341 //qWarning("odefaultbackend: ACTION::ADD"); 344 //qWarning("odefaultbackend: ACTION::ADD");
342 updateJournal (newcontact, OContact::ACTION_ADD); 345 updateJournal (newcontact, OContact::ACTION_ADD);
343 addContact_p( newcontact ); 346 addContact_p( newcontact );
344 347
345 m_changed = true; 348 m_changed = true;
346 349
347 return true; 350 return true;
348 } 351 }
349 352
350 bool replace ( const OContact &contact ) 353 bool replace ( const OContact &contact )
351 { 354 {
352 m_changed = true; 355 m_changed = true;
353 356
354 bool found = false; 357 bool found = false;
355 358
356 QValueListIterator<OContact> it; 359 QValueListIterator<OContact> it;
357 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 360 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
358 if ( (*it).uid() == contact.uid() ){ 361 if ( (*it).uid() == contact.uid() ){
359 found = true; 362 found = true;
360 break; 363 break;
361 } 364 }
362 } 365 }
363 if (found) { 366 if (found) {
364 updateJournal (contact, OContact::ACTION_REPLACE); 367 updateJournal (contact, OContact::ACTION_REPLACE);
365 m_contactList.remove (it); 368 m_contactList.remove (it);
366 m_contactList.append (contact); 369 m_contactList.append (contact);
367 return true; 370 return true;
368 } else 371 } else
369 return false; 372 return false;
370 } 373 }
371 374
372 bool remove ( int uid ) 375 bool remove ( int uid )
373 { 376 {
374 m_changed = true; 377 m_changed = true;
375 378
376 bool found = false; 379 bool found = false;
377 QValueListIterator<OContact> it; 380 QValueListIterator<OContact> it;
378 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 381 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
379 if ((*it).uid() == uid){ 382 if ((*it).uid() == uid){
380 found = true; 383 found = true;
381 break; 384 break;
382 } 385 }
383 } 386 }
384 if (found) { 387 if (found) {
385 updateJournal ( *it, OContact::ACTION_REMOVE); 388 updateJournal ( *it, OContact::ACTION_REMOVE);
386 m_contactList.remove (it); 389 m_contactList.remove (it);
387 return true; 390 return true;
388 } else 391 } else
389 return false; 392 return false;
390 } 393 }
391 394
392 bool reload(){ 395 bool reload(){
393 /* Reload is the same as load in this implementation */ 396 /* Reload is the same as load in this implementation */
394 return ( load() ); 397 return ( load() );
395 } 398 }
396 399
397 private: 400 private:
398 void addContact_p( const OContact &newcontact ){ 401 void addContact_p( const OContact &newcontact ){
399 m_contactList.append (newcontact); 402 m_contactList.append (newcontact);
400 } 403 }
401 404
402 /* This function loads the xml-database and the journalfile */ 405 /* This function loads the xml-database and the journalfile */
403 bool load( const QString filename, bool isJournal ) { 406 bool load( const QString filename, bool isJournal ) {
404 407
405 /* We use the time of the last read to check if the file was 408 /* We use the time of the last read to check if the file was
406 * changed externally. 409 * changed externally.
407 */ 410 */
408 if ( !isJournal ){ 411 if ( !isJournal ){
409 QFileInfo fi( filename ); 412 QFileInfo fi( filename );
410 m_readtime = fi.lastModified (); 413 m_readtime = fi.lastModified ();
411 } 414 }
412 415
413 const int JOURNALACTION = Qtopia::Notes + 1; 416 const int JOURNALACTION = Qtopia::Notes + 1;
414 const int JOURNALROW = JOURNALACTION + 1; 417 const int JOURNALROW = JOURNALACTION + 1;
415 418
416 bool foundAction = false; 419 bool foundAction = false;
417 OContact::journal_action action = OContact::ACTION_ADD; 420 OContact::journal_action action = OContact::ACTION_ADD;
418 int journalKey = 0; 421 int journalKey = 0;
419 QMap<int, QString> contactMap; 422 QMap<int, QString> contactMap;
420 QMap<QString, QString> customMap; 423 QMap<QString, QString> customMap;
421 QMap<QString, QString>::Iterator customIt; 424 QMap<QString, QString>::Iterator customIt;
422 QAsciiDict<int> dict( 47 ); 425 QAsciiDict<int> dict( 47 );
423 426
424 dict.setAutoDelete( TRUE ); 427 dict.setAutoDelete( TRUE );
425 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 428 dict.insert( "Uid", new int(Qtopia::AddressUid) );
426 dict.insert( "Title", new int(Qtopia::Title) ); 429 dict.insert( "Title", new int(Qtopia::Title) );
427 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 430 dict.insert( "FirstName", new int(Qtopia::FirstName) );
428 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 431 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
429 dict.insert( "LastName", new int(Qtopia::LastName) ); 432 dict.insert( "LastName", new int(Qtopia::LastName) );
430 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 433 dict.insert( "Suffix", new int(Qtopia::Suffix) );
431 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 434 dict.insert( "FileAs", new int(Qtopia::FileAs) );
432 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 435 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
433 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 436 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
434 dict.insert( "Emails", new int(Qtopia::Emails) ); 437 dict.insert( "Emails", new int(Qtopia::Emails) );
435 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 438 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
436 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 439 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
437 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 440 dict.insert( "HomeState", new int(Qtopia::HomeState) );
438 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 441 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
439 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 442 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
440 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 443 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
441 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 444 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
442 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 445 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
443 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 446 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
444 dict.insert( "Company", new int(Qtopia::Company) ); 447 dict.insert( "Company", new int(Qtopia::Company) );
445 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 448 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
446 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 449 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
447 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 450 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
448 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 451 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
449 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 452 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
450 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 453 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
451 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 454 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
index adc8dc3..ae6ec9e 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
@@ -1,147 +1,150 @@
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.8 2002/11/14 17:04:24 eilers
21 * Sorting will now work if fullname is identical on some entries
22 *
20 * Revision 1.7 2002/11/13 15:02:46 eilers 23 * Revision 1.7 2002/11/13 15:02:46 eilers
21 * Small Bug in sorted fixed 24 * Small Bug in sorted fixed
22 * 25 *
23 * Revision 1.6 2002/11/13 14:14:51 eilers 26 * Revision 1.6 2002/11/13 14:14:51 eilers
24 * Added sorted for Contacts.. 27 * Added sorted for Contacts..
25 * 28 *
26 * Revision 1.5 2002/11/01 15:10:42 eilers 29 * Revision 1.5 2002/11/01 15:10:42 eilers
27 * Added regExp-search in database for all fields in a contact. 30 * Added regExp-search in database for all fields in a contact.
28 * 31 *
29 * Revision 1.4 2002/10/16 10:52:40 eilers 32 * Revision 1.4 2002/10/16 10:52:40 eilers
30 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 33 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
31 * 34 *
32 * Revision 1.3 2002/10/14 16:21:54 eilers 35 * Revision 1.3 2002/10/14 16:21:54 eilers
33 * Some minor interface updates 36 * Some minor interface updates
34 * 37 *
35 * Revision 1.2 2002/10/07 17:34:24 eilers 38 * Revision 1.2 2002/10/07 17:34:24 eilers
36 * added OBackendFactory for advanced backend access 39 * added OBackendFactory for advanced backend access
37 * 40 *
38 * Revision 1.1 2002/09/27 17:11:44 eilers 41 * Revision 1.1 2002/09/27 17:11:44 eilers
39 * Added API for accessing the Contact-Database ! It is compiling, but 42 * Added API for accessing the Contact-Database ! It is compiling, but
40 * please do not expect that anything is working ! 43 * please do not expect that anything is working !
41 * I will debug that stuff in the next time .. 44 * I will debug that stuff in the next time ..
42 * Please read README_COMPILE for compiling ! 45 * Please read README_COMPILE for compiling !
43 * 46 *
44 * 47 *
45 */ 48 */
46 49
47#ifndef _OContactAccessBackend_XML_ 50#ifndef _OContactAccessBackend_XML_
48#define _OContactAccessBackend_XML_ 51#define _OContactAccessBackend_XML_
49 52
50#include <qasciidict.h> 53#include <qasciidict.h>
51#include <qdatetime.h> 54#include <qdatetime.h>
52#include <qfile.h> 55#include <qfile.h>
53#include <qfileinfo.h> 56#include <qfileinfo.h>
54#include <qregexp.h> 57#include <qregexp.h>
55#include <qarray.h> 58#include <qarray.h>
56#include <qmap.h> 59#include <qmap.h>
57 60
58#include <qpe/global.h> 61#include <qpe/global.h>
59 62
60#include <opie/xmltree.h> 63#include <opie/xmltree.h>
61#include "ocontactaccessbackend.h" 64#include "ocontactaccessbackend.h"
62#include "ocontactaccess.h" 65#include "ocontactaccess.h"
63 66
64#include <stdlib.h> 67#include <stdlib.h>
65#include <errno.h> 68#include <errno.h>
66 69
67using namespace Opie; 70using namespace Opie;
68 71
69/* the default xml implementation */ 72/* the default xml implementation */
70class OContactAccessBackend_XML : public OContactAccessBackend { 73class OContactAccessBackend_XML : public OContactAccessBackend {
71 public: 74 public:
72 OContactAccessBackend_XML ( QString appname, QString filename = 0l ): 75 OContactAccessBackend_XML ( QString appname, QString filename = 0l ):
73 m_changed( false ) 76 m_changed( false )
74 { 77 {
75 m_appName = appname; 78 m_appName = appname;
76 79
77 /* Set journalfile name ... */ 80 /* Set journalfile name ... */
78 m_journalName = getenv("HOME"); 81 m_journalName = getenv("HOME");
79 m_journalName +="/.abjournal" + appname; 82 m_journalName +="/.abjournal" + appname;
80 83
81 /* Expecting to access the default filename if nothing else is set */ 84 /* Expecting to access the default filename if nothing else is set */
82 if ( filename.isEmpty() ){ 85 if ( filename.isEmpty() ){
83 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 86 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
84 } else 87 } else
85 m_fileName = filename; 88 m_fileName = filename;
86 89
87 /* Load Database now */ 90 /* Load Database now */
88 load (); 91 load ();
89 } 92 }
90 93
91 bool save() { 94 bool save() {
92 95
93 if ( !m_changed ) 96 if ( !m_changed )
94 return true; 97 return true;
95 98
96 QString strNewFile = m_fileName + ".new"; 99 QString strNewFile = m_fileName + ".new";
97 QFile f( strNewFile ); 100 QFile f( strNewFile );
98 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 101 if ( !f.open( IO_WriteOnly|IO_Raw ) )
99 return false; 102 return false;
100 103
101 int total_written; 104 int total_written;
102 QString out; 105 QString out;
103 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 106 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
104 " <Groups>\n" 107 " <Groups>\n"
105 " </Groups>\n" 108 " </Groups>\n"
106 " <Contacts>\n"; 109 " <Contacts>\n";
107 //QValueList<Contact>::iterator it; 110 //QValueList<Contact>::iterator it;
108 QValueListConstIterator<OContact> it; 111 QValueListConstIterator<OContact> it;
109 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) { 112 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) {
110 out += "<Contact "; 113 out += "<Contact ";
111 (*it).save( out ); 114 (*it).save( out );
112 out += "/>\n"; 115 out += "/>\n";
113 QCString cstr = out.utf8(); 116 QCString cstr = out.utf8();
114 total_written = f.writeBlock( cstr.data(), cstr.length() ); 117 total_written = f.writeBlock( cstr.data(), cstr.length() );
115 if ( total_written != int(cstr.length()) ) { 118 if ( total_written != int(cstr.length()) ) {
116 f.close(); 119 f.close();
117 QFile::remove( strNewFile ); 120 QFile::remove( strNewFile );
118 return false; 121 return false;
119 } 122 }
120 out = ""; 123 out = "";
121 } 124 }
122 out += " </Contacts>\n</AddressBook>\n"; 125 out += " </Contacts>\n</AddressBook>\n";
123 126
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 f.close(); 134 f.close();
132 135
133 // move the file over, I'm just going to use the system call 136 // move the file over, I'm just going to use the system call
134 // because, I don't feel like using QDir. 137 // because, I don't feel like using QDir.
135 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 138 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
136 qWarning( "problem renaming file %s to %s, errno: %d", 139 qWarning( "problem renaming file %s to %s, errno: %d",
137 strNewFile.latin1(), m_journalName.latin1(), errno ); 140 strNewFile.latin1(), m_journalName.latin1(), errno );
138 // remove the tmp file... 141 // remove the tmp file...
139 QFile::remove( strNewFile ); 142 QFile::remove( strNewFile );
140 } 143 }
141 144
142 /* The journalfile should be removed now... */ 145 /* The journalfile should be removed now... */
143 removeJournal(); 146 removeJournal();
144 147
145 m_changed = false; 148 m_changed = false;
146 return true; 149 return true;
147 } 150 }
@@ -194,258 +197,258 @@ class OContactAccessBackend_XML : public OContactAccessBackend {
194 { 197 {
195 bool found = false; 198 bool found = false;
196 OContact foundContact; //Create empty contact 199 OContact foundContact; //Create empty contact
197 200
198 QValueListConstIterator<OContact> it; 201 QValueListConstIterator<OContact> it;
199 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 202 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
200 if ((*it).uid() == uid){ 203 if ((*it).uid() == uid){
201 found = true; 204 found = true;
202 break; 205 break;
203 } 206 }
204 } 207 }
205 if ( found ){ 208 if ( found ){
206 foundContact = *it; 209 foundContact = *it;
207 } 210 }
208 211
209 return ( foundContact ); 212 return ( foundContact );
210 } 213 }
211 214
212 QArray<int> queryByExample ( const OContact &query, int settings ){ 215 QArray<int> queryByExample ( const OContact &query, int settings ){
213 216
214 QArray<int> m_currentQuery( m_contactList.count() ); 217 QArray<int> m_currentQuery( m_contactList.count() );
215 QValueListConstIterator<OContact> it; 218 QValueListConstIterator<OContact> it;
216 uint arraycounter = 0; 219 uint arraycounter = 0;
217 220
218 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 221 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
219 /* Search all fields and compare them with query object. Store them into list 222 /* Search all fields and compare them with query object. Store them into list
220 * if all fields matches. 223 * if all fields matches.
221 */ 224 */
222 bool allcorrect = true; 225 bool allcorrect = true;
223 for ( int i = 0; i < Qtopia::rid; i++ ) { 226 for ( int i = 0; i < Qtopia::rid; i++ ) {
224 /* Just compare fields which are not empty in the query object */ 227 /* Just compare fields which are not empty in the query object */
225 if ( !query.field(i).isEmpty() ){ 228 if ( !query.field(i).isEmpty() ){
226 switch ( settings & ~OContactAccess::IgnoreCase ){ 229 switch ( settings & ~OContactAccess::IgnoreCase ){
227 case OContactAccess::RegExp:{ 230 case OContactAccess::RegExp:{
228 QRegExp expr ( query.field(i), 231 QRegExp expr ( query.field(i),
229 !(settings & OContactAccess::IgnoreCase), 232 !(settings & OContactAccess::IgnoreCase),
230 false ); 233 false );
231 if ( expr.find ( (*it).field(i), 0 ) == -1 ) 234 if ( expr.find ( (*it).field(i), 0 ) == -1 )
232 allcorrect = false; 235 allcorrect = false;
233 } 236 }
234 break; 237 break;
235 case OContactAccess::WildCards:{ 238 case OContactAccess::WildCards:{
236 QRegExp expr ( query.field(i), 239 QRegExp expr ( query.field(i),
237 !(settings & OContactAccess::IgnoreCase), 240 !(settings & OContactAccess::IgnoreCase),
238 true ); 241 true );
239 if ( expr.find ( (*it).field(i), 0 ) == -1 ) 242 if ( expr.find ( (*it).field(i), 0 ) == -1 )
240 allcorrect = false; 243 allcorrect = false;
241 } 244 }
242 break; 245 break;
243 case OContactAccess::ExactMatch:{ 246 case OContactAccess::ExactMatch:{
244 if (settings & OContactAccess::IgnoreCase){ 247 if (settings & OContactAccess::IgnoreCase){
245 if ( query.field(i).upper() != 248 if ( query.field(i).upper() !=
246 (*it).field(i).upper() ) 249 (*it).field(i).upper() )
247 allcorrect = false; 250 allcorrect = false;
248 }else{ 251 }else{
249 if ( query.field(i) != (*it).field(i) ) 252 if ( query.field(i) != (*it).field(i) )
250 allcorrect = false; 253 allcorrect = false;
251 } 254 }
252 } 255 }
253 break; 256 break;
254 } 257 }
255 } 258 }
256 } 259 }
257 if ( allcorrect ){ 260 if ( allcorrect ){
258 m_currentQuery[arraycounter++] = (*it).uid(); 261 m_currentQuery[arraycounter++] = (*it).uid();
259 } 262 }
260 } 263 }
261 264
262 // Shrink to fit.. 265 // Shrink to fit..
263 m_currentQuery.resize(arraycounter); 266 m_currentQuery.resize(arraycounter);
264 267
265 return m_currentQuery; 268 return m_currentQuery;
266 } 269 }
267 270
268 QArray<int> matchRegexp( const QRegExp &r ) const{ 271 QArray<int> matchRegexp( const QRegExp &r ) const{
269 QArray<int> m_currentQuery( m_contactList.count() ); 272 QArray<int> m_currentQuery( m_contactList.count() );
270 QValueListConstIterator<OContact> it; 273 QValueListConstIterator<OContact> it;
271 uint arraycounter = 0; 274 uint arraycounter = 0;
272 275
273 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 276 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
274 if ( (*it).match( r ) ){ 277 if ( (*it).match( r ) ){
275 m_currentQuery[arraycounter++] = (*it).uid(); 278 m_currentQuery[arraycounter++] = (*it).uid();
276 } 279 }
277 280
278 } 281 }
279 // Shrink to fit.. 282 // Shrink to fit..
280 m_currentQuery.resize(arraycounter); 283 m_currentQuery.resize(arraycounter);
281 284
282 return m_currentQuery; 285 return m_currentQuery;
283 } 286 }
284 287
285 const uint querySettings() 288 const uint querySettings()
286 { 289 {
287 return ( OContactAccess::WildCards 290 return ( OContactAccess::WildCards
288 & OContactAccess::IgnoreCase 291 & OContactAccess::IgnoreCase
289 & OContactAccess::RegExp 292 & OContactAccess::RegExp
290 & OContactAccess::ExactMatch ); 293 & OContactAccess::ExactMatch );
291 } 294 }
292 295
293 bool hasQuerySettings (uint querySettings) const 296 bool hasQuerySettings (uint querySettings) const
294 { 297 {
295 /* OContactAccess::IgnoreCase may be added with one 298 /* OContactAccess::IgnoreCase may be added with one
296 * of the other settings, but never used alone. 299 * of the other settings, but never used alone.
297 * The other settings are just valid alone... 300 * The other settings are just valid alone...
298 */ 301 */
299 switch ( querySettings & ~OContactAccess::IgnoreCase ){ 302 switch ( querySettings & ~OContactAccess::IgnoreCase ){
300 case OContactAccess::RegExp: 303 case OContactAccess::RegExp:
301 return ( true ); 304 return ( true );
302 case OContactAccess::WildCards: 305 case OContactAccess::WildCards:
303 return ( true ); 306 return ( true );
304 case OContactAccess::ExactMatch: 307 case OContactAccess::ExactMatch:
305 return ( true ); 308 return ( true );
306 default: 309 default:
307 return ( false ); 310 return ( false );
308 } 311 }
309 } 312 }
310 313
311 // Currently only asc implemented.. 314 // Currently only asc implemented..
312 QArray<int> sorted( bool asc, int , int , int ) 315 QArray<int> sorted( bool asc, int , int , int )
313 { 316 {
314 QMap<QString, int> nameToUid; 317 QMap<QString, int> nameToUid;
315 QStringList names; 318 QStringList names;
316 QArray<int> m_currentQuery( m_contactList.count() ); 319 QArray<int> m_currentQuery( m_contactList.count() );
317 320
318 // First fill map and StringList with all Names 321 // First fill map and StringList with all Names
319 // Afterwards sort namelist and use map to fill array to return.. 322 // Afterwards sort namelist and use map to fill array to return..
320 QValueListConstIterator<OContact> it; 323 QValueListConstIterator<OContact> it;
321 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 324 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
322 names.append( (*it).fileAs() ); 325 names.append( (*it).fileAs() + QString::number( (*it).uid() ) );
323 nameToUid.insert( (*it).fileAs(), (*it).uid() ); 326 nameToUid.insert( (*it).fileAs() + QString::number( (*it).uid() ), (*it).uid() );
324 } 327 }
325 names.sort(); 328 names.sort();
326 329
327 int i = 0; 330 int i = 0;
328 if ( asc ){ 331 if ( asc ){
329 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 332 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
330 m_currentQuery[i++] = nameToUid[ (*it) ]; 333 m_currentQuery[i++] = nameToUid[ (*it) ];
331 }else{ 334 }else{
332 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 335 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
333 m_currentQuery[i++] = nameToUid[ (*it) ]; 336 m_currentQuery[i++] = nameToUid[ (*it) ];
334 } 337 }
335 338
336 return m_currentQuery; 339 return m_currentQuery;
337 340
338 } 341 }
339 bool add ( const OContact &newcontact ) 342 bool add ( const OContact &newcontact )
340 { 343 {
341 //qWarning("odefaultbackend: ACTION::ADD"); 344 //qWarning("odefaultbackend: ACTION::ADD");
342 updateJournal (newcontact, OContact::ACTION_ADD); 345 updateJournal (newcontact, OContact::ACTION_ADD);
343 addContact_p( newcontact ); 346 addContact_p( newcontact );
344 347
345 m_changed = true; 348 m_changed = true;
346 349
347 return true; 350 return true;
348 } 351 }
349 352
350 bool replace ( const OContact &contact ) 353 bool replace ( const OContact &contact )
351 { 354 {
352 m_changed = true; 355 m_changed = true;
353 356
354 bool found = false; 357 bool found = false;
355 358
356 QValueListIterator<OContact> it; 359 QValueListIterator<OContact> it;
357 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 360 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
358 if ( (*it).uid() == contact.uid() ){ 361 if ( (*it).uid() == contact.uid() ){
359 found = true; 362 found = true;
360 break; 363 break;
361 } 364 }
362 } 365 }
363 if (found) { 366 if (found) {
364 updateJournal (contact, OContact::ACTION_REPLACE); 367 updateJournal (contact, OContact::ACTION_REPLACE);
365 m_contactList.remove (it); 368 m_contactList.remove (it);
366 m_contactList.append (contact); 369 m_contactList.append (contact);
367 return true; 370 return true;
368 } else 371 } else
369 return false; 372 return false;
370 } 373 }
371 374
372 bool remove ( int uid ) 375 bool remove ( int uid )
373 { 376 {
374 m_changed = true; 377 m_changed = true;
375 378
376 bool found = false; 379 bool found = false;
377 QValueListIterator<OContact> it; 380 QValueListIterator<OContact> it;
378 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 381 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
379 if ((*it).uid() == uid){ 382 if ((*it).uid() == uid){
380 found = true; 383 found = true;
381 break; 384 break;
382 } 385 }
383 } 386 }
384 if (found) { 387 if (found) {
385 updateJournal ( *it, OContact::ACTION_REMOVE); 388 updateJournal ( *it, OContact::ACTION_REMOVE);
386 m_contactList.remove (it); 389 m_contactList.remove (it);
387 return true; 390 return true;
388 } else 391 } else
389 return false; 392 return false;
390 } 393 }
391 394
392 bool reload(){ 395 bool reload(){
393 /* Reload is the same as load in this implementation */ 396 /* Reload is the same as load in this implementation */
394 return ( load() ); 397 return ( load() );
395 } 398 }
396 399
397 private: 400 private:
398 void addContact_p( const OContact &newcontact ){ 401 void addContact_p( const OContact &newcontact ){
399 m_contactList.append (newcontact); 402 m_contactList.append (newcontact);
400 } 403 }
401 404
402 /* This function loads the xml-database and the journalfile */ 405 /* This function loads the xml-database and the journalfile */
403 bool load( const QString filename, bool isJournal ) { 406 bool load( const QString filename, bool isJournal ) {
404 407
405 /* We use the time of the last read to check if the file was 408 /* We use the time of the last read to check if the file was
406 * changed externally. 409 * changed externally.
407 */ 410 */
408 if ( !isJournal ){ 411 if ( !isJournal ){
409 QFileInfo fi( filename ); 412 QFileInfo fi( filename );
410 m_readtime = fi.lastModified (); 413 m_readtime = fi.lastModified ();
411 } 414 }
412 415
413 const int JOURNALACTION = Qtopia::Notes + 1; 416 const int JOURNALACTION = Qtopia::Notes + 1;
414 const int JOURNALROW = JOURNALACTION + 1; 417 const int JOURNALROW = JOURNALACTION + 1;
415 418
416 bool foundAction = false; 419 bool foundAction = false;
417 OContact::journal_action action = OContact::ACTION_ADD; 420 OContact::journal_action action = OContact::ACTION_ADD;
418 int journalKey = 0; 421 int journalKey = 0;
419 QMap<int, QString> contactMap; 422 QMap<int, QString> contactMap;
420 QMap<QString, QString> customMap; 423 QMap<QString, QString> customMap;
421 QMap<QString, QString>::Iterator customIt; 424 QMap<QString, QString>::Iterator customIt;
422 QAsciiDict<int> dict( 47 ); 425 QAsciiDict<int> dict( 47 );
423 426
424 dict.setAutoDelete( TRUE ); 427 dict.setAutoDelete( TRUE );
425 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 428 dict.insert( "Uid", new int(Qtopia::AddressUid) );
426 dict.insert( "Title", new int(Qtopia::Title) ); 429 dict.insert( "Title", new int(Qtopia::Title) );
427 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 430 dict.insert( "FirstName", new int(Qtopia::FirstName) );
428 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 431 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
429 dict.insert( "LastName", new int(Qtopia::LastName) ); 432 dict.insert( "LastName", new int(Qtopia::LastName) );
430 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 433 dict.insert( "Suffix", new int(Qtopia::Suffix) );
431 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 434 dict.insert( "FileAs", new int(Qtopia::FileAs) );
432 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 435 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
433 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 436 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
434 dict.insert( "Emails", new int(Qtopia::Emails) ); 437 dict.insert( "Emails", new int(Qtopia::Emails) );
435 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 438 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
436 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 439 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
437 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 440 dict.insert( "HomeState", new int(Qtopia::HomeState) );
438 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 441 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
439 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 442 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
440 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 443 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
441 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 444 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
442 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 445 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
443 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 446 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
444 dict.insert( "Company", new int(Qtopia::Company) ); 447 dict.insert( "Company", new int(Qtopia::Company) );
445 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 448 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
446 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 449 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
447 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 450 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
448 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 451 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
449 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 452 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
450 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 453 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
451 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 454 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );