summaryrefslogtreecommitdiff
path: root/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
Side-by-side diff
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 @@
/*
* XML Backend for the OPIE-Contact Database.
*
* Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
*
* =====================================================================
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* =====================================================================
* ToDo: XML-Backend: Automatic reload if something was changed...
*
*
* =====================================================================
* Version: $Id$
* =====================================================================
* History:
* $Log$
+ * Revision 1.4 2002/10/16 10:52:40 eilers
+ * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
+ *
* Revision 1.3 2002/10/14 16:21:54 eilers
* Some minor interface updates
*
* Revision 1.2 2002/10/07 17:34:24 eilers
* added OBackendFactory for advanced backend access
*
* Revision 1.1 2002/09/27 17:11:44 eilers
* Added API for accessing the Contact-Database ! It is compiling, but
* please do not expect that anything is working !
* I will debug that stuff in the next time ..
* Please read README_COMPILE for compiling !
*
*
*/
#ifndef _OContactAccessBackend_XML_
#define _OContactAccessBackend_XML_
#include <qasciidict.h>
#include <qdatetime.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qregexp.h>
#include <qarray.h>
#include <qpe/global.h>
#include <opie/xmltree.h>
#include "ocontactaccessbackend.h"
#include "ocontactaccess.h"
#include <stdlib.h>
#include <errno.h>
using namespace Opie;
/* the default xml implementation */
class OContactAccessBackend_XML : public OContactAccessBackend {
public:
- OContactAccessBackend_XML ( QString appname, QString filename = 0l )
+ OContactAccessBackend_XML ( QString appname, QString filename = 0l ):
+ m_changed( false )
{
m_appName = appname;
/* Set journalfile name ... */
m_journalName = getenv("HOME");
m_journalName +="/.abjournal" + appname;
/* Expecting to access the default filename if nothing else is set */
if ( filename.isEmpty() ){
m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
} else
m_fileName = filename;
/* Load Database now */
load ();
}
bool save() {
+
+ if ( !m_changed )
+ return true;
+
QString strNewFile = m_fileName + ".new";
QFile f( strNewFile );
if ( !f.open( IO_WriteOnly|IO_Raw ) )
return false;
int total_written;
QString out;
out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
" <Groups>\n"
" </Groups>\n"
" <Contacts>\n";
//QValueList<Contact>::iterator it;
QValueListConstIterator<OContact> it;
for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) {
out += "<Contact ";
(*it).save( out );
out += "/>\n";
QCString cstr = out.utf8();
total_written = f.writeBlock( cstr.data(), cstr.length() );
if ( total_written != int(cstr.length()) ) {
f.close();
QFile::remove( strNewFile );
return false;
}
out = "";
}
out += " </Contacts>\n</AddressBook>\n";
QCString cstr = out.utf8();
total_written = f.writeBlock( cstr.data(), cstr.length() );
if ( total_written != int( cstr.length() ) ) {
f.close();
QFile::remove( strNewFile );
return false;
}
f.close();
// move the file over, I'm just going to use the system call
// because, I don't feel like using QDir.
if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
qWarning( "problem renaming file %s to %s, errno: %d",
strNewFile.latin1(), m_journalName.latin1(), errno );
// remove the tmp file...
QFile::remove( strNewFile );
}
/* The journalfile should be removed now... */
removeJournal();
+
+ m_changed = false;
return true;
}
bool load () {
m_contactList.clear();
/* Load XML-File and journal if it exists */
if ( !load ( m_fileName, false ) )
return false;
/* The returncode of the journalfile is ignored due to the
* fact that it does not exist when this class is instantiated !
* But there may such a file exist, if the application crashed.
* Therefore we try to load it to get the changes before the #
* crash happened...
*/
load (m_journalName, true);
return true;
}
void clear () {
m_contactList.clear();
+ m_changed = false;
}
bool wasChangedExternally()
{
QFileInfo fi( m_fileName );
QDateTime lastmod = fi.lastModified ();
return (lastmod != m_readtime);
}
QArray<int> allRecords() const {
QArray<int> uid_list( m_contactList.count() );
uint counter = 0;
QValueListConstIterator<OContact> it;
for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
uid_list[counter++] = (*it).uid();
}
return ( uid_list );
}
@@ -254,73 +265,80 @@ class OContactAccessBackend_XML : public OContactAccessBackend {
bool hasQuerySettings (uint querySettings) const
{
/* OContactAccess::IgnoreCase may be added with one
* of the other settings, but never used alone.
* The other settings are just valid alone...
*/
switch ( querySettings & ~OContactAccess::IgnoreCase ){
case OContactAccess::RegExp:
return ( true );
case OContactAccess::WildCards:
return ( true );
case OContactAccess::ExactMatch:
return ( true );
default:
return ( false );
}
}
bool add ( const OContact &newcontact )
{
//qWarning("odefaultbackend: ACTION::ADD");
updateJournal (newcontact, OContact::ACTION_ADD);
addContact_p( newcontact );
+
+ m_changed = true;
+
return true;
}
bool replace ( const OContact &contact )
{
+ m_changed = true;
+
bool found = false;
QValueListIterator<OContact> it;
for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
if ( (*it).uid() == contact.uid() ){
found = true;
break;
}
}
if (found) {
updateJournal (contact, OContact::ACTION_REPLACE);
m_contactList.remove (it);
m_contactList.append (contact);
return true;
} else
return false;
}
bool remove ( int uid )
{
+ m_changed = true;
+
bool found = false;
QValueListIterator<OContact> it;
for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
if ((*it).uid() == uid){
found = true;
break;
}
}
if (found) {
updateJournal ( *it, OContact::ACTION_REMOVE);
m_contactList.remove (it);
return true;
} else
return false;
}
bool reload(){
/* Reload is the same as load in this implementation */
return ( load() );
}
private:
void addContact_p( const OContact &newcontact ){
m_contactList.append (newcontact);
@@ -532,32 +550,33 @@ class OContactAccessBackend_XML : public OContactAccessBackend {
// get a XML-File which is readable by our parser.
// This is just a cheat, but better than rewrite the parser.
if ( created ){
buf = "<Contacts>";
QCString cstr = buf.utf8();
f.writeBlock( cstr.data(), cstr.length() );
}
buf = "<Contact ";
cnt.save( buf );
buf += " action=\"" + QString::number( (int)action ) + "\" ";
buf += "/>\n";
QCString cstr = buf.utf8();
f.writeBlock( cstr.data(), cstr.length() );
}
void removeJournal()
{
QFile f ( m_journalName );
if ( f.exists() )
f.remove();
}
protected:
+ bool m_changed;
QString m_journalName;
QString m_fileName;
QString m_appName;
QValueList<OContact> m_contactList;
QDateTime m_readtime;
};
#endif