summaryrefslogtreecommitdiff
path: root/libopie/pim
Unidiff
Diffstat (limited to 'libopie/pim') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.h17
1 files changed, 11 insertions, 6 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,539 +1,544 @@
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) );