summaryrefslogtreecommitdiff
authoreilers <eilers>2003-09-22 14:31:15 (UTC)
committer eilers <eilers>2003-09-22 14:31:15 (UTC)
commit34e86ddf4f9b1045a5b730beab2d8d72e2dd4d56 (patch) (unidiff)
treecee19bfcf7c8d6a24cd4aaf578bd64b38b2d0ee4
parentfd500184450e37c239e573adf1c12a6ff62b65f6 (diff)
downloadopie-34e86ddf4f9b1045a5b730beab2d8d72e2dd4d56.zip
opie-34e86ddf4f9b1045a5b730beab2d8d72e2dd4d56.tar.gz
opie-34e86ddf4f9b1045a5b730beab2d8d72e2dd4d56.tar.bz2
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...
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/libopie.pro17
-rw-r--r--libopie/pim/obackendfactory.h16
-rw-r--r--libopie/pim/ocontact.h13
-rw-r--r--libopie/pim/ocontactaccessbackend_sql.cpp664
-rw-r--r--libopie/pim/ocontactaccessbackend_sql.h96
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.cpp7
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.h6
-rw-r--r--libopie/pim/ocontactfields.cpp456
-rw-r--r--libopie/pim/ocontactfields.h60
-rw-r--r--libopie/pim/otodoaccesssql.cpp73
-rw-r--r--libopie/pim/otodoaccesssql.h6
-rw-r--r--libopie/pim/test/converter.cpp64
-rw-r--r--libopie/pim/test/converter.pro12
-rw-r--r--libopie/pim/test/converter_base.ui43
-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
24 files changed, 2881 insertions, 49 deletions
diff --git a/libopie/libopie.pro b/libopie/libopie.pro
index 2148233..0398775 100644
--- a/libopie/libopie.pro
+++ b/libopie/libopie.pro
@@ -21,6 +21,7 @@ HEADERS = ofontmenu.h \
21 pim/otodoaccessbackend.h \ 21 pim/otodoaccessbackend.h \
22 pim/oconversion.h \ 22 pim/oconversion.h \
23 pim/ocontact.h \ 23 pim/ocontact.h \
24 pim/ocontactfields.h \
24 pim/ocontactaccess.h \ 25 pim/ocontactaccess.h \
25 pim/ocontactaccessbackend.h \ 26 pim/ocontactaccessbackend.h \
26 pim/ocontactaccessbackend_xml.h \ 27 pim/ocontactaccessbackend_xml.h \
@@ -65,6 +66,7 @@ SOURCES = ofontmenu.cc \
65 pim/otodoaccessxml.cpp \ 66 pim/otodoaccessxml.cpp \
66 pim/oconversion.cpp \ 67 pim/oconversion.cpp \
67 pim/ocontact.cpp \ 68 pim/ocontact.cpp \
69 pim/ocontactfields.cpp \
68 pim/ocontactaccess.cpp \ 70 pim/ocontactaccess.cpp \
69 pim/ocontactaccessbackend_vcard.cpp \ 71 pim/ocontactaccessbackend_vcard.cpp \
70 pim/ocontactaccessbackend_xml.cpp \ 72 pim/ocontactaccessbackend_xml.cpp \
@@ -91,9 +93,22 @@ TARGET = opie
91INCLUDEPATH += $(OPIEDIR)/include 93INCLUDEPATH += $(OPIEDIR)/include
92DESTDIR = $(OPIEDIR)/lib$(PROJMAK) 94DESTDIR = $(OPIEDIR)/lib$(PROJMAK)
93 95
96# The following is just for my Notebook !
97# It should never be committed !! (eilers)
98# QMAKE_CXXFLAGS += -DQT_NO_SOUND
99
94LIBS += -lqpe 100LIBS += -lqpe
95 101
96# LIBS += -lopiesql 102# Add SQL-Support if selected by config (eilers)
103CONFTEST = $$system( echo $CONFIG_SQL_PIM_BACKEND )
104contains( CONFTEST, y ){
105
106DEFINES += __USE_SQL
107LIBS += -lopiedb2 -lsqlite
108HEADERS += pim/otodoaccesssql.h pim/ocontactaccessbackend_sql.h
109SOURCES += pim/otodoaccesssql.cpp pim/ocontactaccessbackend_sql.cpp
110
111}
97 112
98INTERFACES = otimepickerbase.ui orecurrancebase.ui 113INTERFACES = otimepickerbase.ui orecurrancebase.ui
99TARGET = opie 114TARGET = opie
diff --git a/libopie/pim/obackendfactory.h b/libopie/pim/obackendfactory.h
index f3c339d..3567687 100644
--- a/libopie/pim/obackendfactory.h
+++ b/libopie/pim/obackendfactory.h
@@ -16,6 +16,11 @@
16 * ===================================================================== 16 * =====================================================================
17 * History: 17 * History:
18 * $Log$ 18 * $Log$
19 * Revision 1.8 2003/09/22 14:31:16 eilers
20 * Added first experimental incarnation of sql-backend for addressbook.
21 * Some modifications to be able to compile the todo sql-backend.
22 * A lot of changes fill follow...
23 *
19 * Revision 1.7 2003/08/01 12:30:16 eilers 24 * Revision 1.7 2003/08/01 12:30:16 eilers
20 * Merging changes from BRANCH_1_0 to HEAD 25 * Merging changes from BRANCH_1_0 to HEAD
21 * 26 *
@@ -74,6 +79,7 @@
74 79
75#ifdef __USE_SQL 80#ifdef __USE_SQL
76#include "otodoaccesssql.h" 81#include "otodoaccesssql.h"
82#include "ocontactaccessbackend_sql.h"
77#endif 83#endif
78 84
79class OBackendPrivate; 85class OBackendPrivate;
@@ -118,6 +124,8 @@ class OBackendFactory
118 config.setGroup ( backendName ); 124 config.setGroup ( backendName );
119 QString backend = config.readEntry( "usebackend" ); 125 QString backend = config.readEntry( "usebackend" );
120 126
127 qWarning("Selected backend for %s is: %s", backendName.latin1(), backend.latin1() );
128
121 QAsciiDict<int> dict ( 3 ); 129 QAsciiDict<int> dict ( 3 );
122 dict.setAutoDelete ( TRUE ); 130 dict.setAutoDelete ( TRUE );
123 131
@@ -125,9 +133,6 @@ class OBackendFactory
125 dict.insert( "contact", new int (CONTACT) ); 133 dict.insert( "contact", new int (CONTACT) );
126 dict.insert( "datebook", new int(DATE) ); 134 dict.insert( "datebook", new int(DATE) );
127 135
128 qWarning ("TODO is: %d", TODO);
129 qWarning ("CONTACT is: %d", CONTACT);
130
131 int *find = dict[ backendName ]; 136 int *find = dict[ backendName ];
132 if (!find ) return 0; 137 if (!find ) return 0;
133 138
@@ -143,8 +148,13 @@ class OBackendFactory
143 148
144 return (T*) new OTodoAccessXML( appName ); 149 return (T*) new OTodoAccessXML( appName );
145 case CONTACT: 150 case CONTACT:
151#ifdef __USE_SQL
152 if ( backend == "sql" )
153 return (T*) new OContactAccessBackend_SQL("");
154#else
146 if ( backend == "sql" ) 155 if ( backend == "sql" )
147 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 156 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
157#endif
148 158
149 return (T*) new OContactAccessBackend_XML( appName ); 159 return (T*) new OContactAccessBackend_XML( appName );
150 case DATE: 160 case DATE:
diff --git a/libopie/pim/ocontact.h b/libopie/pim/ocontact.h
index 9a1a8dc..1d46b81 100644
--- a/libopie/pim/ocontact.h
+++ b/libopie/pim/ocontact.h
@@ -196,11 +196,6 @@ public:
196 QString groups() const { return find( Qtopia::Groups ); } 196 QString groups() const { return find( Qtopia::Groups ); }
197 QStringList groupList() const; 197 QStringList groupList() const;
198 198
199// // custom
200// const QString &customField( const QString &key )
201// { return find( Custom- + key ); }
202
203
204 QString toRichText() const; 199 QString toRichText() const;
205 QMap<int, QString> toMap() const; 200 QMap<int, QString> toMap() const;
206 QString field( int key ) const { return find( key ); } 201 QString field( int key ) const { return find( key ); }
@@ -209,19 +204,19 @@ public:
209 void setUid( int i ); 204 void setUid( int i );
210 205
211 QString toShortText()const; 206 QString toShortText()const;
212 QString OContact::type()const; 207 QString type()const;
213 QMap<QString,QString> OContact::toExtraMap() const; 208 class QString recordField(int) const;
214 class QString OContact::recordField(int) const;
215 209
216 // Why private ? (eilers,se) 210 // Why private ? (eilers,se)
217 QString emailSeparator() const { return " "; } 211 QString emailSeparator() const { return " "; }
212
218 // the emails should be seperated by a comma 213 // the emails should be seperated by a comma
219 void setEmails( const QString &v ); 214 void setEmails( const QString &v );
220 QString emails() const { return find( Qtopia::Emails ); } 215 QString emails() const { return find( Qtopia::Emails ); }
221 static int rtti(); 216 static int rtti();
222 217
223private: 218private:
224 // The XML-Backend needs some access to the private functions 219 // The XML Backend needs some access to the private functions
225 friend class OContactAccessBackend_XML; 220 friend class OContactAccessBackend_XML;
226 221
227 void insert( int key, const QString &value ); 222 void insert( int key, const QString &value );
diff --git a/libopie/pim/ocontactaccessbackend_sql.cpp b/libopie/pim/ocontactaccessbackend_sql.cpp
new file mode 100644
index 0000000..4afa5f3
--- a/dev/null
+++ b/libopie/pim/ocontactaccessbackend_sql.cpp
@@ -0,0 +1,664 @@
1/*
2 * SQL Backend for the OPIE-Contact Database.
3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 *
6 * =====================================================================
7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * =====================================================================
12 * =====================================================================
13 * Version: $Id$
14 * =====================================================================
15 * History:
16 * $Log$
17 * Revision 1.1 2003/09/22 14:31:16 eilers
18 * Added first experimental incarnation of sql-backend for addressbook.
19 * Some modifications to be able to compile the todo sql-backend.
20 * A lot of changes fill follow...
21 *
22 */
23
24#include "ocontactaccessbackend_sql.h"
25
26#include <qarray.h>
27#include <qdatetime.h>
28#include <qstringlist.h>
29
30#include <qpe/global.h>
31#include <qpe/recordfields.h>
32
33#include <opie/ocontactfields.h>
34#include <opie/oconversion.h>
35#include <opie2/osqldriver.h>
36#include <opie2/osqlresult.h>
37#include <opie2/osqlmanager.h>
38#include <opie2/osqlquery.h>
39
40/*
41 * Implementation of used query types
42 * CREATE query
43 * LOAD query
44 * INSERT
45 * REMOVE
46 * CLEAR
47 */
48namespace {
49 /**
50 * CreateQuery for the Todolist Table
51 */
52 class CreateQuery : public OSQLQuery {
53 public:
54 CreateQuery();
55 ~CreateQuery();
56 QString query()const;
57 };
58
59 /**
60 * Clears (delete) a Table
61 */
62 class ClearQuery : public OSQLQuery {
63 public:
64 ClearQuery();
65 ~ClearQuery();
66 QString query()const;
67
68 };
69
70
71 /**
72 * LoadQuery
73 * this one queries for all uids
74 */
75 class LoadQuery : public OSQLQuery {
76 public:
77 LoadQuery();
78 ~LoadQuery();
79 QString query()const;
80 };
81
82 /**
83 * inserts/adds a OContact to the table
84 */
85 class InsertQuery : public OSQLQuery {
86 public:
87 InsertQuery(const OContact& );
88 ~InsertQuery();
89 QString query()const;
90 private:
91 OContact m_contact;
92 };
93
94
95 /**
96 * removes one from the table
97 */
98 class RemoveQuery : public OSQLQuery {
99 public:
100 RemoveQuery(int uid );
101 ~RemoveQuery();
102 QString query()const;
103 private:
104 int m_uid;
105 };
106
107 /**
108 * a find query for noncustom elements
109 */
110 class FindQuery : public OSQLQuery {
111 public:
112 FindQuery(int uid);
113 FindQuery(const QArray<int>& );
114 ~FindQuery();
115 QString query()const;
116 private:
117 QString single()const;
118 QString multi()const;
119 QArray<int> m_uids;
120 int m_uid;
121 };
122
123 /**
124 * a find query for custom elements
125 */
126 class FindCustomQuery : public OSQLQuery {
127 public:
128 FindCustomQuery(int uid);
129 FindCustomQuery(const QArray<int>& );
130 ~FindCustomQuery();
131 QString query()const;
132 private:
133 QString single()const;
134 QString multi()const;
135 QArray<int> m_uids;
136 int m_uid;
137 };
138
139
140
141 // We using three tables to store the information:
142 // 1. addressbook : It contains General information about the contact (non custom)
143 // 2. dates : Stuff like birthdays, anniversaries, etc.
144 // 3. custom_data : Not official supported entries
145 // All tables are connected by the uid of the contact.
146 // Maybe I should add a table for meta-information ?
147 CreateQuery::CreateQuery() : OSQLQuery() {}
148 CreateQuery::~CreateQuery() {}
149 QString CreateQuery::query()const {
150 QString qu;
151 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));";
152 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
153 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );";
154 return qu;
155 }
156
157 ClearQuery::ClearQuery()
158 : OSQLQuery() {}
159 ClearQuery::~ClearQuery() {}
160 QString ClearQuery::query()const {
161 QString qu = "drop table addressbook;";
162 qu += "drop table custom_data;";
163 qu += "drop table dates;";
164 return qu;
165 }
166
167// Distinct loading is not very fast. If I expect that every person has just
168// one (and always one) 'Last Name', I can request all uid's for existing lastnames,
169// which is faster..
170// But this may not be true for all entries, like company contacts..
171// The current AddressBook application handles this problem, but other may not.. (eilers)
172#define __USE_SUPERFAST_LOADQUERY
173
174 LoadQuery::LoadQuery() : OSQLQuery() {}
175 LoadQuery::~LoadQuery() {}
176 QString LoadQuery::query()const {
177 QString qu;
178#ifndef __USE_SUPERFAST_LOADQUERY
179 qu += "select distinct uid from addressbook";
180#else
181 qu += "select uid from addressbook where type = 'Last Name'";
182#endif
183
184 return qu;
185 }
186
187
188 InsertQuery::InsertQuery( const OContact& contact )
189 : OSQLQuery(), m_contact( contact ) {
190 }
191
192 InsertQuery::~InsertQuery() {
193 }
194
195 /*
196 * converts from a OContact to a query
197 */
198 QString InsertQuery::query()const{
199
200 // Get all information out of the contact-class
201 // Remember: The category is stored in contactMap, too !
202 QMap<int, QString> contactMap = m_contact.toMap();
203 QMap<QString, QString> customMap = m_contact.toExtraMap();
204
205 QMap<QString, QString> addressbook_db;
206
207 // Get the translation from the ID to the String
208 QMap<int, QString> transMap = OContactFields::idToUntrFields();
209
210 for( QMap<int, QString>::Iterator it = contactMap.begin();
211 it != contactMap.end(); ++it ){
212 switch ( it.key() ){
213 case Qtopia::Birthday:{
214 // These entries should stored in a special format
215 // year-month-day
216 QDate day = m_contact.birthday();
217 addressbook_db.insert( transMap[it.key()],
218 QString("%1-%2-%3")
219 .arg( day.year() )
220 .arg( day.month() )
221 .arg( day.day() ) );
222 }
223 break;
224 case Qtopia::Anniversary:{
225 // These entries should stored in a special format
226 // year-month-day
227 QDate day = m_contact.anniversary();
228 addressbook_db.insert( transMap[it.key()],
229 QString("%1-%2-%3")
230 .arg( day.year() )
231 .arg( day.month() )
232 .arg( day.day() ) );
233 }
234 break;
235 case Qtopia::AddressUid: // Ignore UID
236 break;
237 default: // Translate id to String
238 addressbook_db.insert( transMap[it.key()], it.data() );
239 break;
240 }
241
242 }
243
244 // Now convert this whole stuff into a SQL String, beginning with
245 // the addressbook table..
246 QString qu;
247 // qu += "begin transaction;";
248 int id = 0;
249 for( QMap<QString, QString>::Iterator it = addressbook_db.begin();
250 it != addressbook_db.end(); ++it ){
251 qu += "insert into addressbook VALUES("
252 + QString::number( m_contact.uid() )
253 + ","
254 + QString::number( id++ )
255 + ",'"
256 + it.key() //.latin1()
257 + "',"
258 + "0" // Priority for future enhancements
259 + ",'"
260 + it.data() //.latin1()
261 + "');";
262 }
263
264 // Now add custom data..
265 id = 0;
266 for( QMap<QString, QString>::Iterator it = customMap.begin();
267 it != customMap.end(); ++it ){
268 qu += "insert into custom_data VALUES("
269 + QString::number( m_contact.uid() )
270 + ","
271 + QString::number( id++ )
272 + ",'"
273 + it.key() //.latin1()
274 + "',"
275 + "0" // Priority for future enhancements
276 + ",'"
277 + it.data() //.latin1()
278 + "');";
279 }
280
281 // qu += "commit;";
282 qWarning("add %s", qu.latin1() );
283 return qu;
284 }
285
286
287 RemoveQuery::RemoveQuery(int uid )
288 : OSQLQuery(), m_uid( uid ) {}
289 RemoveQuery::~RemoveQuery() {}
290 QString RemoveQuery::query()const {
291 QString qu = "DELETE from addressbook where uid = "
292 + QString::number(m_uid) + ";";
293 qu += "DELETE from dates where uid = "
294 + QString::number(m_uid) + ";";
295 qu += "DELETE from custom_data where uid = "
296 + QString::number(m_uid) + ";";
297 return qu;
298 }
299
300
301
302
303 FindQuery::FindQuery(int uid)
304 : OSQLQuery(), m_uid( uid ) {
305 }
306 FindQuery::FindQuery(const QArray<int>& ints)
307 : OSQLQuery(), m_uids( ints ){
308 }
309 FindQuery::~FindQuery() {
310 }
311 QString FindQuery::query()const{
312 // if ( m_uids.count() == 0 )
313 return single();
314 }
315 /*
316 else
317 return multi();
318 }
319 QString FindQuery::multi()const {
320 QString qu = "select uid, type, value from addressbook where";
321 for (uint i = 0; i < m_uids.count(); i++ ) {
322 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
323 }
324 qu.remove( qu.length()-2, 2 ); // Hmmmm..
325 return qu;
326 }
327 */
328 QString FindQuery::single()const{
329 QString qu = "select uid, type, value from addressbook where uid = ";
330 qu += QString::number(m_uid);
331 return qu;
332 }
333
334
335 FindCustomQuery::FindCustomQuery(int uid)
336 : OSQLQuery(), m_uid( uid ) {
337 }
338 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
339 : OSQLQuery(), m_uids( ints ){
340 }
341 FindCustomQuery::~FindCustomQuery() {
342 }
343 QString FindCustomQuery::query()const{
344 // if ( m_uids.count() == 0 )
345 return single();
346 }
347 QString FindCustomQuery::single()const{
348 QString qu = "select uid, type, value from custom_data where uid = ";
349 qu += QString::number(m_uid);
350 return qu;
351 }
352
353};
354
355
356/* --------------------------------------------------------------------------- */
357
358OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */,
359 const QString& filename ): m_changed(false)
360{
361 qWarning("C'tor OContactAccessBackend_SQL starts");
362 QTime t;
363 t.start();
364
365 /* Expecting to access the default filename if nothing else is set */
366 if ( filename.isEmpty() ){
367 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
368 } else
369 m_fileName = filename;
370
371 // Get the standart sql-driver from the OSQLManager..
372 OSQLManager man;
373 m_driver = man.standard();
374 m_driver->setUrl( m_fileName );
375
376 load();
377
378 qWarning("C'tor OContactAccessBackend_SQL ends: %d", t.elapsed() );
379}
380
381
382bool OContactAccessBackend_SQL::load ()
383{
384 if (!m_driver->open() )
385 return false;
386
387 // Don't expect that the database exists.
388 // It is save here to create the table, even if it
389 // do exist. ( Is that correct for all databases ?? )
390 CreateQuery creat;
391 OSQLResult res = m_driver->query( &creat );
392
393 update();
394
395 return true;
396
397}
398
399bool OContactAccessBackend_SQL::reload()
400{
401 return load();
402}
403
404bool OContactAccessBackend_SQL::save()
405{
406 return m_driver->close();
407}
408
409
410void OContactAccessBackend_SQL::clear ()
411{
412 ClearQuery cle;
413 OSQLResult res = m_driver->query( &cle );
414 CreateQuery qu;
415 res = m_driver->query(&qu);
416}
417
418bool OContactAccessBackend_SQL::wasChangedExternally()
419{
420 return false;
421}
422
423QArray<int> OContactAccessBackend_SQL::allRecords() const
424{
425
426 // FIXME: Think about cute handling of changed tables..
427 // Thus, we don't have to call update here...
428 if ( m_changed )
429 ((OContactAccessBackend_SQL*)this)->update();
430
431 return m_uids;
432}
433
434bool OContactAccessBackend_SQL::add ( const OContact &newcontact )
435{
436 InsertQuery ins( newcontact );
437 OSQLResult res = m_driver->query( &ins );
438
439 if ( res.state() == OSQLResult::Failure )
440 return false;
441
442 int c = m_uids.count();
443 m_uids.resize( c+1 );
444 m_uids[c] = newcontact.uid();
445
446 return true;
447}
448
449
450bool OContactAccessBackend_SQL::remove ( int uid )
451{
452 RemoveQuery rem( uid );
453 OSQLResult res = m_driver->query(&rem );
454
455 if ( res.state() == OSQLResult::Failure )
456 return false;
457
458 m_changed = true;
459
460 return true;
461}
462
463bool OContactAccessBackend_SQL::replace ( const OContact &contact )
464{
465 if ( !remove( contact.uid() ) )
466 return false;
467
468 return add( contact );
469}
470
471
472OContact OContactAccessBackend_SQL::find ( int uid ) const
473{
474 qWarning("OContactAccessBackend_SQL::find()");
475 QTime t;
476 t.start();
477
478 OContact retContact( requestNonCustom( uid ) );
479 retContact.setExtraMap( requestCustom( uid ) );
480
481 qWarning("OContactAccessBackend_SQL::find() needed: %d", t.elapsed() );
482 return retContact;
483}
484
485
486
487QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() )
488{
489 QArray<int> nix(0);
490 return nix;
491}
492
493QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
494{
495 QArray<int> nix(0);
496 return nix;
497}
498
499const uint OContactAccessBackend_SQL::querySettings()
500{
501 return 0;
502}
503
504bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
505{
506 return false;
507}
508
509QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int )
510{
511 QTime t;
512 t.start();
513
514 // Not implemented..
515 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' ";
516
517 query += "ORDER BY value ";
518 if ( !asc )
519 query += "DESC";
520
521 qWarning("sorted query is: %s", query.latin1() );
522
523 OSQLRawQuery raw( query );
524 OSQLResult res = m_driver->query( &raw );
525 if ( res.state() != OSQLResult::Success ){
526 QArray<int> empty;
527 return empty;
528 }
529
530 QArray<int> list = extractUids( res );
531
532 qWarning("sorted needed %d ms!", t.elapsed() );
533 return list;
534}
535
536
537void OContactAccessBackend_SQL::update()
538{
539 qWarning("Update starts");
540 QTime t;
541 t.start();
542
543 // Now load the database set and extract the uid's
544 // which will be held locally
545
546 LoadQuery lo;
547 OSQLResult res = m_driver->query(&lo);
548 if ( res.state() != OSQLResult::Success )
549 return;
550
551 m_uids = extractUids( res );
552
553 m_changed = false;
554
555 qWarning("Update ends %d", t.elapsed() );
556}
557
558QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
559{
560 qWarning("extractUids");
561 QTime t;
562 t.start();
563 OSQLResultItem::ValueList list = res.results();
564 OSQLResultItem::ValueList::Iterator it;
565 QArray<int> ints(list.count() );
566 qWarning(" count = %d", list.count() );
567
568 int i = 0;
569 for (it = list.begin(); it != list.end(); ++it ) {
570 ints[i] = (*it).data("uid").toInt();
571 i++;
572 }
573 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
574
575 return ints;
576
577}
578
579QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
580{
581 QTime t;
582 t.start();
583
584 QMap<int, QString> nonCustomMap;
585
586 int t2needed = 0;
587 QTime t2;
588 t2.start();
589 FindQuery query( uid );
590 OSQLResult res_noncustom = m_driver->query( &query );
591 t2needed = t2.elapsed();
592
593 if ( res_noncustom.state() == OSQLResult::Failure ) {
594 qWarning("OSQLResult::Failure in find query !!");
595 QMap<int, QString> empty;
596 return empty;
597 }
598
599 int t3needed = 0;
600 QTime t3;
601 t3.start();
602 QMap<QString, int> translateMap = OContactFields::untrFieldsToId();
603
604 OSQLResultItem::ValueList list = res_noncustom.results();
605 OSQLResultItem::ValueList::Iterator it = list.begin();
606 for ( ; it != list.end(); ++it ) {
607 if ( (*it).data("type") != "" ){
608 int typeId = translateMap[(*it).data( "type" )];
609 switch( typeId ){
610 case Qtopia::Birthday:
611 case Qtopia::Anniversary:{
612 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
613 QStringList list = QStringList::split( '-', (*it).data( "value" ) );
614 QStringList::Iterator lit = list.begin();
615 int year = (*lit).toInt();
616 qWarning("1. %s", (*lit).latin1());
617 int month = (*(++lit)).toInt();
618 qWarning("2. %s", (*lit).latin1());
619 int day = (*(++lit)).toInt();
620 qWarning("3. %s", (*lit).latin1());
621 qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day );
622 QDate date( year, month, day );
623 nonCustomMap.insert( typeId, OConversion::dateToString( date ) );
624 }
625 break;
626 default:
627 nonCustomMap.insert( typeId,
628 (*it).data( "value" ) );
629 }
630 }
631 }
632 // Add UID to Map..
633 nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) );
634 t3needed = t3.elapsed();
635
636 qWarning("RequestNonCustom needed: ins:%d, query: %d, mapping: %d", t.elapsed(), t2needed, t3needed );
637 return nonCustomMap;
638}
639
640QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const
641{
642 QTime t;
643 t.start();
644
645 QMap<QString, QString> customMap;
646
647 FindCustomQuery query( uid );
648 OSQLResult res_custom = m_driver->query( &query );
649
650 if ( res_custom.state() == OSQLResult::Failure ) {
651 qWarning("OSQLResult::Failure in find query !!");
652 QMap<QString, QString> empty;
653 return empty;
654 }
655
656 OSQLResultItem::ValueList list = res_custom.results();
657 OSQLResultItem::ValueList::Iterator it = list.begin();
658 for ( ; it != list.end(); ++it ) {
659 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
660 }
661
662 qWarning("RequestCustom needed: %d", t.elapsed() );
663 return customMap;
664}
diff --git a/libopie/pim/ocontactaccessbackend_sql.h b/libopie/pim/ocontactaccessbackend_sql.h
new file mode 100644
index 0000000..bb22551
--- a/dev/null
+++ b/libopie/pim/ocontactaccessbackend_sql.h
@@ -0,0 +1,96 @@
1/*
2 * SQL Backend for the OPIE-Contact Database.
3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 *
6 * =====================================================================
7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * =====================================================================
12 *
13 *
14 * =====================================================================
15 * Version: $Id$
16 * =====================================================================
17 * History:
18 * $Log$
19 * Revision 1.1 2003/09/22 14:31:16 eilers
20 * Added first experimental incarnation of sql-backend for addressbook.
21 * Some modifications to be able to compile the todo sql-backend.
22 * A lot of changes fill follow...
23 *
24 *
25 */
26
27#ifndef _OContactAccessBackend_SQL_
28#define _OContactAccessBackend_SQL_
29
30#include "ocontactaccessbackend.h"
31#include "ocontactaccess.h"
32
33#include <qlist.h>
34#include <qdict.h>
35
36class OSQLDriver;
37class OSQLResult;
38class OSQLResultItem;
39
40/* the default xml implementation */
41/**
42 * This class is the SQL implementation of a Contact backend
43 * it does implement everything available for OContact.
44 * @see OPimAccessBackend for more information of available methods
45 */
46class OContactAccessBackend_SQL : public OContactAccessBackend {
47 public:
48 OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null );
49
50 bool save();
51
52 bool load ();
53
54 void clear ();
55
56 bool wasChangedExternally();
57
58 QArray<int> allRecords() const;
59
60 OContact find ( int uid ) const;
61 // FIXME: Add lookahead-cache support !
62 //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
63
64 QArray<int> queryByExample ( const OContact &query, int settings,
65 const QDateTime& d );
66
67 QArray<int> matchRegexp( const QRegExp &r ) const;
68
69 const uint querySettings();
70
71 bool hasQuerySettings (uint querySettings) const;
72
73 // Currently only asc implemented..
74 QArray<int> sorted( bool asc, int , int , int );
75 bool add ( const OContact &newcontact );
76
77 bool replace ( const OContact &contact );
78
79 bool remove ( int uid );
80 bool reload();
81
82 private:
83 QArray<int> extractUids( OSQLResult& res ) const;
84 QMap<int, QString> requestNonCustom( int uid ) const;
85 QMap<QString, QString> requestCustom( int uid ) const;
86 void update();
87
88 protected:
89 bool m_changed;
90 QString m_fileName;
91 QArray<int> m_uids;
92
93 OSQLDriver* m_driver;
94};
95
96#endif
diff --git a/libopie/pim/ocontactaccessbackend_xml.cpp b/libopie/pim/ocontactaccessbackend_xml.cpp
index 1b5af2f..aae7fca 100644
--- a/libopie/pim/ocontactaccessbackend_xml.cpp
+++ b/libopie/pim/ocontactaccessbackend_xml.cpp
@@ -9,14 +9,17 @@
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 *
14 * 12 *
15 * ===================================================================== 13 * =====================================================================
16 * Version: $Id$ 14 * Version: $Id$
17 * ===================================================================== 15 * =====================================================================
18 * History: 16 * History:
19 * $Log$ 17 * $Log$
18 * Revision 1.9 2003/09/22 14:31:16 eilers
19 * Added first experimental incarnation of sql-backend for addressbook.
20 * Some modifications to be able to compile the todo sql-backend.
21 * A lot of changes fill follow...
22 *
20 * Revision 1.8 2003/08/30 15:28:26 eilers 23 * Revision 1.8 2003/08/30 15:28:26 eilers
21 * Removed some unimportant debug output which causes slow down.. 24 * Removed some unimportant debug output which causes slow down..
22 * 25 *
diff --git a/libopie/pim/ocontactaccessbackend_xml.h b/libopie/pim/ocontactaccessbackend_xml.h
index 7b5365b..a0cae4d 100644
--- a/libopie/pim/ocontactaccessbackend_xml.h
+++ b/libopie/pim/ocontactaccessbackend_xml.h
@@ -10,6 +10,7 @@
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed... 12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 * File Locking to protect against concurrent access
13 * 14 *
14 * 15 *
15 * ===================================================================== 16 * =====================================================================
@@ -17,6 +18,11 @@
17 * ===================================================================== 18 * =====================================================================
18 * History: 19 * History:
19 * $Log$ 20 * $Log$
21 * Revision 1.15 2003/09/22 14:31:16 eilers
22 * Added first experimental incarnation of sql-backend for addressbook.
23 * Some modifications to be able to compile the todo sql-backend.
24 * A lot of changes fill follow...
25 *
20 * Revision 1.14 2003/04/13 18:07:10 zecke 26 * Revision 1.14 2003/04/13 18:07:10 zecke
21 * More API doc 27 * More API doc
22 * QString -> const QString& 28 * QString -> const QString&
diff --git a/libopie/pim/ocontactfields.cpp b/libopie/pim/ocontactfields.cpp
new file mode 100644
index 0000000..831a596
--- a/dev/null
+++ b/libopie/pim/ocontactfields.cpp
@@ -0,0 +1,456 @@
1
2#include "ocontactfields.h"
3
4#include <qstringlist.h>
5#include <qobject.h>
6
7// We should use our own enum in the future ..
8#include <qpe/recordfields.h>
9#include <qpe/config.h>
10#include <opie/ocontact.h>
11
12/*!
13 \internal
14 Returns a list of details field names for a contact.
15*/
16QStringList OContactFields::untrdetailsfields( bool sorted )
17{
18 QStringList list;
19 QMap<int, QString> mapIdToStr = idToUntrFields();
20
21 list.append( mapIdToStr[ Qtopia::Office ] );
22 list.append( mapIdToStr[ Qtopia::Profession ] );
23 list.append( mapIdToStr[ Qtopia::Assistant ] );
24 list.append( mapIdToStr[ Qtopia::Manager ] );
25
26 list.append( mapIdToStr[ Qtopia::Spouse ] );
27 list.append( mapIdToStr[ Qtopia::Gender ] );
28 list.append( mapIdToStr[ Qtopia::Birthday ] );
29 list.append( mapIdToStr[ Qtopia::Anniversary ] );
30 list.append( mapIdToStr[ Qtopia::Nickname ] );
31 list.append( mapIdToStr[ Qtopia::Children ] );
32
33 if (sorted) list.sort();
34 return list;
35}
36
37/*!
38 \internal
39 Returns a translated list of details field names for a contact.
40*/
41QStringList OContactFields::trdetailsfields( bool sorted )
42{
43 QStringList list;
44 QMap<int, QString> mapIdToStr = idToTrFields();
45
46 list.append( mapIdToStr[Qtopia::Office] );
47 list.append( mapIdToStr[Qtopia::Profession] );
48 list.append( mapIdToStr[Qtopia::Assistant] );
49 list.append( mapIdToStr[Qtopia::Manager] );
50
51 list.append( mapIdToStr[Qtopia::Spouse] );
52 list.append( mapIdToStr[Qtopia::Gender] );
53 list.append( mapIdToStr[Qtopia::Birthday] );
54 list.append( mapIdToStr[Qtopia::Anniversary] );
55 list.append( mapIdToStr[Qtopia::Nickname] );
56 list.append( mapIdToStr[Qtopia::Children] );
57
58 if (sorted) list.sort();
59 return list;
60}
61
62
63/*!
64 \internal
65 Returns a translated list of phone field names for a contact.
66*/
67QStringList OContactFields::trphonefields( bool sorted )
68{
69 QStringList list;
70 QMap<int, QString> mapIdToStr = idToTrFields();
71
72 list.append( mapIdToStr[Qtopia::BusinessPhone] );
73 list.append( mapIdToStr[Qtopia::BusinessFax] );
74 list.append( mapIdToStr[Qtopia::BusinessMobile] );
75 list.append( mapIdToStr[Qtopia::BusinessPager] );
76 list.append( mapIdToStr[Qtopia::BusinessWebPage] );
77
78 list.append( mapIdToStr[Qtopia::DefaultEmail] );
79 list.append( mapIdToStr[Qtopia::Emails] );
80
81 list.append( mapIdToStr[Qtopia::HomePhone] );
82 list.append( mapIdToStr[Qtopia::HomeFax] );
83 list.append( mapIdToStr[Qtopia::HomeMobile] );
84 // list.append( mapIdToStr[Qtopia::HomePager] );
85 list.append( mapIdToStr[Qtopia::HomeWebPage] );
86
87 if (sorted) list.sort();
88
89 return list;
90}
91
92
93/*!
94 \internal
95 Returns a list of phone field names for a contact.
96*/
97QStringList OContactFields::untrphonefields( bool sorted )
98{
99 QStringList list;
100 QMap<int, QString> mapIdToStr = idToUntrFields();
101
102 list.append( mapIdToStr[ Qtopia::BusinessPhone ] );
103 list.append( mapIdToStr[ Qtopia::BusinessFax ] );
104 list.append( mapIdToStr[ Qtopia::BusinessMobile ] );
105 list.append( mapIdToStr[ Qtopia::BusinessPager ] );
106 list.append( mapIdToStr[ Qtopia::BusinessWebPage ] );
107
108 list.append( mapIdToStr[ Qtopia::DefaultEmail ] );
109 list.append( mapIdToStr[ Qtopia::Emails ] );
110
111 list.append( mapIdToStr[ Qtopia::HomePhone ] );
112 list.append( mapIdToStr[ Qtopia::HomeFax ] );
113 list.append( mapIdToStr[ Qtopia::HomeMobile ] );
114 //list.append( mapIdToStr[Qtopia::HomePager] );
115 list.append( mapIdToStr[Qtopia::HomeWebPage] );
116
117 if (sorted) list.sort();
118
119 return list;
120}
121
122
123/*!
124 \internal
125 Returns a translated list of field names for a contact.
126*/
127QStringList OContactFields::trfields( bool sorted )
128{
129 QStringList list;
130 QMap<int, QString> mapIdToStr = idToTrFields();
131
132 list.append( mapIdToStr[Qtopia::Title]);
133 list.append( mapIdToStr[Qtopia::FirstName] );
134 list.append( mapIdToStr[Qtopia::MiddleName] );
135 list.append( mapIdToStr[Qtopia::LastName] );
136 list.append( mapIdToStr[Qtopia::Suffix] );
137 list.append( mapIdToStr[Qtopia::FileAs] );
138
139 list.append( mapIdToStr[Qtopia::JobTitle] );
140 list.append( mapIdToStr[Qtopia::Department] );
141 list.append( mapIdToStr[Qtopia::Company] );
142
143 list += trphonefields( sorted );
144
145 list.append( mapIdToStr[Qtopia::BusinessStreet] );
146 list.append( mapIdToStr[Qtopia::BusinessCity] );
147 list.append( mapIdToStr[Qtopia::BusinessState] );
148 list.append( mapIdToStr[Qtopia::BusinessZip] );
149 list.append( mapIdToStr[Qtopia::BusinessCountry] );
150
151 list.append( mapIdToStr[Qtopia::HomeStreet] );
152 list.append( mapIdToStr[Qtopia::HomeCity] );
153 list.append( mapIdToStr[Qtopia::HomeState] );
154 list.append( mapIdToStr[Qtopia::HomeZip] );
155 list.append( mapIdToStr[Qtopia::HomeCountry] );
156
157 list += trdetailsfields( sorted );
158
159 list.append( mapIdToStr[Qtopia::Notes] );
160 list.append( mapIdToStr[Qtopia::Groups] );
161
162 if (sorted) list.sort();
163
164 return list;
165}
166
167/*!
168 \internal
169 Returns an untranslated list of field names for a contact.
170*/
171QStringList OContactFields::untrfields( bool sorted )
172{
173 QStringList list;
174 QMap<int, QString> mapIdToStr = idToUntrFields();
175
176 list.append( mapIdToStr[ Qtopia::Title ] );
177 list.append( mapIdToStr[ Qtopia::FirstName ] );
178 list.append( mapIdToStr[ Qtopia::MiddleName ] );
179 list.append( mapIdToStr[ Qtopia::LastName ] );
180 list.append( mapIdToStr[ Qtopia::Suffix ] );
181 list.append( mapIdToStr[ Qtopia::FileAs ] );
182
183 list.append( mapIdToStr[ Qtopia::JobTitle ] );
184 list.append( mapIdToStr[ Qtopia::Department ] );
185 list.append( mapIdToStr[ Qtopia::Company ] );
186
187 list += untrphonefields( sorted );
188
189 list.append( mapIdToStr[ Qtopia::BusinessStreet ] );
190 list.append( mapIdToStr[ Qtopia::BusinessCity ] );
191 list.append( mapIdToStr[ Qtopia::BusinessState ] );
192 list.append( mapIdToStr[ Qtopia::BusinessZip ] );
193 list.append( mapIdToStr[ Qtopia::BusinessCountry ] );
194
195 list.append( mapIdToStr[ Qtopia::HomeStreet ] );
196 list.append( mapIdToStr[ Qtopia::HomeCity ] );
197 list.append( mapIdToStr[ Qtopia::HomeState ] );
198 list.append( mapIdToStr[ Qtopia::HomeZip ] );
199 list.append( mapIdToStr[ Qtopia::HomeCountry ] );
200
201 list += untrdetailsfields( sorted );
202
203 list.append( mapIdToStr[ Qtopia::Notes ] );
204 list.append( mapIdToStr[ Qtopia::Groups ] );
205
206 if (sorted) list.sort();
207
208 return list;
209}
210QMap<int, QString> OContactFields::idToTrFields()
211{
212 QMap<int, QString> ret_map;
213
214 ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") );
215 ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) );
216 ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) );
217 ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) );
218 ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" ));
219 ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) );
220
221 ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) );
222 ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) );
223 ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) );
224 ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) );
225 ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) );
226 ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" ));
227
228 // email
229 ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) );
230 ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) );
231
232 ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) );
233 ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) );
234 ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) );
235
236 // business
237 ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) );
238 ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) );
239 ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) );
240 ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) );
241 ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) );
242 ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) );
243 ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) );
244
245 ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) );
246 ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) );
247 ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) );
248 ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) );
249
250 // home
251 ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) );
252 ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) );
253 ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) );
254 ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) );
255 ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) );
256 ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) );
257
258 //personal
259 ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) );
260 ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) );
261 ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) );
262 ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) );
263 ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) );
264 ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) );
265
266 // other
267 ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) );
268
269
270 return ret_map;
271}
272
273QMap<int, QString> OContactFields::idToUntrFields()
274{
275 QMap<int, QString> ret_map;
276
277 ret_map.insert( Qtopia::Title, "Name Title" );
278 ret_map.insert( Qtopia::FirstName, "First Name" );
279 ret_map.insert( Qtopia::MiddleName, "Middle Name" );
280 ret_map.insert( Qtopia::LastName, "Last Name" );
281 ret_map.insert( Qtopia::Suffix, "Suffix" );
282 ret_map.insert( Qtopia::FileAs, "File As" );
283
284 ret_map.insert( Qtopia::JobTitle, "Job Title" );
285 ret_map.insert( Qtopia::Department, "Department" );
286 ret_map.insert( Qtopia::Company, "Company" );
287 ret_map.insert( Qtopia::BusinessPhone, "Business Phone" );
288 ret_map.insert( Qtopia::BusinessFax, "Business Fax" );
289 ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" );
290
291 // email
292 ret_map.insert( Qtopia::DefaultEmail, "Default Email" );
293 ret_map.insert( Qtopia::Emails, "Emails" );
294
295 ret_map.insert( Qtopia::HomePhone, "Home Phone" );
296 ret_map.insert( Qtopia::HomeFax, "Home Fax" );
297 ret_map.insert( Qtopia::HomeMobile, "Home Mobile" );
298
299 // business
300 ret_map.insert( Qtopia::BusinessStreet, "Business Street" );
301 ret_map.insert( Qtopia::BusinessCity, "Business City" );
302 ret_map.insert( Qtopia::BusinessState, "Business State" );
303 ret_map.insert( Qtopia::BusinessZip, "Business Zip" );
304 ret_map.insert( Qtopia::BusinessCountry, "Business Country" );
305 ret_map.insert( Qtopia::BusinessPager, "Business Pager" );
306 ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" );
307
308 ret_map.insert( Qtopia::Office, "Office" );
309 ret_map.insert( Qtopia::Profession, "Profession" );
310 ret_map.insert( Qtopia::Assistant, "Assistant" );
311 ret_map.insert( Qtopia::Manager, "Manager" );
312
313 // home
314 ret_map.insert( Qtopia::HomeStreet, "Home Street" );
315 ret_map.insert( Qtopia::HomeCity, "Home City" );
316 ret_map.insert( Qtopia::HomeState, "Home State" );
317 ret_map.insert( Qtopia::HomeZip, "Home Zip" );
318 ret_map.insert( Qtopia::HomeCountry, "Home Country" );
319 ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" );
320
321 //personal
322 ret_map.insert( Qtopia::Spouse, "Spouse" );
323 ret_map.insert( Qtopia::Gender, "Gender" );
324 ret_map.insert( Qtopia::Birthday, "Birthday" );
325 ret_map.insert( Qtopia::Anniversary, "Anniversary" );
326 ret_map.insert( Qtopia::Nickname, "Nickname" );
327 ret_map.insert( Qtopia::Children, "Children" );
328
329 // other
330 ret_map.insert( Qtopia::Notes, "Notes" );
331
332
333 return ret_map;
334}
335
336QMap<QString, int> OContactFields::trFieldsToId()
337{
338 QMap<int, QString> idtostr = idToTrFields();
339 QMap<QString, int> ret_map;
340
341
342 QMap<int, QString>::Iterator it;
343 for( it = idtostr.begin(); it != idtostr.end(); ++it )
344 ret_map.insert( *it, it.key() );
345
346
347 return ret_map;
348}
349
350QMap<QString, int> OContactFields::untrFieldsToId()
351{
352 QMap<int, QString> idtostr = idToUntrFields();
353 QMap<QString, int> ret_map;
354
355
356 QMap<int, QString>::Iterator it;
357 for( it = idtostr.begin(); it != idtostr.end(); ++it )
358 ret_map.insert( *it, it.key() );
359
360
361 return ret_map;
362}
363
364
365OContactFields::OContactFields():
366 fieldOrder( DEFAULT_FIELD_ORDER ),
367 changedFieldOrder( false )
368{
369 // Get the global field order from the config file and
370 // use it as a start pattern
371 Config cfg ( "AddressBook" );
372 cfg.setGroup( "ContactFieldOrder" );
373 globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER );
374}
375
376OContactFields::~OContactFields(){
377
378 // We will store the fieldorder into the config file
379 // to reuse it for the future..
380 if ( changedFieldOrder ){
381 Config cfg ( "AddressBook" );
382 cfg.setGroup( "ContactFieldOrder" );
383 cfg.writeEntry( "General", globalFieldOrder );
384 }
385}
386
387
388
389void OContactFields::saveToRecord( OContact &cnt ){
390
391 qDebug("ocontactfields saveToRecord: >%s<",fieldOrder.latin1());
392
393 // Store fieldorder into this contact.
394 cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder );
395
396 globalFieldOrder = fieldOrder;
397 changedFieldOrder = true;
398
399}
400
401void OContactFields::loadFromRecord( const OContact &cnt ){
402 qDebug("ocontactfields loadFromRecord");
403 qDebug("loading >%s<",cnt.fullName().latin1());
404
405 // Get fieldorder for this contact. If none is defined,
406 // we will use the global one from the config file..
407
408 fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME );
409
410 qDebug("fieldOrder from contact>%s<",fieldOrder.latin1());
411
412 if (fieldOrder.isEmpty()){
413 fieldOrder = globalFieldOrder;
414 }
415
416
417 qDebug("effective fieldOrder in loadFromRecord >%s<",fieldOrder.latin1());
418}
419
420void OContactFields::setFieldOrder( int num, int index ){
421 qDebug("qcontactfields setfieldorder pos %i -> %i",num,index);
422
423 fieldOrder[num] = QString::number( index, 16 )[0];
424
425 // We will store this new fieldorder globally to
426 // remember it for contacts which have none
427 globalFieldOrder = fieldOrder;
428 changedFieldOrder = true;
429
430 qDebug("fieldOrder >%s<",fieldOrder.latin1());
431}
432
433int OContactFields::getFieldOrder( int num, int defIndex ){
434 qDebug("ocontactfields getFieldOrder");
435 qDebug("fieldOrder >%s<",fieldOrder.latin1());
436
437 // Get index of combo as char..
438 QChar poschar = fieldOrder[num];
439
440 bool ok;
441 int ret = 0;
442 // Convert char to number..
443 if ( !( poschar == QChar::null ) )
444 ret = QString( poschar ).toInt(&ok, 16);
445 else
446 ok = false;
447
448 // Return default value if index for
449 // num was not set or if anything else happened..
450 if ( !ok ) ret = defIndex;
451
452 qDebug("returning >%i<",ret);
453
454 return ret;
455
456}
diff --git a/libopie/pim/ocontactfields.h b/libopie/pim/ocontactfields.h
new file mode 100644
index 0000000..9f6171b
--- a/dev/null
+++ b/libopie/pim/ocontactfields.h
@@ -0,0 +1,60 @@
1#ifndef OPIE_CONTACTS_FIELDS
2#define OPIE_CONTACTS_FIELDS
3
4class QStringList;
5
6#include <qmap.h>
7#include <qstring.h>
8#include <opie/ocontact.h>
9
10#define CONTACT_FIELD_ORDER_NAME "opie-contactfield-order"
11#define DEFAULT_FIELD_ORDER "__________"
12
13class OContactFields{
14
15 public:
16 OContactFields();
17 ~OContactFields();
18 /** Set the index for combo boxes.
19 * Sets the <b>index</b> of combo <b>num</b>.
20 * @param num selects the number of the combo
21 * @param index sets the index in the combo
22 */
23 void setFieldOrder( int num, int index );
24
25 /** Get the index for combo boxes.
26 * Returns the index of combo <b>num</b> or defindex
27 * if none was defined..
28 * @param num Selects the number of the combo
29 * @param defIndex will be returned if none was defined (either
30 * globally in the config file, nor by the contact which was used
31 * by loadFromRecord() )
32 */
33 int getFieldOrder( int num, int defIndex);
34
35 /** Store fieldorder to contact. */
36 void saveToRecord( OContact& );
37 /** Get Fieldorder from contact. */
38 void loadFromRecord( const OContact& );
39
40 private:
41 QString fieldOrder;
42 QString globalFieldOrder;
43 bool changedFieldOrder;
44
45 public:
46 static QStringList trphonefields( bool sorted = true );
47 static QStringList untrphonefields( bool sorted = true );
48 static QStringList trdetailsfields( bool sorted = true );
49 static QStringList untrdetailsfields( bool sorted = true );
50 static QStringList trfields( bool sorted = true );
51 static QStringList untrfields( bool sorted = true );
52
53 static QMap<int, QString> idToTrFields();
54 static QMap<QString, int> trFieldsToId();
55 static QMap<int, QString> idToUntrFields();
56 static QMap<QString, int> untrFieldsToId();
57
58};
59
60#endif
diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp
index ec9c14c..23e0c3e 100644
--- a/libopie/pim/otodoaccesssql.cpp
+++ b/libopie/pim/otodoaccesssql.cpp
@@ -3,10 +3,10 @@
3 3
4#include <qpe/global.h> 4#include <qpe/global.h>
5 5
6#include <opie/osqldriver.h> 6#include <opie2/osqldriver.h>
7#include <opie/osqlresult.h> 7#include <opie2/osqlresult.h>
8#include <opie/osqlmanager.h> 8#include <opie2/osqlmanager.h>
9#include <opie/osqlquery.h> 9#include <opie2/osqlquery.h>
10 10
11#include "otodoaccesssql.h" 11#include "otodoaccesssql.h"
12 12
@@ -249,7 +249,7 @@ OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file )
249 OSQLManager man; 249 OSQLManager man;
250 m_driver = man.standard(); 250 m_driver = man.standard();
251 m_driver->setUrl(fi); 251 m_driver->setUrl(fi);
252 fillDict(); 252 // fillDict();
253} 253}
254 254
255OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ 255OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){
@@ -297,7 +297,7 @@ OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
297 // we try to cache CACHE items 297 // we try to cache CACHE items
298 switch( dir ) { 298 switch( dir ) {
299 /* forward */ 299 /* forward */
300 case 0: 300 case 0: // FIXME: Not a good style to use magic numbers here (eilers)
301 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { 301 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
302 qWarning("size %d %d", size, ints[i] ); 302 qWarning("size %d %d", size, ints[i] );
303 search[size] = ints[i]; 303 search[size] = ints[i];
@@ -305,7 +305,7 @@ OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
305 } 305 }
306 break; 306 break;
307 /* reverse */ 307 /* reverse */
308 case 1: 308 case 1: // FIXME: Not a good style to use magic numbers here (eilers)
309 for (uint i = cur; i != 0 && size < CACHE; i-- ) { 309 for (uint i = cur; i != 0 && size < CACHE; i-- ) {
310 search[size] = ints[i]; 310 search[size] = ints[i];
311 size++; 311 size++;
@@ -381,6 +381,7 @@ QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
381 /* 381 /*
382 * Sort Filter stuff 382 * Sort Filter stuff
383 * not that straight forward 383 * not that straight forward
384 * FIXME: Replace magic numbers
384 * 385 *
385 */ 386 */
386 /* Category */ 387 /* Category */
@@ -492,6 +493,7 @@ void OTodoAccessBackendSQL::fillDict() {
492 /* initialize dict */ 493 /* initialize dict */
493 /* 494 /*
494 * UPDATE dict if you change anything!!! 495 * UPDATE dict if you change anything!!!
496 * FIXME: Isn't this dict obsolete ? (eilers)
495 */ 497 */
496 m_dict.setAutoDelete( TRUE ); 498 m_dict.setAutoDelete( TRUE );
497 m_dict.insert("Categories" , new int(OTodo::Category) ); 499 m_dict.insert("Categories" , new int(OTodo::Category) );
@@ -505,10 +507,10 @@ void OTodoAccessBackendSQL::fillDict() {
505 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 507 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) );
506 m_dict.insert("DateYear" , new int(OTodo::DateYear) ); 508 m_dict.insert("DateYear" , new int(OTodo::DateYear) );
507 m_dict.insert("Progress" , new int(OTodo::Progress) ); 509 m_dict.insert("Progress" , new int(OTodo::Progress) );
508 m_dict.insert("Completed", new int(OTodo::Completed) ); 510 m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers)
509 m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); 511 m_dict.insert("CrossReference", new int(OTodo::CrossReference) );
510 m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); 512// m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers)
511 m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); 513// m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers)
512} 514}
513/* 515/*
514 * need to be const so let's fool the 516 * need to be const so let's fool the
@@ -538,3 +540,54 @@ QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{
538 return ints; 540 return ints;
539} 541}
540 542
543QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
544{
545
546#warning OTodoAccessBackendSQL::matchRegexp() not implemented !!
547
548#if 0
549
550 Copied from xml-backend by not adapted to sql (eilers)
551
552 QArray<int> m_currentQuery( m_events.count() );
553 uint arraycounter = 0;
554
555
556
557 QMap<int, OTodo>::ConstIterator it;
558 for (it = m_events.begin(); it != m_events.end(); ++it ) {
559 if ( it.data().match( r ) )
560 m_currentQuery[arraycounter++] = it.data().uid();
561
562 }
563 // Shrink to fit..
564 m_currentQuery.resize(arraycounter);
565
566 return m_currentQuery;
567#endif
568 QArray<int> empty;
569 return empty;
570}
571QBitArray OTodoAccessBackendSQL::supports()const {
572
573 static QBitArray ar = sup();
574 return ar;
575}
576
577QBitArray OTodoAccessBackendSQL::sup() {
578
579 QBitArray ar( OTodo::CompletedDate + 1 );
580 ar.fill( true );
581 ar[OTodo::CrossReference] = false;
582 ar[OTodo::State ] = false;
583 ar[OTodo::Reminders] = false;
584 ar[OTodo::Notifiers] = false;
585 ar[OTodo::Maintainer] = false;
586
587 return ar;
588}
589
590void OTodoAccessBackendSQL::removeAllCompleted(){
591#warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !!
592
593}
diff --git a/libopie/pim/otodoaccesssql.h b/libopie/pim/otodoaccesssql.h
index 6a4257c..77d8b77 100644
--- a/libopie/pim/otodoaccesssql.h
+++ b/libopie/pim/otodoaccesssql.h
@@ -31,6 +31,11 @@ public:
31 const QDate& end, bool includeNoDates ); 31 const QDate& end, bool includeNoDates );
32 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat ); 32 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat );
33 33
34 QBitArray supports()const;
35 QArray<int> matchRegexp( const QRegExp &r ) const;
36 void removeAllCompleted();
37
38
34private: 39private:
35 void update()const; 40 void update()const;
36 void fillDict(); 41 void fillDict();
@@ -39,6 +44,7 @@ private:
39 inline OTodo todo( OSQLResultItem& )const; 44 inline OTodo todo( OSQLResultItem& )const;
40 inline QArray<int> uids( const OSQLResult& )const; 45 inline QArray<int> uids( const OSQLResult& )const;
41 OTodo todo( int uid )const; 46 OTodo todo( int uid )const;
47 QBitArray sup();
42 48
43 QAsciiDict<int> m_dict; 49 QAsciiDict<int> m_dict;
44 OSQLDriver* m_driver; 50 OSQLDriver* m_driver;
diff --git a/libopie/pim/test/converter.cpp b/libopie/pim/test/converter.cpp
new file mode 100644
index 0000000..0a488f2
--- a/dev/null
+++ b/libopie/pim/test/converter.cpp
@@ -0,0 +1,64 @@
1#include <qpe/qpeapplication.h>
2
3#include <opie/ocontactaccess.h>
4#include <opie/ocontactaccessbackend_xml.h>
5#include <opie/ocontactaccessbackend_sql.h>
6
7#include "converter_base.h"
8
9class ConvertXMLToSQL: public converter_base {
10public:
11 ConvertXMLToSQL()
12 {
13 convertContact();
14 }
15private:
16 void convertContact();
17
18};
19
20
21void ConvertXMLToSQL::convertContact(){
22 qWarning("Converting Contacts from XML to SQL..");
23
24 // Creating backends to the requested databases..
25 OContactAccessBackend* xmlBackend = new OContactAccessBackend_XML( "Converter",
26 QString::null );
27
28 OContactAccessBackend* sqlBackend = new OContactAccessBackend_SQL( QString::null,
29 QString::null );
30 // Put the created backends into frontends to access them
31 OContactAccess* xmlAccess = new OContactAccess ( "addressbook_xml",
32 QString::null , xmlBackend, true );
33
34 OContactAccess* sqlAccess = new OContactAccess ( "addressbook_sql",
35 QString::null , sqlBackend, true );
36
37 // Clean the sql-database..
38 sqlAccess->clear();
39
40 // Now trasmit every contact from the xml database to the sql-database
41 OContactAccess::List contactList = xmlAccess->allRecords();
42 if ( sqlAccess && xmlAccess ){
43 OContactAccess::List::Iterator it;
44 for ( it = contactList.begin(); it != contactList.end(); ++it )
45 sqlAccess->add( *it );
46 }
47
48 // Delete the frontends. Backends will be deleted automatically, too !
49 delete sqlAccess;
50 delete xmlAccess;
51}
52
53int main( int argc, char** argv ) {
54
55 QPEApplication a( argc, argv );
56
57 ConvertXMLToSQL dlg;
58
59 a.showMainWidget( &dlg );
60 // dlg. showMaximized ( );
61
62 return a.exec();
63
64}
diff --git a/libopie/pim/test/converter.pro b/libopie/pim/test/converter.pro
new file mode 100644
index 0000000..aa74bff
--- a/dev/null
+++ b/libopie/pim/test/converter.pro
@@ -0,0 +1,12 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on debug
3 # CONFIG = qt warn_on release
4 #HEADERS =
5 SOURCES = converter.cpp
6INTERFACES = converter_base.ui
7 INCLUDEPATH+= $(OPIEDIR)/include
8 DEPENDPATH+= $(OPIEDIR)/include
9LIBS += -lqpe -lopie
10 TARGET = converter
11
12include ( $(OPIEDIR)/include.pro )
diff --git a/libopie/pim/test/converter_base.ui b/libopie/pim/test/converter_base.ui
new file mode 100644
index 0000000..f680550
--- a/dev/null
+++ b/libopie/pim/test/converter_base.ui
@@ -0,0 +1,43 @@
1<!DOCTYPE UI><UI>
2<class>converter_base</class>
3<widget>
4 <class>QDialog</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>converter_base</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>579</width>
15 <height>211</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Form2</string>
21 </property>
22 <widget>
23 <class>QLabel</class>
24 <property stdset="1">
25 <name>name</name>
26 <cstring>TextLabel1</cstring>
27 </property>
28 <property stdset="1">
29 <name>geometry</name>
30 <rect>
31 <x>340</x>
32 <y>40</y>
33 <width>210</width>
34 <height>20</height>
35 </rect>
36 </property>
37 <property stdset="1">
38 <name>text</name>
39 <string>Converter from XML-&gt;SQL</string>
40 </property>
41 </widget>
42</widget>
43</UI>
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
@@ -16,6 +16,11 @@
16 * ===================================================================== 16 * =====================================================================
17 * History: 17 * History:
18 * $Log$ 18 * $Log$
19 * Revision 1.8 2003/09/22 14:31:16 eilers
20 * Added first experimental incarnation of sql-backend for addressbook.
21 * Some modifications to be able to compile the todo sql-backend.
22 * A lot of changes fill follow...
23 *
19 * Revision 1.7 2003/08/01 12:30:16 eilers 24 * Revision 1.7 2003/08/01 12:30:16 eilers
20 * Merging changes from BRANCH_1_0 to HEAD 25 * Merging changes from BRANCH_1_0 to HEAD
21 * 26 *
@@ -74,6 +79,7 @@
74 79
75#ifdef __USE_SQL 80#ifdef __USE_SQL
76#include "otodoaccesssql.h" 81#include "otodoaccesssql.h"
82#include "ocontactaccessbackend_sql.h"
77#endif 83#endif
78 84
79class OBackendPrivate; 85class OBackendPrivate;
@@ -118,6 +124,8 @@ class OBackendFactory
118 config.setGroup ( backendName ); 124 config.setGroup ( backendName );
119 QString backend = config.readEntry( "usebackend" ); 125 QString backend = config.readEntry( "usebackend" );
120 126
127 qWarning("Selected backend for %s is: %s", backendName.latin1(), backend.latin1() );
128
121 QAsciiDict<int> dict ( 3 ); 129 QAsciiDict<int> dict ( 3 );
122 dict.setAutoDelete ( TRUE ); 130 dict.setAutoDelete ( TRUE );
123 131
@@ -125,9 +133,6 @@ class OBackendFactory
125 dict.insert( "contact", new int (CONTACT) ); 133 dict.insert( "contact", new int (CONTACT) );
126 dict.insert( "datebook", new int(DATE) ); 134 dict.insert( "datebook", new int(DATE) );
127 135
128 qWarning ("TODO is: %d", TODO);
129 qWarning ("CONTACT is: %d", CONTACT);
130
131 int *find = dict[ backendName ]; 136 int *find = dict[ backendName ];
132 if (!find ) return 0; 137 if (!find ) return 0;
133 138
@@ -143,8 +148,13 @@ class OBackendFactory
143 148
144 return (T*) new OTodoAccessXML( appName ); 149 return (T*) new OTodoAccessXML( appName );
145 case CONTACT: 150 case CONTACT:
151#ifdef __USE_SQL
152 if ( backend == "sql" )
153 return (T*) new OContactAccessBackend_SQL("");
154#else
146 if ( backend == "sql" ) 155 if ( backend == "sql" )
147 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 156 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
157#endif
148 158
149 return (T*) new OContactAccessBackend_XML( appName ); 159 return (T*) new OContactAccessBackend_XML( appName );
150 case DATE: 160 case DATE:
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 @@
1/*
2 * SQL Backend for the OPIE-Contact Database.
3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 *
6 * =====================================================================
7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * =====================================================================
12 * =====================================================================
13 * Version: $Id$
14 * =====================================================================
15 * History:
16 * $Log$
17 * Revision 1.1 2003/09/22 14:31:16 eilers
18 * Added first experimental incarnation of sql-backend for addressbook.
19 * Some modifications to be able to compile the todo sql-backend.
20 * A lot of changes fill follow...
21 *
22 */
23
24#include "ocontactaccessbackend_sql.h"
25
26#include <qarray.h>
27#include <qdatetime.h>
28#include <qstringlist.h>
29
30#include <qpe/global.h>
31#include <qpe/recordfields.h>
32
33#include <opie/ocontactfields.h>
34#include <opie/oconversion.h>
35#include <opie2/osqldriver.h>
36#include <opie2/osqlresult.h>
37#include <opie2/osqlmanager.h>
38#include <opie2/osqlquery.h>
39
40/*
41 * Implementation of used query types
42 * CREATE query
43 * LOAD query
44 * INSERT
45 * REMOVE
46 * CLEAR
47 */
48namespace {
49 /**
50 * CreateQuery for the Todolist Table
51 */
52 class CreateQuery : public OSQLQuery {
53 public:
54 CreateQuery();
55 ~CreateQuery();
56 QString query()const;
57 };
58
59 /**
60 * Clears (delete) a Table
61 */
62 class ClearQuery : public OSQLQuery {
63 public:
64 ClearQuery();
65 ~ClearQuery();
66 QString query()const;
67
68 };
69
70
71 /**
72 * LoadQuery
73 * this one queries for all uids
74 */
75 class LoadQuery : public OSQLQuery {
76 public:
77 LoadQuery();
78 ~LoadQuery();
79 QString query()const;
80 };
81
82 /**
83 * inserts/adds a OContact to the table
84 */
85 class InsertQuery : public OSQLQuery {
86 public:
87 InsertQuery(const OContact& );
88 ~InsertQuery();
89 QString query()const;
90 private:
91 OContact m_contact;
92 };
93
94
95 /**
96 * removes one from the table
97 */
98 class RemoveQuery : public OSQLQuery {
99 public:
100 RemoveQuery(int uid );
101 ~RemoveQuery();
102 QString query()const;
103 private:
104 int m_uid;
105 };
106
107 /**
108 * a find query for noncustom elements
109 */
110 class FindQuery : public OSQLQuery {
111 public:
112 FindQuery(int uid);
113 FindQuery(const QArray<int>& );
114 ~FindQuery();
115 QString query()const;
116 private:
117 QString single()const;
118 QString multi()const;
119 QArray<int> m_uids;
120 int m_uid;
121 };
122
123 /**
124 * a find query for custom elements
125 */
126 class FindCustomQuery : public OSQLQuery {
127 public:
128 FindCustomQuery(int uid);
129 FindCustomQuery(const QArray<int>& );
130 ~FindCustomQuery();
131 QString query()const;
132 private:
133 QString single()const;
134 QString multi()const;
135 QArray<int> m_uids;
136 int m_uid;
137 };
138
139
140
141 // We using three tables to store the information:
142 // 1. addressbook : It contains General information about the contact (non custom)
143 // 2. dates : Stuff like birthdays, anniversaries, etc.
144 // 3. custom_data : Not official supported entries
145 // All tables are connected by the uid of the contact.
146 // Maybe I should add a table for meta-information ?
147 CreateQuery::CreateQuery() : OSQLQuery() {}
148 CreateQuery::~CreateQuery() {}
149 QString CreateQuery::query()const {
150 QString qu;
151 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));";
152 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
153 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );";
154 return qu;
155 }
156
157 ClearQuery::ClearQuery()
158 : OSQLQuery() {}
159 ClearQuery::~ClearQuery() {}
160 QString ClearQuery::query()const {
161 QString qu = "drop table addressbook;";
162 qu += "drop table custom_data;";
163 qu += "drop table dates;";
164 return qu;
165 }
166
167// Distinct loading is not very fast. If I expect that every person has just
168// one (and always one) 'Last Name', I can request all uid's for existing lastnames,
169// which is faster..
170// But this may not be true for all entries, like company contacts..
171// The current AddressBook application handles this problem, but other may not.. (eilers)
172#define __USE_SUPERFAST_LOADQUERY
173
174 LoadQuery::LoadQuery() : OSQLQuery() {}
175 LoadQuery::~LoadQuery() {}
176 QString LoadQuery::query()const {
177 QString qu;
178#ifndef __USE_SUPERFAST_LOADQUERY
179 qu += "select distinct uid from addressbook";
180#else
181 qu += "select uid from addressbook where type = 'Last Name'";
182#endif
183
184 return qu;
185 }
186
187
188 InsertQuery::InsertQuery( const OContact& contact )
189 : OSQLQuery(), m_contact( contact ) {
190 }
191
192 InsertQuery::~InsertQuery() {
193 }
194
195 /*
196 * converts from a OContact to a query
197 */
198 QString InsertQuery::query()const{
199
200 // Get all information out of the contact-class
201 // Remember: The category is stored in contactMap, too !
202 QMap<int, QString> contactMap = m_contact.toMap();
203 QMap<QString, QString> customMap = m_contact.toExtraMap();
204
205 QMap<QString, QString> addressbook_db;
206
207 // Get the translation from the ID to the String
208 QMap<int, QString> transMap = OContactFields::idToUntrFields();
209
210 for( QMap<int, QString>::Iterator it = contactMap.begin();
211 it != contactMap.end(); ++it ){
212 switch ( it.key() ){
213 case Qtopia::Birthday:{
214 // These entries should stored in a special format
215 // year-month-day
216 QDate day = m_contact.birthday();
217 addressbook_db.insert( transMap[it.key()],
218 QString("%1-%2-%3")
219 .arg( day.year() )
220 .arg( day.month() )
221 .arg( day.day() ) );
222 }
223 break;
224 case Qtopia::Anniversary:{
225 // These entries should stored in a special format
226 // year-month-day
227 QDate day = m_contact.anniversary();
228 addressbook_db.insert( transMap[it.key()],
229 QString("%1-%2-%3")
230 .arg( day.year() )
231 .arg( day.month() )
232 .arg( day.day() ) );
233 }
234 break;
235 case Qtopia::AddressUid: // Ignore UID
236 break;
237 default: // Translate id to String
238 addressbook_db.insert( transMap[it.key()], it.data() );
239 break;
240 }
241
242 }
243
244 // Now convert this whole stuff into a SQL String, beginning with
245 // the addressbook table..
246 QString qu;
247 // qu += "begin transaction;";
248 int id = 0;
249 for( QMap<QString, QString>::Iterator it = addressbook_db.begin();
250 it != addressbook_db.end(); ++it ){
251 qu += "insert into addressbook VALUES("
252 + QString::number( m_contact.uid() )
253 + ","
254 + QString::number( id++ )
255 + ",'"
256 + it.key() //.latin1()
257 + "',"
258 + "0" // Priority for future enhancements
259 + ",'"
260 + it.data() //.latin1()
261 + "');";
262 }
263
264 // Now add custom data..
265 id = 0;
266 for( QMap<QString, QString>::Iterator it = customMap.begin();
267 it != customMap.end(); ++it ){
268 qu += "insert into custom_data VALUES("
269 + QString::number( m_contact.uid() )
270 + ","
271 + QString::number( id++ )
272 + ",'"
273 + it.key() //.latin1()
274 + "',"
275 + "0" // Priority for future enhancements
276 + ",'"
277 + it.data() //.latin1()
278 + "');";
279 }
280
281 // qu += "commit;";
282 qWarning("add %s", qu.latin1() );
283 return qu;
284 }
285
286
287 RemoveQuery::RemoveQuery(int uid )
288 : OSQLQuery(), m_uid( uid ) {}
289 RemoveQuery::~RemoveQuery() {}
290 QString RemoveQuery::query()const {
291 QString qu = "DELETE from addressbook where uid = "
292 + QString::number(m_uid) + ";";
293 qu += "DELETE from dates where uid = "
294 + QString::number(m_uid) + ";";
295 qu += "DELETE from custom_data where uid = "
296 + QString::number(m_uid) + ";";
297 return qu;
298 }
299
300
301
302
303 FindQuery::FindQuery(int uid)
304 : OSQLQuery(), m_uid( uid ) {
305 }
306 FindQuery::FindQuery(const QArray<int>& ints)
307 : OSQLQuery(), m_uids( ints ){
308 }
309 FindQuery::~FindQuery() {
310 }
311 QString FindQuery::query()const{
312 // if ( m_uids.count() == 0 )
313 return single();
314 }
315 /*
316 else
317 return multi();
318 }
319 QString FindQuery::multi()const {
320 QString qu = "select uid, type, value from addressbook where";
321 for (uint i = 0; i < m_uids.count(); i++ ) {
322 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
323 }
324 qu.remove( qu.length()-2, 2 ); // Hmmmm..
325 return qu;
326 }
327 */
328 QString FindQuery::single()const{
329 QString qu = "select uid, type, value from addressbook where uid = ";
330 qu += QString::number(m_uid);
331 return qu;
332 }
333
334
335 FindCustomQuery::FindCustomQuery(int uid)
336 : OSQLQuery(), m_uid( uid ) {
337 }
338 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
339 : OSQLQuery(), m_uids( ints ){
340 }
341 FindCustomQuery::~FindCustomQuery() {
342 }
343 QString FindCustomQuery::query()const{
344 // if ( m_uids.count() == 0 )
345 return single();
346 }
347 QString FindCustomQuery::single()const{
348 QString qu = "select uid, type, value from custom_data where uid = ";
349 qu += QString::number(m_uid);
350 return qu;
351 }
352
353};
354
355
356/* --------------------------------------------------------------------------- */
357
358OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */,
359 const QString& filename ): m_changed(false)
360{
361 qWarning("C'tor OContactAccessBackend_SQL starts");
362 QTime t;
363 t.start();
364
365 /* Expecting to access the default filename if nothing else is set */
366 if ( filename.isEmpty() ){
367 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
368 } else
369 m_fileName = filename;
370
371 // Get the standart sql-driver from the OSQLManager..
372 OSQLManager man;
373 m_driver = man.standard();
374 m_driver->setUrl( m_fileName );
375
376 load();
377
378 qWarning("C'tor OContactAccessBackend_SQL ends: %d", t.elapsed() );
379}
380
381
382bool OContactAccessBackend_SQL::load ()
383{
384 if (!m_driver->open() )
385 return false;
386
387 // Don't expect that the database exists.
388 // It is save here to create the table, even if it
389 // do exist. ( Is that correct for all databases ?? )
390 CreateQuery creat;
391 OSQLResult res = m_driver->query( &creat );
392
393 update();
394
395 return true;
396
397}
398
399bool OContactAccessBackend_SQL::reload()
400{
401 return load();
402}
403
404bool OContactAccessBackend_SQL::save()
405{
406 return m_driver->close();
407}
408
409
410void OContactAccessBackend_SQL::clear ()
411{
412 ClearQuery cle;
413 OSQLResult res = m_driver->query( &cle );
414 CreateQuery qu;
415 res = m_driver->query(&qu);
416}
417
418bool OContactAccessBackend_SQL::wasChangedExternally()
419{
420 return false;
421}
422
423QArray<int> OContactAccessBackend_SQL::allRecords() const
424{
425
426 // FIXME: Think about cute handling of changed tables..
427 // Thus, we don't have to call update here...
428 if ( m_changed )
429 ((OContactAccessBackend_SQL*)this)->update();
430
431 return m_uids;
432}
433
434bool OContactAccessBackend_SQL::add ( const OContact &newcontact )
435{
436 InsertQuery ins( newcontact );
437 OSQLResult res = m_driver->query( &ins );
438
439 if ( res.state() == OSQLResult::Failure )
440 return false;
441
442 int c = m_uids.count();
443 m_uids.resize( c+1 );
444 m_uids[c] = newcontact.uid();
445
446 return true;
447}
448
449
450bool OContactAccessBackend_SQL::remove ( int uid )
451{
452 RemoveQuery rem( uid );
453 OSQLResult res = m_driver->query(&rem );
454
455 if ( res.state() == OSQLResult::Failure )
456 return false;
457
458 m_changed = true;
459
460 return true;
461}
462
463bool OContactAccessBackend_SQL::replace ( const OContact &contact )
464{
465 if ( !remove( contact.uid() ) )
466 return false;
467
468 return add( contact );
469}
470
471
472OContact OContactAccessBackend_SQL::find ( int uid ) const
473{
474 qWarning("OContactAccessBackend_SQL::find()");
475 QTime t;
476 t.start();
477
478 OContact retContact( requestNonCustom( uid ) );
479 retContact.setExtraMap( requestCustom( uid ) );
480
481 qWarning("OContactAccessBackend_SQL::find() needed: %d", t.elapsed() );
482 return retContact;
483}
484
485
486
487QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() )
488{
489 QArray<int> nix(0);
490 return nix;
491}
492
493QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
494{
495 QArray<int> nix(0);
496 return nix;
497}
498
499const uint OContactAccessBackend_SQL::querySettings()
500{
501 return 0;
502}
503
504bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
505{
506 return false;
507}
508
509QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int )
510{
511 QTime t;
512 t.start();
513
514 // Not implemented..
515 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' ";
516
517 query += "ORDER BY value ";
518 if ( !asc )
519 query += "DESC";
520
521 qWarning("sorted query is: %s", query.latin1() );
522
523 OSQLRawQuery raw( query );
524 OSQLResult res = m_driver->query( &raw );
525 if ( res.state() != OSQLResult::Success ){
526 QArray<int> empty;
527 return empty;
528 }
529
530 QArray<int> list = extractUids( res );
531
532 qWarning("sorted needed %d ms!", t.elapsed() );
533 return list;
534}
535
536
537void OContactAccessBackend_SQL::update()
538{
539 qWarning("Update starts");
540 QTime t;
541 t.start();
542
543 // Now load the database set and extract the uid's
544 // which will be held locally
545
546 LoadQuery lo;
547 OSQLResult res = m_driver->query(&lo);
548 if ( res.state() != OSQLResult::Success )
549 return;
550
551 m_uids = extractUids( res );
552
553 m_changed = false;
554
555 qWarning("Update ends %d", t.elapsed() );
556}
557
558QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
559{
560 qWarning("extractUids");
561 QTime t;
562 t.start();
563 OSQLResultItem::ValueList list = res.results();
564 OSQLResultItem::ValueList::Iterator it;
565 QArray<int> ints(list.count() );
566 qWarning(" count = %d", list.count() );
567
568 int i = 0;
569 for (it = list.begin(); it != list.end(); ++it ) {
570 ints[i] = (*it).data("uid").toInt();
571 i++;
572 }
573 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
574
575 return ints;
576
577}
578
579QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
580{
581 QTime t;
582 t.start();
583
584 QMap<int, QString> nonCustomMap;
585
586 int t2needed = 0;
587 QTime t2;
588 t2.start();
589 FindQuery query( uid );
590 OSQLResult res_noncustom = m_driver->query( &query );
591 t2needed = t2.elapsed();
592
593 if ( res_noncustom.state() == OSQLResult::Failure ) {
594 qWarning("OSQLResult::Failure in find query !!");
595 QMap<int, QString> empty;
596 return empty;
597 }
598
599 int t3needed = 0;
600 QTime t3;
601 t3.start();
602 QMap<QString, int> translateMap = OContactFields::untrFieldsToId();
603
604 OSQLResultItem::ValueList list = res_noncustom.results();
605 OSQLResultItem::ValueList::Iterator it = list.begin();
606 for ( ; it != list.end(); ++it ) {
607 if ( (*it).data("type") != "" ){
608 int typeId = translateMap[(*it).data( "type" )];
609 switch( typeId ){
610 case Qtopia::Birthday:
611 case Qtopia::Anniversary:{
612 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
613 QStringList list = QStringList::split( '-', (*it).data( "value" ) );
614 QStringList::Iterator lit = list.begin();
615 int year = (*lit).toInt();
616 qWarning("1. %s", (*lit).latin1());
617 int month = (*(++lit)).toInt();
618 qWarning("2. %s", (*lit).latin1());
619 int day = (*(++lit)).toInt();
620 qWarning("3. %s", (*lit).latin1());
621 qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day );
622 QDate date( year, month, day );
623 nonCustomMap.insert( typeId, OConversion::dateToString( date ) );
624 }
625 break;
626 default:
627 nonCustomMap.insert( typeId,
628 (*it).data( "value" ) );
629 }
630 }
631 }
632 // Add UID to Map..
633 nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) );
634 t3needed = t3.elapsed();
635
636 qWarning("RequestNonCustom needed: ins:%d, query: %d, mapping: %d", t.elapsed(), t2needed, t3needed );
637 return nonCustomMap;
638}
639
640QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const
641{
642 QTime t;
643 t.start();
644
645 QMap<QString, QString> customMap;
646
647 FindCustomQuery query( uid );
648 OSQLResult res_custom = m_driver->query( &query );
649
650 if ( res_custom.state() == OSQLResult::Failure ) {
651 qWarning("OSQLResult::Failure in find query !!");
652 QMap<QString, QString> empty;
653 return empty;
654 }
655
656 OSQLResultItem::ValueList list = res_custom.results();
657 OSQLResultItem::ValueList::Iterator it = list.begin();
658 for ( ; it != list.end(); ++it ) {
659 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
660 }
661
662 qWarning("RequestCustom needed: %d", t.elapsed() );
663 return customMap;
664}
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 @@
1/*
2 * SQL Backend for the OPIE-Contact Database.
3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 *
6 * =====================================================================
7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * =====================================================================
12 *
13 *
14 * =====================================================================
15 * Version: $Id$
16 * =====================================================================
17 * History:
18 * $Log$
19 * Revision 1.1 2003/09/22 14:31:16 eilers
20 * Added first experimental incarnation of sql-backend for addressbook.
21 * Some modifications to be able to compile the todo sql-backend.
22 * A lot of changes fill follow...
23 *
24 *
25 */
26
27#ifndef _OContactAccessBackend_SQL_
28#define _OContactAccessBackend_SQL_
29
30#include "ocontactaccessbackend.h"
31#include "ocontactaccess.h"
32
33#include <qlist.h>
34#include <qdict.h>
35
36class OSQLDriver;
37class OSQLResult;
38class OSQLResultItem;
39
40/* the default xml implementation */
41/**
42 * This class is the SQL implementation of a Contact backend
43 * it does implement everything available for OContact.
44 * @see OPimAccessBackend for more information of available methods
45 */
46class OContactAccessBackend_SQL : public OContactAccessBackend {
47 public:
48 OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null );
49
50 bool save();
51
52 bool load ();
53
54 void clear ();
55
56 bool wasChangedExternally();
57
58 QArray<int> allRecords() const;
59
60 OContact find ( int uid ) const;
61 // FIXME: Add lookahead-cache support !
62 //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
63
64 QArray<int> queryByExample ( const OContact &query, int settings,
65 const QDateTime& d );
66
67 QArray<int> matchRegexp( const QRegExp &r ) const;
68
69 const uint querySettings();
70
71 bool hasQuerySettings (uint querySettings) const;
72
73 // Currently only asc implemented..
74 QArray<int> sorted( bool asc, int , int , int );
75 bool add ( const OContact &newcontact );
76
77 bool replace ( const OContact &contact );
78
79 bool remove ( int uid );
80 bool reload();
81
82 private:
83 QArray<int> extractUids( OSQLResult& res ) const;
84 QMap<int, QString> requestNonCustom( int uid ) const;
85 QMap<QString, QString> requestCustom( int uid ) const;
86 void update();
87
88 protected:
89 bool m_changed;
90 QString m_fileName;
91 QArray<int> m_uids;
92
93 OSQLDriver* m_driver;
94};
95
96#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
@@ -9,14 +9,17 @@
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 *
14 * 12 *
15 * ===================================================================== 13 * =====================================================================
16 * Version: $Id$ 14 * Version: $Id$
17 * ===================================================================== 15 * =====================================================================
18 * History: 16 * History:
19 * $Log$ 17 * $Log$
18 * Revision 1.9 2003/09/22 14:31:16 eilers
19 * Added first experimental incarnation of sql-backend for addressbook.
20 * Some modifications to be able to compile the todo sql-backend.
21 * A lot of changes fill follow...
22 *
20 * Revision 1.8 2003/08/30 15:28:26 eilers 23 * Revision 1.8 2003/08/30 15:28:26 eilers
21 * Removed some unimportant debug output which causes slow down.. 24 * Removed some unimportant debug output which causes slow down..
22 * 25 *
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
@@ -10,6 +10,7 @@
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed... 12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 * File Locking to protect against concurrent access
13 * 14 *
14 * 15 *
15 * ===================================================================== 16 * =====================================================================
@@ -17,6 +18,11 @@
17 * ===================================================================== 18 * =====================================================================
18 * History: 19 * History:
19 * $Log$ 20 * $Log$
21 * Revision 1.15 2003/09/22 14:31:16 eilers
22 * Added first experimental incarnation of sql-backend for addressbook.
23 * Some modifications to be able to compile the todo sql-backend.
24 * A lot of changes fill follow...
25 *
20 * Revision 1.14 2003/04/13 18:07:10 zecke 26 * Revision 1.14 2003/04/13 18:07:10 zecke
21 * More API doc 27 * More API doc
22 * QString -> const QString& 28 * QString -> const QString&
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
@@ -3,10 +3,10 @@
3 3
4#include <qpe/global.h> 4#include <qpe/global.h>
5 5
6#include <opie/osqldriver.h> 6#include <opie2/osqldriver.h>
7#include <opie/osqlresult.h> 7#include <opie2/osqlresult.h>
8#include <opie/osqlmanager.h> 8#include <opie2/osqlmanager.h>
9#include <opie/osqlquery.h> 9#include <opie2/osqlquery.h>
10 10
11#include "otodoaccesssql.h" 11#include "otodoaccesssql.h"
12 12
@@ -249,7 +249,7 @@ OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file )
249 OSQLManager man; 249 OSQLManager man;
250 m_driver = man.standard(); 250 m_driver = man.standard();
251 m_driver->setUrl(fi); 251 m_driver->setUrl(fi);
252 fillDict(); 252 // fillDict();
253} 253}
254 254
255OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ 255OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){
@@ -297,7 +297,7 @@ OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
297 // we try to cache CACHE items 297 // we try to cache CACHE items
298 switch( dir ) { 298 switch( dir ) {
299 /* forward */ 299 /* forward */
300 case 0: 300 case 0: // FIXME: Not a good style to use magic numbers here (eilers)
301 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { 301 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
302 qWarning("size %d %d", size, ints[i] ); 302 qWarning("size %d %d", size, ints[i] );
303 search[size] = ints[i]; 303 search[size] = ints[i];
@@ -305,7 +305,7 @@ OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
305 } 305 }
306 break; 306 break;
307 /* reverse */ 307 /* reverse */
308 case 1: 308 case 1: // FIXME: Not a good style to use magic numbers here (eilers)
309 for (uint i = cur; i != 0 && size < CACHE; i-- ) { 309 for (uint i = cur; i != 0 && size < CACHE; i-- ) {
310 search[size] = ints[i]; 310 search[size] = ints[i];
311 size++; 311 size++;
@@ -381,6 +381,7 @@ QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
381 /* 381 /*
382 * Sort Filter stuff 382 * Sort Filter stuff
383 * not that straight forward 383 * not that straight forward
384 * FIXME: Replace magic numbers
384 * 385 *
385 */ 386 */
386 /* Category */ 387 /* Category */
@@ -492,6 +493,7 @@ void OTodoAccessBackendSQL::fillDict() {
492 /* initialize dict */ 493 /* initialize dict */
493 /* 494 /*
494 * UPDATE dict if you change anything!!! 495 * UPDATE dict if you change anything!!!
496 * FIXME: Isn't this dict obsolete ? (eilers)
495 */ 497 */
496 m_dict.setAutoDelete( TRUE ); 498 m_dict.setAutoDelete( TRUE );
497 m_dict.insert("Categories" , new int(OTodo::Category) ); 499 m_dict.insert("Categories" , new int(OTodo::Category) );
@@ -505,10 +507,10 @@ void OTodoAccessBackendSQL::fillDict() {
505 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 507 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) );
506 m_dict.insert("DateYear" , new int(OTodo::DateYear) ); 508 m_dict.insert("DateYear" , new int(OTodo::DateYear) );
507 m_dict.insert("Progress" , new int(OTodo::Progress) ); 509 m_dict.insert("Progress" , new int(OTodo::Progress) );
508 m_dict.insert("Completed", new int(OTodo::Completed) ); 510 m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers)
509 m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); 511 m_dict.insert("CrossReference", new int(OTodo::CrossReference) );
510 m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); 512// m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers)
511 m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); 513// m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers)
512} 514}
513/* 515/*
514 * need to be const so let's fool the 516 * need to be const so let's fool the
@@ -538,3 +540,54 @@ QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{
538 return ints; 540 return ints;
539} 541}
540 542
543QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
544{
545
546#warning OTodoAccessBackendSQL::matchRegexp() not implemented !!
547
548#if 0
549
550 Copied from xml-backend by not adapted to sql (eilers)
551
552 QArray<int> m_currentQuery( m_events.count() );
553 uint arraycounter = 0;
554
555
556
557 QMap<int, OTodo>::ConstIterator it;
558 for (it = m_events.begin(); it != m_events.end(); ++it ) {
559 if ( it.data().match( r ) )
560 m_currentQuery[arraycounter++] = it.data().uid();
561
562 }
563 // Shrink to fit..
564 m_currentQuery.resize(arraycounter);
565
566 return m_currentQuery;
567#endif
568 QArray<int> empty;
569 return empty;
570}
571QBitArray OTodoAccessBackendSQL::supports()const {
572
573 static QBitArray ar = sup();
574 return ar;
575}
576
577QBitArray OTodoAccessBackendSQL::sup() {
578
579 QBitArray ar( OTodo::CompletedDate + 1 );
580 ar.fill( true );
581 ar[OTodo::CrossReference] = false;
582 ar[OTodo::State ] = false;
583 ar[OTodo::Reminders] = false;
584 ar[OTodo::Notifiers] = false;
585 ar[OTodo::Maintainer] = false;
586
587 return ar;
588}
589
590void OTodoAccessBackendSQL::removeAllCompleted(){
591#warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !!
592
593}
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
@@ -31,6 +31,11 @@ public:
31 const QDate& end, bool includeNoDates ); 31 const QDate& end, bool includeNoDates );
32 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat ); 32 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat );
33 33
34 QBitArray supports()const;
35 QArray<int> matchRegexp( const QRegExp &r ) const;
36 void removeAllCompleted();
37
38
34private: 39private:
35 void update()const; 40 void update()const;
36 void fillDict(); 41 void fillDict();
@@ -39,6 +44,7 @@ private:
39 inline OTodo todo( OSQLResultItem& )const; 44 inline OTodo todo( OSQLResultItem& )const;
40 inline QArray<int> uids( const OSQLResult& )const; 45 inline QArray<int> uids( const OSQLResult& )const;
41 OTodo todo( int uid )const; 46 OTodo todo( int uid )const;
47 QBitArray sup();
42 48
43 QAsciiDict<int> m_dict; 49 QAsciiDict<int> m_dict;
44 OSQLDriver* m_driver; 50 OSQLDriver* m_driver;
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
@@ -196,11 +196,6 @@ public:
196 QString groups() const { return find( Qtopia::Groups ); } 196 QString groups() const { return find( Qtopia::Groups ); }
197 QStringList groupList() const; 197 QStringList groupList() const;
198 198
199// // custom
200// const QString &customField( const QString &key )
201// { return find( Custom- + key ); }
202
203
204 QString toRichText() const; 199 QString toRichText() const;
205 QMap<int, QString> toMap() const; 200 QMap<int, QString> toMap() const;
206 QString field( int key ) const { return find( key ); } 201 QString field( int key ) const { return find( key ); }
@@ -209,19 +204,19 @@ public:
209 void setUid( int i ); 204 void setUid( int i );
210 205
211 QString toShortText()const; 206 QString toShortText()const;
212 QString OContact::type()const; 207 QString type()const;
213 QMap<QString,QString> OContact::toExtraMap() const; 208 class QString recordField(int) const;
214 class QString OContact::recordField(int) const;
215 209
216 // Why private ? (eilers,se) 210 // Why private ? (eilers,se)
217 QString emailSeparator() const { return " "; } 211 QString emailSeparator() const { return " "; }
212
218 // the emails should be seperated by a comma 213 // the emails should be seperated by a comma
219 void setEmails( const QString &v ); 214 void setEmails( const QString &v );
220 QString emails() const { return find( Qtopia::Emails ); } 215 QString emails() const { return find( Qtopia::Emails ); }
221 static int rtti(); 216 static int rtti();
222 217
223private: 218private:
224 // The XML-Backend needs some access to the private functions 219 // The XML Backend needs some access to the private functions
225 friend class OContactAccessBackend_XML; 220 friend class OContactAccessBackend_XML;
226 221
227 void insert( int key, const QString &value ); 222 void insert( int key, const QString &value );
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 @@
1
2#include "ocontactfields.h"
3
4#include <qstringlist.h>
5#include <qobject.h>
6
7// We should use our own enum in the future ..
8#include <qpe/recordfields.h>
9#include <qpe/config.h>
10#include <opie/ocontact.h>
11
12/*!
13 \internal
14 Returns a list of details field names for a contact.
15*/
16QStringList OContactFields::untrdetailsfields( bool sorted )
17{
18 QStringList list;
19 QMap<int, QString> mapIdToStr = idToUntrFields();
20
21 list.append( mapIdToStr[ Qtopia::Office ] );
22 list.append( mapIdToStr[ Qtopia::Profession ] );
23 list.append( mapIdToStr[ Qtopia::Assistant ] );
24 list.append( mapIdToStr[ Qtopia::Manager ] );
25
26 list.append( mapIdToStr[ Qtopia::Spouse ] );
27 list.append( mapIdToStr[ Qtopia::Gender ] );
28 list.append( mapIdToStr[ Qtopia::Birthday ] );
29 list.append( mapIdToStr[ Qtopia::Anniversary ] );
30 list.append( mapIdToStr[ Qtopia::Nickname ] );
31 list.append( mapIdToStr[ Qtopia::Children ] );
32
33 if (sorted) list.sort();
34 return list;
35}
36
37/*!
38 \internal
39 Returns a translated list of details field names for a contact.
40*/
41QStringList OContactFields::trdetailsfields( bool sorted )
42{
43 QStringList list;
44 QMap<int, QString> mapIdToStr = idToTrFields();
45
46 list.append( mapIdToStr[Qtopia::Office] );
47 list.append( mapIdToStr[Qtopia::Profession] );
48 list.append( mapIdToStr[Qtopia::Assistant] );
49 list.append( mapIdToStr[Qtopia::Manager] );
50
51 list.append( mapIdToStr[Qtopia::Spouse] );
52 list.append( mapIdToStr[Qtopia::Gender] );
53 list.append( mapIdToStr[Qtopia::Birthday] );
54 list.append( mapIdToStr[Qtopia::Anniversary] );
55 list.append( mapIdToStr[Qtopia::Nickname] );
56 list.append( mapIdToStr[Qtopia::Children] );
57
58 if (sorted) list.sort();
59 return list;
60}
61
62
63/*!
64 \internal
65 Returns a translated list of phone field names for a contact.
66*/
67QStringList OContactFields::trphonefields( bool sorted )
68{
69 QStringList list;
70 QMap<int, QString> mapIdToStr = idToTrFields();
71
72 list.append( mapIdToStr[Qtopia::BusinessPhone] );
73 list.append( mapIdToStr[Qtopia::BusinessFax] );
74 list.append( mapIdToStr[Qtopia::BusinessMobile] );
75 list.append( mapIdToStr[Qtopia::BusinessPager] );
76 list.append( mapIdToStr[Qtopia::BusinessWebPage] );
77
78 list.append( mapIdToStr[Qtopia::DefaultEmail] );
79 list.append( mapIdToStr[Qtopia::Emails] );
80
81 list.append( mapIdToStr[Qtopia::HomePhone] );
82 list.append( mapIdToStr[Qtopia::HomeFax] );
83 list.append( mapIdToStr[Qtopia::HomeMobile] );
84 // list.append( mapIdToStr[Qtopia::HomePager] );
85 list.append( mapIdToStr[Qtopia::HomeWebPage] );
86
87 if (sorted) list.sort();
88
89 return list;
90}
91
92
93/*!
94 \internal
95 Returns a list of phone field names for a contact.
96*/
97QStringList OContactFields::untrphonefields( bool sorted )
98{
99 QStringList list;
100 QMap<int, QString> mapIdToStr = idToUntrFields();
101
102 list.append( mapIdToStr[ Qtopia::BusinessPhone ] );
103 list.append( mapIdToStr[ Qtopia::BusinessFax ] );
104 list.append( mapIdToStr[ Qtopia::BusinessMobile ] );
105 list.append( mapIdToStr[ Qtopia::BusinessPager ] );
106 list.append( mapIdToStr[ Qtopia::BusinessWebPage ] );
107
108 list.append( mapIdToStr[ Qtopia::DefaultEmail ] );
109 list.append( mapIdToStr[ Qtopia::Emails ] );
110
111 list.append( mapIdToStr[ Qtopia::HomePhone ] );
112 list.append( mapIdToStr[ Qtopia::HomeFax ] );
113 list.append( mapIdToStr[ Qtopia::HomeMobile ] );
114 //list.append( mapIdToStr[Qtopia::HomePager] );
115 list.append( mapIdToStr[Qtopia::HomeWebPage] );
116
117 if (sorted) list.sort();
118
119 return list;
120}
121
122
123/*!
124 \internal
125 Returns a translated list of field names for a contact.
126*/
127QStringList OContactFields::trfields( bool sorted )
128{
129 QStringList list;
130 QMap<int, QString> mapIdToStr = idToTrFields();
131
132 list.append( mapIdToStr[Qtopia::Title]);
133 list.append( mapIdToStr[Qtopia::FirstName] );
134 list.append( mapIdToStr[Qtopia::MiddleName] );
135 list.append( mapIdToStr[Qtopia::LastName] );
136 list.append( mapIdToStr[Qtopia::Suffix] );
137 list.append( mapIdToStr[Qtopia::FileAs] );
138
139 list.append( mapIdToStr[Qtopia::JobTitle] );
140 list.append( mapIdToStr[Qtopia::Department] );
141 list.append( mapIdToStr[Qtopia::Company] );
142
143 list += trphonefields( sorted );
144
145 list.append( mapIdToStr[Qtopia::BusinessStreet] );
146 list.append( mapIdToStr[Qtopia::BusinessCity] );
147 list.append( mapIdToStr[Qtopia::BusinessState] );
148 list.append( mapIdToStr[Qtopia::BusinessZip] );
149 list.append( mapIdToStr[Qtopia::BusinessCountry] );
150
151 list.append( mapIdToStr[Qtopia::HomeStreet] );
152 list.append( mapIdToStr[Qtopia::HomeCity] );
153 list.append( mapIdToStr[Qtopia::HomeState] );
154 list.append( mapIdToStr[Qtopia::HomeZip] );
155 list.append( mapIdToStr[Qtopia::HomeCountry] );
156
157 list += trdetailsfields( sorted );
158
159 list.append( mapIdToStr[Qtopia::Notes] );
160 list.append( mapIdToStr[Qtopia::Groups] );
161
162 if (sorted) list.sort();
163
164 return list;
165}
166
167/*!
168 \internal
169 Returns an untranslated list of field names for a contact.
170*/
171QStringList OContactFields::untrfields( bool sorted )
172{
173 QStringList list;
174 QMap<int, QString> mapIdToStr = idToUntrFields();
175
176 list.append( mapIdToStr[ Qtopia::Title ] );
177 list.append( mapIdToStr[ Qtopia::FirstName ] );
178 list.append( mapIdToStr[ Qtopia::MiddleName ] );
179 list.append( mapIdToStr[ Qtopia::LastName ] );
180 list.append( mapIdToStr[ Qtopia::Suffix ] );
181 list.append( mapIdToStr[ Qtopia::FileAs ] );
182
183 list.append( mapIdToStr[ Qtopia::JobTitle ] );
184 list.append( mapIdToStr[ Qtopia::Department ] );
185 list.append( mapIdToStr[ Qtopia::Company ] );
186
187 list += untrphonefields( sorted );
188
189 list.append( mapIdToStr[ Qtopia::BusinessStreet ] );
190 list.append( mapIdToStr[ Qtopia::BusinessCity ] );
191 list.append( mapIdToStr[ Qtopia::BusinessState ] );
192 list.append( mapIdToStr[ Qtopia::BusinessZip ] );
193 list.append( mapIdToStr[ Qtopia::BusinessCountry ] );
194
195 list.append( mapIdToStr[ Qtopia::HomeStreet ] );
196 list.append( mapIdToStr[ Qtopia::HomeCity ] );
197 list.append( mapIdToStr[ Qtopia::HomeState ] );
198 list.append( mapIdToStr[ Qtopia::HomeZip ] );
199 list.append( mapIdToStr[ Qtopia::HomeCountry ] );
200
201 list += untrdetailsfields( sorted );
202
203 list.append( mapIdToStr[ Qtopia::Notes ] );
204 list.append( mapIdToStr[ Qtopia::Groups ] );
205
206 if (sorted) list.sort();
207
208 return list;
209}
210QMap<int, QString> OContactFields::idToTrFields()
211{
212 QMap<int, QString> ret_map;
213
214 ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") );
215 ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) );
216 ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) );
217 ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) );
218 ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" ));
219 ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) );
220
221 ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) );
222 ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) );
223 ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) );
224 ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) );
225 ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) );
226 ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" ));
227
228 // email
229 ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) );
230 ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) );
231
232 ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) );
233 ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) );
234 ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) );
235
236 // business
237 ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) );
238 ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) );
239 ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) );
240 ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) );
241 ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) );
242 ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) );
243 ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) );
244
245 ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) );
246 ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) );
247 ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) );
248 ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) );
249
250 // home
251 ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) );
252 ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) );
253 ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) );
254 ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) );
255 ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) );
256 ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) );
257
258 //personal
259 ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) );
260 ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) );
261 ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) );
262 ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) );
263 ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) );
264 ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) );
265
266 // other
267 ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) );
268
269
270 return ret_map;
271}
272
273QMap<int, QString> OContactFields::idToUntrFields()
274{
275 QMap<int, QString> ret_map;
276
277 ret_map.insert( Qtopia::Title, "Name Title" );
278 ret_map.insert( Qtopia::FirstName, "First Name" );
279 ret_map.insert( Qtopia::MiddleName, "Middle Name" );
280 ret_map.insert( Qtopia::LastName, "Last Name" );
281 ret_map.insert( Qtopia::Suffix, "Suffix" );
282 ret_map.insert( Qtopia::FileAs, "File As" );
283
284 ret_map.insert( Qtopia::JobTitle, "Job Title" );
285 ret_map.insert( Qtopia::Department, "Department" );
286 ret_map.insert( Qtopia::Company, "Company" );
287 ret_map.insert( Qtopia::BusinessPhone, "Business Phone" );
288 ret_map.insert( Qtopia::BusinessFax, "Business Fax" );
289 ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" );
290
291 // email
292 ret_map.insert( Qtopia::DefaultEmail, "Default Email" );
293 ret_map.insert( Qtopia::Emails, "Emails" );
294
295 ret_map.insert( Qtopia::HomePhone, "Home Phone" );
296 ret_map.insert( Qtopia::HomeFax, "Home Fax" );
297 ret_map.insert( Qtopia::HomeMobile, "Home Mobile" );
298
299 // business
300 ret_map.insert( Qtopia::BusinessStreet, "Business Street" );
301 ret_map.insert( Qtopia::BusinessCity, "Business City" );
302 ret_map.insert( Qtopia::BusinessState, "Business State" );
303 ret_map.insert( Qtopia::BusinessZip, "Business Zip" );
304 ret_map.insert( Qtopia::BusinessCountry, "Business Country" );
305 ret_map.insert( Qtopia::BusinessPager, "Business Pager" );
306 ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" );
307
308 ret_map.insert( Qtopia::Office, "Office" );
309 ret_map.insert( Qtopia::Profession, "Profession" );
310 ret_map.insert( Qtopia::Assistant, "Assistant" );
311 ret_map.insert( Qtopia::Manager, "Manager" );
312
313 // home
314 ret_map.insert( Qtopia::HomeStreet, "Home Street" );
315 ret_map.insert( Qtopia::HomeCity, "Home City" );
316 ret_map.insert( Qtopia::HomeState, "Home State" );
317 ret_map.insert( Qtopia::HomeZip, "Home Zip" );
318 ret_map.insert( Qtopia::HomeCountry, "Home Country" );
319 ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" );
320
321 //personal
322 ret_map.insert( Qtopia::Spouse, "Spouse" );
323 ret_map.insert( Qtopia::Gender, "Gender" );
324 ret_map.insert( Qtopia::Birthday, "Birthday" );
325 ret_map.insert( Qtopia::Anniversary, "Anniversary" );
326 ret_map.insert( Qtopia::Nickname, "Nickname" );
327 ret_map.insert( Qtopia::Children, "Children" );
328
329 // other
330 ret_map.insert( Qtopia::Notes, "Notes" );
331
332
333 return ret_map;
334}
335
336QMap<QString, int> OContactFields::trFieldsToId()
337{
338 QMap<int, QString> idtostr = idToTrFields();
339 QMap<QString, int> ret_map;
340
341
342 QMap<int, QString>::Iterator it;
343 for( it = idtostr.begin(); it != idtostr.end(); ++it )
344 ret_map.insert( *it, it.key() );
345
346
347 return ret_map;
348}
349
350QMap<QString, int> OContactFields::untrFieldsToId()
351{
352 QMap<int, QString> idtostr = idToUntrFields();
353 QMap<QString, int> ret_map;
354
355
356 QMap<int, QString>::Iterator it;
357 for( it = idtostr.begin(); it != idtostr.end(); ++it )
358 ret_map.insert( *it, it.key() );
359
360
361 return ret_map;
362}
363
364
365OContactFields::OContactFields():
366 fieldOrder( DEFAULT_FIELD_ORDER ),
367 changedFieldOrder( false )
368{
369 // Get the global field order from the config file and
370 // use it as a start pattern
371 Config cfg ( "AddressBook" );
372 cfg.setGroup( "ContactFieldOrder" );
373 globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER );
374}
375
376OContactFields::~OContactFields(){
377
378 // We will store the fieldorder into the config file
379 // to reuse it for the future..
380 if ( changedFieldOrder ){
381 Config cfg ( "AddressBook" );
382 cfg.setGroup( "ContactFieldOrder" );
383 cfg.writeEntry( "General", globalFieldOrder );
384 }
385}
386
387
388
389void OContactFields::saveToRecord( OContact &cnt ){
390
391 qDebug("ocontactfields saveToRecord: >%s<",fieldOrder.latin1());
392
393 // Store fieldorder into this contact.
394 cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder );
395
396 globalFieldOrder = fieldOrder;
397 changedFieldOrder = true;
398
399}
400
401void OContactFields::loadFromRecord( const OContact &cnt ){
402 qDebug("ocontactfields loadFromRecord");
403 qDebug("loading >%s<",cnt.fullName().latin1());
404
405 // Get fieldorder for this contact. If none is defined,
406 // we will use the global one from the config file..
407
408 fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME );
409
410 qDebug("fieldOrder from contact>%s<",fieldOrder.latin1());
411
412 if (fieldOrder.isEmpty()){
413 fieldOrder = globalFieldOrder;
414 }
415
416
417 qDebug("effective fieldOrder in loadFromRecord >%s<",fieldOrder.latin1());
418}
419
420void OContactFields::setFieldOrder( int num, int index ){
421 qDebug("qcontactfields setfieldorder pos %i -> %i",num,index);
422
423 fieldOrder[num] = QString::number( index, 16 )[0];
424
425 // We will store this new fieldorder globally to
426 // remember it for contacts which have none
427 globalFieldOrder = fieldOrder;
428 changedFieldOrder = true;
429
430 qDebug("fieldOrder >%s<",fieldOrder.latin1());
431}
432
433int OContactFields::getFieldOrder( int num, int defIndex ){
434 qDebug("ocontactfields getFieldOrder");
435 qDebug("fieldOrder >%s<",fieldOrder.latin1());
436
437 // Get index of combo as char..
438 QChar poschar = fieldOrder[num];
439
440 bool ok;
441 int ret = 0;
442 // Convert char to number..
443 if ( !( poschar == QChar::null ) )
444 ret = QString( poschar ).toInt(&ok, 16);
445 else
446 ok = false;
447
448 // Return default value if index for
449 // num was not set or if anything else happened..
450 if ( !ok ) ret = defIndex;
451
452 qDebug("returning >%i<",ret);
453
454 return ret;
455
456}
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 @@
1#ifndef OPIE_CONTACTS_FIELDS
2#define OPIE_CONTACTS_FIELDS
3
4class QStringList;
5
6#include <qmap.h>
7#include <qstring.h>
8#include <opie/ocontact.h>
9
10#define CONTACT_FIELD_ORDER_NAME "opie-contactfield-order"
11#define DEFAULT_FIELD_ORDER "__________"
12
13class OContactFields{
14
15 public:
16 OContactFields();
17 ~OContactFields();
18 /** Set the index for combo boxes.
19 * Sets the <b>index</b> of combo <b>num</b>.
20 * @param num selects the number of the combo
21 * @param index sets the index in the combo
22 */
23 void setFieldOrder( int num, int index );
24
25 /** Get the index for combo boxes.
26 * Returns the index of combo <b>num</b> or defindex
27 * if none was defined..
28 * @param num Selects the number of the combo
29 * @param defIndex will be returned if none was defined (either
30 * globally in the config file, nor by the contact which was used
31 * by loadFromRecord() )
32 */
33 int getFieldOrder( int num, int defIndex);
34
35 /** Store fieldorder to contact. */
36 void saveToRecord( OContact& );
37 /** Get Fieldorder from contact. */
38 void loadFromRecord( const OContact& );
39
40 private:
41 QString fieldOrder;
42 QString globalFieldOrder;
43 bool changedFieldOrder;
44
45 public:
46 static QStringList trphonefields( bool sorted = true );
47 static QStringList untrphonefields( bool sorted = true );
48 static QStringList trdetailsfields( bool sorted = true );
49 static QStringList untrdetailsfields( bool sorted = true );
50 static QStringList trfields( bool sorted = true );
51 static QStringList untrfields( bool sorted = true );
52
53 static QMap<int, QString> idToTrFields();
54 static QMap<QString, int> trFieldsToId();
55 static QMap<int, QString> idToUntrFields();
56 static QMap<QString, int> untrFieldsToId();
57
58};
59
60#endif