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