summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/opiecore.pro6
-rw-r--r--libopie2/opiecore/xmltree.cpp (renamed from libopie2/opiepim/core/backends/private/xmltree.cc)2
-rw-r--r--libopie2/opiecore/xmltree.h (renamed from libopie2/opiepim/core/backends/private/xmltree.h)4
-rw-r--r--libopie2/opiepim/backend/backends.pro6
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp5
5 files changed, 10 insertions, 13 deletions
diff --git a/libopie2/opiecore/opiecore.pro b/libopie2/opiecore/opiecore.pro
index ff3c036..67ef072 100644
--- a/libopie2/opiecore/opiecore.pro
+++ b/libopie2/opiecore/opiecore.pro
@@ -1,39 +1,41 @@
TEMPLATE = lib
CONFIG += qt warn_on debug
DESTDIR = $(OPIEDIR)/lib
HEADERS = oapplication.h \
oconfig.h \
odebug.h \
oglobal.h \
oglobalsettings.h \
oprocess.h \
oprocctrl.h \
osmartpointer.h \
- ostorageinfo.h
+ ostorageinfo.h \
+ xmltree.h
SOURCES = oapplication.cpp \
oconfig.cpp \
odebug.cpp \
oglobal.cpp \
oglobalsettings.cpp \
oprocess.cpp \
oprocctrl.cpp \
- ostorageinfo.cpp
+ ostorageinfo.cpp \
+ xmltree.cpp
include ( device/device.pro )
INTERFACES =
TARGET = opiecore2
VERSION = 1.9.0
INCLUDEPATH += $(OPIEDIR)/include
DEPENDPATH += $(OPIEDIR)/include
!contains( platform, x11 ) {
LIBS = -lqpe
include ( $(OPIEDIR)/include.pro )
}
contains( platform, x11 ) {
LIBS = -L$(OPIEDIR)/lib -Wl,-rpath,$(OPIEDIR)/lib
}
diff --git a/libopie2/opiepim/core/backends/private/xmltree.cc b/libopie2/opiecore/xmltree.cpp
index 40749ca..72fe9fd 100644
--- a/libopie2/opiepim/core/backends/private/xmltree.cc
+++ b/libopie2/opiecore/xmltree.cpp
@@ -1,323 +1,323 @@
/* This file is part of the KDE project
Copyright (C) 2001 Simon Hausmann <hausmann@kde.org>
This library 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.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "xmltree.h"
#include <qpe/stringutil.h>
#include <qxml.h>
#include <assert.h>
-using namespace Opie::Pim::Private;
+using namespace Opie::Core;
XMLElement::XMLElement()
: m_parent( 0 ), m_next( 0 ), m_prev( 0 ), m_first( 0 ), m_last( 0 )
{
}
XMLElement::~XMLElement()
{
XMLElement *n = m_first;
while ( n )
{
XMLElement *tmp = n;
n = n->m_next;
delete tmp;
}
}
void XMLElement::appendChild( XMLElement *child )
{
if ( child->m_parent )
child->m_parent->removeChild( child );
child->m_parent = this;
if ( m_last )
m_last->m_next = child;
child->m_prev = m_last;
if ( !m_first )
m_first = child;
m_last = child;
}
void XMLElement::insertAfter( XMLElement *newChild, XMLElement *refChild )
{
assert( newChild != refChild );
if ( refChild == m_last )
{
appendChild( newChild );
return;
}
assert( refChild );
assert( refChild->m_parent );
assert( refChild->m_parent == this );
if ( newChild->m_parent && newChild != refChild )
newChild->m_parent->removeChild( newChild );
newChild->m_parent = this;
XMLElement *next = refChild->m_next;
refChild->m_next = newChild;
newChild->m_prev = refChild;
newChild->m_next = next;
if ( next )
next->m_prev = newChild;
}
QString XMLElement::attribute( const QString &attr ) const
{
AttributeMap::ConstIterator it = m_attributes.find( attr );
if ( it == m_attributes.end() )
return QString::null;
return it.data();
}
void XMLElement::setAttribute( const QString &attr, const QString &value )
{
m_attributes.replace( attr, value );
}
void XMLElement::insertBefore( XMLElement *newChild, XMLElement *refChild )
{
assert( refChild );
assert( refChild->m_parent );
assert( refChild->m_parent == this );
assert( newChild != refChild );
if ( newChild->m_parent && newChild != refChild )
newChild->m_parent->removeChild( newChild );
newChild->m_parent = this;
XMLElement *prev = refChild->m_prev;
refChild->m_prev = newChild;
newChild->m_prev = prev;
newChild->m_next = refChild;
if ( prev )
prev->m_next = newChild;
if ( refChild == m_first )
m_first = newChild;
}
void XMLElement::removeChild( XMLElement *child )
{
if ( child->m_parent != this )
return;
if ( m_first == child )
m_first = child->m_next;
if ( m_last == child )
m_last = child->m_prev;
if ( child->m_prev )
child->m_prev->m_next = child->m_next;
if ( child->m_next )
child->m_next->m_prev = child->m_prev;
child->m_parent = 0;
child->m_prev = 0;
child->m_next = 0;
}
void XMLElement::save( QTextStream &s, uint indent )
{
if ( !m_value.isEmpty() )
{
s << Qtopia::escapeString( m_value );
return;
}
for ( uint i = 0; i < indent; ++i )
s << " ";
s << "<" << m_tag;
if ( !m_attributes.isEmpty() )
{
s << " ";
AttributeMap::ConstIterator it = m_attributes.begin();
AttributeMap::ConstIterator end = m_attributes.end();
for (; it != end; ++it )
{
s << it.key() << "=\"" << Qtopia::escapeString( it.data() ) << "\"";
s << " ";
}
}
if ( m_last )
{
if ( ( m_first && !m_first->value().isEmpty() ) || !m_parent )
s << ">";
else
s << ">" << endl;
int newIndent = indent;
if ( m_parent )
newIndent++;
XMLElement *n = m_first;
while ( n )
{
n->save( s, newIndent );
n = n->nextChild();
}
if ( m_last && m_last->value().isEmpty() && m_parent )
for ( uint i = 0; i < indent; ++i )
s << " ";
if ( m_parent )
s << "</" << m_tag << ">" << endl;
}
else
s << "/>" << endl;
}
class Handler : public QXmlDefaultHandler
{
public:
Handler() : m_node( 0 ), m_root( 0 ) {}
XMLElement *root() const { return m_root; }
virtual bool startDocument();
virtual bool endDocument();
virtual bool startElement( const QString &ns, const QString &ln, const QString &qName,
const QXmlAttributes &attr );
virtual bool endElement( const QString &ns, const QString &ln, const QString &qName );
virtual bool characters( const QString &ch );
private:
XMLElement *m_node;
XMLElement *m_root;
};
bool Handler::startDocument()
{
m_root = m_node = new XMLElement;
return true;
}
bool Handler::endDocument()
{
return m_root == m_node;
}
bool Handler::startElement( const QString &, const QString &, const QString &qName,
const QXmlAttributes &attr )
{
XMLElement *bm = new XMLElement;
XMLElement::AttributeMap attributes;
for ( int i = 0; i < attr.length(); ++i )
attributes[ attr.qName( i ) ] = attr.value( i );
bm->setAttributes( attributes );
bm->setTagName( qName );
m_node->appendChild( bm );
m_node = bm;
return true;
}
bool Handler::endElement( const QString &, const QString &, const QString & )
{
if ( m_node == m_root )
return false;
m_node = m_node->parent();
return true;
}
bool Handler::characters( const QString &ch )
{
XMLElement *textNode = new XMLElement;
textNode->setValue( ch );
m_node->appendChild( textNode );
return true;
}
XMLElement *XMLElement::namedItem( const QString &name )
{
XMLElement *e = m_first;
for (; e; e = e->nextChild() )
if ( e->tagName() == name )
return e;
return 0;
}
XMLElement *XMLElement::clone() const
{
XMLElement *res = new XMLElement;
res->setTagName( m_tag );
res->setValue( m_value );
res->setAttributes( m_attributes );
XMLElement *e = m_first;
for (; e; e = e->m_next )
res->appendChild( e->clone() );
return res;
}
XMLElement *XMLElement::load( const QString &fileName )
{
QFile f( fileName );
if ( !f.open( IO_ReadOnly ) )
return 0;
QTextStream stream( &f );
stream.setEncoding( QTextStream::UnicodeUTF8 );
QXmlInputSource src( stream );
QXmlSimpleReader reader;
Handler handler;
reader.setFeature( "http://trolltech.com/xml/features/report-whitespace-only-CharData", false );
reader.setContentHandler( &handler );
reader.parse( src );
return handler.root();;
}
/* vim: et sw=4
*/
diff --git a/libopie2/opiepim/core/backends/private/xmltree.h b/libopie2/opiecore/xmltree.h
index 9817a02..5fd79e7 100644
--- a/libopie2/opiepim/core/backends/private/xmltree.h
+++ b/libopie2/opiecore/xmltree.h
@@ -1,122 +1,120 @@
/* This file is part of the KDE project
Copyright (C) 2000,2001 Simon Hausmann <hausmann@kde.org>
This library 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.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef __bookmarks_h__
#define __bookmarks_h__
#include <qstring.h>
#include <qmap.h>
#include <qtextstream.h>
namespace Opie {
-namespace Pim {
-namespace Private{
+namespace Core {
/**
* A small xml lib written by Simon Hausmann.
*/
class XMLElement
{
public:
typedef QMap<QString, QString> AttributeMap;
/**
* The constructor of XMLElement
*/
XMLElement();
~XMLElement();
/** appendChild appends a child to the XMLElement behind the last element.
* The ownership of the child get's transfered to the
* this XMLElement.
* If child is already the child of another parent
* it's get removed from the other parent first.
*/
void appendChild( XMLElement *child );
/** inserts newChild after refChild. If newChild is the child
* of another parent the child will get removed.
* The ownership of child gets transfered.
*
*/
void insertAfter( XMLElement *newChild, XMLElement *refChild );
/** same as insertAfter but the element get's inserted before refChild.
*
*/
void insertBefore( XMLElement *newChild, XMLElement *refChild );
/** removeChild removes the child from the XMLElement.
* The ownership gets dropped. You need to delete the
* child yourself.
*/
void removeChild( XMLElement *child );
/** parent() returns the parent of this XMLElement
* If there is no parent 0l gets returned
*/
XMLElement *parent() const { return m_parent; }
XMLElement *firstChild() const { return m_first; }
XMLElement *nextChild() const { return m_next; }
XMLElement *prevChild() const { return m_prev; }
XMLElement *lastChild() const { return m_last; }
void setTagName( const QString &tag ) { m_tag = tag; }
QString tagName() const { return m_tag; }
void setValue( const QString &val ) { m_value = val; }
QString value() const { return m_value; }
void setAttributes( const AttributeMap &attrs ) { m_attributes = attrs; }
AttributeMap attributes() const { return m_attributes; }
AttributeMap &attributes() { return m_attributes; }
QString attribute( const QString & ) const;
void setAttribute( const QString &attr, const QString &value );
void save( QTextStream &stream, uint indent = 0 );
XMLElement *namedItem( const QString &name );
XMLElement *clone() const;
static XMLElement *load( const QString &fileName );
private:
QString m_tag;
QString m_value;
AttributeMap m_attributes;
XMLElement *m_parent;
XMLElement *m_next;
XMLElement *m_prev;
XMLElement *m_first;
XMLElement *m_last;
XMLElement( const XMLElement &rhs );
XMLElement &operator=( const XMLElement &rhs );
class Private;
Private* d;
};
}
-}
} // namespace Opie
#endif
diff --git a/libopie2/opiepim/backend/backends.pro b/libopie2/opiepim/backend/backends.pro
index d4867ba..953d928 100644
--- a/libopie2/opiepim/backend/backends.pro
+++ b/libopie2/opiepim/backend/backends.pro
@@ -1,33 +1,31 @@
SOURCES += core/backends/ocontactaccessbackend_sql.cpp \
core/backends/ocontactaccessbackend_vcard.cpp \
core/backends/ocontactaccessbackend_xml.cpp \
core/backends/ocontactaccess.cpp \
core/backends/odatebookaccessbackend.cpp \
core/backends/odatebookaccessbackend_xml.cpp \
core/backends/otodoaccessbackend.cpp \
core/backends/otodoaccess.cpp \
core/backends/otodoaccesssql.cpp \
core/backends/otodoaccessvcal.cpp \
core/backends/otodoaccessxml.cpp \
core/backends/odatebookaccess.cpp \
- core/backends/odatebookaccessbackend_sql.cpp \
- core/backends/private/xmltree.cc
+ core/backends/odatebookaccessbackend_sql.cpp
HEADERS += core/backends/obackendfactory.h \
core/backends/ocontactaccessbackend.h \
core/backends/ocontactaccessbackend_sql.h \
core/backends/ocontactaccessbackend_vcard.h \
core/backends/ocontactaccessbackend_xml.h \
core/backends/ocontactaccess.h \
core/backends/odatebookaccessbackend.h \
core/backends/odatebookaccessbackend_sql.h \
core/backends/odatebookaccessbackend_xml.h \
core/backends/opimaccessbackend.h \
core/backends/opimaccesstemplate.h \
core/backends/otodoaccessbackend.h \
core/backends/otodoaccess.h \
core/backends/otodoaccesssql.h \
core/backends/otodoaccessvcal.h \
core/backends/otodoaccessxml.h \
- core/backends/odatebookaccess.h \
- core/backends/private/xmltree.h
+ core/backends/odatebookaccess.h
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
index f5e76d5..2b467c3 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
@@ -1,750 +1,749 @@
/*
This file is part of the Opie Project
Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
=. Copyright (C) The Opie Team <opie-devel@handhelds.org>
.=l.
.>+-=
_;:, .> :=|. This program is free software; you can
.> <`_, > . <= redistribute it and/or modify it under
:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
.="- .-=="i, .._ License as published by the Free Software
- . .-<_> .<> Foundation; either version 2 of the License,
._= =} : or (at your option) any later version.
.%`+i> _;_.
.i_,=:_. -<s. This program is distributed in the hope that
+ . -:. = it will be useful, but WITHOUT ANY WARRANTY;
: .. .:, . . . without even the implied warranty of
=_ + =;=|` MERCHANTABILITY or FITNESS FOR A
_.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
..}^=.= = ; Library General Public License for more
++= -. .` .: details.
: = ...= . :.=-
-. .:....=;==+<; You should have received a copy of the GNU
-_. . . )=. = Library General Public License along with
-- :-=` this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/*
* XML Backend for the OPIE-Contact Database.
*/
#include <opie2/ocontactaccessbackend_xml.h>
#include <qasciidict.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qregexp.h>
#include <qarray.h>
#include <qmap.h>
#include <qpe/global.h>
-#include "private/xmltree.h"
+#include <opie2/xmltree.h>
#include <opie2/ocontactaccessbackend.h>
#include <opie2/ocontactaccess.h>
#include <stdlib.h>
#include <errno.h>
-using namespace Opie;
-using namespace Opie::Pim::Private;
+using namespace Opie::Core;
namespace Opie {
OPimContactAccessBackend_XML::OPimContactAccessBackend_XML ( const QString& appname, const QString& filename ):
m_changed( false )
{
// Just m_contactlist should call delete if an entry
// is removed.
m_contactList.setAutoDelete( true );
m_uidToContact.setAutoDelete( 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 OPimContactAccessBackend_XML::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;
int idx_offset = 0;
QString out;
// Write Header
out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
" <Groups>\n"
" </Groups>\n"
" <Contacts>\n";
QCString cstr = out.utf8();
f.writeBlock( cstr.data(), cstr.length() );
idx_offset += cstr.length();
out = "";
// Write all contacts
QListIterator<OPimContact> it( m_contactList );
for ( ; it.current(); ++it ) {
// qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset );
out += "<Contact ";
(*it)->save( out );
out += "/>\n";
cstr = out.utf8();
total_written = f.writeBlock( cstr.data(), cstr.length() );
idx_offset += cstr.length();
if ( total_written != int(cstr.length()) ) {
f.close();
QFile::remove( strNewFile );
return false;
}
out = "";
}
out += " </Contacts>\n</AddressBook>\n";
// Write Footer
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 OPimContactAccessBackend_XML::load ()
{
m_contactList.clear();
m_uidToContact.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 OPimContactAccessBackend_XML::clear ()
{
m_contactList.clear();
m_uidToContact.clear();
m_changed = false;
}
bool OPimContactAccessBackend_XML::wasChangedExternally()
{
QFileInfo fi( m_fileName );
QDateTime lastmod = fi.lastModified ();
return (lastmod != m_readtime);
}
QArray<int> OPimContactAccessBackend_XML::allRecords() const
{
QArray<int> uid_list( m_contactList.count() );
uint counter = 0;
QListIterator<OPimContact> it( m_contactList );
for( ; it.current(); ++it ){
uid_list[counter++] = (*it)->uid();
}
return ( uid_list );
}
OPimContact OPimContactAccessBackend_XML::find ( int uid ) const
{
OPimContact foundContact; //Create empty contact
OPimContact* found = m_uidToContact.find( QString().setNum( uid ) );
if ( found ){
foundContact = *found;
}
return ( foundContact );
}
QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings,
const QDateTime& d )
{
QArray<int> m_currentQuery( m_contactList.count() );
QListIterator<OPimContact> it( m_contactList );
uint arraycounter = 0;
for( ; it.current(); ++it ){
/* Search all fields and compare them with query object. Store them into list
* if all fields matches.
*/
QDate* queryDate = 0l;
QDate* checkDate = 0l;
bool allcorrect = true;
for ( int i = 0; i < Qtopia::Groups; i++ ) {
// Birthday and anniversary are special nonstring fields and should
// be handled specially
switch ( i ){
case Qtopia::Birthday:
queryDate = new QDate( query.birthday() );
checkDate = new QDate( (*it)->birthday() );
case Qtopia::Anniversary:
if ( queryDate == 0l ){
queryDate = new QDate( query.anniversary() );
checkDate = new QDate( (*it)->anniversary() );
}
if ( queryDate->isValid() ){
if( checkDate->isValid() ){
if ( settings & OPimContactAccess::DateYear ){
if ( queryDate->year() != checkDate->year() )
allcorrect = false;
}
if ( settings & OPimContactAccess::DateMonth ){
if ( queryDate->month() != checkDate->month() )
allcorrect = false;
}
if ( settings & OPimContactAccess::DateDay ){
if ( queryDate->day() != checkDate->day() )
allcorrect = false;
}
if ( settings & OPimContactAccess::DateDiff ) {
QDate current;
// If we get an additional date, we
// will take this date instead of
// the current one..
if ( !d.date().isValid() )
current = QDate::currentDate();
else
current = d.date();
// We have to equalize the year, otherwise
// the search will fail..
checkDate->setYMD( current.year(),
checkDate->month(),
checkDate->day() );
if ( *checkDate < current )
checkDate->setYMD( current.year()+1,
checkDate->month(),
checkDate->day() );
// Check whether the birthday/anniversary date is between
// the current/given date and the maximum date
// ( maximum time range ) !
qWarning("Checking if %s is between %s and %s ! ",
checkDate->toString().latin1(),
current.toString().latin1(),
queryDate->toString().latin1() );
if ( current.daysTo( *queryDate ) >= 0 ){
if ( !( ( *checkDate >= current ) &&
( *checkDate <= *queryDate ) ) ){
allcorrect = false;
qWarning (" Nope!..");
}
}
}
} else{
// checkDate is invalid. Therefore this entry is always rejected
allcorrect = false;
}
}
delete queryDate;
queryDate = 0l;
delete checkDate;
checkDate = 0l;
break;
default:
/* Just compare fields which are not empty in the query object */
if ( !query.field(i).isEmpty() ){
switch ( settings & ~( OPimContactAccess::IgnoreCase
| OPimContactAccess::DateDiff
| OPimContactAccess::DateYear
| OPimContactAccess::DateMonth
| OPimContactAccess::DateDay
| OPimContactAccess::MatchOne
) ){
case OPimContactAccess::RegExp:{
QRegExp expr ( query.field(i),
!(settings & OPimContactAccess::IgnoreCase),
false );
if ( expr.find ( (*it)->field(i), 0 ) == -1 )
allcorrect = false;
}
break;
case OPimContactAccess::WildCards:{
QRegExp expr ( query.field(i),
!(settings & OPimContactAccess::IgnoreCase),
true );
if ( expr.find ( (*it)->field(i), 0 ) == -1 )
allcorrect = false;
}
break;
case OPimContactAccess::ExactMatch:{
if (settings & OPimContactAccess::IgnoreCase){
if ( query.field(i).upper() !=
(*it)->field(i).upper() )
allcorrect = false;
}else{
if ( query.field(i) != (*it)->field(i) )
allcorrect = false;
}
}
break;
}
}
}
}
if ( allcorrect ){
m_currentQuery[arraycounter++] = (*it)->uid();
}
}
// Shrink to fit..
m_currentQuery.resize(arraycounter);
return m_currentQuery;
}
QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
{
QArray<int> m_currentQuery( m_contactList.count() );
QListIterator<OPimContact> it( m_contactList );
uint arraycounter = 0;
for( ; it.current(); ++it ){
if ( (*it)->match( r ) ){
m_currentQuery[arraycounter++] = (*it)->uid();
}
}
// Shrink to fit..
m_currentQuery.resize(arraycounter);
return m_currentQuery;
}
const uint OPimContactAccessBackend_XML::querySettings()
{
return ( OPimContactAccess::WildCards
| OPimContactAccess::IgnoreCase
| OPimContactAccess::RegExp
| OPimContactAccess::ExactMatch
| OPimContactAccess::DateDiff
| OPimContactAccess::DateYear
| OPimContactAccess::DateMonth
| OPimContactAccess::DateDay
);
}
bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const
{
/* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
* may be added with any of the other settings. IgnoreCase should never used alone.
* Wildcards, RegExp, ExactMatch should never used at the same time...
*/
// Step 1: Check whether the given settings are supported by this backend
if ( ( querySettings & (
OPimContactAccess::IgnoreCase
| OPimContactAccess::WildCards
| OPimContactAccess::DateDiff
| OPimContactAccess::DateYear
| OPimContactAccess::DateMonth
| OPimContactAccess::DateDay
| OPimContactAccess::RegExp
| OPimContactAccess::ExactMatch
) ) != querySettings )
return false;
// Step 2: Check whether the given combinations are ok..
// IngoreCase alone is invalid
if ( querySettings == OPimContactAccess::IgnoreCase )
return false;
// WildCards, RegExp and ExactMatch should never used at the same time
switch ( querySettings & ~( OPimContactAccess::IgnoreCase
| OPimContactAccess::DateDiff
| OPimContactAccess::DateYear
| OPimContactAccess::DateMonth
| OPimContactAccess::DateDay
)
){
case OPimContactAccess::RegExp:
return ( true );
case OPimContactAccess::WildCards:
return ( true );
case OPimContactAccess::ExactMatch:
return ( true );
case 0: // one of the upper removed bits were set..
return ( true );
default:
return ( false );
}
}
// Currently only asc implemented..
QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int )
{
QMap<QString, int> nameToUid;
QStringList names;
QArray<int> m_currentQuery( m_contactList.count() );
// First fill map and StringList with all Names
// Afterwards sort namelist and use map to fill array to return..
QListIterator<OPimContact> it( m_contactList );
for( ; it.current(); ++it ){
names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) );
nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() );
}
names.sort();
int i = 0;
if ( asc ){
for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
m_currentQuery[i++] = nameToUid[ (*it) ];
}else{
for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
m_currentQuery[i++] = nameToUid[ (*it) ];
}
return m_currentQuery;
}
bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact )
{
//qWarning("odefaultbackend: ACTION::ADD");
updateJournal (newcontact, ACTION_ADD);
addContact_p( newcontact );
m_changed = true;
return true;
}
bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact )
{
m_changed = true;
OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) );
if ( found ) {
OPimContact* newCont = new OPimContact( contact );
updateJournal ( *newCont, ACTION_REPLACE);
m_contactList.removeRef ( found );
m_contactList.append ( newCont );
m_uidToContact.remove( QString().setNum( contact.uid() ) );
m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont );
qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid());
return true;
} else
return false;
}
bool OPimContactAccessBackend_XML::remove ( int uid )
{
m_changed = true;
OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) );
if ( found ) {
updateJournal ( *found, ACTION_REMOVE);
m_contactList.removeRef ( found );
m_uidToContact.remove( QString().setNum( uid ) );
return true;
} else
return false;
}
bool OPimContactAccessBackend_XML::reload(){
/* Reload is the same as load in this implementation */
return ( load() );
}
void OPimContactAccessBackend_XML::addContact_p( const OPimContact &newcontact )
{
OPimContact* contRef = new OPimContact( newcontact );
m_contactList.append ( contRef );
m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef );
}
/* This function loads the xml-database and the journalfile */
bool OPimContactAccessBackend_XML::load( const QString filename, bool isJournal )
{
/* We use the time of the last read to check if the file was
* changed externally.
*/
if ( !isJournal ){
QFileInfo fi( filename );
m_readtime = fi.lastModified ();
}
const int JOURNALACTION = Qtopia::Notes + 1;
const int JOURNALROW = JOURNALACTION + 1;
bool foundAction = false;
journal_action action = ACTION_ADD;
int journalKey = 0;
QMap<int, QString> contactMap;
QMap<QString, QString> customMap;
QMap<QString, QString>::Iterator customIt;
QAsciiDict<int> dict( 47 );
dict.setAutoDelete( TRUE );
dict.insert( "Uid", new int(Qtopia::AddressUid) );
dict.insert( "Title", new int(Qtopia::Title) );
dict.insert( "FirstName", new int(Qtopia::FirstName) );
dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
dict.insert( "LastName", new int(Qtopia::LastName) );
dict.insert( "Suffix", new int(Qtopia::Suffix) );
dict.insert( "FileAs", new int(Qtopia::FileAs) );
dict.insert( "Categories", new int(Qtopia::AddressCategory) );
dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
dict.insert( "Emails", new int(Qtopia::Emails) );
dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
dict.insert( "HomeState", new int(Qtopia::HomeState) );
dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
dict.insert( "Company", new int(Qtopia::Company) );
dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
dict.insert( "Department", new int(Qtopia::Department) );
dict.insert( "Office", new int(Qtopia::Office) );
dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
dict.insert( "Profession", new int(Qtopia::Profession) );
dict.insert( "Assistant", new int(Qtopia::Assistant) );
dict.insert( "Manager", new int(Qtopia::Manager) );
dict.insert( "Spouse", new int(Qtopia::Spouse) );
dict.insert( "Children", new int(Qtopia::Children) );
dict.insert( "Gender", new int(Qtopia::Gender) );
dict.insert( "Birthday", new int(Qtopia::Birthday) );
dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
dict.insert( "Nickname", new int(Qtopia::Nickname) );
dict.insert( "Notes", new int(Qtopia::Notes) );
dict.insert( "action", new int(JOURNALACTION) );
dict.insert( "actionrow", new int(JOURNALROW) );
//qWarning( "OPimContactDefaultBackEnd::loading %s", filename.latin1() );
XMLElement *root = XMLElement::load( filename );
if(root != 0l ){ // start parsing
/* Parse all XML-Elements and put the data into the
* Contact-Class
*/
XMLElement *element = root->firstChild();
//qWarning("OPimContactAccess::load tagName(): %s", root->tagName().latin1() );
element = element->firstChild();
/* Search Tag "Contacts" which is the parent of all Contacts */
while( element && !isJournal ){
if( element->tagName() != QString::fromLatin1("Contacts") ){
//qWarning ("OPimContactDefBack::Searching for Tag \"Contacts\"! Found: %s",
// element->tagName().latin1());
element = element->nextChild();
} else {
element = element->firstChild();
break;
}
}
/* Parse all Contacts and ignore unknown tags */
while( element ){
if( element->tagName() != QString::fromLatin1("Contact") ){
//qWarning ("OPimContactDefBack::Searching for Tag \"Contact\"! Found: %s",
// element->tagName().latin1());
element = element->nextChild();
continue;
}
/* Found alement with tagname "contact", now parse and store all
* attributes contained
*/
//qWarning("OPimContactDefBack::load element tagName() : %s",
// element->tagName().latin1() );
QString dummy;
foundAction = false;
XMLElement::AttributeMap aMap = element->attributes();
XMLElement::AttributeMap::Iterator it;
contactMap.clear();
customMap.clear();
for( it = aMap.begin(); it != aMap.end(); ++it ){
// qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1());
int *find = dict[ it.key() ];
/* Unknown attributes will be stored as "Custom" elements */
if ( !find ) {
// qWarning("Attribute %s not known.", it.key().latin1());
//contact.setCustomField(it.key(), it.data());
customMap.insert( it.key(), it.data() );
continue;
}
/* Check if special conversion is needed and add attribute
* into Contact class
*/
switch( *find ) {
/*
case Qtopia::AddressUid:
contact.setUid( it.data().toInt() );
break;
case Qtopia::AddressCategory:
contact.setCategories( Qtopia::Record::idsFromString( it.data( )));
break;
*/
case JOURNALACTION:
action = journal_action(it.data().toInt());
foundAction = true;
qWarning ("ODefBack(journal)::ACTION found: %d", action);
break;
case JOURNALROW:
journalKey = it.data().toInt();
break;
default: // no conversion needed add them to the map
contactMap.insert( *find, it.data() );
break;
}
}
/* now generate the Contact contact */
OPimContact contact( contactMap );
for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) {
contact.setCustomField( customIt.key(), customIt.data() );
}
if (foundAction){
foundAction = false;
switch ( action ) {
case ACTION_ADD:
addContact_p (contact);
break;
case ACTION_REMOVE:
if ( !remove (contact.uid()) )
qWarning ("ODefBack(journal)::Unable to remove uid: %d",
contact.uid() );
break;
case ACTION_REPLACE:
if ( !replace ( contact ) )
qWarning ("ODefBack(journal)::Unable to replace uid: %d",
contact.uid() );
break;
default:
qWarning ("Unknown action: ignored !");
break;
}
}else{
/* Add contact to list */
addContact_p (contact);
}
/* Move to next element */
element = element->nextChild();
}
}else {
qWarning("ODefBack::could not load");
}
delete root;
qWarning("returning from loading" );
return true;
}
void OPimContactAccessBackend_XML::updateJournal( const OPimContact& cnt,
journal_action action )
{
QFile f( m_journalName );
bool created = !f.exists();
if ( !f.open(IO_WriteOnly|IO_Append) )
return;
QString buf;
QCString str;
// if the file was created, we have to set the Tag "<CONTACTS>" to
// 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 OPimContactAccessBackend_XML::removeJournal()
{
QFile f ( m_journalName );
if ( f.exists() )
f.remove();
}
}