summaryrefslogtreecommitdiff
path: root/libopie2/opiepim
Side-by-side diff
Diffstat (limited to 'libopie2/opiepim') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/obackendfactory.h16
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp664
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.h96
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp7
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.h6
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.cpp73
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.h6
-rw-r--r--libopie2/opiepim/ocontact.h13
-rw-r--r--libopie2/opiepim/ocontactfields.cpp456
-rw-r--r--libopie2/opiepim/ocontactfields.h60
10 files changed, 1373 insertions, 24 deletions
diff --git a/libopie2/opiepim/backend/obackendfactory.h b/libopie2/opiepim/backend/obackendfactory.h
index f3c339d..3567687 100644
--- a/libopie2/opiepim/backend/obackendfactory.h
+++ b/libopie2/opiepim/backend/obackendfactory.h
@@ -7,24 +7,29 @@
* 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: Use plugins
* =====================================================================
* Version: $Id$
* =====================================================================
* History:
* $Log$
+ * Revision 1.8 2003/09/22 14:31:16 eilers
+ * Added first experimental incarnation of sql-backend for addressbook.
+ * Some modifications to be able to compile the todo sql-backend.
+ * A lot of changes fill follow...
+ *
* Revision 1.7 2003/08/01 12:30:16 eilers
* Merging changes from BRANCH_1_0 to HEAD
*
* Revision 1.6.4.1 2003/06/30 14:34:19 eilers
* Patches from Zecke:
* Fixing and cleaning up extraMap handling
* Adding d_ptr for binary compatibility in the future
*
* Revision 1.6 2003/04/13 18:07:10 zecke
* More API doc
* QString -> const QString&
* QString = 0l -> QString::null
@@ -65,24 +70,25 @@
#define OPIE_BACKENDFACTORY_H_
#include <qstring.h>
#include <qasciidict.h>
#include <qpe/config.h>
#include "otodoaccessxml.h"
#include "ocontactaccessbackend_xml.h"
#include "odatebookaccessbackend_xml.h"
#ifdef __USE_SQL
#include "otodoaccesssql.h"
+#include "ocontactaccessbackend_sql.h"
#endif
class OBackendPrivate;
/**
* This class is our factory. It will give us the default implementations
* of at least Todolist, Contacts and Datebook. In the future this class will
* allow users to switch the backend with ( XML->SQLite ) without the need
* to recompile.#
* This class as the whole PIM Api is making use of templates
*
* <pre>
@@ -109,51 +115,55 @@ class OBackendFactory
* Returns a backend implementation for backendName
* @param backendName the type of the backend
* @param appName will be passed on to the backend
*/
static T* Default( const QString backendName, const QString& appName ){
// __asm__("int3");
Config config( "pimaccess" );
config.setGroup ( backendName );
QString backend = config.readEntry( "usebackend" );
+ qWarning("Selected backend for %s is: %s", backendName.latin1(), backend.latin1() );
+
QAsciiDict<int> dict ( 3 );
dict.setAutoDelete ( TRUE );
dict.insert( "todo", new int (TODO) );
dict.insert( "contact", new int (CONTACT) );
dict.insert( "datebook", new int(DATE) );
- qWarning ("TODO is: %d", TODO);
- qWarning ("CONTACT is: %d", CONTACT);
-
int *find = dict[ backendName ];
if (!find ) return 0;
switch ( *find ){
case TODO:
#ifdef __USE_SQL
if ( backend == "sql" )
return (T*) new OTodoAccessBackendSQL("");
#else
if ( backend == "sql" )
qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
#endif
return (T*) new OTodoAccessXML( appName );
case CONTACT:
+#ifdef __USE_SQL
+ if ( backend == "sql" )
+ return (T*) new OContactAccessBackend_SQL("");
+#else
if ( backend == "sql" )
qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
+#endif
return (T*) new OContactAccessBackend_XML( appName );
case DATE:
if ( backend == "sql" )
qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!");
return (T*) new ODateBookAccessBackend_XML( appName );
default:
return NULL;
}
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
new file mode 100644
index 0000000..4afa5f3
--- a/dev/null
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
@@ -0,0 +1,664 @@
+/*
+ * SQL 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.
+ * =====================================================================
+ * =====================================================================
+ * Version: $Id$
+ * =====================================================================
+ * History:
+ * $Log$
+ * Revision 1.1 2003/09/22 14:31:16 eilers
+ * Added first experimental incarnation of sql-backend for addressbook.
+ * Some modifications to be able to compile the todo sql-backend.
+ * A lot of changes fill follow...
+ *
+ */
+
+#include "ocontactaccessbackend_sql.h"
+
+#include <qarray.h>
+#include <qdatetime.h>
+#include <qstringlist.h>
+
+#include <qpe/global.h>
+#include <qpe/recordfields.h>
+
+#include <opie/ocontactfields.h>
+#include <opie/oconversion.h>
+#include <opie2/osqldriver.h>
+#include <opie2/osqlresult.h>
+#include <opie2/osqlmanager.h>
+#include <opie2/osqlquery.h>
+
+/*
+ * Implementation of used query types
+ * CREATE query
+ * LOAD query
+ * INSERT
+ * REMOVE
+ * CLEAR
+ */
+namespace {
+ /**
+ * CreateQuery for the Todolist Table
+ */
+ class CreateQuery : public OSQLQuery {
+ public:
+ CreateQuery();
+ ~CreateQuery();
+ QString query()const;
+ };
+
+ /**
+ * Clears (delete) a Table
+ */
+ class ClearQuery : public OSQLQuery {
+ public:
+ ClearQuery();
+ ~ClearQuery();
+ QString query()const;
+
+ };
+
+
+ /**
+ * LoadQuery
+ * this one queries for all uids
+ */
+ class LoadQuery : public OSQLQuery {
+ public:
+ LoadQuery();
+ ~LoadQuery();
+ QString query()const;
+ };
+
+ /**
+ * inserts/adds a OContact to the table
+ */
+ class InsertQuery : public OSQLQuery {
+ public:
+ InsertQuery(const OContact& );
+ ~InsertQuery();
+ QString query()const;
+ private:
+ OContact m_contact;
+ };
+
+
+ /**
+ * removes one from the table
+ */
+ class RemoveQuery : public OSQLQuery {
+ public:
+ RemoveQuery(int uid );
+ ~RemoveQuery();
+ QString query()const;
+ private:
+ int m_uid;
+ };
+
+ /**
+ * a find query for noncustom elements
+ */
+ class FindQuery : public OSQLQuery {
+ public:
+ FindQuery(int uid);
+ FindQuery(const QArray<int>& );
+ ~FindQuery();
+ QString query()const;
+ private:
+ QString single()const;
+ QString multi()const;
+ QArray<int> m_uids;
+ int m_uid;
+ };
+
+ /**
+ * a find query for custom elements
+ */
+ class FindCustomQuery : public OSQLQuery {
+ public:
+ FindCustomQuery(int uid);
+ FindCustomQuery(const QArray<int>& );
+ ~FindCustomQuery();
+ QString query()const;
+ private:
+ QString single()const;
+ QString multi()const;
+ QArray<int> m_uids;
+ int m_uid;
+ };
+
+
+
+ // We using three tables to store the information:
+ // 1. addressbook : It contains General information about the contact (non custom)
+ // 2. dates : Stuff like birthdays, anniversaries, etc.
+ // 3. custom_data : Not official supported entries
+ // All tables are connected by the uid of the contact.
+ // Maybe I should add a table for meta-information ?
+ CreateQuery::CreateQuery() : OSQLQuery() {}
+ CreateQuery::~CreateQuery() {}
+ QString CreateQuery::query()const {
+ QString qu;
+ qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));";
+ qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
+// qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );";
+ return qu;
+ }
+
+ ClearQuery::ClearQuery()
+ : OSQLQuery() {}
+ ClearQuery::~ClearQuery() {}
+ QString ClearQuery::query()const {
+ QString qu = "drop table addressbook;";
+ qu += "drop table custom_data;";
+ qu += "drop table dates;";
+ return qu;
+ }
+
+// Distinct loading is not very fast. If I expect that every person has just
+// one (and always one) 'Last Name', I can request all uid's for existing lastnames,
+// which is faster..
+// But this may not be true for all entries, like company contacts..
+// The current AddressBook application handles this problem, but other may not.. (eilers)
+#define __USE_SUPERFAST_LOADQUERY
+
+ LoadQuery::LoadQuery() : OSQLQuery() {}
+ LoadQuery::~LoadQuery() {}
+ QString LoadQuery::query()const {
+ QString qu;
+#ifndef __USE_SUPERFAST_LOADQUERY
+ qu += "select distinct uid from addressbook";
+#else
+ qu += "select uid from addressbook where type = 'Last Name'";
+#endif
+
+ return qu;
+ }
+
+
+ InsertQuery::InsertQuery( const OContact& contact )
+ : OSQLQuery(), m_contact( contact ) {
+ }
+
+ InsertQuery::~InsertQuery() {
+ }
+
+ /*
+ * converts from a OContact to a query
+ */
+ QString InsertQuery::query()const{
+
+ // Get all information out of the contact-class
+ // Remember: The category is stored in contactMap, too !
+ QMap<int, QString> contactMap = m_contact.toMap();
+ QMap<QString, QString> customMap = m_contact.toExtraMap();
+
+ QMap<QString, QString> addressbook_db;
+
+ // Get the translation from the ID to the String
+ QMap<int, QString> transMap = OContactFields::idToUntrFields();
+
+ for( QMap<int, QString>::Iterator it = contactMap.begin();
+ it != contactMap.end(); ++it ){
+ switch ( it.key() ){
+ case Qtopia::Birthday:{
+ // These entries should stored in a special format
+ // year-month-day
+ QDate day = m_contact.birthday();
+ addressbook_db.insert( transMap[it.key()],
+ QString("%1-%2-%3")
+ .arg( day.year() )
+ .arg( day.month() )
+ .arg( day.day() ) );
+ }
+ break;
+ case Qtopia::Anniversary:{
+ // These entries should stored in a special format
+ // year-month-day
+ QDate day = m_contact.anniversary();
+ addressbook_db.insert( transMap[it.key()],
+ QString("%1-%2-%3")
+ .arg( day.year() )
+ .arg( day.month() )
+ .arg( day.day() ) );
+ }
+ break;
+ case Qtopia::AddressUid: // Ignore UID
+ break;
+ default: // Translate id to String
+ addressbook_db.insert( transMap[it.key()], it.data() );
+ break;
+ }
+
+ }
+
+ // Now convert this whole stuff into a SQL String, beginning with
+ // the addressbook table..
+ QString qu;
+ // qu += "begin transaction;";
+ int id = 0;
+ for( QMap<QString, QString>::Iterator it = addressbook_db.begin();
+ it != addressbook_db.end(); ++it ){
+ qu += "insert into addressbook VALUES("
+ + QString::number( m_contact.uid() )
+ + ","
+ + QString::number( id++ )
+ + ",'"
+ + it.key() //.latin1()
+ + "',"
+ + "0" // Priority for future enhancements
+ + ",'"
+ + it.data() //.latin1()
+ + "');";
+ }
+
+ // Now add custom data..
+ id = 0;
+ for( QMap<QString, QString>::Iterator it = customMap.begin();
+ it != customMap.end(); ++it ){
+ qu += "insert into custom_data VALUES("
+ + QString::number( m_contact.uid() )
+ + ","
+ + QString::number( id++ )
+ + ",'"
+ + it.key() //.latin1()
+ + "',"
+ + "0" // Priority for future enhancements
+ + ",'"
+ + it.data() //.latin1()
+ + "');";
+ }
+
+ // qu += "commit;";
+ qWarning("add %s", qu.latin1() );
+ return qu;
+ }
+
+
+ RemoveQuery::RemoveQuery(int uid )
+ : OSQLQuery(), m_uid( uid ) {}
+ RemoveQuery::~RemoveQuery() {}
+ QString RemoveQuery::query()const {
+ QString qu = "DELETE from addressbook where uid = "
+ + QString::number(m_uid) + ";";
+ qu += "DELETE from dates where uid = "
+ + QString::number(m_uid) + ";";
+ qu += "DELETE from custom_data where uid = "
+ + QString::number(m_uid) + ";";
+ return qu;
+ }
+
+
+
+
+ FindQuery::FindQuery(int uid)
+ : OSQLQuery(), m_uid( uid ) {
+ }
+ FindQuery::FindQuery(const QArray<int>& ints)
+ : OSQLQuery(), m_uids( ints ){
+ }
+ FindQuery::~FindQuery() {
+ }
+ QString FindQuery::query()const{
+// if ( m_uids.count() == 0 )
+ return single();
+ }
+ /*
+ else
+ return multi();
+ }
+ QString FindQuery::multi()const {
+ QString qu = "select uid, type, value from addressbook where";
+ for (uint i = 0; i < m_uids.count(); i++ ) {
+ qu += " UID = " + QString::number( m_uids[i] ) + " OR";
+ }
+ qu.remove( qu.length()-2, 2 ); // Hmmmm..
+ return qu;
+ }
+ */
+ QString FindQuery::single()const{
+ QString qu = "select uid, type, value from addressbook where uid = ";
+ qu += QString::number(m_uid);
+ return qu;
+ }
+
+
+ FindCustomQuery::FindCustomQuery(int uid)
+ : OSQLQuery(), m_uid( uid ) {
+ }
+ FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
+ : OSQLQuery(), m_uids( ints ){
+ }
+ FindCustomQuery::~FindCustomQuery() {
+ }
+ QString FindCustomQuery::query()const{
+// if ( m_uids.count() == 0 )
+ return single();
+ }
+ QString FindCustomQuery::single()const{
+ QString qu = "select uid, type, value from custom_data where uid = ";
+ qu += QString::number(m_uid);
+ return qu;
+ }
+
+};
+
+
+/* --------------------------------------------------------------------------- */
+
+OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */,
+ const QString& filename ): m_changed(false)
+{
+ qWarning("C'tor OContactAccessBackend_SQL starts");
+ QTime t;
+ t.start();
+
+ /* Expecting to access the default filename if nothing else is set */
+ if ( filename.isEmpty() ){
+ m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
+ } else
+ m_fileName = filename;
+
+ // Get the standart sql-driver from the OSQLManager..
+ OSQLManager man;
+ m_driver = man.standard();
+ m_driver->setUrl( m_fileName );
+
+ load();
+
+ qWarning("C'tor OContactAccessBackend_SQL ends: %d", t.elapsed() );
+}
+
+
+bool OContactAccessBackend_SQL::load ()
+{
+ if (!m_driver->open() )
+ return false;
+
+ // Don't expect that the database exists.
+ // It is save here to create the table, even if it
+ // do exist. ( Is that correct for all databases ?? )
+ CreateQuery creat;
+ OSQLResult res = m_driver->query( &creat );
+
+ update();
+
+ return true;
+
+}
+
+bool OContactAccessBackend_SQL::reload()
+{
+ return load();
+}
+
+bool OContactAccessBackend_SQL::save()
+{
+ return m_driver->close();
+}
+
+
+void OContactAccessBackend_SQL::clear ()
+{
+ ClearQuery cle;
+ OSQLResult res = m_driver->query( &cle );
+ CreateQuery qu;
+ res = m_driver->query(&qu);
+}
+
+bool OContactAccessBackend_SQL::wasChangedExternally()
+{
+ return false;
+}
+
+QArray<int> OContactAccessBackend_SQL::allRecords() const
+{
+
+ // FIXME: Think about cute handling of changed tables..
+ // Thus, we don't have to call update here...
+ if ( m_changed )
+ ((OContactAccessBackend_SQL*)this)->update();
+
+ return m_uids;
+}
+
+bool OContactAccessBackend_SQL::add ( const OContact &newcontact )
+{
+ InsertQuery ins( newcontact );
+ OSQLResult res = m_driver->query( &ins );
+
+ if ( res.state() == OSQLResult::Failure )
+ return false;
+
+ int c = m_uids.count();
+ m_uids.resize( c+1 );
+ m_uids[c] = newcontact.uid();
+
+ return true;
+}
+
+
+bool OContactAccessBackend_SQL::remove ( int uid )
+{
+ RemoveQuery rem( uid );
+ OSQLResult res = m_driver->query(&rem );
+
+ if ( res.state() == OSQLResult::Failure )
+ return false;
+
+ m_changed = true;
+
+ return true;
+}
+
+bool OContactAccessBackend_SQL::replace ( const OContact &contact )
+{
+ if ( !remove( contact.uid() ) )
+ return false;
+
+ return add( contact );
+}
+
+
+OContact OContactAccessBackend_SQL::find ( int uid ) const
+{
+ qWarning("OContactAccessBackend_SQL::find()");
+ QTime t;
+ t.start();
+
+ OContact retContact( requestNonCustom( uid ) );
+ retContact.setExtraMap( requestCustom( uid ) );
+
+ qWarning("OContactAccessBackend_SQL::find() needed: %d", t.elapsed() );
+ return retContact;
+}
+
+
+
+QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() )
+{
+ QArray<int> nix(0);
+ return nix;
+}
+
+QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
+{
+ QArray<int> nix(0);
+ return nix;
+}
+
+const uint OContactAccessBackend_SQL::querySettings()
+{
+ return 0;
+}
+
+bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
+{
+ return false;
+}
+
+QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int )
+{
+ QTime t;
+ t.start();
+
+ // Not implemented..
+ QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' ";
+
+ query += "ORDER BY value ";
+ if ( !asc )
+ query += "DESC";
+
+ qWarning("sorted query is: %s", query.latin1() );
+
+ OSQLRawQuery raw( query );
+ OSQLResult res = m_driver->query( &raw );
+ if ( res.state() != OSQLResult::Success ){
+ QArray<int> empty;
+ return empty;
+ }
+
+ QArray<int> list = extractUids( res );
+
+ qWarning("sorted needed %d ms!", t.elapsed() );
+ return list;
+}
+
+
+void OContactAccessBackend_SQL::update()
+{
+ qWarning("Update starts");
+ QTime t;
+ t.start();
+
+ // Now load the database set and extract the uid's
+ // which will be held locally
+
+ LoadQuery lo;
+ OSQLResult res = m_driver->query(&lo);
+ if ( res.state() != OSQLResult::Success )
+ return;
+
+ m_uids = extractUids( res );
+
+ m_changed = false;
+
+ qWarning("Update ends %d", t.elapsed() );
+}
+
+QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
+{
+ qWarning("extractUids");
+ QTime t;
+ t.start();
+ OSQLResultItem::ValueList list = res.results();
+ OSQLResultItem::ValueList::Iterator it;
+ QArray<int> ints(list.count() );
+ qWarning(" count = %d", list.count() );
+
+ int i = 0;
+ for (it = list.begin(); it != list.end(); ++it ) {
+ ints[i] = (*it).data("uid").toInt();
+ i++;
+ }
+ qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
+
+ return ints;
+
+}
+
+QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
+{
+ QTime t;
+ t.start();
+
+ QMap<int, QString> nonCustomMap;
+
+ int t2needed = 0;
+ QTime t2;
+ t2.start();
+ FindQuery query( uid );
+ OSQLResult res_noncustom = m_driver->query( &query );
+ t2needed = t2.elapsed();
+
+ if ( res_noncustom.state() == OSQLResult::Failure ) {
+ qWarning("OSQLResult::Failure in find query !!");
+ QMap<int, QString> empty;
+ return empty;
+ }
+
+ int t3needed = 0;
+ QTime t3;
+ t3.start();
+ QMap<QString, int> translateMap = OContactFields::untrFieldsToId();
+
+ OSQLResultItem::ValueList list = res_noncustom.results();
+ OSQLResultItem::ValueList::Iterator it = list.begin();
+ for ( ; it != list.end(); ++it ) {
+ if ( (*it).data("type") != "" ){
+ int typeId = translateMap[(*it).data( "type" )];
+ switch( typeId ){
+ case Qtopia::Birthday:
+ case Qtopia::Anniversary:{
+ // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
+ QStringList list = QStringList::split( '-', (*it).data( "value" ) );
+ QStringList::Iterator lit = list.begin();
+ int year = (*lit).toInt();
+ qWarning("1. %s", (*lit).latin1());
+ int month = (*(++lit)).toInt();
+ qWarning("2. %s", (*lit).latin1());
+ int day = (*(++lit)).toInt();
+ qWarning("3. %s", (*lit).latin1());
+ qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day );
+ QDate date( year, month, day );
+ nonCustomMap.insert( typeId, OConversion::dateToString( date ) );
+ }
+ break;
+ default:
+ nonCustomMap.insert( typeId,
+ (*it).data( "value" ) );
+ }
+ }
+ }
+ // Add UID to Map..
+ nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) );
+ t3needed = t3.elapsed();
+
+ qWarning("RequestNonCustom needed: ins:%d, query: %d, mapping: %d", t.elapsed(), t2needed, t3needed );
+ return nonCustomMap;
+}
+
+QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const
+{
+ QTime t;
+ t.start();
+
+ QMap<QString, QString> customMap;
+
+ FindCustomQuery query( uid );
+ OSQLResult res_custom = m_driver->query( &query );
+
+ if ( res_custom.state() == OSQLResult::Failure ) {
+ qWarning("OSQLResult::Failure in find query !!");
+ QMap<QString, QString> empty;
+ return empty;
+ }
+
+ OSQLResultItem::ValueList list = res_custom.results();
+ OSQLResultItem::ValueList::Iterator it = list.begin();
+ for ( ; it != list.end(); ++it ) {
+ customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
+ }
+
+ qWarning("RequestCustom needed: %d", t.elapsed() );
+ return customMap;
+}
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
new file mode 100644
index 0000000..bb22551
--- a/dev/null
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
@@ -0,0 +1,96 @@
+/*
+ * SQL 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.
+ * =====================================================================
+ *
+ *
+ * =====================================================================
+ * Version: $Id$
+ * =====================================================================
+ * History:
+ * $Log$
+ * Revision 1.1 2003/09/22 14:31:16 eilers
+ * Added first experimental incarnation of sql-backend for addressbook.
+ * Some modifications to be able to compile the todo sql-backend.
+ * A lot of changes fill follow...
+ *
+ *
+ */
+
+#ifndef _OContactAccessBackend_SQL_
+#define _OContactAccessBackend_SQL_
+
+#include "ocontactaccessbackend.h"
+#include "ocontactaccess.h"
+
+#include <qlist.h>
+#include <qdict.h>
+
+class OSQLDriver;
+class OSQLResult;
+class OSQLResultItem;
+
+/* the default xml implementation */
+/**
+ * This class is the SQL implementation of a Contact backend
+ * it does implement everything available for OContact.
+ * @see OPimAccessBackend for more information of available methods
+ */
+class OContactAccessBackend_SQL : public OContactAccessBackend {
+ public:
+ OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null );
+
+ bool save();
+
+ bool load ();
+
+ void clear ();
+
+ bool wasChangedExternally();
+
+ QArray<int> allRecords() const;
+
+ OContact find ( int uid ) const;
+ // FIXME: Add lookahead-cache support !
+ //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
+
+ QArray<int> queryByExample ( const OContact &query, int settings,
+ const QDateTime& d );
+
+ QArray<int> matchRegexp( const QRegExp &r ) const;
+
+ const uint querySettings();
+
+ bool hasQuerySettings (uint querySettings) const;
+
+ // Currently only asc implemented..
+ QArray<int> sorted( bool asc, int , int , int );
+ bool add ( const OContact &newcontact );
+
+ bool replace ( const OContact &contact );
+
+ bool remove ( int uid );
+ bool reload();
+
+ private:
+ QArray<int> extractUids( OSQLResult& res ) const;
+ QMap<int, QString> requestNonCustom( int uid ) const;
+ QMap<QString, QString> requestCustom( int uid ) const;
+ void update();
+
+ protected:
+ bool m_changed;
+ QString m_fileName;
+ QArray<int> m_uids;
+
+ OSQLDriver* m_driver;
+};
+
+#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
index 1b5af2f..aae7fca 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
@@ -1,31 +1,34 @@
/*
* 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.9 2003/09/22 14:31:16 eilers
+ * Added first experimental incarnation of sql-backend for addressbook.
+ * Some modifications to be able to compile the todo sql-backend.
+ * A lot of changes fill follow...
+ *
* Revision 1.8 2003/08/30 15:28:26 eilers
* Removed some unimportant debug output which causes slow down..
*
* Revision 1.7 2003/08/01 12:30:16 eilers
* Merging changes from BRANCH_1_0 to HEAD
*
* Revision 1.6 2003/07/07 16:19:47 eilers
* Fixing serious bug in hasQuerySettings()
*
* Revision 1.5 2003/04/13 18:07:10 zecke
* More API doc
* QString -> const QString&
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
index 7b5365b..a0cae4d 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
@@ -1,31 +1,37 @@
/*
* 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...
+ * File Locking to protect against concurrent access
*
*
* =====================================================================
* Version: $Id$
* =====================================================================
* History:
* $Log$
+ * Revision 1.15 2003/09/22 14:31:16 eilers
+ * Added first experimental incarnation of sql-backend for addressbook.
+ * Some modifications to be able to compile the todo sql-backend.
+ * A lot of changes fill follow...
+ *
* Revision 1.14 2003/04/13 18:07:10 zecke
* More API doc
* QString -> const QString&
* QString = 0l -> QString::null
*
* Revision 1.13 2003/03/21 10:33:09 eilers
* Merged speed optimized xml backend for contacts to main.
* Added QDateTime to querybyexample. For instance, it is now possible to get
* all Birthdays/Anniversaries between two dates. This should be used
* to show all birthdays in the datebook..
* This change is sourcecode backward compatible but you have to upgrade
* the binaries for today-addressbook.
diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp
index ec9c14c..23e0c3e 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.cpp
+++ b/libopie2/opiepim/backend/otodoaccesssql.cpp
@@ -1,21 +1,21 @@
#include <qdatetime.h>
#include <qpe/global.h>
-#include <opie/osqldriver.h>
-#include <opie/osqlresult.h>
-#include <opie/osqlmanager.h>
-#include <opie/osqlquery.h>
+#include <opie2/osqldriver.h>
+#include <opie2/osqlresult.h>
+#include <opie2/osqlmanager.h>
+#include <opie2/osqlquery.h>
#include "otodoaccesssql.h"
/*
* first some query
* CREATE query
* LOAD query
* INSERT
* REMOVE
* CLEAR
*/
namespace {
@@ -240,25 +240,25 @@ namespace {
}
};
OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file )
: OTodoAccessBackend(), m_dict(15), m_dirty(true)
{
QString fi = file;
if ( fi.isEmpty() )
fi = Global::applicationFileName( "todolist", "todolist.db" );
OSQLManager man;
m_driver = man.standard();
m_driver->setUrl(fi);
- fillDict();
+ // fillDict();
}
OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){
}
bool OTodoAccessBackendSQL::load(){
if (!m_driver->open() )
return false;
CreateQuery creat;
OSQLResult res = m_driver->query(&creat );
m_dirty = true;
@@ -288,33 +288,33 @@ OTodo OTodoAccessBackendSQL::find(int uid ) const{
}
OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
uint cur, Frontend::CacheDirection dir ) const{
int CACHE = readAhead();
qWarning("searching for %d", uid );
QArray<int> search( CACHE );
uint size =0;
OTodo to;
// we try to cache CACHE items
switch( dir ) {
/* forward */
- case 0:
+ case 0: // FIXME: Not a good style to use magic numbers here (eilers)
for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
qWarning("size %d %d", size, ints[i] );
search[size] = ints[i];
size++;
}
break;
/* reverse */
- case 1:
+ case 1: // FIXME: Not a good style to use magic numbers here (eilers)
for (uint i = cur; i != 0 && size < CACHE; i-- ) {
search[size] = ints[i];
size++;
}
break;
}
search.resize( size );
FindQuery query( search );
OSQLResult res = m_driver->query( &query );
if ( res.state() != OSQLResult::Success )
return to;
@@ -372,24 +372,25 @@ QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s,
/*
*
*/
QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
int sortFilter, int cat ) {
qWarning("sorted %d, %d", asc, sortOrder );
QString query;
query = "select uid from todolist WHERE ";
/*
* Sort Filter stuff
* not that straight forward
+ * FIXME: Replace magic numbers
*
*/
/* Category */
if ( sortFilter & 1 ) {
QString str;
if (cat != 0 ) str = QString::number( cat );
query += " categories like '%" +str+"%' AND";
}
/* Show only overdue */
if ( sortFilter & 2 ) {
QDate date = QDate::currentDate();
QString due;
@@ -483,41 +484,42 @@ OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const {
}
OTodo OTodoAccessBackendSQL::todo( int uid )const {
FindQuery find( uid );
return todo( m_driver->query(&find) );
}
/*
* update the dict
*/
void OTodoAccessBackendSQL::fillDict() {
/* initialize dict */
/*
* UPDATE dict if you change anything!!!
+ * FIXME: Isn't this dict obsolete ? (eilers)
*/
m_dict.setAutoDelete( TRUE );
m_dict.insert("Categories" , new int(OTodo::Category) );
m_dict.insert("Uid" , new int(OTodo::Uid) );
m_dict.insert("HasDate" , new int(OTodo::HasDate) );
m_dict.insert("Completed" , new int(OTodo::Completed) );
m_dict.insert("Description" , new int(OTodo::Description) );
m_dict.insert("Summary" , new int(OTodo::Summary) );
m_dict.insert("Priority" , new int(OTodo::Priority) );
m_dict.insert("DateDay" , new int(OTodo::DateDay) );
m_dict.insert("DateMonth" , new int(OTodo::DateMonth) );
m_dict.insert("DateYear" , new int(OTodo::DateYear) );
m_dict.insert("Progress" , new int(OTodo::Progress) );
- m_dict.insert("Completed", new int(OTodo::Completed) );
+ m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers)
m_dict.insert("CrossReference", new int(OTodo::CrossReference) );
- m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) );
- m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) );
+// m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers)
+// m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers)
}
/*
* need to be const so let's fool the
* compiler :(
*/
void OTodoAccessBackendSQL::update()const {
((OTodoAccessBackendSQL*)this)->m_dirty = false;
LoadQuery lo;
OSQLResult res = m_driver->query(&lo);
if ( res.state() != OSQLResult::Success )
return;
@@ -529,12 +531,63 @@ QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{
OSQLResultItem::ValueList::Iterator it;
QArray<int> ints(list.count() );
qWarning(" count = %d", list.count() );
int i = 0;
for (it = list.begin(); it != list.end(); ++it ) {
ints[i] = (*it).data("uid").toInt();
i++;
}
return ints;
}
+QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
+{
+
+#warning OTodoAccessBackendSQL::matchRegexp() not implemented !!
+
+#if 0
+
+ Copied from xml-backend by not adapted to sql (eilers)
+
+ QArray<int> m_currentQuery( m_events.count() );
+ uint arraycounter = 0;
+
+
+
+ QMap<int, OTodo>::ConstIterator it;
+ for (it = m_events.begin(); it != m_events.end(); ++it ) {
+ if ( it.data().match( r ) )
+ m_currentQuery[arraycounter++] = it.data().uid();
+
+ }
+ // Shrink to fit..
+ m_currentQuery.resize(arraycounter);
+
+ return m_currentQuery;
+#endif
+ QArray<int> empty;
+ return empty;
+}
+QBitArray OTodoAccessBackendSQL::supports()const {
+
+ static QBitArray ar = sup();
+ return ar;
+}
+
+QBitArray OTodoAccessBackendSQL::sup() {
+
+ QBitArray ar( OTodo::CompletedDate + 1 );
+ ar.fill( true );
+ ar[OTodo::CrossReference] = false;
+ ar[OTodo::State ] = false;
+ ar[OTodo::Reminders] = false;
+ ar[OTodo::Notifiers] = false;
+ ar[OTodo::Maintainer] = false;
+
+ return ar;
+}
+
+void OTodoAccessBackendSQL::removeAllCompleted(){
+#warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !!
+
+}
diff --git a/libopie2/opiepim/backend/otodoaccesssql.h b/libopie2/opiepim/backend/otodoaccesssql.h
index 6a4257c..77d8b77 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.h
+++ b/libopie2/opiepim/backend/otodoaccesssql.h
@@ -22,29 +22,35 @@ public:
OTodo find(int uid)const;
OTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
void clear();
bool add( const OTodo& t );
bool remove( int uid );
bool replace( const OTodo& t );
QArray<int> overDue();
QArray<int> effectiveToDos( const QDate& start,
const QDate& end, bool includeNoDates );
QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat );
+ QBitArray supports()const;
+ QArray<int> matchRegexp( const QRegExp &r ) const;
+ void removeAllCompleted();
+
+
private:
void update()const;
void fillDict();
inline bool date( QDate& date, const QString& )const;
inline OTodo todo( const OSQLResult& )const;
inline OTodo todo( OSQLResultItem& )const;
inline QArray<int> uids( const OSQLResult& )const;
OTodo todo( int uid )const;
+ QBitArray sup();
QAsciiDict<int> m_dict;
OSQLDriver* m_driver;
QArray<int> m_uids;
bool m_dirty : 1;
};
#endif
diff --git a/libopie2/opiepim/ocontact.h b/libopie2/opiepim/ocontact.h
index 9a1a8dc..1d46b81 100644
--- a/libopie2/opiepim/ocontact.h
+++ b/libopie2/opiepim/ocontact.h
@@ -187,50 +187,45 @@ public:
QString gender() const { return find( Qtopia::Gender ); }
QDate birthday() const;
QDate anniversary() const;
QString nickname() const { return find( Qtopia::Nickname ); }
QString children() const { return find( Qtopia::Children ); }
QStringList childrenList() const;
// other
QString notes() const { return find( Qtopia::Notes ); }
QString groups() const { return find( Qtopia::Groups ); }
QStringList groupList() const;
-// // custom
-// const QString &customField( const QString &key )
-// { return find( Custom- + key ); }
-
-
QString toRichText() const;
QMap<int, QString> toMap() const;
QString field( int key ) const { return find( key ); }
void setUid( int i );
QString toShortText()const;
- QString OContact::type()const;
- QMap<QString,QString> OContact::toExtraMap() const;
- class QString OContact::recordField(int) const;
+ QString type()const;
+ class QString recordField(int) const;
// Why private ? (eilers,se)
QString emailSeparator() const { return " "; }
+
// the emails should be seperated by a comma
void setEmails( const QString &v );
QString emails() const { return find( Qtopia::Emails ); }
static int rtti();
private:
- // The XML-Backend needs some access to the private functions
+ // The XML Backend needs some access to the private functions
friend class OContactAccessBackend_XML;
void insert( int key, const QString &value );
void replace( int key, const QString &value );
QString find( int key ) const;
static QStringList fields();
void save( QString &buf ) const;
QString displayAddress( const QString &street,
const QString &city,
const QString &state,
diff --git a/libopie2/opiepim/ocontactfields.cpp b/libopie2/opiepim/ocontactfields.cpp
new file mode 100644
index 0000000..831a596
--- a/dev/null
+++ b/libopie2/opiepim/ocontactfields.cpp
@@ -0,0 +1,456 @@
+
+#include "ocontactfields.h"
+
+#include <qstringlist.h>
+#include <qobject.h>
+
+// We should use our own enum in the future ..
+#include <qpe/recordfields.h>
+#include <qpe/config.h>
+#include <opie/ocontact.h>
+
+/*!
+ \internal
+ Returns a list of details field names for a contact.
+*/
+QStringList OContactFields::untrdetailsfields( bool sorted )
+{
+ QStringList list;
+ QMap<int, QString> mapIdToStr = idToUntrFields();
+
+ list.append( mapIdToStr[ Qtopia::Office ] );
+ list.append( mapIdToStr[ Qtopia::Profession ] );
+ list.append( mapIdToStr[ Qtopia::Assistant ] );
+ list.append( mapIdToStr[ Qtopia::Manager ] );
+
+ list.append( mapIdToStr[ Qtopia::Spouse ] );
+ list.append( mapIdToStr[ Qtopia::Gender ] );
+ list.append( mapIdToStr[ Qtopia::Birthday ] );
+ list.append( mapIdToStr[ Qtopia::Anniversary ] );
+ list.append( mapIdToStr[ Qtopia::Nickname ] );
+ list.append( mapIdToStr[ Qtopia::Children ] );
+
+ if (sorted) list.sort();
+ return list;
+}
+
+/*!
+ \internal
+ Returns a translated list of details field names for a contact.
+*/
+QStringList OContactFields::trdetailsfields( bool sorted )
+{
+ QStringList list;
+ QMap<int, QString> mapIdToStr = idToTrFields();
+
+ list.append( mapIdToStr[Qtopia::Office] );
+ list.append( mapIdToStr[Qtopia::Profession] );
+ list.append( mapIdToStr[Qtopia::Assistant] );
+ list.append( mapIdToStr[Qtopia::Manager] );
+
+ list.append( mapIdToStr[Qtopia::Spouse] );
+ list.append( mapIdToStr[Qtopia::Gender] );
+ list.append( mapIdToStr[Qtopia::Birthday] );
+ list.append( mapIdToStr[Qtopia::Anniversary] );
+ list.append( mapIdToStr[Qtopia::Nickname] );
+ list.append( mapIdToStr[Qtopia::Children] );
+
+ if (sorted) list.sort();
+ return list;
+}
+
+
+/*!
+ \internal
+ Returns a translated list of phone field names for a contact.
+*/
+QStringList OContactFields::trphonefields( bool sorted )
+{
+ QStringList list;
+ QMap<int, QString> mapIdToStr = idToTrFields();
+
+ list.append( mapIdToStr[Qtopia::BusinessPhone] );
+ list.append( mapIdToStr[Qtopia::BusinessFax] );
+ list.append( mapIdToStr[Qtopia::BusinessMobile] );
+ list.append( mapIdToStr[Qtopia::BusinessPager] );
+ list.append( mapIdToStr[Qtopia::BusinessWebPage] );
+
+ list.append( mapIdToStr[Qtopia::DefaultEmail] );
+ list.append( mapIdToStr[Qtopia::Emails] );
+
+ list.append( mapIdToStr[Qtopia::HomePhone] );
+ list.append( mapIdToStr[Qtopia::HomeFax] );
+ list.append( mapIdToStr[Qtopia::HomeMobile] );
+ // list.append( mapIdToStr[Qtopia::HomePager] );
+ list.append( mapIdToStr[Qtopia::HomeWebPage] );
+
+ if (sorted) list.sort();
+
+ return list;
+}
+
+
+/*!
+ \internal
+ Returns a list of phone field names for a contact.
+*/
+QStringList OContactFields::untrphonefields( bool sorted )
+{
+ QStringList list;
+ QMap<int, QString> mapIdToStr = idToUntrFields();
+
+ list.append( mapIdToStr[ Qtopia::BusinessPhone ] );
+ list.append( mapIdToStr[ Qtopia::BusinessFax ] );
+ list.append( mapIdToStr[ Qtopia::BusinessMobile ] );
+ list.append( mapIdToStr[ Qtopia::BusinessPager ] );
+ list.append( mapIdToStr[ Qtopia::BusinessWebPage ] );
+
+ list.append( mapIdToStr[ Qtopia::DefaultEmail ] );
+ list.append( mapIdToStr[ Qtopia::Emails ] );
+
+ list.append( mapIdToStr[ Qtopia::HomePhone ] );
+ list.append( mapIdToStr[ Qtopia::HomeFax ] );
+ list.append( mapIdToStr[ Qtopia::HomeMobile ] );
+ //list.append( mapIdToStr[Qtopia::HomePager] );
+ list.append( mapIdToStr[Qtopia::HomeWebPage] );
+
+ if (sorted) list.sort();
+
+ return list;
+}
+
+
+/*!
+ \internal
+ Returns a translated list of field names for a contact.
+*/
+QStringList OContactFields::trfields( bool sorted )
+{
+ QStringList list;
+ QMap<int, QString> mapIdToStr = idToTrFields();
+
+ list.append( mapIdToStr[Qtopia::Title]);
+ list.append( mapIdToStr[Qtopia::FirstName] );
+ list.append( mapIdToStr[Qtopia::MiddleName] );
+ list.append( mapIdToStr[Qtopia::LastName] );
+ list.append( mapIdToStr[Qtopia::Suffix] );
+ list.append( mapIdToStr[Qtopia::FileAs] );
+
+ list.append( mapIdToStr[Qtopia::JobTitle] );
+ list.append( mapIdToStr[Qtopia::Department] );
+ list.append( mapIdToStr[Qtopia::Company] );
+
+ list += trphonefields( sorted );
+
+ list.append( mapIdToStr[Qtopia::BusinessStreet] );
+ list.append( mapIdToStr[Qtopia::BusinessCity] );
+ list.append( mapIdToStr[Qtopia::BusinessState] );
+ list.append( mapIdToStr[Qtopia::BusinessZip] );
+ list.append( mapIdToStr[Qtopia::BusinessCountry] );
+
+ list.append( mapIdToStr[Qtopia::HomeStreet] );
+ list.append( mapIdToStr[Qtopia::HomeCity] );
+ list.append( mapIdToStr[Qtopia::HomeState] );
+ list.append( mapIdToStr[Qtopia::HomeZip] );
+ list.append( mapIdToStr[Qtopia::HomeCountry] );
+
+ list += trdetailsfields( sorted );
+
+ list.append( mapIdToStr[Qtopia::Notes] );
+ list.append( mapIdToStr[Qtopia::Groups] );
+
+ if (sorted) list.sort();
+
+ return list;
+}
+
+/*!
+ \internal
+ Returns an untranslated list of field names for a contact.
+*/
+QStringList OContactFields::untrfields( bool sorted )
+{
+ QStringList list;
+ QMap<int, QString> mapIdToStr = idToUntrFields();
+
+ list.append( mapIdToStr[ Qtopia::Title ] );
+ list.append( mapIdToStr[ Qtopia::FirstName ] );
+ list.append( mapIdToStr[ Qtopia::MiddleName ] );
+ list.append( mapIdToStr[ Qtopia::LastName ] );
+ list.append( mapIdToStr[ Qtopia::Suffix ] );
+ list.append( mapIdToStr[ Qtopia::FileAs ] );
+
+ list.append( mapIdToStr[ Qtopia::JobTitle ] );
+ list.append( mapIdToStr[ Qtopia::Department ] );
+ list.append( mapIdToStr[ Qtopia::Company ] );
+
+ list += untrphonefields( sorted );
+
+ list.append( mapIdToStr[ Qtopia::BusinessStreet ] );
+ list.append( mapIdToStr[ Qtopia::BusinessCity ] );
+ list.append( mapIdToStr[ Qtopia::BusinessState ] );
+ list.append( mapIdToStr[ Qtopia::BusinessZip ] );
+ list.append( mapIdToStr[ Qtopia::BusinessCountry ] );
+
+ list.append( mapIdToStr[ Qtopia::HomeStreet ] );
+ list.append( mapIdToStr[ Qtopia::HomeCity ] );
+ list.append( mapIdToStr[ Qtopia::HomeState ] );
+ list.append( mapIdToStr[ Qtopia::HomeZip ] );
+ list.append( mapIdToStr[ Qtopia::HomeCountry ] );
+
+ list += untrdetailsfields( sorted );
+
+ list.append( mapIdToStr[ Qtopia::Notes ] );
+ list.append( mapIdToStr[ Qtopia::Groups ] );
+
+ if (sorted) list.sort();
+
+ return list;
+}
+QMap<int, QString> OContactFields::idToTrFields()
+{
+ QMap<int, QString> ret_map;
+
+ ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") );
+ ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) );
+ ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) );
+ ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) );
+ ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" ));
+ ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) );
+
+ ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) );
+ ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) );
+ ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) );
+ ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) );
+ ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) );
+ ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" ));
+
+ // email
+ ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) );
+ ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) );
+
+ ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) );
+ ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) );
+ ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) );
+
+ // business
+ ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) );
+ ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) );
+ ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) );
+ ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) );
+ ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) );
+ ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) );
+ ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) );
+
+ ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) );
+ ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) );
+ ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) );
+ ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) );
+
+ // home
+ ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) );
+ ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) );
+ ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) );
+ ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) );
+ ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) );
+ ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) );
+
+ //personal
+ ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) );
+ ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) );
+ ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) );
+ ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) );
+ ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) );
+ ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) );
+
+ // other
+ ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) );
+
+
+ return ret_map;
+}
+
+QMap<int, QString> OContactFields::idToUntrFields()
+{
+ QMap<int, QString> ret_map;
+
+ ret_map.insert( Qtopia::Title, "Name Title" );
+ ret_map.insert( Qtopia::FirstName, "First Name" );
+ ret_map.insert( Qtopia::MiddleName, "Middle Name" );
+ ret_map.insert( Qtopia::LastName, "Last Name" );
+ ret_map.insert( Qtopia::Suffix, "Suffix" );
+ ret_map.insert( Qtopia::FileAs, "File As" );
+
+ ret_map.insert( Qtopia::JobTitle, "Job Title" );
+ ret_map.insert( Qtopia::Department, "Department" );
+ ret_map.insert( Qtopia::Company, "Company" );
+ ret_map.insert( Qtopia::BusinessPhone, "Business Phone" );
+ ret_map.insert( Qtopia::BusinessFax, "Business Fax" );
+ ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" );
+
+ // email
+ ret_map.insert( Qtopia::DefaultEmail, "Default Email" );
+ ret_map.insert( Qtopia::Emails, "Emails" );
+
+ ret_map.insert( Qtopia::HomePhone, "Home Phone" );
+ ret_map.insert( Qtopia::HomeFax, "Home Fax" );
+ ret_map.insert( Qtopia::HomeMobile, "Home Mobile" );
+
+ // business
+ ret_map.insert( Qtopia::BusinessStreet, "Business Street" );
+ ret_map.insert( Qtopia::BusinessCity, "Business City" );
+ ret_map.insert( Qtopia::BusinessState, "Business State" );
+ ret_map.insert( Qtopia::BusinessZip, "Business Zip" );
+ ret_map.insert( Qtopia::BusinessCountry, "Business Country" );
+ ret_map.insert( Qtopia::BusinessPager, "Business Pager" );
+ ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" );
+
+ ret_map.insert( Qtopia::Office, "Office" );
+ ret_map.insert( Qtopia::Profession, "Profession" );
+ ret_map.insert( Qtopia::Assistant, "Assistant" );
+ ret_map.insert( Qtopia::Manager, "Manager" );
+
+ // home
+ ret_map.insert( Qtopia::HomeStreet, "Home Street" );
+ ret_map.insert( Qtopia::HomeCity, "Home City" );
+ ret_map.insert( Qtopia::HomeState, "Home State" );
+ ret_map.insert( Qtopia::HomeZip, "Home Zip" );
+ ret_map.insert( Qtopia::HomeCountry, "Home Country" );
+ ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" );
+
+ //personal
+ ret_map.insert( Qtopia::Spouse, "Spouse" );
+ ret_map.insert( Qtopia::Gender, "Gender" );
+ ret_map.insert( Qtopia::Birthday, "Birthday" );
+ ret_map.insert( Qtopia::Anniversary, "Anniversary" );
+ ret_map.insert( Qtopia::Nickname, "Nickname" );
+ ret_map.insert( Qtopia::Children, "Children" );
+
+ // other
+ ret_map.insert( Qtopia::Notes, "Notes" );
+
+
+ return ret_map;
+}
+
+QMap<QString, int> OContactFields::trFieldsToId()
+{
+ QMap<int, QString> idtostr = idToTrFields();
+ QMap<QString, int> ret_map;
+
+
+ QMap<int, QString>::Iterator it;
+ for( it = idtostr.begin(); it != idtostr.end(); ++it )
+ ret_map.insert( *it, it.key() );
+
+
+ return ret_map;
+}
+
+QMap<QString, int> OContactFields::untrFieldsToId()
+{
+ QMap<int, QString> idtostr = idToUntrFields();
+ QMap<QString, int> ret_map;
+
+
+ QMap<int, QString>::Iterator it;
+ for( it = idtostr.begin(); it != idtostr.end(); ++it )
+ ret_map.insert( *it, it.key() );
+
+
+ return ret_map;
+}
+
+
+OContactFields::OContactFields():
+ fieldOrder( DEFAULT_FIELD_ORDER ),
+ changedFieldOrder( false )
+{
+ // Get the global field order from the config file and
+ // use it as a start pattern
+ Config cfg ( "AddressBook" );
+ cfg.setGroup( "ContactFieldOrder" );
+ globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER );
+}
+
+OContactFields::~OContactFields(){
+
+ // We will store the fieldorder into the config file
+ // to reuse it for the future..
+ if ( changedFieldOrder ){
+ Config cfg ( "AddressBook" );
+ cfg.setGroup( "ContactFieldOrder" );
+ cfg.writeEntry( "General", globalFieldOrder );
+ }
+}
+
+
+
+void OContactFields::saveToRecord( OContact &cnt ){
+
+ qDebug("ocontactfields saveToRecord: >%s<",fieldOrder.latin1());
+
+ // Store fieldorder into this contact.
+ cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder );
+
+ globalFieldOrder = fieldOrder;
+ changedFieldOrder = true;
+
+}
+
+void OContactFields::loadFromRecord( const OContact &cnt ){
+ qDebug("ocontactfields loadFromRecord");
+ qDebug("loading >%s<",cnt.fullName().latin1());
+
+ // Get fieldorder for this contact. If none is defined,
+ // we will use the global one from the config file..
+
+ fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME );
+
+ qDebug("fieldOrder from contact>%s<",fieldOrder.latin1());
+
+ if (fieldOrder.isEmpty()){
+ fieldOrder = globalFieldOrder;
+ }
+
+
+ qDebug("effective fieldOrder in loadFromRecord >%s<",fieldOrder.latin1());
+}
+
+void OContactFields::setFieldOrder( int num, int index ){
+ qDebug("qcontactfields setfieldorder pos %i -> %i",num,index);
+
+ fieldOrder[num] = QString::number( index, 16 )[0];
+
+ // We will store this new fieldorder globally to
+ // remember it for contacts which have none
+ globalFieldOrder = fieldOrder;
+ changedFieldOrder = true;
+
+ qDebug("fieldOrder >%s<",fieldOrder.latin1());
+}
+
+int OContactFields::getFieldOrder( int num, int defIndex ){
+ qDebug("ocontactfields getFieldOrder");
+ qDebug("fieldOrder >%s<",fieldOrder.latin1());
+
+ // Get index of combo as char..
+ QChar poschar = fieldOrder[num];
+
+ bool ok;
+ int ret = 0;
+ // Convert char to number..
+ if ( !( poschar == QChar::null ) )
+ ret = QString( poschar ).toInt(&ok, 16);
+ else
+ ok = false;
+
+ // Return default value if index for
+ // num was not set or if anything else happened..
+ if ( !ok ) ret = defIndex;
+
+ qDebug("returning >%i<",ret);
+
+ return ret;
+
+}
diff --git a/libopie2/opiepim/ocontactfields.h b/libopie2/opiepim/ocontactfields.h
new file mode 100644
index 0000000..9f6171b
--- a/dev/null
+++ b/libopie2/opiepim/ocontactfields.h
@@ -0,0 +1,60 @@
+#ifndef OPIE_CONTACTS_FIELDS
+#define OPIE_CONTACTS_FIELDS
+
+class QStringList;
+
+#include <qmap.h>
+#include <qstring.h>
+#include <opie/ocontact.h>
+
+#define CONTACT_FIELD_ORDER_NAME "opie-contactfield-order"
+#define DEFAULT_FIELD_ORDER "__________"
+
+class OContactFields{
+
+ public:
+ OContactFields();
+ ~OContactFields();
+ /** Set the index for combo boxes.
+ * Sets the <b>index</b> of combo <b>num</b>.
+ * @param num selects the number of the combo
+ * @param index sets the index in the combo
+ */
+ void setFieldOrder( int num, int index );
+
+ /** Get the index for combo boxes.
+ * Returns the index of combo <b>num</b> or defindex
+ * if none was defined..
+ * @param num Selects the number of the combo
+ * @param defIndex will be returned if none was defined (either
+ * globally in the config file, nor by the contact which was used
+ * by loadFromRecord() )
+ */
+ int getFieldOrder( int num, int defIndex);
+
+ /** Store fieldorder to contact. */
+ void saveToRecord( OContact& );
+ /** Get Fieldorder from contact. */
+ void loadFromRecord( const OContact& );
+
+ private:
+ QString fieldOrder;
+ QString globalFieldOrder;
+ bool changedFieldOrder;
+
+ public:
+ static QStringList trphonefields( bool sorted = true );
+ static QStringList untrphonefields( bool sorted = true );
+ static QStringList trdetailsfields( bool sorted = true );
+ static QStringList untrdetailsfields( bool sorted = true );
+ static QStringList trfields( bool sorted = true );
+ static QStringList untrfields( bool sorted = true );
+
+ static QMap<int, QString> idToTrFields();
+ static QMap<QString, int> trFieldsToId();
+ static QMap<int, QString> idToUntrFields();
+ static QMap<QString, int> untrFieldsToId();
+
+};
+
+#endif