summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.cpp5
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp5
2 files changed, 8 insertions, 2 deletions
diff --git a/libopie/pim/ocontactaccessbackend_xml.cpp b/libopie/pim/ocontactaccessbackend_xml.cpp
index 9fe3d1e..c5a7820 100644
--- a/libopie/pim/ocontactaccessbackend_xml.cpp
+++ b/libopie/pim/ocontactaccessbackend_xml.cpp
@@ -1,299 +1,302 @@
1/* 1/*
2 * XML Backend for the OPIE-Contact Database. 2 * XML Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed... 12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 * 13 *
14 * 14 *
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.4 2003/03/21 14:32:54 mickeyl
21 * g++ compliance fix: default arguments belong into the declaration, but not the definition
22 *
20 * Revision 1.3 2003/03/21 12:26:28 eilers 23 * Revision 1.3 2003/03/21 12:26:28 eilers
21 * Fixing small bug: If we search a birthday from today to today, it returned 24 * Fixing small bug: If we search a birthday from today to today, it returned
22 * every contact .. 25 * every contact ..
23 * 26 *
24 * Revision 1.2 2003/03/21 10:33:09 eilers 27 * Revision 1.2 2003/03/21 10:33:09 eilers
25 * Merged speed optimized xml backend for contacts to main. 28 * Merged speed optimized xml backend for contacts to main.
26 * Added QDateTime to querybyexample. For instance, it is now possible to get 29 * Added QDateTime to querybyexample. For instance, it is now possible to get
27 * all Birthdays/Anniversaries between two dates. This should be used 30 * all Birthdays/Anniversaries between two dates. This should be used
28 * to show all birthdays in the datebook.. 31 * to show all birthdays in the datebook..
29 * This change is sourcecode backward compatible but you have to upgrade 32 * This change is sourcecode backward compatible but you have to upgrade
30 * the binaries for today-addressbook. 33 * the binaries for today-addressbook.
31 * 34 *
32 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers 35 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers
33 * Speed optimization. Removed the sequential search loops. 36 * Speed optimization. Removed the sequential search loops.
34 * 37 *
35 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers 38 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers
36 * Writing offsets to debug output.. 39 * Writing offsets to debug output..
37 * 40 *
38 * Revision 1.1 2003/02/09 15:05:01 eilers 41 * Revision 1.1 2003/02/09 15:05:01 eilers
39 * Nothing happened.. Just some cleanup before I will start.. 42 * Nothing happened.. Just some cleanup before I will start..
40 * 43 *
41 * Revision 1.12 2003/01/03 16:58:03 eilers 44 * Revision 1.12 2003/01/03 16:58:03 eilers
42 * Reenable debug output 45 * Reenable debug output
43 * 46 *
44 * Revision 1.11 2003/01/03 12:31:28 eilers 47 * Revision 1.11 2003/01/03 12:31:28 eilers
45 * Bugfix for calculating data diffs.. 48 * Bugfix for calculating data diffs..
46 * 49 *
47 * Revision 1.10 2003/01/02 14:27:12 eilers 50 * Revision 1.10 2003/01/02 14:27:12 eilers
48 * Improved query by example: Search by date is possible.. First step 51 * Improved query by example: Search by date is possible.. First step
49 * for a today plugin for birthdays.. 52 * for a today plugin for birthdays..
50 * 53 *
51 * Revision 1.9 2002/12/08 12:48:57 eilers 54 * Revision 1.9 2002/12/08 12:48:57 eilers
52 * Moved journal-enum from ocontact into i the xml-backend.. 55 * Moved journal-enum from ocontact into i the xml-backend..
53 * 56 *
54 * Revision 1.8 2002/11/14 17:04:24 eilers 57 * Revision 1.8 2002/11/14 17:04:24 eilers
55 * Sorting will now work if fullname is identical on some entries 58 * Sorting will now work if fullname is identical on some entries
56 * 59 *
57 * Revision 1.7 2002/11/13 15:02:46 eilers 60 * Revision 1.7 2002/11/13 15:02:46 eilers
58 * Small Bug in sorted fixed 61 * Small Bug in sorted fixed
59 * 62 *
60 * Revision 1.6 2002/11/13 14:14:51 eilers 63 * Revision 1.6 2002/11/13 14:14:51 eilers
61 * Added sorted for Contacts.. 64 * Added sorted for Contacts..
62 * 65 *
63 * Revision 1.5 2002/11/01 15:10:42 eilers 66 * Revision 1.5 2002/11/01 15:10:42 eilers
64 * Added regExp-search in database for all fields in a contact. 67 * Added regExp-search in database for all fields in a contact.
65 * 68 *
66 * Revision 1.4 2002/10/16 10:52:40 eilers 69 * Revision 1.4 2002/10/16 10:52:40 eilers
67 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 70 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
68 * 71 *
69 * Revision 1.3 2002/10/14 16:21:54 eilers 72 * Revision 1.3 2002/10/14 16:21:54 eilers
70 * Some minor interface updates 73 * Some minor interface updates
71 * 74 *
72 * Revision 1.2 2002/10/07 17:34:24 eilers 75 * Revision 1.2 2002/10/07 17:34:24 eilers
73 * added OBackendFactory for advanced backend access 76 * added OBackendFactory for advanced backend access
74 * 77 *
75 * Revision 1.1 2002/09/27 17:11:44 eilers 78 * Revision 1.1 2002/09/27 17:11:44 eilers
76 * Added API for accessing the Contact-Database ! It is compiling, but 79 * Added API for accessing the Contact-Database ! It is compiling, but
77 * please do not expect that anything is working ! 80 * please do not expect that anything is working !
78 * I will debug that stuff in the next time .. 81 * I will debug that stuff in the next time ..
79 * Please read README_COMPILE for compiling ! 82 * Please read README_COMPILE for compiling !
80 * 83 *
81 * 84 *
82 */ 85 */
83 86
84#include "ocontactaccessbackend_xml.h" 87#include "ocontactaccessbackend_xml.h"
85 88
86#include <qasciidict.h> 89#include <qasciidict.h>
87#include <qdatetime.h> 90#include <qdatetime.h>
88#include <qfile.h> 91#include <qfile.h>
89#include <qfileinfo.h> 92#include <qfileinfo.h>
90#include <qregexp.h> 93#include <qregexp.h>
91#include <qarray.h> 94#include <qarray.h>
92#include <qmap.h> 95#include <qmap.h>
93#include <qdatetime.h> 96#include <qdatetime.h>
94 97
95#include <qpe/global.h> 98#include <qpe/global.h>
96 99
97#include <opie/xmltree.h> 100#include <opie/xmltree.h>
98#include "ocontactaccessbackend.h" 101#include "ocontactaccessbackend.h"
99#include "ocontactaccess.h" 102#include "ocontactaccess.h"
100 103
101#include <stdlib.h> 104#include <stdlib.h>
102#include <errno.h> 105#include <errno.h>
103 106
104using namespace Opie; 107using namespace Opie;
105 108
106 109
107OContactAccessBackend_XML::OContactAccessBackend_XML ( QString appname, QString filename = 0l ): 110OContactAccessBackend_XML::OContactAccessBackend_XML ( QString appname, QString filename ):
108 m_changed( false ) 111 m_changed( false )
109{ 112{
110 // Just m_contactlist should call delete if an entry 113 // Just m_contactlist should call delete if an entry
111 // is removed. 114 // is removed.
112 m_contactList.setAutoDelete( true ); 115 m_contactList.setAutoDelete( true );
113 m_uidToContact.setAutoDelete( false ); 116 m_uidToContact.setAutoDelete( false );
114 117
115 m_appName = appname; 118 m_appName = appname;
116 119
117 /* Set journalfile name ... */ 120 /* Set journalfile name ... */
118 m_journalName = getenv("HOME"); 121 m_journalName = getenv("HOME");
119 m_journalName +="/.abjournal" + appname; 122 m_journalName +="/.abjournal" + appname;
120 123
121 /* Expecting to access the default filename if nothing else is set */ 124 /* Expecting to access the default filename if nothing else is set */
122 if ( filename.isEmpty() ){ 125 if ( filename.isEmpty() ){
123 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 126 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
124 } else 127 } else
125 m_fileName = filename; 128 m_fileName = filename;
126 129
127 /* Load Database now */ 130 /* Load Database now */
128 load (); 131 load ();
129} 132}
130 133
131bool OContactAccessBackend_XML::save() 134bool OContactAccessBackend_XML::save()
132{ 135{
133 136
134 if ( !m_changed ) 137 if ( !m_changed )
135 return true; 138 return true;
136 139
137 QString strNewFile = m_fileName + ".new"; 140 QString strNewFile = m_fileName + ".new";
138 QFile f( strNewFile ); 141 QFile f( strNewFile );
139 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 142 if ( !f.open( IO_WriteOnly|IO_Raw ) )
140 return false; 143 return false;
141 144
142 int total_written; 145 int total_written;
143 int idx_offset = 0; 146 int idx_offset = 0;
144 QString out; 147 QString out;
145 148
146 // Write Header 149 // Write Header
147 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 150 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
148 " <Groups>\n" 151 " <Groups>\n"
149 " </Groups>\n" 152 " </Groups>\n"
150 " <Contacts>\n"; 153 " <Contacts>\n";
151 QCString cstr = out.utf8(); 154 QCString cstr = out.utf8();
152 f.writeBlock( cstr.data(), cstr.length() ); 155 f.writeBlock( cstr.data(), cstr.length() );
153 idx_offset += cstr.length(); 156 idx_offset += cstr.length();
154 out = ""; 157 out = "";
155 158
156 // Write all contacts 159 // Write all contacts
157 QListIterator<OContact> it( m_contactList ); 160 QListIterator<OContact> it( m_contactList );
158 for ( ; it.current(); ++it ) { 161 for ( ; it.current(); ++it ) {
159 qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); 162 qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset );
160 out += "<Contact "; 163 out += "<Contact ";
161 (*it)->save( out ); 164 (*it)->save( out );
162 out += "/>\n"; 165 out += "/>\n";
163 cstr = out.utf8(); 166 cstr = out.utf8();
164 total_written = f.writeBlock( cstr.data(), cstr.length() ); 167 total_written = f.writeBlock( cstr.data(), cstr.length() );
165 idx_offset += cstr.length(); 168 idx_offset += cstr.length();
166 if ( total_written != int(cstr.length()) ) { 169 if ( total_written != int(cstr.length()) ) {
167 f.close(); 170 f.close();
168 QFile::remove( strNewFile ); 171 QFile::remove( strNewFile );
169 return false; 172 return false;
170 } 173 }
171 out = ""; 174 out = "";
172 } 175 }
173 out += " </Contacts>\n</AddressBook>\n"; 176 out += " </Contacts>\n</AddressBook>\n";
174 177
175 // Write Footer 178 // Write Footer
176 cstr = out.utf8(); 179 cstr = out.utf8();
177 total_written = f.writeBlock( cstr.data(), cstr.length() ); 180 total_written = f.writeBlock( cstr.data(), cstr.length() );
178 if ( total_written != int( cstr.length() ) ) { 181 if ( total_written != int( cstr.length() ) ) {
179 f.close(); 182 f.close();
180 QFile::remove( strNewFile ); 183 QFile::remove( strNewFile );
181 return false; 184 return false;
182 } 185 }
183 f.close(); 186 f.close();
184 187
185 // move the file over, I'm just going to use the system call 188 // move the file over, I'm just going to use the system call
186 // because, I don't feel like using QDir. 189 // because, I don't feel like using QDir.
187 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 190 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
188 qWarning( "problem renaming file %s to %s, errno: %d", 191 qWarning( "problem renaming file %s to %s, errno: %d",
189 strNewFile.latin1(), m_journalName.latin1(), errno ); 192 strNewFile.latin1(), m_journalName.latin1(), errno );
190 // remove the tmp file... 193 // remove the tmp file...
191 QFile::remove( strNewFile ); 194 QFile::remove( strNewFile );
192 } 195 }
193 196
194 /* The journalfile should be removed now... */ 197 /* The journalfile should be removed now... */
195 removeJournal(); 198 removeJournal();
196 199
197 m_changed = false; 200 m_changed = false;
198 return true; 201 return true;
199} 202}
200 203
201bool OContactAccessBackend_XML::load () 204bool OContactAccessBackend_XML::load ()
202{ 205{
203 m_contactList.clear(); 206 m_contactList.clear();
204 m_uidToContact.clear(); 207 m_uidToContact.clear();
205 208
206 /* Load XML-File and journal if it exists */ 209 /* Load XML-File and journal if it exists */
207 if ( !load ( m_fileName, false ) ) 210 if ( !load ( m_fileName, false ) )
208 return false; 211 return false;
209 /* The returncode of the journalfile is ignored due to the 212 /* The returncode of the journalfile is ignored due to the
210 * fact that it does not exist when this class is instantiated ! 213 * fact that it does not exist when this class is instantiated !
211 * But there may such a file exist, if the application crashed. 214 * But there may such a file exist, if the application crashed.
212 * Therefore we try to load it to get the changes before the # 215 * Therefore we try to load it to get the changes before the #
213 * crash happened... 216 * crash happened...
214 */ 217 */
215 load (m_journalName, true); 218 load (m_journalName, true);
216 219
217 return true; 220 return true;
218} 221}
219 222
220void OContactAccessBackend_XML::clear () 223void OContactAccessBackend_XML::clear ()
221{ 224{
222 m_contactList.clear(); 225 m_contactList.clear();
223 m_uidToContact.clear(); 226 m_uidToContact.clear();
224 227
225 m_changed = false; 228 m_changed = false;
226} 229}
227 230
228bool OContactAccessBackend_XML::wasChangedExternally() 231bool OContactAccessBackend_XML::wasChangedExternally()
229{ 232{
230 QFileInfo fi( m_fileName ); 233 QFileInfo fi( m_fileName );
231 234
232 QDateTime lastmod = fi.lastModified (); 235 QDateTime lastmod = fi.lastModified ();
233 236
234 return (lastmod != m_readtime); 237 return (lastmod != m_readtime);
235} 238}
236 239
237QArray<int> OContactAccessBackend_XML::allRecords() const 240QArray<int> OContactAccessBackend_XML::allRecords() const
238{ 241{
239 QArray<int> uid_list( m_contactList.count() ); 242 QArray<int> uid_list( m_contactList.count() );
240 243
241 uint counter = 0; 244 uint counter = 0;
242 QListIterator<OContact> it( m_contactList ); 245 QListIterator<OContact> it( m_contactList );
243 for( ; it.current(); ++it ){ 246 for( ; it.current(); ++it ){
244 uid_list[counter++] = (*it)->uid(); 247 uid_list[counter++] = (*it)->uid();
245 } 248 }
246 249
247 return ( uid_list ); 250 return ( uid_list );
248} 251}
249 252
250OContact OContactAccessBackend_XML::find ( int uid ) const 253OContact OContactAccessBackend_XML::find ( int uid ) const
251{ 254{
252 OContact foundContact; //Create empty contact 255 OContact foundContact; //Create empty contact
253 256
254 OContact* found = m_uidToContact.find( QString().setNum( uid ) ); 257 OContact* found = m_uidToContact.find( QString().setNum( uid ) );
255 258
256 if ( found ){ 259 if ( found ){
257 foundContact = *found; 260 foundContact = *found;
258 } 261 }
259 262
260 return ( foundContact ); 263 return ( foundContact );
261} 264}
262 265
263QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings, 266QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings,
264 const QDateTime& d ) 267 const QDateTime& d )
265{ 268{
266 269
267 QArray<int> m_currentQuery( m_contactList.count() ); 270 QArray<int> m_currentQuery( m_contactList.count() );
268 QListIterator<OContact> it( m_contactList ); 271 QListIterator<OContact> it( m_contactList );
269 uint arraycounter = 0; 272 uint arraycounter = 0;
270 273
271 for( ; it.current(); ++it ){ 274 for( ; it.current(); ++it ){
272 /* Search all fields and compare them with query object. Store them into list 275 /* Search all fields and compare them with query object. Store them into list
273 * if all fields matches. 276 * if all fields matches.
274 */ 277 */
275 QDate* queryDate = 0l; 278 QDate* queryDate = 0l;
276 QDate* checkDate = 0l; 279 QDate* checkDate = 0l;
277 bool allcorrect = true; 280 bool allcorrect = true;
278 for ( int i = 0; i < Qtopia::Groups; i++ ) { 281 for ( int i = 0; i < Qtopia::Groups; i++ ) {
279 // Birthday and anniversary are special nonstring fields and should 282 // Birthday and anniversary are special nonstring fields and should
280 // be handled specially 283 // be handled specially
281 switch ( i ){ 284 switch ( i ){
282 case Qtopia::Birthday: 285 case Qtopia::Birthday:
283 queryDate = new QDate( query.birthday() ); 286 queryDate = new QDate( query.birthday() );
284 checkDate = new QDate( (*it)->birthday() ); 287 checkDate = new QDate( (*it)->birthday() );
285 case Qtopia::Anniversary: 288 case Qtopia::Anniversary:
286 if ( queryDate == 0l ){ 289 if ( queryDate == 0l ){
287 queryDate = new QDate( query.anniversary() ); 290 queryDate = new QDate( query.anniversary() );
288 checkDate = new QDate( (*it)->anniversary() ); 291 checkDate = new QDate( (*it)->anniversary() );
289 } 292 }
290 293
291 if ( queryDate->isValid() ){ 294 if ( queryDate->isValid() ){
292 if( checkDate->isValid() ){ 295 if( checkDate->isValid() ){
293 if ( settings & OContactAccess::DateYear ){ 296 if ( settings & OContactAccess::DateYear ){
294 if ( queryDate->year() != checkDate->year() ) 297 if ( queryDate->year() != checkDate->year() )
295 allcorrect = false; 298 allcorrect = false;
296 } 299 }
297 if ( settings & OContactAccess::DateMonth ){ 300 if ( settings & OContactAccess::DateMonth ){
298 if ( queryDate->month() != checkDate->month() ) 301 if ( queryDate->month() != checkDate->month() )
299 allcorrect = false; 302 allcorrect = false;
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
index 9fe3d1e..c5a7820 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
@@ -1,299 +1,302 @@
1/* 1/*
2 * XML Backend for the OPIE-Contact Database. 2 * XML Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed... 12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 * 13 *
14 * 14 *
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.4 2003/03/21 14:32:54 mickeyl
21 * g++ compliance fix: default arguments belong into the declaration, but not the definition
22 *
20 * Revision 1.3 2003/03/21 12:26:28 eilers 23 * Revision 1.3 2003/03/21 12:26:28 eilers
21 * Fixing small bug: If we search a birthday from today to today, it returned 24 * Fixing small bug: If we search a birthday from today to today, it returned
22 * every contact .. 25 * every contact ..
23 * 26 *
24 * Revision 1.2 2003/03/21 10:33:09 eilers 27 * Revision 1.2 2003/03/21 10:33:09 eilers
25 * Merged speed optimized xml backend for contacts to main. 28 * Merged speed optimized xml backend for contacts to main.
26 * Added QDateTime to querybyexample. For instance, it is now possible to get 29 * Added QDateTime to querybyexample. For instance, it is now possible to get
27 * all Birthdays/Anniversaries between two dates. This should be used 30 * all Birthdays/Anniversaries between two dates. This should be used
28 * to show all birthdays in the datebook.. 31 * to show all birthdays in the datebook..
29 * This change is sourcecode backward compatible but you have to upgrade 32 * This change is sourcecode backward compatible but you have to upgrade
30 * the binaries for today-addressbook. 33 * the binaries for today-addressbook.
31 * 34 *
32 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers 35 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers
33 * Speed optimization. Removed the sequential search loops. 36 * Speed optimization. Removed the sequential search loops.
34 * 37 *
35 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers 38 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers
36 * Writing offsets to debug output.. 39 * Writing offsets to debug output..
37 * 40 *
38 * Revision 1.1 2003/02/09 15:05:01 eilers 41 * Revision 1.1 2003/02/09 15:05:01 eilers
39 * Nothing happened.. Just some cleanup before I will start.. 42 * Nothing happened.. Just some cleanup before I will start..
40 * 43 *
41 * Revision 1.12 2003/01/03 16:58:03 eilers 44 * Revision 1.12 2003/01/03 16:58:03 eilers
42 * Reenable debug output 45 * Reenable debug output
43 * 46 *
44 * Revision 1.11 2003/01/03 12:31:28 eilers 47 * Revision 1.11 2003/01/03 12:31:28 eilers
45 * Bugfix for calculating data diffs.. 48 * Bugfix for calculating data diffs..
46 * 49 *
47 * Revision 1.10 2003/01/02 14:27:12 eilers 50 * Revision 1.10 2003/01/02 14:27:12 eilers
48 * Improved query by example: Search by date is possible.. First step 51 * Improved query by example: Search by date is possible.. First step
49 * for a today plugin for birthdays.. 52 * for a today plugin for birthdays..
50 * 53 *
51 * Revision 1.9 2002/12/08 12:48:57 eilers 54 * Revision 1.9 2002/12/08 12:48:57 eilers
52 * Moved journal-enum from ocontact into i the xml-backend.. 55 * Moved journal-enum from ocontact into i the xml-backend..
53 * 56 *
54 * Revision 1.8 2002/11/14 17:04:24 eilers 57 * Revision 1.8 2002/11/14 17:04:24 eilers
55 * Sorting will now work if fullname is identical on some entries 58 * Sorting will now work if fullname is identical on some entries
56 * 59 *
57 * Revision 1.7 2002/11/13 15:02:46 eilers 60 * Revision 1.7 2002/11/13 15:02:46 eilers
58 * Small Bug in sorted fixed 61 * Small Bug in sorted fixed
59 * 62 *
60 * Revision 1.6 2002/11/13 14:14:51 eilers 63 * Revision 1.6 2002/11/13 14:14:51 eilers
61 * Added sorted for Contacts.. 64 * Added sorted for Contacts..
62 * 65 *
63 * Revision 1.5 2002/11/01 15:10:42 eilers 66 * Revision 1.5 2002/11/01 15:10:42 eilers
64 * Added regExp-search in database for all fields in a contact. 67 * Added regExp-search in database for all fields in a contact.
65 * 68 *
66 * Revision 1.4 2002/10/16 10:52:40 eilers 69 * Revision 1.4 2002/10/16 10:52:40 eilers
67 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 70 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
68 * 71 *
69 * Revision 1.3 2002/10/14 16:21:54 eilers 72 * Revision 1.3 2002/10/14 16:21:54 eilers
70 * Some minor interface updates 73 * Some minor interface updates
71 * 74 *
72 * Revision 1.2 2002/10/07 17:34:24 eilers 75 * Revision 1.2 2002/10/07 17:34:24 eilers
73 * added OBackendFactory for advanced backend access 76 * added OBackendFactory for advanced backend access
74 * 77 *
75 * Revision 1.1 2002/09/27 17:11:44 eilers 78 * Revision 1.1 2002/09/27 17:11:44 eilers
76 * Added API for accessing the Contact-Database ! It is compiling, but 79 * Added API for accessing the Contact-Database ! It is compiling, but
77 * please do not expect that anything is working ! 80 * please do not expect that anything is working !
78 * I will debug that stuff in the next time .. 81 * I will debug that stuff in the next time ..
79 * Please read README_COMPILE for compiling ! 82 * Please read README_COMPILE for compiling !
80 * 83 *
81 * 84 *
82 */ 85 */
83 86
84#include "ocontactaccessbackend_xml.h" 87#include "ocontactaccessbackend_xml.h"
85 88
86#include <qasciidict.h> 89#include <qasciidict.h>
87#include <qdatetime.h> 90#include <qdatetime.h>
88#include <qfile.h> 91#include <qfile.h>
89#include <qfileinfo.h> 92#include <qfileinfo.h>
90#include <qregexp.h> 93#include <qregexp.h>
91#include <qarray.h> 94#include <qarray.h>
92#include <qmap.h> 95#include <qmap.h>
93#include <qdatetime.h> 96#include <qdatetime.h>
94 97
95#include <qpe/global.h> 98#include <qpe/global.h>
96 99
97#include <opie/xmltree.h> 100#include <opie/xmltree.h>
98#include "ocontactaccessbackend.h" 101#include "ocontactaccessbackend.h"
99#include "ocontactaccess.h" 102#include "ocontactaccess.h"
100 103
101#include <stdlib.h> 104#include <stdlib.h>
102#include <errno.h> 105#include <errno.h>
103 106
104using namespace Opie; 107using namespace Opie;
105 108
106 109
107OContactAccessBackend_XML::OContactAccessBackend_XML ( QString appname, QString filename = 0l ): 110OContactAccessBackend_XML::OContactAccessBackend_XML ( QString appname, QString filename ):
108 m_changed( false ) 111 m_changed( false )
109{ 112{
110 // Just m_contactlist should call delete if an entry 113 // Just m_contactlist should call delete if an entry
111 // is removed. 114 // is removed.
112 m_contactList.setAutoDelete( true ); 115 m_contactList.setAutoDelete( true );
113 m_uidToContact.setAutoDelete( false ); 116 m_uidToContact.setAutoDelete( false );
114 117
115 m_appName = appname; 118 m_appName = appname;
116 119
117 /* Set journalfile name ... */ 120 /* Set journalfile name ... */
118 m_journalName = getenv("HOME"); 121 m_journalName = getenv("HOME");
119 m_journalName +="/.abjournal" + appname; 122 m_journalName +="/.abjournal" + appname;
120 123
121 /* Expecting to access the default filename if nothing else is set */ 124 /* Expecting to access the default filename if nothing else is set */
122 if ( filename.isEmpty() ){ 125 if ( filename.isEmpty() ){
123 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 126 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
124 } else 127 } else
125 m_fileName = filename; 128 m_fileName = filename;
126 129
127 /* Load Database now */ 130 /* Load Database now */
128 load (); 131 load ();
129} 132}
130 133
131bool OContactAccessBackend_XML::save() 134bool OContactAccessBackend_XML::save()
132{ 135{
133 136
134 if ( !m_changed ) 137 if ( !m_changed )
135 return true; 138 return true;
136 139
137 QString strNewFile = m_fileName + ".new"; 140 QString strNewFile = m_fileName + ".new";
138 QFile f( strNewFile ); 141 QFile f( strNewFile );
139 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 142 if ( !f.open( IO_WriteOnly|IO_Raw ) )
140 return false; 143 return false;
141 144
142 int total_written; 145 int total_written;
143 int idx_offset = 0; 146 int idx_offset = 0;
144 QString out; 147 QString out;
145 148
146 // Write Header 149 // Write Header
147 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 150 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
148 " <Groups>\n" 151 " <Groups>\n"
149 " </Groups>\n" 152 " </Groups>\n"
150 " <Contacts>\n"; 153 " <Contacts>\n";
151 QCString cstr = out.utf8(); 154 QCString cstr = out.utf8();
152 f.writeBlock( cstr.data(), cstr.length() ); 155 f.writeBlock( cstr.data(), cstr.length() );
153 idx_offset += cstr.length(); 156 idx_offset += cstr.length();
154 out = ""; 157 out = "";
155 158
156 // Write all contacts 159 // Write all contacts
157 QListIterator<OContact> it( m_contactList ); 160 QListIterator<OContact> it( m_contactList );
158 for ( ; it.current(); ++it ) { 161 for ( ; it.current(); ++it ) {
159 qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); 162 qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset );
160 out += "<Contact "; 163 out += "<Contact ";
161 (*it)->save( out ); 164 (*it)->save( out );
162 out += "/>\n"; 165 out += "/>\n";
163 cstr = out.utf8(); 166 cstr = out.utf8();
164 total_written = f.writeBlock( cstr.data(), cstr.length() ); 167 total_written = f.writeBlock( cstr.data(), cstr.length() );
165 idx_offset += cstr.length(); 168 idx_offset += cstr.length();
166 if ( total_written != int(cstr.length()) ) { 169 if ( total_written != int(cstr.length()) ) {
167 f.close(); 170 f.close();
168 QFile::remove( strNewFile ); 171 QFile::remove( strNewFile );
169 return false; 172 return false;
170 } 173 }
171 out = ""; 174 out = "";
172 } 175 }
173 out += " </Contacts>\n</AddressBook>\n"; 176 out += " </Contacts>\n</AddressBook>\n";
174 177
175 // Write Footer 178 // Write Footer
176 cstr = out.utf8(); 179 cstr = out.utf8();
177 total_written = f.writeBlock( cstr.data(), cstr.length() ); 180 total_written = f.writeBlock( cstr.data(), cstr.length() );
178 if ( total_written != int( cstr.length() ) ) { 181 if ( total_written != int( cstr.length() ) ) {
179 f.close(); 182 f.close();
180 QFile::remove( strNewFile ); 183 QFile::remove( strNewFile );
181 return false; 184 return false;
182 } 185 }
183 f.close(); 186 f.close();
184 187
185 // move the file over, I'm just going to use the system call 188 // move the file over, I'm just going to use the system call
186 // because, I don't feel like using QDir. 189 // because, I don't feel like using QDir.
187 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 190 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
188 qWarning( "problem renaming file %s to %s, errno: %d", 191 qWarning( "problem renaming file %s to %s, errno: %d",
189 strNewFile.latin1(), m_journalName.latin1(), errno ); 192 strNewFile.latin1(), m_journalName.latin1(), errno );
190 // remove the tmp file... 193 // remove the tmp file...
191 QFile::remove( strNewFile ); 194 QFile::remove( strNewFile );
192 } 195 }
193 196
194 /* The journalfile should be removed now... */ 197 /* The journalfile should be removed now... */
195 removeJournal(); 198 removeJournal();
196 199
197 m_changed = false; 200 m_changed = false;
198 return true; 201 return true;
199} 202}
200 203
201bool OContactAccessBackend_XML::load () 204bool OContactAccessBackend_XML::load ()
202{ 205{
203 m_contactList.clear(); 206 m_contactList.clear();
204 m_uidToContact.clear(); 207 m_uidToContact.clear();
205 208
206 /* Load XML-File and journal if it exists */ 209 /* Load XML-File and journal if it exists */
207 if ( !load ( m_fileName, false ) ) 210 if ( !load ( m_fileName, false ) )
208 return false; 211 return false;
209 /* The returncode of the journalfile is ignored due to the 212 /* The returncode of the journalfile is ignored due to the
210 * fact that it does not exist when this class is instantiated ! 213 * fact that it does not exist when this class is instantiated !
211 * But there may such a file exist, if the application crashed. 214 * But there may such a file exist, if the application crashed.
212 * Therefore we try to load it to get the changes before the # 215 * Therefore we try to load it to get the changes before the #
213 * crash happened... 216 * crash happened...
214 */ 217 */
215 load (m_journalName, true); 218 load (m_journalName, true);
216 219
217 return true; 220 return true;
218} 221}
219 222
220void OContactAccessBackend_XML::clear () 223void OContactAccessBackend_XML::clear ()
221{ 224{
222 m_contactList.clear(); 225 m_contactList.clear();
223 m_uidToContact.clear(); 226 m_uidToContact.clear();
224 227
225 m_changed = false; 228 m_changed = false;
226} 229}
227 230
228bool OContactAccessBackend_XML::wasChangedExternally() 231bool OContactAccessBackend_XML::wasChangedExternally()
229{ 232{
230 QFileInfo fi( m_fileName ); 233 QFileInfo fi( m_fileName );
231 234
232 QDateTime lastmod = fi.lastModified (); 235 QDateTime lastmod = fi.lastModified ();
233 236
234 return (lastmod != m_readtime); 237 return (lastmod != m_readtime);
235} 238}
236 239
237QArray<int> OContactAccessBackend_XML::allRecords() const 240QArray<int> OContactAccessBackend_XML::allRecords() const
238{ 241{
239 QArray<int> uid_list( m_contactList.count() ); 242 QArray<int> uid_list( m_contactList.count() );
240 243
241 uint counter = 0; 244 uint counter = 0;
242 QListIterator<OContact> it( m_contactList ); 245 QListIterator<OContact> it( m_contactList );
243 for( ; it.current(); ++it ){ 246 for( ; it.current(); ++it ){
244 uid_list[counter++] = (*it)->uid(); 247 uid_list[counter++] = (*it)->uid();
245 } 248 }
246 249
247 return ( uid_list ); 250 return ( uid_list );
248} 251}
249 252
250OContact OContactAccessBackend_XML::find ( int uid ) const 253OContact OContactAccessBackend_XML::find ( int uid ) const
251{ 254{
252 OContact foundContact; //Create empty contact 255 OContact foundContact; //Create empty contact
253 256
254 OContact* found = m_uidToContact.find( QString().setNum( uid ) ); 257 OContact* found = m_uidToContact.find( QString().setNum( uid ) );
255 258
256 if ( found ){ 259 if ( found ){
257 foundContact = *found; 260 foundContact = *found;
258 } 261 }
259 262
260 return ( foundContact ); 263 return ( foundContact );
261} 264}
262 265
263QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings, 266QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings,
264 const QDateTime& d ) 267 const QDateTime& d )
265{ 268{
266 269
267 QArray<int> m_currentQuery( m_contactList.count() ); 270 QArray<int> m_currentQuery( m_contactList.count() );
268 QListIterator<OContact> it( m_contactList ); 271 QListIterator<OContact> it( m_contactList );
269 uint arraycounter = 0; 272 uint arraycounter = 0;
270 273
271 for( ; it.current(); ++it ){ 274 for( ; it.current(); ++it ){
272 /* Search all fields and compare them with query object. Store them into list 275 /* Search all fields and compare them with query object. Store them into list
273 * if all fields matches. 276 * if all fields matches.
274 */ 277 */
275 QDate* queryDate = 0l; 278 QDate* queryDate = 0l;
276 QDate* checkDate = 0l; 279 QDate* checkDate = 0l;
277 bool allcorrect = true; 280 bool allcorrect = true;
278 for ( int i = 0; i < Qtopia::Groups; i++ ) { 281 for ( int i = 0; i < Qtopia::Groups; i++ ) {
279 // Birthday and anniversary are special nonstring fields and should 282 // Birthday and anniversary are special nonstring fields and should
280 // be handled specially 283 // be handled specially
281 switch ( i ){ 284 switch ( i ){
282 case Qtopia::Birthday: 285 case Qtopia::Birthday:
283 queryDate = new QDate( query.birthday() ); 286 queryDate = new QDate( query.birthday() );
284 checkDate = new QDate( (*it)->birthday() ); 287 checkDate = new QDate( (*it)->birthday() );
285 case Qtopia::Anniversary: 288 case Qtopia::Anniversary:
286 if ( queryDate == 0l ){ 289 if ( queryDate == 0l ){
287 queryDate = new QDate( query.anniversary() ); 290 queryDate = new QDate( query.anniversary() );
288 checkDate = new QDate( (*it)->anniversary() ); 291 checkDate = new QDate( (*it)->anniversary() );
289 } 292 }
290 293
291 if ( queryDate->isValid() ){ 294 if ( queryDate->isValid() ){
292 if( checkDate->isValid() ){ 295 if( checkDate->isValid() ){
293 if ( settings & OContactAccess::DateYear ){ 296 if ( settings & OContactAccess::DateYear ){
294 if ( queryDate->year() != checkDate->year() ) 297 if ( queryDate->year() != checkDate->year() )
295 allcorrect = false; 298 allcorrect = false;
296 } 299 }
297 if ( settings & OContactAccess::DateMonth ){ 300 if ( settings & OContactAccess::DateMonth ){
298 if ( queryDate->month() != checkDate->month() ) 301 if ( queryDate->month() != checkDate->month() )
299 allcorrect = false; 302 allcorrect = false;