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