-rw-r--r-- | libopie/pim/obackendfactory.h | 16 | ||||
-rw-r--r-- | libopie/pim/ocontact.h | 13 | ||||
-rw-r--r-- | libopie/pim/ocontactaccessbackend_sql.cpp | 664 | ||||
-rw-r--r-- | libopie/pim/ocontactaccessbackend_sql.h | 96 | ||||
-rw-r--r-- | libopie/pim/ocontactaccessbackend_xml.cpp | 7 | ||||
-rw-r--r-- | libopie/pim/ocontactaccessbackend_xml.h | 6 | ||||
-rw-r--r-- | libopie/pim/ocontactfields.cpp | 456 | ||||
-rw-r--r-- | libopie/pim/ocontactfields.h | 60 | ||||
-rw-r--r-- | libopie/pim/otodoaccesssql.cpp | 73 | ||||
-rw-r--r-- | libopie/pim/otodoaccesssql.h | 6 | ||||
-rw-r--r-- | libopie/pim/test/converter.cpp | 64 | ||||
-rw-r--r-- | libopie/pim/test/converter.pro | 12 | ||||
-rw-r--r-- | libopie/pim/test/converter_base.ui | 43 |
13 files changed, 1492 insertions, 24 deletions
diff --git a/libopie/pim/obackendfactory.h b/libopie/pim/obackendfactory.h index f3c339d..3567687 100644 --- a/libopie/pim/obackendfactory.h +++ b/libopie/pim/obackendfactory.h | |||
@@ -1,166 +1,176 @@ | |||
1 | /* | 1 | /* |
2 | * Class to manage Backends. | 2 | * Class to manage Backends. |
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; | 9 | * License as published by the Free Software Foundation; |
10 | * either version 2 of the License, or (at your option) any later | 10 | * either version 2 of the License, or (at your option) any later |
11 | * version. | 11 | * version. |
12 | * ===================================================================== | 12 | * ===================================================================== |
13 | * ToDo: Use plugins | 13 | * ToDo: Use plugins |
14 | * ===================================================================== | 14 | * ===================================================================== |
15 | * Version: $Id$ | 15 | * Version: $Id$ |
16 | * ===================================================================== | 16 | * ===================================================================== |
17 | * History: | 17 | * History: |
18 | * $Log$ | 18 | * $Log$ |
19 | * Revision 1.8 2003/09/22 14:31:16 eilers | ||
20 | * Added first experimental incarnation of sql-backend for addressbook. | ||
21 | * Some modifications to be able to compile the todo sql-backend. | ||
22 | * A lot of changes fill follow... | ||
23 | * | ||
19 | * Revision 1.7 2003/08/01 12:30:16 eilers | 24 | * Revision 1.7 2003/08/01 12:30:16 eilers |
20 | * Merging changes from BRANCH_1_0 to HEAD | 25 | * Merging changes from BRANCH_1_0 to HEAD |
21 | * | 26 | * |
22 | * Revision 1.6.4.1 2003/06/30 14:34:19 eilers | 27 | * Revision 1.6.4.1 2003/06/30 14:34:19 eilers |
23 | * Patches from Zecke: | 28 | * Patches from Zecke: |
24 | * Fixing and cleaning up extraMap handling | 29 | * Fixing and cleaning up extraMap handling |
25 | * Adding d_ptr for binary compatibility in the future | 30 | * Adding d_ptr for binary compatibility in the future |
26 | * | 31 | * |
27 | * Revision 1.6 2003/04/13 18:07:10 zecke | 32 | * Revision 1.6 2003/04/13 18:07:10 zecke |
28 | * More API doc | 33 | * More API doc |
29 | * QString -> const QString& | 34 | * QString -> const QString& |
30 | * QString = 0l -> QString::null | 35 | * QString = 0l -> QString::null |
31 | * | 36 | * |
32 | * Revision 1.5 2003/02/21 23:31:52 zecke | 37 | * Revision 1.5 2003/02/21 23:31:52 zecke |
33 | * Add XML datebookresource | 38 | * Add XML datebookresource |
34 | * -clean up todoaccessxml header | 39 | * -clean up todoaccessxml header |
35 | * -implement some more stuff in the oeven tester | 40 | * -implement some more stuff in the oeven tester |
36 | * -extend DefaultFactory to not crash and to use datebook | 41 | * -extend DefaultFactory to not crash and to use datebook |
37 | * | 42 | * |
38 | * -reading of OEvents is working nicely.. saving will be added | 43 | * -reading of OEvents is working nicely.. saving will be added |
39 | * tomorrow | 44 | * tomorrow |
40 | * -fix spelling in ODateBookAcces | 45 | * -fix spelling in ODateBookAcces |
41 | * | 46 | * |
42 | * Revision 1.4 2002/10/14 15:55:18 eilers | 47 | * Revision 1.4 2002/10/14 15:55:18 eilers |
43 | * Redeactivate SQL.. ;) | 48 | * Redeactivate SQL.. ;) |
44 | * | 49 | * |
45 | * Revision 1.3 2002/10/10 17:08:58 zecke | 50 | * Revision 1.3 2002/10/10 17:08:58 zecke |
46 | * The Cache is finally in place | 51 | * The Cache is finally in place |
47 | * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;) | 52 | * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;) |
48 | * The read ahead functionality does not make sense for XMLs backends because most of the stuff is already in memory. While using readahead on SQL makes things a lot faster.... | 53 | * The read ahead functionality does not make sense for XMLs backends because most of the stuff is already in memory. While using readahead on SQL makes things a lot faster.... |
49 | * I still have to fully implement read ahead | 54 | * I still have to fully implement read ahead |
50 | * This change is bic but sc | 55 | * This change is bic but sc |
51 | * | 56 | * |
52 | * Revision 1.2 2002/10/08 09:27:36 eilers | 57 | * Revision 1.2 2002/10/08 09:27:36 eilers |
53 | * Fixed libopie.pro to include the new pim-API. | 58 | * Fixed libopie.pro to include the new pim-API. |
54 | * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to | 59 | * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to |
55 | * compile itself would need to install libsqlite, libopiesql... | 60 | * compile itself would need to install libsqlite, libopiesql... |
56 | * Therefore, the backend currently uses XML only.. | 61 | * Therefore, the backend currently uses XML only.. |
57 | * | 62 | * |
58 | * Revision 1.1 2002/10/07 17:35:01 eilers | 63 | * Revision 1.1 2002/10/07 17:35:01 eilers |
59 | * added OBackendFactory for advanced backend access | 64 | * added OBackendFactory for advanced backend access |
60 | * | 65 | * |
61 | * | 66 | * |
62 | * ===================================================================== | 67 | * ===================================================================== |
63 | */ | 68 | */ |
64 | #ifndef OPIE_BACKENDFACTORY_H_ | 69 | #ifndef OPIE_BACKENDFACTORY_H_ |
65 | #define OPIE_BACKENDFACTORY_H_ | 70 | #define OPIE_BACKENDFACTORY_H_ |
66 | 71 | ||
67 | #include <qstring.h> | 72 | #include <qstring.h> |
68 | #include <qasciidict.h> | 73 | #include <qasciidict.h> |
69 | #include <qpe/config.h> | 74 | #include <qpe/config.h> |
70 | 75 | ||
71 | #include "otodoaccessxml.h" | 76 | #include "otodoaccessxml.h" |
72 | #include "ocontactaccessbackend_xml.h" | 77 | #include "ocontactaccessbackend_xml.h" |
73 | #include "odatebookaccessbackend_xml.h" | 78 | #include "odatebookaccessbackend_xml.h" |
74 | 79 | ||
75 | #ifdef __USE_SQL | 80 | #ifdef __USE_SQL |
76 | #include "otodoaccesssql.h" | 81 | #include "otodoaccesssql.h" |
82 | #include "ocontactaccessbackend_sql.h" | ||
77 | #endif | 83 | #endif |
78 | 84 | ||
79 | class OBackendPrivate; | 85 | class OBackendPrivate; |
80 | 86 | ||
81 | /** | 87 | /** |
82 | * This class is our factory. It will give us the default implementations | 88 | * This class is our factory. It will give us the default implementations |
83 | * of at least Todolist, Contacts and Datebook. In the future this class will | 89 | * of at least Todolist, Contacts and Datebook. In the future this class will |
84 | * allow users to switch the backend with ( XML->SQLite ) without the need | 90 | * allow users to switch the backend with ( XML->SQLite ) without the need |
85 | * to recompile.# | 91 | * to recompile.# |
86 | * This class as the whole PIM Api is making use of templates | 92 | * This class as the whole PIM Api is making use of templates |
87 | * | 93 | * |
88 | * <pre> | 94 | * <pre> |
89 | * OTodoAccessBackend* backend = OBackEndFactory<OTodoAccessBackend>::Default("todo", QString::null ); | 95 | * OTodoAccessBackend* backend = OBackEndFactory<OTodoAccessBackend>::Default("todo", QString::null ); |
90 | * backend->load(); | 96 | * backend->load(); |
91 | * </pre> | 97 | * </pre> |
92 | * | 98 | * |
93 | * @author Stefan Eilers | 99 | * @author Stefan Eilers |
94 | * @version 0.1 | 100 | * @version 0.1 |
95 | */ | 101 | */ |
96 | template<class T> | 102 | template<class T> |
97 | class OBackendFactory | 103 | class OBackendFactory |
98 | { | 104 | { |
99 | public: | 105 | public: |
100 | OBackendFactory() {}; | 106 | OBackendFactory() {}; |
101 | 107 | ||
102 | enum BACKENDS { | 108 | enum BACKENDS { |
103 | TODO, | 109 | TODO, |
104 | CONTACT, | 110 | CONTACT, |
105 | DATE | 111 | DATE |
106 | }; | 112 | }; |
107 | 113 | ||
108 | /** | 114 | /** |
109 | * Returns a backend implementation for backendName | 115 | * Returns a backend implementation for backendName |
110 | * @param backendName the type of the backend | 116 | * @param backendName the type of the backend |
111 | * @param appName will be passed on to the backend | 117 | * @param appName will be passed on to the backend |
112 | */ | 118 | */ |
113 | static T* Default( const QString backendName, const QString& appName ){ | 119 | static T* Default( const QString backendName, const QString& appName ){ |
114 | 120 | ||
115 | // __asm__("int3"); | 121 | // __asm__("int3"); |
116 | 122 | ||
117 | Config config( "pimaccess" ); | 123 | Config config( "pimaccess" ); |
118 | config.setGroup ( backendName ); | 124 | config.setGroup ( backendName ); |
119 | QString backend = config.readEntry( "usebackend" ); | 125 | QString backend = config.readEntry( "usebackend" ); |
120 | 126 | ||
127 | qWarning("Selected backend for %s is: %s", backendName.latin1(), backend.latin1() ); | ||
128 | |||
121 | QAsciiDict<int> dict ( 3 ); | 129 | QAsciiDict<int> dict ( 3 ); |
122 | dict.setAutoDelete ( TRUE ); | 130 | dict.setAutoDelete ( TRUE ); |
123 | 131 | ||
124 | dict.insert( "todo", new int (TODO) ); | 132 | dict.insert( "todo", new int (TODO) ); |
125 | dict.insert( "contact", new int (CONTACT) ); | 133 | dict.insert( "contact", new int (CONTACT) ); |
126 | dict.insert( "datebook", new int(DATE) ); | 134 | dict.insert( "datebook", new int(DATE) ); |
127 | 135 | ||
128 | qWarning ("TODO is: %d", TODO); | ||
129 | qWarning ("CONTACT is: %d", CONTACT); | ||
130 | |||
131 | int *find = dict[ backendName ]; | 136 | int *find = dict[ backendName ]; |
132 | if (!find ) return 0; | 137 | if (!find ) return 0; |
133 | 138 | ||
134 | switch ( *find ){ | 139 | switch ( *find ){ |
135 | case TODO: | 140 | case TODO: |
136 | #ifdef __USE_SQL | 141 | #ifdef __USE_SQL |
137 | if ( backend == "sql" ) | 142 | if ( backend == "sql" ) |
138 | return (T*) new OTodoAccessBackendSQL(""); | 143 | return (T*) new OTodoAccessBackendSQL(""); |
139 | #else | 144 | #else |
140 | if ( backend == "sql" ) | 145 | if ( backend == "sql" ) |
141 | qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); | 146 | qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); |
142 | #endif | 147 | #endif |
143 | 148 | ||
144 | return (T*) new OTodoAccessXML( appName ); | 149 | return (T*) new OTodoAccessXML( appName ); |
145 | case CONTACT: | 150 | case CONTACT: |
151 | #ifdef __USE_SQL | ||
152 | if ( backend == "sql" ) | ||
153 | return (T*) new OContactAccessBackend_SQL(""); | ||
154 | #else | ||
146 | if ( backend == "sql" ) | 155 | if ( backend == "sql" ) |
147 | qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); | 156 | qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); |
157 | #endif | ||
148 | 158 | ||
149 | return (T*) new OContactAccessBackend_XML( appName ); | 159 | return (T*) new OContactAccessBackend_XML( appName ); |
150 | case DATE: | 160 | case DATE: |
151 | if ( backend == "sql" ) | 161 | if ( backend == "sql" ) |
152 | qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!"); | 162 | qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!"); |
153 | 163 | ||
154 | return (T*) new ODateBookAccessBackend_XML( appName ); | 164 | return (T*) new ODateBookAccessBackend_XML( appName ); |
155 | default: | 165 | default: |
156 | return NULL; | 166 | return NULL; |
157 | } | 167 | } |
158 | 168 | ||
159 | 169 | ||
160 | } | 170 | } |
161 | private: | 171 | private: |
162 | OBackendPrivate* d; | 172 | OBackendPrivate* d; |
163 | }; | 173 | }; |
164 | 174 | ||
165 | 175 | ||
166 | #endif | 176 | #endif |
diff --git a/libopie/pim/ocontact.h b/libopie/pim/ocontact.h index 9a1a8dc..1d46b81 100644 --- a/libopie/pim/ocontact.h +++ b/libopie/pim/ocontact.h | |||
@@ -1,245 +1,240 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** Copyright (C) 2002-2003 by Stefan Eilers (eilers.stefan@epost.de) | 3 | ** Copyright (C) 2002-2003 by Stefan Eilers (eilers.stefan@epost.de) |
4 | ** | 4 | ** |
5 | ** This file may be distributed and/or modified under the terms of the | 5 | ** This file may be distributed and/or modified under the terms of the |
6 | ** GNU General Public License version 2 as published by the Free Software | 6 | ** GNU General Public License version 2 as published by the Free Software |
7 | ** Foundation and appearing in the file LICENSE.GPL included in the | 7 | ** Foundation and appearing in the file LICENSE.GPL included in the |
8 | ** packaging of this file. | 8 | ** packaging of this file. |
9 | ** | 9 | ** |
10 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 10 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
11 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 11 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
12 | ** | 12 | ** |
13 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 13 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
14 | ** | 14 | ** |
15 | ** Contact info@trolltech.com if any conditions of this licensing are | 15 | ** Contact info@trolltech.com if any conditions of this licensing are |
16 | ** not clear to you. | 16 | ** not clear to you. |
17 | ** | 17 | ** |
18 | **********************************************************************/ | 18 | **********************************************************************/ |
19 | 19 | ||
20 | #ifndef __OCONTACT_H__ | 20 | #ifndef __OCONTACT_H__ |
21 | #define __OCONTACT_H__ | 21 | #define __OCONTACT_H__ |
22 | 22 | ||
23 | #include <opie/opimrecord.h> | 23 | #include <opie/opimrecord.h> |
24 | #include <qpe/recordfields.h> | 24 | #include <qpe/recordfields.h> |
25 | 25 | ||
26 | #include <qdatetime.h> | 26 | #include <qdatetime.h> |
27 | #include <qstringlist.h> | 27 | #include <qstringlist.h> |
28 | 28 | ||
29 | #if defined(QPC_TEMPLATEDLL) | 29 | #if defined(QPC_TEMPLATEDLL) |
30 | // MOC_SKIP_BEGIN | 30 | // MOC_SKIP_BEGIN |
31 | QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>; | 31 | QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>; |
32 | // MOC_SKIP_END | 32 | // MOC_SKIP_END |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | class OContactPrivate; | 35 | class OContactPrivate; |
36 | 36 | ||
37 | /** | 37 | /** |
38 | * OContact class represents a specialised PIM Record for contacts. | 38 | * OContact class represents a specialised PIM Record for contacts. |
39 | * It does store all kind of persopn related information. | 39 | * It does store all kind of persopn related information. |
40 | * | 40 | * |
41 | * @short Contact Container | 41 | * @short Contact Container |
42 | * @author TT, Stefan Eiler, Holger Freyther | 42 | * @author TT, Stefan Eiler, Holger Freyther |
43 | */ | 43 | */ |
44 | class QPC_EXPORT OContact : public OPimRecord | 44 | class QPC_EXPORT OContact : public OPimRecord |
45 | { | 45 | { |
46 | friend class DataSet; | 46 | friend class DataSet; |
47 | public: | 47 | public: |
48 | OContact(); | 48 | OContact(); |
49 | OContact( const QMap<int, QString> &fromMap ); | 49 | OContact( const QMap<int, QString> &fromMap ); |
50 | virtual ~OContact(); | 50 | virtual ~OContact(); |
51 | 51 | ||
52 | enum DateFormat{ | 52 | enum DateFormat{ |
53 | Zip_City_State = 0, | 53 | Zip_City_State = 0, |
54 | City_State_Zip | 54 | City_State_Zip |
55 | }; | 55 | }; |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * do we need to inline them | 58 | * do we need to inline them |
59 | * if yes do we need to inline them this way? | 59 | * if yes do we need to inline them this way? |
60 | * -zecke | 60 | * -zecke |
61 | */ | 61 | */ |
62 | void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } | 62 | void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } |
63 | void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } | 63 | void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } |
64 | void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } | 64 | void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } |
65 | void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } | 65 | void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } |
66 | void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } | 66 | void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } |
67 | void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } | 67 | void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } |
68 | void setFileAs(); | 68 | void setFileAs(); |
69 | 69 | ||
70 | // default email address | 70 | // default email address |
71 | void setDefaultEmail( const QString &v ); | 71 | void setDefaultEmail( const QString &v ); |
72 | // inserts email to list and ensure's doesn't already exist | 72 | // inserts email to list and ensure's doesn't already exist |
73 | void insertEmail( const QString &v ); | 73 | void insertEmail( const QString &v ); |
74 | void removeEmail( const QString &v ); | 74 | void removeEmail( const QString &v ); |
75 | void clearEmails(); | 75 | void clearEmails(); |
76 | void insertEmails( const QStringList &v ); | 76 | void insertEmails( const QStringList &v ); |
77 | 77 | ||
78 | // home | 78 | // home |
79 | void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } | 79 | void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } |
80 | void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } | 80 | void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } |
81 | void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); } | 81 | void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); } |
82 | void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); } | 82 | void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); } |
83 | void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); } | 83 | void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); } |
84 | void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); } | 84 | void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); } |
85 | void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); } | 85 | void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); } |
86 | void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); } | 86 | void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); } |
87 | void setHomeWebpage( const QString &v ) { replace( Qtopia::HomeWebPage, v ); } | 87 | void setHomeWebpage( const QString &v ) { replace( Qtopia::HomeWebPage, v ); } |
88 | 88 | ||
89 | // business | 89 | // business |
90 | void setCompany( const QString &v ) { replace( Qtopia::Company, v ); } | 90 | void setCompany( const QString &v ) { replace( Qtopia::Company, v ); } |
91 | void setBusinessStreet( const QString &v ) { replace( Qtopia::BusinessStreet, v ); } | 91 | void setBusinessStreet( const QString &v ) { replace( Qtopia::BusinessStreet, v ); } |
92 | void setBusinessCity( const QString &v ) { replace( Qtopia::BusinessCity, v ); } | 92 | void setBusinessCity( const QString &v ) { replace( Qtopia::BusinessCity, v ); } |
93 | void setBusinessState( const QString &v ) { replace( Qtopia::BusinessState, v ); } | 93 | void setBusinessState( const QString &v ) { replace( Qtopia::BusinessState, v ); } |
94 | void setBusinessZip( const QString &v ) { replace( Qtopia::BusinessZip, v ); } | 94 | void setBusinessZip( const QString &v ) { replace( Qtopia::BusinessZip, v ); } |
95 | void setBusinessCountry( const QString &v ) { replace( Qtopia::BusinessCountry, v ); } | 95 | void setBusinessCountry( const QString &v ) { replace( Qtopia::BusinessCountry, v ); } |
96 | void setBusinessWebpage( const QString &v ) { replace( Qtopia::BusinessWebPage, v ); } | 96 | void setBusinessWebpage( const QString &v ) { replace( Qtopia::BusinessWebPage, v ); } |
97 | void setJobTitle( const QString &v ) { replace( Qtopia::JobTitle, v ); } | 97 | void setJobTitle( const QString &v ) { replace( Qtopia::JobTitle, v ); } |
98 | void setDepartment( const QString &v ) { replace( Qtopia::Department, v ); } | 98 | void setDepartment( const QString &v ) { replace( Qtopia::Department, v ); } |
99 | void setOffice( const QString &v ) { replace( Qtopia::Office, v ); } | 99 | void setOffice( const QString &v ) { replace( Qtopia::Office, v ); } |
100 | void setBusinessPhone( const QString &v ) { replace( Qtopia::BusinessPhone, v ); } | 100 | void setBusinessPhone( const QString &v ) { replace( Qtopia::BusinessPhone, v ); } |
101 | void setBusinessFax( const QString &v ) { replace( Qtopia::BusinessFax, v ); } | 101 | void setBusinessFax( const QString &v ) { replace( Qtopia::BusinessFax, v ); } |
102 | void setBusinessMobile( const QString &v ) { replace( Qtopia::BusinessMobile, v ); } | 102 | void setBusinessMobile( const QString &v ) { replace( Qtopia::BusinessMobile, v ); } |
103 | void setBusinessPager( const QString &v ) { replace( Qtopia::BusinessPager, v ); } | 103 | void setBusinessPager( const QString &v ) { replace( Qtopia::BusinessPager, v ); } |
104 | void setProfession( const QString &v ) { replace( Qtopia::Profession, v ); } | 104 | void setProfession( const QString &v ) { replace( Qtopia::Profession, v ); } |
105 | void setAssistant( const QString &v ) { replace( Qtopia::Assistant, v ); } | 105 | void setAssistant( const QString &v ) { replace( Qtopia::Assistant, v ); } |
106 | void setManager( const QString &v ) { replace( Qtopia::Manager, v ); } | 106 | void setManager( const QString &v ) { replace( Qtopia::Manager, v ); } |
107 | 107 | ||
108 | // personal | 108 | // personal |
109 | void setSpouse( const QString &v ) { replace( Qtopia::Spouse, v ); } | 109 | void setSpouse( const QString &v ) { replace( Qtopia::Spouse, v ); } |
110 | void setGender( const QString &v ) { replace( Qtopia::Gender, v ); } | 110 | void setGender( const QString &v ) { replace( Qtopia::Gender, v ); } |
111 | void setBirthday( const QDate &v ); | 111 | void setBirthday( const QDate &v ); |
112 | void setAnniversary( const QDate &v ); | 112 | void setAnniversary( const QDate &v ); |
113 | void setNickname( const QString &v ) { replace( Qtopia::Nickname, v ); } | 113 | void setNickname( const QString &v ) { replace( Qtopia::Nickname, v ); } |
114 | void setChildren( const QString &v ); | 114 | void setChildren( const QString &v ); |
115 | 115 | ||
116 | // other | 116 | // other |
117 | void setNotes( const QString &v ) { replace( Qtopia::Notes, v); } | 117 | void setNotes( const QString &v ) { replace( Qtopia::Notes, v); } |
118 | 118 | ||
119 | virtual bool match( const QRegExp ®exp ) const; | 119 | virtual bool match( const QRegExp ®exp ) const; |
120 | 120 | ||
121 | // // custom | 121 | // // custom |
122 | // void setCustomField( const QString &key, const QString &v ) | 122 | // void setCustomField( const QString &key, const QString &v ) |
123 | // { replace(Custom- + key, v ); } | 123 | // { replace(Custom- + key, v ); } |
124 | 124 | ||
125 | // name | 125 | // name |
126 | QString fullName() const; | 126 | QString fullName() const; |
127 | QString title() const { return find( Qtopia::Title ); } | 127 | QString title() const { return find( Qtopia::Title ); } |
128 | QString firstName() const { return find( Qtopia::FirstName ); } | 128 | QString firstName() const { return find( Qtopia::FirstName ); } |
129 | QString middleName() const { return find( Qtopia::MiddleName ); } | 129 | QString middleName() const { return find( Qtopia::MiddleName ); } |
130 | QString lastName() const { return find( Qtopia::LastName ); } | 130 | QString lastName() const { return find( Qtopia::LastName ); } |
131 | QString suffix() const { return find( Qtopia::Suffix ); } | 131 | QString suffix() const { return find( Qtopia::Suffix ); } |
132 | QString fileAs() const { return find( Qtopia::FileAs ); } | 132 | QString fileAs() const { return find( Qtopia::FileAs ); } |
133 | 133 | ||
134 | 134 | ||
135 | QString defaultEmail() const { return find( Qtopia::DefaultEmail ); } | 135 | QString defaultEmail() const { return find( Qtopia::DefaultEmail ); } |
136 | QStringList emailList() const; | 136 | QStringList emailList() const; |
137 | 137 | ||
138 | // home | 138 | // home |
139 | /* | 139 | /* |
140 | * OPimAddress address(enum Location)const; | 140 | * OPimAddress address(enum Location)const; |
141 | * would be some how nicer... | 141 | * would be some how nicer... |
142 | * -zecke | 142 | * -zecke |
143 | */ | 143 | */ |
144 | QString homeStreet() const { return find( Qtopia::HomeStreet ); } | 144 | QString homeStreet() const { return find( Qtopia::HomeStreet ); } |
145 | QString homeCity() const { return find( Qtopia::HomeCity ); } | 145 | QString homeCity() const { return find( Qtopia::HomeCity ); } |
146 | QString homeState() const { return find( Qtopia::HomeState ); } | 146 | QString homeState() const { return find( Qtopia::HomeState ); } |
147 | QString homeZip() const { return find( Qtopia::HomeZip ); } | 147 | QString homeZip() const { return find( Qtopia::HomeZip ); } |
148 | QString homeCountry() const { return find( Qtopia::HomeCountry ); } | 148 | QString homeCountry() const { return find( Qtopia::HomeCountry ); } |
149 | QString homePhone() const { return find( Qtopia::HomePhone ); } | 149 | QString homePhone() const { return find( Qtopia::HomePhone ); } |
150 | QString homeFax() const { return find( Qtopia::HomeFax ); } | 150 | QString homeFax() const { return find( Qtopia::HomeFax ); } |
151 | QString homeMobile() const { return find( Qtopia::HomeMobile ); } | 151 | QString homeMobile() const { return find( Qtopia::HomeMobile ); } |
152 | QString homeWebpage() const { return find( Qtopia::HomeWebPage ); } | 152 | QString homeWebpage() const { return find( Qtopia::HomeWebPage ); } |
153 | /** Multi line string containing all non-empty address info in the form | 153 | /** Multi line string containing all non-empty address info in the form |
154 | * Street | 154 | * Street |
155 | * City, State Zip | 155 | * City, State Zip |
156 | * Country | 156 | * Country |
157 | */ | 157 | */ |
158 | QString displayHomeAddress() const; | 158 | QString displayHomeAddress() const; |
159 | 159 | ||
160 | // business | 160 | // business |
161 | QString company() const { return find( Qtopia::Company ); } | 161 | QString company() const { return find( Qtopia::Company ); } |
162 | QString businessStreet() const { return find( Qtopia::BusinessStreet ); } | 162 | QString businessStreet() const { return find( Qtopia::BusinessStreet ); } |
163 | QString businessCity() const { return find( Qtopia::BusinessCity ); } | 163 | QString businessCity() const { return find( Qtopia::BusinessCity ); } |
164 | QString businessState() const { return find( Qtopia::BusinessState ); } | 164 | QString businessState() const { return find( Qtopia::BusinessState ); } |
165 | QString businessZip() const { return find( Qtopia::BusinessZip ); } | 165 | QString businessZip() const { return find( Qtopia::BusinessZip ); } |
166 | QString businessCountry() const { return find( Qtopia::BusinessCountry ); } | 166 | QString businessCountry() const { return find( Qtopia::BusinessCountry ); } |
167 | QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); } | 167 | QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); } |
168 | QString jobTitle() const { return find( Qtopia::JobTitle ); } | 168 | QString jobTitle() const { return find( Qtopia::JobTitle ); } |
169 | QString department() const { return find( Qtopia::Department ); } | 169 | QString department() const { return find( Qtopia::Department ); } |
170 | QString office() const { return find( Qtopia::Office ); } | 170 | QString office() const { return find( Qtopia::Office ); } |
171 | QString businessPhone() const { return find( Qtopia::BusinessPhone ); } | 171 | QString businessPhone() const { return find( Qtopia::BusinessPhone ); } |
172 | QString businessFax() const { return find( Qtopia::BusinessFax ); } | 172 | QString businessFax() const { return find( Qtopia::BusinessFax ); } |
173 | QString businessMobile() const { return find( Qtopia::BusinessMobile ); } | 173 | QString businessMobile() const { return find( Qtopia::BusinessMobile ); } |
174 | QString businessPager() const { return find( Qtopia::BusinessPager ); } | 174 | QString businessPager() const { return find( Qtopia::BusinessPager ); } |
175 | QString profession() const { return find( Qtopia::Profession ); } | 175 | QString profession() const { return find( Qtopia::Profession ); } |
176 | QString assistant() const { return find( Qtopia::Assistant ); } | 176 | QString assistant() const { return find( Qtopia::Assistant ); } |
177 | QString manager() const { return find( Qtopia::Manager ); } | 177 | QString manager() const { return find( Qtopia::Manager ); } |
178 | /** Multi line string containing all non-empty address info in the form | 178 | /** Multi line string containing all non-empty address info in the form |
179 | * Street | 179 | * Street |
180 | * City, State Zip | 180 | * City, State Zip |
181 | * Country | 181 | * Country |
182 | */ | 182 | */ |
183 | QString displayBusinessAddress() const; | 183 | QString displayBusinessAddress() const; |
184 | 184 | ||
185 | //personal | 185 | //personal |
186 | QString spouse() const { return find( Qtopia::Spouse ); } | 186 | QString spouse() const { return find( Qtopia::Spouse ); } |
187 | QString gender() const { return find( Qtopia::Gender ); } | 187 | QString gender() const { return find( Qtopia::Gender ); } |
188 | QDate birthday() const; | 188 | QDate birthday() const; |
189 | QDate anniversary() const; | 189 | QDate anniversary() const; |
190 | QString nickname() const { return find( Qtopia::Nickname ); } | 190 | QString nickname() const { return find( Qtopia::Nickname ); } |
191 | QString children() const { return find( Qtopia::Children ); } | 191 | QString children() const { return find( Qtopia::Children ); } |
192 | QStringList childrenList() const; | 192 | QStringList childrenList() const; |
193 | 193 | ||
194 | // other | 194 | // other |
195 | QString notes() const { return find( Qtopia::Notes ); } | 195 | QString notes() const { return find( Qtopia::Notes ); } |
196 | QString groups() const { return find( Qtopia::Groups ); } | 196 | QString groups() const { return find( Qtopia::Groups ); } |
197 | QStringList groupList() const; | 197 | QStringList groupList() const; |
198 | 198 | ||
199 | // // custom | ||
200 | // const QString &customField( const QString &key ) | ||
201 | // { return find( Custom- + key ); } | ||
202 | |||
203 | |||
204 | QString toRichText() const; | 199 | QString toRichText() const; |
205 | QMap<int, QString> toMap() const; | 200 | QMap<int, QString> toMap() const; |
206 | QString field( int key ) const { return find( key ); } | 201 | QString field( int key ) const { return find( key ); } |
207 | 202 | ||
208 | 203 | ||
209 | void setUid( int i ); | 204 | void setUid( int i ); |
210 | 205 | ||
211 | QString toShortText()const; | 206 | QString toShortText()const; |
212 | QString OContact::type()const; | 207 | QString type()const; |
213 | QMap<QString,QString> OContact::toExtraMap() const; | 208 | class QString recordField(int) const; |
214 | class QString OContact::recordField(int) const; | ||
215 | 209 | ||
216 | // Why private ? (eilers,se) | 210 | // Why private ? (eilers,se) |
217 | QString emailSeparator() const { return " "; } | 211 | QString emailSeparator() const { return " "; } |
212 | |||
218 | // the emails should be seperated by a comma | 213 | // the emails should be seperated by a comma |
219 | void setEmails( const QString &v ); | 214 | void setEmails( const QString &v ); |
220 | QString emails() const { return find( Qtopia::Emails ); } | 215 | QString emails() const { return find( Qtopia::Emails ); } |
221 | static int rtti(); | 216 | static int rtti(); |
222 | 217 | ||
223 | private: | 218 | private: |
224 | // The XML-Backend needs some access to the private functions | 219 | // The XML Backend needs some access to the private functions |
225 | friend class OContactAccessBackend_XML; | 220 | friend class OContactAccessBackend_XML; |
226 | 221 | ||
227 | void insert( int key, const QString &value ); | 222 | void insert( int key, const QString &value ); |
228 | void replace( int key, const QString &value ); | 223 | void replace( int key, const QString &value ); |
229 | QString find( int key ) const; | 224 | QString find( int key ) const; |
230 | static QStringList fields(); | 225 | static QStringList fields(); |
231 | 226 | ||
232 | void save( QString &buf ) const; | 227 | void save( QString &buf ) const; |
233 | 228 | ||
234 | QString displayAddress( const QString &street, | 229 | QString displayAddress( const QString &street, |
235 | const QString &city, | 230 | const QString &city, |
236 | const QString &state, | 231 | const QString &state, |
237 | const QString &zip, | 232 | const QString &zip, |
238 | const QString &country ) const; | 233 | const QString &country ) const; |
239 | 234 | ||
240 | QMap<int, QString> mMap; | 235 | QMap<int, QString> mMap; |
241 | OContactPrivate *d; | 236 | OContactPrivate *d; |
242 | }; | 237 | }; |
243 | 238 | ||
244 | 239 | ||
245 | #endif | 240 | #endif |
diff --git a/libopie/pim/ocontactaccessbackend_sql.cpp b/libopie/pim/ocontactaccessbackend_sql.cpp new file mode 100644 index 0000000..4afa5f3 --- a/dev/null +++ b/libopie/pim/ocontactaccessbackend_sql.cpp | |||
@@ -0,0 +1,664 @@ | |||
1 | /* | ||
2 | * SQL Backend for the OPIE-Contact Database. | ||
3 | * | ||
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * | ||
6 | * ===================================================================== | ||
7 | *This program is free software; you can redistribute it and/or | ||
8 | *modify it under the terms of the GNU Library General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2 of the License, or (at your option) any later version. | ||
11 | * ===================================================================== | ||
12 | * ===================================================================== | ||
13 | * Version: $Id$ | ||
14 | * ===================================================================== | ||
15 | * History: | ||
16 | * $Log$ | ||
17 | * Revision 1.1 2003/09/22 14:31:16 eilers | ||
18 | * Added first experimental incarnation of sql-backend for addressbook. | ||
19 | * Some modifications to be able to compile the todo sql-backend. | ||
20 | * A lot of changes fill follow... | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include "ocontactaccessbackend_sql.h" | ||
25 | |||
26 | #include <qarray.h> | ||
27 | #include <qdatetime.h> | ||
28 | #include <qstringlist.h> | ||
29 | |||
30 | #include <qpe/global.h> | ||
31 | #include <qpe/recordfields.h> | ||
32 | |||
33 | #include <opie/ocontactfields.h> | ||
34 | #include <opie/oconversion.h> | ||
35 | #include <opie2/osqldriver.h> | ||
36 | #include <opie2/osqlresult.h> | ||
37 | #include <opie2/osqlmanager.h> | ||
38 | #include <opie2/osqlquery.h> | ||
39 | |||
40 | /* | ||
41 | * Implementation of used query types | ||
42 | * CREATE query | ||
43 | * LOAD query | ||
44 | * INSERT | ||
45 | * REMOVE | ||
46 | * CLEAR | ||
47 | */ | ||
48 | namespace { | ||
49 | /** | ||
50 | * CreateQuery for the Todolist Table | ||
51 | */ | ||
52 | class CreateQuery : public OSQLQuery { | ||
53 | public: | ||
54 | CreateQuery(); | ||
55 | ~CreateQuery(); | ||
56 | QString query()const; | ||
57 | }; | ||
58 | |||
59 | /** | ||
60 | * Clears (delete) a Table | ||
61 | */ | ||
62 | class ClearQuery : public OSQLQuery { | ||
63 | public: | ||
64 | ClearQuery(); | ||
65 | ~ClearQuery(); | ||
66 | QString query()const; | ||
67 | |||
68 | }; | ||
69 | |||
70 | |||
71 | /** | ||
72 | * LoadQuery | ||
73 | * this one queries for all uids | ||
74 | */ | ||
75 | class LoadQuery : public OSQLQuery { | ||
76 | public: | ||
77 | LoadQuery(); | ||
78 | ~LoadQuery(); | ||
79 | QString query()const; | ||
80 | }; | ||
81 | |||
82 | /** | ||
83 | * inserts/adds a OContact to the table | ||
84 | */ | ||
85 | class InsertQuery : public OSQLQuery { | ||
86 | public: | ||
87 | InsertQuery(const OContact& ); | ||
88 | ~InsertQuery(); | ||
89 | QString query()const; | ||
90 | private: | ||
91 | OContact m_contact; | ||
92 | }; | ||
93 | |||
94 | |||
95 | /** | ||
96 | * removes one from the table | ||
97 | */ | ||
98 | class RemoveQuery : public OSQLQuery { | ||
99 | public: | ||
100 | RemoveQuery(int uid ); | ||
101 | ~RemoveQuery(); | ||
102 | QString query()const; | ||
103 | private: | ||
104 | int m_uid; | ||
105 | }; | ||
106 | |||
107 | /** | ||
108 | * a find query for noncustom elements | ||
109 | */ | ||
110 | class FindQuery : public OSQLQuery { | ||
111 | public: | ||
112 | FindQuery(int uid); | ||
113 | FindQuery(const QArray<int>& ); | ||
114 | ~FindQuery(); | ||
115 | QString query()const; | ||
116 | private: | ||
117 | QString single()const; | ||
118 | QString multi()const; | ||
119 | QArray<int> m_uids; | ||
120 | int m_uid; | ||
121 | }; | ||
122 | |||
123 | /** | ||
124 | * a find query for custom elements | ||
125 | */ | ||
126 | class FindCustomQuery : public OSQLQuery { | ||
127 | public: | ||
128 | FindCustomQuery(int uid); | ||
129 | FindCustomQuery(const QArray<int>& ); | ||
130 | ~FindCustomQuery(); | ||
131 | QString query()const; | ||
132 | private: | ||
133 | QString single()const; | ||
134 | QString multi()const; | ||
135 | QArray<int> m_uids; | ||
136 | int m_uid; | ||
137 | }; | ||
138 | |||
139 | |||
140 | |||
141 | // We using three tables to store the information: | ||
142 | // 1. addressbook : It contains General information about the contact (non custom) | ||
143 | // 2. dates : Stuff like birthdays, anniversaries, etc. | ||
144 | // 3. custom_data : Not official supported entries | ||
145 | // All tables are connected by the uid of the contact. | ||
146 | // Maybe I should add a table for meta-information ? | ||
147 | CreateQuery::CreateQuery() : OSQLQuery() {} | ||
148 | CreateQuery::~CreateQuery() {} | ||
149 | QString CreateQuery::query()const { | ||
150 | QString qu; | ||
151 | qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));"; | ||
152 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; | ||
153 | // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );"; | ||
154 | return qu; | ||
155 | } | ||
156 | |||
157 | ClearQuery::ClearQuery() | ||
158 | : OSQLQuery() {} | ||
159 | ClearQuery::~ClearQuery() {} | ||
160 | QString ClearQuery::query()const { | ||
161 | QString qu = "drop table addressbook;"; | ||
162 | qu += "drop table custom_data;"; | ||
163 | qu += "drop table dates;"; | ||
164 | return qu; | ||
165 | } | ||
166 | |||
167 | // Distinct loading is not very fast. If I expect that every person has just | ||
168 | // one (and always one) 'Last Name', I can request all uid's for existing lastnames, | ||
169 | // which is faster.. | ||
170 | // But this may not be true for all entries, like company contacts.. | ||
171 | // The current AddressBook application handles this problem, but other may not.. (eilers) | ||
172 | #define __USE_SUPERFAST_LOADQUERY | ||
173 | |||
174 | LoadQuery::LoadQuery() : OSQLQuery() {} | ||
175 | LoadQuery::~LoadQuery() {} | ||
176 | QString LoadQuery::query()const { | ||
177 | QString qu; | ||
178 | #ifndef __USE_SUPERFAST_LOADQUERY | ||
179 | qu += "select distinct uid from addressbook"; | ||
180 | #else | ||
181 | qu += "select uid from addressbook where type = 'Last Name'"; | ||
182 | #endif | ||
183 | |||
184 | return qu; | ||
185 | } | ||
186 | |||
187 | |||
188 | InsertQuery::InsertQuery( const OContact& contact ) | ||
189 | : OSQLQuery(), m_contact( contact ) { | ||
190 | } | ||
191 | |||
192 | InsertQuery::~InsertQuery() { | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * converts from a OContact to a query | ||
197 | */ | ||
198 | QString InsertQuery::query()const{ | ||
199 | |||
200 | // Get all information out of the contact-class | ||
201 | // Remember: The category is stored in contactMap, too ! | ||
202 | QMap<int, QString> contactMap = m_contact.toMap(); | ||
203 | QMap<QString, QString> customMap = m_contact.toExtraMap(); | ||
204 | |||
205 | QMap<QString, QString> addressbook_db; | ||
206 | |||
207 | // Get the translation from the ID to the String | ||
208 | QMap<int, QString> transMap = OContactFields::idToUntrFields(); | ||
209 | |||
210 | for( QMap<int, QString>::Iterator it = contactMap.begin(); | ||
211 | it != contactMap.end(); ++it ){ | ||
212 | switch ( it.key() ){ | ||
213 | case Qtopia::Birthday:{ | ||
214 | // These entries should stored in a special format | ||
215 | // year-month-day | ||
216 | QDate day = m_contact.birthday(); | ||
217 | addressbook_db.insert( transMap[it.key()], | ||
218 | QString("%1-%2-%3") | ||
219 | .arg( day.year() ) | ||
220 | .arg( day.month() ) | ||
221 | .arg( day.day() ) ); | ||
222 | } | ||
223 | break; | ||
224 | case Qtopia::Anniversary:{ | ||
225 | // These entries should stored in a special format | ||
226 | // year-month-day | ||
227 | QDate day = m_contact.anniversary(); | ||
228 | addressbook_db.insert( transMap[it.key()], | ||
229 | QString("%1-%2-%3") | ||
230 | .arg( day.year() ) | ||
231 | .arg( day.month() ) | ||
232 | .arg( day.day() ) ); | ||
233 | } | ||
234 | break; | ||
235 | case Qtopia::AddressUid: // Ignore UID | ||
236 | break; | ||
237 | default: // Translate id to String | ||
238 | addressbook_db.insert( transMap[it.key()], it.data() ); | ||
239 | break; | ||
240 | } | ||
241 | |||
242 | } | ||
243 | |||
244 | // Now convert this whole stuff into a SQL String, beginning with | ||
245 | // the addressbook table.. | ||
246 | QString qu; | ||
247 | // qu += "begin transaction;"; | ||
248 | int id = 0; | ||
249 | for( QMap<QString, QString>::Iterator it = addressbook_db.begin(); | ||
250 | it != addressbook_db.end(); ++it ){ | ||
251 | qu += "insert into addressbook VALUES(" | ||
252 | + QString::number( m_contact.uid() ) | ||
253 | + "," | ||
254 | + QString::number( id++ ) | ||
255 | + ",'" | ||
256 | + it.key() //.latin1() | ||
257 | + "'," | ||
258 | + "0" // Priority for future enhancements | ||
259 | + ",'" | ||
260 | + it.data() //.latin1() | ||
261 | + "');"; | ||
262 | } | ||
263 | |||
264 | // Now add custom data.. | ||
265 | id = 0; | ||
266 | for( QMap<QString, QString>::Iterator it = customMap.begin(); | ||
267 | it != customMap.end(); ++it ){ | ||
268 | qu += "insert into custom_data VALUES(" | ||
269 | + QString::number( m_contact.uid() ) | ||
270 | + "," | ||
271 | + QString::number( id++ ) | ||
272 | + ",'" | ||
273 | + it.key() //.latin1() | ||
274 | + "'," | ||
275 | + "0" // Priority for future enhancements | ||
276 | + ",'" | ||
277 | + it.data() //.latin1() | ||
278 | + "');"; | ||
279 | } | ||
280 | |||
281 | // qu += "commit;"; | ||
282 | qWarning("add %s", qu.latin1() ); | ||
283 | return qu; | ||
284 | } | ||
285 | |||
286 | |||
287 | RemoveQuery::RemoveQuery(int uid ) | ||
288 | : OSQLQuery(), m_uid( uid ) {} | ||
289 | RemoveQuery::~RemoveQuery() {} | ||
290 | QString RemoveQuery::query()const { | ||
291 | QString qu = "DELETE from addressbook where uid = " | ||
292 | + QString::number(m_uid) + ";"; | ||
293 | qu += "DELETE from dates where uid = " | ||
294 | + QString::number(m_uid) + ";"; | ||
295 | qu += "DELETE from custom_data where uid = " | ||
296 | + QString::number(m_uid) + ";"; | ||
297 | return qu; | ||
298 | } | ||
299 | |||
300 | |||
301 | |||
302 | |||
303 | FindQuery::FindQuery(int uid) | ||
304 | : OSQLQuery(), m_uid( uid ) { | ||
305 | } | ||
306 | FindQuery::FindQuery(const QArray<int>& ints) | ||
307 | : OSQLQuery(), m_uids( ints ){ | ||
308 | } | ||
309 | FindQuery::~FindQuery() { | ||
310 | } | ||
311 | QString FindQuery::query()const{ | ||
312 | // if ( m_uids.count() == 0 ) | ||
313 | return single(); | ||
314 | } | ||
315 | /* | ||
316 | else | ||
317 | return multi(); | ||
318 | } | ||
319 | QString FindQuery::multi()const { | ||
320 | QString qu = "select uid, type, value from addressbook where"; | ||
321 | for (uint i = 0; i < m_uids.count(); i++ ) { | ||
322 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | ||
323 | } | ||
324 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. | ||
325 | return qu; | ||
326 | } | ||
327 | */ | ||
328 | QString FindQuery::single()const{ | ||
329 | QString qu = "select uid, type, value from addressbook where uid = "; | ||
330 | qu += QString::number(m_uid); | ||
331 | return qu; | ||
332 | } | ||
333 | |||
334 | |||
335 | FindCustomQuery::FindCustomQuery(int uid) | ||
336 | : OSQLQuery(), m_uid( uid ) { | ||
337 | } | ||
338 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) | ||
339 | : OSQLQuery(), m_uids( ints ){ | ||
340 | } | ||
341 | FindCustomQuery::~FindCustomQuery() { | ||
342 | } | ||
343 | QString FindCustomQuery::query()const{ | ||
344 | // if ( m_uids.count() == 0 ) | ||
345 | return single(); | ||
346 | } | ||
347 | QString FindCustomQuery::single()const{ | ||
348 | QString qu = "select uid, type, value from custom_data where uid = "; | ||
349 | qu += QString::number(m_uid); | ||
350 | return qu; | ||
351 | } | ||
352 | |||
353 | }; | ||
354 | |||
355 | |||
356 | /* --------------------------------------------------------------------------- */ | ||
357 | |||
358 | OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, | ||
359 | const QString& filename ): m_changed(false) | ||
360 | { | ||
361 | qWarning("C'tor OContactAccessBackend_SQL starts"); | ||
362 | QTime t; | ||
363 | t.start(); | ||
364 | |||
365 | /* Expecting to access the default filename if nothing else is set */ | ||
366 | if ( filename.isEmpty() ){ | ||
367 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); | ||
368 | } else | ||
369 | m_fileName = filename; | ||
370 | |||
371 | // Get the standart sql-driver from the OSQLManager.. | ||
372 | OSQLManager man; | ||
373 | m_driver = man.standard(); | ||
374 | m_driver->setUrl( m_fileName ); | ||
375 | |||
376 | load(); | ||
377 | |||
378 | qWarning("C'tor OContactAccessBackend_SQL ends: %d", t.elapsed() ); | ||
379 | } | ||
380 | |||
381 | |||
382 | bool OContactAccessBackend_SQL::load () | ||
383 | { | ||
384 | if (!m_driver->open() ) | ||
385 | return false; | ||
386 | |||
387 | // Don't expect that the database exists. | ||
388 | // It is save here to create the table, even if it | ||
389 | // do exist. ( Is that correct for all databases ?? ) | ||
390 | CreateQuery creat; | ||
391 | OSQLResult res = m_driver->query( &creat ); | ||
392 | |||
393 | update(); | ||
394 | |||
395 | return true; | ||
396 | |||
397 | } | ||
398 | |||
399 | bool OContactAccessBackend_SQL::reload() | ||
400 | { | ||
401 | return load(); | ||
402 | } | ||
403 | |||
404 | bool OContactAccessBackend_SQL::save() | ||
405 | { | ||
406 | return m_driver->close(); | ||
407 | } | ||
408 | |||
409 | |||
410 | void OContactAccessBackend_SQL::clear () | ||
411 | { | ||
412 | ClearQuery cle; | ||
413 | OSQLResult res = m_driver->query( &cle ); | ||
414 | CreateQuery qu; | ||
415 | res = m_driver->query(&qu); | ||
416 | } | ||
417 | |||
418 | bool OContactAccessBackend_SQL::wasChangedExternally() | ||
419 | { | ||
420 | return false; | ||
421 | } | ||
422 | |||
423 | QArray<int> OContactAccessBackend_SQL::allRecords() const | ||
424 | { | ||
425 | |||
426 | // FIXME: Think about cute handling of changed tables.. | ||
427 | // Thus, we don't have to call update here... | ||
428 | if ( m_changed ) | ||
429 | ((OContactAccessBackend_SQL*)this)->update(); | ||
430 | |||
431 | return m_uids; | ||
432 | } | ||
433 | |||
434 | bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) | ||
435 | { | ||
436 | InsertQuery ins( newcontact ); | ||
437 | OSQLResult res = m_driver->query( &ins ); | ||
438 | |||
439 | if ( res.state() == OSQLResult::Failure ) | ||
440 | return false; | ||
441 | |||
442 | int c = m_uids.count(); | ||
443 | m_uids.resize( c+1 ); | ||
444 | m_uids[c] = newcontact.uid(); | ||
445 | |||
446 | return true; | ||
447 | } | ||
448 | |||
449 | |||
450 | bool OContactAccessBackend_SQL::remove ( int uid ) | ||
451 | { | ||
452 | RemoveQuery rem( uid ); | ||
453 | OSQLResult res = m_driver->query(&rem ); | ||
454 | |||
455 | if ( res.state() == OSQLResult::Failure ) | ||
456 | return false; | ||
457 | |||
458 | m_changed = true; | ||
459 | |||
460 | return true; | ||
461 | } | ||
462 | |||
463 | bool OContactAccessBackend_SQL::replace ( const OContact &contact ) | ||
464 | { | ||
465 | if ( !remove( contact.uid() ) ) | ||
466 | return false; | ||
467 | |||
468 | return add( contact ); | ||
469 | } | ||
470 | |||
471 | |||
472 | OContact OContactAccessBackend_SQL::find ( int uid ) const | ||
473 | { | ||
474 | qWarning("OContactAccessBackend_SQL::find()"); | ||
475 | QTime t; | ||
476 | t.start(); | ||
477 | |||
478 | OContact retContact( requestNonCustom( uid ) ); | ||
479 | retContact.setExtraMap( requestCustom( uid ) ); | ||
480 | |||
481 | qWarning("OContactAccessBackend_SQL::find() needed: %d", t.elapsed() ); | ||
482 | return retContact; | ||
483 | } | ||
484 | |||
485 | |||
486 | |||
487 | QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ) | ||
488 | { | ||
489 | QArray<int> nix(0); | ||
490 | return nix; | ||
491 | } | ||
492 | |||
493 | QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | ||
494 | { | ||
495 | QArray<int> nix(0); | ||
496 | return nix; | ||
497 | } | ||
498 | |||
499 | const uint OContactAccessBackend_SQL::querySettings() | ||
500 | { | ||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const | ||
505 | { | ||
506 | return false; | ||
507 | } | ||
508 | |||
509 | QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int ) | ||
510 | { | ||
511 | QTime t; | ||
512 | t.start(); | ||
513 | |||
514 | // Not implemented.. | ||
515 | QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' "; | ||
516 | |||
517 | query += "ORDER BY value "; | ||
518 | if ( !asc ) | ||
519 | query += "DESC"; | ||
520 | |||
521 | qWarning("sorted query is: %s", query.latin1() ); | ||
522 | |||
523 | OSQLRawQuery raw( query ); | ||
524 | OSQLResult res = m_driver->query( &raw ); | ||
525 | if ( res.state() != OSQLResult::Success ){ | ||
526 | QArray<int> empty; | ||
527 | return empty; | ||
528 | } | ||
529 | |||
530 | QArray<int> list = extractUids( res ); | ||
531 | |||
532 | qWarning("sorted needed %d ms!", t.elapsed() ); | ||
533 | return list; | ||
534 | } | ||
535 | |||
536 | |||
537 | void OContactAccessBackend_SQL::update() | ||
538 | { | ||
539 | qWarning("Update starts"); | ||
540 | QTime t; | ||
541 | t.start(); | ||
542 | |||
543 | // Now load the database set and extract the uid's | ||
544 | // which will be held locally | ||
545 | |||
546 | LoadQuery lo; | ||
547 | OSQLResult res = m_driver->query(&lo); | ||
548 | if ( res.state() != OSQLResult::Success ) | ||
549 | return; | ||
550 | |||
551 | m_uids = extractUids( res ); | ||
552 | |||
553 | m_changed = false; | ||
554 | |||
555 | qWarning("Update ends %d", t.elapsed() ); | ||
556 | } | ||
557 | |||
558 | QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const | ||
559 | { | ||
560 | qWarning("extractUids"); | ||
561 | QTime t; | ||
562 | t.start(); | ||
563 | OSQLResultItem::ValueList list = res.results(); | ||
564 | OSQLResultItem::ValueList::Iterator it; | ||
565 | QArray<int> ints(list.count() ); | ||
566 | qWarning(" count = %d", list.count() ); | ||
567 | |||
568 | int i = 0; | ||
569 | for (it = list.begin(); it != list.end(); ++it ) { | ||
570 | ints[i] = (*it).data("uid").toInt(); | ||
571 | i++; | ||
572 | } | ||
573 | qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); | ||
574 | |||
575 | return ints; | ||
576 | |||
577 | } | ||
578 | |||
579 | QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const | ||
580 | { | ||
581 | QTime t; | ||
582 | t.start(); | ||
583 | |||
584 | QMap<int, QString> nonCustomMap; | ||
585 | |||
586 | int t2needed = 0; | ||
587 | QTime t2; | ||
588 | t2.start(); | ||
589 | FindQuery query( uid ); | ||
590 | OSQLResult res_noncustom = m_driver->query( &query ); | ||
591 | t2needed = t2.elapsed(); | ||
592 | |||
593 | if ( res_noncustom.state() == OSQLResult::Failure ) { | ||
594 | qWarning("OSQLResult::Failure in find query !!"); | ||
595 | QMap<int, QString> empty; | ||
596 | return empty; | ||
597 | } | ||
598 | |||
599 | int t3needed = 0; | ||
600 | QTime t3; | ||
601 | t3.start(); | ||
602 | QMap<QString, int> translateMap = OContactFields::untrFieldsToId(); | ||
603 | |||
604 | OSQLResultItem::ValueList list = res_noncustom.results(); | ||
605 | OSQLResultItem::ValueList::Iterator it = list.begin(); | ||
606 | for ( ; it != list.end(); ++it ) { | ||
607 | if ( (*it).data("type") != "" ){ | ||
608 | int typeId = translateMap[(*it).data( "type" )]; | ||
609 | switch( typeId ){ | ||
610 | case Qtopia::Birthday: | ||
611 | case Qtopia::Anniversary:{ | ||
612 | // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) | ||
613 | QStringList list = QStringList::split( '-', (*it).data( "value" ) ); | ||
614 | QStringList::Iterator lit = list.begin(); | ||
615 | int year = (*lit).toInt(); | ||
616 | qWarning("1. %s", (*lit).latin1()); | ||
617 | int month = (*(++lit)).toInt(); | ||
618 | qWarning("2. %s", (*lit).latin1()); | ||
619 | int day = (*(++lit)).toInt(); | ||
620 | qWarning("3. %s", (*lit).latin1()); | ||
621 | qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day ); | ||
622 | QDate date( year, month, day ); | ||
623 | nonCustomMap.insert( typeId, OConversion::dateToString( date ) ); | ||
624 | } | ||
625 | break; | ||
626 | default: | ||
627 | nonCustomMap.insert( typeId, | ||
628 | (*it).data( "value" ) ); | ||
629 | } | ||
630 | } | ||
631 | } | ||
632 | // Add UID to Map.. | ||
633 | nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) ); | ||
634 | t3needed = t3.elapsed(); | ||
635 | |||
636 | qWarning("RequestNonCustom needed: ins:%d, query: %d, mapping: %d", t.elapsed(), t2needed, t3needed ); | ||
637 | return nonCustomMap; | ||
638 | } | ||
639 | |||
640 | QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const | ||
641 | { | ||
642 | QTime t; | ||
643 | t.start(); | ||
644 | |||
645 | QMap<QString, QString> customMap; | ||
646 | |||
647 | FindCustomQuery query( uid ); | ||
648 | OSQLResult res_custom = m_driver->query( &query ); | ||
649 | |||
650 | if ( res_custom.state() == OSQLResult::Failure ) { | ||
651 | qWarning("OSQLResult::Failure in find query !!"); | ||
652 | QMap<QString, QString> empty; | ||
653 | return empty; | ||
654 | } | ||
655 | |||
656 | OSQLResultItem::ValueList list = res_custom.results(); | ||
657 | OSQLResultItem::ValueList::Iterator it = list.begin(); | ||
658 | for ( ; it != list.end(); ++it ) { | ||
659 | customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); | ||
660 | } | ||
661 | |||
662 | qWarning("RequestCustom needed: %d", t.elapsed() ); | ||
663 | return customMap; | ||
664 | } | ||
diff --git a/libopie/pim/ocontactaccessbackend_sql.h b/libopie/pim/ocontactaccessbackend_sql.h new file mode 100644 index 0000000..bb22551 --- a/dev/null +++ b/libopie/pim/ocontactaccessbackend_sql.h | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * SQL Backend for the OPIE-Contact Database. | ||
3 | * | ||
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * | ||
6 | * ===================================================================== | ||
7 | *This program is free software; you can redistribute it and/or | ||
8 | *modify it under the terms of the GNU Library General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2 of the License, or (at your option) any later version. | ||
11 | * ===================================================================== | ||
12 | * | ||
13 | * | ||
14 | * ===================================================================== | ||
15 | * Version: $Id$ | ||
16 | * ===================================================================== | ||
17 | * History: | ||
18 | * $Log$ | ||
19 | * Revision 1.1 2003/09/22 14:31:16 eilers | ||
20 | * Added first experimental incarnation of sql-backend for addressbook. | ||
21 | * Some modifications to be able to compile the todo sql-backend. | ||
22 | * A lot of changes fill follow... | ||
23 | * | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #ifndef _OContactAccessBackend_SQL_ | ||
28 | #define _OContactAccessBackend_SQL_ | ||
29 | |||
30 | #include "ocontactaccessbackend.h" | ||
31 | #include "ocontactaccess.h" | ||
32 | |||
33 | #include <qlist.h> | ||
34 | #include <qdict.h> | ||
35 | |||
36 | class OSQLDriver; | ||
37 | class OSQLResult; | ||
38 | class OSQLResultItem; | ||
39 | |||
40 | /* the default xml implementation */ | ||
41 | /** | ||
42 | * This class is the SQL implementation of a Contact backend | ||
43 | * it does implement everything available for OContact. | ||
44 | * @see OPimAccessBackend for more information of available methods | ||
45 | */ | ||
46 | class OContactAccessBackend_SQL : public OContactAccessBackend { | ||
47 | public: | ||
48 | OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); | ||
49 | |||
50 | bool save(); | ||
51 | |||
52 | bool load (); | ||
53 | |||
54 | void clear (); | ||
55 | |||
56 | bool wasChangedExternally(); | ||
57 | |||
58 | QArray<int> allRecords() const; | ||
59 | |||
60 | OContact find ( int uid ) const; | ||
61 | // FIXME: Add lookahead-cache support ! | ||
62 | //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; | ||
63 | |||
64 | QArray<int> queryByExample ( const OContact &query, int settings, | ||
65 | const QDateTime& d ); | ||
66 | |||
67 | QArray<int> matchRegexp( const QRegExp &r ) const; | ||
68 | |||
69 | const uint querySettings(); | ||
70 | |||
71 | bool hasQuerySettings (uint querySettings) const; | ||
72 | |||
73 | // Currently only asc implemented.. | ||
74 | QArray<int> sorted( bool asc, int , int , int ); | ||
75 | bool add ( const OContact &newcontact ); | ||
76 | |||
77 | bool replace ( const OContact &contact ); | ||
78 | |||
79 | bool remove ( int uid ); | ||
80 | bool reload(); | ||
81 | |||
82 | private: | ||
83 | QArray<int> extractUids( OSQLResult& res ) const; | ||
84 | QMap<int, QString> requestNonCustom( int uid ) const; | ||
85 | QMap<QString, QString> requestCustom( int uid ) const; | ||
86 | void update(); | ||
87 | |||
88 | protected: | ||
89 | bool m_changed; | ||
90 | QString m_fileName; | ||
91 | QArray<int> m_uids; | ||
92 | |||
93 | OSQLDriver* m_driver; | ||
94 | }; | ||
95 | |||
96 | #endif | ||
diff --git a/libopie/pim/ocontactaccessbackend_xml.cpp b/libopie/pim/ocontactaccessbackend_xml.cpp index 1b5af2f..aae7fca 100644 --- a/libopie/pim/ocontactaccessbackend_xml.cpp +++ b/libopie/pim/ocontactaccessbackend_xml.cpp | |||
@@ -1,817 +1,820 @@ | |||
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... | ||
13 | * | ||
14 | * | 12 | * |
15 | * ===================================================================== | 13 | * ===================================================================== |
16 | * Version: $Id$ | 14 | * Version: $Id$ |
17 | * ===================================================================== | 15 | * ===================================================================== |
18 | * History: | 16 | * History: |
19 | * $Log$ | 17 | * $Log$ |
18 | * Revision 1.9 2003/09/22 14:31:16 eilers | ||
19 | * Added first experimental incarnation of sql-backend for addressbook. | ||
20 | * Some modifications to be able to compile the todo sql-backend. | ||
21 | * A lot of changes fill follow... | ||
22 | * | ||
20 | * Revision 1.8 2003/08/30 15:28:26 eilers | 23 | * Revision 1.8 2003/08/30 15:28:26 eilers |
21 | * Removed some unimportant debug output which causes slow down.. | 24 | * Removed some unimportant debug output which causes slow down.. |
22 | * | 25 | * |
23 | * Revision 1.7 2003/08/01 12:30:16 eilers | 26 | * Revision 1.7 2003/08/01 12:30:16 eilers |
24 | * Merging changes from BRANCH_1_0 to HEAD | 27 | * Merging changes from BRANCH_1_0 to HEAD |
25 | * | 28 | * |
26 | * Revision 1.6 2003/07/07 16:19:47 eilers | 29 | * Revision 1.6 2003/07/07 16:19:47 eilers |
27 | * Fixing serious bug in hasQuerySettings() | 30 | * Fixing serious bug in hasQuerySettings() |
28 | * | 31 | * |
29 | * Revision 1.5 2003/04/13 18:07:10 zecke | 32 | * Revision 1.5 2003/04/13 18:07:10 zecke |
30 | * More API doc | 33 | * More API doc |
31 | * QString -> const QString& | 34 | * QString -> const QString& |
32 | * QString = 0l -> QString::null | 35 | * QString = 0l -> QString::null |
33 | * | 36 | * |
34 | * Revision 1.4 2003/03/21 14:32:54 mickeyl | 37 | * Revision 1.4 2003/03/21 14:32:54 mickeyl |
35 | * g++ compliance fix: default arguments belong into the declaration, but not the definition | 38 | * g++ compliance fix: default arguments belong into the declaration, but not the definition |
36 | * | 39 | * |
37 | * Revision 1.3 2003/03/21 12:26:28 eilers | 40 | * Revision 1.3 2003/03/21 12:26:28 eilers |
38 | * Fixing small bug: If we search a birthday from today to today, it returned | 41 | * Fixing small bug: If we search a birthday from today to today, it returned |
39 | * every contact .. | 42 | * every contact .. |
40 | * | 43 | * |
41 | * Revision 1.2 2003/03/21 10:33:09 eilers | 44 | * Revision 1.2 2003/03/21 10:33:09 eilers |
42 | * Merged speed optimized xml backend for contacts to main. | 45 | * Merged speed optimized xml backend for contacts to main. |
43 | * Added QDateTime to querybyexample. For instance, it is now possible to get | 46 | * Added QDateTime to querybyexample. For instance, it is now possible to get |
44 | * all Birthdays/Anniversaries between two dates. This should be used | 47 | * all Birthdays/Anniversaries between two dates. This should be used |
45 | * to show all birthdays in the datebook.. | 48 | * to show all birthdays in the datebook.. |
46 | * This change is sourcecode backward compatible but you have to upgrade | 49 | * This change is sourcecode backward compatible but you have to upgrade |
47 | * the binaries for today-addressbook. | 50 | * the binaries for today-addressbook. |
48 | * | 51 | * |
49 | * Revision 1.1.2.2 2003/02/11 12:17:28 eilers | 52 | * Revision 1.1.2.2 2003/02/11 12:17:28 eilers |
50 | * Speed optimization. Removed the sequential search loops. | 53 | * Speed optimization. Removed the sequential search loops. |
51 | * | 54 | * |
52 | * Revision 1.1.2.1 2003/02/10 15:31:38 eilers | 55 | * Revision 1.1.2.1 2003/02/10 15:31:38 eilers |
53 | * Writing offsets to debug output.. | 56 | * Writing offsets to debug output.. |
54 | * | 57 | * |
55 | * Revision 1.1 2003/02/09 15:05:01 eilers | 58 | * Revision 1.1 2003/02/09 15:05:01 eilers |
56 | * Nothing happened.. Just some cleanup before I will start.. | 59 | * Nothing happened.. Just some cleanup before I will start.. |
57 | * | 60 | * |
58 | * Revision 1.12 2003/01/03 16:58:03 eilers | 61 | * Revision 1.12 2003/01/03 16:58:03 eilers |
59 | * Reenable debug output | 62 | * Reenable debug output |
60 | * | 63 | * |
61 | * Revision 1.11 2003/01/03 12:31:28 eilers | 64 | * Revision 1.11 2003/01/03 12:31:28 eilers |
62 | * Bugfix for calculating data diffs.. | 65 | * Bugfix for calculating data diffs.. |
63 | * | 66 | * |
64 | * Revision 1.10 2003/01/02 14:27:12 eilers | 67 | * Revision 1.10 2003/01/02 14:27:12 eilers |
65 | * Improved query by example: Search by date is possible.. First step | 68 | * Improved query by example: Search by date is possible.. First step |
66 | * for a today plugin for birthdays.. | 69 | * for a today plugin for birthdays.. |
67 | * | 70 | * |
68 | * Revision 1.9 2002/12/08 12:48:57 eilers | 71 | * Revision 1.9 2002/12/08 12:48:57 eilers |
69 | * Moved journal-enum from ocontact into i the xml-backend.. | 72 | * Moved journal-enum from ocontact into i the xml-backend.. |
70 | * | 73 | * |
71 | * Revision 1.8 2002/11/14 17:04:24 eilers | 74 | * Revision 1.8 2002/11/14 17:04:24 eilers |
72 | * Sorting will now work if fullname is identical on some entries | 75 | * Sorting will now work if fullname is identical on some entries |
73 | * | 76 | * |
74 | * Revision 1.7 2002/11/13 15:02:46 eilers | 77 | * Revision 1.7 2002/11/13 15:02:46 eilers |
75 | * Small Bug in sorted fixed | 78 | * Small Bug in sorted fixed |
76 | * | 79 | * |
77 | * Revision 1.6 2002/11/13 14:14:51 eilers | 80 | * Revision 1.6 2002/11/13 14:14:51 eilers |
78 | * Added sorted for Contacts.. | 81 | * Added sorted for Contacts.. |
79 | * | 82 | * |
80 | * Revision 1.5 2002/11/01 15:10:42 eilers | 83 | * Revision 1.5 2002/11/01 15:10:42 eilers |
81 | * Added regExp-search in database for all fields in a contact. | 84 | * Added regExp-search in database for all fields in a contact. |
82 | * | 85 | * |
83 | * Revision 1.4 2002/10/16 10:52:40 eilers | 86 | * Revision 1.4 2002/10/16 10:52:40 eilers |
84 | * Added some docu to the interface and now using the cache infrastucture by zecke.. :) | 87 | * Added some docu to the interface and now using the cache infrastucture by zecke.. :) |
85 | * | 88 | * |
86 | * Revision 1.3 2002/10/14 16:21:54 eilers | 89 | * Revision 1.3 2002/10/14 16:21:54 eilers |
87 | * Some minor interface updates | 90 | * Some minor interface updates |
88 | * | 91 | * |
89 | * Revision 1.2 2002/10/07 17:34:24 eilers | 92 | * Revision 1.2 2002/10/07 17:34:24 eilers |
90 | * added OBackendFactory for advanced backend access | 93 | * added OBackendFactory for advanced backend access |
91 | * | 94 | * |
92 | * Revision 1.1 2002/09/27 17:11:44 eilers | 95 | * Revision 1.1 2002/09/27 17:11:44 eilers |
93 | * Added API for accessing the Contact-Database ! It is compiling, but | 96 | * Added API for accessing the Contact-Database ! It is compiling, but |
94 | * please do not expect that anything is working ! | 97 | * please do not expect that anything is working ! |
95 | * I will debug that stuff in the next time .. | 98 | * I will debug that stuff in the next time .. |
96 | * Please read README_COMPILE for compiling ! | 99 | * Please read README_COMPILE for compiling ! |
97 | * | 100 | * |
98 | * | 101 | * |
99 | */ | 102 | */ |
100 | 103 | ||
101 | #include "ocontactaccessbackend_xml.h" | 104 | #include "ocontactaccessbackend_xml.h" |
102 | 105 | ||
103 | #include <qasciidict.h> | 106 | #include <qasciidict.h> |
104 | #include <qdatetime.h> | 107 | #include <qdatetime.h> |
105 | #include <qfile.h> | 108 | #include <qfile.h> |
106 | #include <qfileinfo.h> | 109 | #include <qfileinfo.h> |
107 | #include <qregexp.h> | 110 | #include <qregexp.h> |
108 | #include <qarray.h> | 111 | #include <qarray.h> |
109 | #include <qmap.h> | 112 | #include <qmap.h> |
110 | #include <qdatetime.h> | 113 | #include <qdatetime.h> |
111 | 114 | ||
112 | #include <qpe/global.h> | 115 | #include <qpe/global.h> |
113 | 116 | ||
114 | #include <opie/xmltree.h> | 117 | #include <opie/xmltree.h> |
115 | #include "ocontactaccessbackend.h" | 118 | #include "ocontactaccessbackend.h" |
116 | #include "ocontactaccess.h" | 119 | #include "ocontactaccess.h" |
117 | 120 | ||
118 | #include <stdlib.h> | 121 | #include <stdlib.h> |
119 | #include <errno.h> | 122 | #include <errno.h> |
120 | 123 | ||
121 | using namespace Opie; | 124 | using namespace Opie; |
122 | 125 | ||
123 | 126 | ||
124 | OContactAccessBackend_XML::OContactAccessBackend_XML ( const QString& appname, const QString& filename ): | 127 | OContactAccessBackend_XML::OContactAccessBackend_XML ( const QString& appname, const QString& filename ): |
125 | m_changed( false ) | 128 | m_changed( false ) |
126 | { | 129 | { |
127 | // Just m_contactlist should call delete if an entry | 130 | // Just m_contactlist should call delete if an entry |
128 | // is removed. | 131 | // is removed. |
129 | m_contactList.setAutoDelete( true ); | 132 | m_contactList.setAutoDelete( true ); |
130 | m_uidToContact.setAutoDelete( false ); | 133 | m_uidToContact.setAutoDelete( false ); |
131 | 134 | ||
132 | m_appName = appname; | 135 | m_appName = appname; |
133 | 136 | ||
134 | /* Set journalfile name ... */ | 137 | /* Set journalfile name ... */ |
135 | m_journalName = getenv("HOME"); | 138 | m_journalName = getenv("HOME"); |
136 | m_journalName +="/.abjournal" + appname; | 139 | m_journalName +="/.abjournal" + appname; |
137 | 140 | ||
138 | /* Expecting to access the default filename if nothing else is set */ | 141 | /* Expecting to access the default filename if nothing else is set */ |
139 | if ( filename.isEmpty() ){ | 142 | if ( filename.isEmpty() ){ |
140 | m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); | 143 | m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); |
141 | } else | 144 | } else |
142 | m_fileName = filename; | 145 | m_fileName = filename; |
143 | 146 | ||
144 | /* Load Database now */ | 147 | /* Load Database now */ |
145 | load (); | 148 | load (); |
146 | } | 149 | } |
147 | 150 | ||
148 | bool OContactAccessBackend_XML::save() | 151 | bool OContactAccessBackend_XML::save() |
149 | { | 152 | { |
150 | 153 | ||
151 | if ( !m_changed ) | 154 | if ( !m_changed ) |
152 | return true; | 155 | return true; |
153 | 156 | ||
154 | QString strNewFile = m_fileName + ".new"; | 157 | QString strNewFile = m_fileName + ".new"; |
155 | QFile f( strNewFile ); | 158 | QFile f( strNewFile ); |
156 | if ( !f.open( IO_WriteOnly|IO_Raw ) ) | 159 | if ( !f.open( IO_WriteOnly|IO_Raw ) ) |
157 | return false; | 160 | return false; |
158 | 161 | ||
159 | int total_written; | 162 | int total_written; |
160 | int idx_offset = 0; | 163 | int idx_offset = 0; |
161 | QString out; | 164 | QString out; |
162 | 165 | ||
163 | // Write Header | 166 | // Write Header |
164 | out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" | 167 | out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" |
165 | " <Groups>\n" | 168 | " <Groups>\n" |
166 | " </Groups>\n" | 169 | " </Groups>\n" |
167 | " <Contacts>\n"; | 170 | " <Contacts>\n"; |
168 | QCString cstr = out.utf8(); | 171 | QCString cstr = out.utf8(); |
169 | f.writeBlock( cstr.data(), cstr.length() ); | 172 | f.writeBlock( cstr.data(), cstr.length() ); |
170 | idx_offset += cstr.length(); | 173 | idx_offset += cstr.length(); |
171 | out = ""; | 174 | out = ""; |
172 | 175 | ||
173 | // Write all contacts | 176 | // Write all contacts |
174 | QListIterator<OContact> it( m_contactList ); | 177 | QListIterator<OContact> it( m_contactList ); |
175 | for ( ; it.current(); ++it ) { | 178 | for ( ; it.current(); ++it ) { |
176 | // qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); | 179 | // qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); |
177 | out += "<Contact "; | 180 | out += "<Contact "; |
178 | (*it)->save( out ); | 181 | (*it)->save( out ); |
179 | out += "/>\n"; | 182 | out += "/>\n"; |
180 | cstr = out.utf8(); | 183 | cstr = out.utf8(); |
181 | total_written = f.writeBlock( cstr.data(), cstr.length() ); | 184 | total_written = f.writeBlock( cstr.data(), cstr.length() ); |
182 | idx_offset += cstr.length(); | 185 | idx_offset += cstr.length(); |
183 | if ( total_written != int(cstr.length()) ) { | 186 | if ( total_written != int(cstr.length()) ) { |
184 | f.close(); | 187 | f.close(); |
185 | QFile::remove( strNewFile ); | 188 | QFile::remove( strNewFile ); |
186 | return false; | 189 | return false; |
187 | } | 190 | } |
188 | out = ""; | 191 | out = ""; |
189 | } | 192 | } |
190 | out += " </Contacts>\n</AddressBook>\n"; | 193 | out += " </Contacts>\n</AddressBook>\n"; |
191 | 194 | ||
192 | // Write Footer | 195 | // Write Footer |
193 | cstr = out.utf8(); | 196 | cstr = out.utf8(); |
194 | total_written = f.writeBlock( cstr.data(), cstr.length() ); | 197 | total_written = f.writeBlock( cstr.data(), cstr.length() ); |
195 | if ( total_written != int( cstr.length() ) ) { | 198 | if ( total_written != int( cstr.length() ) ) { |
196 | f.close(); | 199 | f.close(); |
197 | QFile::remove( strNewFile ); | 200 | QFile::remove( strNewFile ); |
198 | return false; | 201 | return false; |
199 | } | 202 | } |
200 | f.close(); | 203 | f.close(); |
201 | 204 | ||
202 | // move the file over, I'm just going to use the system call | 205 | // move the file over, I'm just going to use the system call |
203 | // because, I don't feel like using QDir. | 206 | // because, I don't feel like using QDir. |
204 | if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { | 207 | if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { |
205 | qWarning( "problem renaming file %s to %s, errno: %d", | 208 | qWarning( "problem renaming file %s to %s, errno: %d", |
206 | strNewFile.latin1(), m_journalName.latin1(), errno ); | 209 | strNewFile.latin1(), m_journalName.latin1(), errno ); |
207 | // remove the tmp file... | 210 | // remove the tmp file... |
208 | QFile::remove( strNewFile ); | 211 | QFile::remove( strNewFile ); |
209 | } | 212 | } |
210 | 213 | ||
211 | /* The journalfile should be removed now... */ | 214 | /* The journalfile should be removed now... */ |
212 | removeJournal(); | 215 | removeJournal(); |
213 | 216 | ||
214 | m_changed = false; | 217 | m_changed = false; |
215 | return true; | 218 | return true; |
216 | } | 219 | } |
217 | 220 | ||
218 | bool OContactAccessBackend_XML::load () | 221 | bool OContactAccessBackend_XML::load () |
219 | { | 222 | { |
220 | m_contactList.clear(); | 223 | m_contactList.clear(); |
221 | m_uidToContact.clear(); | 224 | m_uidToContact.clear(); |
222 | 225 | ||
223 | /* Load XML-File and journal if it exists */ | 226 | /* Load XML-File and journal if it exists */ |
224 | if ( !load ( m_fileName, false ) ) | 227 | if ( !load ( m_fileName, false ) ) |
225 | return false; | 228 | return false; |
226 | /* The returncode of the journalfile is ignored due to the | 229 | /* The returncode of the journalfile is ignored due to the |
227 | * fact that it does not exist when this class is instantiated ! | 230 | * fact that it does not exist when this class is instantiated ! |
228 | * But there may such a file exist, if the application crashed. | 231 | * But there may such a file exist, if the application crashed. |
229 | * Therefore we try to load it to get the changes before the # | 232 | * Therefore we try to load it to get the changes before the # |
230 | * crash happened... | 233 | * crash happened... |
231 | */ | 234 | */ |
232 | load (m_journalName, true); | 235 | load (m_journalName, true); |
233 | 236 | ||
234 | return true; | 237 | return true; |
235 | } | 238 | } |
236 | 239 | ||
237 | void OContactAccessBackend_XML::clear () | 240 | void OContactAccessBackend_XML::clear () |
238 | { | 241 | { |
239 | m_contactList.clear(); | 242 | m_contactList.clear(); |
240 | m_uidToContact.clear(); | 243 | m_uidToContact.clear(); |
241 | 244 | ||
242 | m_changed = false; | 245 | m_changed = false; |
243 | } | 246 | } |
244 | 247 | ||
245 | bool OContactAccessBackend_XML::wasChangedExternally() | 248 | bool OContactAccessBackend_XML::wasChangedExternally() |
246 | { | 249 | { |
247 | QFileInfo fi( m_fileName ); | 250 | QFileInfo fi( m_fileName ); |
248 | 251 | ||
249 | QDateTime lastmod = fi.lastModified (); | 252 | QDateTime lastmod = fi.lastModified (); |
250 | 253 | ||
251 | return (lastmod != m_readtime); | 254 | return (lastmod != m_readtime); |
252 | } | 255 | } |
253 | 256 | ||
254 | QArray<int> OContactAccessBackend_XML::allRecords() const | 257 | QArray<int> OContactAccessBackend_XML::allRecords() const |
255 | { | 258 | { |
256 | QArray<int> uid_list( m_contactList.count() ); | 259 | QArray<int> uid_list( m_contactList.count() ); |
257 | 260 | ||
258 | uint counter = 0; | 261 | uint counter = 0; |
259 | QListIterator<OContact> it( m_contactList ); | 262 | QListIterator<OContact> it( m_contactList ); |
260 | for( ; it.current(); ++it ){ | 263 | for( ; it.current(); ++it ){ |
261 | uid_list[counter++] = (*it)->uid(); | 264 | uid_list[counter++] = (*it)->uid(); |
262 | } | 265 | } |
263 | 266 | ||
264 | return ( uid_list ); | 267 | return ( uid_list ); |
265 | } | 268 | } |
266 | 269 | ||
267 | OContact OContactAccessBackend_XML::find ( int uid ) const | 270 | OContact OContactAccessBackend_XML::find ( int uid ) const |
268 | { | 271 | { |
269 | OContact foundContact; //Create empty contact | 272 | OContact foundContact; //Create empty contact |
270 | 273 | ||
271 | OContact* found = m_uidToContact.find( QString().setNum( uid ) ); | 274 | OContact* found = m_uidToContact.find( QString().setNum( uid ) ); |
272 | 275 | ||
273 | if ( found ){ | 276 | if ( found ){ |
274 | foundContact = *found; | 277 | foundContact = *found; |
275 | } | 278 | } |
276 | 279 | ||
277 | return ( foundContact ); | 280 | return ( foundContact ); |
278 | } | 281 | } |
279 | 282 | ||
280 | QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings, | 283 | QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings, |
281 | const QDateTime& d ) | 284 | const QDateTime& d ) |
282 | { | 285 | { |
283 | 286 | ||
284 | QArray<int> m_currentQuery( m_contactList.count() ); | 287 | QArray<int> m_currentQuery( m_contactList.count() ); |
285 | QListIterator<OContact> it( m_contactList ); | 288 | QListIterator<OContact> it( m_contactList ); |
286 | uint arraycounter = 0; | 289 | uint arraycounter = 0; |
287 | 290 | ||
288 | for( ; it.current(); ++it ){ | 291 | for( ; it.current(); ++it ){ |
289 | /* Search all fields and compare them with query object. Store them into list | 292 | /* Search all fields and compare them with query object. Store them into list |
290 | * if all fields matches. | 293 | * if all fields matches. |
291 | */ | 294 | */ |
292 | QDate* queryDate = 0l; | 295 | QDate* queryDate = 0l; |
293 | QDate* checkDate = 0l; | 296 | QDate* checkDate = 0l; |
294 | bool allcorrect = true; | 297 | bool allcorrect = true; |
295 | for ( int i = 0; i < Qtopia::Groups; i++ ) { | 298 | for ( int i = 0; i < Qtopia::Groups; i++ ) { |
296 | // Birthday and anniversary are special nonstring fields and should | 299 | // Birthday and anniversary are special nonstring fields and should |
297 | // be handled specially | 300 | // be handled specially |
298 | switch ( i ){ | 301 | switch ( i ){ |
299 | case Qtopia::Birthday: | 302 | case Qtopia::Birthday: |
300 | queryDate = new QDate( query.birthday() ); | 303 | queryDate = new QDate( query.birthday() ); |
301 | checkDate = new QDate( (*it)->birthday() ); | 304 | checkDate = new QDate( (*it)->birthday() ); |
302 | case Qtopia::Anniversary: | 305 | case Qtopia::Anniversary: |
303 | if ( queryDate == 0l ){ | 306 | if ( queryDate == 0l ){ |
304 | queryDate = new QDate( query.anniversary() ); | 307 | queryDate = new QDate( query.anniversary() ); |
305 | checkDate = new QDate( (*it)->anniversary() ); | 308 | checkDate = new QDate( (*it)->anniversary() ); |
306 | } | 309 | } |
307 | 310 | ||
308 | if ( queryDate->isValid() ){ | 311 | if ( queryDate->isValid() ){ |
309 | if( checkDate->isValid() ){ | 312 | if( checkDate->isValid() ){ |
310 | if ( settings & OContactAccess::DateYear ){ | 313 | if ( settings & OContactAccess::DateYear ){ |
311 | if ( queryDate->year() != checkDate->year() ) | 314 | if ( queryDate->year() != checkDate->year() ) |
312 | allcorrect = false; | 315 | allcorrect = false; |
313 | } | 316 | } |
314 | if ( settings & OContactAccess::DateMonth ){ | 317 | if ( settings & OContactAccess::DateMonth ){ |
315 | if ( queryDate->month() != checkDate->month() ) | 318 | if ( queryDate->month() != checkDate->month() ) |
316 | allcorrect = false; | 319 | allcorrect = false; |
317 | } | 320 | } |
318 | if ( settings & OContactAccess::DateDay ){ | 321 | if ( settings & OContactAccess::DateDay ){ |
319 | if ( queryDate->day() != checkDate->day() ) | 322 | if ( queryDate->day() != checkDate->day() ) |
320 | allcorrect = false; | 323 | allcorrect = false; |
321 | } | 324 | } |
322 | if ( settings & OContactAccess::DateDiff ) { | 325 | if ( settings & OContactAccess::DateDiff ) { |
323 | QDate current; | 326 | QDate current; |
324 | // If we get an additional date, we | 327 | // If we get an additional date, we |
325 | // will take this date instead of | 328 | // will take this date instead of |
326 | // the current one.. | 329 | // the current one.. |
327 | if ( !d.date().isValid() ) | 330 | if ( !d.date().isValid() ) |
328 | current = QDate::currentDate(); | 331 | current = QDate::currentDate(); |
329 | else | 332 | else |
330 | current = d.date(); | 333 | current = d.date(); |
331 | 334 | ||
332 | // We have to equalize the year, otherwise | 335 | // We have to equalize the year, otherwise |
333 | // the search will fail.. | 336 | // the search will fail.. |
334 | checkDate->setYMD( current.year(), | 337 | checkDate->setYMD( current.year(), |
335 | checkDate->month(), | 338 | checkDate->month(), |
336 | checkDate->day() ); | 339 | checkDate->day() ); |
337 | if ( *checkDate < current ) | 340 | if ( *checkDate < current ) |
338 | checkDate->setYMD( current.year()+1, | 341 | checkDate->setYMD( current.year()+1, |
339 | checkDate->month(), | 342 | checkDate->month(), |
340 | checkDate->day() ); | 343 | checkDate->day() ); |
341 | 344 | ||
342 | // Check whether the birthday/anniversary date is between | 345 | // Check whether the birthday/anniversary date is between |
343 | // the current/given date and the maximum date | 346 | // the current/given date and the maximum date |
344 | // ( maximum time range ) ! | 347 | // ( maximum time range ) ! |
345 | qWarning("Checking if %s is between %s and %s ! ", | 348 | qWarning("Checking if %s is between %s and %s ! ", |
346 | checkDate->toString().latin1(), | 349 | checkDate->toString().latin1(), |
347 | current.toString().latin1(), | 350 | current.toString().latin1(), |
348 | queryDate->toString().latin1() ); | 351 | queryDate->toString().latin1() ); |
349 | if ( current.daysTo( *queryDate ) >= 0 ){ | 352 | if ( current.daysTo( *queryDate ) >= 0 ){ |
350 | if ( !( ( *checkDate >= current ) && | 353 | if ( !( ( *checkDate >= current ) && |
351 | ( *checkDate <= *queryDate ) ) ){ | 354 | ( *checkDate <= *queryDate ) ) ){ |
352 | allcorrect = false; | 355 | allcorrect = false; |
353 | qWarning (" Nope!.."); | 356 | qWarning (" Nope!.."); |
354 | } | 357 | } |
355 | } | 358 | } |
356 | } | 359 | } |
357 | } else{ | 360 | } else{ |
358 | // checkDate is invalid. Therefore this entry is always rejected | 361 | // checkDate is invalid. Therefore this entry is always rejected |
359 | allcorrect = false; | 362 | allcorrect = false; |
360 | } | 363 | } |
361 | } | 364 | } |
362 | 365 | ||
363 | delete queryDate; | 366 | delete queryDate; |
364 | queryDate = 0l; | 367 | queryDate = 0l; |
365 | delete checkDate; | 368 | delete checkDate; |
366 | checkDate = 0l; | 369 | checkDate = 0l; |
367 | break; | 370 | break; |
368 | default: | 371 | default: |
369 | /* Just compare fields which are not empty in the query object */ | 372 | /* Just compare fields which are not empty in the query object */ |
370 | if ( !query.field(i).isEmpty() ){ | 373 | if ( !query.field(i).isEmpty() ){ |
371 | switch ( settings & ~( OContactAccess::IgnoreCase | 374 | switch ( settings & ~( OContactAccess::IgnoreCase |
372 | | OContactAccess::DateDiff | 375 | | OContactAccess::DateDiff |
373 | | OContactAccess::DateYear | 376 | | OContactAccess::DateYear |
374 | | OContactAccess::DateMonth | 377 | | OContactAccess::DateMonth |
375 | | OContactAccess::DateDay | 378 | | OContactAccess::DateDay |
376 | | OContactAccess::MatchOne | 379 | | OContactAccess::MatchOne |
377 | ) ){ | 380 | ) ){ |
378 | 381 | ||
379 | case OContactAccess::RegExp:{ | 382 | case OContactAccess::RegExp:{ |
380 | QRegExp expr ( query.field(i), | 383 | QRegExp expr ( query.field(i), |
381 | !(settings & OContactAccess::IgnoreCase), | 384 | !(settings & OContactAccess::IgnoreCase), |
382 | false ); | 385 | false ); |
383 | if ( expr.find ( (*it)->field(i), 0 ) == -1 ) | 386 | if ( expr.find ( (*it)->field(i), 0 ) == -1 ) |
384 | allcorrect = false; | 387 | allcorrect = false; |
385 | } | 388 | } |
386 | break; | 389 | break; |
387 | case OContactAccess::WildCards:{ | 390 | case OContactAccess::WildCards:{ |
388 | QRegExp expr ( query.field(i), | 391 | QRegExp expr ( query.field(i), |
389 | !(settings & OContactAccess::IgnoreCase), | 392 | !(settings & OContactAccess::IgnoreCase), |
390 | true ); | 393 | true ); |
391 | if ( expr.find ( (*it)->field(i), 0 ) == -1 ) | 394 | if ( expr.find ( (*it)->field(i), 0 ) == -1 ) |
392 | allcorrect = false; | 395 | allcorrect = false; |
393 | } | 396 | } |
394 | break; | 397 | break; |
395 | case OContactAccess::ExactMatch:{ | 398 | case OContactAccess::ExactMatch:{ |
396 | if (settings & OContactAccess::IgnoreCase){ | 399 | if (settings & OContactAccess::IgnoreCase){ |
397 | if ( query.field(i).upper() != | 400 | if ( query.field(i).upper() != |
398 | (*it)->field(i).upper() ) | 401 | (*it)->field(i).upper() ) |
399 | allcorrect = false; | 402 | allcorrect = false; |
400 | }else{ | 403 | }else{ |
401 | if ( query.field(i) != (*it)->field(i) ) | 404 | if ( query.field(i) != (*it)->field(i) ) |
402 | allcorrect = false; | 405 | allcorrect = false; |
403 | } | 406 | } |
404 | } | 407 | } |
405 | break; | 408 | break; |
406 | } | 409 | } |
407 | } | 410 | } |
408 | } | 411 | } |
409 | } | 412 | } |
410 | if ( allcorrect ){ | 413 | if ( allcorrect ){ |
411 | m_currentQuery[arraycounter++] = (*it)->uid(); | 414 | m_currentQuery[arraycounter++] = (*it)->uid(); |
412 | } | 415 | } |
413 | } | 416 | } |
414 | 417 | ||
415 | // Shrink to fit.. | 418 | // Shrink to fit.. |
416 | m_currentQuery.resize(arraycounter); | 419 | m_currentQuery.resize(arraycounter); |
417 | 420 | ||
418 | return m_currentQuery; | 421 | return m_currentQuery; |
419 | } | 422 | } |
420 | 423 | ||
421 | QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const | 424 | QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const |
422 | { | 425 | { |
423 | QArray<int> m_currentQuery( m_contactList.count() ); | 426 | QArray<int> m_currentQuery( m_contactList.count() ); |
424 | QListIterator<OContact> it( m_contactList ); | 427 | QListIterator<OContact> it( m_contactList ); |
425 | uint arraycounter = 0; | 428 | uint arraycounter = 0; |
426 | 429 | ||
427 | for( ; it.current(); ++it ){ | 430 | for( ; it.current(); ++it ){ |
428 | if ( (*it)->match( r ) ){ | 431 | if ( (*it)->match( r ) ){ |
429 | m_currentQuery[arraycounter++] = (*it)->uid(); | 432 | m_currentQuery[arraycounter++] = (*it)->uid(); |
430 | } | 433 | } |
431 | 434 | ||
432 | } | 435 | } |
433 | // Shrink to fit.. | 436 | // Shrink to fit.. |
434 | m_currentQuery.resize(arraycounter); | 437 | m_currentQuery.resize(arraycounter); |
435 | 438 | ||
436 | return m_currentQuery; | 439 | return m_currentQuery; |
437 | } | 440 | } |
438 | 441 | ||
439 | const uint OContactAccessBackend_XML::querySettings() | 442 | const uint OContactAccessBackend_XML::querySettings() |
440 | { | 443 | { |
441 | return ( OContactAccess::WildCards | 444 | return ( OContactAccess::WildCards |
442 | | OContactAccess::IgnoreCase | 445 | | OContactAccess::IgnoreCase |
443 | | OContactAccess::RegExp | 446 | | OContactAccess::RegExp |
444 | | OContactAccess::ExactMatch | 447 | | OContactAccess::ExactMatch |
445 | | OContactAccess::DateDiff | 448 | | OContactAccess::DateDiff |
446 | | OContactAccess::DateYear | 449 | | OContactAccess::DateYear |
447 | | OContactAccess::DateMonth | 450 | | OContactAccess::DateMonth |
448 | | OContactAccess::DateDay | 451 | | OContactAccess::DateDay |
449 | ); | 452 | ); |
450 | } | 453 | } |
451 | 454 | ||
452 | bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const | 455 | bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const |
453 | { | 456 | { |
454 | /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay | 457 | /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay |
455 | * may be added with any of the other settings. IgnoreCase should never used alone. | 458 | * may be added with any of the other settings. IgnoreCase should never used alone. |
456 | * Wildcards, RegExp, ExactMatch should never used at the same time... | 459 | * Wildcards, RegExp, ExactMatch should never used at the same time... |
457 | */ | 460 | */ |
458 | 461 | ||
459 | // Step 1: Check whether the given settings are supported by this backend | 462 | // Step 1: Check whether the given settings are supported by this backend |
460 | if ( ( querySettings & ( | 463 | if ( ( querySettings & ( |
461 | OContactAccess::IgnoreCase | 464 | OContactAccess::IgnoreCase |
462 | | OContactAccess::WildCards | 465 | | OContactAccess::WildCards |
463 | | OContactAccess::DateDiff | 466 | | OContactAccess::DateDiff |
464 | | OContactAccess::DateYear | 467 | | OContactAccess::DateYear |
465 | | OContactAccess::DateMonth | 468 | | OContactAccess::DateMonth |
466 | | OContactAccess::DateDay | 469 | | OContactAccess::DateDay |
467 | | OContactAccess::RegExp | 470 | | OContactAccess::RegExp |
468 | | OContactAccess::ExactMatch | 471 | | OContactAccess::ExactMatch |
469 | ) ) != querySettings ) | 472 | ) ) != querySettings ) |
470 | return false; | 473 | return false; |
471 | 474 | ||
472 | // Step 2: Check whether the given combinations are ok.. | 475 | // Step 2: Check whether the given combinations are ok.. |
473 | 476 | ||
474 | // IngoreCase alone is invalid | 477 | // IngoreCase alone is invalid |
475 | if ( querySettings == OContactAccess::IgnoreCase ) | 478 | if ( querySettings == OContactAccess::IgnoreCase ) |
476 | return false; | 479 | return false; |
477 | 480 | ||
478 | // WildCards, RegExp and ExactMatch should never used at the same time | 481 | // WildCards, RegExp and ExactMatch should never used at the same time |
479 | switch ( querySettings & ~( OContactAccess::IgnoreCase | 482 | switch ( querySettings & ~( OContactAccess::IgnoreCase |
480 | | OContactAccess::DateDiff | 483 | | OContactAccess::DateDiff |
481 | | OContactAccess::DateYear | 484 | | OContactAccess::DateYear |
482 | | OContactAccess::DateMonth | 485 | | OContactAccess::DateMonth |
483 | | OContactAccess::DateDay | 486 | | OContactAccess::DateDay |
484 | ) | 487 | ) |
485 | ){ | 488 | ){ |
486 | case OContactAccess::RegExp: | 489 | case OContactAccess::RegExp: |
487 | return ( true ); | 490 | return ( true ); |
488 | case OContactAccess::WildCards: | 491 | case OContactAccess::WildCards: |
489 | return ( true ); | 492 | return ( true ); |
490 | case OContactAccess::ExactMatch: | 493 | case OContactAccess::ExactMatch: |
491 | return ( true ); | 494 | return ( true ); |
492 | case 0: // one of the upper removed bits were set.. | 495 | case 0: // one of the upper removed bits were set.. |
493 | return ( true ); | 496 | return ( true ); |
494 | default: | 497 | default: |
495 | return ( false ); | 498 | return ( false ); |
496 | } | 499 | } |
497 | } | 500 | } |
498 | 501 | ||
499 | // Currently only asc implemented.. | 502 | // Currently only asc implemented.. |
500 | QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int ) | 503 | QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int ) |
501 | { | 504 | { |
502 | QMap<QString, int> nameToUid; | 505 | QMap<QString, int> nameToUid; |
503 | QStringList names; | 506 | QStringList names; |
504 | QArray<int> m_currentQuery( m_contactList.count() ); | 507 | QArray<int> m_currentQuery( m_contactList.count() ); |
505 | 508 | ||
506 | // First fill map and StringList with all Names | 509 | // First fill map and StringList with all Names |
507 | // Afterwards sort namelist and use map to fill array to return.. | 510 | // Afterwards sort namelist and use map to fill array to return.. |
508 | QListIterator<OContact> it( m_contactList ); | 511 | QListIterator<OContact> it( m_contactList ); |
509 | for( ; it.current(); ++it ){ | 512 | for( ; it.current(); ++it ){ |
510 | names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); | 513 | names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); |
511 | nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); | 514 | nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); |
512 | } | 515 | } |
513 | names.sort(); | 516 | names.sort(); |
514 | 517 | ||
515 | int i = 0; | 518 | int i = 0; |
516 | if ( asc ){ | 519 | if ( asc ){ |
517 | for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) | 520 | for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) |
518 | m_currentQuery[i++] = nameToUid[ (*it) ]; | 521 | m_currentQuery[i++] = nameToUid[ (*it) ]; |
519 | }else{ | 522 | }else{ |
520 | for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) | 523 | for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) |
521 | m_currentQuery[i++] = nameToUid[ (*it) ]; | 524 | m_currentQuery[i++] = nameToUid[ (*it) ]; |
522 | } | 525 | } |
523 | 526 | ||
524 | return m_currentQuery; | 527 | return m_currentQuery; |
525 | 528 | ||
526 | } | 529 | } |
527 | 530 | ||
528 | bool OContactAccessBackend_XML::add ( const OContact &newcontact ) | 531 | bool OContactAccessBackend_XML::add ( const OContact &newcontact ) |
529 | { | 532 | { |
530 | //qWarning("odefaultbackend: ACTION::ADD"); | 533 | //qWarning("odefaultbackend: ACTION::ADD"); |
531 | updateJournal (newcontact, ACTION_ADD); | 534 | updateJournal (newcontact, ACTION_ADD); |
532 | addContact_p( newcontact ); | 535 | addContact_p( newcontact ); |
533 | 536 | ||
534 | m_changed = true; | 537 | m_changed = true; |
535 | 538 | ||
536 | return true; | 539 | return true; |
537 | } | 540 | } |
538 | 541 | ||
539 | bool OContactAccessBackend_XML::replace ( const OContact &contact ) | 542 | bool OContactAccessBackend_XML::replace ( const OContact &contact ) |
540 | { | 543 | { |
541 | m_changed = true; | 544 | m_changed = true; |
542 | 545 | ||
543 | OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); | 546 | OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); |
544 | 547 | ||
545 | if ( found ) { | 548 | if ( found ) { |
546 | OContact* newCont = new OContact( contact ); | 549 | OContact* newCont = new OContact( contact ); |
547 | 550 | ||
548 | updateJournal ( *newCont, ACTION_REPLACE); | 551 | updateJournal ( *newCont, ACTION_REPLACE); |
549 | m_contactList.removeRef ( found ); | 552 | m_contactList.removeRef ( found ); |
550 | m_contactList.append ( newCont ); | 553 | m_contactList.append ( newCont ); |
551 | m_uidToContact.remove( QString().setNum( contact.uid() ) ); | 554 | m_uidToContact.remove( QString().setNum( contact.uid() ) ); |
552 | m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); | 555 | m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); |
553 | 556 | ||
554 | qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); | 557 | qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); |
555 | 558 | ||
556 | return true; | 559 | return true; |
557 | } else | 560 | } else |
558 | return false; | 561 | return false; |
559 | } | 562 | } |
560 | 563 | ||
561 | bool OContactAccessBackend_XML::remove ( int uid ) | 564 | bool OContactAccessBackend_XML::remove ( int uid ) |
562 | { | 565 | { |
563 | m_changed = true; | 566 | m_changed = true; |
564 | 567 | ||
565 | OContact* found = m_uidToContact.find ( QString().setNum( uid ) ); | 568 | OContact* found = m_uidToContact.find ( QString().setNum( uid ) ); |
566 | 569 | ||
567 | if ( found ) { | 570 | if ( found ) { |
568 | updateJournal ( *found, ACTION_REMOVE); | 571 | updateJournal ( *found, ACTION_REMOVE); |
569 | m_contactList.removeRef ( found ); | 572 | m_contactList.removeRef ( found ); |
570 | m_uidToContact.remove( QString().setNum( uid ) ); | 573 | m_uidToContact.remove( QString().setNum( uid ) ); |
571 | 574 | ||
572 | return true; | 575 | return true; |
573 | } else | 576 | } else |
574 | return false; | 577 | return false; |
575 | } | 578 | } |
576 | 579 | ||
577 | bool OContactAccessBackend_XML::reload(){ | 580 | bool OContactAccessBackend_XML::reload(){ |
578 | /* Reload is the same as load in this implementation */ | 581 | /* Reload is the same as load in this implementation */ |
579 | return ( load() ); | 582 | return ( load() ); |
580 | } | 583 | } |
581 | 584 | ||
582 | void OContactAccessBackend_XML::addContact_p( const OContact &newcontact ) | 585 | void OContactAccessBackend_XML::addContact_p( const OContact &newcontact ) |
583 | { | 586 | { |
584 | OContact* contRef = new OContact( newcontact ); | 587 | OContact* contRef = new OContact( newcontact ); |
585 | 588 | ||
586 | m_contactList.append ( contRef ); | 589 | m_contactList.append ( contRef ); |
587 | m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); | 590 | m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); |
588 | } | 591 | } |
589 | 592 | ||
590 | /* This function loads the xml-database and the journalfile */ | 593 | /* This function loads the xml-database and the journalfile */ |
591 | bool OContactAccessBackend_XML::load( const QString filename, bool isJournal ) | 594 | bool OContactAccessBackend_XML::load( const QString filename, bool isJournal ) |
592 | { | 595 | { |
593 | 596 | ||
594 | /* We use the time of the last read to check if the file was | 597 | /* We use the time of the last read to check if the file was |
595 | * changed externally. | 598 | * changed externally. |
596 | */ | 599 | */ |
597 | if ( !isJournal ){ | 600 | if ( !isJournal ){ |
598 | QFileInfo fi( filename ); | 601 | QFileInfo fi( filename ); |
599 | m_readtime = fi.lastModified (); | 602 | m_readtime = fi.lastModified (); |
600 | } | 603 | } |
601 | 604 | ||
602 | const int JOURNALACTION = Qtopia::Notes + 1; | 605 | const int JOURNALACTION = Qtopia::Notes + 1; |
603 | const int JOURNALROW = JOURNALACTION + 1; | 606 | const int JOURNALROW = JOURNALACTION + 1; |
604 | 607 | ||
605 | bool foundAction = false; | 608 | bool foundAction = false; |
606 | journal_action action = ACTION_ADD; | 609 | journal_action action = ACTION_ADD; |
607 | int journalKey = 0; | 610 | int journalKey = 0; |
608 | QMap<int, QString> contactMap; | 611 | QMap<int, QString> contactMap; |
609 | QMap<QString, QString> customMap; | 612 | QMap<QString, QString> customMap; |
610 | QMap<QString, QString>::Iterator customIt; | 613 | QMap<QString, QString>::Iterator customIt; |
611 | QAsciiDict<int> dict( 47 ); | 614 | QAsciiDict<int> dict( 47 ); |
612 | 615 | ||
613 | dict.setAutoDelete( TRUE ); | 616 | dict.setAutoDelete( TRUE ); |
614 | dict.insert( "Uid", new int(Qtopia::AddressUid) ); | 617 | dict.insert( "Uid", new int(Qtopia::AddressUid) ); |
615 | dict.insert( "Title", new int(Qtopia::Title) ); | 618 | dict.insert( "Title", new int(Qtopia::Title) ); |
616 | dict.insert( "FirstName", new int(Qtopia::FirstName) ); | 619 | dict.insert( "FirstName", new int(Qtopia::FirstName) ); |
617 | dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); | 620 | dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); |
618 | dict.insert( "LastName", new int(Qtopia::LastName) ); | 621 | dict.insert( "LastName", new int(Qtopia::LastName) ); |
619 | dict.insert( "Suffix", new int(Qtopia::Suffix) ); | 622 | dict.insert( "Suffix", new int(Qtopia::Suffix) ); |
620 | dict.insert( "FileAs", new int(Qtopia::FileAs) ); | 623 | dict.insert( "FileAs", new int(Qtopia::FileAs) ); |
621 | dict.insert( "Categories", new int(Qtopia::AddressCategory) ); | 624 | dict.insert( "Categories", new int(Qtopia::AddressCategory) ); |
622 | dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); | 625 | dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); |
623 | dict.insert( "Emails", new int(Qtopia::Emails) ); | 626 | dict.insert( "Emails", new int(Qtopia::Emails) ); |
624 | dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); | 627 | dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); |
625 | dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); | 628 | dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); |
626 | dict.insert( "HomeState", new int(Qtopia::HomeState) ); | 629 | dict.insert( "HomeState", new int(Qtopia::HomeState) ); |
627 | dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); | 630 | dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); |
628 | dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); | 631 | dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); |
629 | dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); | 632 | dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); |
630 | dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); | 633 | dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); |
631 | dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); | 634 | dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); |
632 | dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); | 635 | dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); |
633 | dict.insert( "Company", new int(Qtopia::Company) ); | 636 | dict.insert( "Company", new int(Qtopia::Company) ); |
634 | dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); | 637 | dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); |
635 | dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); | 638 | dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); |
636 | dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); | 639 | dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); |
637 | dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); | 640 | dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); |
638 | dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); | 641 | dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); |
639 | dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); | 642 | dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); |
640 | dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); | 643 | dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); |
641 | dict.insert( "Department", new int(Qtopia::Department) ); | 644 | dict.insert( "Department", new int(Qtopia::Department) ); |
642 | dict.insert( "Office", new int(Qtopia::Office) ); | 645 | dict.insert( "Office", new int(Qtopia::Office) ); |
643 | dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); | 646 | dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); |
644 | dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); | 647 | dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); |
645 | dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); | 648 | dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); |
646 | dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); | 649 | dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); |
647 | dict.insert( "Profession", new int(Qtopia::Profession) ); | 650 | dict.insert( "Profession", new int(Qtopia::Profession) ); |
648 | dict.insert( "Assistant", new int(Qtopia::Assistant) ); | 651 | dict.insert( "Assistant", new int(Qtopia::Assistant) ); |
649 | dict.insert( "Manager", new int(Qtopia::Manager) ); | 652 | dict.insert( "Manager", new int(Qtopia::Manager) ); |
650 | dict.insert( "Spouse", new int(Qtopia::Spouse) ); | 653 | dict.insert( "Spouse", new int(Qtopia::Spouse) ); |
651 | dict.insert( "Children", new int(Qtopia::Children) ); | 654 | dict.insert( "Children", new int(Qtopia::Children) ); |
652 | dict.insert( "Gender", new int(Qtopia::Gender) ); | 655 | dict.insert( "Gender", new int(Qtopia::Gender) ); |
653 | dict.insert( "Birthday", new int(Qtopia::Birthday) ); | 656 | dict.insert( "Birthday", new int(Qtopia::Birthday) ); |
654 | dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); | 657 | dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); |
655 | dict.insert( "Nickname", new int(Qtopia::Nickname) ); | 658 | dict.insert( "Nickname", new int(Qtopia::Nickname) ); |
656 | dict.insert( "Notes", new int(Qtopia::Notes) ); | 659 | dict.insert( "Notes", new int(Qtopia::Notes) ); |
657 | dict.insert( "action", new int(JOURNALACTION) ); | 660 | dict.insert( "action", new int(JOURNALACTION) ); |
658 | dict.insert( "actionrow", new int(JOURNALROW) ); | 661 | dict.insert( "actionrow", new int(JOURNALROW) ); |
659 | 662 | ||
660 | //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() ); | 663 | //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() ); |
661 | 664 | ||
662 | XMLElement *root = XMLElement::load( filename ); | 665 | XMLElement *root = XMLElement::load( filename ); |
663 | if(root != 0l ){ // start parsing | 666 | if(root != 0l ){ // start parsing |
664 | /* Parse all XML-Elements and put the data into the | 667 | /* Parse all XML-Elements and put the data into the |
665 | * Contact-Class | 668 | * Contact-Class |
666 | */ | 669 | */ |
667 | XMLElement *element = root->firstChild(); | 670 | XMLElement *element = root->firstChild(); |
668 | //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() ); | 671 | //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() ); |
669 | element = element->firstChild(); | 672 | element = element->firstChild(); |
670 | 673 | ||
671 | /* Search Tag "Contacts" which is the parent of all Contacts */ | 674 | /* Search Tag "Contacts" which is the parent of all Contacts */ |
672 | while( element && !isJournal ){ | 675 | while( element && !isJournal ){ |
673 | if( element->tagName() != QString::fromLatin1("Contacts") ){ | 676 | if( element->tagName() != QString::fromLatin1("Contacts") ){ |
674 | //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s", | 677 | //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s", |
675 | // element->tagName().latin1()); | 678 | // element->tagName().latin1()); |
676 | element = element->nextChild(); | 679 | element = element->nextChild(); |
677 | } else { | 680 | } else { |
678 | element = element->firstChild(); | 681 | element = element->firstChild(); |
679 | break; | 682 | break; |
680 | } | 683 | } |
681 | } | 684 | } |
682 | /* Parse all Contacts and ignore unknown tags */ | 685 | /* Parse all Contacts and ignore unknown tags */ |
683 | while( element ){ | 686 | while( element ){ |
684 | if( element->tagName() != QString::fromLatin1("Contact") ){ | 687 | if( element->tagName() != QString::fromLatin1("Contact") ){ |
685 | //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s", | 688 | //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s", |
686 | // element->tagName().latin1()); | 689 | // element->tagName().latin1()); |
687 | element = element->nextChild(); | 690 | element = element->nextChild(); |
688 | continue; | 691 | continue; |
689 | } | 692 | } |
690 | /* Found alement with tagname "contact", now parse and store all | 693 | /* Found alement with tagname "contact", now parse and store all |
691 | * attributes contained | 694 | * attributes contained |
692 | */ | 695 | */ |
693 | //qWarning("OContactDefBack::load element tagName() : %s", | 696 | //qWarning("OContactDefBack::load element tagName() : %s", |
694 | // element->tagName().latin1() ); | 697 | // element->tagName().latin1() ); |
695 | QString dummy; | 698 | QString dummy; |
696 | foundAction = false; | 699 | foundAction = false; |
697 | 700 | ||
698 | XMLElement::AttributeMap aMap = element->attributes(); | 701 | XMLElement::AttributeMap aMap = element->attributes(); |
699 | XMLElement::AttributeMap::Iterator it; | 702 | XMLElement::AttributeMap::Iterator it; |
700 | contactMap.clear(); | 703 | contactMap.clear(); |
701 | customMap.clear(); | 704 | customMap.clear(); |
702 | for( it = aMap.begin(); it != aMap.end(); ++it ){ | 705 | for( it = aMap.begin(); it != aMap.end(); ++it ){ |
703 | // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); | 706 | // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); |
704 | 707 | ||
705 | int *find = dict[ it.key() ]; | 708 | int *find = dict[ it.key() ]; |
706 | /* Unknown attributes will be stored as "Custom" elements */ | 709 | /* Unknown attributes will be stored as "Custom" elements */ |
707 | if ( !find ) { | 710 | if ( !find ) { |
708 | // qWarning("Attribute %s not known.", it.key().latin1()); | 711 | // qWarning("Attribute %s not known.", it.key().latin1()); |
709 | //contact.setCustomField(it.key(), it.data()); | 712 | //contact.setCustomField(it.key(), it.data()); |
710 | customMap.insert( it.key(), it.data() ); | 713 | customMap.insert( it.key(), it.data() ); |
711 | continue; | 714 | continue; |
712 | } | 715 | } |
713 | 716 | ||
714 | /* Check if special conversion is needed and add attribute | 717 | /* Check if special conversion is needed and add attribute |
715 | * into Contact class | 718 | * into Contact class |
716 | */ | 719 | */ |
717 | switch( *find ) { | 720 | switch( *find ) { |
718 | /* | 721 | /* |
719 | case Qtopia::AddressUid: | 722 | case Qtopia::AddressUid: |
720 | contact.setUid( it.data().toInt() ); | 723 | contact.setUid( it.data().toInt() ); |
721 | break; | 724 | break; |
722 | case Qtopia::AddressCategory: | 725 | case Qtopia::AddressCategory: |
723 | contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); | 726 | contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); |
724 | break; | 727 | break; |
725 | */ | 728 | */ |
726 | case JOURNALACTION: | 729 | case JOURNALACTION: |
727 | action = journal_action(it.data().toInt()); | 730 | action = journal_action(it.data().toInt()); |
728 | foundAction = true; | 731 | foundAction = true; |
729 | qWarning ("ODefBack(journal)::ACTION found: %d", action); | 732 | qWarning ("ODefBack(journal)::ACTION found: %d", action); |
730 | break; | 733 | break; |
731 | case JOURNALROW: | 734 | case JOURNALROW: |
732 | journalKey = it.data().toInt(); | 735 | journalKey = it.data().toInt(); |
733 | break; | 736 | break; |
734 | default: // no conversion needed add them to the map | 737 | default: // no conversion needed add them to the map |
735 | contactMap.insert( *find, it.data() ); | 738 | contactMap.insert( *find, it.data() ); |
736 | break; | 739 | break; |
737 | } | 740 | } |
738 | } | 741 | } |
739 | /* now generate the Contact contact */ | 742 | /* now generate the Contact contact */ |
740 | OContact contact( contactMap ); | 743 | OContact contact( contactMap ); |
741 | 744 | ||
742 | for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { | 745 | for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { |
743 | contact.setCustomField( customIt.key(), customIt.data() ); | 746 | contact.setCustomField( customIt.key(), customIt.data() ); |
744 | } | 747 | } |
745 | 748 | ||
746 | if (foundAction){ | 749 | if (foundAction){ |
747 | foundAction = false; | 750 | foundAction = false; |
748 | switch ( action ) { | 751 | switch ( action ) { |
749 | case ACTION_ADD: | 752 | case ACTION_ADD: |
750 | addContact_p (contact); | 753 | addContact_p (contact); |
751 | break; | 754 | break; |
752 | case ACTION_REMOVE: | 755 | case ACTION_REMOVE: |
753 | if ( !remove (contact.uid()) ) | 756 | if ( !remove (contact.uid()) ) |
754 | qWarning ("ODefBack(journal)::Unable to remove uid: %d", | 757 | qWarning ("ODefBack(journal)::Unable to remove uid: %d", |
755 | contact.uid() ); | 758 | contact.uid() ); |
756 | break; | 759 | break; |
757 | case ACTION_REPLACE: | 760 | case ACTION_REPLACE: |
758 | if ( !replace ( contact ) ) | 761 | if ( !replace ( contact ) ) |
759 | qWarning ("ODefBack(journal)::Unable to replace uid: %d", | 762 | qWarning ("ODefBack(journal)::Unable to replace uid: %d", |
760 | contact.uid() ); | 763 | contact.uid() ); |
761 | break; | 764 | break; |
762 | default: | 765 | default: |
763 | qWarning ("Unknown action: ignored !"); | 766 | qWarning ("Unknown action: ignored !"); |
764 | break; | 767 | break; |
765 | } | 768 | } |
766 | }else{ | 769 | }else{ |
767 | /* Add contact to list */ | 770 | /* Add contact to list */ |
768 | addContact_p (contact); | 771 | addContact_p (contact); |
769 | } | 772 | } |
770 | 773 | ||
771 | /* Move to next element */ | 774 | /* Move to next element */ |
772 | element = element->nextChild(); | 775 | element = element->nextChild(); |
773 | } | 776 | } |
774 | }else { | 777 | }else { |
775 | qWarning("ODefBack::could not load"); | 778 | qWarning("ODefBack::could not load"); |
776 | } | 779 | } |
777 | delete root; | 780 | delete root; |
778 | qWarning("returning from loading" ); | 781 | qWarning("returning from loading" ); |
779 | return true; | 782 | return true; |
780 | } | 783 | } |
781 | 784 | ||
782 | 785 | ||
783 | void OContactAccessBackend_XML::updateJournal( const OContact& cnt, | 786 | void OContactAccessBackend_XML::updateJournal( const OContact& cnt, |
784 | journal_action action ) | 787 | journal_action action ) |
785 | { | 788 | { |
786 | QFile f( m_journalName ); | 789 | QFile f( m_journalName ); |
787 | bool created = !f.exists(); | 790 | bool created = !f.exists(); |
788 | if ( !f.open(IO_WriteOnly|IO_Append) ) | 791 | if ( !f.open(IO_WriteOnly|IO_Append) ) |
789 | return; | 792 | return; |
790 | 793 | ||
791 | QString buf; | 794 | QString buf; |
792 | QCString str; | 795 | QCString str; |
793 | 796 | ||
794 | // if the file was created, we have to set the Tag "<CONTACTS>" to | 797 | // if the file was created, we have to set the Tag "<CONTACTS>" to |
795 | // get a XML-File which is readable by our parser. | 798 | // get a XML-File which is readable by our parser. |
796 | // This is just a cheat, but better than rewrite the parser. | 799 | // This is just a cheat, but better than rewrite the parser. |
797 | if ( created ){ | 800 | if ( created ){ |
798 | buf = "<Contacts>"; | 801 | buf = "<Contacts>"; |
799 | QCString cstr = buf.utf8(); | 802 | QCString cstr = buf.utf8(); |
800 | f.writeBlock( cstr.data(), cstr.length() ); | 803 | f.writeBlock( cstr.data(), cstr.length() ); |
801 | } | 804 | } |
802 | 805 | ||
803 | buf = "<Contact "; | 806 | buf = "<Contact "; |
804 | cnt.save( buf ); | 807 | cnt.save( buf ); |
805 | buf += " action=\"" + QString::number( (int)action ) + "\" "; | 808 | buf += " action=\"" + QString::number( (int)action ) + "\" "; |
806 | buf += "/>\n"; | 809 | buf += "/>\n"; |
807 | QCString cstr = buf.utf8(); | 810 | QCString cstr = buf.utf8(); |
808 | f.writeBlock( cstr.data(), cstr.length() ); | 811 | f.writeBlock( cstr.data(), cstr.length() ); |
809 | } | 812 | } |
810 | 813 | ||
811 | void OContactAccessBackend_XML::removeJournal() | 814 | void OContactAccessBackend_XML::removeJournal() |
812 | { | 815 | { |
813 | QFile f ( m_journalName ); | 816 | QFile f ( m_journalName ); |
814 | if ( f.exists() ) | 817 | if ( f.exists() ) |
815 | f.remove(); | 818 | f.remove(); |
816 | } | 819 | } |
817 | 820 | ||
diff --git a/libopie/pim/ocontactaccessbackend_xml.h b/libopie/pim/ocontactaccessbackend_xml.h index 7b5365b..a0cae4d 100644 --- a/libopie/pim/ocontactaccessbackend_xml.h +++ b/libopie/pim/ocontactaccessbackend_xml.h | |||
@@ -1,154 +1,160 @@ | |||
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 | * File Locking to protect against concurrent access | ||
13 | * | 14 | * |
14 | * | 15 | * |
15 | * ===================================================================== | 16 | * ===================================================================== |
16 | * Version: $Id$ | 17 | * Version: $Id$ |
17 | * ===================================================================== | 18 | * ===================================================================== |
18 | * History: | 19 | * History: |
19 | * $Log$ | 20 | * $Log$ |
21 | * Revision 1.15 2003/09/22 14:31:16 eilers | ||
22 | * Added first experimental incarnation of sql-backend for addressbook. | ||
23 | * Some modifications to be able to compile the todo sql-backend. | ||
24 | * A lot of changes fill follow... | ||
25 | * | ||
20 | * Revision 1.14 2003/04/13 18:07:10 zecke | 26 | * Revision 1.14 2003/04/13 18:07:10 zecke |
21 | * More API doc | 27 | * More API doc |
22 | * QString -> const QString& | 28 | * QString -> const QString& |
23 | * QString = 0l -> QString::null | 29 | * QString = 0l -> QString::null |
24 | * | 30 | * |
25 | * Revision 1.13 2003/03/21 10:33:09 eilers | 31 | * Revision 1.13 2003/03/21 10:33:09 eilers |
26 | * Merged speed optimized xml backend for contacts to main. | 32 | * Merged speed optimized xml backend for contacts to main. |
27 | * Added QDateTime to querybyexample. For instance, it is now possible to get | 33 | * Added QDateTime to querybyexample. For instance, it is now possible to get |
28 | * all Birthdays/Anniversaries between two dates. This should be used | 34 | * all Birthdays/Anniversaries between two dates. This should be used |
29 | * to show all birthdays in the datebook.. | 35 | * to show all birthdays in the datebook.. |
30 | * This change is sourcecode backward compatible but you have to upgrade | 36 | * This change is sourcecode backward compatible but you have to upgrade |
31 | * the binaries for today-addressbook. | 37 | * the binaries for today-addressbook. |
32 | * | 38 | * |
33 | * Revision 1.12.2.2 2003/02/11 12:17:28 eilers | 39 | * Revision 1.12.2.2 2003/02/11 12:17:28 eilers |
34 | * Speed optimization. Removed the sequential search loops. | 40 | * Speed optimization. Removed the sequential search loops. |
35 | * | 41 | * |
36 | * Revision 1.12.2.1 2003/02/09 15:05:01 eilers | 42 | * Revision 1.12.2.1 2003/02/09 15:05:01 eilers |
37 | * Nothing happened.. Just some cleanup before I will start.. | 43 | * Nothing happened.. Just some cleanup before I will start.. |
38 | * | 44 | * |
39 | * Revision 1.12 2003/01/03 16:58:03 eilers | 45 | * Revision 1.12 2003/01/03 16:58:03 eilers |
40 | * Reenable debug output | 46 | * Reenable debug output |
41 | * | 47 | * |
42 | * Revision 1.11 2003/01/03 12:31:28 eilers | 48 | * Revision 1.11 2003/01/03 12:31:28 eilers |
43 | * Bugfix for calculating data diffs.. | 49 | * Bugfix for calculating data diffs.. |
44 | * | 50 | * |
45 | * Revision 1.10 2003/01/02 14:27:12 eilers | 51 | * Revision 1.10 2003/01/02 14:27:12 eilers |
46 | * Improved query by example: Search by date is possible.. First step | 52 | * Improved query by example: Search by date is possible.. First step |
47 | * for a today plugin for birthdays.. | 53 | * for a today plugin for birthdays.. |
48 | * | 54 | * |
49 | * Revision 1.9 2002/12/08 12:48:57 eilers | 55 | * Revision 1.9 2002/12/08 12:48:57 eilers |
50 | * Moved journal-enum from ocontact into i the xml-backend.. | 56 | * Moved journal-enum from ocontact into i the xml-backend.. |
51 | * | 57 | * |
52 | * Revision 1.8 2002/11/14 17:04:24 eilers | 58 | * Revision 1.8 2002/11/14 17:04:24 eilers |
53 | * Sorting will now work if fullname is identical on some entries | 59 | * Sorting will now work if fullname is identical on some entries |
54 | * | 60 | * |
55 | * Revision 1.7 2002/11/13 15:02:46 eilers | 61 | * Revision 1.7 2002/11/13 15:02:46 eilers |
56 | * Small Bug in sorted fixed | 62 | * Small Bug in sorted fixed |
57 | * | 63 | * |
58 | * Revision 1.6 2002/11/13 14:14:51 eilers | 64 | * Revision 1.6 2002/11/13 14:14:51 eilers |
59 | * Added sorted for Contacts.. | 65 | * Added sorted for Contacts.. |
60 | * | 66 | * |
61 | * Revision 1.5 2002/11/01 15:10:42 eilers | 67 | * Revision 1.5 2002/11/01 15:10:42 eilers |
62 | * Added regExp-search in database for all fields in a contact. | 68 | * Added regExp-search in database for all fields in a contact. |
63 | * | 69 | * |
64 | * Revision 1.4 2002/10/16 10:52:40 eilers | 70 | * Revision 1.4 2002/10/16 10:52:40 eilers |
65 | * Added some docu to the interface and now using the cache infrastucture by zecke.. :) | 71 | * Added some docu to the interface and now using the cache infrastucture by zecke.. :) |
66 | * | 72 | * |
67 | * Revision 1.3 2002/10/14 16:21:54 eilers | 73 | * Revision 1.3 2002/10/14 16:21:54 eilers |
68 | * Some minor interface updates | 74 | * Some minor interface updates |
69 | * | 75 | * |
70 | * Revision 1.2 2002/10/07 17:34:24 eilers | 76 | * Revision 1.2 2002/10/07 17:34:24 eilers |
71 | * added OBackendFactory for advanced backend access | 77 | * added OBackendFactory for advanced backend access |
72 | * | 78 | * |
73 | * Revision 1.1 2002/09/27 17:11:44 eilers | 79 | * Revision 1.1 2002/09/27 17:11:44 eilers |
74 | * Added API for accessing the Contact-Database ! It is compiling, but | 80 | * Added API for accessing the Contact-Database ! It is compiling, but |
75 | * please do not expect that anything is working ! | 81 | * please do not expect that anything is working ! |
76 | * I will debug that stuff in the next time .. | 82 | * I will debug that stuff in the next time .. |
77 | * Please read README_COMPILE for compiling ! | 83 | * Please read README_COMPILE for compiling ! |
78 | * | 84 | * |
79 | * | 85 | * |
80 | */ | 86 | */ |
81 | 87 | ||
82 | #ifndef _OContactAccessBackend_XML_ | 88 | #ifndef _OContactAccessBackend_XML_ |
83 | #define _OContactAccessBackend_XML_ | 89 | #define _OContactAccessBackend_XML_ |
84 | 90 | ||
85 | #include "ocontactaccessbackend.h" | 91 | #include "ocontactaccessbackend.h" |
86 | #include "ocontactaccess.h" | 92 | #include "ocontactaccess.h" |
87 | 93 | ||
88 | #include <qlist.h> | 94 | #include <qlist.h> |
89 | #include <qdict.h> | 95 | #include <qdict.h> |
90 | 96 | ||
91 | /* the default xml implementation */ | 97 | /* the default xml implementation */ |
92 | /** | 98 | /** |
93 | * This class is the XML implementation of a Contact backend | 99 | * This class is the XML implementation of a Contact backend |
94 | * it does implement everything available for OContact. | 100 | * it does implement everything available for OContact. |
95 | * @see OPimAccessBackend for more information of available methods | 101 | * @see OPimAccessBackend for more information of available methods |
96 | */ | 102 | */ |
97 | class OContactAccessBackend_XML : public OContactAccessBackend { | 103 | class OContactAccessBackend_XML : public OContactAccessBackend { |
98 | public: | 104 | public: |
99 | OContactAccessBackend_XML ( const QString& appname, const QString& filename = QString::null ); | 105 | OContactAccessBackend_XML ( const QString& appname, const QString& filename = QString::null ); |
100 | 106 | ||
101 | bool save(); | 107 | bool save(); |
102 | 108 | ||
103 | bool load (); | 109 | bool load (); |
104 | 110 | ||
105 | void clear (); | 111 | void clear (); |
106 | 112 | ||
107 | bool wasChangedExternally(); | 113 | bool wasChangedExternally(); |
108 | 114 | ||
109 | QArray<int> allRecords() const; | 115 | QArray<int> allRecords() const; |
110 | 116 | ||
111 | OContact find ( int uid ) const; | 117 | OContact find ( int uid ) const; |
112 | 118 | ||
113 | QArray<int> queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ); | 119 | QArray<int> queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ); |
114 | 120 | ||
115 | QArray<int> matchRegexp( const QRegExp &r ) const; | 121 | QArray<int> matchRegexp( const QRegExp &r ) const; |
116 | 122 | ||
117 | const uint querySettings(); | 123 | const uint querySettings(); |
118 | 124 | ||
119 | bool hasQuerySettings (uint querySettings) const; | 125 | bool hasQuerySettings (uint querySettings) const; |
120 | 126 | ||
121 | // Currently only asc implemented.. | 127 | // Currently only asc implemented.. |
122 | QArray<int> sorted( bool asc, int , int , int ); | 128 | QArray<int> sorted( bool asc, int , int , int ); |
123 | bool add ( const OContact &newcontact ); | 129 | bool add ( const OContact &newcontact ); |
124 | 130 | ||
125 | bool replace ( const OContact &contact ); | 131 | bool replace ( const OContact &contact ); |
126 | 132 | ||
127 | bool remove ( int uid ); | 133 | bool remove ( int uid ); |
128 | bool reload(); | 134 | bool reload(); |
129 | 135 | ||
130 | private: | 136 | private: |
131 | 137 | ||
132 | enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; | 138 | enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; |
133 | 139 | ||
134 | void addContact_p( const OContact &newcontact ); | 140 | void addContact_p( const OContact &newcontact ); |
135 | 141 | ||
136 | /* This function loads the xml-database and the journalfile */ | 142 | /* This function loads the xml-database and the journalfile */ |
137 | bool load( const QString filename, bool isJournal ); | 143 | bool load( const QString filename, bool isJournal ); |
138 | 144 | ||
139 | 145 | ||
140 | void updateJournal( const OContact& cnt, journal_action action ); | 146 | void updateJournal( const OContact& cnt, journal_action action ); |
141 | void removeJournal(); | 147 | void removeJournal(); |
142 | 148 | ||
143 | protected: | 149 | protected: |
144 | bool m_changed; | 150 | bool m_changed; |
145 | QString m_journalName; | 151 | QString m_journalName; |
146 | QString m_fileName; | 152 | QString m_fileName; |
147 | QString m_appName; | 153 | QString m_appName; |
148 | QList<OContact> m_contactList; | 154 | QList<OContact> m_contactList; |
149 | QDateTime m_readtime; | 155 | QDateTime m_readtime; |
150 | 156 | ||
151 | QDict<OContact> m_uidToContact; | 157 | QDict<OContact> m_uidToContact; |
152 | }; | 158 | }; |
153 | 159 | ||
154 | #endif | 160 | #endif |
diff --git a/libopie/pim/ocontactfields.cpp b/libopie/pim/ocontactfields.cpp new file mode 100644 index 0000000..831a596 --- a/dev/null +++ b/libopie/pim/ocontactfields.cpp | |||
@@ -0,0 +1,456 @@ | |||
1 | |||
2 | #include "ocontactfields.h" | ||
3 | |||
4 | #include <qstringlist.h> | ||
5 | #include <qobject.h> | ||
6 | |||
7 | // We should use our own enum in the future .. | ||
8 | #include <qpe/recordfields.h> | ||
9 | #include <qpe/config.h> | ||
10 | #include <opie/ocontact.h> | ||
11 | |||
12 | /*! | ||
13 | \internal | ||
14 | Returns a list of details field names for a contact. | ||
15 | */ | ||
16 | QStringList OContactFields::untrdetailsfields( bool sorted ) | ||
17 | { | ||
18 | QStringList list; | ||
19 | QMap<int, QString> mapIdToStr = idToUntrFields(); | ||
20 | |||
21 | list.append( mapIdToStr[ Qtopia::Office ] ); | ||
22 | list.append( mapIdToStr[ Qtopia::Profession ] ); | ||
23 | list.append( mapIdToStr[ Qtopia::Assistant ] ); | ||
24 | list.append( mapIdToStr[ Qtopia::Manager ] ); | ||
25 | |||
26 | list.append( mapIdToStr[ Qtopia::Spouse ] ); | ||
27 | list.append( mapIdToStr[ Qtopia::Gender ] ); | ||
28 | list.append( mapIdToStr[ Qtopia::Birthday ] ); | ||
29 | list.append( mapIdToStr[ Qtopia::Anniversary ] ); | ||
30 | list.append( mapIdToStr[ Qtopia::Nickname ] ); | ||
31 | list.append( mapIdToStr[ Qtopia::Children ] ); | ||
32 | |||
33 | if (sorted) list.sort(); | ||
34 | return list; | ||
35 | } | ||
36 | |||
37 | /*! | ||
38 | \internal | ||
39 | Returns a translated list of details field names for a contact. | ||
40 | */ | ||
41 | QStringList OContactFields::trdetailsfields( bool sorted ) | ||
42 | { | ||
43 | QStringList list; | ||
44 | QMap<int, QString> mapIdToStr = idToTrFields(); | ||
45 | |||
46 | list.append( mapIdToStr[Qtopia::Office] ); | ||
47 | list.append( mapIdToStr[Qtopia::Profession] ); | ||
48 | list.append( mapIdToStr[Qtopia::Assistant] ); | ||
49 | list.append( mapIdToStr[Qtopia::Manager] ); | ||
50 | |||
51 | list.append( mapIdToStr[Qtopia::Spouse] ); | ||
52 | list.append( mapIdToStr[Qtopia::Gender] ); | ||
53 | list.append( mapIdToStr[Qtopia::Birthday] ); | ||
54 | list.append( mapIdToStr[Qtopia::Anniversary] ); | ||
55 | list.append( mapIdToStr[Qtopia::Nickname] ); | ||
56 | list.append( mapIdToStr[Qtopia::Children] ); | ||
57 | |||
58 | if (sorted) list.sort(); | ||
59 | return list; | ||
60 | } | ||
61 | |||
62 | |||
63 | /*! | ||
64 | \internal | ||
65 | Returns a translated list of phone field names for a contact. | ||
66 | */ | ||
67 | QStringList OContactFields::trphonefields( bool sorted ) | ||
68 | { | ||
69 | QStringList list; | ||
70 | QMap<int, QString> mapIdToStr = idToTrFields(); | ||
71 | |||
72 | list.append( mapIdToStr[Qtopia::BusinessPhone] ); | ||
73 | list.append( mapIdToStr[Qtopia::BusinessFax] ); | ||
74 | list.append( mapIdToStr[Qtopia::BusinessMobile] ); | ||
75 | list.append( mapIdToStr[Qtopia::BusinessPager] ); | ||
76 | list.append( mapIdToStr[Qtopia::BusinessWebPage] ); | ||
77 | |||
78 | list.append( mapIdToStr[Qtopia::DefaultEmail] ); | ||
79 | list.append( mapIdToStr[Qtopia::Emails] ); | ||
80 | |||
81 | list.append( mapIdToStr[Qtopia::HomePhone] ); | ||
82 | list.append( mapIdToStr[Qtopia::HomeFax] ); | ||
83 | list.append( mapIdToStr[Qtopia::HomeMobile] ); | ||
84 | // list.append( mapIdToStr[Qtopia::HomePager] ); | ||
85 | list.append( mapIdToStr[Qtopia::HomeWebPage] ); | ||
86 | |||
87 | if (sorted) list.sort(); | ||
88 | |||
89 | return list; | ||
90 | } | ||
91 | |||
92 | |||
93 | /*! | ||
94 | \internal | ||
95 | Returns a list of phone field names for a contact. | ||
96 | */ | ||
97 | QStringList OContactFields::untrphonefields( bool sorted ) | ||
98 | { | ||
99 | QStringList list; | ||
100 | QMap<int, QString> mapIdToStr = idToUntrFields(); | ||
101 | |||
102 | list.append( mapIdToStr[ Qtopia::BusinessPhone ] ); | ||
103 | list.append( mapIdToStr[ Qtopia::BusinessFax ] ); | ||
104 | list.append( mapIdToStr[ Qtopia::BusinessMobile ] ); | ||
105 | list.append( mapIdToStr[ Qtopia::BusinessPager ] ); | ||
106 | list.append( mapIdToStr[ Qtopia::BusinessWebPage ] ); | ||
107 | |||
108 | list.append( mapIdToStr[ Qtopia::DefaultEmail ] ); | ||
109 | list.append( mapIdToStr[ Qtopia::Emails ] ); | ||
110 | |||
111 | list.append( mapIdToStr[ Qtopia::HomePhone ] ); | ||
112 | list.append( mapIdToStr[ Qtopia::HomeFax ] ); | ||
113 | list.append( mapIdToStr[ Qtopia::HomeMobile ] ); | ||
114 | //list.append( mapIdToStr[Qtopia::HomePager] ); | ||
115 | list.append( mapIdToStr[Qtopia::HomeWebPage] ); | ||
116 | |||
117 | if (sorted) list.sort(); | ||
118 | |||
119 | return list; | ||
120 | } | ||
121 | |||
122 | |||
123 | /*! | ||
124 | \internal | ||
125 | Returns a translated list of field names for a contact. | ||
126 | */ | ||
127 | QStringList OContactFields::trfields( bool sorted ) | ||
128 | { | ||
129 | QStringList list; | ||
130 | QMap<int, QString> mapIdToStr = idToTrFields(); | ||
131 | |||
132 | list.append( mapIdToStr[Qtopia::Title]); | ||
133 | list.append( mapIdToStr[Qtopia::FirstName] ); | ||
134 | list.append( mapIdToStr[Qtopia::MiddleName] ); | ||
135 | list.append( mapIdToStr[Qtopia::LastName] ); | ||
136 | list.append( mapIdToStr[Qtopia::Suffix] ); | ||
137 | list.append( mapIdToStr[Qtopia::FileAs] ); | ||
138 | |||
139 | list.append( mapIdToStr[Qtopia::JobTitle] ); | ||
140 | list.append( mapIdToStr[Qtopia::Department] ); | ||
141 | list.append( mapIdToStr[Qtopia::Company] ); | ||
142 | |||
143 | list += trphonefields( sorted ); | ||
144 | |||
145 | list.append( mapIdToStr[Qtopia::BusinessStreet] ); | ||
146 | list.append( mapIdToStr[Qtopia::BusinessCity] ); | ||
147 | list.append( mapIdToStr[Qtopia::BusinessState] ); | ||
148 | list.append( mapIdToStr[Qtopia::BusinessZip] ); | ||
149 | list.append( mapIdToStr[Qtopia::BusinessCountry] ); | ||
150 | |||
151 | list.append( mapIdToStr[Qtopia::HomeStreet] ); | ||
152 | list.append( mapIdToStr[Qtopia::HomeCity] ); | ||
153 | list.append( mapIdToStr[Qtopia::HomeState] ); | ||
154 | list.append( mapIdToStr[Qtopia::HomeZip] ); | ||
155 | list.append( mapIdToStr[Qtopia::HomeCountry] ); | ||
156 | |||
157 | list += trdetailsfields( sorted ); | ||
158 | |||
159 | list.append( mapIdToStr[Qtopia::Notes] ); | ||
160 | list.append( mapIdToStr[Qtopia::Groups] ); | ||
161 | |||
162 | if (sorted) list.sort(); | ||
163 | |||
164 | return list; | ||
165 | } | ||
166 | |||
167 | /*! | ||
168 | \internal | ||
169 | Returns an untranslated list of field names for a contact. | ||
170 | */ | ||
171 | QStringList OContactFields::untrfields( bool sorted ) | ||
172 | { | ||
173 | QStringList list; | ||
174 | QMap<int, QString> mapIdToStr = idToUntrFields(); | ||
175 | |||
176 | list.append( mapIdToStr[ Qtopia::Title ] ); | ||
177 | list.append( mapIdToStr[ Qtopia::FirstName ] ); | ||
178 | list.append( mapIdToStr[ Qtopia::MiddleName ] ); | ||
179 | list.append( mapIdToStr[ Qtopia::LastName ] ); | ||
180 | list.append( mapIdToStr[ Qtopia::Suffix ] ); | ||
181 | list.append( mapIdToStr[ Qtopia::FileAs ] ); | ||
182 | |||
183 | list.append( mapIdToStr[ Qtopia::JobTitle ] ); | ||
184 | list.append( mapIdToStr[ Qtopia::Department ] ); | ||
185 | list.append( mapIdToStr[ Qtopia::Company ] ); | ||
186 | |||
187 | list += untrphonefields( sorted ); | ||
188 | |||
189 | list.append( mapIdToStr[ Qtopia::BusinessStreet ] ); | ||
190 | list.append( mapIdToStr[ Qtopia::BusinessCity ] ); | ||
191 | list.append( mapIdToStr[ Qtopia::BusinessState ] ); | ||
192 | list.append( mapIdToStr[ Qtopia::BusinessZip ] ); | ||
193 | list.append( mapIdToStr[ Qtopia::BusinessCountry ] ); | ||
194 | |||
195 | list.append( mapIdToStr[ Qtopia::HomeStreet ] ); | ||
196 | list.append( mapIdToStr[ Qtopia::HomeCity ] ); | ||
197 | list.append( mapIdToStr[ Qtopia::HomeState ] ); | ||
198 | list.append( mapIdToStr[ Qtopia::HomeZip ] ); | ||
199 | list.append( mapIdToStr[ Qtopia::HomeCountry ] ); | ||
200 | |||
201 | list += untrdetailsfields( sorted ); | ||
202 | |||
203 | list.append( mapIdToStr[ Qtopia::Notes ] ); | ||
204 | list.append( mapIdToStr[ Qtopia::Groups ] ); | ||
205 | |||
206 | if (sorted) list.sort(); | ||
207 | |||
208 | return list; | ||
209 | } | ||
210 | QMap<int, QString> OContactFields::idToTrFields() | ||
211 | { | ||
212 | QMap<int, QString> ret_map; | ||
213 | |||
214 | ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") ); | ||
215 | ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) ); | ||
216 | ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) ); | ||
217 | ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) ); | ||
218 | ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" )); | ||
219 | ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) ); | ||
220 | |||
221 | ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) ); | ||
222 | ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) ); | ||
223 | ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) ); | ||
224 | ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) ); | ||
225 | ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) ); | ||
226 | ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" )); | ||
227 | |||
228 | |||
229 | ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) ); | ||
230 | ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) ); | ||
231 | |||
232 | ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) ); | ||
233 | ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) ); | ||
234 | ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) ); | ||
235 | |||
236 | // business | ||
237 | ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) ); | ||
238 | ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) ); | ||
239 | ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) ); | ||
240 | ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) ); | ||
241 | ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) ); | ||
242 | ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) ); | ||
243 | ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) ); | ||
244 | |||
245 | ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) ); | ||
246 | ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) ); | ||
247 | ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) ); | ||
248 | ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) ); | ||
249 | |||
250 | // home | ||
251 | ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) ); | ||
252 | ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) ); | ||
253 | ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) ); | ||
254 | ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) ); | ||
255 | ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) ); | ||
256 | ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) ); | ||
257 | |||
258 | //personal | ||
259 | ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) ); | ||
260 | ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) ); | ||
261 | ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) ); | ||
262 | ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) ); | ||
263 | ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) ); | ||
264 | ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) ); | ||
265 | |||
266 | // other | ||
267 | ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) ); | ||
268 | |||
269 | |||
270 | return ret_map; | ||
271 | } | ||
272 | |||
273 | QMap<int, QString> OContactFields::idToUntrFields() | ||
274 | { | ||
275 | QMap<int, QString> ret_map; | ||
276 | |||
277 | ret_map.insert( Qtopia::Title, "Name Title" ); | ||
278 | ret_map.insert( Qtopia::FirstName, "First Name" ); | ||
279 | ret_map.insert( Qtopia::MiddleName, "Middle Name" ); | ||
280 | ret_map.insert( Qtopia::LastName, "Last Name" ); | ||
281 | ret_map.insert( Qtopia::Suffix, "Suffix" ); | ||
282 | ret_map.insert( Qtopia::FileAs, "File As" ); | ||
283 | |||
284 | ret_map.insert( Qtopia::JobTitle, "Job Title" ); | ||
285 | ret_map.insert( Qtopia::Department, "Department" ); | ||
286 | ret_map.insert( Qtopia::Company, "Company" ); | ||
287 | ret_map.insert( Qtopia::BusinessPhone, "Business Phone" ); | ||
288 | ret_map.insert( Qtopia::BusinessFax, "Business Fax" ); | ||
289 | ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" ); | ||
290 | |||
291 | |||
292 | ret_map.insert( Qtopia::DefaultEmail, "Default Email" ); | ||
293 | ret_map.insert( Qtopia::Emails, "Emails" ); | ||
294 | |||
295 | ret_map.insert( Qtopia::HomePhone, "Home Phone" ); | ||
296 | ret_map.insert( Qtopia::HomeFax, "Home Fax" ); | ||
297 | ret_map.insert( Qtopia::HomeMobile, "Home Mobile" ); | ||
298 | |||
299 | // business | ||
300 | ret_map.insert( Qtopia::BusinessStreet, "Business Street" ); | ||
301 | ret_map.insert( Qtopia::BusinessCity, "Business City" ); | ||
302 | ret_map.insert( Qtopia::BusinessState, "Business State" ); | ||
303 | ret_map.insert( Qtopia::BusinessZip, "Business Zip" ); | ||
304 | ret_map.insert( Qtopia::BusinessCountry, "Business Country" ); | ||
305 | ret_map.insert( Qtopia::BusinessPager, "Business Pager" ); | ||
306 | ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" ); | ||
307 | |||
308 | ret_map.insert( Qtopia::Office, "Office" ); | ||
309 | ret_map.insert( Qtopia::Profession, "Profession" ); | ||
310 | ret_map.insert( Qtopia::Assistant, "Assistant" ); | ||
311 | ret_map.insert( Qtopia::Manager, "Manager" ); | ||
312 | |||
313 | // home | ||
314 | ret_map.insert( Qtopia::HomeStreet, "Home Street" ); | ||
315 | ret_map.insert( Qtopia::HomeCity, "Home City" ); | ||
316 | ret_map.insert( Qtopia::HomeState, "Home State" ); | ||
317 | ret_map.insert( Qtopia::HomeZip, "Home Zip" ); | ||
318 | ret_map.insert( Qtopia::HomeCountry, "Home Country" ); | ||
319 | ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" ); | ||
320 | |||
321 | //personal | ||
322 | ret_map.insert( Qtopia::Spouse, "Spouse" ); | ||
323 | ret_map.insert( Qtopia::Gender, "Gender" ); | ||
324 | ret_map.insert( Qtopia::Birthday, "Birthday" ); | ||
325 | ret_map.insert( Qtopia::Anniversary, "Anniversary" ); | ||
326 | ret_map.insert( Qtopia::Nickname, "Nickname" ); | ||
327 | ret_map.insert( Qtopia::Children, "Children" ); | ||
328 | |||
329 | // other | ||
330 | ret_map.insert( Qtopia::Notes, "Notes" ); | ||
331 | |||
332 | |||
333 | return ret_map; | ||
334 | } | ||
335 | |||
336 | QMap<QString, int> OContactFields::trFieldsToId() | ||
337 | { | ||
338 | QMap<int, QString> idtostr = idToTrFields(); | ||
339 | QMap<QString, int> ret_map; | ||
340 | |||
341 | |||
342 | QMap<int, QString>::Iterator it; | ||
343 | for( it = idtostr.begin(); it != idtostr.end(); ++it ) | ||
344 | ret_map.insert( *it, it.key() ); | ||
345 | |||
346 | |||
347 | return ret_map; | ||
348 | } | ||
349 | |||
350 | QMap<QString, int> OContactFields::untrFieldsToId() | ||
351 | { | ||
352 | QMap<int, QString> idtostr = idToUntrFields(); | ||
353 | QMap<QString, int> ret_map; | ||
354 | |||
355 | |||
356 | QMap<int, QString>::Iterator it; | ||
357 | for( it = idtostr.begin(); it != idtostr.end(); ++it ) | ||
358 | ret_map.insert( *it, it.key() ); | ||
359 | |||
360 | |||
361 | return ret_map; | ||
362 | } | ||
363 | |||
364 | |||
365 | OContactFields::OContactFields(): | ||
366 | fieldOrder( DEFAULT_FIELD_ORDER ), | ||
367 | changedFieldOrder( false ) | ||
368 | { | ||
369 | // Get the global field order from the config file and | ||
370 | // use it as a start pattern | ||
371 | Config cfg ( "AddressBook" ); | ||
372 | cfg.setGroup( "ContactFieldOrder" ); | ||
373 | globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER ); | ||
374 | } | ||
375 | |||
376 | OContactFields::~OContactFields(){ | ||
377 | |||
378 | // We will store the fieldorder into the config file | ||
379 | // to reuse it for the future.. | ||
380 | if ( changedFieldOrder ){ | ||
381 | Config cfg ( "AddressBook" ); | ||
382 | cfg.setGroup( "ContactFieldOrder" ); | ||
383 | cfg.writeEntry( "General", globalFieldOrder ); | ||
384 | } | ||
385 | } | ||
386 | |||
387 | |||
388 | |||
389 | void OContactFields::saveToRecord( OContact &cnt ){ | ||
390 | |||
391 | qDebug("ocontactfields saveToRecord: >%s<",fieldOrder.latin1()); | ||
392 | |||
393 | // Store fieldorder into this contact. | ||
394 | cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder ); | ||
395 | |||
396 | globalFieldOrder = fieldOrder; | ||
397 | changedFieldOrder = true; | ||
398 | |||
399 | } | ||
400 | |||
401 | void OContactFields::loadFromRecord( const OContact &cnt ){ | ||
402 | qDebug("ocontactfields loadFromRecord"); | ||
403 | qDebug("loading >%s<",cnt.fullName().latin1()); | ||
404 | |||
405 | // Get fieldorder for this contact. If none is defined, | ||
406 | // we will use the global one from the config file.. | ||
407 | |||
408 | fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME ); | ||
409 | |||
410 | qDebug("fieldOrder from contact>%s<",fieldOrder.latin1()); | ||
411 | |||
412 | if (fieldOrder.isEmpty()){ | ||
413 | fieldOrder = globalFieldOrder; | ||
414 | } | ||
415 | |||
416 | |||
417 | qDebug("effective fieldOrder in loadFromRecord >%s<",fieldOrder.latin1()); | ||
418 | } | ||
419 | |||
420 | void OContactFields::setFieldOrder( int num, int index ){ | ||
421 | qDebug("qcontactfields setfieldorder pos %i -> %i",num,index); | ||
422 | |||
423 | fieldOrder[num] = QString::number( index, 16 )[0]; | ||
424 | |||
425 | // We will store this new fieldorder globally to | ||
426 | // remember it for contacts which have none | ||
427 | globalFieldOrder = fieldOrder; | ||
428 | changedFieldOrder = true; | ||
429 | |||
430 | qDebug("fieldOrder >%s<",fieldOrder.latin1()); | ||
431 | } | ||
432 | |||
433 | int OContactFields::getFieldOrder( int num, int defIndex ){ | ||
434 | qDebug("ocontactfields getFieldOrder"); | ||
435 | qDebug("fieldOrder >%s<",fieldOrder.latin1()); | ||
436 | |||
437 | // Get index of combo as char.. | ||
438 | QChar poschar = fieldOrder[num]; | ||
439 | |||
440 | bool ok; | ||
441 | int ret = 0; | ||
442 | // Convert char to number.. | ||
443 | if ( !( poschar == QChar::null ) ) | ||
444 | ret = QString( poschar ).toInt(&ok, 16); | ||
445 | else | ||
446 | ok = false; | ||
447 | |||
448 | // Return default value if index for | ||
449 | // num was not set or if anything else happened.. | ||
450 | if ( !ok ) ret = defIndex; | ||
451 | |||
452 | qDebug("returning >%i<",ret); | ||
453 | |||
454 | return ret; | ||
455 | |||
456 | } | ||
diff --git a/libopie/pim/ocontactfields.h b/libopie/pim/ocontactfields.h new file mode 100644 index 0000000..9f6171b --- a/dev/null +++ b/libopie/pim/ocontactfields.h | |||
@@ -0,0 +1,60 @@ | |||
1 | #ifndef OPIE_CONTACTS_FIELDS | ||
2 | #define OPIE_CONTACTS_FIELDS | ||
3 | |||
4 | class QStringList; | ||
5 | |||
6 | #include <qmap.h> | ||
7 | #include <qstring.h> | ||
8 | #include <opie/ocontact.h> | ||
9 | |||
10 | #define CONTACT_FIELD_ORDER_NAME "opie-contactfield-order" | ||
11 | #define DEFAULT_FIELD_ORDER "__________" | ||
12 | |||
13 | class OContactFields{ | ||
14 | |||
15 | public: | ||
16 | OContactFields(); | ||
17 | ~OContactFields(); | ||
18 | /** Set the index for combo boxes. | ||
19 | * Sets the <b>index</b> of combo <b>num</b>. | ||
20 | * @param num selects the number of the combo | ||
21 | * @param index sets the index in the combo | ||
22 | */ | ||
23 | void setFieldOrder( int num, int index ); | ||
24 | |||
25 | /** Get the index for combo boxes. | ||
26 | * Returns the index of combo <b>num</b> or defindex | ||
27 | * if none was defined.. | ||
28 | * @param num Selects the number of the combo | ||
29 | * @param defIndex will be returned if none was defined (either | ||
30 | * globally in the config file, nor by the contact which was used | ||
31 | * by loadFromRecord() ) | ||
32 | */ | ||
33 | int getFieldOrder( int num, int defIndex); | ||
34 | |||
35 | /** Store fieldorder to contact. */ | ||
36 | void saveToRecord( OContact& ); | ||
37 | /** Get Fieldorder from contact. */ | ||
38 | void loadFromRecord( const OContact& ); | ||
39 | |||
40 | private: | ||
41 | QString fieldOrder; | ||
42 | QString globalFieldOrder; | ||
43 | bool changedFieldOrder; | ||
44 | |||
45 | public: | ||
46 | static QStringList trphonefields( bool sorted = true ); | ||
47 | static QStringList untrphonefields( bool sorted = true ); | ||
48 | static QStringList trdetailsfields( bool sorted = true ); | ||
49 | static QStringList untrdetailsfields( bool sorted = true ); | ||
50 | static QStringList trfields( bool sorted = true ); | ||
51 | static QStringList untrfields( bool sorted = true ); | ||
52 | |||
53 | static QMap<int, QString> idToTrFields(); | ||
54 | static QMap<QString, int> trFieldsToId(); | ||
55 | static QMap<int, QString> idToUntrFields(); | ||
56 | static QMap<QString, int> untrFieldsToId(); | ||
57 | |||
58 | }; | ||
59 | |||
60 | #endif | ||
diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp index ec9c14c..23e0c3e 100644 --- a/libopie/pim/otodoaccesssql.cpp +++ b/libopie/pim/otodoaccesssql.cpp | |||
@@ -1,540 +1,593 @@ | |||
1 | 1 | ||
2 | #include <qdatetime.h> | 2 | #include <qdatetime.h> |
3 | 3 | ||
4 | #include <qpe/global.h> | 4 | #include <qpe/global.h> |
5 | 5 | ||
6 | #include <opie/osqldriver.h> | 6 | #include <opie2/osqldriver.h> |
7 | #include <opie/osqlresult.h> | 7 | #include <opie2/osqlresult.h> |
8 | #include <opie/osqlmanager.h> | 8 | #include <opie2/osqlmanager.h> |
9 | #include <opie/osqlquery.h> | 9 | #include <opie2/osqlquery.h> |
10 | 10 | ||
11 | #include "otodoaccesssql.h" | 11 | #include "otodoaccesssql.h" |
12 | 12 | ||
13 | /* | 13 | /* |
14 | * first some query | 14 | * first some query |
15 | * CREATE query | 15 | * CREATE query |
16 | * LOAD query | 16 | * LOAD query |
17 | * INSERT | 17 | * INSERT |
18 | * REMOVE | 18 | * REMOVE |
19 | * CLEAR | 19 | * CLEAR |
20 | */ | 20 | */ |
21 | namespace { | 21 | namespace { |
22 | /** | 22 | /** |
23 | * CreateQuery for the Todolist Table | 23 | * CreateQuery for the Todolist Table |
24 | */ | 24 | */ |
25 | class CreateQuery : public OSQLQuery { | 25 | class CreateQuery : public OSQLQuery { |
26 | public: | 26 | public: |
27 | CreateQuery(); | 27 | CreateQuery(); |
28 | ~CreateQuery(); | 28 | ~CreateQuery(); |
29 | QString query()const; | 29 | QString query()const; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * LoadQuery | 33 | * LoadQuery |
34 | * this one queries for all uids | 34 | * this one queries for all uids |
35 | */ | 35 | */ |
36 | class LoadQuery : public OSQLQuery { | 36 | class LoadQuery : public OSQLQuery { |
37 | public: | 37 | public: |
38 | LoadQuery(); | 38 | LoadQuery(); |
39 | ~LoadQuery(); | 39 | ~LoadQuery(); |
40 | QString query()const; | 40 | QString query()const; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | /** | 43 | /** |
44 | * inserts/adds a OTodo to the table | 44 | * inserts/adds a OTodo to the table |
45 | */ | 45 | */ |
46 | class InsertQuery : public OSQLQuery { | 46 | class InsertQuery : public OSQLQuery { |
47 | public: | 47 | public: |
48 | InsertQuery(const OTodo& ); | 48 | InsertQuery(const OTodo& ); |
49 | ~InsertQuery(); | 49 | ~InsertQuery(); |
50 | QString query()const; | 50 | QString query()const; |
51 | private: | 51 | private: |
52 | OTodo m_todo; | 52 | OTodo m_todo; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * removes one from the table | 56 | * removes one from the table |
57 | */ | 57 | */ |
58 | class RemoveQuery : public OSQLQuery { | 58 | class RemoveQuery : public OSQLQuery { |
59 | public: | 59 | public: |
60 | RemoveQuery(int uid ); | 60 | RemoveQuery(int uid ); |
61 | ~RemoveQuery(); | 61 | ~RemoveQuery(); |
62 | QString query()const; | 62 | QString query()const; |
63 | private: | 63 | private: |
64 | int m_uid; | 64 | int m_uid; |
65 | }; | 65 | }; |
66 | 66 | ||
67 | /** | 67 | /** |
68 | * Clears (delete) a Table | 68 | * Clears (delete) a Table |
69 | */ | 69 | */ |
70 | class ClearQuery : public OSQLQuery { | 70 | class ClearQuery : public OSQLQuery { |
71 | public: | 71 | public: |
72 | ClearQuery(); | 72 | ClearQuery(); |
73 | ~ClearQuery(); | 73 | ~ClearQuery(); |
74 | QString query()const; | 74 | QString query()const; |
75 | 75 | ||
76 | }; | 76 | }; |
77 | 77 | ||
78 | /** | 78 | /** |
79 | * a find query | 79 | * a find query |
80 | */ | 80 | */ |
81 | class FindQuery : public OSQLQuery { | 81 | class FindQuery : public OSQLQuery { |
82 | public: | 82 | public: |
83 | FindQuery(int uid); | 83 | FindQuery(int uid); |
84 | FindQuery(const QArray<int>& ); | 84 | FindQuery(const QArray<int>& ); |
85 | ~FindQuery(); | 85 | ~FindQuery(); |
86 | QString query()const; | 86 | QString query()const; |
87 | private: | 87 | private: |
88 | QString single()const; | 88 | QString single()const; |
89 | QString multi()const; | 89 | QString multi()const; |
90 | QArray<int> m_uids; | 90 | QArray<int> m_uids; |
91 | int m_uid; | 91 | int m_uid; |
92 | }; | 92 | }; |
93 | 93 | ||
94 | /** | 94 | /** |
95 | * overdue query | 95 | * overdue query |
96 | */ | 96 | */ |
97 | class OverDueQuery : public OSQLQuery { | 97 | class OverDueQuery : public OSQLQuery { |
98 | public: | 98 | public: |
99 | OverDueQuery(); | 99 | OverDueQuery(); |
100 | ~OverDueQuery(); | 100 | ~OverDueQuery(); |
101 | QString query()const; | 101 | QString query()const; |
102 | }; | 102 | }; |
103 | class EffQuery : public OSQLQuery { | 103 | class EffQuery : public OSQLQuery { |
104 | public: | 104 | public: |
105 | EffQuery( const QDate&, const QDate&, bool inc ); | 105 | EffQuery( const QDate&, const QDate&, bool inc ); |
106 | ~EffQuery(); | 106 | ~EffQuery(); |
107 | QString query()const; | 107 | QString query()const; |
108 | private: | 108 | private: |
109 | QString with()const; | 109 | QString with()const; |
110 | QString out()const; | 110 | QString out()const; |
111 | QDate m_start; | 111 | QDate m_start; |
112 | QDate m_end; | 112 | QDate m_end; |
113 | bool m_inc :1; | 113 | bool m_inc :1; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | 116 | ||
117 | CreateQuery::CreateQuery() : OSQLQuery() {} | 117 | CreateQuery::CreateQuery() : OSQLQuery() {} |
118 | CreateQuery::~CreateQuery() {} | 118 | CreateQuery::~CreateQuery() {} |
119 | QString CreateQuery::query()const { | 119 | QString CreateQuery::query()const { |
120 | QString qu; | 120 | QString qu; |
121 | qu += "create table todolist( uid, categories, completed, progress, "; | 121 | qu += "create table todolist( uid, categories, completed, progress, "; |
122 | qu += "summary, DueDate, priority, description )"; | 122 | qu += "summary, DueDate, priority, description )"; |
123 | return qu; | 123 | return qu; |
124 | } | 124 | } |
125 | 125 | ||
126 | LoadQuery::LoadQuery() : OSQLQuery() {} | 126 | LoadQuery::LoadQuery() : OSQLQuery() {} |
127 | LoadQuery::~LoadQuery() {} | 127 | LoadQuery::~LoadQuery() {} |
128 | QString LoadQuery::query()const { | 128 | QString LoadQuery::query()const { |
129 | QString qu; | 129 | QString qu; |
130 | qu += "select distinct uid from todolist"; | 130 | qu += "select distinct uid from todolist"; |
131 | 131 | ||
132 | return qu; | 132 | return qu; |
133 | } | 133 | } |
134 | 134 | ||
135 | InsertQuery::InsertQuery( const OTodo& todo ) | 135 | InsertQuery::InsertQuery( const OTodo& todo ) |
136 | : OSQLQuery(), m_todo( todo ) { | 136 | : OSQLQuery(), m_todo( todo ) { |
137 | } | 137 | } |
138 | InsertQuery::~InsertQuery() { | 138 | InsertQuery::~InsertQuery() { |
139 | } | 139 | } |
140 | /* | 140 | /* |
141 | * converts from a OTodo to a query | 141 | * converts from a OTodo to a query |
142 | * we leave out X-Ref + Alarms | 142 | * we leave out X-Ref + Alarms |
143 | */ | 143 | */ |
144 | QString InsertQuery::query()const{ | 144 | QString InsertQuery::query()const{ |
145 | 145 | ||
146 | int year, month, day; | 146 | int year, month, day; |
147 | year = month = day = 0; | 147 | year = month = day = 0; |
148 | if (m_todo.hasDueDate() ) { | 148 | if (m_todo.hasDueDate() ) { |
149 | QDate date = m_todo.dueDate(); | 149 | QDate date = m_todo.dueDate(); |
150 | year = date.year(); | 150 | year = date.year(); |
151 | month = date.month(); | 151 | month = date.month(); |
152 | day = date.day(); | 152 | day = date.day(); |
153 | } | 153 | } |
154 | QString qu; | 154 | QString qu; |
155 | qu = "insert into todolist VALUES(" + QString::number( m_todo.uid() ) + ",'" + m_todo.idsToString( m_todo.categories() ) + "',"; | 155 | qu = "insert into todolist VALUES(" + QString::number( m_todo.uid() ) + ",'" + m_todo.idsToString( m_todo.categories() ) + "',"; |
156 | qu += QString::number( m_todo.isCompleted() ) + "," + QString::number( m_todo.progress() ) + ","; | 156 | qu += QString::number( m_todo.isCompleted() ) + "," + QString::number( m_todo.progress() ) + ","; |
157 | qu += "'"+m_todo.summary()+"','"+QString::number(year)+"-"+QString::number(month)+"-"+QString::number(day)+"',"; | 157 | qu += "'"+m_todo.summary()+"','"+QString::number(year)+"-"+QString::number(month)+"-"+QString::number(day)+"',"; |
158 | qu += QString::number(m_todo.priority() ) +",'" + m_todo.description() + "')"; | 158 | qu += QString::number(m_todo.priority() ) +",'" + m_todo.description() + "')"; |
159 | 159 | ||
160 | qWarning("add %s", qu.latin1() ); | 160 | qWarning("add %s", qu.latin1() ); |
161 | return qu; | 161 | return qu; |
162 | } | 162 | } |
163 | 163 | ||
164 | RemoveQuery::RemoveQuery(int uid ) | 164 | RemoveQuery::RemoveQuery(int uid ) |
165 | : OSQLQuery(), m_uid( uid ) {} | 165 | : OSQLQuery(), m_uid( uid ) {} |
166 | RemoveQuery::~RemoveQuery() {} | 166 | RemoveQuery::~RemoveQuery() {} |
167 | QString RemoveQuery::query()const { | 167 | QString RemoveQuery::query()const { |
168 | QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); | 168 | QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); |
169 | return qu; | 169 | return qu; |
170 | } | 170 | } |
171 | 171 | ||
172 | 172 | ||
173 | ClearQuery::ClearQuery() | 173 | ClearQuery::ClearQuery() |
174 | : OSQLQuery() {} | 174 | : OSQLQuery() {} |
175 | ClearQuery::~ClearQuery() {} | 175 | ClearQuery::~ClearQuery() {} |
176 | QString ClearQuery::query()const { | 176 | QString ClearQuery::query()const { |
177 | QString qu = "drop table todolist"; | 177 | QString qu = "drop table todolist"; |
178 | return qu; | 178 | return qu; |
179 | } | 179 | } |
180 | FindQuery::FindQuery(int uid) | 180 | FindQuery::FindQuery(int uid) |
181 | : OSQLQuery(), m_uid(uid ) { | 181 | : OSQLQuery(), m_uid(uid ) { |
182 | } | 182 | } |
183 | FindQuery::FindQuery(const QArray<int>& ints) | 183 | FindQuery::FindQuery(const QArray<int>& ints) |
184 | : OSQLQuery(), m_uids(ints){ | 184 | : OSQLQuery(), m_uids(ints){ |
185 | } | 185 | } |
186 | FindQuery::~FindQuery() { | 186 | FindQuery::~FindQuery() { |
187 | } | 187 | } |
188 | QString FindQuery::query()const{ | 188 | QString FindQuery::query()const{ |
189 | if (m_uids.count() == 0 ) | 189 | if (m_uids.count() == 0 ) |
190 | return single(); | 190 | return single(); |
191 | else | 191 | else |
192 | return multi(); | 192 | return multi(); |
193 | } | 193 | } |
194 | QString FindQuery::single()const{ | 194 | QString FindQuery::single()const{ |
195 | QString qu = "select uid, categories, completed, progress, summary, "; | 195 | QString qu = "select uid, categories, completed, progress, summary, "; |
196 | qu += "DueDate, priority, description from todolist where uid = " + QString::number(m_uid); | 196 | qu += "DueDate, priority, description from todolist where uid = " + QString::number(m_uid); |
197 | return qu; | 197 | return qu; |
198 | } | 198 | } |
199 | QString FindQuery::multi()const { | 199 | QString FindQuery::multi()const { |
200 | QString qu = "select uid, categories, completed, progress, summary, "; | 200 | QString qu = "select uid, categories, completed, progress, summary, "; |
201 | qu += "DueDate, priority, description from todolist where "; | 201 | qu += "DueDate, priority, description from todolist where "; |
202 | for (uint i = 0; i < m_uids.count(); i++ ) { | 202 | for (uint i = 0; i < m_uids.count(); i++ ) { |
203 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | 203 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; |
204 | } | 204 | } |
205 | qu.remove( qu.length()-2, 2 ); | 205 | qu.remove( qu.length()-2, 2 ); |
206 | return qu; | 206 | return qu; |
207 | } | 207 | } |
208 | 208 | ||
209 | OverDueQuery::OverDueQuery(): OSQLQuery() {} | 209 | OverDueQuery::OverDueQuery(): OSQLQuery() {} |
210 | OverDueQuery::~OverDueQuery() {} | 210 | OverDueQuery::~OverDueQuery() {} |
211 | QString OverDueQuery::query()const { | 211 | QString OverDueQuery::query()const { |
212 | QDate date = QDate::currentDate(); | 212 | QDate date = QDate::currentDate(); |
213 | QString str; | 213 | QString str; |
214 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); | 214 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); |
215 | 215 | ||
216 | return str; | 216 | return str; |
217 | } | 217 | } |
218 | 218 | ||
219 | 219 | ||
220 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) | 220 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) |
221 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} | 221 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} |
222 | EffQuery::~EffQuery() {} | 222 | EffQuery::~EffQuery() {} |
223 | QString EffQuery::query()const { | 223 | QString EffQuery::query()const { |
224 | return m_inc ? with() : out(); | 224 | return m_inc ? with() : out(); |
225 | } | 225 | } |
226 | QString EffQuery::with()const { | 226 | QString EffQuery::with()const { |
227 | QString str; | 227 | QString str; |
228 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") | 228 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") |
229 | .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) | 229 | .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) |
230 | .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); | 230 | .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); |
231 | return str; | 231 | return str; |
232 | } | 232 | } |
233 | QString EffQuery::out()const { | 233 | QString EffQuery::out()const { |
234 | QString str; | 234 | QString str; |
235 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") | 235 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") |
236 | .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) | 236 | .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) |
237 | .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); | 237 | .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); |
238 | 238 | ||
239 | return str; | 239 | return str; |
240 | } | 240 | } |
241 | }; | 241 | }; |
242 | 242 | ||
243 | OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) | 243 | OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) |
244 | : OTodoAccessBackend(), m_dict(15), m_dirty(true) | 244 | : OTodoAccessBackend(), m_dict(15), m_dirty(true) |
245 | { | 245 | { |
246 | QString fi = file; | 246 | QString fi = file; |
247 | if ( fi.isEmpty() ) | 247 | if ( fi.isEmpty() ) |
248 | fi = Global::applicationFileName( "todolist", "todolist.db" ); | 248 | fi = Global::applicationFileName( "todolist", "todolist.db" ); |
249 | OSQLManager man; | 249 | OSQLManager man; |
250 | m_driver = man.standard(); | 250 | m_driver = man.standard(); |
251 | m_driver->setUrl(fi); | 251 | m_driver->setUrl(fi); |
252 | fillDict(); | 252 | // fillDict(); |
253 | } | 253 | } |
254 | 254 | ||
255 | OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ | 255 | OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ |
256 | } | 256 | } |
257 | bool OTodoAccessBackendSQL::load(){ | 257 | bool OTodoAccessBackendSQL::load(){ |
258 | if (!m_driver->open() ) | 258 | if (!m_driver->open() ) |
259 | return false; | 259 | return false; |
260 | 260 | ||
261 | CreateQuery creat; | 261 | CreateQuery creat; |
262 | OSQLResult res = m_driver->query(&creat ); | 262 | OSQLResult res = m_driver->query(&creat ); |
263 | 263 | ||
264 | m_dirty = true; | 264 | m_dirty = true; |
265 | return true; | 265 | return true; |
266 | } | 266 | } |
267 | bool OTodoAccessBackendSQL::reload(){ | 267 | bool OTodoAccessBackendSQL::reload(){ |
268 | return load(); | 268 | return load(); |
269 | } | 269 | } |
270 | 270 | ||
271 | bool OTodoAccessBackendSQL::save(){ | 271 | bool OTodoAccessBackendSQL::save(){ |
272 | return m_driver->close(); | 272 | return m_driver->close(); |
273 | } | 273 | } |
274 | QArray<int> OTodoAccessBackendSQL::allRecords()const { | 274 | QArray<int> OTodoAccessBackendSQL::allRecords()const { |
275 | if (m_dirty ) | 275 | if (m_dirty ) |
276 | update(); | 276 | update(); |
277 | 277 | ||
278 | return m_uids; | 278 | return m_uids; |
279 | } | 279 | } |
280 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ | 280 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ |
281 | QArray<int> ints(0); | 281 | QArray<int> ints(0); |
282 | return ints; | 282 | return ints; |
283 | } | 283 | } |
284 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ | 284 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ |
285 | FindQuery query( uid ); | 285 | FindQuery query( uid ); |
286 | return todo( m_driver->query(&query) ); | 286 | return todo( m_driver->query(&query) ); |
287 | 287 | ||
288 | } | 288 | } |
289 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, | 289 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, |
290 | uint cur, Frontend::CacheDirection dir ) const{ | 290 | uint cur, Frontend::CacheDirection dir ) const{ |
291 | int CACHE = readAhead(); | 291 | int CACHE = readAhead(); |
292 | qWarning("searching for %d", uid ); | 292 | qWarning("searching for %d", uid ); |
293 | QArray<int> search( CACHE ); | 293 | QArray<int> search( CACHE ); |
294 | uint size =0; | 294 | uint size =0; |
295 | OTodo to; | 295 | OTodo to; |
296 | 296 | ||
297 | // we try to cache CACHE items | 297 | // we try to cache CACHE items |
298 | switch( dir ) { | 298 | switch( dir ) { |
299 | /* forward */ | 299 | /* forward */ |
300 | case 0: | 300 | case 0: // FIXME: Not a good style to use magic numbers here (eilers) |
301 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { | 301 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { |
302 | qWarning("size %d %d", size, ints[i] ); | 302 | qWarning("size %d %d", size, ints[i] ); |
303 | search[size] = ints[i]; | 303 | search[size] = ints[i]; |
304 | size++; | 304 | size++; |
305 | } | 305 | } |
306 | break; | 306 | break; |
307 | /* reverse */ | 307 | /* reverse */ |
308 | case 1: | 308 | case 1: // FIXME: Not a good style to use magic numbers here (eilers) |
309 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { | 309 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { |
310 | search[size] = ints[i]; | 310 | search[size] = ints[i]; |
311 | size++; | 311 | size++; |
312 | } | 312 | } |
313 | break; | 313 | break; |
314 | } | 314 | } |
315 | search.resize( size ); | 315 | search.resize( size ); |
316 | FindQuery query( search ); | 316 | FindQuery query( search ); |
317 | OSQLResult res = m_driver->query( &query ); | 317 | OSQLResult res = m_driver->query( &query ); |
318 | if ( res.state() != OSQLResult::Success ) | 318 | if ( res.state() != OSQLResult::Success ) |
319 | return to; | 319 | return to; |
320 | 320 | ||
321 | return todo( res ); | 321 | return todo( res ); |
322 | } | 322 | } |
323 | void OTodoAccessBackendSQL::clear() { | 323 | void OTodoAccessBackendSQL::clear() { |
324 | ClearQuery cle; | 324 | ClearQuery cle; |
325 | OSQLResult res = m_driver->query( &cle ); | 325 | OSQLResult res = m_driver->query( &cle ); |
326 | CreateQuery qu; | 326 | CreateQuery qu; |
327 | res = m_driver->query(&qu); | 327 | res = m_driver->query(&qu); |
328 | } | 328 | } |
329 | bool OTodoAccessBackendSQL::add( const OTodo& t) { | 329 | bool OTodoAccessBackendSQL::add( const OTodo& t) { |
330 | InsertQuery ins( t ); | 330 | InsertQuery ins( t ); |
331 | OSQLResult res = m_driver->query( &ins ); | 331 | OSQLResult res = m_driver->query( &ins ); |
332 | 332 | ||
333 | if ( res.state() == OSQLResult::Failure ) | 333 | if ( res.state() == OSQLResult::Failure ) |
334 | return false; | 334 | return false; |
335 | int c = m_uids.count(); | 335 | int c = m_uids.count(); |
336 | m_uids.resize( c+1 ); | 336 | m_uids.resize( c+1 ); |
337 | m_uids[c] = t.uid(); | 337 | m_uids[c] = t.uid(); |
338 | 338 | ||
339 | return true; | 339 | return true; |
340 | } | 340 | } |
341 | bool OTodoAccessBackendSQL::remove( int uid ) { | 341 | bool OTodoAccessBackendSQL::remove( int uid ) { |
342 | RemoveQuery rem( uid ); | 342 | RemoveQuery rem( uid ); |
343 | OSQLResult res = m_driver->query(&rem ); | 343 | OSQLResult res = m_driver->query(&rem ); |
344 | 344 | ||
345 | if ( res.state() == OSQLResult::Failure ) | 345 | if ( res.state() == OSQLResult::Failure ) |
346 | return false; | 346 | return false; |
347 | 347 | ||
348 | m_dirty = true; | 348 | m_dirty = true; |
349 | return true; | 349 | return true; |
350 | } | 350 | } |
351 | /* | 351 | /* |
352 | * FIXME better set query | 352 | * FIXME better set query |
353 | * but we need the cache for that | 353 | * but we need the cache for that |
354 | * now we remove | 354 | * now we remove |
355 | */ | 355 | */ |
356 | bool OTodoAccessBackendSQL::replace( const OTodo& t) { | 356 | bool OTodoAccessBackendSQL::replace( const OTodo& t) { |
357 | remove( t.uid() ); | 357 | remove( t.uid() ); |
358 | bool b= add(t); | 358 | bool b= add(t); |
359 | m_dirty = false; // we changed some stuff but the UID stayed the same | 359 | m_dirty = false; // we changed some stuff but the UID stayed the same |
360 | return b; | 360 | return b; |
361 | } | 361 | } |
362 | QArray<int> OTodoAccessBackendSQL::overDue() { | 362 | QArray<int> OTodoAccessBackendSQL::overDue() { |
363 | OverDueQuery qu; | 363 | OverDueQuery qu; |
364 | return uids( m_driver->query(&qu ) ); | 364 | return uids( m_driver->query(&qu ) ); |
365 | } | 365 | } |
366 | QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, | 366 | QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, |
367 | const QDate& t, | 367 | const QDate& t, |
368 | bool u) { | 368 | bool u) { |
369 | EffQuery ef(s, t, u ); | 369 | EffQuery ef(s, t, u ); |
370 | return uids (m_driver->query(&ef) ); | 370 | return uids (m_driver->query(&ef) ); |
371 | } | 371 | } |
372 | /* | 372 | /* |
373 | * | 373 | * |
374 | */ | 374 | */ |
375 | QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, | 375 | QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, |
376 | int sortFilter, int cat ) { | 376 | int sortFilter, int cat ) { |
377 | qWarning("sorted %d, %d", asc, sortOrder ); | 377 | qWarning("sorted %d, %d", asc, sortOrder ); |
378 | QString query; | 378 | QString query; |
379 | query = "select uid from todolist WHERE "; | 379 | query = "select uid from todolist WHERE "; |
380 | 380 | ||
381 | /* | 381 | /* |
382 | * Sort Filter stuff | 382 | * Sort Filter stuff |
383 | * not that straight forward | 383 | * not that straight forward |
384 | * FIXME: Replace magic numbers | ||
384 | * | 385 | * |
385 | */ | 386 | */ |
386 | /* Category */ | 387 | /* Category */ |
387 | if ( sortFilter & 1 ) { | 388 | if ( sortFilter & 1 ) { |
388 | QString str; | 389 | QString str; |
389 | if (cat != 0 ) str = QString::number( cat ); | 390 | if (cat != 0 ) str = QString::number( cat ); |
390 | query += " categories like '%" +str+"%' AND"; | 391 | query += " categories like '%" +str+"%' AND"; |
391 | } | 392 | } |
392 | /* Show only overdue */ | 393 | /* Show only overdue */ |
393 | if ( sortFilter & 2 ) { | 394 | if ( sortFilter & 2 ) { |
394 | QDate date = QDate::currentDate(); | 395 | QDate date = QDate::currentDate(); |
395 | QString due; | 396 | QString due; |
396 | QString base; | 397 | QString base; |
397 | base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); | 398 | base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); |
398 | query += " " + base + " AND"; | 399 | query += " " + base + " AND"; |
399 | } | 400 | } |
400 | /* not show completed */ | 401 | /* not show completed */ |
401 | if ( sortFilter & 4 ) { | 402 | if ( sortFilter & 4 ) { |
402 | query += " completed = 0 AND"; | 403 | query += " completed = 0 AND"; |
403 | }else{ | 404 | }else{ |
404 | query += " ( completed = 1 OR completed = 0) AND"; | 405 | query += " ( completed = 1 OR completed = 0) AND"; |
405 | } | 406 | } |
406 | /* srtip the end */ | 407 | /* srtip the end */ |
407 | query = query.remove( query.length()-3, 3 ); | 408 | query = query.remove( query.length()-3, 3 ); |
408 | 409 | ||
409 | 410 | ||
410 | /* | 411 | /* |
411 | * sort order stuff | 412 | * sort order stuff |
412 | * quite straight forward | 413 | * quite straight forward |
413 | */ | 414 | */ |
414 | query += "ORDER BY "; | 415 | query += "ORDER BY "; |
415 | switch( sortOrder ) { | 416 | switch( sortOrder ) { |
416 | /* completed */ | 417 | /* completed */ |
417 | case 0: | 418 | case 0: |
418 | query += "completed"; | 419 | query += "completed"; |
419 | break; | 420 | break; |
420 | case 1: | 421 | case 1: |
421 | query += "priority"; | 422 | query += "priority"; |
422 | break; | 423 | break; |
423 | case 2: | 424 | case 2: |
424 | query += "summary"; | 425 | query += "summary"; |
425 | break; | 426 | break; |
426 | case 3: | 427 | case 3: |
427 | query += "DueDate"; | 428 | query += "DueDate"; |
428 | break; | 429 | break; |
429 | } | 430 | } |
430 | 431 | ||
431 | if ( !asc ) { | 432 | if ( !asc ) { |
432 | qWarning("not ascending!"); | 433 | qWarning("not ascending!"); |
433 | query += " DESC"; | 434 | query += " DESC"; |
434 | } | 435 | } |
435 | 436 | ||
436 | qWarning( query ); | 437 | qWarning( query ); |
437 | OSQLRawQuery raw(query ); | 438 | OSQLRawQuery raw(query ); |
438 | return uids( m_driver->query(&raw) ); | 439 | return uids( m_driver->query(&raw) ); |
439 | } | 440 | } |
440 | bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ | 441 | bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ |
441 | if ( str == "0-0-0" ) | 442 | if ( str == "0-0-0" ) |
442 | return false; | 443 | return false; |
443 | else{ | 444 | else{ |
444 | int day, year, month; | 445 | int day, year, month; |
445 | QStringList list = QStringList::split("-", str ); | 446 | QStringList list = QStringList::split("-", str ); |
446 | year = list[0].toInt(); | 447 | year = list[0].toInt(); |
447 | month = list[1].toInt(); | 448 | month = list[1].toInt(); |
448 | day = list[2].toInt(); | 449 | day = list[2].toInt(); |
449 | da.setYMD( year, month, day ); | 450 | da.setYMD( year, month, day ); |
450 | return true; | 451 | return true; |
451 | } | 452 | } |
452 | } | 453 | } |
453 | OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ | 454 | OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ |
454 | if ( res.state() == OSQLResult::Failure ) { | 455 | if ( res.state() == OSQLResult::Failure ) { |
455 | OTodo to; | 456 | OTodo to; |
456 | return to; | 457 | return to; |
457 | } | 458 | } |
458 | 459 | ||
459 | OSQLResultItem::ValueList list = res.results(); | 460 | OSQLResultItem::ValueList list = res.results(); |
460 | OSQLResultItem::ValueList::Iterator it = list.begin(); | 461 | OSQLResultItem::ValueList::Iterator it = list.begin(); |
461 | qWarning("todo1"); | 462 | qWarning("todo1"); |
462 | OTodo to = todo( (*it) ); | 463 | OTodo to = todo( (*it) ); |
463 | cache( to ); | 464 | cache( to ); |
464 | ++it; | 465 | ++it; |
465 | 466 | ||
466 | for ( ; it != list.end(); ++it ) { | 467 | for ( ; it != list.end(); ++it ) { |
467 | qWarning("caching"); | 468 | qWarning("caching"); |
468 | cache( todo( (*it) ) ); | 469 | cache( todo( (*it) ) ); |
469 | } | 470 | } |
470 | return to; | 471 | return to; |
471 | } | 472 | } |
472 | OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const { | 473 | OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const { |
473 | qWarning("todo"); | 474 | qWarning("todo"); |
474 | bool has = false; QDate da = QDate::currentDate(); | 475 | bool has = false; QDate da = QDate::currentDate(); |
475 | has = date( da, item.data("DueDate") ); | 476 | has = date( da, item.data("DueDate") ); |
476 | QStringList cats = QStringList::split(";", item.data("categories") ); | 477 | QStringList cats = QStringList::split(";", item.data("categories") ); |
477 | 478 | ||
478 | OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), | 479 | OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), |
479 | cats, item.data("summary"), item.data("description"), | 480 | cats, item.data("summary"), item.data("description"), |
480 | item.data("progress").toUShort(), has, da, | 481 | item.data("progress").toUShort(), has, da, |
481 | item.data("uid").toInt() ); | 482 | item.data("uid").toInt() ); |
482 | return to; | 483 | return to; |
483 | } | 484 | } |
484 | OTodo OTodoAccessBackendSQL::todo( int uid )const { | 485 | OTodo OTodoAccessBackendSQL::todo( int uid )const { |
485 | FindQuery find( uid ); | 486 | FindQuery find( uid ); |
486 | return todo( m_driver->query(&find) ); | 487 | return todo( m_driver->query(&find) ); |
487 | } | 488 | } |
488 | /* | 489 | /* |
489 | * update the dict | 490 | * update the dict |
490 | */ | 491 | */ |
491 | void OTodoAccessBackendSQL::fillDict() { | 492 | void OTodoAccessBackendSQL::fillDict() { |
492 | /* initialize dict */ | 493 | /* initialize dict */ |
493 | /* | 494 | /* |
494 | * UPDATE dict if you change anything!!! | 495 | * UPDATE dict if you change anything!!! |
496 | * FIXME: Isn't this dict obsolete ? (eilers) | ||
495 | */ | 497 | */ |
496 | m_dict.setAutoDelete( TRUE ); | 498 | m_dict.setAutoDelete( TRUE ); |
497 | m_dict.insert("Categories" , new int(OTodo::Category) ); | 499 | m_dict.insert("Categories" , new int(OTodo::Category) ); |
498 | m_dict.insert("Uid" , new int(OTodo::Uid) ); | 500 | m_dict.insert("Uid" , new int(OTodo::Uid) ); |
499 | m_dict.insert("HasDate" , new int(OTodo::HasDate) ); | 501 | m_dict.insert("HasDate" , new int(OTodo::HasDate) ); |
500 | m_dict.insert("Completed" , new int(OTodo::Completed) ); | 502 | m_dict.insert("Completed" , new int(OTodo::Completed) ); |
501 | m_dict.insert("Description" , new int(OTodo::Description) ); | 503 | m_dict.insert("Description" , new int(OTodo::Description) ); |
502 | m_dict.insert("Summary" , new int(OTodo::Summary) ); | 504 | m_dict.insert("Summary" , new int(OTodo::Summary) ); |
503 | m_dict.insert("Priority" , new int(OTodo::Priority) ); | 505 | m_dict.insert("Priority" , new int(OTodo::Priority) ); |
504 | m_dict.insert("DateDay" , new int(OTodo::DateDay) ); | 506 | m_dict.insert("DateDay" , new int(OTodo::DateDay) ); |
505 | m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); | 507 | m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); |
506 | m_dict.insert("DateYear" , new int(OTodo::DateYear) ); | 508 | m_dict.insert("DateYear" , new int(OTodo::DateYear) ); |
507 | m_dict.insert("Progress" , new int(OTodo::Progress) ); | 509 | m_dict.insert("Progress" , new int(OTodo::Progress) ); |
508 | m_dict.insert("Completed", new int(OTodo::Completed) ); | 510 | m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers) |
509 | m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); | 511 | m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); |
510 | m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); | 512 | // m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers) |
511 | m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); | 513 | // m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers) |
512 | } | 514 | } |
513 | /* | 515 | /* |
514 | * need to be const so let's fool the | 516 | * need to be const so let's fool the |
515 | * compiler :( | 517 | * compiler :( |
516 | */ | 518 | */ |
517 | void OTodoAccessBackendSQL::update()const { | 519 | void OTodoAccessBackendSQL::update()const { |
518 | ((OTodoAccessBackendSQL*)this)->m_dirty = false; | 520 | ((OTodoAccessBackendSQL*)this)->m_dirty = false; |
519 | LoadQuery lo; | 521 | LoadQuery lo; |
520 | OSQLResult res = m_driver->query(&lo); | 522 | OSQLResult res = m_driver->query(&lo); |
521 | if ( res.state() != OSQLResult::Success ) | 523 | if ( res.state() != OSQLResult::Success ) |
522 | return; | 524 | return; |
523 | 525 | ||
524 | ((OTodoAccessBackendSQL*)this)->m_uids = uids( res ); | 526 | ((OTodoAccessBackendSQL*)this)->m_uids = uids( res ); |
525 | } | 527 | } |
526 | QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{ | 528 | QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{ |
527 | 529 | ||
528 | OSQLResultItem::ValueList list = res.results(); | 530 | OSQLResultItem::ValueList list = res.results(); |
529 | OSQLResultItem::ValueList::Iterator it; | 531 | OSQLResultItem::ValueList::Iterator it; |
530 | QArray<int> ints(list.count() ); | 532 | QArray<int> ints(list.count() ); |
531 | qWarning(" count = %d", list.count() ); | 533 | qWarning(" count = %d", list.count() ); |
532 | 534 | ||
533 | int i = 0; | 535 | int i = 0; |
534 | for (it = list.begin(); it != list.end(); ++it ) { | 536 | for (it = list.begin(); it != list.end(); ++it ) { |
535 | ints[i] = (*it).data("uid").toInt(); | 537 | ints[i] = (*it).data("uid").toInt(); |
536 | i++; | 538 | i++; |
537 | } | 539 | } |
538 | return ints; | 540 | return ints; |
539 | } | 541 | } |
540 | 542 | ||
543 | QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const | ||
544 | { | ||
545 | |||
546 | #warning OTodoAccessBackendSQL::matchRegexp() not implemented !! | ||
547 | |||
548 | #if 0 | ||
549 | |||
550 | Copied from xml-backend by not adapted to sql (eilers) | ||
551 | |||
552 | QArray<int> m_currentQuery( m_events.count() ); | ||
553 | uint arraycounter = 0; | ||
554 | |||
555 | |||
556 | |||
557 | QMap<int, OTodo>::ConstIterator it; | ||
558 | for (it = m_events.begin(); it != m_events.end(); ++it ) { | ||
559 | if ( it.data().match( r ) ) | ||
560 | m_currentQuery[arraycounter++] = it.data().uid(); | ||
561 | |||
562 | } | ||
563 | // Shrink to fit.. | ||
564 | m_currentQuery.resize(arraycounter); | ||
565 | |||
566 | return m_currentQuery; | ||
567 | #endif | ||
568 | QArray<int> empty; | ||
569 | return empty; | ||
570 | } | ||
571 | QBitArray OTodoAccessBackendSQL::supports()const { | ||
572 | |||
573 | static QBitArray ar = sup(); | ||
574 | return ar; | ||
575 | } | ||
576 | |||
577 | QBitArray OTodoAccessBackendSQL::sup() { | ||
578 | |||
579 | QBitArray ar( OTodo::CompletedDate + 1 ); | ||
580 | ar.fill( true ); | ||
581 | ar[OTodo::CrossReference] = false; | ||
582 | ar[OTodo::State ] = false; | ||
583 | ar[OTodo::Reminders] = false; | ||
584 | ar[OTodo::Notifiers] = false; | ||
585 | ar[OTodo::Maintainer] = false; | ||
586 | |||
587 | return ar; | ||
588 | } | ||
589 | |||
590 | void OTodoAccessBackendSQL::removeAllCompleted(){ | ||
591 | #warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !! | ||
592 | |||
593 | } | ||
diff --git a/libopie/pim/otodoaccesssql.h b/libopie/pim/otodoaccesssql.h index 6a4257c..77d8b77 100644 --- a/libopie/pim/otodoaccesssql.h +++ b/libopie/pim/otodoaccesssql.h | |||
@@ -1,50 +1,56 @@ | |||
1 | #ifndef OPIE_PIM_ACCESS_SQL_H | 1 | #ifndef OPIE_PIM_ACCESS_SQL_H |
2 | #define OPIE_PIM_ACCESS_SQL_H | 2 | #define OPIE_PIM_ACCESS_SQL_H |
3 | 3 | ||
4 | #include <qasciidict.h> | 4 | #include <qasciidict.h> |
5 | 5 | ||
6 | #include "otodoaccessbackend.h" | 6 | #include "otodoaccessbackend.h" |
7 | 7 | ||
8 | class OSQLDriver; | 8 | class OSQLDriver; |
9 | class OSQLResult; | 9 | class OSQLResult; |
10 | class OSQLResultItem; | 10 | class OSQLResultItem; |
11 | class OTodoAccessBackendSQL : public OTodoAccessBackend { | 11 | class OTodoAccessBackendSQL : public OTodoAccessBackend { |
12 | public: | 12 | public: |
13 | OTodoAccessBackendSQL( const QString& file ); | 13 | OTodoAccessBackendSQL( const QString& file ); |
14 | ~OTodoAccessBackendSQL(); | 14 | ~OTodoAccessBackendSQL(); |
15 | 15 | ||
16 | bool load(); | 16 | bool load(); |
17 | bool reload(); | 17 | bool reload(); |
18 | bool save(); | 18 | bool save(); |
19 | QArray<int> allRecords()const; | 19 | QArray<int> allRecords()const; |
20 | 20 | ||
21 | QArray<int> queryByExample( const OTodo& t, int settings, const QDateTime& d = QDateTime() ); | 21 | QArray<int> queryByExample( const OTodo& t, int settings, const QDateTime& d = QDateTime() ); |
22 | OTodo find(int uid)const; | 22 | OTodo find(int uid)const; |
23 | OTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; | 23 | OTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; |
24 | void clear(); | 24 | void clear(); |
25 | bool add( const OTodo& t ); | 25 | bool add( const OTodo& t ); |
26 | bool remove( int uid ); | 26 | bool remove( int uid ); |
27 | bool replace( const OTodo& t ); | 27 | bool replace( const OTodo& t ); |
28 | 28 | ||
29 | QArray<int> overDue(); | 29 | QArray<int> overDue(); |
30 | QArray<int> effectiveToDos( const QDate& start, | 30 | QArray<int> effectiveToDos( const QDate& start, |
31 | const QDate& end, bool includeNoDates ); | 31 | const QDate& end, bool includeNoDates ); |
32 | QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat ); | 32 | QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat ); |
33 | 33 | ||
34 | QBitArray supports()const; | ||
35 | QArray<int> matchRegexp( const QRegExp &r ) const; | ||
36 | void removeAllCompleted(); | ||
37 | |||
38 | |||
34 | private: | 39 | private: |
35 | void update()const; | 40 | void update()const; |
36 | void fillDict(); | 41 | void fillDict(); |
37 | inline bool date( QDate& date, const QString& )const; | 42 | inline bool date( QDate& date, const QString& )const; |
38 | inline OTodo todo( const OSQLResult& )const; | 43 | inline OTodo todo( const OSQLResult& )const; |
39 | inline OTodo todo( OSQLResultItem& )const; | 44 | inline OTodo todo( OSQLResultItem& )const; |
40 | inline QArray<int> uids( const OSQLResult& )const; | 45 | inline QArray<int> uids( const OSQLResult& )const; |
41 | OTodo todo( int uid )const; | 46 | OTodo todo( int uid )const; |
47 | QBitArray sup(); | ||
42 | 48 | ||
43 | QAsciiDict<int> m_dict; | 49 | QAsciiDict<int> m_dict; |
44 | OSQLDriver* m_driver; | 50 | OSQLDriver* m_driver; |
45 | QArray<int> m_uids; | 51 | QArray<int> m_uids; |
46 | bool m_dirty : 1; | 52 | bool m_dirty : 1; |
47 | }; | 53 | }; |
48 | 54 | ||
49 | 55 | ||
50 | #endif | 56 | #endif |
diff --git a/libopie/pim/test/converter.cpp b/libopie/pim/test/converter.cpp new file mode 100644 index 0000000..0a488f2 --- a/dev/null +++ b/libopie/pim/test/converter.cpp | |||
@@ -0,0 +1,64 @@ | |||
1 | #include <qpe/qpeapplication.h> | ||
2 | |||
3 | #include <opie/ocontactaccess.h> | ||
4 | #include <opie/ocontactaccessbackend_xml.h> | ||
5 | #include <opie/ocontactaccessbackend_sql.h> | ||
6 | |||
7 | #include "converter_base.h" | ||
8 | |||
9 | class ConvertXMLToSQL: public converter_base { | ||
10 | public: | ||
11 | ConvertXMLToSQL() | ||
12 | { | ||
13 | convertContact(); | ||
14 | } | ||
15 | private: | ||
16 | void convertContact(); | ||
17 | |||
18 | }; | ||
19 | |||
20 | |||
21 | void ConvertXMLToSQL::convertContact(){ | ||
22 | qWarning("Converting Contacts from XML to SQL.."); | ||
23 | |||
24 | // Creating backends to the requested databases.. | ||
25 | OContactAccessBackend* xmlBackend = new OContactAccessBackend_XML( "Converter", | ||
26 | QString::null ); | ||
27 | |||
28 | OContactAccessBackend* sqlBackend = new OContactAccessBackend_SQL( QString::null, | ||
29 | QString::null ); | ||
30 | // Put the created backends into frontends to access them | ||
31 | OContactAccess* xmlAccess = new OContactAccess ( "addressbook_xml", | ||
32 | QString::null , xmlBackend, true ); | ||
33 | |||
34 | OContactAccess* sqlAccess = new OContactAccess ( "addressbook_sql", | ||
35 | QString::null , sqlBackend, true ); | ||
36 | |||
37 | // Clean the sql-database.. | ||
38 | sqlAccess->clear(); | ||
39 | |||
40 | // Now trasmit every contact from the xml database to the sql-database | ||
41 | OContactAccess::List contactList = xmlAccess->allRecords(); | ||
42 | if ( sqlAccess && xmlAccess ){ | ||
43 | OContactAccess::List::Iterator it; | ||
44 | for ( it = contactList.begin(); it != contactList.end(); ++it ) | ||
45 | sqlAccess->add( *it ); | ||
46 | } | ||
47 | |||
48 | // Delete the frontends. Backends will be deleted automatically, too ! | ||
49 | delete sqlAccess; | ||
50 | delete xmlAccess; | ||
51 | } | ||
52 | |||
53 | int main( int argc, char** argv ) { | ||
54 | |||
55 | QPEApplication a( argc, argv ); | ||
56 | |||
57 | ConvertXMLToSQL dlg; | ||
58 | |||
59 | a.showMainWidget( &dlg ); | ||
60 | // dlg. showMaximized ( ); | ||
61 | |||
62 | return a.exec(); | ||
63 | |||
64 | } | ||
diff --git a/libopie/pim/test/converter.pro b/libopie/pim/test/converter.pro new file mode 100644 index 0000000..aa74bff --- a/dev/null +++ b/libopie/pim/test/converter.pro | |||
@@ -0,0 +1,12 @@ | |||
1 | TEMPLATE= app | ||
2 | CONFIG = qt warn_on debug | ||
3 | # CONFIG = qt warn_on release | ||
4 | #HEADERS = | ||
5 | SOURCES = converter.cpp | ||
6 | INTERFACES = converter_base.ui | ||
7 | INCLUDEPATH+= $(OPIEDIR)/include | ||
8 | DEPENDPATH+= $(OPIEDIR)/include | ||
9 | LIBS += -lqpe -lopie | ||
10 | TARGET = converter | ||
11 | |||
12 | include ( $(OPIEDIR)/include.pro ) | ||
diff --git a/libopie/pim/test/converter_base.ui b/libopie/pim/test/converter_base.ui new file mode 100644 index 0000000..f680550 --- a/dev/null +++ b/libopie/pim/test/converter_base.ui | |||
@@ -0,0 +1,43 @@ | |||
1 | <!DOCTYPE UI><UI> | ||
2 | <class>converter_base</class> | ||
3 | <widget> | ||
4 | <class>QDialog</class> | ||
5 | <property stdset="1"> | ||
6 | <name>name</name> | ||
7 | <cstring>converter_base</cstring> | ||
8 | </property> | ||
9 | <property stdset="1"> | ||
10 | <name>geometry</name> | ||
11 | <rect> | ||
12 | <x>0</x> | ||
13 | <y>0</y> | ||
14 | <width>579</width> | ||
15 | <height>211</height> | ||
16 | </rect> | ||
17 | </property> | ||
18 | <property stdset="1"> | ||
19 | <name>caption</name> | ||
20 | <string>Form2</string> | ||
21 | </property> | ||
22 | <widget> | ||
23 | <class>QLabel</class> | ||
24 | <property stdset="1"> | ||
25 | <name>name</name> | ||
26 | <cstring>TextLabel1</cstring> | ||
27 | </property> | ||
28 | <property stdset="1"> | ||
29 | <name>geometry</name> | ||
30 | <rect> | ||
31 | <x>340</x> | ||
32 | <y>40</y> | ||
33 | <width>210</width> | ||
34 | <height>20</height> | ||
35 | </rect> | ||
36 | </property> | ||
37 | <property stdset="1"> | ||
38 | <name>text</name> | ||
39 | <string>Converter from XML->SQL</string> | ||
40 | </property> | ||
41 | </widget> | ||
42 | </widget> | ||
43 | </UI> | ||