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,302 +1,302 @@
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 */