summaryrefslogtreecommitdiff
path: root/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
Unidiff
Diffstat (limited to 'libopie2/opiepim/backend/ocontactaccessbackend_xml.h') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.h21
1 files changed, 20 insertions, 1 deletions
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
index 50ea329..12a75ba 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
@@ -1,171 +1,182 @@
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 2002/10/16 10:52:40 eilers
21 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
22 *
20 * Revision 1.3 2002/10/14 16:21:54 eilers 23 * Revision 1.3 2002/10/14 16:21:54 eilers
21 * Some minor interface updates 24 * Some minor interface updates
22 * 25 *
23 * Revision 1.2 2002/10/07 17:34:24 eilers 26 * Revision 1.2 2002/10/07 17:34:24 eilers
24 * added OBackendFactory for advanced backend access 27 * added OBackendFactory for advanced backend access
25 * 28 *
26 * Revision 1.1 2002/09/27 17:11:44 eilers 29 * Revision 1.1 2002/09/27 17:11:44 eilers
27 * Added API for accessing the Contact-Database ! It is compiling, but 30 * Added API for accessing the Contact-Database ! It is compiling, but
28 * please do not expect that anything is working ! 31 * please do not expect that anything is working !
29 * I will debug that stuff in the next time .. 32 * I will debug that stuff in the next time ..
30 * Please read README_COMPILE for compiling ! 33 * Please read README_COMPILE for compiling !
31 * 34 *
32 * 35 *
33 */ 36 */
34 37
35#ifndef _OContactAccessBackend_XML_ 38#ifndef _OContactAccessBackend_XML_
36#define _OContactAccessBackend_XML_ 39#define _OContactAccessBackend_XML_
37 40
38#include <qasciidict.h> 41#include <qasciidict.h>
39#include <qdatetime.h> 42#include <qdatetime.h>
40#include <qfile.h> 43#include <qfile.h>
41#include <qfileinfo.h> 44#include <qfileinfo.h>
42#include <qregexp.h> 45#include <qregexp.h>
43#include <qarray.h> 46#include <qarray.h>
44 47
45#include <qpe/global.h> 48#include <qpe/global.h>
46 49
47#include <opie/xmltree.h> 50#include <opie/xmltree.h>
48#include "ocontactaccessbackend.h" 51#include "ocontactaccessbackend.h"
49#include "ocontactaccess.h" 52#include "ocontactaccess.h"
50 53
51#include <stdlib.h> 54#include <stdlib.h>
52#include <errno.h> 55#include <errno.h>
53 56
54using namespace Opie; 57using namespace Opie;
55 58
56/* the default xml implementation */ 59/* the default xml implementation */
57class OContactAccessBackend_XML : public OContactAccessBackend { 60class OContactAccessBackend_XML : public OContactAccessBackend {
58 public: 61 public:
59 OContactAccessBackend_XML ( QString appname, QString filename = 0l ) 62 OContactAccessBackend_XML ( QString appname, QString filename = 0l ):
63 m_changed( false )
60 { 64 {
61 m_appName = appname; 65 m_appName = appname;
62 66
63 /* Set journalfile name ... */ 67 /* Set journalfile name ... */
64 m_journalName = getenv("HOME"); 68 m_journalName = getenv("HOME");
65 m_journalName +="/.abjournal" + appname; 69 m_journalName +="/.abjournal" + appname;
66 70
67 /* Expecting to access the default filename if nothing else is set */ 71 /* Expecting to access the default filename if nothing else is set */
68 if ( filename.isEmpty() ){ 72 if ( filename.isEmpty() ){
69 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 73 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
70 } else 74 } else
71 m_fileName = filename; 75 m_fileName = filename;
72 76
73 /* Load Database now */ 77 /* Load Database now */
74 load (); 78 load ();
75 } 79 }
76 80
77 bool save() { 81 bool save() {
82
83 if ( !m_changed )
84 return true;
85
78 QString strNewFile = m_fileName + ".new"; 86 QString strNewFile = m_fileName + ".new";
79 QFile f( strNewFile ); 87 QFile f( strNewFile );
80 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 88 if ( !f.open( IO_WriteOnly|IO_Raw ) )
81 return false; 89 return false;
82 90
83 int total_written; 91 int total_written;
84 QString out; 92 QString out;
85 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 93 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
86 " <Groups>\n" 94 " <Groups>\n"
87 " </Groups>\n" 95 " </Groups>\n"
88 " <Contacts>\n"; 96 " <Contacts>\n";
89 //QValueList<Contact>::iterator it; 97 //QValueList<Contact>::iterator it;
90 QValueListConstIterator<OContact> it; 98 QValueListConstIterator<OContact> it;
91 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) { 99 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) {
92 out += "<Contact "; 100 out += "<Contact ";
93 (*it).save( out ); 101 (*it).save( out );
94 out += "/>\n"; 102 out += "/>\n";
95 QCString cstr = out.utf8(); 103 QCString cstr = out.utf8();
96 total_written = f.writeBlock( cstr.data(), cstr.length() ); 104 total_written = f.writeBlock( cstr.data(), cstr.length() );
97 if ( total_written != int(cstr.length()) ) { 105 if ( total_written != int(cstr.length()) ) {
98 f.close(); 106 f.close();
99 QFile::remove( strNewFile ); 107 QFile::remove( strNewFile );
100 return false; 108 return false;
101 } 109 }
102 out = ""; 110 out = "";
103 } 111 }
104 out += " </Contacts>\n</AddressBook>\n"; 112 out += " </Contacts>\n</AddressBook>\n";
105 113
106 QCString cstr = out.utf8(); 114 QCString cstr = out.utf8();
107 total_written = f.writeBlock( cstr.data(), cstr.length() ); 115 total_written = f.writeBlock( cstr.data(), cstr.length() );
108 if ( total_written != int( cstr.length() ) ) { 116 if ( total_written != int( cstr.length() ) ) {
109 f.close(); 117 f.close();
110 QFile::remove( strNewFile ); 118 QFile::remove( strNewFile );
111 return false; 119 return false;
112 } 120 }
113 f.close(); 121 f.close();
114 122
115 // move the file over, I'm just going to use the system call 123 // move the file over, I'm just going to use the system call
116 // because, I don't feel like using QDir. 124 // because, I don't feel like using QDir.
117 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 125 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
118 qWarning( "problem renaming file %s to %s, errno: %d", 126 qWarning( "problem renaming file %s to %s, errno: %d",
119 strNewFile.latin1(), m_journalName.latin1(), errno ); 127 strNewFile.latin1(), m_journalName.latin1(), errno );
120 // remove the tmp file... 128 // remove the tmp file...
121 QFile::remove( strNewFile ); 129 QFile::remove( strNewFile );
122 } 130 }
123 131
124 /* The journalfile should be removed now... */ 132 /* The journalfile should be removed now... */
125 removeJournal(); 133 removeJournal();
134
135 m_changed = false;
126 return true; 136 return true;
127 } 137 }
128 138
129 bool load () { 139 bool load () {
130 m_contactList.clear(); 140 m_contactList.clear();
131 141
132 /* Load XML-File and journal if it exists */ 142 /* Load XML-File and journal if it exists */
133 if ( !load ( m_fileName, false ) ) 143 if ( !load ( m_fileName, false ) )
134 return false; 144 return false;
135 /* The returncode of the journalfile is ignored due to the 145 /* The returncode of the journalfile is ignored due to the
136 * fact that it does not exist when this class is instantiated ! 146 * fact that it does not exist when this class is instantiated !
137 * But there may such a file exist, if the application crashed. 147 * But there may such a file exist, if the application crashed.
138 * Therefore we try to load it to get the changes before the # 148 * Therefore we try to load it to get the changes before the #
139 * crash happened... 149 * crash happened...
140 */ 150 */
141 load (m_journalName, true); 151 load (m_journalName, true);
142 152
143 return true; 153 return true;
144 } 154 }
145 155
146 void clear () { 156 void clear () {
147 m_contactList.clear(); 157 m_contactList.clear();
158 m_changed = false;
148 159
149 } 160 }
150 161
151 bool wasChangedExternally() 162 bool wasChangedExternally()
152 { 163 {
153 QFileInfo fi( m_fileName ); 164 QFileInfo fi( m_fileName );
154 165
155 QDateTime lastmod = fi.lastModified (); 166 QDateTime lastmod = fi.lastModified ();
156 167
157 return (lastmod != m_readtime); 168 return (lastmod != m_readtime);
158 } 169 }
159 170
160 QArray<int> allRecords() const { 171 QArray<int> allRecords() const {
161 QArray<int> uid_list( m_contactList.count() ); 172 QArray<int> uid_list( m_contactList.count() );
162 173
163 uint counter = 0; 174 uint counter = 0;
164 QValueListConstIterator<OContact> it; 175 QValueListConstIterator<OContact> it;
165 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 176 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
166 uid_list[counter++] = (*it).uid(); 177 uid_list[counter++] = (*it).uid();
167 } 178 }
168 179
169 return ( uid_list ); 180 return ( uid_list );
170 } 181 }
171 182
@@ -254,73 +265,80 @@ class OContactAccessBackend_XML : public OContactAccessBackend {
254 265
255 bool hasQuerySettings (uint querySettings) const 266 bool hasQuerySettings (uint querySettings) const
256 { 267 {
257 /* OContactAccess::IgnoreCase may be added with one 268 /* OContactAccess::IgnoreCase may be added with one
258 * of the other settings, but never used alone. 269 * of the other settings, but never used alone.
259 * The other settings are just valid alone... 270 * The other settings are just valid alone...
260 */ 271 */
261 switch ( querySettings & ~OContactAccess::IgnoreCase ){ 272 switch ( querySettings & ~OContactAccess::IgnoreCase ){
262 case OContactAccess::RegExp: 273 case OContactAccess::RegExp:
263 return ( true ); 274 return ( true );
264 case OContactAccess::WildCards: 275 case OContactAccess::WildCards:
265 return ( true ); 276 return ( true );
266 case OContactAccess::ExactMatch: 277 case OContactAccess::ExactMatch:
267 return ( true ); 278 return ( true );
268 default: 279 default:
269 return ( false ); 280 return ( false );
270 } 281 }
271 } 282 }
272 283
273 bool add ( const OContact &newcontact ) 284 bool add ( const OContact &newcontact )
274 { 285 {
275 //qWarning("odefaultbackend: ACTION::ADD"); 286 //qWarning("odefaultbackend: ACTION::ADD");
276 updateJournal (newcontact, OContact::ACTION_ADD); 287 updateJournal (newcontact, OContact::ACTION_ADD);
277 addContact_p( newcontact ); 288 addContact_p( newcontact );
289
290 m_changed = true;
291
278 return true; 292 return true;
279 } 293 }
280 294
281 bool replace ( const OContact &contact ) 295 bool replace ( const OContact &contact )
282 { 296 {
297 m_changed = true;
298
283 bool found = false; 299 bool found = false;
284 300
285 QValueListIterator<OContact> it; 301 QValueListIterator<OContact> it;
286 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 302 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
287 if ( (*it).uid() == contact.uid() ){ 303 if ( (*it).uid() == contact.uid() ){
288 found = true; 304 found = true;
289 break; 305 break;
290 } 306 }
291 } 307 }
292 if (found) { 308 if (found) {
293 updateJournal (contact, OContact::ACTION_REPLACE); 309 updateJournal (contact, OContact::ACTION_REPLACE);
294 m_contactList.remove (it); 310 m_contactList.remove (it);
295 m_contactList.append (contact); 311 m_contactList.append (contact);
296 return true; 312 return true;
297 } else 313 } else
298 return false; 314 return false;
299 } 315 }
300 316
301 bool remove ( int uid ) 317 bool remove ( int uid )
302 { 318 {
319 m_changed = true;
320
303 bool found = false; 321 bool found = false;
304 QValueListIterator<OContact> it; 322 QValueListIterator<OContact> it;
305 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 323 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
306 if ((*it).uid() == uid){ 324 if ((*it).uid() == uid){
307 found = true; 325 found = true;
308 break; 326 break;
309 } 327 }
310 } 328 }
311 if (found) { 329 if (found) {
312 updateJournal ( *it, OContact::ACTION_REMOVE); 330 updateJournal ( *it, OContact::ACTION_REMOVE);
313 m_contactList.remove (it); 331 m_contactList.remove (it);
314 return true; 332 return true;
315 } else 333 } else
316 return false; 334 return false;
317 } 335 }
318 336
319 bool reload(){ 337 bool reload(){
320 /* Reload is the same as load in this implementation */ 338 /* Reload is the same as load in this implementation */
321 return ( load() ); 339 return ( load() );
322 } 340 }
323 341
324 private: 342 private:
325 void addContact_p( const OContact &newcontact ){ 343 void addContact_p( const OContact &newcontact ){
326 m_contactList.append (newcontact); 344 m_contactList.append (newcontact);
@@ -532,32 +550,33 @@ class OContactAccessBackend_XML : public OContactAccessBackend {
532 // get a XML-File which is readable by our parser. 550 // get a XML-File which is readable by our parser.
533 // This is just a cheat, but better than rewrite the parser. 551 // This is just a cheat, but better than rewrite the parser.
534 if ( created ){ 552 if ( created ){
535 buf = "<Contacts>"; 553 buf = "<Contacts>";
536 QCString cstr = buf.utf8(); 554 QCString cstr = buf.utf8();
537 f.writeBlock( cstr.data(), cstr.length() ); 555 f.writeBlock( cstr.data(), cstr.length() );
538 } 556 }
539 557
540 buf = "<Contact "; 558 buf = "<Contact ";
541 cnt.save( buf ); 559 cnt.save( buf );
542 buf += " action=\"" + QString::number( (int)action ) + "\" "; 560 buf += " action=\"" + QString::number( (int)action ) + "\" ";
543 buf += "/>\n"; 561 buf += "/>\n";
544 QCString cstr = buf.utf8(); 562 QCString cstr = buf.utf8();
545 f.writeBlock( cstr.data(), cstr.length() ); 563 f.writeBlock( cstr.data(), cstr.length() );
546 } 564 }
547 565
548 void removeJournal() 566 void removeJournal()
549 { 567 {
550 QFile f ( m_journalName ); 568 QFile f ( m_journalName );
551 if ( f.exists() ) 569 if ( f.exists() )
552 f.remove(); 570 f.remove();
553 } 571 }
554 572
555 protected: 573 protected:
574 bool m_changed;
556 QString m_journalName; 575 QString m_journalName;
557 QString m_fileName; 576 QString m_fileName;
558 QString m_appName; 577 QString m_appName;
559 QValueList<OContact> m_contactList; 578 QValueList<OContact> m_contactList;
560 QDateTime m_readtime; 579 QDateTime m_readtime;
561}; 580};
562 581
563#endif 582#endif