summaryrefslogtreecommitdiff
authoreilers <eilers>2002-11-13 14:14:51 (UTC)
committer eilers <eilers>2002-11-13 14:14:51 (UTC)
commit2255284b2e80bdc2881ab9106e9afa614a08c140 (patch) (unidiff)
tree89e53028d842061371e6414ee037f96fa0fbef5e
parenteaecbed44924ece119c5b41db2828b4554f263d2 (diff)
downloadopie-2255284b2e80bdc2881ab9106e9afa614a08c140.zip
opie-2255284b2e80bdc2881ab9106e9afa614a08c140.tar.gz
opie-2255284b2e80bdc2881ab9106e9afa614a08c140.tar.bz2
Added sorted for Contacts..
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontactaccess.cpp8
-rw-r--r--libopie/pim/ocontactaccess.h11
-rw-r--r--libopie/pim/ocontactaccessbackend.h4
-rw-r--r--libopie/pim/ocontactaccessbackend_vcard.cpp10
-rw-r--r--libopie/pim/ocontactaccessbackend_vcard.h4
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.h32
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend.h4
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp10
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_vcard.h4
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.h32
-rw-r--r--libopie2/opiepim/core/ocontactaccess.cpp8
-rw-r--r--libopie2/opiepim/core/ocontactaccess.h11
12 files changed, 138 insertions, 0 deletions
diff --git a/libopie/pim/ocontactaccess.cpp b/libopie/pim/ocontactaccess.cpp
index f868b53..9c9338e 100644
--- a/libopie/pim/ocontactaccess.cpp
+++ b/libopie/pim/ocontactaccess.cpp
@@ -1,161 +1,169 @@
1/* 1/*
2 * Class to manage the Contacts. 2 * Class to manage the Contacts.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * Info: This class could just work with a change in the header-file 12 * Info: This class could just work with a change in the header-file
13 * of the Contact class ! Therefore our libopie only compiles 13 * of the Contact class ! Therefore our libopie only compiles
14 * with our version of libqpe 14 * with our version of libqpe
15 * ===================================================================== 15 * =====================================================================
16 * ToDo: XML-Backend: Automatic reload if something was changed... 16 * ToDo: XML-Backend: Automatic reload if something was changed...
17 * 17 *
18 * 18 *
19 * ===================================================================== 19 * =====================================================================
20 * Version: $Id$ 20 * Version: $Id$
21 * ===================================================================== 21 * =====================================================================
22 * History: 22 * History:
23 * $Log$ 23 * $Log$
24 * Revision 1.7 2002/11/13 14:14:51 eilers
25 * Added sorted for Contacts..
26 *
24 * Revision 1.6 2002/11/01 15:10:42 eilers 27 * Revision 1.6 2002/11/01 15:10:42 eilers
25 * Added regExp-search in database for all fields in a contact. 28 * Added regExp-search in database for all fields in a contact.
26 * 29 *
27 * Revision 1.5 2002/10/16 10:52:40 eilers 30 * Revision 1.5 2002/10/16 10:52:40 eilers
28 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 31 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
29 * 32 *
30 * Revision 1.4 2002/10/14 16:21:54 eilers 33 * Revision 1.4 2002/10/14 16:21:54 eilers
31 * Some minor interface updates 34 * Some minor interface updates
32 * 35 *
33 * Revision 1.3 2002/10/07 17:34:24 eilers 36 * Revision 1.3 2002/10/07 17:34:24 eilers
34 * added OBackendFactory for advanced backend access 37 * added OBackendFactory for advanced backend access
35 * 38 *
36 * Revision 1.2 2002/10/02 16:18:11 eilers 39 * Revision 1.2 2002/10/02 16:18:11 eilers
37 * debugged and seems to work almost perfectly .. 40 * debugged and seems to work almost perfectly ..
38 * 41 *
39 * Revision 1.1 2002/09/27 17:11:44 eilers 42 * Revision 1.1 2002/09/27 17:11:44 eilers
40 * Added API for accessing the Contact-Database ! It is compiling, but 43 * Added API for accessing the Contact-Database ! It is compiling, but
41 * please do not expect that anything is working ! 44 * please do not expect that anything is working !
42 * I will debug that stuff in the next time .. 45 * I will debug that stuff in the next time ..
43 * Please read README_COMPILE for compiling ! 46 * Please read README_COMPILE for compiling !
44 * 47 *
45 * 48 *
46 */ 49 */
47 50
48#include "ocontactaccess.h" 51#include "ocontactaccess.h"
49#include "obackendfactory.h" 52#include "obackendfactory.h"
50 53
51#include <qasciidict.h> 54#include <qasciidict.h>
52#include <qdatetime.h> 55#include <qdatetime.h>
53#include <qfile.h> 56#include <qfile.h>
54#include <qregexp.h> 57#include <qregexp.h>
55#include <qlist.h> 58#include <qlist.h>
56#include <qcopchannel_qws.h> 59#include <qcopchannel_qws.h>
57 60
58//#include <qpe/qcopenvelope_qws.h> 61//#include <qpe/qcopenvelope_qws.h>
59#include <qpe/global.h> 62#include <qpe/global.h>
60 63
61#include <errno.h> 64#include <errno.h>
62#include <fcntl.h> 65#include <fcntl.h>
63#include <unistd.h> 66#include <unistd.h>
64#include <stdlib.h> 67#include <stdlib.h>
65 68
66#include "ocontactaccessbackend_xml.h" 69#include "ocontactaccessbackend_xml.h"
67 70
68 71
69OContactAccess::OContactAccess ( const QString appname, const QString , 72OContactAccess::OContactAccess ( const QString appname, const QString ,
70 OContactAccessBackend* end, bool autosync ): 73 OContactAccessBackend* end, bool autosync ):
71 OPimAccessTemplate<OContact>( end ) 74 OPimAccessTemplate<OContact>( end )
72{ 75{
73 /* take care of the backend. If there is no one defined, we 76 /* take care of the backend. If there is no one defined, we
74 * will use the XML-Backend as default (until we have a cute SQL-Backend..). 77 * will use the XML-Backend as default (until we have a cute SQL-Backend..).
75 */ 78 */
76 if( end == 0 ) { 79 if( end == 0 ) {
77 qWarning ("Using BackendFactory !"); 80 qWarning ("Using BackendFactory !");
78 end = OBackendFactory<OContactAccessBackend>::Default( "contact", appname ); 81 end = OBackendFactory<OContactAccessBackend>::Default( "contact", appname );
79 } 82 }
80 // Set backend locally and in template 83 // Set backend locally and in template
81 m_backEnd = end; 84 m_backEnd = end;
82 OPimAccessTemplate<OContact>::setBackEnd (end); 85 OPimAccessTemplate<OContact>::setBackEnd (end);
83 86
84 87
85 /* Connect signal of external db change to function */ 88 /* Connect signal of external db change to function */
86 QCopChannel *dbchannel = new QCopChannel( "QPE/PIM", this ); 89 QCopChannel *dbchannel = new QCopChannel( "QPE/PIM", this );
87 connect( dbchannel, SIGNAL(received(const QCString &, const QByteArray &)), 90 connect( dbchannel, SIGNAL(received(const QCString &, const QByteArray &)),
88 this, SLOT(copMessage( const QCString &, const QByteArray &)) ); 91 this, SLOT(copMessage( const QCString &, const QByteArray &)) );
89 if ( autosync ){ 92 if ( autosync ){
90 QCopChannel *syncchannel = new QCopChannel( "QPE/Sync", this ); 93 QCopChannel *syncchannel = new QCopChannel( "QPE/Sync", this );
91 connect( syncchannel, SIGNAL(received(const QCString &, const QByteArray &)), 94 connect( syncchannel, SIGNAL(received(const QCString &, const QByteArray &)),
92 this, SLOT(copMessage( const QCString &, const QByteArray &)) ); 95 this, SLOT(copMessage( const QCString &, const QByteArray &)) );
93 } 96 }
94 97
95 98
96} 99}
97OContactAccess::~OContactAccess () 100OContactAccess::~OContactAccess ()
98{ 101{
99 /* The user may forget to save the changed database, therefore try to 102 /* The user may forget to save the changed database, therefore try to
100 * do it for him.. 103 * do it for him..
101 */ 104 */
102 save(); 105 save();
103 // delete m_backEnd; is done by template.. 106 // delete m_backEnd; is done by template..
104} 107}
105 108
106 109
107bool OContactAccess::save () 110bool OContactAccess::save ()
108{ 111{
109 /* If the database was changed externally, we could not save the 112 /* If the database was changed externally, we could not save the
110 * Data. This will remove added items which is unacceptable ! 113 * Data. This will remove added items which is unacceptable !
111 * Therefore: Reload database and merge the data... 114 * Therefore: Reload database and merge the data...
112 */ 115 */
113 if ( OPimAccessTemplate<OContact>::wasChangedExternally() ) 116 if ( OPimAccessTemplate<OContact>::wasChangedExternally() )
114 reload(); 117 reload();
115 118
116 bool status = OPimAccessTemplate<OContact>::save(); 119 bool status = OPimAccessTemplate<OContact>::save();
117 if ( !status ) return false; 120 if ( !status ) return false;
118 121
119 /* Now tell everyone that new data is available. 122 /* Now tell everyone that new data is available.
120 */ 123 */
121 QCopEnvelope e( "QPE/PIM", "addressbookUpdated()" ); 124 QCopEnvelope e( "QPE/PIM", "addressbookUpdated()" );
122 125
123 return true; 126 return true;
124} 127}
125 128
126ORecordList<OContact> OContactAccess::matchRegexp( const QRegExp &r ) const{ 129ORecordList<OContact> OContactAccess::matchRegexp( const QRegExp &r ) const{
127 QArray<int> matchingContacts = m_backEnd -> matchRegexp( r ); 130 QArray<int> matchingContacts = m_backEnd -> matchRegexp( r );
128 return ( ORecordList<OContact>(matchingContacts, this) ); 131 return ( ORecordList<OContact>(matchingContacts, this) );
129} 132}
130 133
131const uint OContactAccess::querySettings() 134const uint OContactAccess::querySettings()
132{ 135{
133 return ( m_backEnd->querySettings() ); 136 return ( m_backEnd->querySettings() );
134} 137}
135 138
136bool OContactAccess::hasQuerySettings ( int querySettings ) const 139bool OContactAccess::hasQuerySettings ( int querySettings ) const
137{ 140{
138 return ( m_backEnd->hasQuerySettings ( querySettings ) ); 141 return ( m_backEnd->hasQuerySettings ( querySettings ) );
139} 142}
143ORecordList<OContact> OContactAccess::sorted( bool ascending, int sortOrder, int sortFilter, int cat ) const
144{
145 QArray<int> matchingContacts = m_backEnd -> sorted( ascending, sortOrder, sortFilter, cat );
146 return ( ORecordList<OContact>(matchingContacts, this) );
147}
140 148
141 149
142bool OContactAccess::wasChangedExternally()const 150bool OContactAccess::wasChangedExternally()const
143{ 151{
144 return ( m_backEnd->wasChangedExternally() ); 152 return ( m_backEnd->wasChangedExternally() );
145} 153}
146 154
147 155
148void OContactAccess::copMessage( const QCString &msg, const QByteArray & ) 156void OContactAccess::copMessage( const QCString &msg, const QByteArray & )
149{ 157{
150 if ( msg == "addressbookUpdated()" ){ 158 if ( msg == "addressbookUpdated()" ){
151 qWarning ("OContactAccess: Received addressbokUpdated()"); 159 qWarning ("OContactAccess: Received addressbokUpdated()");
152 emit signalChanged ( this ); 160 emit signalChanged ( this );
153 } else if ( msg == "flush()" ) { 161 } else if ( msg == "flush()" ) {
154 qWarning ("OContactAccess: Received flush()"); 162 qWarning ("OContactAccess: Received flush()");
155 save (); 163 save ();
156 } else if ( msg == "reload()" ) { 164 } else if ( msg == "reload()" ) {
157 qWarning ("OContactAccess: Received reload()"); 165 qWarning ("OContactAccess: Received reload()");
158 reload (); 166 reload ();
159 emit signalChanged ( this ); 167 emit signalChanged ( this );
160 } 168 }
161} 169}
diff --git a/libopie/pim/ocontactaccess.h b/libopie/pim/ocontactaccess.h
index b4921d5..961968f 100644
--- a/libopie/pim/ocontactaccess.h
+++ b/libopie/pim/ocontactaccess.h
@@ -1,139 +1,150 @@
1/* 1/*
2 * Class to manage the Contacts. 2 * Class to manage the Contacts.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) 5 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org)
6 * 6 *
7 * ===================================================================== 7 * =====================================================================
8 *This program is free software; you can redistribute it and/or 8 *This program is free software; you can redistribute it and/or
9 *modify it under the terms of the GNU Library General Public 9 *modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; 10 * License as published by the Free Software Foundation;
11 * either version 2 of the License, or (at your option) any later 11 * either version 2 of the License, or (at your option) any later
12 * version. 12 * version.
13 * ===================================================================== 13 * =====================================================================
14 * ToDo: Define enum for query settings 14 * ToDo: Define enum for query settings
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.5 2002/11/13 14:14:51 eilers
21 * Added sorted for Contacts..
22 *
20 * Revision 1.4 2002/11/01 15:10:42 eilers 23 * Revision 1.4 2002/11/01 15:10:42 eilers
21 * Added regExp-search in database for all fields in a contact. 24 * Added regExp-search in database for all fields in a contact.
22 * 25 *
23 * Revision 1.3 2002/10/16 10:52:40 eilers 26 * Revision 1.3 2002/10/16 10:52:40 eilers
24 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 27 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
25 * 28 *
26 * Revision 1.2 2002/10/14 16:21:54 eilers 29 * Revision 1.2 2002/10/14 16:21:54 eilers
27 * Some minor interface updates 30 * Some minor interface updates
28 * 31 *
29 * Revision 1.1 2002/09/27 17:11:44 eilers 32 * Revision 1.1 2002/09/27 17:11:44 eilers
30 * Added API for accessing the Contact-Database ! It is compiling, but 33 * Added API for accessing the Contact-Database ! It is compiling, but
31 * please do not expect that anything is working ! 34 * please do not expect that anything is working !
32 * I will debug that stuff in the next time .. 35 * I will debug that stuff in the next time ..
33 * Please read README_COMPILE for compiling ! 36 * Please read README_COMPILE for compiling !
34 * 37 *
35 * ===================================================================== 38 * =====================================================================
36 */ 39 */
37#ifndef _OCONTACTACCESS_H 40#ifndef _OCONTACTACCESS_H
38#define _OCONTACTACCESS_H 41#define _OCONTACTACCESS_H
39 42
40#include <qobject.h> 43#include <qobject.h>
41 44
42#include <qpe/qcopenvelope_qws.h> 45#include <qpe/qcopenvelope_qws.h>
43 46
44#include <qvaluelist.h> 47#include <qvaluelist.h>
45#include <qfileinfo.h> 48#include <qfileinfo.h>
46 49
47#include "ocontact.h" 50#include "ocontact.h"
48#include "ocontactaccessbackend.h" 51#include "ocontactaccessbackend.h"
49#include "opimaccesstemplate.h" 52#include "opimaccesstemplate.h"
50 53
51/** Class to access the contacts database. 54/** Class to access the contacts database.
52 * This is just a frontend for the real database handling which is 55 * This is just a frontend for the real database handling which is
53 * done by the backend. 56 * done by the backend.
54 * @see OPimAccessTemplate 57 * @see OPimAccessTemplate
55 */ 58 */
56class OContactAccess: public QObject, public OPimAccessTemplate<OContact> 59class OContactAccess: public QObject, public OPimAccessTemplate<OContact>
57{ 60{
58 Q_OBJECT 61 Q_OBJECT
59 62
60 public: 63 public:
61 /** Create Database with contacts (addressbook). 64 /** Create Database with contacts (addressbook).
62 * @param appname Name of application which wants access to the database 65 * @param appname Name of application which wants access to the database
63 * (i.e. "todolist") 66 * (i.e. "todolist")
64 * @param filename The name of the database file. If not set, the default one 67 * @param filename The name of the database file. If not set, the default one
65 * is used. 68 * is used.
66 * @param backend Pointer to an alternative Backend. If not set, we will use 69 * @param backend Pointer to an alternative Backend. If not set, we will use
67 * the default backend. 70 * the default backend.
68 * @param handlesync If <b>true</b> the database stores the current state 71 * @param handlesync If <b>true</b> the database stores the current state
69 * automatically if it receives the signals <i>flush()</i> and <i>reload()</i> 72 * automatically if it receives the signals <i>flush()</i> and <i>reload()</i>
70 * which are used before and after synchronisation. If the application wants 73 * which are used before and after synchronisation. If the application wants
71 * to react itself, it should be disabled by setting it to <b>false</b> 74 * to react itself, it should be disabled by setting it to <b>false</b>
72 * @see OContactAccessBackend 75 * @see OContactAccessBackend
73 */ 76 */
74 OContactAccess (const QString appname, const QString filename = 0l, 77 OContactAccess (const QString appname, const QString filename = 0l,
75 OContactAccessBackend* backend = 0l, bool handlesync = true); 78 OContactAccessBackend* backend = 0l, bool handlesync = true);
76 ~OContactAccess (); 79 ~OContactAccess ();
77 80
78 /** Constants for query. 81 /** Constants for query.
79 * Use this constants to set the query parameters. 82 * Use this constants to set the query parameters.
80 * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes ! 83 * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes !
81 * @see queryByExample() 84 * @see queryByExample()
82 */ 85 */
83 enum QuerySettings { 86 enum QuerySettings {
84 WildCards = 0x0001, 87 WildCards = 0x0001,
85 IgnoreCase = 0x0002, 88 IgnoreCase = 0x0002,
86 RegExp = 0x0004, 89 RegExp = 0x0004,
87 ExactMatch = 0x0008, 90 ExactMatch = 0x0008,
88 MatchOne = 0x0010 // Only one Entry must match 91 MatchOne = 0x0010 // Only one Entry must match
89 }; 92 };
90 93
91 94
92 ORecordList<OContact> matchRegexp( const QRegExp &r )const; 95 ORecordList<OContact> matchRegexp( const QRegExp &r )const;
93 96
97 /** Return all Contacts in a sorted manner.
98 * @param ascending true: Sorted in acending order.
99 * @param sortOrder Currently not implemented. Just defined to stay compatible to otodoaccess
100 * @param sortFilter Currently not implemented. Just defined to stay compatible to otodoaccess
101 * @param cat Currently not implemented. Just defined to stay compatible to otodoaccess
102 */
103 List sorted( bool ascending, int sortOrder, int sortFilter, int cat ) const;
104
94 /** Return all possible settings. 105 /** Return all possible settings.
95 * @return All settings provided by the current backend 106 * @return All settings provided by the current backend
96 * (i.e.: query_WildCards & query_IgnoreCase) 107 * (i.e.: query_WildCards & query_IgnoreCase)
97 */ 108 */
98 const uint querySettings(); 109 const uint querySettings();
99 110
100 /** Check whether settings are correct. 111 /** Check whether settings are correct.
101 * @return <i>true</i> if the given settings are correct and possible. 112 * @return <i>true</i> if the given settings are correct and possible.
102 */ 113 */
103 bool hasQuerySettings ( int querySettings ) const; 114 bool hasQuerySettings ( int querySettings ) const;
104 115
105 /** 116 /**
106 * if the resource was changed externally. 117 * if the resource was changed externally.
107 * You should use the signal instead of polling possible changes ! 118 * You should use the signal instead of polling possible changes !
108 */ 119 */
109 bool wasChangedExternally()const; 120 bool wasChangedExternally()const;
110 121
111 122
112 /** Save contacts database. 123 /** Save contacts database.
113 * Save is more a "commit". After calling this function, all changes are public available. 124 * Save is more a "commit". After calling this function, all changes are public available.
114 * @return true if successful 125 * @return true if successful
115 */ 126 */
116 bool save(); 127 bool save();
117 128
118 signals: 129 signals:
119 /* Signal is emitted if the database was changed. Therefore 130 /* Signal is emitted if the database was changed. Therefore
120 * we may need to reload to stay consistent. 131 * we may need to reload to stay consistent.
121 * @param which Pointer to the database who created this event. This pointer 132 * @param which Pointer to the database who created this event. This pointer
122 * is useful if an application has to handle multiple databases at the same time. 133 * is useful if an application has to handle multiple databases at the same time.
123 * @see reload() 134 * @see reload()
124 */ 135 */
125 void signalChanged ( const OContactAccess *which ); 136 void signalChanged ( const OContactAccess *which );
126 137
127 138
128 private: 139 private:
129 // class OContactAccessPrivate; 140 // class OContactAccessPrivate;
130 // OContactAccessPrivate* d; 141 // OContactAccessPrivate* d;
131 OContactAccessBackend *m_backEnd; 142 OContactAccessBackend *m_backEnd;
132 bool m_loading:1; 143 bool m_loading:1;
133 144
134 private slots: 145 private slots:
135 void copMessage( const QCString &msg, const QByteArray &data ); 146 void copMessage( const QCString &msg, const QByteArray &data );
136 147
137 148
138}; 149};
139#endif 150#endif
diff --git a/libopie/pim/ocontactaccessbackend.h b/libopie/pim/ocontactaccessbackend.h
index c898f61..821f5bf 100644
--- a/libopie/pim/ocontactaccessbackend.h
+++ b/libopie/pim/ocontactaccessbackend.h
@@ -1,81 +1,85 @@
1/** 1/**
2 * The class responsible for managing a backend. 2 * The class responsible for managing a backend.
3 * The implementation of this abstract class contains 3 * The implementation of this abstract class contains
4 * the complete database handling. 4 * the complete database handling.
5 * 5 *
6 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 6 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
7 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) 7 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org)
8 * 8 *
9 * ===================================================================== 9 * =====================================================================
10 *This program is free software; you can redistribute it and/or 10 *This program is free software; you can redistribute it and/or
11 *modify it under the terms of the GNU Library General Public 11 *modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; 12 * License as published by the Free Software Foundation;
13 * either version 2 of the License, or (at your option) any later 13 * either version 2 of the License, or (at your option) any later
14 * version. 14 * version.
15 * ===================================================================== 15 * =====================================================================
16 * ToDo: Define enum for query settings 16 * ToDo: Define enum for query settings
17 * ===================================================================== 17 * =====================================================================
18 * Version: $Id$ 18 * Version: $Id$
19 * ===================================================================== 19 * =====================================================================
20 * History: 20 * History:
21 * $Log$ 21 * $Log$
22 * Revision 1.4 2002/11/13 14:14:51 eilers
23 * Added sorted for Contacts..
24 *
22 * Revision 1.3 2002/11/01 15:10:42 eilers 25 * Revision 1.3 2002/11/01 15:10:42 eilers
23 * Added regExp-search in database for all fields in a contact. 26 * Added regExp-search in database for all fields in a contact.
24 * 27 *
25 * Revision 1.2 2002/10/07 17:34:24 eilers 28 * Revision 1.2 2002/10/07 17:34:24 eilers
26 * added OBackendFactory for advanced backend access 29 * added OBackendFactory for advanced backend access
27 * 30 *
28 * Revision 1.1 2002/09/27 17:11:44 eilers 31 * Revision 1.1 2002/09/27 17:11:44 eilers
29 * Added API for accessing the Contact-Database ! It is compiling, but 32 * Added API for accessing the Contact-Database ! It is compiling, but
30 * please do not expect that anything is working ! 33 * please do not expect that anything is working !
31 * I will debug that stuff in the next time .. 34 * I will debug that stuff in the next time ..
32 * Please read README_COMPILE for compiling ! 35 * Please read README_COMPILE for compiling !
33 * 36 *
34 * ===================================================================== 37 * =====================================================================
35 * 38 *
36 */ 39 */
37 40
38#ifndef _OCONTACTACCESSBACKEND_H_ 41#ifndef _OCONTACTACCESSBACKEND_H_
39#define _OCONTACTACCESSBACKEND_H_ 42#define _OCONTACTACCESSBACKEND_H_
40 43
41#include "ocontact.h" 44#include "ocontact.h"
42#include "opimaccessbackend.h" 45#include "opimaccessbackend.h"
43 46
44#include "qregexp.h" 47#include "qregexp.h"
45 48
46class OContactAccessBackend: public OPimAccessBackend<OContact> { 49class OContactAccessBackend: public OPimAccessBackend<OContact> {
47 public: 50 public:
48 OContactAccessBackend() {} 51 OContactAccessBackend() {}
49 virtual ~OContactAccessBackend() {} 52 virtual ~OContactAccessBackend() {}
50 53
51 54
52 /** Return if database was changed externally. 55 /** Return if database was changed externally.
53 * This may just make sense on file based databases like a XML-File. 56 * This may just make sense on file based databases like a XML-File.
54 * It is used to prevent to overwrite the current database content 57 * It is used to prevent to overwrite the current database content
55 * if the file was already changed by something else ! 58 * if the file was already changed by something else !
56 * If this happens, we have to reload before save our data. 59 * If this happens, we have to reload before save our data.
57 * If we use real databases, this should be handled by the database 60 * If we use real databases, this should be handled by the database
58 * management system themselve, therefore this function should always return false in 61 * management system themselve, therefore this function should always return false in
59 * this case. It is not our problem to handle this conflict ... 62 * this case. It is not our problem to handle this conflict ...
60 * @return <i>true</i> if the database was changed and if save without reload will 63 * @return <i>true</i> if the database was changed and if save without reload will
61 * be dangerous. <i>false</i> if the database was not changed or it is save to write 64 * be dangerous. <i>false</i> if the database was not changed or it is save to write
62 * in this situation. 65 * in this situation.
63 */ 66 */
64 virtual bool wasChangedExternally() = 0; 67 virtual bool wasChangedExternally() = 0;
65 68
66 virtual QArray<int> matchRegexp( const QRegExp &r ) const = 0; 69 virtual QArray<int> matchRegexp( const QRegExp &r ) const = 0;
67 70
68 /** Return all possible settings. 71 /** Return all possible settings.
69 * @return All settings provided by the current backend 72 * @return All settings provided by the current backend
70 * (i.e.: query_WildCards & query_IgnoreCase) 73 * (i.e.: query_WildCards & query_IgnoreCase)
71 */ 74 */
72 virtual const uint querySettings() = 0; 75 virtual const uint querySettings() = 0;
73 76
74 /** Check whether settings are correct. 77 /** Check whether settings are correct.
75 * @return <i>true</i> if the given settings are correct and possible. 78 * @return <i>true</i> if the given settings are correct and possible.
76 */ 79 */
77 virtual bool hasQuerySettings (uint querySettings) const = 0; 80 virtual bool hasQuerySettings (uint querySettings) const = 0;
78 81
82 virtual QArray<int> sorted( bool ascending, int sortOrder, int sortFilter, int cat ) = 0;
79 83
80}; 84};
81#endif 85#endif
diff --git a/libopie/pim/ocontactaccessbackend_vcard.cpp b/libopie/pim/ocontactaccessbackend_vcard.cpp
index faa72b4..09ae37b 100644
--- a/libopie/pim/ocontactaccessbackend_vcard.cpp
+++ b/libopie/pim/ocontactaccessbackend_vcard.cpp
@@ -1,372 +1,382 @@
1/* 1/*
2 * VCard Backend for the OPIE-Contact Database. 2 * VCard Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (C) 2000 Trolltech AS. All rights reserved. 4 * Copyright (C) 2000 Trolltech AS. All rights reserved.
5 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 5 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
6 * 6 *
7 * ===================================================================== 7 * =====================================================================
8 *This program is free software; you can redistribute it and/or 8 *This program is free software; you can redistribute it and/or
9 *modify it under the terms of the GNU Library General Public 9 *modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version. 11 * version 2 of the License, or (at your option) any later version.
12 * ===================================================================== 12 * =====================================================================
13 * ToDo: 13 * ToDo:
14 * 14 *
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.4 2002/11/13 14:14:51 eilers
21 * Added sorted for Contacts..
22 *
20 * Revision 1.3 2002/11/11 16:41:09 kergoth 23 * Revision 1.3 2002/11/11 16:41:09 kergoth
21 * no default arguments in implementation 24 * no default arguments in implementation
22 * 25 *
23 * Revision 1.2 2002/11/10 15:41:53 eilers 26 * Revision 1.2 2002/11/10 15:41:53 eilers
24 * Bugfixes.. 27 * Bugfixes..
25 * 28 *
26 * Revision 1.1 2002/11/09 14:34:52 eilers 29 * Revision 1.1 2002/11/09 14:34:52 eilers
27 * Added VCard Backend. 30 * Added VCard Backend.
28 * 31 *
29 */ 32 */
30#include "ocontactaccessbackend_vcard.h" 33#include "ocontactaccessbackend_vcard.h"
31#include "../../library/backend/vobject_p.h" 34#include "../../library/backend/vobject_p.h"
32#include "../../library/backend/qfiledirect_p.h" 35#include "../../library/backend/qfiledirect_p.h"
33 36
34#include <qpe/timeconversion.h> 37#include <qpe/timeconversion.h>
35 38
36#include <qfile.h> 39#include <qfile.h>
37 40
38OContactAccessBackend_VCard::OContactAccessBackend_VCard ( QString , QString filename ): 41OContactAccessBackend_VCard::OContactAccessBackend_VCard ( QString , QString filename ):
39 m_dirty( false ), 42 m_dirty( false ),
40 m_file( filename ) 43 m_file( filename )
41{ 44{
42 load(); 45 load();
43} 46}
44 47
45 48
46bool OContactAccessBackend_VCard::load () 49bool OContactAccessBackend_VCard::load ()
47{ 50{
48 m_map.clear(); 51 m_map.clear();
49 m_dirty = false; 52 m_dirty = false;
50 53
51 VObject* obj = 0l; 54 VObject* obj = 0l;
52 obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); 55 obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() );
53 if ( !obj ) 56 if ( !obj )
54 return false; 57 return false;
55 58
56 while ( obj ) { 59 while ( obj ) {
57 OContact con = parseVObject( obj ); 60 OContact con = parseVObject( obj );
58 /* 61 /*
59 * if uid is 0 assign a new one 62 * if uid is 0 assign a new one
60 * this at least happens on 63 * this at least happens on
61 * Nokia6210 64 * Nokia6210
62 */ 65 */
63 if ( con.uid() == 0 ){ 66 if ( con.uid() == 0 ){
64 con.setUid( 1 ); 67 con.setUid( 1 );
65 qWarning("assigned new uid %d",con.uid() ); 68 qWarning("assigned new uid %d",con.uid() );
66 } 69 }
67 70
68 m_map.insert( con.uid(), con ); 71 m_map.insert( con.uid(), con );
69 72
70 VObject *t = obj; 73 VObject *t = obj;
71 obj = nextVObjectInList(obj); 74 obj = nextVObjectInList(obj);
72 cleanVObject( t ); 75 cleanVObject( t );
73 } 76 }
74 77
75 return true; 78 return true;
76 79
77} 80}
78bool OContactAccessBackend_VCard::reload() 81bool OContactAccessBackend_VCard::reload()
79{ 82{
80 return load(); 83 return load();
81} 84}
82bool OContactAccessBackend_VCard::save() 85bool OContactAccessBackend_VCard::save()
83{ 86{
84 if (!m_dirty ) 87 if (!m_dirty )
85 return true; 88 return true;
86 89
87 QFileDirect file( m_file ); 90 QFileDirect file( m_file );
88 if (!file.open(IO_WriteOnly ) ) 91 if (!file.open(IO_WriteOnly ) )
89 return false; 92 return false;
90 93
91 VObject *obj; 94 VObject *obj;
92 obj = newVObject( VCCalProp ); 95 obj = newVObject( VCCalProp );
93 addPropValue( obj, VCVersionProp, "1.0" ); 96 addPropValue( obj, VCVersionProp, "1.0" );
94 97
95 VObject *vo; 98 VObject *vo;
96 for(QMap<int, OContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ 99 for(QMap<int, OContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){
97 vo = createVObject( *it ); 100 vo = createVObject( *it );
98 writeVObject( file.directHandle() , vo ); 101 writeVObject( file.directHandle() , vo );
99 cleanVObject( vo ); 102 cleanVObject( vo );
100 } 103 }
101 cleanStrTbl(); 104 cleanStrTbl();
102 105
103 m_dirty = false; 106 m_dirty = false;
104 return true; 107 return true;
105 108
106 109
107} 110}
108void OContactAccessBackend_VCard::clear () 111void OContactAccessBackend_VCard::clear ()
109{ 112{
110 m_map.clear(); 113 m_map.clear();
111 m_dirty = true; // ??? sure ? (se) 114 m_dirty = true; // ??? sure ? (se)
112} 115}
113 116
114bool OContactAccessBackend_VCard::add ( const OContact& newcontact ) 117bool OContactAccessBackend_VCard::add ( const OContact& newcontact )
115{ 118{
116 m_map.insert( newcontact.uid(), newcontact ); 119 m_map.insert( newcontact.uid(), newcontact );
117 m_dirty = true; 120 m_dirty = true;
118 return true; 121 return true;
119} 122}
120 123
121bool OContactAccessBackend_VCard::remove ( int uid ) 124bool OContactAccessBackend_VCard::remove ( int uid )
122{ 125{
123 m_map.remove( uid ); 126 m_map.remove( uid );
124 m_dirty = true; 127 m_dirty = true;
125 return true; 128 return true;
126} 129}
127 130
128bool OContactAccessBackend_VCard::replace ( const OContact &contact ) 131bool OContactAccessBackend_VCard::replace ( const OContact &contact )
129{ 132{
130 m_map.replace( contact.uid(), contact ); 133 m_map.replace( contact.uid(), contact );
131 m_dirty = true; 134 m_dirty = true;
132 return true; 135 return true;
133} 136}
134 137
135OContact OContactAccessBackend_VCard::find ( int uid ) const 138OContact OContactAccessBackend_VCard::find ( int uid ) const
136{ 139{
137 return m_map[uid]; 140 return m_map[uid];
138} 141}
139 142
140QArray<int> OContactAccessBackend_VCard::allRecords() const 143QArray<int> OContactAccessBackend_VCard::allRecords() const
141{ 144{
142 QArray<int> ar( m_map.count() ); 145 QArray<int> ar( m_map.count() );
143 QMap<int, OContact>::ConstIterator it; 146 QMap<int, OContact>::ConstIterator it;
144 int i = 0; 147 int i = 0;
145 for ( it = m_map.begin(); it != m_map.end(); ++it ) { 148 for ( it = m_map.begin(); it != m_map.end(); ++it ) {
146 ar[i] = it.key(); 149 ar[i] = it.key();
147 i++; 150 i++;
148 } 151 }
149 return ar; 152 return ar;
150} 153}
151 154
152// Not implemented 155// Not implemented
153QArray<int> OContactAccessBackend_VCard::queryByExample ( const OContact&, int ) 156QArray<int> OContactAccessBackend_VCard::queryByExample ( const OContact&, int )
154{ 157{
155 QArray<int> ar(0); 158 QArray<int> ar(0);
156 return ar; 159 return ar;
157} 160}
158 161
159// Not implemented 162// Not implemented
160QArray<int> OContactAccessBackend_VCard::matchRegexp( const QRegExp& ) const 163QArray<int> OContactAccessBackend_VCard::matchRegexp( const QRegExp& ) const
161{ 164{
162 QArray<int> ar(0); 165 QArray<int> ar(0);
163 return ar; 166 return ar;
164} 167}
165 168
166const uint OContactAccessBackend_VCard::querySettings() 169const uint OContactAccessBackend_VCard::querySettings()
167{ 170{
168 return 0; // No search possible 171 return 0; // No search possible
169} 172}
170 173
171bool OContactAccessBackend_VCard::hasQuerySettings (uint ) const 174bool OContactAccessBackend_VCard::hasQuerySettings (uint ) const
172{ 175{
173 return false; // No search possible, therefore all settings invalid ;) 176 return false; // No search possible, therefore all settings invalid ;)
174} 177}
175 178
176bool OContactAccessBackend_VCard::wasChangedExternally() 179bool OContactAccessBackend_VCard::wasChangedExternally()
177{ 180{
178 return false; // Don't expect concurrent access 181 return false; // Don't expect concurrent access
179} 182}
180 183
184// Not implemented
185QArray<int> OContactAccessBackend_VCard::sorted( bool , int, int, int )
186{
187 QArray<int> ar(0);
188 return ar;
189}
190
181// *** Private stuff *** 191// *** Private stuff ***
182 192
183 193
184OContact OContactAccessBackend_VCard::parseVObject( VObject *obj ) 194OContact OContactAccessBackend_VCard::parseVObject( VObject *obj )
185{ 195{
186 OContact c; 196 OContact c;
187 197
188 VObjectIterator it; 198 VObjectIterator it;
189 initPropIterator( &it, obj ); 199 initPropIterator( &it, obj );
190 while( moreIteration( &it ) ) { 200 while( moreIteration( &it ) ) {
191 VObject *o = nextVObject( &it ); 201 VObject *o = nextVObject( &it );
192 QCString name = vObjectName( o ); 202 QCString name = vObjectName( o );
193 QCString value = vObjectStringZValue( o ); 203 QCString value = vObjectStringZValue( o );
194 if ( name == VCNameProp ) { 204 if ( name == VCNameProp ) {
195 VObjectIterator nit; 205 VObjectIterator nit;
196 initPropIterator( &nit, o ); 206 initPropIterator( &nit, o );
197 while( moreIteration( &nit ) ) { 207 while( moreIteration( &nit ) ) {
198 VObject *o = nextVObject( &nit ); 208 VObject *o = nextVObject( &nit );
199 QCString name = vObjectTypeInfo( o ); 209 QCString name = vObjectTypeInfo( o );
200 QString value = vObjectStringZValue( o ); 210 QString value = vObjectStringZValue( o );
201 if ( name == VCNamePrefixesProp ) 211 if ( name == VCNamePrefixesProp )
202 c.setTitle( value ); 212 c.setTitle( value );
203 else if ( name == VCNameSuffixesProp ) 213 else if ( name == VCNameSuffixesProp )
204 c.setSuffix( value ); 214 c.setSuffix( value );
205 else if ( name == VCFamilyNameProp ) 215 else if ( name == VCFamilyNameProp )
206 c.setLastName( value ); 216 c.setLastName( value );
207 else if ( name == VCGivenNameProp ) 217 else if ( name == VCGivenNameProp )
208 c.setFirstName( value ); 218 c.setFirstName( value );
209 else if ( name == VCAdditionalNamesProp ) 219 else if ( name == VCAdditionalNamesProp )
210 c.setMiddleName( value ); 220 c.setMiddleName( value );
211 } 221 }
212 } 222 }
213 else if ( name == VCAdrProp ) { 223 else if ( name == VCAdrProp ) {
214 bool work = TRUE; // default address is work address 224 bool work = TRUE; // default address is work address
215 QString street; 225 QString street;
216 QString city; 226 QString city;
217 QString region; 227 QString region;
218 QString postal; 228 QString postal;
219 QString country; 229 QString country;
220 230
221 VObjectIterator nit; 231 VObjectIterator nit;
222 initPropIterator( &nit, o ); 232 initPropIterator( &nit, o );
223 while( moreIteration( &nit ) ) { 233 while( moreIteration( &nit ) ) {
224 VObject *o = nextVObject( &nit ); 234 VObject *o = nextVObject( &nit );
225 QCString name = vObjectName( o ); 235 QCString name = vObjectName( o );
226 QString value = vObjectStringZValue( o ); 236 QString value = vObjectStringZValue( o );
227 if ( name == VCHomeProp ) 237 if ( name == VCHomeProp )
228 work = FALSE; 238 work = FALSE;
229 else if ( name == VCWorkProp ) 239 else if ( name == VCWorkProp )
230 work = TRUE; 240 work = TRUE;
231 else if ( name == VCStreetAddressProp ) 241 else if ( name == VCStreetAddressProp )
232 street = value; 242 street = value;
233 else if ( name == VCCityProp ) 243 else if ( name == VCCityProp )
234 city = value; 244 city = value;
235 else if ( name == VCRegionProp ) 245 else if ( name == VCRegionProp )
236 region = value; 246 region = value;
237 else if ( name == VCPostalCodeProp ) 247 else if ( name == VCPostalCodeProp )
238 postal = value; 248 postal = value;
239 else if ( name == VCCountryNameProp ) 249 else if ( name == VCCountryNameProp )
240 country = value; 250 country = value;
241 } 251 }
242 if ( work ) { 252 if ( work ) {
243 c.setBusinessStreet( street ); 253 c.setBusinessStreet( street );
244 c.setBusinessCity( city ); 254 c.setBusinessCity( city );
245 c.setBusinessCountry( country ); 255 c.setBusinessCountry( country );
246 c.setBusinessZip( postal ); 256 c.setBusinessZip( postal );
247 c.setBusinessState( region ); 257 c.setBusinessState( region );
248 } else { 258 } else {
249 c.setHomeStreet( street ); 259 c.setHomeStreet( street );
250 c.setHomeCity( city ); 260 c.setHomeCity( city );
251 c.setHomeCountry( country ); 261 c.setHomeCountry( country );
252 c.setHomeZip( postal ); 262 c.setHomeZip( postal );
253 c.setHomeState( region ); 263 c.setHomeState( region );
254 } 264 }
255 } 265 }
256 else if ( name == VCTelephoneProp ) { 266 else if ( name == VCTelephoneProp ) {
257 enum { 267 enum {
258 HOME = 0x01, 268 HOME = 0x01,
259 WORK = 0x02, 269 WORK = 0x02,
260 VOICE = 0x04, 270 VOICE = 0x04,
261 CELL = 0x08, 271 CELL = 0x08,
262 FAX = 0x10, 272 FAX = 0x10,
263 PAGER = 0x20, 273 PAGER = 0x20,
264 UNKNOWN = 0x80 274 UNKNOWN = 0x80
265 }; 275 };
266 int type = 0; 276 int type = 0;
267 277
268 VObjectIterator nit; 278 VObjectIterator nit;
269 initPropIterator( &nit, o ); 279 initPropIterator( &nit, o );
270 while( moreIteration( &nit ) ) { 280 while( moreIteration( &nit ) ) {
271 VObject *o = nextVObject( &nit ); 281 VObject *o = nextVObject( &nit );
272 QCString name = vObjectTypeInfo( o ); 282 QCString name = vObjectTypeInfo( o );
273 if ( name == VCHomeProp ) 283 if ( name == VCHomeProp )
274 type |= HOME; 284 type |= HOME;
275 else if ( name == VCWorkProp ) 285 else if ( name == VCWorkProp )
276 type |= WORK; 286 type |= WORK;
277 else if ( name == VCVoiceProp ) 287 else if ( name == VCVoiceProp )
278 type |= VOICE; 288 type |= VOICE;
279 else if ( name == VCCellularProp ) 289 else if ( name == VCCellularProp )
280 type |= CELL; 290 type |= CELL;
281 else if ( name == VCFaxProp ) 291 else if ( name == VCFaxProp )
282 type |= FAX; 292 type |= FAX;
283 else if ( name == VCPagerProp ) 293 else if ( name == VCPagerProp )
284 type |= PAGER; 294 type |= PAGER;
285 else if ( name == VCPreferredProp ) 295 else if ( name == VCPreferredProp )
286 ; 296 ;
287 else 297 else
288 type |= UNKNOWN; 298 type |= UNKNOWN;
289 } 299 }
290 if ( (type & UNKNOWN) != UNKNOWN ) { 300 if ( (type & UNKNOWN) != UNKNOWN ) {
291 if ( ( type & (HOME|WORK) ) == 0 ) // default 301 if ( ( type & (HOME|WORK) ) == 0 ) // default
292 type |= HOME; 302 type |= HOME;
293 if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default 303 if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default
294 type |= VOICE; 304 type |= VOICE;
295 305
296 if ( (type & (VOICE|HOME) ) == (VOICE|HOME) ) 306 if ( (type & (VOICE|HOME) ) == (VOICE|HOME) )
297 c.setHomePhone( value ); 307 c.setHomePhone( value );
298 if ( ( type & (FAX|HOME) ) == (FAX|HOME) ) 308 if ( ( type & (FAX|HOME) ) == (FAX|HOME) )
299 c.setHomeFax( value ); 309 c.setHomeFax( value );
300 if ( ( type & (CELL|HOME) ) == (CELL|HOME) ) 310 if ( ( type & (CELL|HOME) ) == (CELL|HOME) )
301 c.setHomeMobile( value ); 311 c.setHomeMobile( value );
302 if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) ) 312 if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) )
303 c.setBusinessPhone( value ); 313 c.setBusinessPhone( value );
304 if ( ( type & (FAX|WORK) ) == (FAX|WORK) ) 314 if ( ( type & (FAX|WORK) ) == (FAX|WORK) )
305 c.setBusinessFax( value ); 315 c.setBusinessFax( value );
306 if ( ( type & (CELL|WORK) ) == (CELL|WORK) ) 316 if ( ( type & (CELL|WORK) ) == (CELL|WORK) )
307 c.setBusinessMobile( value ); 317 c.setBusinessMobile( value );
308 if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) ) 318 if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) )
309 c.setBusinessPager( value ); 319 c.setBusinessPager( value );
310 } 320 }
311 } 321 }
312 else if ( name == VCEmailAddressProp ) { 322 else if ( name == VCEmailAddressProp ) {
313 QString email = vObjectStringZValue( o ); 323 QString email = vObjectStringZValue( o );
314 bool valid = TRUE; 324 bool valid = TRUE;
315 VObjectIterator nit; 325 VObjectIterator nit;
316 initPropIterator( &nit, o ); 326 initPropIterator( &nit, o );
317 while( moreIteration( &nit ) ) { 327 while( moreIteration( &nit ) ) {
318 VObject *o = nextVObject( &nit ); 328 VObject *o = nextVObject( &nit );
319 QCString name = vObjectTypeInfo( o ); 329 QCString name = vObjectTypeInfo( o );
320 if ( name != VCInternetProp && name != VCHomeProp && 330 if ( name != VCInternetProp && name != VCHomeProp &&
321 name != VCWorkProp && 331 name != VCWorkProp &&
322 name != VCPreferredProp ) 332 name != VCPreferredProp )
323 // ### preffered should map to default email 333 // ### preffered should map to default email
324 valid = FALSE; 334 valid = FALSE;
325 } 335 }
326 if ( valid ) { 336 if ( valid ) {
327 c.insertEmail( email ); 337 c.insertEmail( email );
328 } 338 }
329 } 339 }
330 else if ( name == VCURLProp ) { 340 else if ( name == VCURLProp ) {
331 VObjectIterator nit; 341 VObjectIterator nit;
332 initPropIterator( &nit, o ); 342 initPropIterator( &nit, o );
333 while( moreIteration( &nit ) ) { 343 while( moreIteration( &nit ) ) {
334 VObject *o = nextVObject( &nit ); 344 VObject *o = nextVObject( &nit );
335 QCString name = vObjectTypeInfo( o ); 345 QCString name = vObjectTypeInfo( o );
336 if ( name == VCHomeProp ) 346 if ( name == VCHomeProp )
337 c.setHomeWebpage( value ); 347 c.setHomeWebpage( value );
338 else if ( name == VCWorkProp ) 348 else if ( name == VCWorkProp )
339 c.setBusinessWebpage( value ); 349 c.setBusinessWebpage( value );
340 } 350 }
341 } 351 }
342 else if ( name == VCOrgProp ) { 352 else if ( name == VCOrgProp ) {
343 VObjectIterator nit; 353 VObjectIterator nit;
344 initPropIterator( &nit, o ); 354 initPropIterator( &nit, o );
345 while( moreIteration( &nit ) ) { 355 while( moreIteration( &nit ) ) {
346 VObject *o = nextVObject( &nit ); 356 VObject *o = nextVObject( &nit );
347 QCString name = vObjectName( o ); 357 QCString name = vObjectName( o );
348 QString value = vObjectStringZValue( o ); 358 QString value = vObjectStringZValue( o );
349 if ( name == VCOrgNameProp ) 359 if ( name == VCOrgNameProp )
350 c.setCompany( value ); 360 c.setCompany( value );
351 else if ( name == VCOrgUnitProp ) 361 else if ( name == VCOrgUnitProp )
352 c.setDepartment( value ); 362 c.setDepartment( value );
353 else if ( name == VCOrgUnit2Prop ) 363 else if ( name == VCOrgUnit2Prop )
354 c.setOffice( value ); 364 c.setOffice( value );
355 } 365 }
356 } 366 }
357 else if ( name == VCTitleProp ) { 367 else if ( name == VCTitleProp ) {
358 c.setJobTitle( value ); 368 c.setJobTitle( value );
359 } 369 }
360 else if ( name == "X-Qtopia-Profession" ) { 370 else if ( name == "X-Qtopia-Profession" ) {
361 c.setProfession( value ); 371 c.setProfession( value );
362 } 372 }
363 else if ( name == "X-Qtopia-Manager" ) { 373 else if ( name == "X-Qtopia-Manager" ) {
364 c.setManager( value ); 374 c.setManager( value );
365 } 375 }
366 else if ( name == "X-Qtopia-Assistant" ) { 376 else if ( name == "X-Qtopia-Assistant" ) {
367 c.setAssistant( value ); 377 c.setAssistant( value );
368 } 378 }
369 else if ( name == "X-Qtopia-Spouse" ) { 379 else if ( name == "X-Qtopia-Spouse" ) {
370 c.setSpouse( value ); 380 c.setSpouse( value );
371 } 381 }
372 else if ( name == "X-Qtopia-Gender" ) { 382 else if ( name == "X-Qtopia-Gender" ) {
diff --git a/libopie/pim/ocontactaccessbackend_vcard.h b/libopie/pim/ocontactaccessbackend_vcard.h
index 177ec24..4437756 100644
--- a/libopie/pim/ocontactaccessbackend_vcard.h
+++ b/libopie/pim/ocontactaccessbackend_vcard.h
@@ -1,70 +1,74 @@
1/* 1/*
2 * VCard Backend for the OPIE-Contact Database. 2 * VCard Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (C) 2000 Trolltech AS. All rights reserved. 4 * Copyright (C) 2000 Trolltech AS. All rights reserved.
5 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 5 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
6 * 6 *
7 * ===================================================================== 7 * =====================================================================
8 *This program is free software; you can redistribute it and/or 8 *This program is free software; you can redistribute it and/or
9 *modify it under the terms of the GNU Library General Public 9 *modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version. 11 * version 2 of the License, or (at your option) any later version.
12 * ===================================================================== 12 * =====================================================================
13 * ToDo: 13 * ToDo:
14 * 14 *
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.3 2002/11/13 14:14:51 eilers
21 * Added sorted for Contacts..
22 *
20 * Revision 1.2 2002/11/10 15:41:53 eilers 23 * Revision 1.2 2002/11/10 15:41:53 eilers
21 * Bugfixes.. 24 * Bugfixes..
22 * 25 *
23 * Revision 1.1 2002/11/09 14:34:52 eilers 26 * Revision 1.1 2002/11/09 14:34:52 eilers
24 * Added VCard Backend. 27 * Added VCard Backend.
25 * 28 *
26 */ 29 */
27#ifndef __OCONTACTACCESSBACKEND_VCARD_H_ 30#ifndef __OCONTACTACCESSBACKEND_VCARD_H_
28#define __OCONTACTACCESSBACKEND_VCARD_H_ 31#define __OCONTACTACCESSBACKEND_VCARD_H_
29 32
30#include <opie/ocontact.h> 33#include <opie/ocontact.h>
31 34
32#include "ocontactaccessbackend.h" 35#include "ocontactaccessbackend.h"
33 36
34class VObject; 37class VObject;
35 38
36class OContactAccessBackend_VCard : public OContactAccessBackend { 39class OContactAccessBackend_VCard : public OContactAccessBackend {
37 public: 40 public:
38 OContactAccessBackend_VCard ( QString appname, QString filename = 0l ); 41 OContactAccessBackend_VCard ( QString appname, QString filename = 0l );
39 42
40 bool load (); 43 bool load ();
41 bool reload(); 44 bool reload();
42 bool save(); 45 bool save();
43 void clear (); 46 void clear ();
44 47
45 bool add ( const OContact& newcontact ); 48 bool add ( const OContact& newcontact );
46 bool remove ( int uid ); 49 bool remove ( int uid );
47 bool replace ( const OContact& contact ); 50 bool replace ( const OContact& contact );
48 51
49 OContact find ( int uid ) const; 52 OContact find ( int uid ) const;
50 QArray<int> allRecords() const; 53 QArray<int> allRecords() const;
51 QArray<int> queryByExample ( const OContact &query, int settings ); 54 QArray<int> queryByExample ( const OContact &query, int settings );
52 QArray<int> matchRegexp( const QRegExp &r ) const; 55 QArray<int> matchRegexp( const QRegExp &r ) const;
53 56
54 const uint querySettings(); 57 const uint querySettings();
55 bool hasQuerySettings (uint querySettings) const; 58 bool hasQuerySettings (uint querySettings) const;
59 QArray<int> sorted( bool ascending, int sortOrder, int sortFilter, int cat );
56 bool wasChangedExternally(); 60 bool wasChangedExternally();
57 61
58private: 62private:
59 OContact parseVObject( VObject* obj ); 63 OContact parseVObject( VObject* obj );
60 VObject* createVObject( const OContact& c ); 64 VObject* createVObject( const OContact& c );
61 QDate convVCardDateToDate( const QString& datestr ); 65 QDate convVCardDateToDate( const QString& datestr );
62 VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value ); 66 VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value );
63 VObject *safeAddProp( VObject* o, const char* prop); 67 VObject *safeAddProp( VObject* o, const char* prop);
64 68
65 bool m_dirty : 1; 69 bool m_dirty : 1;
66 QString m_file; 70 QString m_file;
67 QMap<int, OContact> m_map; 71 QMap<int, OContact> m_map;
68}; 72};
69 73
70#endif 74#endif
diff --git a/libopie/pim/ocontactaccessbackend_xml.h b/libopie/pim/ocontactaccessbackend_xml.h
index f7e8207..8b95102 100644
--- a/libopie/pim/ocontactaccessbackend_xml.h
+++ b/libopie/pim/ocontactaccessbackend_xml.h
@@ -1,495 +1,527 @@
1/* 1/*
2 * XML Backend for the OPIE-Contact Database. 2 * XML Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed... 12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 * 13 *
14 * 14 *
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.6 2002/11/13 14:14:51 eilers
21 * Added sorted for Contacts..
22 *
20 * Revision 1.5 2002/11/01 15:10:42 eilers 23 * Revision 1.5 2002/11/01 15:10:42 eilers
21 * Added regExp-search in database for all fields in a contact. 24 * Added regExp-search in database for all fields in a contact.
22 * 25 *
23 * Revision 1.4 2002/10/16 10:52:40 eilers 26 * Revision 1.4 2002/10/16 10:52:40 eilers
24 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 27 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
25 * 28 *
26 * Revision 1.3 2002/10/14 16:21:54 eilers 29 * Revision 1.3 2002/10/14 16:21:54 eilers
27 * Some minor interface updates 30 * Some minor interface updates
28 * 31 *
29 * Revision 1.2 2002/10/07 17:34:24 eilers 32 * Revision 1.2 2002/10/07 17:34:24 eilers
30 * added OBackendFactory for advanced backend access 33 * added OBackendFactory for advanced backend access
31 * 34 *
32 * Revision 1.1 2002/09/27 17:11:44 eilers 35 * Revision 1.1 2002/09/27 17:11:44 eilers
33 * Added API for accessing the Contact-Database ! It is compiling, but 36 * Added API for accessing the Contact-Database ! It is compiling, but
34 * please do not expect that anything is working ! 37 * please do not expect that anything is working !
35 * I will debug that stuff in the next time .. 38 * I will debug that stuff in the next time ..
36 * Please read README_COMPILE for compiling ! 39 * Please read README_COMPILE for compiling !
37 * 40 *
38 * 41 *
39 */ 42 */
40 43
41#ifndef _OContactAccessBackend_XML_ 44#ifndef _OContactAccessBackend_XML_
42#define _OContactAccessBackend_XML_ 45#define _OContactAccessBackend_XML_
43 46
44#include <qasciidict.h> 47#include <qasciidict.h>
45#include <qdatetime.h> 48#include <qdatetime.h>
46#include <qfile.h> 49#include <qfile.h>
47#include <qfileinfo.h> 50#include <qfileinfo.h>
48#include <qregexp.h> 51#include <qregexp.h>
49#include <qarray.h> 52#include <qarray.h>
53#include <qmap.h>
50 54
51#include <qpe/global.h> 55#include <qpe/global.h>
52 56
53#include <opie/xmltree.h> 57#include <opie/xmltree.h>
54#include "ocontactaccessbackend.h" 58#include "ocontactaccessbackend.h"
55#include "ocontactaccess.h" 59#include "ocontactaccess.h"
56 60
57#include <stdlib.h> 61#include <stdlib.h>
58#include <errno.h> 62#include <errno.h>
59 63
60using namespace Opie; 64using namespace Opie;
61 65
62/* the default xml implementation */ 66/* the default xml implementation */
63class OContactAccessBackend_XML : public OContactAccessBackend { 67class OContactAccessBackend_XML : public OContactAccessBackend {
64 public: 68 public:
65 OContactAccessBackend_XML ( QString appname, QString filename = 0l ): 69 OContactAccessBackend_XML ( QString appname, QString filename = 0l ):
66 m_changed( false ) 70 m_changed( false )
67 { 71 {
68 m_appName = appname; 72 m_appName = appname;
69 73
70 /* Set journalfile name ... */ 74 /* Set journalfile name ... */
71 m_journalName = getenv("HOME"); 75 m_journalName = getenv("HOME");
72 m_journalName +="/.abjournal" + appname; 76 m_journalName +="/.abjournal" + appname;
73 77
74 /* Expecting to access the default filename if nothing else is set */ 78 /* Expecting to access the default filename if nothing else is set */
75 if ( filename.isEmpty() ){ 79 if ( filename.isEmpty() ){
76 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 80 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
77 } else 81 } else
78 m_fileName = filename; 82 m_fileName = filename;
79 83
80 /* Load Database now */ 84 /* Load Database now */
81 load (); 85 load ();
82 } 86 }
83 87
84 bool save() { 88 bool save() {
85 89
86 if ( !m_changed ) 90 if ( !m_changed )
87 return true; 91 return true;
88 92
89 QString strNewFile = m_fileName + ".new"; 93 QString strNewFile = m_fileName + ".new";
90 QFile f( strNewFile ); 94 QFile f( strNewFile );
91 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 95 if ( !f.open( IO_WriteOnly|IO_Raw ) )
92 return false; 96 return false;
93 97
94 int total_written; 98 int total_written;
95 QString out; 99 QString out;
96 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 100 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
97 " <Groups>\n" 101 " <Groups>\n"
98 " </Groups>\n" 102 " </Groups>\n"
99 " <Contacts>\n"; 103 " <Contacts>\n";
100 //QValueList<Contact>::iterator it; 104 //QValueList<Contact>::iterator it;
101 QValueListConstIterator<OContact> it; 105 QValueListConstIterator<OContact> it;
102 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) { 106 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) {
103 out += "<Contact "; 107 out += "<Contact ";
104 (*it).save( out ); 108 (*it).save( out );
105 out += "/>\n"; 109 out += "/>\n";
106 QCString cstr = out.utf8(); 110 QCString cstr = out.utf8();
107 total_written = f.writeBlock( cstr.data(), cstr.length() ); 111 total_written = f.writeBlock( cstr.data(), cstr.length() );
108 if ( total_written != int(cstr.length()) ) { 112 if ( total_written != int(cstr.length()) ) {
109 f.close(); 113 f.close();
110 QFile::remove( strNewFile ); 114 QFile::remove( strNewFile );
111 return false; 115 return false;
112 } 116 }
113 out = ""; 117 out = "";
114 } 118 }
115 out += " </Contacts>\n</AddressBook>\n"; 119 out += " </Contacts>\n</AddressBook>\n";
116 120
117 QCString cstr = out.utf8(); 121 QCString cstr = out.utf8();
118 total_written = f.writeBlock( cstr.data(), cstr.length() ); 122 total_written = f.writeBlock( cstr.data(), cstr.length() );
119 if ( total_written != int( cstr.length() ) ) { 123 if ( total_written != int( cstr.length() ) ) {
120 f.close(); 124 f.close();
121 QFile::remove( strNewFile ); 125 QFile::remove( strNewFile );
122 return false; 126 return false;
123 } 127 }
124 f.close(); 128 f.close();
125 129
126 // move the file over, I'm just going to use the system call 130 // move the file over, I'm just going to use the system call
127 // because, I don't feel like using QDir. 131 // because, I don't feel like using QDir.
128 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 132 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
129 qWarning( "problem renaming file %s to %s, errno: %d", 133 qWarning( "problem renaming file %s to %s, errno: %d",
130 strNewFile.latin1(), m_journalName.latin1(), errno ); 134 strNewFile.latin1(), m_journalName.latin1(), errno );
131 // remove the tmp file... 135 // remove the tmp file...
132 QFile::remove( strNewFile ); 136 QFile::remove( strNewFile );
133 } 137 }
134 138
135 /* The journalfile should be removed now... */ 139 /* The journalfile should be removed now... */
136 removeJournal(); 140 removeJournal();
137 141
138 m_changed = false; 142 m_changed = false;
139 return true; 143 return true;
140 } 144 }
141 145
142 bool load () { 146 bool load () {
143 m_contactList.clear(); 147 m_contactList.clear();
144 148
145 /* Load XML-File and journal if it exists */ 149 /* Load XML-File and journal if it exists */
146 if ( !load ( m_fileName, false ) ) 150 if ( !load ( m_fileName, false ) )
147 return false; 151 return false;
148 /* The returncode of the journalfile is ignored due to the 152 /* The returncode of the journalfile is ignored due to the
149 * fact that it does not exist when this class is instantiated ! 153 * fact that it does not exist when this class is instantiated !
150 * But there may such a file exist, if the application crashed. 154 * But there may such a file exist, if the application crashed.
151 * Therefore we try to load it to get the changes before the # 155 * Therefore we try to load it to get the changes before the #
152 * crash happened... 156 * crash happened...
153 */ 157 */
154 load (m_journalName, true); 158 load (m_journalName, true);
155 159
156 return true; 160 return true;
157 } 161 }
158 162
159 void clear () { 163 void clear () {
160 m_contactList.clear(); 164 m_contactList.clear();
161 m_changed = false; 165 m_changed = false;
162 166
163 } 167 }
164 168
165 bool wasChangedExternally() 169 bool wasChangedExternally()
166 { 170 {
167 QFileInfo fi( m_fileName ); 171 QFileInfo fi( m_fileName );
168 172
169 QDateTime lastmod = fi.lastModified (); 173 QDateTime lastmod = fi.lastModified ();
170 174
171 return (lastmod != m_readtime); 175 return (lastmod != m_readtime);
172 } 176 }
173 177
174 QArray<int> allRecords() const { 178 QArray<int> allRecords() const {
175 QArray<int> uid_list( m_contactList.count() ); 179 QArray<int> uid_list( m_contactList.count() );
176 180
177 uint counter = 0; 181 uint counter = 0;
178 QValueListConstIterator<OContact> it; 182 QValueListConstIterator<OContact> it;
179 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 183 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
180 uid_list[counter++] = (*it).uid(); 184 uid_list[counter++] = (*it).uid();
181 } 185 }
182 186
183 return ( uid_list ); 187 return ( uid_list );
184 } 188 }
185 189
186 OContact find ( int uid ) const 190 OContact find ( int uid ) const
187 { 191 {
188 bool found = false; 192 bool found = false;
189 OContact foundContact; //Create empty contact 193 OContact foundContact; //Create empty contact
190 194
191 QValueListConstIterator<OContact> it; 195 QValueListConstIterator<OContact> it;
192 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 196 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
193 if ((*it).uid() == uid){ 197 if ((*it).uid() == uid){
194 found = true; 198 found = true;
195 break; 199 break;
196 } 200 }
197 } 201 }
198 if ( found ){ 202 if ( found ){
199 foundContact = *it; 203 foundContact = *it;
200 } 204 }
201 205
202 return ( foundContact ); 206 return ( foundContact );
203 } 207 }
204 208
205 QArray<int> queryByExample ( const OContact &query, int settings ){ 209 QArray<int> queryByExample ( const OContact &query, int settings ){
206 210
207 QArray<int> m_currentQuery( m_contactList.count() ); 211 QArray<int> m_currentQuery( m_contactList.count() );
208 QValueListConstIterator<OContact> it; 212 QValueListConstIterator<OContact> it;
209 uint arraycounter = 0; 213 uint arraycounter = 0;
210 214
211 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 215 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
212 /* Search all fields and compare them with query object. Store them into list 216 /* Search all fields and compare them with query object. Store them into list
213 * if all fields matches. 217 * if all fields matches.
214 */ 218 */
215 bool allcorrect = true; 219 bool allcorrect = true;
216 for ( int i = 0; i < Qtopia::rid; i++ ) { 220 for ( int i = 0; i < Qtopia::rid; i++ ) {
217 /* Just compare fields which are not empty in the query object */ 221 /* Just compare fields which are not empty in the query object */
218 if ( !query.field(i).isEmpty() ){ 222 if ( !query.field(i).isEmpty() ){
219 switch ( settings & ~OContactAccess::IgnoreCase ){ 223 switch ( settings & ~OContactAccess::IgnoreCase ){
220 case OContactAccess::RegExp:{ 224 case OContactAccess::RegExp:{
221 QRegExp expr ( query.field(i), 225 QRegExp expr ( query.field(i),
222 !(settings & OContactAccess::IgnoreCase), 226 !(settings & OContactAccess::IgnoreCase),
223 false ); 227 false );
224 if ( expr.find ( (*it).field(i), 0 ) == -1 ) 228 if ( expr.find ( (*it).field(i), 0 ) == -1 )
225 allcorrect = false; 229 allcorrect = false;
226 } 230 }
227 break; 231 break;
228 case OContactAccess::WildCards:{ 232 case OContactAccess::WildCards:{
229 QRegExp expr ( query.field(i), 233 QRegExp expr ( query.field(i),
230 !(settings & OContactAccess::IgnoreCase), 234 !(settings & OContactAccess::IgnoreCase),
231 true ); 235 true );
232 if ( expr.find ( (*it).field(i), 0 ) == -1 ) 236 if ( expr.find ( (*it).field(i), 0 ) == -1 )
233 allcorrect = false; 237 allcorrect = false;
234 } 238 }
235 break; 239 break;
236 case OContactAccess::ExactMatch:{ 240 case OContactAccess::ExactMatch:{
237 if (settings & OContactAccess::IgnoreCase){ 241 if (settings & OContactAccess::IgnoreCase){
238 if ( query.field(i).upper() != 242 if ( query.field(i).upper() !=
239 (*it).field(i).upper() ) 243 (*it).field(i).upper() )
240 allcorrect = false; 244 allcorrect = false;
241 }else{ 245 }else{
242 if ( query.field(i) != (*it).field(i) ) 246 if ( query.field(i) != (*it).field(i) )
243 allcorrect = false; 247 allcorrect = false;
244 } 248 }
245 } 249 }
246 break; 250 break;
247 } 251 }
248 } 252 }
249 } 253 }
250 if ( allcorrect ){ 254 if ( allcorrect ){
251 m_currentQuery[arraycounter++] = (*it).uid(); 255 m_currentQuery[arraycounter++] = (*it).uid();
252 } 256 }
253 } 257 }
254 258
255 // Shrink to fit.. 259 // Shrink to fit..
256 m_currentQuery.resize(arraycounter); 260 m_currentQuery.resize(arraycounter);
257 261
258 return m_currentQuery; 262 return m_currentQuery;
259 } 263 }
260 264
261 QArray<int> matchRegexp( const QRegExp &r ) const{ 265 QArray<int> matchRegexp( const QRegExp &r ) const{
262 QArray<int> m_currentQuery( m_contactList.count() ); 266 QArray<int> m_currentQuery( m_contactList.count() );
263 QValueListConstIterator<OContact> it; 267 QValueListConstIterator<OContact> it;
264 uint arraycounter = 0; 268 uint arraycounter = 0;
265 269
266 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 270 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
267 if ( (*it).match( r ) ){ 271 if ( (*it).match( r ) ){
268 m_currentQuery[arraycounter++] = (*it).uid(); 272 m_currentQuery[arraycounter++] = (*it).uid();
269 } 273 }
270 274
271 } 275 }
272 // Shrink to fit.. 276 // Shrink to fit..
273 m_currentQuery.resize(arraycounter); 277 m_currentQuery.resize(arraycounter);
274 278
275 return m_currentQuery; 279 return m_currentQuery;
276 } 280 }
277 281
278 const uint querySettings() 282 const uint querySettings()
279 { 283 {
280 return ( OContactAccess::WildCards 284 return ( OContactAccess::WildCards
281 & OContactAccess::IgnoreCase 285 & OContactAccess::IgnoreCase
282 & OContactAccess::RegExp 286 & OContactAccess::RegExp
283 & OContactAccess::ExactMatch ); 287 & OContactAccess::ExactMatch );
284 } 288 }
285 289
286 bool hasQuerySettings (uint querySettings) const 290 bool hasQuerySettings (uint querySettings) const
287 { 291 {
288 /* OContactAccess::IgnoreCase may be added with one 292 /* OContactAccess::IgnoreCase may be added with one
289 * of the other settings, but never used alone. 293 * of the other settings, but never used alone.
290 * The other settings are just valid alone... 294 * The other settings are just valid alone...
291 */ 295 */
292 switch ( querySettings & ~OContactAccess::IgnoreCase ){ 296 switch ( querySettings & ~OContactAccess::IgnoreCase ){
293 case OContactAccess::RegExp: 297 case OContactAccess::RegExp:
294 return ( true ); 298 return ( true );
295 case OContactAccess::WildCards: 299 case OContactAccess::WildCards:
296 return ( true ); 300 return ( true );
297 case OContactAccess::ExactMatch: 301 case OContactAccess::ExactMatch:
298 return ( true ); 302 return ( true );
299 default: 303 default:
300 return ( false ); 304 return ( false );
301 } 305 }
302 } 306 }
303 307
308 // Currently only asc implemented..
309 QArray<int> sorted( bool asc, int , int , int )
310 {
311 QMap<QString, int> nameToUid;
312 QStringList names;
313 QArray<int> m_currentQuery( m_contactList.count() );
314
315 // First fill map and StringList with all Names ( better LastNames ? )
316 // Afterwards sort namelist and use map to fill array to return..
317 QValueListConstIterator<OContact> it;
318 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
319 names.append( (*it).lastName() );
320 nameToUid.insert( (*it).lastName(), (*it).uid() );
321 }
322 names.sort();
323
324 int i = 0;
325 if ( asc ){
326 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
327 m_currentQuery[i++] = nameToUid[ (*it) ];
328 }else{
329 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
330 m_currentQuery[i++] = nameToUid[ (*it) ];
331 }
332
333 return m_currentQuery;
334
335 }
304 bool add ( const OContact &newcontact ) 336 bool add ( const OContact &newcontact )
305 { 337 {
306 //qWarning("odefaultbackend: ACTION::ADD"); 338 //qWarning("odefaultbackend: ACTION::ADD");
307 updateJournal (newcontact, OContact::ACTION_ADD); 339 updateJournal (newcontact, OContact::ACTION_ADD);
308 addContact_p( newcontact ); 340 addContact_p( newcontact );
309 341
310 m_changed = true; 342 m_changed = true;
311 343
312 return true; 344 return true;
313 } 345 }
314 346
315 bool replace ( const OContact &contact ) 347 bool replace ( const OContact &contact )
316 { 348 {
317 m_changed = true; 349 m_changed = true;
318 350
319 bool found = false; 351 bool found = false;
320 352
321 QValueListIterator<OContact> it; 353 QValueListIterator<OContact> it;
322 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 354 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
323 if ( (*it).uid() == contact.uid() ){ 355 if ( (*it).uid() == contact.uid() ){
324 found = true; 356 found = true;
325 break; 357 break;
326 } 358 }
327 } 359 }
328 if (found) { 360 if (found) {
329 updateJournal (contact, OContact::ACTION_REPLACE); 361 updateJournal (contact, OContact::ACTION_REPLACE);
330 m_contactList.remove (it); 362 m_contactList.remove (it);
331 m_contactList.append (contact); 363 m_contactList.append (contact);
332 return true; 364 return true;
333 } else 365 } else
334 return false; 366 return false;
335 } 367 }
336 368
337 bool remove ( int uid ) 369 bool remove ( int uid )
338 { 370 {
339 m_changed = true; 371 m_changed = true;
340 372
341 bool found = false; 373 bool found = false;
342 QValueListIterator<OContact> it; 374 QValueListIterator<OContact> it;
343 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 375 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
344 if ((*it).uid() == uid){ 376 if ((*it).uid() == uid){
345 found = true; 377 found = true;
346 break; 378 break;
347 } 379 }
348 } 380 }
349 if (found) { 381 if (found) {
350 updateJournal ( *it, OContact::ACTION_REMOVE); 382 updateJournal ( *it, OContact::ACTION_REMOVE);
351 m_contactList.remove (it); 383 m_contactList.remove (it);
352 return true; 384 return true;
353 } else 385 } else
354 return false; 386 return false;
355 } 387 }
356 388
357 bool reload(){ 389 bool reload(){
358 /* Reload is the same as load in this implementation */ 390 /* Reload is the same as load in this implementation */
359 return ( load() ); 391 return ( load() );
360 } 392 }
361 393
362 private: 394 private:
363 void addContact_p( const OContact &newcontact ){ 395 void addContact_p( const OContact &newcontact ){
364 m_contactList.append (newcontact); 396 m_contactList.append (newcontact);
365 } 397 }
366 398
367 /* This function loads the xml-database and the journalfile */ 399 /* This function loads the xml-database and the journalfile */
368 bool load( const QString filename, bool isJournal ) { 400 bool load( const QString filename, bool isJournal ) {
369 401
370 /* We use the time of the last read to check if the file was 402 /* We use the time of the last read to check if the file was
371 * changed externally. 403 * changed externally.
372 */ 404 */
373 if ( !isJournal ){ 405 if ( !isJournal ){
374 QFileInfo fi( filename ); 406 QFileInfo fi( filename );
375 m_readtime = fi.lastModified (); 407 m_readtime = fi.lastModified ();
376 } 408 }
377 409
378 const int JOURNALACTION = Qtopia::Notes + 1; 410 const int JOURNALACTION = Qtopia::Notes + 1;
379 const int JOURNALROW = JOURNALACTION + 1; 411 const int JOURNALROW = JOURNALACTION + 1;
380 412
381 bool foundAction = false; 413 bool foundAction = false;
382 OContact::journal_action action = OContact::ACTION_ADD; 414 OContact::journal_action action = OContact::ACTION_ADD;
383 int journalKey = 0; 415 int journalKey = 0;
384 QMap<int, QString> contactMap; 416 QMap<int, QString> contactMap;
385 QMap<QString, QString> customMap; 417 QMap<QString, QString> customMap;
386 QMap<QString, QString>::Iterator customIt; 418 QMap<QString, QString>::Iterator customIt;
387 QAsciiDict<int> dict( 47 ); 419 QAsciiDict<int> dict( 47 );
388 420
389 dict.setAutoDelete( TRUE ); 421 dict.setAutoDelete( TRUE );
390 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 422 dict.insert( "Uid", new int(Qtopia::AddressUid) );
391 dict.insert( "Title", new int(Qtopia::Title) ); 423 dict.insert( "Title", new int(Qtopia::Title) );
392 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 424 dict.insert( "FirstName", new int(Qtopia::FirstName) );
393 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 425 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
394 dict.insert( "LastName", new int(Qtopia::LastName) ); 426 dict.insert( "LastName", new int(Qtopia::LastName) );
395 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 427 dict.insert( "Suffix", new int(Qtopia::Suffix) );
396 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 428 dict.insert( "FileAs", new int(Qtopia::FileAs) );
397 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 429 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
398 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 430 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
399 dict.insert( "Emails", new int(Qtopia::Emails) ); 431 dict.insert( "Emails", new int(Qtopia::Emails) );
400 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 432 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
401 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 433 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
402 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 434 dict.insert( "HomeState", new int(Qtopia::HomeState) );
403 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 435 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
404 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 436 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
405 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 437 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
406 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 438 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
407 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 439 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
408 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 440 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
409 dict.insert( "Company", new int(Qtopia::Company) ); 441 dict.insert( "Company", new int(Qtopia::Company) );
410 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 442 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
411 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 443 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
412 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 444 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
413 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 445 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
414 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 446 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
415 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 447 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
416 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 448 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
417 dict.insert( "Department", new int(Qtopia::Department) ); 449 dict.insert( "Department", new int(Qtopia::Department) );
418 dict.insert( "Office", new int(Qtopia::Office) ); 450 dict.insert( "Office", new int(Qtopia::Office) );
419 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); 451 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
420 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); 452 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
421 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); 453 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
422 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); 454 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
423 dict.insert( "Profession", new int(Qtopia::Profession) ); 455 dict.insert( "Profession", new int(Qtopia::Profession) );
424 dict.insert( "Assistant", new int(Qtopia::Assistant) ); 456 dict.insert( "Assistant", new int(Qtopia::Assistant) );
425 dict.insert( "Manager", new int(Qtopia::Manager) ); 457 dict.insert( "Manager", new int(Qtopia::Manager) );
426 dict.insert( "Spouse", new int(Qtopia::Spouse) ); 458 dict.insert( "Spouse", new int(Qtopia::Spouse) );
427 dict.insert( "Children", new int(Qtopia::Children) ); 459 dict.insert( "Children", new int(Qtopia::Children) );
428 dict.insert( "Gender", new int(Qtopia::Gender) ); 460 dict.insert( "Gender", new int(Qtopia::Gender) );
429 dict.insert( "Birthday", new int(Qtopia::Birthday) ); 461 dict.insert( "Birthday", new int(Qtopia::Birthday) );
430 dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); 462 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
431 dict.insert( "Nickname", new int(Qtopia::Nickname) ); 463 dict.insert( "Nickname", new int(Qtopia::Nickname) );
432 dict.insert( "Notes", new int(Qtopia::Notes) ); 464 dict.insert( "Notes", new int(Qtopia::Notes) );
433 dict.insert( "action", new int(JOURNALACTION) ); 465 dict.insert( "action", new int(JOURNALACTION) );
434 dict.insert( "actionrow", new int(JOURNALROW) ); 466 dict.insert( "actionrow", new int(JOURNALROW) );
435 467
436 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() ); 468 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() );
437 469
438 XMLElement *root = XMLElement::load( filename ); 470 XMLElement *root = XMLElement::load( filename );
439 if(root != 0l ){ // start parsing 471 if(root != 0l ){ // start parsing
440 /* Parse all XML-Elements and put the data into the 472 /* Parse all XML-Elements and put the data into the
441 * Contact-Class 473 * Contact-Class
442 */ 474 */
443 XMLElement *element = root->firstChild(); 475 XMLElement *element = root->firstChild();
444 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() ); 476 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() );
445 element = element->firstChild(); 477 element = element->firstChild();
446 478
447 /* Search Tag "Contacts" which is the parent of all Contacts */ 479 /* Search Tag "Contacts" which is the parent of all Contacts */
448 while( element && !isJournal ){ 480 while( element && !isJournal ){
449 if( element->tagName() != QString::fromLatin1("Contacts") ){ 481 if( element->tagName() != QString::fromLatin1("Contacts") ){
450 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s", 482 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s",
451 // element->tagName().latin1()); 483 // element->tagName().latin1());
452 element = element->nextChild(); 484 element = element->nextChild();
453 } else { 485 } else {
454 element = element->firstChild(); 486 element = element->firstChild();
455 break; 487 break;
456 } 488 }
457 } 489 }
458 /* Parse all Contacts and ignore unknown tags */ 490 /* Parse all Contacts and ignore unknown tags */
459 while( element ){ 491 while( element ){
460 if( element->tagName() != QString::fromLatin1("Contact") ){ 492 if( element->tagName() != QString::fromLatin1("Contact") ){
461 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s", 493 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s",
462 // element->tagName().latin1()); 494 // element->tagName().latin1());
463 element = element->nextChild(); 495 element = element->nextChild();
464 continue; 496 continue;
465 } 497 }
466 /* Found alement with tagname "contact", now parse and store all 498 /* Found alement with tagname "contact", now parse and store all
467 * attributes contained 499 * attributes contained
468 */ 500 */
469 //qWarning("OContactDefBack::load element tagName() : %s", 501 //qWarning("OContactDefBack::load element tagName() : %s",
470 // element->tagName().latin1() ); 502 // element->tagName().latin1() );
471 QString dummy; 503 QString dummy;
472 foundAction = false; 504 foundAction = false;
473 505
474 XMLElement::AttributeMap aMap = element->attributes(); 506 XMLElement::AttributeMap aMap = element->attributes();
475 XMLElement::AttributeMap::Iterator it; 507 XMLElement::AttributeMap::Iterator it;
476 contactMap.clear(); 508 contactMap.clear();
477 customMap.clear(); 509 customMap.clear();
478 for( it = aMap.begin(); it != aMap.end(); ++it ){ 510 for( it = aMap.begin(); it != aMap.end(); ++it ){
479 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); 511 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1());
480 512
481 int *find = dict[ it.key() ]; 513 int *find = dict[ it.key() ];
482 /* Unknown attributes will be stored as "Custom" elements */ 514 /* Unknown attributes will be stored as "Custom" elements */
483 if ( !find ) { 515 if ( !find ) {
484 qWarning("Attribute %s not known.", it.key().latin1()); 516 qWarning("Attribute %s not known.", it.key().latin1());
485 //contact.setCustomField(it.key(), it.data()); 517 //contact.setCustomField(it.key(), it.data());
486 customMap.insert( it.key(), it.data() ); 518 customMap.insert( it.key(), it.data() );
487 continue; 519 continue;
488 } 520 }
489 521
490 /* Check if special conversion is needed and add attribute 522 /* Check if special conversion is needed and add attribute
491 * into Contact class 523 * into Contact class
492 */ 524 */
493 switch( *find ) { 525 switch( *find ) {
494 /* 526 /*
495 case Qtopia::AddressUid: 527 case Qtopia::AddressUid:
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.h b/libopie2/opiepim/backend/ocontactaccessbackend.h
index c898f61..821f5bf 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend.h
@@ -1,81 +1,85 @@
1/** 1/**
2 * The class responsible for managing a backend. 2 * The class responsible for managing a backend.
3 * The implementation of this abstract class contains 3 * The implementation of this abstract class contains
4 * the complete database handling. 4 * the complete database handling.
5 * 5 *
6 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 6 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
7 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) 7 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org)
8 * 8 *
9 * ===================================================================== 9 * =====================================================================
10 *This program is free software; you can redistribute it and/or 10 *This program is free software; you can redistribute it and/or
11 *modify it under the terms of the GNU Library General Public 11 *modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; 12 * License as published by the Free Software Foundation;
13 * either version 2 of the License, or (at your option) any later 13 * either version 2 of the License, or (at your option) any later
14 * version. 14 * version.
15 * ===================================================================== 15 * =====================================================================
16 * ToDo: Define enum for query settings 16 * ToDo: Define enum for query settings
17 * ===================================================================== 17 * =====================================================================
18 * Version: $Id$ 18 * Version: $Id$
19 * ===================================================================== 19 * =====================================================================
20 * History: 20 * History:
21 * $Log$ 21 * $Log$
22 * Revision 1.4 2002/11/13 14:14:51 eilers
23 * Added sorted for Contacts..
24 *
22 * Revision 1.3 2002/11/01 15:10:42 eilers 25 * Revision 1.3 2002/11/01 15:10:42 eilers
23 * Added regExp-search in database for all fields in a contact. 26 * Added regExp-search in database for all fields in a contact.
24 * 27 *
25 * Revision 1.2 2002/10/07 17:34:24 eilers 28 * Revision 1.2 2002/10/07 17:34:24 eilers
26 * added OBackendFactory for advanced backend access 29 * added OBackendFactory for advanced backend access
27 * 30 *
28 * Revision 1.1 2002/09/27 17:11:44 eilers 31 * Revision 1.1 2002/09/27 17:11:44 eilers
29 * Added API for accessing the Contact-Database ! It is compiling, but 32 * Added API for accessing the Contact-Database ! It is compiling, but
30 * please do not expect that anything is working ! 33 * please do not expect that anything is working !
31 * I will debug that stuff in the next time .. 34 * I will debug that stuff in the next time ..
32 * Please read README_COMPILE for compiling ! 35 * Please read README_COMPILE for compiling !
33 * 36 *
34 * ===================================================================== 37 * =====================================================================
35 * 38 *
36 */ 39 */
37 40
38#ifndef _OCONTACTACCESSBACKEND_H_ 41#ifndef _OCONTACTACCESSBACKEND_H_
39#define _OCONTACTACCESSBACKEND_H_ 42#define _OCONTACTACCESSBACKEND_H_
40 43
41#include "ocontact.h" 44#include "ocontact.h"
42#include "opimaccessbackend.h" 45#include "opimaccessbackend.h"
43 46
44#include "qregexp.h" 47#include "qregexp.h"
45 48
46class OContactAccessBackend: public OPimAccessBackend<OContact> { 49class OContactAccessBackend: public OPimAccessBackend<OContact> {
47 public: 50 public:
48 OContactAccessBackend() {} 51 OContactAccessBackend() {}
49 virtual ~OContactAccessBackend() {} 52 virtual ~OContactAccessBackend() {}
50 53
51 54
52 /** Return if database was changed externally. 55 /** Return if database was changed externally.
53 * This may just make sense on file based databases like a XML-File. 56 * This may just make sense on file based databases like a XML-File.
54 * It is used to prevent to overwrite the current database content 57 * It is used to prevent to overwrite the current database content
55 * if the file was already changed by something else ! 58 * if the file was already changed by something else !
56 * If this happens, we have to reload before save our data. 59 * If this happens, we have to reload before save our data.
57 * If we use real databases, this should be handled by the database 60 * If we use real databases, this should be handled by the database
58 * management system themselve, therefore this function should always return false in 61 * management system themselve, therefore this function should always return false in
59 * this case. It is not our problem to handle this conflict ... 62 * this case. It is not our problem to handle this conflict ...
60 * @return <i>true</i> if the database was changed and if save without reload will 63 * @return <i>true</i> if the database was changed and if save without reload will
61 * be dangerous. <i>false</i> if the database was not changed or it is save to write 64 * be dangerous. <i>false</i> if the database was not changed or it is save to write
62 * in this situation. 65 * in this situation.
63 */ 66 */
64 virtual bool wasChangedExternally() = 0; 67 virtual bool wasChangedExternally() = 0;
65 68
66 virtual QArray<int> matchRegexp( const QRegExp &r ) const = 0; 69 virtual QArray<int> matchRegexp( const QRegExp &r ) const = 0;
67 70
68 /** Return all possible settings. 71 /** Return all possible settings.
69 * @return All settings provided by the current backend 72 * @return All settings provided by the current backend
70 * (i.e.: query_WildCards & query_IgnoreCase) 73 * (i.e.: query_WildCards & query_IgnoreCase)
71 */ 74 */
72 virtual const uint querySettings() = 0; 75 virtual const uint querySettings() = 0;
73 76
74 /** Check whether settings are correct. 77 /** Check whether settings are correct.
75 * @return <i>true</i> if the given settings are correct and possible. 78 * @return <i>true</i> if the given settings are correct and possible.
76 */ 79 */
77 virtual bool hasQuerySettings (uint querySettings) const = 0; 80 virtual bool hasQuerySettings (uint querySettings) const = 0;
78 81
82 virtual QArray<int> sorted( bool ascending, int sortOrder, int sortFilter, int cat ) = 0;
79 83
80}; 84};
81#endif 85#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
index faa72b4..09ae37b 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
@@ -1,372 +1,382 @@
1/* 1/*
2 * VCard Backend for the OPIE-Contact Database. 2 * VCard Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (C) 2000 Trolltech AS. All rights reserved. 4 * Copyright (C) 2000 Trolltech AS. All rights reserved.
5 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 5 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
6 * 6 *
7 * ===================================================================== 7 * =====================================================================
8 *This program is free software; you can redistribute it and/or 8 *This program is free software; you can redistribute it and/or
9 *modify it under the terms of the GNU Library General Public 9 *modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version. 11 * version 2 of the License, or (at your option) any later version.
12 * ===================================================================== 12 * =====================================================================
13 * ToDo: 13 * ToDo:
14 * 14 *
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.4 2002/11/13 14:14:51 eilers
21 * Added sorted for Contacts..
22 *
20 * Revision 1.3 2002/11/11 16:41:09 kergoth 23 * Revision 1.3 2002/11/11 16:41:09 kergoth
21 * no default arguments in implementation 24 * no default arguments in implementation
22 * 25 *
23 * Revision 1.2 2002/11/10 15:41:53 eilers 26 * Revision 1.2 2002/11/10 15:41:53 eilers
24 * Bugfixes.. 27 * Bugfixes..
25 * 28 *
26 * Revision 1.1 2002/11/09 14:34:52 eilers 29 * Revision 1.1 2002/11/09 14:34:52 eilers
27 * Added VCard Backend. 30 * Added VCard Backend.
28 * 31 *
29 */ 32 */
30#include "ocontactaccessbackend_vcard.h" 33#include "ocontactaccessbackend_vcard.h"
31#include "../../library/backend/vobject_p.h" 34#include "../../library/backend/vobject_p.h"
32#include "../../library/backend/qfiledirect_p.h" 35#include "../../library/backend/qfiledirect_p.h"
33 36
34#include <qpe/timeconversion.h> 37#include <qpe/timeconversion.h>
35 38
36#include <qfile.h> 39#include <qfile.h>
37 40
38OContactAccessBackend_VCard::OContactAccessBackend_VCard ( QString , QString filename ): 41OContactAccessBackend_VCard::OContactAccessBackend_VCard ( QString , QString filename ):
39 m_dirty( false ), 42 m_dirty( false ),
40 m_file( filename ) 43 m_file( filename )
41{ 44{
42 load(); 45 load();
43} 46}
44 47
45 48
46bool OContactAccessBackend_VCard::load () 49bool OContactAccessBackend_VCard::load ()
47{ 50{
48 m_map.clear(); 51 m_map.clear();
49 m_dirty = false; 52 m_dirty = false;
50 53
51 VObject* obj = 0l; 54 VObject* obj = 0l;
52 obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); 55 obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() );
53 if ( !obj ) 56 if ( !obj )
54 return false; 57 return false;
55 58
56 while ( obj ) { 59 while ( obj ) {
57 OContact con = parseVObject( obj ); 60 OContact con = parseVObject( obj );
58 /* 61 /*
59 * if uid is 0 assign a new one 62 * if uid is 0 assign a new one
60 * this at least happens on 63 * this at least happens on
61 * Nokia6210 64 * Nokia6210
62 */ 65 */
63 if ( con.uid() == 0 ){ 66 if ( con.uid() == 0 ){
64 con.setUid( 1 ); 67 con.setUid( 1 );
65 qWarning("assigned new uid %d",con.uid() ); 68 qWarning("assigned new uid %d",con.uid() );
66 } 69 }
67 70
68 m_map.insert( con.uid(), con ); 71 m_map.insert( con.uid(), con );
69 72
70 VObject *t = obj; 73 VObject *t = obj;
71 obj = nextVObjectInList(obj); 74 obj = nextVObjectInList(obj);
72 cleanVObject( t ); 75 cleanVObject( t );
73 } 76 }
74 77
75 return true; 78 return true;
76 79
77} 80}
78bool OContactAccessBackend_VCard::reload() 81bool OContactAccessBackend_VCard::reload()
79{ 82{
80 return load(); 83 return load();
81} 84}
82bool OContactAccessBackend_VCard::save() 85bool OContactAccessBackend_VCard::save()
83{ 86{
84 if (!m_dirty ) 87 if (!m_dirty )
85 return true; 88 return true;
86 89
87 QFileDirect file( m_file ); 90 QFileDirect file( m_file );
88 if (!file.open(IO_WriteOnly ) ) 91 if (!file.open(IO_WriteOnly ) )
89 return false; 92 return false;
90 93
91 VObject *obj; 94 VObject *obj;
92 obj = newVObject( VCCalProp ); 95 obj = newVObject( VCCalProp );
93 addPropValue( obj, VCVersionProp, "1.0" ); 96 addPropValue( obj, VCVersionProp, "1.0" );
94 97
95 VObject *vo; 98 VObject *vo;
96 for(QMap<int, OContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ 99 for(QMap<int, OContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){
97 vo = createVObject( *it ); 100 vo = createVObject( *it );
98 writeVObject( file.directHandle() , vo ); 101 writeVObject( file.directHandle() , vo );
99 cleanVObject( vo ); 102 cleanVObject( vo );
100 } 103 }
101 cleanStrTbl(); 104 cleanStrTbl();
102 105
103 m_dirty = false; 106 m_dirty = false;
104 return true; 107 return true;
105 108
106 109
107} 110}
108void OContactAccessBackend_VCard::clear () 111void OContactAccessBackend_VCard::clear ()
109{ 112{
110 m_map.clear(); 113 m_map.clear();
111 m_dirty = true; // ??? sure ? (se) 114 m_dirty = true; // ??? sure ? (se)
112} 115}
113 116
114bool OContactAccessBackend_VCard::add ( const OContact& newcontact ) 117bool OContactAccessBackend_VCard::add ( const OContact& newcontact )
115{ 118{
116 m_map.insert( newcontact.uid(), newcontact ); 119 m_map.insert( newcontact.uid(), newcontact );
117 m_dirty = true; 120 m_dirty = true;
118 return true; 121 return true;
119} 122}
120 123
121bool OContactAccessBackend_VCard::remove ( int uid ) 124bool OContactAccessBackend_VCard::remove ( int uid )
122{ 125{
123 m_map.remove( uid ); 126 m_map.remove( uid );
124 m_dirty = true; 127 m_dirty = true;
125 return true; 128 return true;
126} 129}
127 130
128bool OContactAccessBackend_VCard::replace ( const OContact &contact ) 131bool OContactAccessBackend_VCard::replace ( const OContact &contact )
129{ 132{
130 m_map.replace( contact.uid(), contact ); 133 m_map.replace( contact.uid(), contact );
131 m_dirty = true; 134 m_dirty = true;
132 return true; 135 return true;
133} 136}
134 137
135OContact OContactAccessBackend_VCard::find ( int uid ) const 138OContact OContactAccessBackend_VCard::find ( int uid ) const
136{ 139{
137 return m_map[uid]; 140 return m_map[uid];
138} 141}
139 142
140QArray<int> OContactAccessBackend_VCard::allRecords() const 143QArray<int> OContactAccessBackend_VCard::allRecords() const
141{ 144{
142 QArray<int> ar( m_map.count() ); 145 QArray<int> ar( m_map.count() );
143 QMap<int, OContact>::ConstIterator it; 146 QMap<int, OContact>::ConstIterator it;
144 int i = 0; 147 int i = 0;
145 for ( it = m_map.begin(); it != m_map.end(); ++it ) { 148 for ( it = m_map.begin(); it != m_map.end(); ++it ) {
146 ar[i] = it.key(); 149 ar[i] = it.key();
147 i++; 150 i++;
148 } 151 }
149 return ar; 152 return ar;
150} 153}
151 154
152// Not implemented 155// Not implemented
153QArray<int> OContactAccessBackend_VCard::queryByExample ( const OContact&, int ) 156QArray<int> OContactAccessBackend_VCard::queryByExample ( const OContact&, int )
154{ 157{
155 QArray<int> ar(0); 158 QArray<int> ar(0);
156 return ar; 159 return ar;
157} 160}
158 161
159// Not implemented 162// Not implemented
160QArray<int> OContactAccessBackend_VCard::matchRegexp( const QRegExp& ) const 163QArray<int> OContactAccessBackend_VCard::matchRegexp( const QRegExp& ) const
161{ 164{
162 QArray<int> ar(0); 165 QArray<int> ar(0);
163 return ar; 166 return ar;
164} 167}
165 168
166const uint OContactAccessBackend_VCard::querySettings() 169const uint OContactAccessBackend_VCard::querySettings()
167{ 170{
168 return 0; // No search possible 171 return 0; // No search possible
169} 172}
170 173
171bool OContactAccessBackend_VCard::hasQuerySettings (uint ) const 174bool OContactAccessBackend_VCard::hasQuerySettings (uint ) const
172{ 175{
173 return false; // No search possible, therefore all settings invalid ;) 176 return false; // No search possible, therefore all settings invalid ;)
174} 177}
175 178
176bool OContactAccessBackend_VCard::wasChangedExternally() 179bool OContactAccessBackend_VCard::wasChangedExternally()
177{ 180{
178 return false; // Don't expect concurrent access 181 return false; // Don't expect concurrent access
179} 182}
180 183
184// Not implemented
185QArray<int> OContactAccessBackend_VCard::sorted( bool , int, int, int )
186{
187 QArray<int> ar(0);
188 return ar;
189}
190
181// *** Private stuff *** 191// *** Private stuff ***
182 192
183 193
184OContact OContactAccessBackend_VCard::parseVObject( VObject *obj ) 194OContact OContactAccessBackend_VCard::parseVObject( VObject *obj )
185{ 195{
186 OContact c; 196 OContact c;
187 197
188 VObjectIterator it; 198 VObjectIterator it;
189 initPropIterator( &it, obj ); 199 initPropIterator( &it, obj );
190 while( moreIteration( &it ) ) { 200 while( moreIteration( &it ) ) {
191 VObject *o = nextVObject( &it ); 201 VObject *o = nextVObject( &it );
192 QCString name = vObjectName( o ); 202 QCString name = vObjectName( o );
193 QCString value = vObjectStringZValue( o ); 203 QCString value = vObjectStringZValue( o );
194 if ( name == VCNameProp ) { 204 if ( name == VCNameProp ) {
195 VObjectIterator nit; 205 VObjectIterator nit;
196 initPropIterator( &nit, o ); 206 initPropIterator( &nit, o );
197 while( moreIteration( &nit ) ) { 207 while( moreIteration( &nit ) ) {
198 VObject *o = nextVObject( &nit ); 208 VObject *o = nextVObject( &nit );
199 QCString name = vObjectTypeInfo( o ); 209 QCString name = vObjectTypeInfo( o );
200 QString value = vObjectStringZValue( o ); 210 QString value = vObjectStringZValue( o );
201 if ( name == VCNamePrefixesProp ) 211 if ( name == VCNamePrefixesProp )
202 c.setTitle( value ); 212 c.setTitle( value );
203 else if ( name == VCNameSuffixesProp ) 213 else if ( name == VCNameSuffixesProp )
204 c.setSuffix( value ); 214 c.setSuffix( value );
205 else if ( name == VCFamilyNameProp ) 215 else if ( name == VCFamilyNameProp )
206 c.setLastName( value ); 216 c.setLastName( value );
207 else if ( name == VCGivenNameProp ) 217 else if ( name == VCGivenNameProp )
208 c.setFirstName( value ); 218 c.setFirstName( value );
209 else if ( name == VCAdditionalNamesProp ) 219 else if ( name == VCAdditionalNamesProp )
210 c.setMiddleName( value ); 220 c.setMiddleName( value );
211 } 221 }
212 } 222 }
213 else if ( name == VCAdrProp ) { 223 else if ( name == VCAdrProp ) {
214 bool work = TRUE; // default address is work address 224 bool work = TRUE; // default address is work address
215 QString street; 225 QString street;
216 QString city; 226 QString city;
217 QString region; 227 QString region;
218 QString postal; 228 QString postal;
219 QString country; 229 QString country;
220 230
221 VObjectIterator nit; 231 VObjectIterator nit;
222 initPropIterator( &nit, o ); 232 initPropIterator( &nit, o );
223 while( moreIteration( &nit ) ) { 233 while( moreIteration( &nit ) ) {
224 VObject *o = nextVObject( &nit ); 234 VObject *o = nextVObject( &nit );
225 QCString name = vObjectName( o ); 235 QCString name = vObjectName( o );
226 QString value = vObjectStringZValue( o ); 236 QString value = vObjectStringZValue( o );
227 if ( name == VCHomeProp ) 237 if ( name == VCHomeProp )
228 work = FALSE; 238 work = FALSE;
229 else if ( name == VCWorkProp ) 239 else if ( name == VCWorkProp )
230 work = TRUE; 240 work = TRUE;
231 else if ( name == VCStreetAddressProp ) 241 else if ( name == VCStreetAddressProp )
232 street = value; 242 street = value;
233 else if ( name == VCCityProp ) 243 else if ( name == VCCityProp )
234 city = value; 244 city = value;
235 else if ( name == VCRegionProp ) 245 else if ( name == VCRegionProp )
236 region = value; 246 region = value;
237 else if ( name == VCPostalCodeProp ) 247 else if ( name == VCPostalCodeProp )
238 postal = value; 248 postal = value;
239 else if ( name == VCCountryNameProp ) 249 else if ( name == VCCountryNameProp )
240 country = value; 250 country = value;
241 } 251 }
242 if ( work ) { 252 if ( work ) {
243 c.setBusinessStreet( street ); 253 c.setBusinessStreet( street );
244 c.setBusinessCity( city ); 254 c.setBusinessCity( city );
245 c.setBusinessCountry( country ); 255 c.setBusinessCountry( country );
246 c.setBusinessZip( postal ); 256 c.setBusinessZip( postal );
247 c.setBusinessState( region ); 257 c.setBusinessState( region );
248 } else { 258 } else {
249 c.setHomeStreet( street ); 259 c.setHomeStreet( street );
250 c.setHomeCity( city ); 260 c.setHomeCity( city );
251 c.setHomeCountry( country ); 261 c.setHomeCountry( country );
252 c.setHomeZip( postal ); 262 c.setHomeZip( postal );
253 c.setHomeState( region ); 263 c.setHomeState( region );
254 } 264 }
255 } 265 }
256 else if ( name == VCTelephoneProp ) { 266 else if ( name == VCTelephoneProp ) {
257 enum { 267 enum {
258 HOME = 0x01, 268 HOME = 0x01,
259 WORK = 0x02, 269 WORK = 0x02,
260 VOICE = 0x04, 270 VOICE = 0x04,
261 CELL = 0x08, 271 CELL = 0x08,
262 FAX = 0x10, 272 FAX = 0x10,
263 PAGER = 0x20, 273 PAGER = 0x20,
264 UNKNOWN = 0x80 274 UNKNOWN = 0x80
265 }; 275 };
266 int type = 0; 276 int type = 0;
267 277
268 VObjectIterator nit; 278 VObjectIterator nit;
269 initPropIterator( &nit, o ); 279 initPropIterator( &nit, o );
270 while( moreIteration( &nit ) ) { 280 while( moreIteration( &nit ) ) {
271 VObject *o = nextVObject( &nit ); 281 VObject *o = nextVObject( &nit );
272 QCString name = vObjectTypeInfo( o ); 282 QCString name = vObjectTypeInfo( o );
273 if ( name == VCHomeProp ) 283 if ( name == VCHomeProp )
274 type |= HOME; 284 type |= HOME;
275 else if ( name == VCWorkProp ) 285 else if ( name == VCWorkProp )
276 type |= WORK; 286 type |= WORK;
277 else if ( name == VCVoiceProp ) 287 else if ( name == VCVoiceProp )
278 type |= VOICE; 288 type |= VOICE;
279 else if ( name == VCCellularProp ) 289 else if ( name == VCCellularProp )
280 type |= CELL; 290 type |= CELL;
281 else if ( name == VCFaxProp ) 291 else if ( name == VCFaxProp )
282 type |= FAX; 292 type |= FAX;
283 else if ( name == VCPagerProp ) 293 else if ( name == VCPagerProp )
284 type |= PAGER; 294 type |= PAGER;
285 else if ( name == VCPreferredProp ) 295 else if ( name == VCPreferredProp )
286 ; 296 ;
287 else 297 else
288 type |= UNKNOWN; 298 type |= UNKNOWN;
289 } 299 }
290 if ( (type & UNKNOWN) != UNKNOWN ) { 300 if ( (type & UNKNOWN) != UNKNOWN ) {
291 if ( ( type & (HOME|WORK) ) == 0 ) // default 301 if ( ( type & (HOME|WORK) ) == 0 ) // default
292 type |= HOME; 302 type |= HOME;
293 if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default 303 if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default
294 type |= VOICE; 304 type |= VOICE;
295 305
296 if ( (type & (VOICE|HOME) ) == (VOICE|HOME) ) 306 if ( (type & (VOICE|HOME) ) == (VOICE|HOME) )
297 c.setHomePhone( value ); 307 c.setHomePhone( value );
298 if ( ( type & (FAX|HOME) ) == (FAX|HOME) ) 308 if ( ( type & (FAX|HOME) ) == (FAX|HOME) )
299 c.setHomeFax( value ); 309 c.setHomeFax( value );
300 if ( ( type & (CELL|HOME) ) == (CELL|HOME) ) 310 if ( ( type & (CELL|HOME) ) == (CELL|HOME) )
301 c.setHomeMobile( value ); 311 c.setHomeMobile( value );
302 if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) ) 312 if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) )
303 c.setBusinessPhone( value ); 313 c.setBusinessPhone( value );
304 if ( ( type & (FAX|WORK) ) == (FAX|WORK) ) 314 if ( ( type & (FAX|WORK) ) == (FAX|WORK) )
305 c.setBusinessFax( value ); 315 c.setBusinessFax( value );
306 if ( ( type & (CELL|WORK) ) == (CELL|WORK) ) 316 if ( ( type & (CELL|WORK) ) == (CELL|WORK) )
307 c.setBusinessMobile( value ); 317 c.setBusinessMobile( value );
308 if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) ) 318 if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) )
309 c.setBusinessPager( value ); 319 c.setBusinessPager( value );
310 } 320 }
311 } 321 }
312 else if ( name == VCEmailAddressProp ) { 322 else if ( name == VCEmailAddressProp ) {
313 QString email = vObjectStringZValue( o ); 323 QString email = vObjectStringZValue( o );
314 bool valid = TRUE; 324 bool valid = TRUE;
315 VObjectIterator nit; 325 VObjectIterator nit;
316 initPropIterator( &nit, o ); 326 initPropIterator( &nit, o );
317 while( moreIteration( &nit ) ) { 327 while( moreIteration( &nit ) ) {
318 VObject *o = nextVObject( &nit ); 328 VObject *o = nextVObject( &nit );
319 QCString name = vObjectTypeInfo( o ); 329 QCString name = vObjectTypeInfo( o );
320 if ( name != VCInternetProp && name != VCHomeProp && 330 if ( name != VCInternetProp && name != VCHomeProp &&
321 name != VCWorkProp && 331 name != VCWorkProp &&
322 name != VCPreferredProp ) 332 name != VCPreferredProp )
323 // ### preffered should map to default email 333 // ### preffered should map to default email
324 valid = FALSE; 334 valid = FALSE;
325 } 335 }
326 if ( valid ) { 336 if ( valid ) {
327 c.insertEmail( email ); 337 c.insertEmail( email );
328 } 338 }
329 } 339 }
330 else if ( name == VCURLProp ) { 340 else if ( name == VCURLProp ) {
331 VObjectIterator nit; 341 VObjectIterator nit;
332 initPropIterator( &nit, o ); 342 initPropIterator( &nit, o );
333 while( moreIteration( &nit ) ) { 343 while( moreIteration( &nit ) ) {
334 VObject *o = nextVObject( &nit ); 344 VObject *o = nextVObject( &nit );
335 QCString name = vObjectTypeInfo( o ); 345 QCString name = vObjectTypeInfo( o );
336 if ( name == VCHomeProp ) 346 if ( name == VCHomeProp )
337 c.setHomeWebpage( value ); 347 c.setHomeWebpage( value );
338 else if ( name == VCWorkProp ) 348 else if ( name == VCWorkProp )
339 c.setBusinessWebpage( value ); 349 c.setBusinessWebpage( value );
340 } 350 }
341 } 351 }
342 else if ( name == VCOrgProp ) { 352 else if ( name == VCOrgProp ) {
343 VObjectIterator nit; 353 VObjectIterator nit;
344 initPropIterator( &nit, o ); 354 initPropIterator( &nit, o );
345 while( moreIteration( &nit ) ) { 355 while( moreIteration( &nit ) ) {
346 VObject *o = nextVObject( &nit ); 356 VObject *o = nextVObject( &nit );
347 QCString name = vObjectName( o ); 357 QCString name = vObjectName( o );
348 QString value = vObjectStringZValue( o ); 358 QString value = vObjectStringZValue( o );
349 if ( name == VCOrgNameProp ) 359 if ( name == VCOrgNameProp )
350 c.setCompany( value ); 360 c.setCompany( value );
351 else if ( name == VCOrgUnitProp ) 361 else if ( name == VCOrgUnitProp )
352 c.setDepartment( value ); 362 c.setDepartment( value );
353 else if ( name == VCOrgUnit2Prop ) 363 else if ( name == VCOrgUnit2Prop )
354 c.setOffice( value ); 364 c.setOffice( value );
355 } 365 }
356 } 366 }
357 else if ( name == VCTitleProp ) { 367 else if ( name == VCTitleProp ) {
358 c.setJobTitle( value ); 368 c.setJobTitle( value );
359 } 369 }
360 else if ( name == "X-Qtopia-Profession" ) { 370 else if ( name == "X-Qtopia-Profession" ) {
361 c.setProfession( value ); 371 c.setProfession( value );
362 } 372 }
363 else if ( name == "X-Qtopia-Manager" ) { 373 else if ( name == "X-Qtopia-Manager" ) {
364 c.setManager( value ); 374 c.setManager( value );
365 } 375 }
366 else if ( name == "X-Qtopia-Assistant" ) { 376 else if ( name == "X-Qtopia-Assistant" ) {
367 c.setAssistant( value ); 377 c.setAssistant( value );
368 } 378 }
369 else if ( name == "X-Qtopia-Spouse" ) { 379 else if ( name == "X-Qtopia-Spouse" ) {
370 c.setSpouse( value ); 380 c.setSpouse( value );
371 } 381 }
372 else if ( name == "X-Qtopia-Gender" ) { 382 else if ( name == "X-Qtopia-Gender" ) {
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h
index 177ec24..4437756 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h
@@ -1,70 +1,74 @@
1/* 1/*
2 * VCard Backend for the OPIE-Contact Database. 2 * VCard Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (C) 2000 Trolltech AS. All rights reserved. 4 * Copyright (C) 2000 Trolltech AS. All rights reserved.
5 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 5 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
6 * 6 *
7 * ===================================================================== 7 * =====================================================================
8 *This program is free software; you can redistribute it and/or 8 *This program is free software; you can redistribute it and/or
9 *modify it under the terms of the GNU Library General Public 9 *modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version. 11 * version 2 of the License, or (at your option) any later version.
12 * ===================================================================== 12 * =====================================================================
13 * ToDo: 13 * ToDo:
14 * 14 *
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.3 2002/11/13 14:14:51 eilers
21 * Added sorted for Contacts..
22 *
20 * Revision 1.2 2002/11/10 15:41:53 eilers 23 * Revision 1.2 2002/11/10 15:41:53 eilers
21 * Bugfixes.. 24 * Bugfixes..
22 * 25 *
23 * Revision 1.1 2002/11/09 14:34:52 eilers 26 * Revision 1.1 2002/11/09 14:34:52 eilers
24 * Added VCard Backend. 27 * Added VCard Backend.
25 * 28 *
26 */ 29 */
27#ifndef __OCONTACTACCESSBACKEND_VCARD_H_ 30#ifndef __OCONTACTACCESSBACKEND_VCARD_H_
28#define __OCONTACTACCESSBACKEND_VCARD_H_ 31#define __OCONTACTACCESSBACKEND_VCARD_H_
29 32
30#include <opie/ocontact.h> 33#include <opie/ocontact.h>
31 34
32#include "ocontactaccessbackend.h" 35#include "ocontactaccessbackend.h"
33 36
34class VObject; 37class VObject;
35 38
36class OContactAccessBackend_VCard : public OContactAccessBackend { 39class OContactAccessBackend_VCard : public OContactAccessBackend {
37 public: 40 public:
38 OContactAccessBackend_VCard ( QString appname, QString filename = 0l ); 41 OContactAccessBackend_VCard ( QString appname, QString filename = 0l );
39 42
40 bool load (); 43 bool load ();
41 bool reload(); 44 bool reload();
42 bool save(); 45 bool save();
43 void clear (); 46 void clear ();
44 47
45 bool add ( const OContact& newcontact ); 48 bool add ( const OContact& newcontact );
46 bool remove ( int uid ); 49 bool remove ( int uid );
47 bool replace ( const OContact& contact ); 50 bool replace ( const OContact& contact );
48 51
49 OContact find ( int uid ) const; 52 OContact find ( int uid ) const;
50 QArray<int> allRecords() const; 53 QArray<int> allRecords() const;
51 QArray<int> queryByExample ( const OContact &query, int settings ); 54 QArray<int> queryByExample ( const OContact &query, int settings );
52 QArray<int> matchRegexp( const QRegExp &r ) const; 55 QArray<int> matchRegexp( const QRegExp &r ) const;
53 56
54 const uint querySettings(); 57 const uint querySettings();
55 bool hasQuerySettings (uint querySettings) const; 58 bool hasQuerySettings (uint querySettings) const;
59 QArray<int> sorted( bool ascending, int sortOrder, int sortFilter, int cat );
56 bool wasChangedExternally(); 60 bool wasChangedExternally();
57 61
58private: 62private:
59 OContact parseVObject( VObject* obj ); 63 OContact parseVObject( VObject* obj );
60 VObject* createVObject( const OContact& c ); 64 VObject* createVObject( const OContact& c );
61 QDate convVCardDateToDate( const QString& datestr ); 65 QDate convVCardDateToDate( const QString& datestr );
62 VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value ); 66 VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value );
63 VObject *safeAddProp( VObject* o, const char* prop); 67 VObject *safeAddProp( VObject* o, const char* prop);
64 68
65 bool m_dirty : 1; 69 bool m_dirty : 1;
66 QString m_file; 70 QString m_file;
67 QMap<int, OContact> m_map; 71 QMap<int, OContact> m_map;
68}; 72};
69 73
70#endif 74#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
index f7e8207..8b95102 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
@@ -1,495 +1,527 @@
1/* 1/*
2 * XML Backend for the OPIE-Contact Database. 2 * XML Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed... 12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 * 13 *
14 * 14 *
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.6 2002/11/13 14:14:51 eilers
21 * Added sorted for Contacts..
22 *
20 * Revision 1.5 2002/11/01 15:10:42 eilers 23 * Revision 1.5 2002/11/01 15:10:42 eilers
21 * Added regExp-search in database for all fields in a contact. 24 * Added regExp-search in database for all fields in a contact.
22 * 25 *
23 * Revision 1.4 2002/10/16 10:52:40 eilers 26 * Revision 1.4 2002/10/16 10:52:40 eilers
24 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 27 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
25 * 28 *
26 * Revision 1.3 2002/10/14 16:21:54 eilers 29 * Revision 1.3 2002/10/14 16:21:54 eilers
27 * Some minor interface updates 30 * Some minor interface updates
28 * 31 *
29 * Revision 1.2 2002/10/07 17:34:24 eilers 32 * Revision 1.2 2002/10/07 17:34:24 eilers
30 * added OBackendFactory for advanced backend access 33 * added OBackendFactory for advanced backend access
31 * 34 *
32 * Revision 1.1 2002/09/27 17:11:44 eilers 35 * Revision 1.1 2002/09/27 17:11:44 eilers
33 * Added API for accessing the Contact-Database ! It is compiling, but 36 * Added API for accessing the Contact-Database ! It is compiling, but
34 * please do not expect that anything is working ! 37 * please do not expect that anything is working !
35 * I will debug that stuff in the next time .. 38 * I will debug that stuff in the next time ..
36 * Please read README_COMPILE for compiling ! 39 * Please read README_COMPILE for compiling !
37 * 40 *
38 * 41 *
39 */ 42 */
40 43
41#ifndef _OContactAccessBackend_XML_ 44#ifndef _OContactAccessBackend_XML_
42#define _OContactAccessBackend_XML_ 45#define _OContactAccessBackend_XML_
43 46
44#include <qasciidict.h> 47#include <qasciidict.h>
45#include <qdatetime.h> 48#include <qdatetime.h>
46#include <qfile.h> 49#include <qfile.h>
47#include <qfileinfo.h> 50#include <qfileinfo.h>
48#include <qregexp.h> 51#include <qregexp.h>
49#include <qarray.h> 52#include <qarray.h>
53#include <qmap.h>
50 54
51#include <qpe/global.h> 55#include <qpe/global.h>
52 56
53#include <opie/xmltree.h> 57#include <opie/xmltree.h>
54#include "ocontactaccessbackend.h" 58#include "ocontactaccessbackend.h"
55#include "ocontactaccess.h" 59#include "ocontactaccess.h"
56 60
57#include <stdlib.h> 61#include <stdlib.h>
58#include <errno.h> 62#include <errno.h>
59 63
60using namespace Opie; 64using namespace Opie;
61 65
62/* the default xml implementation */ 66/* the default xml implementation */
63class OContactAccessBackend_XML : public OContactAccessBackend { 67class OContactAccessBackend_XML : public OContactAccessBackend {
64 public: 68 public:
65 OContactAccessBackend_XML ( QString appname, QString filename = 0l ): 69 OContactAccessBackend_XML ( QString appname, QString filename = 0l ):
66 m_changed( false ) 70 m_changed( false )
67 { 71 {
68 m_appName = appname; 72 m_appName = appname;
69 73
70 /* Set journalfile name ... */ 74 /* Set journalfile name ... */
71 m_journalName = getenv("HOME"); 75 m_journalName = getenv("HOME");
72 m_journalName +="/.abjournal" + appname; 76 m_journalName +="/.abjournal" + appname;
73 77
74 /* Expecting to access the default filename if nothing else is set */ 78 /* Expecting to access the default filename if nothing else is set */
75 if ( filename.isEmpty() ){ 79 if ( filename.isEmpty() ){
76 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 80 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
77 } else 81 } else
78 m_fileName = filename; 82 m_fileName = filename;
79 83
80 /* Load Database now */ 84 /* Load Database now */
81 load (); 85 load ();
82 } 86 }
83 87
84 bool save() { 88 bool save() {
85 89
86 if ( !m_changed ) 90 if ( !m_changed )
87 return true; 91 return true;
88 92
89 QString strNewFile = m_fileName + ".new"; 93 QString strNewFile = m_fileName + ".new";
90 QFile f( strNewFile ); 94 QFile f( strNewFile );
91 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 95 if ( !f.open( IO_WriteOnly|IO_Raw ) )
92 return false; 96 return false;
93 97
94 int total_written; 98 int total_written;
95 QString out; 99 QString out;
96 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 100 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
97 " <Groups>\n" 101 " <Groups>\n"
98 " </Groups>\n" 102 " </Groups>\n"
99 " <Contacts>\n"; 103 " <Contacts>\n";
100 //QValueList<Contact>::iterator it; 104 //QValueList<Contact>::iterator it;
101 QValueListConstIterator<OContact> it; 105 QValueListConstIterator<OContact> it;
102 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) { 106 for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) {
103 out += "<Contact "; 107 out += "<Contact ";
104 (*it).save( out ); 108 (*it).save( out );
105 out += "/>\n"; 109 out += "/>\n";
106 QCString cstr = out.utf8(); 110 QCString cstr = out.utf8();
107 total_written = f.writeBlock( cstr.data(), cstr.length() ); 111 total_written = f.writeBlock( cstr.data(), cstr.length() );
108 if ( total_written != int(cstr.length()) ) { 112 if ( total_written != int(cstr.length()) ) {
109 f.close(); 113 f.close();
110 QFile::remove( strNewFile ); 114 QFile::remove( strNewFile );
111 return false; 115 return false;
112 } 116 }
113 out = ""; 117 out = "";
114 } 118 }
115 out += " </Contacts>\n</AddressBook>\n"; 119 out += " </Contacts>\n</AddressBook>\n";
116 120
117 QCString cstr = out.utf8(); 121 QCString cstr = out.utf8();
118 total_written = f.writeBlock( cstr.data(), cstr.length() ); 122 total_written = f.writeBlock( cstr.data(), cstr.length() );
119 if ( total_written != int( cstr.length() ) ) { 123 if ( total_written != int( cstr.length() ) ) {
120 f.close(); 124 f.close();
121 QFile::remove( strNewFile ); 125 QFile::remove( strNewFile );
122 return false; 126 return false;
123 } 127 }
124 f.close(); 128 f.close();
125 129
126 // move the file over, I'm just going to use the system call 130 // move the file over, I'm just going to use the system call
127 // because, I don't feel like using QDir. 131 // because, I don't feel like using QDir.
128 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 132 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
129 qWarning( "problem renaming file %s to %s, errno: %d", 133 qWarning( "problem renaming file %s to %s, errno: %d",
130 strNewFile.latin1(), m_journalName.latin1(), errno ); 134 strNewFile.latin1(), m_journalName.latin1(), errno );
131 // remove the tmp file... 135 // remove the tmp file...
132 QFile::remove( strNewFile ); 136 QFile::remove( strNewFile );
133 } 137 }
134 138
135 /* The journalfile should be removed now... */ 139 /* The journalfile should be removed now... */
136 removeJournal(); 140 removeJournal();
137 141
138 m_changed = false; 142 m_changed = false;
139 return true; 143 return true;
140 } 144 }
141 145
142 bool load () { 146 bool load () {
143 m_contactList.clear(); 147 m_contactList.clear();
144 148
145 /* Load XML-File and journal if it exists */ 149 /* Load XML-File and journal if it exists */
146 if ( !load ( m_fileName, false ) ) 150 if ( !load ( m_fileName, false ) )
147 return false; 151 return false;
148 /* The returncode of the journalfile is ignored due to the 152 /* The returncode of the journalfile is ignored due to the
149 * fact that it does not exist when this class is instantiated ! 153 * fact that it does not exist when this class is instantiated !
150 * But there may such a file exist, if the application crashed. 154 * But there may such a file exist, if the application crashed.
151 * Therefore we try to load it to get the changes before the # 155 * Therefore we try to load it to get the changes before the #
152 * crash happened... 156 * crash happened...
153 */ 157 */
154 load (m_journalName, true); 158 load (m_journalName, true);
155 159
156 return true; 160 return true;
157 } 161 }
158 162
159 void clear () { 163 void clear () {
160 m_contactList.clear(); 164 m_contactList.clear();
161 m_changed = false; 165 m_changed = false;
162 166
163 } 167 }
164 168
165 bool wasChangedExternally() 169 bool wasChangedExternally()
166 { 170 {
167 QFileInfo fi( m_fileName ); 171 QFileInfo fi( m_fileName );
168 172
169 QDateTime lastmod = fi.lastModified (); 173 QDateTime lastmod = fi.lastModified ();
170 174
171 return (lastmod != m_readtime); 175 return (lastmod != m_readtime);
172 } 176 }
173 177
174 QArray<int> allRecords() const { 178 QArray<int> allRecords() const {
175 QArray<int> uid_list( m_contactList.count() ); 179 QArray<int> uid_list( m_contactList.count() );
176 180
177 uint counter = 0; 181 uint counter = 0;
178 QValueListConstIterator<OContact> it; 182 QValueListConstIterator<OContact> it;
179 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 183 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
180 uid_list[counter++] = (*it).uid(); 184 uid_list[counter++] = (*it).uid();
181 } 185 }
182 186
183 return ( uid_list ); 187 return ( uid_list );
184 } 188 }
185 189
186 OContact find ( int uid ) const 190 OContact find ( int uid ) const
187 { 191 {
188 bool found = false; 192 bool found = false;
189 OContact foundContact; //Create empty contact 193 OContact foundContact; //Create empty contact
190 194
191 QValueListConstIterator<OContact> it; 195 QValueListConstIterator<OContact> it;
192 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 196 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
193 if ((*it).uid() == uid){ 197 if ((*it).uid() == uid){
194 found = true; 198 found = true;
195 break; 199 break;
196 } 200 }
197 } 201 }
198 if ( found ){ 202 if ( found ){
199 foundContact = *it; 203 foundContact = *it;
200 } 204 }
201 205
202 return ( foundContact ); 206 return ( foundContact );
203 } 207 }
204 208
205 QArray<int> queryByExample ( const OContact &query, int settings ){ 209 QArray<int> queryByExample ( const OContact &query, int settings ){
206 210
207 QArray<int> m_currentQuery( m_contactList.count() ); 211 QArray<int> m_currentQuery( m_contactList.count() );
208 QValueListConstIterator<OContact> it; 212 QValueListConstIterator<OContact> it;
209 uint arraycounter = 0; 213 uint arraycounter = 0;
210 214
211 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 215 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
212 /* Search all fields and compare them with query object. Store them into list 216 /* Search all fields and compare them with query object. Store them into list
213 * if all fields matches. 217 * if all fields matches.
214 */ 218 */
215 bool allcorrect = true; 219 bool allcorrect = true;
216 for ( int i = 0; i < Qtopia::rid; i++ ) { 220 for ( int i = 0; i < Qtopia::rid; i++ ) {
217 /* Just compare fields which are not empty in the query object */ 221 /* Just compare fields which are not empty in the query object */
218 if ( !query.field(i).isEmpty() ){ 222 if ( !query.field(i).isEmpty() ){
219 switch ( settings & ~OContactAccess::IgnoreCase ){ 223 switch ( settings & ~OContactAccess::IgnoreCase ){
220 case OContactAccess::RegExp:{ 224 case OContactAccess::RegExp:{
221 QRegExp expr ( query.field(i), 225 QRegExp expr ( query.field(i),
222 !(settings & OContactAccess::IgnoreCase), 226 !(settings & OContactAccess::IgnoreCase),
223 false ); 227 false );
224 if ( expr.find ( (*it).field(i), 0 ) == -1 ) 228 if ( expr.find ( (*it).field(i), 0 ) == -1 )
225 allcorrect = false; 229 allcorrect = false;
226 } 230 }
227 break; 231 break;
228 case OContactAccess::WildCards:{ 232 case OContactAccess::WildCards:{
229 QRegExp expr ( query.field(i), 233 QRegExp expr ( query.field(i),
230 !(settings & OContactAccess::IgnoreCase), 234 !(settings & OContactAccess::IgnoreCase),
231 true ); 235 true );
232 if ( expr.find ( (*it).field(i), 0 ) == -1 ) 236 if ( expr.find ( (*it).field(i), 0 ) == -1 )
233 allcorrect = false; 237 allcorrect = false;
234 } 238 }
235 break; 239 break;
236 case OContactAccess::ExactMatch:{ 240 case OContactAccess::ExactMatch:{
237 if (settings & OContactAccess::IgnoreCase){ 241 if (settings & OContactAccess::IgnoreCase){
238 if ( query.field(i).upper() != 242 if ( query.field(i).upper() !=
239 (*it).field(i).upper() ) 243 (*it).field(i).upper() )
240 allcorrect = false; 244 allcorrect = false;
241 }else{ 245 }else{
242 if ( query.field(i) != (*it).field(i) ) 246 if ( query.field(i) != (*it).field(i) )
243 allcorrect = false; 247 allcorrect = false;
244 } 248 }
245 } 249 }
246 break; 250 break;
247 } 251 }
248 } 252 }
249 } 253 }
250 if ( allcorrect ){ 254 if ( allcorrect ){
251 m_currentQuery[arraycounter++] = (*it).uid(); 255 m_currentQuery[arraycounter++] = (*it).uid();
252 } 256 }
253 } 257 }
254 258
255 // Shrink to fit.. 259 // Shrink to fit..
256 m_currentQuery.resize(arraycounter); 260 m_currentQuery.resize(arraycounter);
257 261
258 return m_currentQuery; 262 return m_currentQuery;
259 } 263 }
260 264
261 QArray<int> matchRegexp( const QRegExp &r ) const{ 265 QArray<int> matchRegexp( const QRegExp &r ) const{
262 QArray<int> m_currentQuery( m_contactList.count() ); 266 QArray<int> m_currentQuery( m_contactList.count() );
263 QValueListConstIterator<OContact> it; 267 QValueListConstIterator<OContact> it;
264 uint arraycounter = 0; 268 uint arraycounter = 0;
265 269
266 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 270 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
267 if ( (*it).match( r ) ){ 271 if ( (*it).match( r ) ){
268 m_currentQuery[arraycounter++] = (*it).uid(); 272 m_currentQuery[arraycounter++] = (*it).uid();
269 } 273 }
270 274
271 } 275 }
272 // Shrink to fit.. 276 // Shrink to fit..
273 m_currentQuery.resize(arraycounter); 277 m_currentQuery.resize(arraycounter);
274 278
275 return m_currentQuery; 279 return m_currentQuery;
276 } 280 }
277 281
278 const uint querySettings() 282 const uint querySettings()
279 { 283 {
280 return ( OContactAccess::WildCards 284 return ( OContactAccess::WildCards
281 & OContactAccess::IgnoreCase 285 & OContactAccess::IgnoreCase
282 & OContactAccess::RegExp 286 & OContactAccess::RegExp
283 & OContactAccess::ExactMatch ); 287 & OContactAccess::ExactMatch );
284 } 288 }
285 289
286 bool hasQuerySettings (uint querySettings) const 290 bool hasQuerySettings (uint querySettings) const
287 { 291 {
288 /* OContactAccess::IgnoreCase may be added with one 292 /* OContactAccess::IgnoreCase may be added with one
289 * of the other settings, but never used alone. 293 * of the other settings, but never used alone.
290 * The other settings are just valid alone... 294 * The other settings are just valid alone...
291 */ 295 */
292 switch ( querySettings & ~OContactAccess::IgnoreCase ){ 296 switch ( querySettings & ~OContactAccess::IgnoreCase ){
293 case OContactAccess::RegExp: 297 case OContactAccess::RegExp:
294 return ( true ); 298 return ( true );
295 case OContactAccess::WildCards: 299 case OContactAccess::WildCards:
296 return ( true ); 300 return ( true );
297 case OContactAccess::ExactMatch: 301 case OContactAccess::ExactMatch:
298 return ( true ); 302 return ( true );
299 default: 303 default:
300 return ( false ); 304 return ( false );
301 } 305 }
302 } 306 }
303 307
308 // Currently only asc implemented..
309 QArray<int> sorted( bool asc, int , int , int )
310 {
311 QMap<QString, int> nameToUid;
312 QStringList names;
313 QArray<int> m_currentQuery( m_contactList.count() );
314
315 // First fill map and StringList with all Names ( better LastNames ? )
316 // Afterwards sort namelist and use map to fill array to return..
317 QValueListConstIterator<OContact> it;
318 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
319 names.append( (*it).lastName() );
320 nameToUid.insert( (*it).lastName(), (*it).uid() );
321 }
322 names.sort();
323
324 int i = 0;
325 if ( asc ){
326 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
327 m_currentQuery[i++] = nameToUid[ (*it) ];
328 }else{
329 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
330 m_currentQuery[i++] = nameToUid[ (*it) ];
331 }
332
333 return m_currentQuery;
334
335 }
304 bool add ( const OContact &newcontact ) 336 bool add ( const OContact &newcontact )
305 { 337 {
306 //qWarning("odefaultbackend: ACTION::ADD"); 338 //qWarning("odefaultbackend: ACTION::ADD");
307 updateJournal (newcontact, OContact::ACTION_ADD); 339 updateJournal (newcontact, OContact::ACTION_ADD);
308 addContact_p( newcontact ); 340 addContact_p( newcontact );
309 341
310 m_changed = true; 342 m_changed = true;
311 343
312 return true; 344 return true;
313 } 345 }
314 346
315 bool replace ( const OContact &contact ) 347 bool replace ( const OContact &contact )
316 { 348 {
317 m_changed = true; 349 m_changed = true;
318 350
319 bool found = false; 351 bool found = false;
320 352
321 QValueListIterator<OContact> it; 353 QValueListIterator<OContact> it;
322 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 354 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
323 if ( (*it).uid() == contact.uid() ){ 355 if ( (*it).uid() == contact.uid() ){
324 found = true; 356 found = true;
325 break; 357 break;
326 } 358 }
327 } 359 }
328 if (found) { 360 if (found) {
329 updateJournal (contact, OContact::ACTION_REPLACE); 361 updateJournal (contact, OContact::ACTION_REPLACE);
330 m_contactList.remove (it); 362 m_contactList.remove (it);
331 m_contactList.append (contact); 363 m_contactList.append (contact);
332 return true; 364 return true;
333 } else 365 } else
334 return false; 366 return false;
335 } 367 }
336 368
337 bool remove ( int uid ) 369 bool remove ( int uid )
338 { 370 {
339 m_changed = true; 371 m_changed = true;
340 372
341 bool found = false; 373 bool found = false;
342 QValueListIterator<OContact> it; 374 QValueListIterator<OContact> it;
343 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 375 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
344 if ((*it).uid() == uid){ 376 if ((*it).uid() == uid){
345 found = true; 377 found = true;
346 break; 378 break;
347 } 379 }
348 } 380 }
349 if (found) { 381 if (found) {
350 updateJournal ( *it, OContact::ACTION_REMOVE); 382 updateJournal ( *it, OContact::ACTION_REMOVE);
351 m_contactList.remove (it); 383 m_contactList.remove (it);
352 return true; 384 return true;
353 } else 385 } else
354 return false; 386 return false;
355 } 387 }
356 388
357 bool reload(){ 389 bool reload(){
358 /* Reload is the same as load in this implementation */ 390 /* Reload is the same as load in this implementation */
359 return ( load() ); 391 return ( load() );
360 } 392 }
361 393
362 private: 394 private:
363 void addContact_p( const OContact &newcontact ){ 395 void addContact_p( const OContact &newcontact ){
364 m_contactList.append (newcontact); 396 m_contactList.append (newcontact);
365 } 397 }
366 398
367 /* This function loads the xml-database and the journalfile */ 399 /* This function loads the xml-database and the journalfile */
368 bool load( const QString filename, bool isJournal ) { 400 bool load( const QString filename, bool isJournal ) {
369 401
370 /* We use the time of the last read to check if the file was 402 /* We use the time of the last read to check if the file was
371 * changed externally. 403 * changed externally.
372 */ 404 */
373 if ( !isJournal ){ 405 if ( !isJournal ){
374 QFileInfo fi( filename ); 406 QFileInfo fi( filename );
375 m_readtime = fi.lastModified (); 407 m_readtime = fi.lastModified ();
376 } 408 }
377 409
378 const int JOURNALACTION = Qtopia::Notes + 1; 410 const int JOURNALACTION = Qtopia::Notes + 1;
379 const int JOURNALROW = JOURNALACTION + 1; 411 const int JOURNALROW = JOURNALACTION + 1;
380 412
381 bool foundAction = false; 413 bool foundAction = false;
382 OContact::journal_action action = OContact::ACTION_ADD; 414 OContact::journal_action action = OContact::ACTION_ADD;
383 int journalKey = 0; 415 int journalKey = 0;
384 QMap<int, QString> contactMap; 416 QMap<int, QString> contactMap;
385 QMap<QString, QString> customMap; 417 QMap<QString, QString> customMap;
386 QMap<QString, QString>::Iterator customIt; 418 QMap<QString, QString>::Iterator customIt;
387 QAsciiDict<int> dict( 47 ); 419 QAsciiDict<int> dict( 47 );
388 420
389 dict.setAutoDelete( TRUE ); 421 dict.setAutoDelete( TRUE );
390 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 422 dict.insert( "Uid", new int(Qtopia::AddressUid) );
391 dict.insert( "Title", new int(Qtopia::Title) ); 423 dict.insert( "Title", new int(Qtopia::Title) );
392 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 424 dict.insert( "FirstName", new int(Qtopia::FirstName) );
393 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 425 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
394 dict.insert( "LastName", new int(Qtopia::LastName) ); 426 dict.insert( "LastName", new int(Qtopia::LastName) );
395 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 427 dict.insert( "Suffix", new int(Qtopia::Suffix) );
396 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 428 dict.insert( "FileAs", new int(Qtopia::FileAs) );
397 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 429 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
398 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 430 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
399 dict.insert( "Emails", new int(Qtopia::Emails) ); 431 dict.insert( "Emails", new int(Qtopia::Emails) );
400 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 432 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
401 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 433 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
402 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 434 dict.insert( "HomeState", new int(Qtopia::HomeState) );
403 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 435 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
404 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 436 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
405 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 437 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
406 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 438 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
407 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 439 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
408 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 440 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
409 dict.insert( "Company", new int(Qtopia::Company) ); 441 dict.insert( "Company", new int(Qtopia::Company) );
410 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 442 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
411 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 443 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
412 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 444 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
413 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 445 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
414 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 446 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
415 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 447 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
416 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 448 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
417 dict.insert( "Department", new int(Qtopia::Department) ); 449 dict.insert( "Department", new int(Qtopia::Department) );
418 dict.insert( "Office", new int(Qtopia::Office) ); 450 dict.insert( "Office", new int(Qtopia::Office) );
419 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); 451 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
420 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); 452 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
421 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); 453 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
422 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); 454 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
423 dict.insert( "Profession", new int(Qtopia::Profession) ); 455 dict.insert( "Profession", new int(Qtopia::Profession) );
424 dict.insert( "Assistant", new int(Qtopia::Assistant) ); 456 dict.insert( "Assistant", new int(Qtopia::Assistant) );
425 dict.insert( "Manager", new int(Qtopia::Manager) ); 457 dict.insert( "Manager", new int(Qtopia::Manager) );
426 dict.insert( "Spouse", new int(Qtopia::Spouse) ); 458 dict.insert( "Spouse", new int(Qtopia::Spouse) );
427 dict.insert( "Children", new int(Qtopia::Children) ); 459 dict.insert( "Children", new int(Qtopia::Children) );
428 dict.insert( "Gender", new int(Qtopia::Gender) ); 460 dict.insert( "Gender", new int(Qtopia::Gender) );
429 dict.insert( "Birthday", new int(Qtopia::Birthday) ); 461 dict.insert( "Birthday", new int(Qtopia::Birthday) );
430 dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); 462 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
431 dict.insert( "Nickname", new int(Qtopia::Nickname) ); 463 dict.insert( "Nickname", new int(Qtopia::Nickname) );
432 dict.insert( "Notes", new int(Qtopia::Notes) ); 464 dict.insert( "Notes", new int(Qtopia::Notes) );
433 dict.insert( "action", new int(JOURNALACTION) ); 465 dict.insert( "action", new int(JOURNALACTION) );
434 dict.insert( "actionrow", new int(JOURNALROW) ); 466 dict.insert( "actionrow", new int(JOURNALROW) );
435 467
436 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() ); 468 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() );
437 469
438 XMLElement *root = XMLElement::load( filename ); 470 XMLElement *root = XMLElement::load( filename );
439 if(root != 0l ){ // start parsing 471 if(root != 0l ){ // start parsing
440 /* Parse all XML-Elements and put the data into the 472 /* Parse all XML-Elements and put the data into the
441 * Contact-Class 473 * Contact-Class
442 */ 474 */
443 XMLElement *element = root->firstChild(); 475 XMLElement *element = root->firstChild();
444 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() ); 476 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() );
445 element = element->firstChild(); 477 element = element->firstChild();
446 478
447 /* Search Tag "Contacts" which is the parent of all Contacts */ 479 /* Search Tag "Contacts" which is the parent of all Contacts */
448 while( element && !isJournal ){ 480 while( element && !isJournal ){
449 if( element->tagName() != QString::fromLatin1("Contacts") ){ 481 if( element->tagName() != QString::fromLatin1("Contacts") ){
450 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s", 482 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s",
451 // element->tagName().latin1()); 483 // element->tagName().latin1());
452 element = element->nextChild(); 484 element = element->nextChild();
453 } else { 485 } else {
454 element = element->firstChild(); 486 element = element->firstChild();
455 break; 487 break;
456 } 488 }
457 } 489 }
458 /* Parse all Contacts and ignore unknown tags */ 490 /* Parse all Contacts and ignore unknown tags */
459 while( element ){ 491 while( element ){
460 if( element->tagName() != QString::fromLatin1("Contact") ){ 492 if( element->tagName() != QString::fromLatin1("Contact") ){
461 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s", 493 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s",
462 // element->tagName().latin1()); 494 // element->tagName().latin1());
463 element = element->nextChild(); 495 element = element->nextChild();
464 continue; 496 continue;
465 } 497 }
466 /* Found alement with tagname "contact", now parse and store all 498 /* Found alement with tagname "contact", now parse and store all
467 * attributes contained 499 * attributes contained
468 */ 500 */
469 //qWarning("OContactDefBack::load element tagName() : %s", 501 //qWarning("OContactDefBack::load element tagName() : %s",
470 // element->tagName().latin1() ); 502 // element->tagName().latin1() );
471 QString dummy; 503 QString dummy;
472 foundAction = false; 504 foundAction = false;
473 505
474 XMLElement::AttributeMap aMap = element->attributes(); 506 XMLElement::AttributeMap aMap = element->attributes();
475 XMLElement::AttributeMap::Iterator it; 507 XMLElement::AttributeMap::Iterator it;
476 contactMap.clear(); 508 contactMap.clear();
477 customMap.clear(); 509 customMap.clear();
478 for( it = aMap.begin(); it != aMap.end(); ++it ){ 510 for( it = aMap.begin(); it != aMap.end(); ++it ){
479 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); 511 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1());
480 512
481 int *find = dict[ it.key() ]; 513 int *find = dict[ it.key() ];
482 /* Unknown attributes will be stored as "Custom" elements */ 514 /* Unknown attributes will be stored as "Custom" elements */
483 if ( !find ) { 515 if ( !find ) {
484 qWarning("Attribute %s not known.", it.key().latin1()); 516 qWarning("Attribute %s not known.", it.key().latin1());
485 //contact.setCustomField(it.key(), it.data()); 517 //contact.setCustomField(it.key(), it.data());
486 customMap.insert( it.key(), it.data() ); 518 customMap.insert( it.key(), it.data() );
487 continue; 519 continue;
488 } 520 }
489 521
490 /* Check if special conversion is needed and add attribute 522 /* Check if special conversion is needed and add attribute
491 * into Contact class 523 * into Contact class
492 */ 524 */
493 switch( *find ) { 525 switch( *find ) {
494 /* 526 /*
495 case Qtopia::AddressUid: 527 case Qtopia::AddressUid:
diff --git a/libopie2/opiepim/core/ocontactaccess.cpp b/libopie2/opiepim/core/ocontactaccess.cpp
index f868b53..9c9338e 100644
--- a/libopie2/opiepim/core/ocontactaccess.cpp
+++ b/libopie2/opiepim/core/ocontactaccess.cpp
@@ -1,161 +1,169 @@
1/* 1/*
2 * Class to manage the Contacts. 2 * Class to manage the Contacts.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * Info: This class could just work with a change in the header-file 12 * Info: This class could just work with a change in the header-file
13 * of the Contact class ! Therefore our libopie only compiles 13 * of the Contact class ! Therefore our libopie only compiles
14 * with our version of libqpe 14 * with our version of libqpe
15 * ===================================================================== 15 * =====================================================================
16 * ToDo: XML-Backend: Automatic reload if something was changed... 16 * ToDo: XML-Backend: Automatic reload if something was changed...
17 * 17 *
18 * 18 *
19 * ===================================================================== 19 * =====================================================================
20 * Version: $Id$ 20 * Version: $Id$
21 * ===================================================================== 21 * =====================================================================
22 * History: 22 * History:
23 * $Log$ 23 * $Log$
24 * Revision 1.7 2002/11/13 14:14:51 eilers
25 * Added sorted for Contacts..
26 *
24 * Revision 1.6 2002/11/01 15:10:42 eilers 27 * Revision 1.6 2002/11/01 15:10:42 eilers
25 * Added regExp-search in database for all fields in a contact. 28 * Added regExp-search in database for all fields in a contact.
26 * 29 *
27 * Revision 1.5 2002/10/16 10:52:40 eilers 30 * Revision 1.5 2002/10/16 10:52:40 eilers
28 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 31 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
29 * 32 *
30 * Revision 1.4 2002/10/14 16:21:54 eilers 33 * Revision 1.4 2002/10/14 16:21:54 eilers
31 * Some minor interface updates 34 * Some minor interface updates
32 * 35 *
33 * Revision 1.3 2002/10/07 17:34:24 eilers 36 * Revision 1.3 2002/10/07 17:34:24 eilers
34 * added OBackendFactory for advanced backend access 37 * added OBackendFactory for advanced backend access
35 * 38 *
36 * Revision 1.2 2002/10/02 16:18:11 eilers 39 * Revision 1.2 2002/10/02 16:18:11 eilers
37 * debugged and seems to work almost perfectly .. 40 * debugged and seems to work almost perfectly ..
38 * 41 *
39 * Revision 1.1 2002/09/27 17:11:44 eilers 42 * Revision 1.1 2002/09/27 17:11:44 eilers
40 * Added API for accessing the Contact-Database ! It is compiling, but 43 * Added API for accessing the Contact-Database ! It is compiling, but
41 * please do not expect that anything is working ! 44 * please do not expect that anything is working !
42 * I will debug that stuff in the next time .. 45 * I will debug that stuff in the next time ..
43 * Please read README_COMPILE for compiling ! 46 * Please read README_COMPILE for compiling !
44 * 47 *
45 * 48 *
46 */ 49 */
47 50
48#include "ocontactaccess.h" 51#include "ocontactaccess.h"
49#include "obackendfactory.h" 52#include "obackendfactory.h"
50 53
51#include <qasciidict.h> 54#include <qasciidict.h>
52#include <qdatetime.h> 55#include <qdatetime.h>
53#include <qfile.h> 56#include <qfile.h>
54#include <qregexp.h> 57#include <qregexp.h>
55#include <qlist.h> 58#include <qlist.h>
56#include <qcopchannel_qws.h> 59#include <qcopchannel_qws.h>
57 60
58//#include <qpe/qcopenvelope_qws.h> 61//#include <qpe/qcopenvelope_qws.h>
59#include <qpe/global.h> 62#include <qpe/global.h>
60 63
61#include <errno.h> 64#include <errno.h>
62#include <fcntl.h> 65#include <fcntl.h>
63#include <unistd.h> 66#include <unistd.h>
64#include <stdlib.h> 67#include <stdlib.h>
65 68
66#include "ocontactaccessbackend_xml.h" 69#include "ocontactaccessbackend_xml.h"
67 70
68 71
69OContactAccess::OContactAccess ( const QString appname, const QString , 72OContactAccess::OContactAccess ( const QString appname, const QString ,
70 OContactAccessBackend* end, bool autosync ): 73 OContactAccessBackend* end, bool autosync ):
71 OPimAccessTemplate<OContact>( end ) 74 OPimAccessTemplate<OContact>( end )
72{ 75{
73 /* take care of the backend. If there is no one defined, we 76 /* take care of the backend. If there is no one defined, we
74 * will use the XML-Backend as default (until we have a cute SQL-Backend..). 77 * will use the XML-Backend as default (until we have a cute SQL-Backend..).
75 */ 78 */
76 if( end == 0 ) { 79 if( end == 0 ) {
77 qWarning ("Using BackendFactory !"); 80 qWarning ("Using BackendFactory !");
78 end = OBackendFactory<OContactAccessBackend>::Default( "contact", appname ); 81 end = OBackendFactory<OContactAccessBackend>::Default( "contact", appname );
79 } 82 }
80 // Set backend locally and in template 83 // Set backend locally and in template
81 m_backEnd = end; 84 m_backEnd = end;
82 OPimAccessTemplate<OContact>::setBackEnd (end); 85 OPimAccessTemplate<OContact>::setBackEnd (end);
83 86
84 87
85 /* Connect signal of external db change to function */ 88 /* Connect signal of external db change to function */
86 QCopChannel *dbchannel = new QCopChannel( "QPE/PIM", this ); 89 QCopChannel *dbchannel = new QCopChannel( "QPE/PIM", this );
87 connect( dbchannel, SIGNAL(received(const QCString &, const QByteArray &)), 90 connect( dbchannel, SIGNAL(received(const QCString &, const QByteArray &)),
88 this, SLOT(copMessage( const QCString &, const QByteArray &)) ); 91 this, SLOT(copMessage( const QCString &, const QByteArray &)) );
89 if ( autosync ){ 92 if ( autosync ){
90 QCopChannel *syncchannel = new QCopChannel( "QPE/Sync", this ); 93 QCopChannel *syncchannel = new QCopChannel( "QPE/Sync", this );
91 connect( syncchannel, SIGNAL(received(const QCString &, const QByteArray &)), 94 connect( syncchannel, SIGNAL(received(const QCString &, const QByteArray &)),
92 this, SLOT(copMessage( const QCString &, const QByteArray &)) ); 95 this, SLOT(copMessage( const QCString &, const QByteArray &)) );
93 } 96 }
94 97
95 98
96} 99}
97OContactAccess::~OContactAccess () 100OContactAccess::~OContactAccess ()
98{ 101{
99 /* The user may forget to save the changed database, therefore try to 102 /* The user may forget to save the changed database, therefore try to
100 * do it for him.. 103 * do it for him..
101 */ 104 */
102 save(); 105 save();
103 // delete m_backEnd; is done by template.. 106 // delete m_backEnd; is done by template..
104} 107}
105 108
106 109
107bool OContactAccess::save () 110bool OContactAccess::save ()
108{ 111{
109 /* If the database was changed externally, we could not save the 112 /* If the database was changed externally, we could not save the
110 * Data. This will remove added items which is unacceptable ! 113 * Data. This will remove added items which is unacceptable !
111 * Therefore: Reload database and merge the data... 114 * Therefore: Reload database and merge the data...
112 */ 115 */
113 if ( OPimAccessTemplate<OContact>::wasChangedExternally() ) 116 if ( OPimAccessTemplate<OContact>::wasChangedExternally() )
114 reload(); 117 reload();
115 118
116 bool status = OPimAccessTemplate<OContact>::save(); 119 bool status = OPimAccessTemplate<OContact>::save();
117 if ( !status ) return false; 120 if ( !status ) return false;
118 121
119 /* Now tell everyone that new data is available. 122 /* Now tell everyone that new data is available.
120 */ 123 */
121 QCopEnvelope e( "QPE/PIM", "addressbookUpdated()" ); 124 QCopEnvelope e( "QPE/PIM", "addressbookUpdated()" );
122 125
123 return true; 126 return true;
124} 127}
125 128
126ORecordList<OContact> OContactAccess::matchRegexp( const QRegExp &r ) const{ 129ORecordList<OContact> OContactAccess::matchRegexp( const QRegExp &r ) const{
127 QArray<int> matchingContacts = m_backEnd -> matchRegexp( r ); 130 QArray<int> matchingContacts = m_backEnd -> matchRegexp( r );
128 return ( ORecordList<OContact>(matchingContacts, this) ); 131 return ( ORecordList<OContact>(matchingContacts, this) );
129} 132}
130 133
131const uint OContactAccess::querySettings() 134const uint OContactAccess::querySettings()
132{ 135{
133 return ( m_backEnd->querySettings() ); 136 return ( m_backEnd->querySettings() );
134} 137}
135 138
136bool OContactAccess::hasQuerySettings ( int querySettings ) const 139bool OContactAccess::hasQuerySettings ( int querySettings ) const
137{ 140{
138 return ( m_backEnd->hasQuerySettings ( querySettings ) ); 141 return ( m_backEnd->hasQuerySettings ( querySettings ) );
139} 142}
143ORecordList<OContact> OContactAccess::sorted( bool ascending, int sortOrder, int sortFilter, int cat ) const
144{
145 QArray<int> matchingContacts = m_backEnd -> sorted( ascending, sortOrder, sortFilter, cat );
146 return ( ORecordList<OContact>(matchingContacts, this) );
147}
140 148
141 149
142bool OContactAccess::wasChangedExternally()const 150bool OContactAccess::wasChangedExternally()const
143{ 151{
144 return ( m_backEnd->wasChangedExternally() ); 152 return ( m_backEnd->wasChangedExternally() );
145} 153}
146 154
147 155
148void OContactAccess::copMessage( const QCString &msg, const QByteArray & ) 156void OContactAccess::copMessage( const QCString &msg, const QByteArray & )
149{ 157{
150 if ( msg == "addressbookUpdated()" ){ 158 if ( msg == "addressbookUpdated()" ){
151 qWarning ("OContactAccess: Received addressbokUpdated()"); 159 qWarning ("OContactAccess: Received addressbokUpdated()");
152 emit signalChanged ( this ); 160 emit signalChanged ( this );
153 } else if ( msg == "flush()" ) { 161 } else if ( msg == "flush()" ) {
154 qWarning ("OContactAccess: Received flush()"); 162 qWarning ("OContactAccess: Received flush()");
155 save (); 163 save ();
156 } else if ( msg == "reload()" ) { 164 } else if ( msg == "reload()" ) {
157 qWarning ("OContactAccess: Received reload()"); 165 qWarning ("OContactAccess: Received reload()");
158 reload (); 166 reload ();
159 emit signalChanged ( this ); 167 emit signalChanged ( this );
160 } 168 }
161} 169}
diff --git a/libopie2/opiepim/core/ocontactaccess.h b/libopie2/opiepim/core/ocontactaccess.h
index b4921d5..961968f 100644
--- a/libopie2/opiepim/core/ocontactaccess.h
+++ b/libopie2/opiepim/core/ocontactaccess.h
@@ -1,139 +1,150 @@
1/* 1/*
2 * Class to manage the Contacts. 2 * Class to manage the Contacts.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) 5 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org)
6 * 6 *
7 * ===================================================================== 7 * =====================================================================
8 *This program is free software; you can redistribute it and/or 8 *This program is free software; you can redistribute it and/or
9 *modify it under the terms of the GNU Library General Public 9 *modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; 10 * License as published by the Free Software Foundation;
11 * either version 2 of the License, or (at your option) any later 11 * either version 2 of the License, or (at your option) any later
12 * version. 12 * version.
13 * ===================================================================== 13 * =====================================================================
14 * ToDo: Define enum for query settings 14 * ToDo: Define enum for query settings
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.5 2002/11/13 14:14:51 eilers
21 * Added sorted for Contacts..
22 *
20 * Revision 1.4 2002/11/01 15:10:42 eilers 23 * Revision 1.4 2002/11/01 15:10:42 eilers
21 * Added regExp-search in database for all fields in a contact. 24 * Added regExp-search in database for all fields in a contact.
22 * 25 *
23 * Revision 1.3 2002/10/16 10:52:40 eilers 26 * Revision 1.3 2002/10/16 10:52:40 eilers
24 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 27 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
25 * 28 *
26 * Revision 1.2 2002/10/14 16:21:54 eilers 29 * Revision 1.2 2002/10/14 16:21:54 eilers
27 * Some minor interface updates 30 * Some minor interface updates
28 * 31 *
29 * Revision 1.1 2002/09/27 17:11:44 eilers 32 * Revision 1.1 2002/09/27 17:11:44 eilers
30 * Added API for accessing the Contact-Database ! It is compiling, but 33 * Added API for accessing the Contact-Database ! It is compiling, but
31 * please do not expect that anything is working ! 34 * please do not expect that anything is working !
32 * I will debug that stuff in the next time .. 35 * I will debug that stuff in the next time ..
33 * Please read README_COMPILE for compiling ! 36 * Please read README_COMPILE for compiling !
34 * 37 *
35 * ===================================================================== 38 * =====================================================================
36 */ 39 */
37#ifndef _OCONTACTACCESS_H 40#ifndef _OCONTACTACCESS_H
38#define _OCONTACTACCESS_H 41#define _OCONTACTACCESS_H
39 42
40#include <qobject.h> 43#include <qobject.h>
41 44
42#include <qpe/qcopenvelope_qws.h> 45#include <qpe/qcopenvelope_qws.h>
43 46
44#include <qvaluelist.h> 47#include <qvaluelist.h>
45#include <qfileinfo.h> 48#include <qfileinfo.h>
46 49
47#include "ocontact.h" 50#include "ocontact.h"
48#include "ocontactaccessbackend.h" 51#include "ocontactaccessbackend.h"
49#include "opimaccesstemplate.h" 52#include "opimaccesstemplate.h"
50 53
51/** Class to access the contacts database. 54/** Class to access the contacts database.
52 * This is just a frontend for the real database handling which is 55 * This is just a frontend for the real database handling which is
53 * done by the backend. 56 * done by the backend.
54 * @see OPimAccessTemplate 57 * @see OPimAccessTemplate
55 */ 58 */
56class OContactAccess: public QObject, public OPimAccessTemplate<OContact> 59class OContactAccess: public QObject, public OPimAccessTemplate<OContact>
57{ 60{
58 Q_OBJECT 61 Q_OBJECT
59 62
60 public: 63 public:
61 /** Create Database with contacts (addressbook). 64 /** Create Database with contacts (addressbook).
62 * @param appname Name of application which wants access to the database 65 * @param appname Name of application which wants access to the database
63 * (i.e. "todolist") 66 * (i.e. "todolist")
64 * @param filename The name of the database file. If not set, the default one 67 * @param filename The name of the database file. If not set, the default one
65 * is used. 68 * is used.
66 * @param backend Pointer to an alternative Backend. If not set, we will use 69 * @param backend Pointer to an alternative Backend. If not set, we will use
67 * the default backend. 70 * the default backend.
68 * @param handlesync If <b>true</b> the database stores the current state 71 * @param handlesync If <b>true</b> the database stores the current state
69 * automatically if it receives the signals <i>flush()</i> and <i>reload()</i> 72 * automatically if it receives the signals <i>flush()</i> and <i>reload()</i>
70 * which are used before and after synchronisation. If the application wants 73 * which are used before and after synchronisation. If the application wants
71 * to react itself, it should be disabled by setting it to <b>false</b> 74 * to react itself, it should be disabled by setting it to <b>false</b>
72 * @see OContactAccessBackend 75 * @see OContactAccessBackend
73 */ 76 */
74 OContactAccess (const QString appname, const QString filename = 0l, 77 OContactAccess (const QString appname, const QString filename = 0l,
75 OContactAccessBackend* backend = 0l, bool handlesync = true); 78 OContactAccessBackend* backend = 0l, bool handlesync = true);
76 ~OContactAccess (); 79 ~OContactAccess ();
77 80
78 /** Constants for query. 81 /** Constants for query.
79 * Use this constants to set the query parameters. 82 * Use this constants to set the query parameters.
80 * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes ! 83 * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes !
81 * @see queryByExample() 84 * @see queryByExample()
82 */ 85 */
83 enum QuerySettings { 86 enum QuerySettings {
84 WildCards = 0x0001, 87 WildCards = 0x0001,
85 IgnoreCase = 0x0002, 88 IgnoreCase = 0x0002,
86 RegExp = 0x0004, 89 RegExp = 0x0004,
87 ExactMatch = 0x0008, 90 ExactMatch = 0x0008,
88 MatchOne = 0x0010 // Only one Entry must match 91 MatchOne = 0x0010 // Only one Entry must match
89 }; 92 };
90 93
91 94
92 ORecordList<OContact> matchRegexp( const QRegExp &r )const; 95 ORecordList<OContact> matchRegexp( const QRegExp &r )const;
93 96
97 /** Return all Contacts in a sorted manner.
98 * @param ascending true: Sorted in acending order.
99 * @param sortOrder Currently not implemented. Just defined to stay compatible to otodoaccess
100 * @param sortFilter Currently not implemented. Just defined to stay compatible to otodoaccess
101 * @param cat Currently not implemented. Just defined to stay compatible to otodoaccess
102 */
103 List sorted( bool ascending, int sortOrder, int sortFilter, int cat ) const;
104
94 /** Return all possible settings. 105 /** Return all possible settings.
95 * @return All settings provided by the current backend 106 * @return All settings provided by the current backend
96 * (i.e.: query_WildCards & query_IgnoreCase) 107 * (i.e.: query_WildCards & query_IgnoreCase)
97 */ 108 */
98 const uint querySettings(); 109 const uint querySettings();
99 110
100 /** Check whether settings are correct. 111 /** Check whether settings are correct.
101 * @return <i>true</i> if the given settings are correct and possible. 112 * @return <i>true</i> if the given settings are correct and possible.
102 */ 113 */
103 bool hasQuerySettings ( int querySettings ) const; 114 bool hasQuerySettings ( int querySettings ) const;
104 115
105 /** 116 /**
106 * if the resource was changed externally. 117 * if the resource was changed externally.
107 * You should use the signal instead of polling possible changes ! 118 * You should use the signal instead of polling possible changes !
108 */ 119 */
109 bool wasChangedExternally()const; 120 bool wasChangedExternally()const;
110 121
111 122
112 /** Save contacts database. 123 /** Save contacts database.
113 * Save is more a "commit". After calling this function, all changes are public available. 124 * Save is more a "commit". After calling this function, all changes are public available.
114 * @return true if successful 125 * @return true if successful
115 */ 126 */
116 bool save(); 127 bool save();
117 128
118 signals: 129 signals:
119 /* Signal is emitted if the database was changed. Therefore 130 /* Signal is emitted if the database was changed. Therefore
120 * we may need to reload to stay consistent. 131 * we may need to reload to stay consistent.
121 * @param which Pointer to the database who created this event. This pointer 132 * @param which Pointer to the database who created this event. This pointer
122 * is useful if an application has to handle multiple databases at the same time. 133 * is useful if an application has to handle multiple databases at the same time.
123 * @see reload() 134 * @see reload()
124 */ 135 */
125 void signalChanged ( const OContactAccess *which ); 136 void signalChanged ( const OContactAccess *which );
126 137
127 138
128 private: 139 private:
129 // class OContactAccessPrivate; 140 // class OContactAccessPrivate;
130 // OContactAccessPrivate* d; 141 // OContactAccessPrivate* d;
131 OContactAccessBackend *m_backEnd; 142 OContactAccessBackend *m_backEnd;
132 bool m_loading:1; 143 bool m_loading:1;
133 144
134 private slots: 145 private slots:
135 void copMessage( const QCString &msg, const QByteArray &data ); 146 void copMessage( const QCString &msg, const QByteArray &data );
136 147
137 148
138}; 149};
139#endif 150#endif