summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.cpp5
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp5
2 files changed, 8 insertions, 2 deletions
diff --git a/libopie/pim/ocontactaccessbackend_xml.cpp b/libopie/pim/ocontactaccessbackend_xml.cpp
index 9fe3d1e..c5a7820 100644
--- a/libopie/pim/ocontactaccessbackend_xml.cpp
+++ b/libopie/pim/ocontactaccessbackend_xml.cpp
@@ -1,781 +1,784 @@
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.4 2003/03/21 14:32:54 mickeyl
21 * g++ compliance fix: default arguments belong into the declaration, but not the definition
22 *
20 * Revision 1.3 2003/03/21 12:26:28 eilers 23 * Revision 1.3 2003/03/21 12:26:28 eilers
21 * Fixing small bug: If we search a birthday from today to today, it returned 24 * Fixing small bug: If we search a birthday from today to today, it returned
22 * every contact .. 25 * every contact ..
23 * 26 *
24 * Revision 1.2 2003/03/21 10:33:09 eilers 27 * Revision 1.2 2003/03/21 10:33:09 eilers
25 * Merged speed optimized xml backend for contacts to main. 28 * Merged speed optimized xml backend for contacts to main.
26 * Added QDateTime to querybyexample. For instance, it is now possible to get 29 * Added QDateTime to querybyexample. For instance, it is now possible to get
27 * all Birthdays/Anniversaries between two dates. This should be used 30 * all Birthdays/Anniversaries between two dates. This should be used
28 * to show all birthdays in the datebook.. 31 * to show all birthdays in the datebook..
29 * This change is sourcecode backward compatible but you have to upgrade 32 * This change is sourcecode backward compatible but you have to upgrade
30 * the binaries for today-addressbook. 33 * the binaries for today-addressbook.
31 * 34 *
32 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers 35 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers
33 * Speed optimization. Removed the sequential search loops. 36 * Speed optimization. Removed the sequential search loops.
34 * 37 *
35 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers 38 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers
36 * Writing offsets to debug output.. 39 * Writing offsets to debug output..
37 * 40 *
38 * Revision 1.1 2003/02/09 15:05:01 eilers 41 * Revision 1.1 2003/02/09 15:05:01 eilers
39 * Nothing happened.. Just some cleanup before I will start.. 42 * Nothing happened.. Just some cleanup before I will start..
40 * 43 *
41 * Revision 1.12 2003/01/03 16:58:03 eilers 44 * Revision 1.12 2003/01/03 16:58:03 eilers
42 * Reenable debug output 45 * Reenable debug output
43 * 46 *
44 * Revision 1.11 2003/01/03 12:31:28 eilers 47 * Revision 1.11 2003/01/03 12:31:28 eilers
45 * Bugfix for calculating data diffs.. 48 * Bugfix for calculating data diffs..
46 * 49 *
47 * Revision 1.10 2003/01/02 14:27:12 eilers 50 * Revision 1.10 2003/01/02 14:27:12 eilers
48 * Improved query by example: Search by date is possible.. First step 51 * Improved query by example: Search by date is possible.. First step
49 * for a today plugin for birthdays.. 52 * for a today plugin for birthdays..
50 * 53 *
51 * Revision 1.9 2002/12/08 12:48:57 eilers 54 * Revision 1.9 2002/12/08 12:48:57 eilers
52 * Moved journal-enum from ocontact into i the xml-backend.. 55 * Moved journal-enum from ocontact into i the xml-backend..
53 * 56 *
54 * Revision 1.8 2002/11/14 17:04:24 eilers 57 * Revision 1.8 2002/11/14 17:04:24 eilers
55 * Sorting will now work if fullname is identical on some entries 58 * Sorting will now work if fullname is identical on some entries
56 * 59 *
57 * Revision 1.7 2002/11/13 15:02:46 eilers 60 * Revision 1.7 2002/11/13 15:02:46 eilers
58 * Small Bug in sorted fixed 61 * Small Bug in sorted fixed
59 * 62 *
60 * Revision 1.6 2002/11/13 14:14:51 eilers 63 * Revision 1.6 2002/11/13 14:14:51 eilers
61 * Added sorted for Contacts.. 64 * Added sorted for Contacts..
62 * 65 *
63 * Revision 1.5 2002/11/01 15:10:42 eilers 66 * Revision 1.5 2002/11/01 15:10:42 eilers
64 * Added regExp-search in database for all fields in a contact. 67 * Added regExp-search in database for all fields in a contact.
65 * 68 *
66 * Revision 1.4 2002/10/16 10:52:40 eilers 69 * Revision 1.4 2002/10/16 10:52:40 eilers
67 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 70 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
68 * 71 *
69 * Revision 1.3 2002/10/14 16:21:54 eilers 72 * Revision 1.3 2002/10/14 16:21:54 eilers
70 * Some minor interface updates 73 * Some minor interface updates
71 * 74 *
72 * Revision 1.2 2002/10/07 17:34:24 eilers 75 * Revision 1.2 2002/10/07 17:34:24 eilers
73 * added OBackendFactory for advanced backend access 76 * added OBackendFactory for advanced backend access
74 * 77 *
75 * Revision 1.1 2002/09/27 17:11:44 eilers 78 * Revision 1.1 2002/09/27 17:11:44 eilers
76 * Added API for accessing the Contact-Database ! It is compiling, but 79 * Added API for accessing the Contact-Database ! It is compiling, but
77 * please do not expect that anything is working ! 80 * please do not expect that anything is working !
78 * I will debug that stuff in the next time .. 81 * I will debug that stuff in the next time ..
79 * Please read README_COMPILE for compiling ! 82 * Please read README_COMPILE for compiling !
80 * 83 *
81 * 84 *
82 */ 85 */
83 86
84#include "ocontactaccessbackend_xml.h" 87#include "ocontactaccessbackend_xml.h"
85 88
86#include <qasciidict.h> 89#include <qasciidict.h>
87#include <qdatetime.h> 90#include <qdatetime.h>
88#include <qfile.h> 91#include <qfile.h>
89#include <qfileinfo.h> 92#include <qfileinfo.h>
90#include <qregexp.h> 93#include <qregexp.h>
91#include <qarray.h> 94#include <qarray.h>
92#include <qmap.h> 95#include <qmap.h>
93#include <qdatetime.h> 96#include <qdatetime.h>
94 97
95#include <qpe/global.h> 98#include <qpe/global.h>
96 99
97#include <opie/xmltree.h> 100#include <opie/xmltree.h>
98#include "ocontactaccessbackend.h" 101#include "ocontactaccessbackend.h"
99#include "ocontactaccess.h" 102#include "ocontactaccess.h"
100 103
101#include <stdlib.h> 104#include <stdlib.h>
102#include <errno.h> 105#include <errno.h>
103 106
104using namespace Opie; 107using namespace Opie;
105 108
106 109
107OContactAccessBackend_XML::OContactAccessBackend_XML ( QString appname, QString filename = 0l ): 110OContactAccessBackend_XML::OContactAccessBackend_XML ( QString appname, QString filename ):
108 m_changed( false ) 111 m_changed( false )
109{ 112{
110 // Just m_contactlist should call delete if an entry 113 // Just m_contactlist should call delete if an entry
111 // is removed. 114 // is removed.
112 m_contactList.setAutoDelete( true ); 115 m_contactList.setAutoDelete( true );
113 m_uidToContact.setAutoDelete( false ); 116 m_uidToContact.setAutoDelete( false );
114 117
115 m_appName = appname; 118 m_appName = appname;
116 119
117 /* Set journalfile name ... */ 120 /* Set journalfile name ... */
118 m_journalName = getenv("HOME"); 121 m_journalName = getenv("HOME");
119 m_journalName +="/.abjournal" + appname; 122 m_journalName +="/.abjournal" + appname;
120 123
121 /* Expecting to access the default filename if nothing else is set */ 124 /* Expecting to access the default filename if nothing else is set */
122 if ( filename.isEmpty() ){ 125 if ( filename.isEmpty() ){
123 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 126 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
124 } else 127 } else
125 m_fileName = filename; 128 m_fileName = filename;
126 129
127 /* Load Database now */ 130 /* Load Database now */
128 load (); 131 load ();
129} 132}
130 133
131bool OContactAccessBackend_XML::save() 134bool OContactAccessBackend_XML::save()
132{ 135{
133 136
134 if ( !m_changed ) 137 if ( !m_changed )
135 return true; 138 return true;
136 139
137 QString strNewFile = m_fileName + ".new"; 140 QString strNewFile = m_fileName + ".new";
138 QFile f( strNewFile ); 141 QFile f( strNewFile );
139 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 142 if ( !f.open( IO_WriteOnly|IO_Raw ) )
140 return false; 143 return false;
141 144
142 int total_written; 145 int total_written;
143 int idx_offset = 0; 146 int idx_offset = 0;
144 QString out; 147 QString out;
145 148
146 // Write Header 149 // Write Header
147 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 150 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
148 " <Groups>\n" 151 " <Groups>\n"
149 " </Groups>\n" 152 " </Groups>\n"
150 " <Contacts>\n"; 153 " <Contacts>\n";
151 QCString cstr = out.utf8(); 154 QCString cstr = out.utf8();
152 f.writeBlock( cstr.data(), cstr.length() ); 155 f.writeBlock( cstr.data(), cstr.length() );
153 idx_offset += cstr.length(); 156 idx_offset += cstr.length();
154 out = ""; 157 out = "";
155 158
156 // Write all contacts 159 // Write all contacts
157 QListIterator<OContact> it( m_contactList ); 160 QListIterator<OContact> it( m_contactList );
158 for ( ; it.current(); ++it ) { 161 for ( ; it.current(); ++it ) {
159 qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); 162 qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset );
160 out += "<Contact "; 163 out += "<Contact ";
161 (*it)->save( out ); 164 (*it)->save( out );
162 out += "/>\n"; 165 out += "/>\n";
163 cstr = out.utf8(); 166 cstr = out.utf8();
164 total_written = f.writeBlock( cstr.data(), cstr.length() ); 167 total_written = f.writeBlock( cstr.data(), cstr.length() );
165 idx_offset += cstr.length(); 168 idx_offset += cstr.length();
166 if ( total_written != int(cstr.length()) ) { 169 if ( total_written != int(cstr.length()) ) {
167 f.close(); 170 f.close();
168 QFile::remove( strNewFile ); 171 QFile::remove( strNewFile );
169 return false; 172 return false;
170 } 173 }
171 out = ""; 174 out = "";
172 } 175 }
173 out += " </Contacts>\n</AddressBook>\n"; 176 out += " </Contacts>\n</AddressBook>\n";
174 177
175 // Write Footer 178 // Write Footer
176 cstr = out.utf8(); 179 cstr = out.utf8();
177 total_written = f.writeBlock( cstr.data(), cstr.length() ); 180 total_written = f.writeBlock( cstr.data(), cstr.length() );
178 if ( total_written != int( cstr.length() ) ) { 181 if ( total_written != int( cstr.length() ) ) {
179 f.close(); 182 f.close();
180 QFile::remove( strNewFile ); 183 QFile::remove( strNewFile );
181 return false; 184 return false;
182 } 185 }
183 f.close(); 186 f.close();
184 187
185 // move the file over, I'm just going to use the system call 188 // move the file over, I'm just going to use the system call
186 // because, I don't feel like using QDir. 189 // because, I don't feel like using QDir.
187 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 190 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
188 qWarning( "problem renaming file %s to %s, errno: %d", 191 qWarning( "problem renaming file %s to %s, errno: %d",
189 strNewFile.latin1(), m_journalName.latin1(), errno ); 192 strNewFile.latin1(), m_journalName.latin1(), errno );
190 // remove the tmp file... 193 // remove the tmp file...
191 QFile::remove( strNewFile ); 194 QFile::remove( strNewFile );
192 } 195 }
193 196
194 /* The journalfile should be removed now... */ 197 /* The journalfile should be removed now... */
195 removeJournal(); 198 removeJournal();
196 199
197 m_changed = false; 200 m_changed = false;
198 return true; 201 return true;
199} 202}
200 203
201bool OContactAccessBackend_XML::load () 204bool OContactAccessBackend_XML::load ()
202{ 205{
203 m_contactList.clear(); 206 m_contactList.clear();
204 m_uidToContact.clear(); 207 m_uidToContact.clear();
205 208
206 /* Load XML-File and journal if it exists */ 209 /* Load XML-File and journal if it exists */
207 if ( !load ( m_fileName, false ) ) 210 if ( !load ( m_fileName, false ) )
208 return false; 211 return false;
209 /* The returncode of the journalfile is ignored due to the 212 /* The returncode of the journalfile is ignored due to the
210 * fact that it does not exist when this class is instantiated ! 213 * fact that it does not exist when this class is instantiated !
211 * But there may such a file exist, if the application crashed. 214 * But there may such a file exist, if the application crashed.
212 * Therefore we try to load it to get the changes before the # 215 * Therefore we try to load it to get the changes before the #
213 * crash happened... 216 * crash happened...
214 */ 217 */
215 load (m_journalName, true); 218 load (m_journalName, true);
216 219
217 return true; 220 return true;
218} 221}
219 222
220void OContactAccessBackend_XML::clear () 223void OContactAccessBackend_XML::clear ()
221{ 224{
222 m_contactList.clear(); 225 m_contactList.clear();
223 m_uidToContact.clear(); 226 m_uidToContact.clear();
224 227
225 m_changed = false; 228 m_changed = false;
226} 229}
227 230
228bool OContactAccessBackend_XML::wasChangedExternally() 231bool OContactAccessBackend_XML::wasChangedExternally()
229{ 232{
230 QFileInfo fi( m_fileName ); 233 QFileInfo fi( m_fileName );
231 234
232 QDateTime lastmod = fi.lastModified (); 235 QDateTime lastmod = fi.lastModified ();
233 236
234 return (lastmod != m_readtime); 237 return (lastmod != m_readtime);
235} 238}
236 239
237QArray<int> OContactAccessBackend_XML::allRecords() const 240QArray<int> OContactAccessBackend_XML::allRecords() const
238{ 241{
239 QArray<int> uid_list( m_contactList.count() ); 242 QArray<int> uid_list( m_contactList.count() );
240 243
241 uint counter = 0; 244 uint counter = 0;
242 QListIterator<OContact> it( m_contactList ); 245 QListIterator<OContact> it( m_contactList );
243 for( ; it.current(); ++it ){ 246 for( ; it.current(); ++it ){
244 uid_list[counter++] = (*it)->uid(); 247 uid_list[counter++] = (*it)->uid();
245 } 248 }
246 249
247 return ( uid_list ); 250 return ( uid_list );
248} 251}
249 252
250OContact OContactAccessBackend_XML::find ( int uid ) const 253OContact OContactAccessBackend_XML::find ( int uid ) const
251{ 254{
252 OContact foundContact; //Create empty contact 255 OContact foundContact; //Create empty contact
253 256
254 OContact* found = m_uidToContact.find( QString().setNum( uid ) ); 257 OContact* found = m_uidToContact.find( QString().setNum( uid ) );
255 258
256 if ( found ){ 259 if ( found ){
257 foundContact = *found; 260 foundContact = *found;
258 } 261 }
259 262
260 return ( foundContact ); 263 return ( foundContact );
261} 264}
262 265
263QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings, 266QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings,
264 const QDateTime& d ) 267 const QDateTime& d )
265{ 268{
266 269
267 QArray<int> m_currentQuery( m_contactList.count() ); 270 QArray<int> m_currentQuery( m_contactList.count() );
268 QListIterator<OContact> it( m_contactList ); 271 QListIterator<OContact> it( m_contactList );
269 uint arraycounter = 0; 272 uint arraycounter = 0;
270 273
271 for( ; it.current(); ++it ){ 274 for( ; it.current(); ++it ){
272 /* Search all fields and compare them with query object. Store them into list 275 /* Search all fields and compare them with query object. Store them into list
273 * if all fields matches. 276 * if all fields matches.
274 */ 277 */
275 QDate* queryDate = 0l; 278 QDate* queryDate = 0l;
276 QDate* checkDate = 0l; 279 QDate* checkDate = 0l;
277 bool allcorrect = true; 280 bool allcorrect = true;
278 for ( int i = 0; i < Qtopia::Groups; i++ ) { 281 for ( int i = 0; i < Qtopia::Groups; i++ ) {
279 // Birthday and anniversary are special nonstring fields and should 282 // Birthday and anniversary are special nonstring fields and should
280 // be handled specially 283 // be handled specially
281 switch ( i ){ 284 switch ( i ){
282 case Qtopia::Birthday: 285 case Qtopia::Birthday:
283 queryDate = new QDate( query.birthday() ); 286 queryDate = new QDate( query.birthday() );
284 checkDate = new QDate( (*it)->birthday() ); 287 checkDate = new QDate( (*it)->birthday() );
285 case Qtopia::Anniversary: 288 case Qtopia::Anniversary:
286 if ( queryDate == 0l ){ 289 if ( queryDate == 0l ){
287 queryDate = new QDate( query.anniversary() ); 290 queryDate = new QDate( query.anniversary() );
288 checkDate = new QDate( (*it)->anniversary() ); 291 checkDate = new QDate( (*it)->anniversary() );
289 } 292 }
290 293
291 if ( queryDate->isValid() ){ 294 if ( queryDate->isValid() ){
292 if( checkDate->isValid() ){ 295 if( checkDate->isValid() ){
293 if ( settings & OContactAccess::DateYear ){ 296 if ( settings & OContactAccess::DateYear ){
294 if ( queryDate->year() != checkDate->year() ) 297 if ( queryDate->year() != checkDate->year() )
295 allcorrect = false; 298 allcorrect = false;
296 } 299 }
297 if ( settings & OContactAccess::DateMonth ){ 300 if ( settings & OContactAccess::DateMonth ){
298 if ( queryDate->month() != checkDate->month() ) 301 if ( queryDate->month() != checkDate->month() )
299 allcorrect = false; 302 allcorrect = false;
300 } 303 }
301 if ( settings & OContactAccess::DateDay ){ 304 if ( settings & OContactAccess::DateDay ){
302 if ( queryDate->day() != checkDate->day() ) 305 if ( queryDate->day() != checkDate->day() )
303 allcorrect = false; 306 allcorrect = false;
304 } 307 }
305 if ( settings & OContactAccess::DateDiff ) { 308 if ( settings & OContactAccess::DateDiff ) {
306 QDate current; 309 QDate current;
307 // If we get an additional date, we 310 // If we get an additional date, we
308 // will take this date instead of 311 // will take this date instead of
309 // the current one.. 312 // the current one..
310 if ( !d.date().isValid() ) 313 if ( !d.date().isValid() )
311 current = QDate::currentDate(); 314 current = QDate::currentDate();
312 else 315 else
313 current = d.date(); 316 current = d.date();
314 317
315 // We have to equalize the year, otherwise 318 // We have to equalize the year, otherwise
316 // the search will fail.. 319 // the search will fail..
317 checkDate->setYMD( current.year(), 320 checkDate->setYMD( current.year(),
318 checkDate->month(), 321 checkDate->month(),
319 checkDate->day() ); 322 checkDate->day() );
320 if ( *checkDate < current ) 323 if ( *checkDate < current )
321 checkDate->setYMD( current.year()+1, 324 checkDate->setYMD( current.year()+1,
322 checkDate->month(), 325 checkDate->month(),
323 checkDate->day() ); 326 checkDate->day() );
324 327
325 // Check whether the birthday/anniversary date is between 328 // Check whether the birthday/anniversary date is between
326 // the current/given date and the maximum date 329 // the current/given date and the maximum date
327 // ( maximum time range ) ! 330 // ( maximum time range ) !
328 qWarning("Checking if %s is between %s and %s ! ", 331 qWarning("Checking if %s is between %s and %s ! ",
329 checkDate->toString().latin1(), 332 checkDate->toString().latin1(),
330 current.toString().latin1(), 333 current.toString().latin1(),
331 queryDate->toString().latin1() ); 334 queryDate->toString().latin1() );
332 if ( current.daysTo( *queryDate ) >= 0 ){ 335 if ( current.daysTo( *queryDate ) >= 0 ){
333 if ( !( ( *checkDate >= current ) && 336 if ( !( ( *checkDate >= current ) &&
334 ( *checkDate <= *queryDate ) ) ){ 337 ( *checkDate <= *queryDate ) ) ){
335 allcorrect = false; 338 allcorrect = false;
336 qWarning (" Nope!.."); 339 qWarning (" Nope!..");
337 } 340 }
338 } 341 }
339 } 342 }
340 } else{ 343 } else{
341 // checkDate is invalid. Therefore this entry is always rejected 344 // checkDate is invalid. Therefore this entry is always rejected
342 allcorrect = false; 345 allcorrect = false;
343 } 346 }
344 } 347 }
345 348
346 delete queryDate; 349 delete queryDate;
347 queryDate = 0l; 350 queryDate = 0l;
348 delete checkDate; 351 delete checkDate;
349 checkDate = 0l; 352 checkDate = 0l;
350 break; 353 break;
351 default: 354 default:
352 /* Just compare fields which are not empty in the query object */ 355 /* Just compare fields which are not empty in the query object */
353 if ( !query.field(i).isEmpty() ){ 356 if ( !query.field(i).isEmpty() ){
354 switch ( settings & ~( OContactAccess::IgnoreCase 357 switch ( settings & ~( OContactAccess::IgnoreCase
355 | OContactAccess::DateDiff 358 | OContactAccess::DateDiff
356 | OContactAccess::DateYear 359 | OContactAccess::DateYear
357 | OContactAccess::DateMonth 360 | OContactAccess::DateMonth
358 | OContactAccess::DateDay 361 | OContactAccess::DateDay
359 | OContactAccess::MatchOne 362 | OContactAccess::MatchOne
360 ) ){ 363 ) ){
361 364
362 case OContactAccess::RegExp:{ 365 case OContactAccess::RegExp:{
363 QRegExp expr ( query.field(i), 366 QRegExp expr ( query.field(i),
364 !(settings & OContactAccess::IgnoreCase), 367 !(settings & OContactAccess::IgnoreCase),
365 false ); 368 false );
366 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 369 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
367 allcorrect = false; 370 allcorrect = false;
368 } 371 }
369 break; 372 break;
370 case OContactAccess::WildCards:{ 373 case OContactAccess::WildCards:{
371 QRegExp expr ( query.field(i), 374 QRegExp expr ( query.field(i),
372 !(settings & OContactAccess::IgnoreCase), 375 !(settings & OContactAccess::IgnoreCase),
373 true ); 376 true );
374 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 377 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
375 allcorrect = false; 378 allcorrect = false;
376 } 379 }
377 break; 380 break;
378 case OContactAccess::ExactMatch:{ 381 case OContactAccess::ExactMatch:{
379 if (settings & OContactAccess::IgnoreCase){ 382 if (settings & OContactAccess::IgnoreCase){
380 if ( query.field(i).upper() != 383 if ( query.field(i).upper() !=
381 (*it)->field(i).upper() ) 384 (*it)->field(i).upper() )
382 allcorrect = false; 385 allcorrect = false;
383 }else{ 386 }else{
384 if ( query.field(i) != (*it)->field(i) ) 387 if ( query.field(i) != (*it)->field(i) )
385 allcorrect = false; 388 allcorrect = false;
386 } 389 }
387 } 390 }
388 break; 391 break;
389 } 392 }
390 } 393 }
391 } 394 }
392 } 395 }
393 if ( allcorrect ){ 396 if ( allcorrect ){
394 m_currentQuery[arraycounter++] = (*it)->uid(); 397 m_currentQuery[arraycounter++] = (*it)->uid();
395 } 398 }
396 } 399 }
397 400
398 // Shrink to fit.. 401 // Shrink to fit..
399 m_currentQuery.resize(arraycounter); 402 m_currentQuery.resize(arraycounter);
400 403
401 return m_currentQuery; 404 return m_currentQuery;
402} 405}
403 406
404QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const 407QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
405{ 408{
406 QArray<int> m_currentQuery( m_contactList.count() ); 409 QArray<int> m_currentQuery( m_contactList.count() );
407 QListIterator<OContact> it( m_contactList ); 410 QListIterator<OContact> it( m_contactList );
408 uint arraycounter = 0; 411 uint arraycounter = 0;
409 412
410 for( ; it.current(); ++it ){ 413 for( ; it.current(); ++it ){
411 if ( (*it)->match( r ) ){ 414 if ( (*it)->match( r ) ){
412 m_currentQuery[arraycounter++] = (*it)->uid(); 415 m_currentQuery[arraycounter++] = (*it)->uid();
413 } 416 }
414 417
415 } 418 }
416 // Shrink to fit.. 419 // Shrink to fit..
417 m_currentQuery.resize(arraycounter); 420 m_currentQuery.resize(arraycounter);
418 421
419 return m_currentQuery; 422 return m_currentQuery;
420} 423}
421 424
422const uint OContactAccessBackend_XML::querySettings() 425const uint OContactAccessBackend_XML::querySettings()
423{ 426{
424 return ( OContactAccess::WildCards 427 return ( OContactAccess::WildCards
425 | OContactAccess::IgnoreCase 428 | OContactAccess::IgnoreCase
426 | OContactAccess::RegExp 429 | OContactAccess::RegExp
427 | OContactAccess::ExactMatch 430 | OContactAccess::ExactMatch
428 | OContactAccess::DateDiff 431 | OContactAccess::DateDiff
429 | OContactAccess::DateYear 432 | OContactAccess::DateYear
430 | OContactAccess::DateMonth 433 | OContactAccess::DateMonth
431 | OContactAccess::DateDay 434 | OContactAccess::DateDay
432 ); 435 );
433} 436}
434 437
435bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const 438bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const
436{ 439{
437 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 440 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
438 * may be added with any of the other settings. IgnoreCase should never used alone. 441 * may be added with any of the other settings. IgnoreCase should never used alone.
439 * Wildcards, RegExp, ExactMatch should never used at the same time... 442 * Wildcards, RegExp, ExactMatch should never used at the same time...
440 */ 443 */
441 444
442 if ( querySettings == OContactAccess::IgnoreCase ) 445 if ( querySettings == OContactAccess::IgnoreCase )
443 return false; 446 return false;
444 447
445 switch ( querySettings & ~( OContactAccess::IgnoreCase 448 switch ( querySettings & ~( OContactAccess::IgnoreCase
446 | OContactAccess::DateDiff 449 | OContactAccess::DateDiff
447 | OContactAccess::DateYear 450 | OContactAccess::DateYear
448 | OContactAccess::DateMonth 451 | OContactAccess::DateMonth
449 | OContactAccess::DateDay 452 | OContactAccess::DateDay
450 ) 453 )
451 ){ 454 ){
452 case OContactAccess::RegExp: 455 case OContactAccess::RegExp:
453 return ( true ); 456 return ( true );
454 case OContactAccess::WildCards: 457 case OContactAccess::WildCards:
455 return ( true ); 458 return ( true );
456 case OContactAccess::ExactMatch: 459 case OContactAccess::ExactMatch:
457 return ( true ); 460 return ( true );
458 default: 461 default:
459 return ( false ); 462 return ( false );
460 } 463 }
461} 464}
462 465
463// Currently only asc implemented.. 466// Currently only asc implemented..
464QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int ) 467QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int )
465{ 468{
466 QMap<QString, int> nameToUid; 469 QMap<QString, int> nameToUid;
467 QStringList names; 470 QStringList names;
468 QArray<int> m_currentQuery( m_contactList.count() ); 471 QArray<int> m_currentQuery( m_contactList.count() );
469 472
470 // First fill map and StringList with all Names 473 // First fill map and StringList with all Names
471 // Afterwards sort namelist and use map to fill array to return.. 474 // Afterwards sort namelist and use map to fill array to return..
472 QListIterator<OContact> it( m_contactList ); 475 QListIterator<OContact> it( m_contactList );
473 for( ; it.current(); ++it ){ 476 for( ; it.current(); ++it ){
474 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); 477 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) );
475 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); 478 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() );
476 } 479 }
477 names.sort(); 480 names.sort();
478 481
479 int i = 0; 482 int i = 0;
480 if ( asc ){ 483 if ( asc ){
481 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 484 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
482 m_currentQuery[i++] = nameToUid[ (*it) ]; 485 m_currentQuery[i++] = nameToUid[ (*it) ];
483 }else{ 486 }else{
484 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 487 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
485 m_currentQuery[i++] = nameToUid[ (*it) ]; 488 m_currentQuery[i++] = nameToUid[ (*it) ];
486 } 489 }
487 490
488 return m_currentQuery; 491 return m_currentQuery;
489 492
490} 493}
491 494
492bool OContactAccessBackend_XML::add ( const OContact &newcontact ) 495bool OContactAccessBackend_XML::add ( const OContact &newcontact )
493{ 496{
494 //qWarning("odefaultbackend: ACTION::ADD"); 497 //qWarning("odefaultbackend: ACTION::ADD");
495 updateJournal (newcontact, ACTION_ADD); 498 updateJournal (newcontact, ACTION_ADD);
496 addContact_p( newcontact ); 499 addContact_p( newcontact );
497 500
498 m_changed = true; 501 m_changed = true;
499 502
500 return true; 503 return true;
501} 504}
502 505
503bool OContactAccessBackend_XML::replace ( const OContact &contact ) 506bool OContactAccessBackend_XML::replace ( const OContact &contact )
504{ 507{
505 m_changed = true; 508 m_changed = true;
506 509
507 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); 510 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) );
508 511
509 if ( found ) { 512 if ( found ) {
510 OContact* newCont = new OContact( contact ); 513 OContact* newCont = new OContact( contact );
511 514
512 updateJournal ( *newCont, ACTION_REPLACE); 515 updateJournal ( *newCont, ACTION_REPLACE);
513 m_contactList.removeRef ( found ); 516 m_contactList.removeRef ( found );
514 m_contactList.append ( newCont ); 517 m_contactList.append ( newCont );
515 m_uidToContact.remove( QString().setNum( contact.uid() ) ); 518 m_uidToContact.remove( QString().setNum( contact.uid() ) );
516 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); 519 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont );
517 520
518 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); 521 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid());
519 522
520 return true; 523 return true;
521 } else 524 } else
522 return false; 525 return false;
523} 526}
524 527
525bool OContactAccessBackend_XML::remove ( int uid ) 528bool OContactAccessBackend_XML::remove ( int uid )
526{ 529{
527 m_changed = true; 530 m_changed = true;
528 531
529 OContact* found = m_uidToContact.find ( QString().setNum( uid ) ); 532 OContact* found = m_uidToContact.find ( QString().setNum( uid ) );
530 533
531 if ( found ) { 534 if ( found ) {
532 updateJournal ( *found, ACTION_REMOVE); 535 updateJournal ( *found, ACTION_REMOVE);
533 m_contactList.removeRef ( found ); 536 m_contactList.removeRef ( found );
534 m_uidToContact.remove( QString().setNum( uid ) ); 537 m_uidToContact.remove( QString().setNum( uid ) );
535 538
536 return true; 539 return true;
537 } else 540 } else
538 return false; 541 return false;
539} 542}
540 543
541bool OContactAccessBackend_XML::reload(){ 544bool OContactAccessBackend_XML::reload(){
542 /* Reload is the same as load in this implementation */ 545 /* Reload is the same as load in this implementation */
543 return ( load() ); 546 return ( load() );
544} 547}
545 548
546void OContactAccessBackend_XML::addContact_p( const OContact &newcontact ) 549void OContactAccessBackend_XML::addContact_p( const OContact &newcontact )
547{ 550{
548 OContact* contRef = new OContact( newcontact ); 551 OContact* contRef = new OContact( newcontact );
549 552
550 m_contactList.append ( contRef ); 553 m_contactList.append ( contRef );
551 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); 554 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef );
552} 555}
553 556
554/* This function loads the xml-database and the journalfile */ 557/* This function loads the xml-database and the journalfile */
555bool OContactAccessBackend_XML::load( const QString filename, bool isJournal ) 558bool OContactAccessBackend_XML::load( const QString filename, bool isJournal )
556{ 559{
557 560
558 /* We use the time of the last read to check if the file was 561 /* We use the time of the last read to check if the file was
559 * changed externally. 562 * changed externally.
560 */ 563 */
561 if ( !isJournal ){ 564 if ( !isJournal ){
562 QFileInfo fi( filename ); 565 QFileInfo fi( filename );
563 m_readtime = fi.lastModified (); 566 m_readtime = fi.lastModified ();
564 } 567 }
565 568
566 const int JOURNALACTION = Qtopia::Notes + 1; 569 const int JOURNALACTION = Qtopia::Notes + 1;
567 const int JOURNALROW = JOURNALACTION + 1; 570 const int JOURNALROW = JOURNALACTION + 1;
568 571
569 bool foundAction = false; 572 bool foundAction = false;
570 journal_action action = ACTION_ADD; 573 journal_action action = ACTION_ADD;
571 int journalKey = 0; 574 int journalKey = 0;
572 QMap<int, QString> contactMap; 575 QMap<int, QString> contactMap;
573 QMap<QString, QString> customMap; 576 QMap<QString, QString> customMap;
574 QMap<QString, QString>::Iterator customIt; 577 QMap<QString, QString>::Iterator customIt;
575 QAsciiDict<int> dict( 47 ); 578 QAsciiDict<int> dict( 47 );
576 579
577 dict.setAutoDelete( TRUE ); 580 dict.setAutoDelete( TRUE );
578 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 581 dict.insert( "Uid", new int(Qtopia::AddressUid) );
579 dict.insert( "Title", new int(Qtopia::Title) ); 582 dict.insert( "Title", new int(Qtopia::Title) );
580 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 583 dict.insert( "FirstName", new int(Qtopia::FirstName) );
581 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 584 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
582 dict.insert( "LastName", new int(Qtopia::LastName) ); 585 dict.insert( "LastName", new int(Qtopia::LastName) );
583 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 586 dict.insert( "Suffix", new int(Qtopia::Suffix) );
584 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 587 dict.insert( "FileAs", new int(Qtopia::FileAs) );
585 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 588 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
586 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 589 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
587 dict.insert( "Emails", new int(Qtopia::Emails) ); 590 dict.insert( "Emails", new int(Qtopia::Emails) );
588 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 591 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
589 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 592 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
590 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 593 dict.insert( "HomeState", new int(Qtopia::HomeState) );
591 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 594 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
592 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 595 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
593 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 596 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
594 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 597 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
595 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 598 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
596 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 599 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
597 dict.insert( "Company", new int(Qtopia::Company) ); 600 dict.insert( "Company", new int(Qtopia::Company) );
598 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 601 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
599 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 602 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
600 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 603 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
601 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 604 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
602 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 605 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
603 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 606 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
604 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 607 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
605 dict.insert( "Department", new int(Qtopia::Department) ); 608 dict.insert( "Department", new int(Qtopia::Department) );
606 dict.insert( "Office", new int(Qtopia::Office) ); 609 dict.insert( "Office", new int(Qtopia::Office) );
607 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); 610 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
608 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); 611 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
609 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); 612 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
610 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); 613 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
611 dict.insert( "Profession", new int(Qtopia::Profession) ); 614 dict.insert( "Profession", new int(Qtopia::Profession) );
612 dict.insert( "Assistant", new int(Qtopia::Assistant) ); 615 dict.insert( "Assistant", new int(Qtopia::Assistant) );
613 dict.insert( "Manager", new int(Qtopia::Manager) ); 616 dict.insert( "Manager", new int(Qtopia::Manager) );
614 dict.insert( "Spouse", new int(Qtopia::Spouse) ); 617 dict.insert( "Spouse", new int(Qtopia::Spouse) );
615 dict.insert( "Children", new int(Qtopia::Children) ); 618 dict.insert( "Children", new int(Qtopia::Children) );
616 dict.insert( "Gender", new int(Qtopia::Gender) ); 619 dict.insert( "Gender", new int(Qtopia::Gender) );
617 dict.insert( "Birthday", new int(Qtopia::Birthday) ); 620 dict.insert( "Birthday", new int(Qtopia::Birthday) );
618 dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); 621 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
619 dict.insert( "Nickname", new int(Qtopia::Nickname) ); 622 dict.insert( "Nickname", new int(Qtopia::Nickname) );
620 dict.insert( "Notes", new int(Qtopia::Notes) ); 623 dict.insert( "Notes", new int(Qtopia::Notes) );
621 dict.insert( "action", new int(JOURNALACTION) ); 624 dict.insert( "action", new int(JOURNALACTION) );
622 dict.insert( "actionrow", new int(JOURNALROW) ); 625 dict.insert( "actionrow", new int(JOURNALROW) );
623 626
624 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() ); 627 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() );
625 628
626 XMLElement *root = XMLElement::load( filename ); 629 XMLElement *root = XMLElement::load( filename );
627 if(root != 0l ){ // start parsing 630 if(root != 0l ){ // start parsing
628 /* Parse all XML-Elements and put the data into the 631 /* Parse all XML-Elements and put the data into the
629 * Contact-Class 632 * Contact-Class
630 */ 633 */
631 XMLElement *element = root->firstChild(); 634 XMLElement *element = root->firstChild();
632 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() ); 635 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() );
633 element = element->firstChild(); 636 element = element->firstChild();
634 637
635 /* Search Tag "Contacts" which is the parent of all Contacts */ 638 /* Search Tag "Contacts" which is the parent of all Contacts */
636 while( element && !isJournal ){ 639 while( element && !isJournal ){
637 if( element->tagName() != QString::fromLatin1("Contacts") ){ 640 if( element->tagName() != QString::fromLatin1("Contacts") ){
638 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s", 641 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s",
639 // element->tagName().latin1()); 642 // element->tagName().latin1());
640 element = element->nextChild(); 643 element = element->nextChild();
641 } else { 644 } else {
642 element = element->firstChild(); 645 element = element->firstChild();
643 break; 646 break;
644 } 647 }
645 } 648 }
646 /* Parse all Contacts and ignore unknown tags */ 649 /* Parse all Contacts and ignore unknown tags */
647 while( element ){ 650 while( element ){
648 if( element->tagName() != QString::fromLatin1("Contact") ){ 651 if( element->tagName() != QString::fromLatin1("Contact") ){
649 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s", 652 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s",
650 // element->tagName().latin1()); 653 // element->tagName().latin1());
651 element = element->nextChild(); 654 element = element->nextChild();
652 continue; 655 continue;
653 } 656 }
654 /* Found alement with tagname "contact", now parse and store all 657 /* Found alement with tagname "contact", now parse and store all
655 * attributes contained 658 * attributes contained
656 */ 659 */
657 //qWarning("OContactDefBack::load element tagName() : %s", 660 //qWarning("OContactDefBack::load element tagName() : %s",
658 // element->tagName().latin1() ); 661 // element->tagName().latin1() );
659 QString dummy; 662 QString dummy;
660 foundAction = false; 663 foundAction = false;
661 664
662 XMLElement::AttributeMap aMap = element->attributes(); 665 XMLElement::AttributeMap aMap = element->attributes();
663 XMLElement::AttributeMap::Iterator it; 666 XMLElement::AttributeMap::Iterator it;
664 contactMap.clear(); 667 contactMap.clear();
665 customMap.clear(); 668 customMap.clear();
666 for( it = aMap.begin(); it != aMap.end(); ++it ){ 669 for( it = aMap.begin(); it != aMap.end(); ++it ){
667 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); 670 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1());
668 671
669 int *find = dict[ it.key() ]; 672 int *find = dict[ it.key() ];
670 /* Unknown attributes will be stored as "Custom" elements */ 673 /* Unknown attributes will be stored as "Custom" elements */
671 if ( !find ) { 674 if ( !find ) {
672 qWarning("Attribute %s not known.", it.key().latin1()); 675 qWarning("Attribute %s not known.", it.key().latin1());
673 //contact.setCustomField(it.key(), it.data()); 676 //contact.setCustomField(it.key(), it.data());
674 customMap.insert( it.key(), it.data() ); 677 customMap.insert( it.key(), it.data() );
675 continue; 678 continue;
676 } 679 }
677 680
678 /* Check if special conversion is needed and add attribute 681 /* Check if special conversion is needed and add attribute
679 * into Contact class 682 * into Contact class
680 */ 683 */
681 switch( *find ) { 684 switch( *find ) {
682 /* 685 /*
683 case Qtopia::AddressUid: 686 case Qtopia::AddressUid:
684 contact.setUid( it.data().toInt() ); 687 contact.setUid( it.data().toInt() );
685 break; 688 break;
686 case Qtopia::AddressCategory: 689 case Qtopia::AddressCategory:
687 contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); 690 contact.setCategories( Qtopia::Record::idsFromString( it.data( )));
688 break; 691 break;
689 */ 692 */
690 case JOURNALACTION: 693 case JOURNALACTION:
691 action = journal_action(it.data().toInt()); 694 action = journal_action(it.data().toInt());
692 foundAction = true; 695 foundAction = true;
693 qWarning ("ODefBack(journal)::ACTION found: %d", action); 696 qWarning ("ODefBack(journal)::ACTION found: %d", action);
694 break; 697 break;
695 case JOURNALROW: 698 case JOURNALROW:
696 journalKey = it.data().toInt(); 699 journalKey = it.data().toInt();
697 break; 700 break;
698 default: // no conversion needed add them to the map 701 default: // no conversion needed add them to the map
699 contactMap.insert( *find, it.data() ); 702 contactMap.insert( *find, it.data() );
700 break; 703 break;
701 } 704 }
702 } 705 }
703 /* now generate the Contact contact */ 706 /* now generate the Contact contact */
704 OContact contact( contactMap ); 707 OContact contact( contactMap );
705 708
706 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { 709 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) {
707 contact.setCustomField( customIt.key(), customIt.data() ); 710 contact.setCustomField( customIt.key(), customIt.data() );
708 } 711 }
709 712
710 if (foundAction){ 713 if (foundAction){
711 foundAction = false; 714 foundAction = false;
712 switch ( action ) { 715 switch ( action ) {
713 case ACTION_ADD: 716 case ACTION_ADD:
714 addContact_p (contact); 717 addContact_p (contact);
715 break; 718 break;
716 case ACTION_REMOVE: 719 case ACTION_REMOVE:
717 if ( !remove (contact.uid()) ) 720 if ( !remove (contact.uid()) )
718 qWarning ("ODefBack(journal)::Unable to remove uid: %d", 721 qWarning ("ODefBack(journal)::Unable to remove uid: %d",
719 contact.uid() ); 722 contact.uid() );
720 break; 723 break;
721 case ACTION_REPLACE: 724 case ACTION_REPLACE:
722 if ( !replace ( contact ) ) 725 if ( !replace ( contact ) )
723 qWarning ("ODefBack(journal)::Unable to replace uid: %d", 726 qWarning ("ODefBack(journal)::Unable to replace uid: %d",
724 contact.uid() ); 727 contact.uid() );
725 break; 728 break;
726 default: 729 default:
727 qWarning ("Unknown action: ignored !"); 730 qWarning ("Unknown action: ignored !");
728 break; 731 break;
729 } 732 }
730 }else{ 733 }else{
731 /* Add contact to list */ 734 /* Add contact to list */
732 addContact_p (contact); 735 addContact_p (contact);
733 } 736 }
734 737
735 /* Move to next element */ 738 /* Move to next element */
736 element = element->nextChild(); 739 element = element->nextChild();
737 } 740 }
738 }else { 741 }else {
739 qWarning("ODefBack::could not load"); 742 qWarning("ODefBack::could not load");
740 } 743 }
741 delete root; 744 delete root;
742 qWarning("returning from loading" ); 745 qWarning("returning from loading" );
743 return true; 746 return true;
744} 747}
745 748
746 749
747void OContactAccessBackend_XML::updateJournal( const OContact& cnt, 750void OContactAccessBackend_XML::updateJournal( const OContact& cnt,
748 journal_action action ) 751 journal_action action )
749{ 752{
750 QFile f( m_journalName ); 753 QFile f( m_journalName );
751 bool created = !f.exists(); 754 bool created = !f.exists();
752 if ( !f.open(IO_WriteOnly|IO_Append) ) 755 if ( !f.open(IO_WriteOnly|IO_Append) )
753 return; 756 return;
754 757
755 QString buf; 758 QString buf;
756 QCString str; 759 QCString str;
757 760
758 // if the file was created, we have to set the Tag "<CONTACTS>" to 761 // if the file was created, we have to set the Tag "<CONTACTS>" to
759 // get a XML-File which is readable by our parser. 762 // get a XML-File which is readable by our parser.
760 // This is just a cheat, but better than rewrite the parser. 763 // This is just a cheat, but better than rewrite the parser.
761 if ( created ){ 764 if ( created ){
762 buf = "<Contacts>"; 765 buf = "<Contacts>";
763 QCString cstr = buf.utf8(); 766 QCString cstr = buf.utf8();
764 f.writeBlock( cstr.data(), cstr.length() ); 767 f.writeBlock( cstr.data(), cstr.length() );
765 } 768 }
766 769
767 buf = "<Contact "; 770 buf = "<Contact ";
768 cnt.save( buf ); 771 cnt.save( buf );
769 buf += " action=\"" + QString::number( (int)action ) + "\" "; 772 buf += " action=\"" + QString::number( (int)action ) + "\" ";
770 buf += "/>\n"; 773 buf += "/>\n";
771 QCString cstr = buf.utf8(); 774 QCString cstr = buf.utf8();
772 f.writeBlock( cstr.data(), cstr.length() ); 775 f.writeBlock( cstr.data(), cstr.length() );
773} 776}
774 777
775void OContactAccessBackend_XML::removeJournal() 778void OContactAccessBackend_XML::removeJournal()
776{ 779{
777 QFile f ( m_journalName ); 780 QFile f ( m_journalName );
778 if ( f.exists() ) 781 if ( f.exists() )
779 f.remove(); 782 f.remove();
780} 783}
781 784
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
index 9fe3d1e..c5a7820 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
@@ -1,781 +1,784 @@
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.4 2003/03/21 14:32:54 mickeyl
21 * g++ compliance fix: default arguments belong into the declaration, but not the definition
22 *
20 * Revision 1.3 2003/03/21 12:26:28 eilers 23 * Revision 1.3 2003/03/21 12:26:28 eilers
21 * Fixing small bug: If we search a birthday from today to today, it returned 24 * Fixing small bug: If we search a birthday from today to today, it returned
22 * every contact .. 25 * every contact ..
23 * 26 *
24 * Revision 1.2 2003/03/21 10:33:09 eilers 27 * Revision 1.2 2003/03/21 10:33:09 eilers
25 * Merged speed optimized xml backend for contacts to main. 28 * Merged speed optimized xml backend for contacts to main.
26 * Added QDateTime to querybyexample. For instance, it is now possible to get 29 * Added QDateTime to querybyexample. For instance, it is now possible to get
27 * all Birthdays/Anniversaries between two dates. This should be used 30 * all Birthdays/Anniversaries between two dates. This should be used
28 * to show all birthdays in the datebook.. 31 * to show all birthdays in the datebook..
29 * This change is sourcecode backward compatible but you have to upgrade 32 * This change is sourcecode backward compatible but you have to upgrade
30 * the binaries for today-addressbook. 33 * the binaries for today-addressbook.
31 * 34 *
32 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers 35 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers
33 * Speed optimization. Removed the sequential search loops. 36 * Speed optimization. Removed the sequential search loops.
34 * 37 *
35 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers 38 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers
36 * Writing offsets to debug output.. 39 * Writing offsets to debug output..
37 * 40 *
38 * Revision 1.1 2003/02/09 15:05:01 eilers 41 * Revision 1.1 2003/02/09 15:05:01 eilers
39 * Nothing happened.. Just some cleanup before I will start.. 42 * Nothing happened.. Just some cleanup before I will start..
40 * 43 *
41 * Revision 1.12 2003/01/03 16:58:03 eilers 44 * Revision 1.12 2003/01/03 16:58:03 eilers
42 * Reenable debug output 45 * Reenable debug output
43 * 46 *
44 * Revision 1.11 2003/01/03 12:31:28 eilers 47 * Revision 1.11 2003/01/03 12:31:28 eilers
45 * Bugfix for calculating data diffs.. 48 * Bugfix for calculating data diffs..
46 * 49 *
47 * Revision 1.10 2003/01/02 14:27:12 eilers 50 * Revision 1.10 2003/01/02 14:27:12 eilers
48 * Improved query by example: Search by date is possible.. First step 51 * Improved query by example: Search by date is possible.. First step
49 * for a today plugin for birthdays.. 52 * for a today plugin for birthdays..
50 * 53 *
51 * Revision 1.9 2002/12/08 12:48:57 eilers 54 * Revision 1.9 2002/12/08 12:48:57 eilers
52 * Moved journal-enum from ocontact into i the xml-backend.. 55 * Moved journal-enum from ocontact into i the xml-backend..
53 * 56 *
54 * Revision 1.8 2002/11/14 17:04:24 eilers 57 * Revision 1.8 2002/11/14 17:04:24 eilers
55 * Sorting will now work if fullname is identical on some entries 58 * Sorting will now work if fullname is identical on some entries
56 * 59 *
57 * Revision 1.7 2002/11/13 15:02:46 eilers 60 * Revision 1.7 2002/11/13 15:02:46 eilers
58 * Small Bug in sorted fixed 61 * Small Bug in sorted fixed
59 * 62 *
60 * Revision 1.6 2002/11/13 14:14:51 eilers 63 * Revision 1.6 2002/11/13 14:14:51 eilers
61 * Added sorted for Contacts.. 64 * Added sorted for Contacts..
62 * 65 *
63 * Revision 1.5 2002/11/01 15:10:42 eilers 66 * Revision 1.5 2002/11/01 15:10:42 eilers
64 * Added regExp-search in database for all fields in a contact. 67 * Added regExp-search in database for all fields in a contact.
65 * 68 *
66 * Revision 1.4 2002/10/16 10:52:40 eilers 69 * Revision 1.4 2002/10/16 10:52:40 eilers
67 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 70 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
68 * 71 *
69 * Revision 1.3 2002/10/14 16:21:54 eilers 72 * Revision 1.3 2002/10/14 16:21:54 eilers
70 * Some minor interface updates 73 * Some minor interface updates
71 * 74 *
72 * Revision 1.2 2002/10/07 17:34:24 eilers 75 * Revision 1.2 2002/10/07 17:34:24 eilers
73 * added OBackendFactory for advanced backend access 76 * added OBackendFactory for advanced backend access
74 * 77 *
75 * Revision 1.1 2002/09/27 17:11:44 eilers 78 * Revision 1.1 2002/09/27 17:11:44 eilers
76 * Added API for accessing the Contact-Database ! It is compiling, but 79 * Added API for accessing the Contact-Database ! It is compiling, but
77 * please do not expect that anything is working ! 80 * please do not expect that anything is working !
78 * I will debug that stuff in the next time .. 81 * I will debug that stuff in the next time ..
79 * Please read README_COMPILE for compiling ! 82 * Please read README_COMPILE for compiling !
80 * 83 *
81 * 84 *
82 */ 85 */
83 86
84#include "ocontactaccessbackend_xml.h" 87#include "ocontactaccessbackend_xml.h"
85 88
86#include <qasciidict.h> 89#include <qasciidict.h>
87#include <qdatetime.h> 90#include <qdatetime.h>
88#include <qfile.h> 91#include <qfile.h>
89#include <qfileinfo.h> 92#include <qfileinfo.h>
90#include <qregexp.h> 93#include <qregexp.h>
91#include <qarray.h> 94#include <qarray.h>
92#include <qmap.h> 95#include <qmap.h>
93#include <qdatetime.h> 96#include <qdatetime.h>
94 97
95#include <qpe/global.h> 98#include <qpe/global.h>
96 99
97#include <opie/xmltree.h> 100#include <opie/xmltree.h>
98#include "ocontactaccessbackend.h" 101#include "ocontactaccessbackend.h"
99#include "ocontactaccess.h" 102#include "ocontactaccess.h"
100 103
101#include <stdlib.h> 104#include <stdlib.h>
102#include <errno.h> 105#include <errno.h>
103 106
104using namespace Opie; 107using namespace Opie;
105 108
106 109
107OContactAccessBackend_XML::OContactAccessBackend_XML ( QString appname, QString filename = 0l ): 110OContactAccessBackend_XML::OContactAccessBackend_XML ( QString appname, QString filename ):
108 m_changed( false ) 111 m_changed( false )
109{ 112{
110 // Just m_contactlist should call delete if an entry 113 // Just m_contactlist should call delete if an entry
111 // is removed. 114 // is removed.
112 m_contactList.setAutoDelete( true ); 115 m_contactList.setAutoDelete( true );
113 m_uidToContact.setAutoDelete( false ); 116 m_uidToContact.setAutoDelete( false );
114 117
115 m_appName = appname; 118 m_appName = appname;
116 119
117 /* Set journalfile name ... */ 120 /* Set journalfile name ... */
118 m_journalName = getenv("HOME"); 121 m_journalName = getenv("HOME");
119 m_journalName +="/.abjournal" + appname; 122 m_journalName +="/.abjournal" + appname;
120 123
121 /* Expecting to access the default filename if nothing else is set */ 124 /* Expecting to access the default filename if nothing else is set */
122 if ( filename.isEmpty() ){ 125 if ( filename.isEmpty() ){
123 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 126 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
124 } else 127 } else
125 m_fileName = filename; 128 m_fileName = filename;
126 129
127 /* Load Database now */ 130 /* Load Database now */
128 load (); 131 load ();
129} 132}
130 133
131bool OContactAccessBackend_XML::save() 134bool OContactAccessBackend_XML::save()
132{ 135{
133 136
134 if ( !m_changed ) 137 if ( !m_changed )
135 return true; 138 return true;
136 139
137 QString strNewFile = m_fileName + ".new"; 140 QString strNewFile = m_fileName + ".new";
138 QFile f( strNewFile ); 141 QFile f( strNewFile );
139 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 142 if ( !f.open( IO_WriteOnly|IO_Raw ) )
140 return false; 143 return false;
141 144
142 int total_written; 145 int total_written;
143 int idx_offset = 0; 146 int idx_offset = 0;
144 QString out; 147 QString out;
145 148
146 // Write Header 149 // Write Header
147 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 150 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
148 " <Groups>\n" 151 " <Groups>\n"
149 " </Groups>\n" 152 " </Groups>\n"
150 " <Contacts>\n"; 153 " <Contacts>\n";
151 QCString cstr = out.utf8(); 154 QCString cstr = out.utf8();
152 f.writeBlock( cstr.data(), cstr.length() ); 155 f.writeBlock( cstr.data(), cstr.length() );
153 idx_offset += cstr.length(); 156 idx_offset += cstr.length();
154 out = ""; 157 out = "";
155 158
156 // Write all contacts 159 // Write all contacts
157 QListIterator<OContact> it( m_contactList ); 160 QListIterator<OContact> it( m_contactList );
158 for ( ; it.current(); ++it ) { 161 for ( ; it.current(); ++it ) {
159 qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); 162 qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset );
160 out += "<Contact "; 163 out += "<Contact ";
161 (*it)->save( out ); 164 (*it)->save( out );
162 out += "/>\n"; 165 out += "/>\n";
163 cstr = out.utf8(); 166 cstr = out.utf8();
164 total_written = f.writeBlock( cstr.data(), cstr.length() ); 167 total_written = f.writeBlock( cstr.data(), cstr.length() );
165 idx_offset += cstr.length(); 168 idx_offset += cstr.length();
166 if ( total_written != int(cstr.length()) ) { 169 if ( total_written != int(cstr.length()) ) {
167 f.close(); 170 f.close();
168 QFile::remove( strNewFile ); 171 QFile::remove( strNewFile );
169 return false; 172 return false;
170 } 173 }
171 out = ""; 174 out = "";
172 } 175 }
173 out += " </Contacts>\n</AddressBook>\n"; 176 out += " </Contacts>\n</AddressBook>\n";
174 177
175 // Write Footer 178 // Write Footer
176 cstr = out.utf8(); 179 cstr = out.utf8();
177 total_written = f.writeBlock( cstr.data(), cstr.length() ); 180 total_written = f.writeBlock( cstr.data(), cstr.length() );
178 if ( total_written != int( cstr.length() ) ) { 181 if ( total_written != int( cstr.length() ) ) {
179 f.close(); 182 f.close();
180 QFile::remove( strNewFile ); 183 QFile::remove( strNewFile );
181 return false; 184 return false;
182 } 185 }
183 f.close(); 186 f.close();
184 187
185 // move the file over, I'm just going to use the system call 188 // move the file over, I'm just going to use the system call
186 // because, I don't feel like using QDir. 189 // because, I don't feel like using QDir.
187 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 190 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
188 qWarning( "problem renaming file %s to %s, errno: %d", 191 qWarning( "problem renaming file %s to %s, errno: %d",
189 strNewFile.latin1(), m_journalName.latin1(), errno ); 192 strNewFile.latin1(), m_journalName.latin1(), errno );
190 // remove the tmp file... 193 // remove the tmp file...
191 QFile::remove( strNewFile ); 194 QFile::remove( strNewFile );
192 } 195 }
193 196
194 /* The journalfile should be removed now... */ 197 /* The journalfile should be removed now... */
195 removeJournal(); 198 removeJournal();
196 199
197 m_changed = false; 200 m_changed = false;
198 return true; 201 return true;
199} 202}
200 203
201bool OContactAccessBackend_XML::load () 204bool OContactAccessBackend_XML::load ()
202{ 205{
203 m_contactList.clear(); 206 m_contactList.clear();
204 m_uidToContact.clear(); 207 m_uidToContact.clear();
205 208
206 /* Load XML-File and journal if it exists */ 209 /* Load XML-File and journal if it exists */
207 if ( !load ( m_fileName, false ) ) 210 if ( !load ( m_fileName, false ) )
208 return false; 211 return false;
209 /* The returncode of the journalfile is ignored due to the 212 /* The returncode of the journalfile is ignored due to the
210 * fact that it does not exist when this class is instantiated ! 213 * fact that it does not exist when this class is instantiated !
211 * But there may such a file exist, if the application crashed. 214 * But there may such a file exist, if the application crashed.
212 * Therefore we try to load it to get the changes before the # 215 * Therefore we try to load it to get the changes before the #
213 * crash happened... 216 * crash happened...
214 */ 217 */
215 load (m_journalName, true); 218 load (m_journalName, true);
216 219
217 return true; 220 return true;
218} 221}
219 222
220void OContactAccessBackend_XML::clear () 223void OContactAccessBackend_XML::clear ()
221{ 224{
222 m_contactList.clear(); 225 m_contactList.clear();
223 m_uidToContact.clear(); 226 m_uidToContact.clear();
224 227
225 m_changed = false; 228 m_changed = false;
226} 229}
227 230
228bool OContactAccessBackend_XML::wasChangedExternally() 231bool OContactAccessBackend_XML::wasChangedExternally()
229{ 232{
230 QFileInfo fi( m_fileName ); 233 QFileInfo fi( m_fileName );
231 234
232 QDateTime lastmod = fi.lastModified (); 235 QDateTime lastmod = fi.lastModified ();
233 236
234 return (lastmod != m_readtime); 237 return (lastmod != m_readtime);
235} 238}
236 239
237QArray<int> OContactAccessBackend_XML::allRecords() const 240QArray<int> OContactAccessBackend_XML::allRecords() const
238{ 241{
239 QArray<int> uid_list( m_contactList.count() ); 242 QArray<int> uid_list( m_contactList.count() );
240 243
241 uint counter = 0; 244 uint counter = 0;
242 QListIterator<OContact> it( m_contactList ); 245 QListIterator<OContact> it( m_contactList );
243 for( ; it.current(); ++it ){ 246 for( ; it.current(); ++it ){
244 uid_list[counter++] = (*it)->uid(); 247 uid_list[counter++] = (*it)->uid();
245 } 248 }
246 249
247 return ( uid_list ); 250 return ( uid_list );
248} 251}
249 252
250OContact OContactAccessBackend_XML::find ( int uid ) const 253OContact OContactAccessBackend_XML::find ( int uid ) const
251{ 254{
252 OContact foundContact; //Create empty contact 255 OContact foundContact; //Create empty contact
253 256
254 OContact* found = m_uidToContact.find( QString().setNum( uid ) ); 257 OContact* found = m_uidToContact.find( QString().setNum( uid ) );
255 258
256 if ( found ){ 259 if ( found ){
257 foundContact = *found; 260 foundContact = *found;
258 } 261 }
259 262
260 return ( foundContact ); 263 return ( foundContact );
261} 264}
262 265
263QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings, 266QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings,
264 const QDateTime& d ) 267 const QDateTime& d )
265{ 268{
266 269
267 QArray<int> m_currentQuery( m_contactList.count() ); 270 QArray<int> m_currentQuery( m_contactList.count() );
268 QListIterator<OContact> it( m_contactList ); 271 QListIterator<OContact> it( m_contactList );
269 uint arraycounter = 0; 272 uint arraycounter = 0;
270 273
271 for( ; it.current(); ++it ){ 274 for( ; it.current(); ++it ){
272 /* Search all fields and compare them with query object. Store them into list 275 /* Search all fields and compare them with query object. Store them into list
273 * if all fields matches. 276 * if all fields matches.
274 */ 277 */
275 QDate* queryDate = 0l; 278 QDate* queryDate = 0l;
276 QDate* checkDate = 0l; 279 QDate* checkDate = 0l;
277 bool allcorrect = true; 280 bool allcorrect = true;
278 for ( int i = 0; i < Qtopia::Groups; i++ ) { 281 for ( int i = 0; i < Qtopia::Groups; i++ ) {
279 // Birthday and anniversary are special nonstring fields and should 282 // Birthday and anniversary are special nonstring fields and should
280 // be handled specially 283 // be handled specially
281 switch ( i ){ 284 switch ( i ){
282 case Qtopia::Birthday: 285 case Qtopia::Birthday:
283 queryDate = new QDate( query.birthday() ); 286 queryDate = new QDate( query.birthday() );
284 checkDate = new QDate( (*it)->birthday() ); 287 checkDate = new QDate( (*it)->birthday() );
285 case Qtopia::Anniversary: 288 case Qtopia::Anniversary:
286 if ( queryDate == 0l ){ 289 if ( queryDate == 0l ){
287 queryDate = new QDate( query.anniversary() ); 290 queryDate = new QDate( query.anniversary() );
288 checkDate = new QDate( (*it)->anniversary() ); 291 checkDate = new QDate( (*it)->anniversary() );
289 } 292 }
290 293
291 if ( queryDate->isValid() ){ 294 if ( queryDate->isValid() ){
292 if( checkDate->isValid() ){ 295 if( checkDate->isValid() ){
293 if ( settings & OContactAccess::DateYear ){ 296 if ( settings & OContactAccess::DateYear ){
294 if ( queryDate->year() != checkDate->year() ) 297 if ( queryDate->year() != checkDate->year() )
295 allcorrect = false; 298 allcorrect = false;
296 } 299 }
297 if ( settings & OContactAccess::DateMonth ){ 300 if ( settings & OContactAccess::DateMonth ){
298 if ( queryDate->month() != checkDate->month() ) 301 if ( queryDate->month() != checkDate->month() )
299 allcorrect = false; 302 allcorrect = false;
300 } 303 }
301 if ( settings & OContactAccess::DateDay ){ 304 if ( settings & OContactAccess::DateDay ){
302 if ( queryDate->day() != checkDate->day() ) 305 if ( queryDate->day() != checkDate->day() )
303 allcorrect = false; 306 allcorrect = false;
304 } 307 }
305 if ( settings & OContactAccess::DateDiff ) { 308 if ( settings & OContactAccess::DateDiff ) {
306 QDate current; 309 QDate current;
307 // If we get an additional date, we 310 // If we get an additional date, we
308 // will take this date instead of 311 // will take this date instead of
309 // the current one.. 312 // the current one..
310 if ( !d.date().isValid() ) 313 if ( !d.date().isValid() )
311 current = QDate::currentDate(); 314 current = QDate::currentDate();
312 else 315 else
313 current = d.date(); 316 current = d.date();
314 317
315 // We have to equalize the year, otherwise 318 // We have to equalize the year, otherwise
316 // the search will fail.. 319 // the search will fail..
317 checkDate->setYMD( current.year(), 320 checkDate->setYMD( current.year(),
318 checkDate->month(), 321 checkDate->month(),
319 checkDate->day() ); 322 checkDate->day() );
320 if ( *checkDate < current ) 323 if ( *checkDate < current )
321 checkDate->setYMD( current.year()+1, 324 checkDate->setYMD( current.year()+1,
322 checkDate->month(), 325 checkDate->month(),
323 checkDate->day() ); 326 checkDate->day() );
324 327
325 // Check whether the birthday/anniversary date is between 328 // Check whether the birthday/anniversary date is between
326 // the current/given date and the maximum date 329 // the current/given date and the maximum date
327 // ( maximum time range ) ! 330 // ( maximum time range ) !
328 qWarning("Checking if %s is between %s and %s ! ", 331 qWarning("Checking if %s is between %s and %s ! ",
329 checkDate->toString().latin1(), 332 checkDate->toString().latin1(),
330 current.toString().latin1(), 333 current.toString().latin1(),
331 queryDate->toString().latin1() ); 334 queryDate->toString().latin1() );
332 if ( current.daysTo( *queryDate ) >= 0 ){ 335 if ( current.daysTo( *queryDate ) >= 0 ){
333 if ( !( ( *checkDate >= current ) && 336 if ( !( ( *checkDate >= current ) &&
334 ( *checkDate <= *queryDate ) ) ){ 337 ( *checkDate <= *queryDate ) ) ){
335 allcorrect = false; 338 allcorrect = false;
336 qWarning (" Nope!.."); 339 qWarning (" Nope!..");
337 } 340 }
338 } 341 }
339 } 342 }
340 } else{ 343 } else{
341 // checkDate is invalid. Therefore this entry is always rejected 344 // checkDate is invalid. Therefore this entry is always rejected
342 allcorrect = false; 345 allcorrect = false;
343 } 346 }
344 } 347 }
345 348
346 delete queryDate; 349 delete queryDate;
347 queryDate = 0l; 350 queryDate = 0l;
348 delete checkDate; 351 delete checkDate;
349 checkDate = 0l; 352 checkDate = 0l;
350 break; 353 break;
351 default: 354 default:
352 /* Just compare fields which are not empty in the query object */ 355 /* Just compare fields which are not empty in the query object */
353 if ( !query.field(i).isEmpty() ){ 356 if ( !query.field(i).isEmpty() ){
354 switch ( settings & ~( OContactAccess::IgnoreCase 357 switch ( settings & ~( OContactAccess::IgnoreCase
355 | OContactAccess::DateDiff 358 | OContactAccess::DateDiff
356 | OContactAccess::DateYear 359 | OContactAccess::DateYear
357 | OContactAccess::DateMonth 360 | OContactAccess::DateMonth
358 | OContactAccess::DateDay 361 | OContactAccess::DateDay
359 | OContactAccess::MatchOne 362 | OContactAccess::MatchOne
360 ) ){ 363 ) ){
361 364
362 case OContactAccess::RegExp:{ 365 case OContactAccess::RegExp:{
363 QRegExp expr ( query.field(i), 366 QRegExp expr ( query.field(i),
364 !(settings & OContactAccess::IgnoreCase), 367 !(settings & OContactAccess::IgnoreCase),
365 false ); 368 false );
366 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 369 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
367 allcorrect = false; 370 allcorrect = false;
368 } 371 }
369 break; 372 break;
370 case OContactAccess::WildCards:{ 373 case OContactAccess::WildCards:{
371 QRegExp expr ( query.field(i), 374 QRegExp expr ( query.field(i),
372 !(settings & OContactAccess::IgnoreCase), 375 !(settings & OContactAccess::IgnoreCase),
373 true ); 376 true );
374 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 377 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
375 allcorrect = false; 378 allcorrect = false;
376 } 379 }
377 break; 380 break;
378 case OContactAccess::ExactMatch:{ 381 case OContactAccess::ExactMatch:{
379 if (settings & OContactAccess::IgnoreCase){ 382 if (settings & OContactAccess::IgnoreCase){
380 if ( query.field(i).upper() != 383 if ( query.field(i).upper() !=
381 (*it)->field(i).upper() ) 384 (*it)->field(i).upper() )
382 allcorrect = false; 385 allcorrect = false;
383 }else{ 386 }else{
384 if ( query.field(i) != (*it)->field(i) ) 387 if ( query.field(i) != (*it)->field(i) )
385 allcorrect = false; 388 allcorrect = false;
386 } 389 }
387 } 390 }
388 break; 391 break;
389 } 392 }
390 } 393 }
391 } 394 }
392 } 395 }
393 if ( allcorrect ){ 396 if ( allcorrect ){
394 m_currentQuery[arraycounter++] = (*it)->uid(); 397 m_currentQuery[arraycounter++] = (*it)->uid();
395 } 398 }
396 } 399 }
397 400
398 // Shrink to fit.. 401 // Shrink to fit..
399 m_currentQuery.resize(arraycounter); 402 m_currentQuery.resize(arraycounter);
400 403
401 return m_currentQuery; 404 return m_currentQuery;
402} 405}
403 406
404QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const 407QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
405{ 408{
406 QArray<int> m_currentQuery( m_contactList.count() ); 409 QArray<int> m_currentQuery( m_contactList.count() );
407 QListIterator<OContact> it( m_contactList ); 410 QListIterator<OContact> it( m_contactList );
408 uint arraycounter = 0; 411 uint arraycounter = 0;
409 412
410 for( ; it.current(); ++it ){ 413 for( ; it.current(); ++it ){
411 if ( (*it)->match( r ) ){ 414 if ( (*it)->match( r ) ){
412 m_currentQuery[arraycounter++] = (*it)->uid(); 415 m_currentQuery[arraycounter++] = (*it)->uid();
413 } 416 }
414 417
415 } 418 }
416 // Shrink to fit.. 419 // Shrink to fit..
417 m_currentQuery.resize(arraycounter); 420 m_currentQuery.resize(arraycounter);
418 421
419 return m_currentQuery; 422 return m_currentQuery;
420} 423}
421 424
422const uint OContactAccessBackend_XML::querySettings() 425const uint OContactAccessBackend_XML::querySettings()
423{ 426{
424 return ( OContactAccess::WildCards 427 return ( OContactAccess::WildCards
425 | OContactAccess::IgnoreCase 428 | OContactAccess::IgnoreCase
426 | OContactAccess::RegExp 429 | OContactAccess::RegExp
427 | OContactAccess::ExactMatch 430 | OContactAccess::ExactMatch
428 | OContactAccess::DateDiff 431 | OContactAccess::DateDiff
429 | OContactAccess::DateYear 432 | OContactAccess::DateYear
430 | OContactAccess::DateMonth 433 | OContactAccess::DateMonth
431 | OContactAccess::DateDay 434 | OContactAccess::DateDay
432 ); 435 );
433} 436}
434 437
435bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const 438bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const
436{ 439{
437 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 440 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
438 * may be added with any of the other settings. IgnoreCase should never used alone. 441 * may be added with any of the other settings. IgnoreCase should never used alone.
439 * Wildcards, RegExp, ExactMatch should never used at the same time... 442 * Wildcards, RegExp, ExactMatch should never used at the same time...
440 */ 443 */
441 444
442 if ( querySettings == OContactAccess::IgnoreCase ) 445 if ( querySettings == OContactAccess::IgnoreCase )
443 return false; 446 return false;
444 447
445 switch ( querySettings & ~( OContactAccess::IgnoreCase 448 switch ( querySettings & ~( OContactAccess::IgnoreCase
446 | OContactAccess::DateDiff 449 | OContactAccess::DateDiff
447 | OContactAccess::DateYear 450 | OContactAccess::DateYear
448 | OContactAccess::DateMonth 451 | OContactAccess::DateMonth
449 | OContactAccess::DateDay 452 | OContactAccess::DateDay
450 ) 453 )
451 ){ 454 ){
452 case OContactAccess::RegExp: 455 case OContactAccess::RegExp:
453 return ( true ); 456 return ( true );
454 case OContactAccess::WildCards: 457 case OContactAccess::WildCards:
455 return ( true ); 458 return ( true );
456 case OContactAccess::ExactMatch: 459 case OContactAccess::ExactMatch:
457 return ( true ); 460 return ( true );
458 default: 461 default:
459 return ( false ); 462 return ( false );
460 } 463 }
461} 464}
462 465
463// Currently only asc implemented.. 466// Currently only asc implemented..
464QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int ) 467QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int )
465{ 468{
466 QMap<QString, int> nameToUid; 469 QMap<QString, int> nameToUid;
467 QStringList names; 470 QStringList names;
468 QArray<int> m_currentQuery( m_contactList.count() ); 471 QArray<int> m_currentQuery( m_contactList.count() );
469 472
470 // First fill map and StringList with all Names 473 // First fill map and StringList with all Names
471 // Afterwards sort namelist and use map to fill array to return.. 474 // Afterwards sort namelist and use map to fill array to return..
472 QListIterator<OContact> it( m_contactList ); 475 QListIterator<OContact> it( m_contactList );
473 for( ; it.current(); ++it ){ 476 for( ; it.current(); ++it ){
474 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); 477 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) );
475 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); 478 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() );
476 } 479 }
477 names.sort(); 480 names.sort();
478 481
479 int i = 0; 482 int i = 0;
480 if ( asc ){ 483 if ( asc ){
481 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 484 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
482 m_currentQuery[i++] = nameToUid[ (*it) ]; 485 m_currentQuery[i++] = nameToUid[ (*it) ];
483 }else{ 486 }else{
484 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 487 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
485 m_currentQuery[i++] = nameToUid[ (*it) ]; 488 m_currentQuery[i++] = nameToUid[ (*it) ];
486 } 489 }
487 490
488 return m_currentQuery; 491 return m_currentQuery;
489 492
490} 493}
491 494
492bool OContactAccessBackend_XML::add ( const OContact &newcontact ) 495bool OContactAccessBackend_XML::add ( const OContact &newcontact )
493{ 496{
494 //qWarning("odefaultbackend: ACTION::ADD"); 497 //qWarning("odefaultbackend: ACTION::ADD");
495 updateJournal (newcontact, ACTION_ADD); 498 updateJournal (newcontact, ACTION_ADD);
496 addContact_p( newcontact ); 499 addContact_p( newcontact );
497 500
498 m_changed = true; 501 m_changed = true;
499 502
500 return true; 503 return true;
501} 504}
502 505
503bool OContactAccessBackend_XML::replace ( const OContact &contact ) 506bool OContactAccessBackend_XML::replace ( const OContact &contact )
504{ 507{
505 m_changed = true; 508 m_changed = true;
506 509
507 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); 510 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) );
508 511
509 if ( found ) { 512 if ( found ) {
510 OContact* newCont = new OContact( contact ); 513 OContact* newCont = new OContact( contact );
511 514
512 updateJournal ( *newCont, ACTION_REPLACE); 515 updateJournal ( *newCont, ACTION_REPLACE);
513 m_contactList.removeRef ( found ); 516 m_contactList.removeRef ( found );
514 m_contactList.append ( newCont ); 517 m_contactList.append ( newCont );
515 m_uidToContact.remove( QString().setNum( contact.uid() ) ); 518 m_uidToContact.remove( QString().setNum( contact.uid() ) );
516 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); 519 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont );
517 520
518 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); 521 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid());
519 522
520 return true; 523 return true;
521 } else 524 } else
522 return false; 525 return false;
523} 526}
524 527
525bool OContactAccessBackend_XML::remove ( int uid ) 528bool OContactAccessBackend_XML::remove ( int uid )
526{ 529{
527 m_changed = true; 530 m_changed = true;
528 531
529 OContact* found = m_uidToContact.find ( QString().setNum( uid ) ); 532 OContact* found = m_uidToContact.find ( QString().setNum( uid ) );
530 533
531 if ( found ) { 534 if ( found ) {
532 updateJournal ( *found, ACTION_REMOVE); 535 updateJournal ( *found, ACTION_REMOVE);
533 m_contactList.removeRef ( found ); 536 m_contactList.removeRef ( found );
534 m_uidToContact.remove( QString().setNum( uid ) ); 537 m_uidToContact.remove( QString().setNum( uid ) );
535 538
536 return true; 539 return true;
537 } else 540 } else
538 return false; 541 return false;
539} 542}
540 543
541bool OContactAccessBackend_XML::reload(){ 544bool OContactAccessBackend_XML::reload(){
542 /* Reload is the same as load in this implementation */ 545 /* Reload is the same as load in this implementation */
543 return ( load() ); 546 return ( load() );
544} 547}
545 548
546void OContactAccessBackend_XML::addContact_p( const OContact &newcontact ) 549void OContactAccessBackend_XML::addContact_p( const OContact &newcontact )
547{ 550{
548 OContact* contRef = new OContact( newcontact ); 551 OContact* contRef = new OContact( newcontact );
549 552
550 m_contactList.append ( contRef ); 553 m_contactList.append ( contRef );
551 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); 554 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef );
552} 555}
553 556
554/* This function loads the xml-database and the journalfile */ 557/* This function loads the xml-database and the journalfile */
555bool OContactAccessBackend_XML::load( const QString filename, bool isJournal ) 558bool OContactAccessBackend_XML::load( const QString filename, bool isJournal )
556{ 559{
557 560
558 /* We use the time of the last read to check if the file was 561 /* We use the time of the last read to check if the file was
559 * changed externally. 562 * changed externally.
560 */ 563 */
561 if ( !isJournal ){ 564 if ( !isJournal ){
562 QFileInfo fi( filename ); 565 QFileInfo fi( filename );
563 m_readtime = fi.lastModified (); 566 m_readtime = fi.lastModified ();
564 } 567 }
565 568
566 const int JOURNALACTION = Qtopia::Notes + 1; 569 const int JOURNALACTION = Qtopia::Notes + 1;
567 const int JOURNALROW = JOURNALACTION + 1; 570 const int JOURNALROW = JOURNALACTION + 1;
568 571
569 bool foundAction = false; 572 bool foundAction = false;
570 journal_action action = ACTION_ADD; 573 journal_action action = ACTION_ADD;
571 int journalKey = 0; 574 int journalKey = 0;
572 QMap<int, QString> contactMap; 575 QMap<int, QString> contactMap;
573 QMap<QString, QString> customMap; 576 QMap<QString, QString> customMap;
574 QMap<QString, QString>::Iterator customIt; 577 QMap<QString, QString>::Iterator customIt;
575 QAsciiDict<int> dict( 47 ); 578 QAsciiDict<int> dict( 47 );
576 579
577 dict.setAutoDelete( TRUE ); 580 dict.setAutoDelete( TRUE );
578 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 581 dict.insert( "Uid", new int(Qtopia::AddressUid) );
579 dict.insert( "Title", new int(Qtopia::Title) ); 582 dict.insert( "Title", new int(Qtopia::Title) );
580 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 583 dict.insert( "FirstName", new int(Qtopia::FirstName) );
581 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 584 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
582 dict.insert( "LastName", new int(Qtopia::LastName) ); 585 dict.insert( "LastName", new int(Qtopia::LastName) );
583 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 586 dict.insert( "Suffix", new int(Qtopia::Suffix) );
584 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 587 dict.insert( "FileAs", new int(Qtopia::FileAs) );
585 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 588 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
586 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 589 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
587 dict.insert( "Emails", new int(Qtopia::Emails) ); 590 dict.insert( "Emails", new int(Qtopia::Emails) );
588 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 591 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
589 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 592 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
590 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 593 dict.insert( "HomeState", new int(Qtopia::HomeState) );
591 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 594 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
592 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 595 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
593 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 596 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
594 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 597 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
595 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 598 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
596 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 599 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
597 dict.insert( "Company", new int(Qtopia::Company) ); 600 dict.insert( "Company", new int(Qtopia::Company) );
598 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 601 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
599 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 602 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
600 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 603 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
601 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 604 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
602 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 605 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
603 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 606 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
604 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 607 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
605 dict.insert( "Department", new int(Qtopia::Department) ); 608 dict.insert( "Department", new int(Qtopia::Department) );
606 dict.insert( "Office", new int(Qtopia::Office) ); 609 dict.insert( "Office", new int(Qtopia::Office) );
607 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); 610 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
608 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); 611 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
609 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); 612 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
610 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); 613 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
611 dict.insert( "Profession", new int(Qtopia::Profession) ); 614 dict.insert( "Profession", new int(Qtopia::Profession) );
612 dict.insert( "Assistant", new int(Qtopia::Assistant) ); 615 dict.insert( "Assistant", new int(Qtopia::Assistant) );
613 dict.insert( "Manager", new int(Qtopia::Manager) ); 616 dict.insert( "Manager", new int(Qtopia::Manager) );
614 dict.insert( "Spouse", new int(Qtopia::Spouse) ); 617 dict.insert( "Spouse", new int(Qtopia::Spouse) );
615 dict.insert( "Children", new int(Qtopia::Children) ); 618 dict.insert( "Children", new int(Qtopia::Children) );
616 dict.insert( "Gender", new int(Qtopia::Gender) ); 619 dict.insert( "Gender", new int(Qtopia::Gender) );
617 dict.insert( "Birthday", new int(Qtopia::Birthday) ); 620 dict.insert( "Birthday", new int(Qtopia::Birthday) );
618 dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); 621 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
619 dict.insert( "Nickname", new int(Qtopia::Nickname) ); 622 dict.insert( "Nickname", new int(Qtopia::Nickname) );
620 dict.insert( "Notes", new int(Qtopia::Notes) ); 623 dict.insert( "Notes", new int(Qtopia::Notes) );
621 dict.insert( "action", new int(JOURNALACTION) ); 624 dict.insert( "action", new int(JOURNALACTION) );
622 dict.insert( "actionrow", new int(JOURNALROW) ); 625 dict.insert( "actionrow", new int(JOURNALROW) );
623 626
624 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() ); 627 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() );
625 628
626 XMLElement *root = XMLElement::load( filename ); 629 XMLElement *root = XMLElement::load( filename );
627 if(root != 0l ){ // start parsing 630 if(root != 0l ){ // start parsing
628 /* Parse all XML-Elements and put the data into the 631 /* Parse all XML-Elements and put the data into the
629 * Contact-Class 632 * Contact-Class
630 */ 633 */
631 XMLElement *element = root->firstChild(); 634 XMLElement *element = root->firstChild();
632 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() ); 635 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() );
633 element = element->firstChild(); 636 element = element->firstChild();
634 637
635 /* Search Tag "Contacts" which is the parent of all Contacts */ 638 /* Search Tag "Contacts" which is the parent of all Contacts */
636 while( element && !isJournal ){ 639 while( element && !isJournal ){
637 if( element->tagName() != QString::fromLatin1("Contacts") ){ 640 if( element->tagName() != QString::fromLatin1("Contacts") ){
638 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s", 641 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s",
639 // element->tagName().latin1()); 642 // element->tagName().latin1());
640 element = element->nextChild(); 643 element = element->nextChild();
641 } else { 644 } else {
642 element = element->firstChild(); 645 element = element->firstChild();
643 break; 646 break;
644 } 647 }
645 } 648 }
646 /* Parse all Contacts and ignore unknown tags */ 649 /* Parse all Contacts and ignore unknown tags */
647 while( element ){ 650 while( element ){
648 if( element->tagName() != QString::fromLatin1("Contact") ){ 651 if( element->tagName() != QString::fromLatin1("Contact") ){
649 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s", 652 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s",
650 // element->tagName().latin1()); 653 // element->tagName().latin1());
651 element = element->nextChild(); 654 element = element->nextChild();
652 continue; 655 continue;
653 } 656 }
654 /* Found alement with tagname "contact", now parse and store all 657 /* Found alement with tagname "contact", now parse and store all
655 * attributes contained 658 * attributes contained
656 */ 659 */
657 //qWarning("OContactDefBack::load element tagName() : %s", 660 //qWarning("OContactDefBack::load element tagName() : %s",
658 // element->tagName().latin1() ); 661 // element->tagName().latin1() );
659 QString dummy; 662 QString dummy;
660 foundAction = false; 663 foundAction = false;
661 664
662 XMLElement::AttributeMap aMap = element->attributes(); 665 XMLElement::AttributeMap aMap = element->attributes();
663 XMLElement::AttributeMap::Iterator it; 666 XMLElement::AttributeMap::Iterator it;
664 contactMap.clear(); 667 contactMap.clear();
665 customMap.clear(); 668 customMap.clear();
666 for( it = aMap.begin(); it != aMap.end(); ++it ){ 669 for( it = aMap.begin(); it != aMap.end(); ++it ){
667 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); 670 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1());
668 671
669 int *find = dict[ it.key() ]; 672 int *find = dict[ it.key() ];
670 /* Unknown attributes will be stored as "Custom" elements */ 673 /* Unknown attributes will be stored as "Custom" elements */
671 if ( !find ) { 674 if ( !find ) {
672 qWarning("Attribute %s not known.", it.key().latin1()); 675 qWarning("Attribute %s not known.", it.key().latin1());
673 //contact.setCustomField(it.key(), it.data()); 676 //contact.setCustomField(it.key(), it.data());
674 customMap.insert( it.key(), it.data() ); 677 customMap.insert( it.key(), it.data() );
675 continue; 678 continue;
676 } 679 }
677 680
678 /* Check if special conversion is needed and add attribute 681 /* Check if special conversion is needed and add attribute
679 * into Contact class 682 * into Contact class
680 */ 683 */
681 switch( *find ) { 684 switch( *find ) {
682 /* 685 /*
683 case Qtopia::AddressUid: 686 case Qtopia::AddressUid:
684 contact.setUid( it.data().toInt() ); 687 contact.setUid( it.data().toInt() );
685 break; 688 break;
686 case Qtopia::AddressCategory: 689 case Qtopia::AddressCategory:
687 contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); 690 contact.setCategories( Qtopia::Record::idsFromString( it.data( )));
688 break; 691 break;
689 */ 692 */
690 case JOURNALACTION: 693 case JOURNALACTION:
691 action = journal_action(it.data().toInt()); 694 action = journal_action(it.data().toInt());
692 foundAction = true; 695 foundAction = true;
693 qWarning ("ODefBack(journal)::ACTION found: %d", action); 696 qWarning ("ODefBack(journal)::ACTION found: %d", action);
694 break; 697 break;
695 case JOURNALROW: 698 case JOURNALROW:
696 journalKey = it.data().toInt(); 699 journalKey = it.data().toInt();
697 break; 700 break;
698 default: // no conversion needed add them to the map 701 default: // no conversion needed add them to the map
699 contactMap.insert( *find, it.data() ); 702 contactMap.insert( *find, it.data() );
700 break; 703 break;
701 } 704 }
702 } 705 }
703 /* now generate the Contact contact */ 706 /* now generate the Contact contact */
704 OContact contact( contactMap ); 707 OContact contact( contactMap );
705 708
706 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { 709 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) {
707 contact.setCustomField( customIt.key(), customIt.data() ); 710 contact.setCustomField( customIt.key(), customIt.data() );
708 } 711 }
709 712
710 if (foundAction){ 713 if (foundAction){
711 foundAction = false; 714 foundAction = false;
712 switch ( action ) { 715 switch ( action ) {
713 case ACTION_ADD: 716 case ACTION_ADD:
714 addContact_p (contact); 717 addContact_p (contact);
715 break; 718 break;
716 case ACTION_REMOVE: 719 case ACTION_REMOVE:
717 if ( !remove (contact.uid()) ) 720 if ( !remove (contact.uid()) )
718 qWarning ("ODefBack(journal)::Unable to remove uid: %d", 721 qWarning ("ODefBack(journal)::Unable to remove uid: %d",
719 contact.uid() ); 722 contact.uid() );
720 break; 723 break;
721 case ACTION_REPLACE: 724 case ACTION_REPLACE:
722 if ( !replace ( contact ) ) 725 if ( !replace ( contact ) )
723 qWarning ("ODefBack(journal)::Unable to replace uid: %d", 726 qWarning ("ODefBack(journal)::Unable to replace uid: %d",
724 contact.uid() ); 727 contact.uid() );
725 break; 728 break;
726 default: 729 default:
727 qWarning ("Unknown action: ignored !"); 730 qWarning ("Unknown action: ignored !");
728 break; 731 break;
729 } 732 }
730 }else{ 733 }else{
731 /* Add contact to list */ 734 /* Add contact to list */
732 addContact_p (contact); 735 addContact_p (contact);
733 } 736 }
734 737
735 /* Move to next element */ 738 /* Move to next element */
736 element = element->nextChild(); 739 element = element->nextChild();
737 } 740 }
738 }else { 741 }else {
739 qWarning("ODefBack::could not load"); 742 qWarning("ODefBack::could not load");
740 } 743 }
741 delete root; 744 delete root;
742 qWarning("returning from loading" ); 745 qWarning("returning from loading" );
743 return true; 746 return true;
744} 747}
745 748
746 749
747void OContactAccessBackend_XML::updateJournal( const OContact& cnt, 750void OContactAccessBackend_XML::updateJournal( const OContact& cnt,
748 journal_action action ) 751 journal_action action )
749{ 752{
750 QFile f( m_journalName ); 753 QFile f( m_journalName );
751 bool created = !f.exists(); 754 bool created = !f.exists();
752 if ( !f.open(IO_WriteOnly|IO_Append) ) 755 if ( !f.open(IO_WriteOnly|IO_Append) )
753 return; 756 return;
754 757
755 QString buf; 758 QString buf;
756 QCString str; 759 QCString str;
757 760
758 // if the file was created, we have to set the Tag "<CONTACTS>" to 761 // if the file was created, we have to set the Tag "<CONTACTS>" to
759 // get a XML-File which is readable by our parser. 762 // get a XML-File which is readable by our parser.
760 // This is just a cheat, but better than rewrite the parser. 763 // This is just a cheat, but better than rewrite the parser.
761 if ( created ){ 764 if ( created ){
762 buf = "<Contacts>"; 765 buf = "<Contacts>";
763 QCString cstr = buf.utf8(); 766 QCString cstr = buf.utf8();
764 f.writeBlock( cstr.data(), cstr.length() ); 767 f.writeBlock( cstr.data(), cstr.length() );
765 } 768 }
766 769
767 buf = "<Contact "; 770 buf = "<Contact ";
768 cnt.save( buf ); 771 cnt.save( buf );
769 buf += " action=\"" + QString::number( (int)action ) + "\" "; 772 buf += " action=\"" + QString::number( (int)action ) + "\" ";
770 buf += "/>\n"; 773 buf += "/>\n";
771 QCString cstr = buf.utf8(); 774 QCString cstr = buf.utf8();
772 f.writeBlock( cstr.data(), cstr.length() ); 775 f.writeBlock( cstr.data(), cstr.length() );
773} 776}
774 777
775void OContactAccessBackend_XML::removeJournal() 778void OContactAccessBackend_XML::removeJournal()
776{ 779{
777 QFile f ( m_journalName ); 780 QFile f ( m_journalName );
778 if ( f.exists() ) 781 if ( f.exists() )
779 f.remove(); 782 f.remove();
780} 783}
781 784