25 files changed, 1218 insertions, 819 deletions
diff --git a/libopie2/opiepim/backend/backends.pro b/libopie2/opiepim/backend/backends.pro index 42d807c..739f74e 100644 --- a/libopie2/opiepim/backend/backends.pro +++ b/libopie2/opiepim/backend/backends.pro | |||
@@ -1,37 +1,40 @@ | |||
1 | SOURCES += \ | 1 | SOURCES += \ |
2 | backend/ocontactaccessbackend.cpp \ | ||
2 | backend/ocontactaccessbackend_vcard.cpp \ | 3 | backend/ocontactaccessbackend_vcard.cpp \ |
3 | backend/ocontactaccessbackend_xml.cpp \ | 4 | backend/ocontactaccessbackend_xml.cpp \ |
4 | backend/odatebookaccessbackend.cpp \ | 5 | backend/odatebookaccessbackend.cpp \ |
5 | backend/odatebookaccessbackend_xml.cpp \ | 6 | backend/odatebookaccessbackend_xml.cpp \ |
7 | backend/opimbackendoccurrence.cpp \ | ||
6 | backend/otodoaccessbackend.cpp \ | 8 | backend/otodoaccessbackend.cpp \ |
7 | backend/otodoaccessvcal.cpp \ | 9 | backend/otodoaccessvcal.cpp \ |
8 | backend/otodoaccessxml.cpp | 10 | backend/otodoaccessxml.cpp |
9 | 11 | ||
10 | HEADERS += \ | 12 | HEADERS += \ |
11 | backend/obackendfactory.h \ | 13 | backend/obackendfactory.h \ |
12 | backend/ocontactaccessbackend.h \ | 14 | backend/ocontactaccessbackend.h \ |
13 | backend/ocontactaccessbackend_vcard.h \ | 15 | backend/ocontactaccessbackend_vcard.h \ |
14 | backend/ocontactaccessbackend_xml.h \ | 16 | backend/ocontactaccessbackend_xml.h \ |
15 | backend/odatebookaccessbackend.h \ | 17 | backend/odatebookaccessbackend.h \ |
16 | backend/odatebookaccessbackend_xml.h \ | 18 | backend/odatebookaccessbackend_xml.h \ |
17 | backend/opimaccessbackend.h \ | 19 | backend/opimaccessbackend.h \ |
20 | backend/opimbackendoccurrence.h \ | ||
18 | backend/otodoaccessbackend.h \ | 21 | backend/otodoaccessbackend.h \ |
19 | backend/otodoaccessvcal.h \ | 22 | backend/otodoaccessvcal.h \ |
20 | backend/otodoaccessxml.h | 23 | backend/otodoaccessxml.h |
21 | 24 | ||
22 | contains( ENABLE_SQL_PIM_BACKEND, y ) { | 25 | contains( ENABLE_SQL_PIM_BACKEND, y ) { |
23 | message ( Enabling the SQL Backend for libopiepim2 ) | 26 | message ( Enabling the SQL Backend for libopiepim2 ) |
24 | DEFINES += __USE_SQL | 27 | DEFINES += __USE_SQL |
25 | LIBS += -lopiedb2 | 28 | LIBS += -lopiedb2 |
26 | HEADERS += backend/otodoaccesssql.h \ | 29 | HEADERS += backend/otodoaccesssql.h \ |
27 | backend/ocontactaccessbackend_sql.h \ | 30 | backend/ocontactaccessbackend_sql.h \ |
28 | backend/odatebookaccessbackend_sql.h | 31 | backend/odatebookaccessbackend_sql.h |
29 | SOURCES += backend/otodoaccesssql.cpp \ | 32 | SOURCES += backend/otodoaccesssql.cpp \ |
30 | backend/ocontactaccessbackend_sql.cpp \ | 33 | backend/ocontactaccessbackend_sql.cpp \ |
31 | backend/odatebookaccessbackend_sql.cpp | 34 | backend/odatebookaccessbackend_sql.cpp |
32 | } | 35 | } |
33 | 36 | ||
34 | !contains( ENABLE_SQL_PIM_BACKEND, y ) { | 37 | !contains( ENABLE_SQL_PIM_BACKEND, y ) { |
35 | message ( No SQL Backend in libopiepim2 ) | 38 | message ( No SQL Backend in libopiepim2 ) |
36 | } | 39 | } |
37 | 40 | ||
diff --git a/libopie2/opiepim/backend/obackendfactory.h b/libopie2/opiepim/backend/obackendfactory.h index 9f3a823..25e247b 100644 --- a/libopie2/opiepim/backend/obackendfactory.h +++ b/libopie2/opiepim/backend/obackendfactory.h | |||
@@ -1,230 +1,232 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers <eilers.stefan@epost.de> | 3 | Copyright (C) Stefan Eilers <eilers.stefan@epost.de> |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | /* | 29 | /* |
30 | * ===================================================================== | 30 | * ===================================================================== |
31 | * ToDo: Use plugins | 31 | * ToDo: Use plugins |
32 | * ===================================================================== | 32 | * ===================================================================== |
33 | */ | 33 | */ |
34 | #ifndef OPIE_BACKENDFACTORY_H_ | 34 | #ifndef OPIE_BACKENDFACTORY_H_ |
35 | #define OPIE_BACKENDFACTORY_H_ | 35 | #define OPIE_BACKENDFACTORY_H_ |
36 | 36 | ||
37 | /* OPIE */ | 37 | /* OPIE */ |
38 | #include <opie2/opimaccessbackend.h> | 38 | #include <opie2/opimaccessbackend.h> |
39 | #include <opie2/opimglobal.h> | 39 | #include <opie2/opimglobal.h> |
40 | #include <opie2/otodoaccessxml.h> | 40 | #include <opie2/otodoaccessxml.h> |
41 | #include <opie2/otodoaccessvcal.h> | 41 | #include <opie2/otodoaccessvcal.h> |
42 | #include <opie2/ocontactaccessbackend_xml.h> | 42 | #include <opie2/ocontactaccessbackend_xml.h> |
43 | #include <opie2/ocontactaccessbackend_vcard.h> | 43 | #include <opie2/ocontactaccessbackend_vcard.h> |
44 | #include <opie2/odatebookaccessbackend_xml.h> | 44 | #include <opie2/odatebookaccessbackend_xml.h> |
45 | #include <opie2/odebug.h> | 45 | #include <opie2/odebug.h> |
46 | 46 | ||
47 | #ifdef __USE_SQL | 47 | #ifdef __USE_SQL |
48 | #include <opie2/otodoaccesssql.h> | 48 | #include <opie2/otodoaccesssql.h> |
49 | #include <opie2/ocontactaccessbackend_sql.h> | 49 | #include <opie2/ocontactaccessbackend_sql.h> |
50 | #include <opie2/odatebookaccessbackend_sql.h> | 50 | #include <opie2/odatebookaccessbackend_sql.h> |
51 | #endif | 51 | #endif |
52 | 52 | ||
53 | #include <qpe/config.h> | 53 | #include <qpe/config.h> |
54 | 54 | ||
55 | /* QT */ | 55 | /* QT */ |
56 | #include <qstring.h> | 56 | #include <qstring.h> |
57 | #include <qasciidict.h> | 57 | #include <qasciidict.h> |
58 | 58 | ||
59 | 59 | ||
60 | 60 | ||
61 | using namespace Opie; | 61 | using namespace Opie; |
62 | using namespace Opie::Pim; | 62 | using namespace Opie::Pim; |
63 | 63 | ||
64 | namespace Opie { | 64 | namespace Opie { |
65 | 65 | ||
66 | class OBackendPrivate; | 66 | class OBackendPrivate; |
67 | 67 | ||
68 | /** | 68 | /** |
69 | * This class is our factory. It will give us the default implementations | 69 | * This class is our factory. It will give us the default implementations |
70 | * of at least Todolist, Contacts and Datebook. In the future this class will | 70 | * of at least Todolist, Contacts and Datebook. In the future this class will |
71 | * allow users to switch the backend with ( XML->SQLite ) without the need | 71 | * allow users to switch the backend with ( XML->SQLite ) without the need |
72 | * to recompile.# | 72 | * to recompile.# |
73 | * This class - as the whole PIM Api - is making use of templates | 73 | * This class - as the whole PIM Api - is making use of templates |
74 | * | 74 | * |
75 | * <pre> | 75 | * <pre> |
76 | * OPimTodoAccessBackend* backend = OBackEndFactory<OPimTodoAccessBackend>::Default( OPimGlobal::TODOLIST, QString::null ); | 76 | * OPimTodoAccessBackend* backend = OBackEndFactory<OPimTodoAccessBackend>::Default( OPimGlobal::TODOLIST, QString::null ); |
77 | * backend->load(); | 77 | * backend->load(); |
78 | * </pre> | 78 | * </pre> |
79 | * | 79 | * |
80 | * @author Stefan Eilers | 80 | * @author Stefan Eilers |
81 | * @version 0.1 | 81 | * @version 0.1 |
82 | */ | 82 | */ |
83 | template<class T> | 83 | template<class T> |
84 | class OBackendFactory | 84 | class OBackendFactory |
85 | { | 85 | { |
86 | public: | 86 | public: |
87 | OBackendFactory() {}; | 87 | OBackendFactory() {}; |
88 | 88 | ||
89 | /** | 89 | /** |
90 | * Returns a selected backend implementation | 90 | * Returns a selected backend implementation |
91 | * @param type the type of the backend | 91 | * @param type the type of the backend |
92 | * @param database the type of the used database | 92 | * @param database the type of the used database |
93 | * @param appName The name of your application. It will be passed on to the backend. | 93 | * @param appName The name of your application. It will be passed on to the backend. |
94 | * @param filename Filename of the database file if you don't want to access the default | 94 | * @param filename Filename of the database file if you don't want to access the default |
95 | * @see OPimGlobal() | 95 | * @see OPimGlobal() |
96 | */ | 96 | */ |
97 | static T* create( OPimGlobal::PimType type, OPimGlobal::DatabaseStyle database, | 97 | static T* create( OPimGlobal::PimType type, OPimGlobal::DatabaseStyle database, |
98 | const QString& appName, const QString& filename = QString::null ){ | 98 | const QString& appName, const QString& filename = QString::null ){ |
99 | owarn << "Selected backend for " << type << " is: " << database << oendl; | 99 | owarn << "Selected backend for " << type << " is: " << |
100 | // If we should use the dafult database style, we have to request it | 100 | database << oendl; |
101 | |||
102 | // If we should use the dafult database style, we have to request it | ||
101 | OPimGlobal::DatabaseStyle use_database = database; | 103 | OPimGlobal::DatabaseStyle use_database = database; |
102 | if ( use_database == OPimGlobal::DEFAULT ){ | 104 | if ( use_database == OPimGlobal::DEFAULT ){ |
103 | use_database = defaultDB( type ); | 105 | use_database = defaultDB( type ); |
104 | } | 106 | } |
105 | 107 | ||
106 | switch ( type ){ | 108 | switch ( type ){ |
107 | case OPimGlobal::TODOLIST: | 109 | case OPimGlobal::TODOLIST: |
108 | 110 | ||
109 | switch ( use_database ){ | 111 | switch ( use_database ){ |
110 | default: // Use SQL if something weird is given. | 112 | default: // Use SQL if something weird is given. |
111 | // Fall through !! | 113 | // Fall through !! |
112 | case OPimGlobal::SQL: | 114 | case OPimGlobal::SQL: |
113 | #ifdef __USE_SQL | 115 | #ifdef __USE_SQL |
114 | return (T*) new OPimTodoAccessBackendSQL( filename ); | 116 | return (T*) new OPimTodoAccessBackendSQL( filename ); |
115 | break; | 117 | break; |
116 | #else | 118 | #else |
117 | owarn << "OBackendFactory:: sql Backend for TODO not implemented! Using XML instead!" << oendl; | 119 | owarn << "OBackendFactory:: sql Backend for TODO not implemented! Using XML instead!" << oendl; |
118 | // Fall through !! | 120 | // Fall through !! |
119 | #endif | 121 | #endif |
120 | case OPimGlobal::XML: | 122 | case OPimGlobal::XML: |
121 | return (T*) new OPimTodoAccessXML( appName, filename ); | 123 | return (T*) new OPimTodoAccessXML( appName, filename ); |
122 | break; | 124 | break; |
123 | case OPimGlobal::VCARD: | 125 | case OPimGlobal::VCARD: |
124 | return (T*) new OPimTodoAccessVCal( filename ); | 126 | return (T*) new OPimTodoAccessVCal( filename ); |
125 | break; | 127 | break; |
126 | } | 128 | } |
127 | case OPimGlobal::CONTACTLIST: | 129 | case OPimGlobal::CONTACTLIST: |
128 | switch ( use_database ){ | 130 | switch ( use_database ){ |
129 | default: // Use SQL if something weird is given. | 131 | default: // Use SQL if something weird is given. |
130 | // Fall through !! | 132 | // Fall through !! |
131 | case OPimGlobal::SQL: | 133 | case OPimGlobal::SQL: |
132 | #ifdef __USE_SQL | 134 | #ifdef __USE_SQL |
133 | return (T*) new OPimContactAccessBackend_SQL( appName, filename ); | 135 | return (T*) new OPimContactAccessBackend_SQL( appName, filename ); |
134 | break; | 136 | break; |
135 | #else | 137 | #else |
136 | owarn << "OBackendFactory:: sql Backend for CONTACT not implemented! Using XML instead!" << oendl; | 138 | owarn << "OBackendFactory:: sql Backend for CONTACT not implemented! Using XML instead!" << oendl; |
137 | // Fall through !! | 139 | // Fall through !! |
138 | #endif | 140 | #endif |
139 | case OPimGlobal::XML: | 141 | case OPimGlobal::XML: |
140 | return (T*) new OPimContactAccessBackend_XML( appName, filename ); | 142 | return (T*) new OPimContactAccessBackend_XML( appName, filename ); |
141 | break; | 143 | break; |
142 | case OPimGlobal::VCARD: | 144 | case OPimGlobal::VCARD: |
143 | return (T*) new OPimContactAccessBackend_VCard( appName, filename ); | 145 | return (T*) new OPimContactAccessBackend_VCard( appName, filename ); |
144 | break; | 146 | break; |
145 | } | 147 | } |
146 | case OPimGlobal::DATEBOOK: | 148 | case OPimGlobal::DATEBOOK: |
147 | switch ( use_database ){ | 149 | switch ( use_database ){ |
148 | default: // Use SQL if something weird is given. | 150 | default: // Use SQL if something weird is given. |
149 | // Fall through !! | 151 | // Fall through !! |
150 | case OPimGlobal::SQL: | 152 | case OPimGlobal::SQL: |
151 | #ifdef __USE_SQL | 153 | #ifdef __USE_SQL |
152 | return (T*) new ODateBookAccessBackend_SQL( appName, filename ); | 154 | return (T*) new ODateBookAccessBackend_SQL( appName, filename ); |
153 | break; | 155 | break; |
154 | #else | 156 | #else |
155 | owarn << "OBackendFactory:: sql Backend for DATEBOOK not implemented! Using XML instead!" << oendl; | 157 | owarn << "OBackendFactory:: sql Backend for DATEBOOK not implemented! Using XML instead!" << oendl; |
156 | // Fall through !! | 158 | // Fall through !! |
157 | #endif | 159 | #endif |
158 | case OPimGlobal::XML: | 160 | case OPimGlobal::XML: |
159 | return (T*) new ODateBookAccessBackend_XML( appName, filename ); | 161 | return (T*) new ODateBookAccessBackend_XML( appName, filename ); |
160 | break; | 162 | break; |
161 | case OPimGlobal::VCARD: | 163 | case OPimGlobal::VCARD: |
162 | owarn << "OBackendFactory:: VCal Backend for DATEBOOK not implemented!" << oendl; | 164 | owarn << "OBackendFactory:: VCal Backend for DATEBOOK not implemented!" << oendl; |
163 | return (T*) NULL; | 165 | return (T*) NULL; |
164 | break; | 166 | break; |
165 | } | 167 | } |
166 | default: | 168 | default: |
167 | return (T*) NULL; | 169 | return (T*) NULL; |
168 | } | 170 | } |
169 | 171 | ||
170 | } | 172 | } |
171 | 173 | ||
172 | /** | 174 | /** |
173 | * Returns the style of the default database which is used to contact PIM data. | 175 | * Returns the style of the default database which is used to contact PIM data. |
174 | * @param type the type of the backend | 176 | * @param type the type of the backend |
175 | * @see OPimGlobal() | 177 | * @see OPimGlobal() |
176 | */ | 178 | */ |
177 | static OPimGlobal::DatabaseStyle defaultDB( OPimGlobal::PimType type ){ | 179 | static OPimGlobal::DatabaseStyle defaultDB( OPimGlobal::PimType type ){ |
178 | QString group_name; | 180 | QString group_name; |
179 | switch ( type ){ | 181 | switch ( type ){ |
180 | case OPimGlobal::TODOLIST: | 182 | case OPimGlobal::TODOLIST: |
181 | group_name = "todo"; | 183 | group_name = "todo"; |
182 | break; | 184 | break; |
183 | case OPimGlobal::CONTACTLIST: | 185 | case OPimGlobal::CONTACTLIST: |
184 | group_name = "contact"; | 186 | group_name = "contact"; |
185 | break; | 187 | break; |
186 | case OPimGlobal::DATEBOOK: | 188 | case OPimGlobal::DATEBOOK: |
187 | group_name = "datebook"; | 189 | group_name = "datebook"; |
188 | break; | 190 | break; |
189 | default: | 191 | default: |
190 | group_name = "unknown"; | 192 | group_name = "unknown"; |
191 | } | 193 | } |
192 | 194 | ||
193 | Config config( "pimaccess" ); | 195 | Config config( "pimaccess" ); |
194 | config.setGroup ( group_name ); | 196 | config.setGroup ( group_name ); |
195 | QString db_String = config.readEntry( "usebackend", "xml" ); | 197 | QString db_String = config.readEntry( "usebackend", "xml" ); |
196 | 198 | ||
197 | QAsciiDict<int> dictDbTypes( OPimGlobal::_END_DatabaseStyle ); | 199 | QAsciiDict<int> dictDbTypes( OPimGlobal::_END_DatabaseStyle ); |
198 | dictDbTypes.setAutoDelete( TRUE ); | 200 | dictDbTypes.setAutoDelete( TRUE ); |
199 | 201 | ||
200 | dictDbTypes.insert( "xml", new int (OPimGlobal::XML) ); | 202 | dictDbTypes.insert( "xml", new int (OPimGlobal::XML) ); |
201 | dictDbTypes.insert( "sql", new int (OPimGlobal::SQL) ); | 203 | dictDbTypes.insert( "sql", new int (OPimGlobal::SQL) ); |
202 | dictDbTypes.insert( "vcard", new int (OPimGlobal::VCARD) ); | 204 | dictDbTypes.insert( "vcard", new int (OPimGlobal::VCARD) ); |
203 | 205 | ||
204 | int* db_find = dictDbTypes[ db_String ]; | 206 | int* db_find = dictDbTypes[ db_String ]; |
205 | 207 | ||
206 | if ( !db_find ) | 208 | if ( !db_find ) |
207 | return OPimGlobal::UNKNOWN; | 209 | return OPimGlobal::UNKNOWN; |
208 | 210 | ||
209 | return (OPimGlobal::DatabaseStyle) *db_find; | 211 | return (OPimGlobal::DatabaseStyle) *db_find; |
210 | } | 212 | } |
211 | 213 | ||
212 | 214 | ||
213 | /** | 215 | /** |
214 | * Returns the default backend implementation for backendName. Which one is used, is defined | 216 | * Returns the default backend implementation for backendName. Which one is used, is defined |
215 | * by the configfile "pimaccess.conf". | 217 | * by the configfile "pimaccess.conf". |
216 | * @param type The type of the backend (@see OPimGlobal()) | 218 | * @param type The type of the backend (@see OPimGlobal()) |
217 | * @param appName The name of your application. It will be passed on to the backend | 219 | * @param appName The name of your application. It will be passed on to the backend |
218 | * @see OPimGlobal() | 220 | * @see OPimGlobal() |
219 | */ | 221 | */ |
220 | static T* defaultBackend( OPimGlobal::PimType type, const QString& appName ){ | 222 | static T* defaultBackend( OPimGlobal::PimType type, const QString& appName ){ |
221 | return create( type, OPimGlobal::DEFAULT, appName ); | 223 | return create( type, OPimGlobal::DEFAULT, appName ); |
222 | } | 224 | } |
223 | private: | 225 | private: |
224 | OBackendPrivate* d; | 226 | OBackendPrivate* d; |
225 | 227 | ||
226 | }; | 228 | }; |
227 | 229 | ||
228 | } | 230 | } |
229 | 231 | ||
230 | #endif | 232 | #endif |
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.cpp b/libopie2/opiepim/backend/ocontactaccessbackend.cpp new file mode 100644 index 0000000..6ef60eb --- a/dev/null +++ b/libopie2/opiepim/backend/ocontactaccessbackend.cpp | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | This file is part of the Opie Project | ||
3 | Copyright (C) 2004 Holger Freyther <freyther@handhelds.org> | ||
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | ||
5 | .=l. | ||
6 | .>+-= | ||
7 | _;:, .> :=|. This program is free software; you can | ||
8 | .> <`_, > . <= redistribute it and/or modify it under | ||
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | ||
10 | .="- .-=="i, .._ License as published by the Free Software | ||
11 | - . .-<_> .<> Foundation; either version 2 of the License, | ||
12 | ._= =} : or (at your option) any later version. | ||
13 | .%`+i> _;_. | ||
14 | .i_,=:_. -<s. This program is distributed in the hope that | ||
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | ||
16 | : .. .:, . . . without even the implied warranty of | ||
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | ||
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | ||
19 | ..}^=.= = ; Library General Public License for more | ||
20 | ++= -. .` .: details. | ||
21 | : = ...= . :.=- | ||
22 | -. .:....=;==+<; You should have received a copy of the GNU | ||
23 | -_. . . )=. = Library General Public License along with | ||
24 | -- :-=` this library; see the file COPYING.LIB. | ||
25 | If not, write to the Free Software Foundation, | ||
26 | Inc., 59 Temple Place - Suite 330, | ||
27 | Boston, MA 02111-1307, USA. | ||
28 | */ | ||
29 | |||
30 | #include "ocontactaccessbackend.h" | ||
31 | #include <opie2/private/opimcontactsortvector.h> | ||
32 | #include <opie2/ocontactaccess.h> | ||
33 | |||
34 | #include <opie2/odebug.h> | ||
35 | |||
36 | namespace Opie { | ||
37 | OPimContactAccessBackend::OPimContactAccessBackend() {} | ||
38 | |||
39 | UIDArray | ||
40 | OPimContactAccessBackend::queryByExample( const OPimContact&, int, | ||
41 | const QDateTime& )const { | ||
42 | return UIDArray(); | ||
43 | } | ||
44 | |||
45 | UIDArray | ||
46 | OPimContactAccessBackend::sorted( const UIDArray& ar, bool asc, int sortOrder, | ||
47 | int filter, const QArray<int>& categories)const { | ||
48 | odebug << "Using Unaccelerated OPimContactAccessBackend sorted Implementation" << oendl; | ||
49 | |||
50 | Internal::OPimContactSortVector vector(ar.count(), asc, sortOrder ); | ||
51 | |||
52 | int item = 0; | ||
53 | uint cat_count = categories.count(); | ||
54 | uint eve_count = ar.count(); | ||
55 | bool bCat = filter & OPimContactAccess::FilterCategory ? true : false; | ||
56 | bool catPassed = false; | ||
57 | int cat; | ||
58 | |||
59 | for ( uint i = 0; i < eve_count; ++i ) { | ||
60 | OPimContact contact = find( ar[i], ar, i, Frontend::Forward ); | ||
61 | if ( contact.isEmpty() ) | ||
62 | continue; | ||
63 | |||
64 | /* show category */ | ||
65 | /* -1 == unfiled */ | ||
66 | catPassed = false; | ||
67 | for ( uint cat_nu = 0; cat_nu < cat_count; ++cat_nu ) { | ||
68 | cat = categories[cat_nu]; | ||
69 | if ( bCat && cat == -1 ) { | ||
70 | if(!contact.categories().isEmpty() ) | ||
71 | continue; | ||
72 | } else if ( bCat && cat != 0) | ||
73 | if (!contact.categories().contains( cat ) ) | ||
74 | continue; | ||
75 | catPassed = true; | ||
76 | break; | ||
77 | } | ||
78 | |||
79 | /* | ||
80 | * If none of the Categories matched | ||
81 | * continue | ||
82 | */ | ||
83 | if ( !catPassed ) | ||
84 | continue; | ||
85 | |||
86 | vector.insert(item++, contact ); | ||
87 | } | ||
88 | |||
89 | vector.resize( item ); | ||
90 | /* sort it now */ | ||
91 | vector.sort(); | ||
92 | /* now get the uids */ | ||
93 | UIDArray array( vector.count() ); | ||
94 | for (uint i= 0; i < vector.count(); i++ ) | ||
95 | array[i] = vector.uidAt( i ); | ||
96 | |||
97 | return array; | ||
98 | } | ||
99 | |||
100 | OPimBackendOccurrence::List OPimContactAccessBackend::occurrences( const QDate& start, | ||
101 | const QDate& end)const { | ||
102 | OPimBackendOccurrence::List lst; | ||
103 | |||
104 | UIDArray records = allRecords(); | ||
105 | const uint count = records.count(); | ||
106 | int uid; | ||
107 | |||
108 | for ( uint i = 0; i < count; ++i ) { | ||
109 | uid = records[i]; | ||
110 | OPimContact contact = find(uid, records, i, Frontend::Forward ); | ||
111 | |||
112 | QDate date = contact.anniversary(); | ||
113 | date = QDate( start.year(), date.month(),date.day() ); | ||
114 | |||
115 | // if ( date.isValid() && date.) { | ||
116 | // } | ||
117 | } | ||
118 | |||
119 | return lst; | ||
120 | } | ||
121 | } | ||
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.h b/libopie2/opiepim/backend/ocontactaccessbackend.h index 8436adc..efb04c7 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend.h | |||
@@ -1,114 +1,108 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) The Main Author <main-author@whereever.org> | 3 | Copyright (C) The Main Author <main-author@whereever.org> |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | /** | 29 | /** |
30 | * The class responsible for managing a backend. | 30 | * The class responsible for managing a backend. |
31 | * The implementation of this abstract class contains | 31 | * The implementation of this abstract class contains |
32 | * the complete database handling. | 32 | * the complete database handling. |
33 | * | 33 | * |
34 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | 34 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) |
35 | * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) | 35 | * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) |
36 | * | 36 | * |
37 | */ | 37 | */ |
38 | 38 | ||
39 | #ifndef _OCONTACTACCESSBACKEND_H_ | 39 | #ifndef _OCONTACTACCESSBACKEND_H_ |
40 | #define _OCONTACTACCESSBACKEND_H_ | 40 | #define _OCONTACTACCESSBACKEND_H_ |
41 | 41 | ||
42 | #include <opie2/opimcontact.h> | 42 | #include <opie2/opimcontact.h> |
43 | #include <opie2/opimaccessbackend.h> | 43 | #include <opie2/opimaccessbackend.h> |
44 | 44 | ||
45 | #include <qregexp.h> | 45 | #include <qregexp.h> |
46 | 46 | ||
47 | namespace Opie { | 47 | namespace Opie { |
48 | /** | 48 | /** |
49 | * This class represents the interface of all Contact Backends. | 49 | * This class represents the interface of all Contact Backends. |
50 | * Derivates of this class will be used to access the contacts. | 50 | * Derivates of this class will be used to access the contacts. |
51 | * As implementation currently XML and vCard exist. This class needs to be implemented | 51 | * As implementation currently XML and vCard exist. This class needs to be implemented |
52 | * if you want to provide your own storage. | 52 | * if you want to provide your own storage. |
53 | * In all queries a list of uids is passed on instead of loading the actual record! | 53 | * In all queries a list of uids is passed on instead of loading the actual record! |
54 | * | 54 | * |
55 | * @see OPimContactAccessBackend_VCard | 55 | * @see OPimContactAccessBackend_VCard |
56 | * @see OPimContactAccessBackend_XML | 56 | * @see OPimContactAccessBackend_XML |
57 | */ | 57 | */ |
58 | class OPimContactAccessBackend: public OPimAccessBackend<OPimContact> { | 58 | class OPimContactAccessBackend: public OPimAccessBackend<OPimContact> { |
59 | public: | 59 | public: |
60 | /** | 60 | OPimContactAccessBackend(); |
61 | * @todo make non line in regard to BC guide of KDE | ||
62 | */ | ||
63 | OPimContactAccessBackend() {} | ||
64 | /** | ||
65 | * @todo make non inline in regard to the BC guide of KDE | ||
66 | */ | ||
67 | virtual ~OPimContactAccessBackend() {} | ||
68 | 61 | ||
69 | 62 | ||
70 | /** | 63 | /** |
71 | * Return if database was changed externally. | 64 | * Return if database was changed externally. |
72 | * This may just make sense on file based databases like a XML-File. | 65 | * This may just make sense on file based databases like a XML-File. |
73 | * It is used to prevent to overwrite the current database content | 66 | * It is used to prevent to overwrite the current database content |
74 | * if the file was already changed by something else ! | 67 | * if the file was already changed by something else ! |
75 | * If this happens, we have to reload before save our data. | 68 | * If this happens, we have to reload before save our data. |
76 | * If we use real databases, this should be handled by the database | 69 | * If we use real databases, this should be handled by the database |
77 | * management system themselve, therefore this function should always return false in | 70 | * management system themselve, therefore this function should always return false in |
78 | * this case. It is not our problem to handle this conflict ... | 71 | * this case. It is not our problem to handle this conflict ... |
79 | * @return <i>true</i> if the database was changed and if save without reload will | 72 | * @return <i>true</i> if the database was changed and if save without reload will |
80 | * be dangerous. <i>false</i> if the database was not changed or it is save to write | 73 | * be dangerous. <i>false</i> if the database was not changed or it is save to write |
81 | * in this situation. | 74 | * in this situation. |
82 | */ | 75 | */ |
83 | virtual bool wasChangedExternally() = 0; | 76 | virtual bool wasChangedExternally() = 0; |
84 | 77 | ||
85 | virtual QArray<int> matchRegexp( const QRegExp &r ) const = 0; | 78 | /** |
79 | * Return all possible settings. | ||
80 | * @return All settings provided by the current backend | ||
81 | * (i.e.: query_WildCards & query_IgnoreCase) | ||
82 | */ | ||
83 | virtual const uint querySettings() = 0; | ||
86 | 84 | ||
87 | /** | 85 | /** |
88 | * Return all possible settings. | 86 | * Check whether settings are correct. |
89 | * @return All settings provided by the current backend | 87 | * @return <i>true</i> if the given settings are correct and possible. |
90 | * (i.e.: query_WildCards & query_IgnoreCase) | 88 | */ |
91 | */ | 89 | virtual bool hasQuerySettings (uint querySettings) const = 0; |
92 | virtual const uint querySettings() = 0; | 90 | |
91 | /** | ||
92 | * Slow and inefficent default implementation | ||
93 | */ | ||
94 | //@{ | ||
95 | UIDArray queryByExample( const OPimContact&, int settings, const QDateTime& d = QDateTime() )const; | ||
96 | UIDArray sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const; | ||
97 | OPimBackendOccurrence::List occurrences( const QDate&, const QDate& )const; | ||
98 | //@} | ||
93 | 99 | ||
94 | /** | ||
95 | * Check whether settings are correct. | ||
96 | * @return <i>true</i> if the given settings are correct and possible. | ||
97 | */ | ||
98 | virtual bool hasQuerySettings (uint querySettings) const = 0; | ||
99 | 100 | ||
100 | /** | ||
101 | * FIXME!!! | ||
102 | * Returns a sorted list of records either ascendinf or descending for a giving criteria and category | ||
103 | */ | ||
104 | virtual QArray<int> sorted( bool ascending, int sortOrder, int sortFilter, int cat ) = 0; | ||
105 | |||
106 | |||
107 | private: | 101 | private: |
108 | class Private; | 102 | class Private; |
109 | Private *d; | 103 | Private *d; |
110 | }; | 104 | }; |
111 | 105 | ||
112 | } | 106 | } |
113 | 107 | ||
114 | #endif | 108 | #endif |
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp index af77a05..43e530a 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp | |||
@@ -1,611 +1,585 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) The Main Author <main-author@whereever.org> | 3 | Copyright (C) The Main Author <main-author@whereever.org> |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | /* | 29 | /* |
30 | * VCard Backend for the OPIE-Contact Database. | 30 | * VCard Backend for the OPIE-Contact Database. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | 33 | ||
34 | #include <opie2/private/vobject_p.h> | 34 | #include <opie2/private/vobject_p.h> |
35 | 35 | ||
36 | /* OPIE */ | 36 | /* OPIE */ |
37 | #include <opie2/ocontactaccessbackend_vcard.h> | 37 | #include <opie2/ocontactaccessbackend_vcard.h> |
38 | #include <opie2/odebug.h> | 38 | #include <opie2/odebug.h> |
39 | 39 | ||
40 | #include <qpe/timeconversion.h> | 40 | #include <qpe/timeconversion.h> |
41 | 41 | ||
42 | //FIXME: Hack to allow direct access to FILE* fh. Rewrite this! | 42 | //FIXME: Hack to allow direct access to FILE* fh. Rewrite this! |
43 | #define protected public | 43 | #define protected public |
44 | #include <qfile.h> | 44 | #include <qfile.h> |
45 | #undef protected | 45 | #undef protected |
46 | 46 | ||
47 | namespace Opie { | 47 | namespace Opie { |
48 | 48 | ||
49 | OPimContactAccessBackend_VCard::OPimContactAccessBackend_VCard ( const QString& , const QString& filename ): | 49 | OPimContactAccessBackend_VCard::OPimContactAccessBackend_VCard ( const QString& , const QString& filename ): |
50 | m_dirty( false ), | 50 | m_dirty( false ), |
51 | m_file( filename ) | 51 | m_file( filename ) |
52 | { | 52 | { |
53 | load(); | 53 | load(); |
54 | } | 54 | } |
55 | 55 | ||
56 | 56 | ||
57 | bool OPimContactAccessBackend_VCard::load () | 57 | bool OPimContactAccessBackend_VCard::load () |
58 | { | 58 | { |
59 | m_map.clear(); | 59 | m_map.clear(); |
60 | m_dirty = false; | 60 | m_dirty = false; |
61 | 61 | ||
62 | VObject* obj = 0l; | 62 | VObject* obj = 0l; |
63 | 63 | ||
64 | if ( QFile::exists(m_file) ){ | 64 | if ( QFile::exists(m_file) ){ |
65 | obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); | 65 | obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); |
66 | if ( !obj ) | 66 | if ( !obj ) |
67 | return false; | 67 | return false; |
68 | }else{ | 68 | }else{ |
69 | odebug << "File \"" << m_file << "\" not found !" << oendl; | 69 | odebug << "File \"" << m_file << "\" not found !" << oendl; |
70 | return false; | 70 | return false; |
71 | } | 71 | } |
72 | 72 | ||
73 | while ( obj ) { | 73 | while ( obj ) { |
74 | OPimContact con = parseVObject( obj ); | 74 | OPimContact con = parseVObject( obj ); |
75 | /* | 75 | /* |
76 | * if uid is 0 assign a new one | 76 | * if uid is 0 assign a new one |
77 | * this at least happens on | 77 | * this at least happens on |
78 | * Nokia6210 | 78 | * Nokia6210 |
79 | */ | 79 | */ |
80 | if ( con.uid() == 0 ){ | 80 | if ( con.uid() == 0 ){ |
81 | con.setUid( 1 ); | 81 | con.setUid( 1 ); |
82 | owarn << "assigned new uid " << con.uid() << "" << oendl; | 82 | owarn << "assigned new uid " << con.uid() << "" << oendl; |
83 | } | 83 | } |
84 | 84 | ||
85 | m_map.insert( con.uid(), con ); | 85 | m_map.insert( con.uid(), con ); |
86 | 86 | ||
87 | VObject *t = obj; | 87 | VObject *t = obj; |
88 | obj = nextVObjectInList(obj); | 88 | obj = nextVObjectInList(obj); |
89 | cleanVObject( t ); | 89 | cleanVObject( t ); |
90 | } | 90 | } |
91 | 91 | ||
92 | return true; | 92 | return true; |
93 | 93 | ||
94 | } | 94 | } |
95 | bool OPimContactAccessBackend_VCard::reload() | 95 | bool OPimContactAccessBackend_VCard::reload() |
96 | { | 96 | { |
97 | return load(); | 97 | return load(); |
98 | } | 98 | } |
99 | bool OPimContactAccessBackend_VCard::save() | 99 | bool OPimContactAccessBackend_VCard::save() |
100 | { | 100 | { |
101 | if (!m_dirty ) | 101 | if (!m_dirty ) |
102 | return true; | 102 | return true; |
103 | 103 | ||
104 | QFile file( m_file ); | 104 | QFile file( m_file ); |
105 | if (!file.open(IO_WriteOnly ) ) | 105 | if (!file.open(IO_WriteOnly ) ) |
106 | return false; | 106 | return false; |
107 | 107 | ||
108 | VObject *obj; | 108 | VObject *obj; |
109 | obj = newVObject( VCCalProp ); | 109 | obj = newVObject( VCCalProp ); |
110 | addPropValue( obj, VCVersionProp, "1.0" ); | 110 | addPropValue( obj, VCVersionProp, "1.0" ); |
111 | 111 | ||
112 | VObject *vo; | 112 | VObject *vo; |
113 | for(QMap<int, OPimContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ | 113 | for(QMap<int, OPimContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ |
114 | vo = createVObject( *it ); | 114 | vo = createVObject( *it ); |
115 | writeVObject( file.fh, vo ); //FIXME: HACK!!! | 115 | writeVObject( file.fh, vo ); //FIXME: HACK!!! |
116 | cleanVObject( vo ); | 116 | cleanVObject( vo ); |
117 | } | 117 | } |
118 | cleanStrTbl(); | 118 | cleanStrTbl(); |
119 | deleteVObject( obj ); | 119 | deleteVObject( obj ); |
120 | 120 | ||
121 | m_dirty = false; | 121 | m_dirty = false; |
122 | return true; | 122 | return true; |
123 | 123 | ||
124 | 124 | ||
125 | } | 125 | } |
126 | void OPimContactAccessBackend_VCard::clear () | 126 | void OPimContactAccessBackend_VCard::clear () |
127 | { | 127 | { |
128 | m_map.clear(); | 128 | m_map.clear(); |
129 | m_dirty = true; // ??? sure ? (se) | 129 | m_dirty = true; // ??? sure ? (se) |
130 | } | 130 | } |
131 | 131 | ||
132 | bool OPimContactAccessBackend_VCard::add ( const OPimContact& newcontact ) | 132 | bool OPimContactAccessBackend_VCard::add ( const OPimContact& newcontact ) |
133 | { | 133 | { |
134 | m_map.insert( newcontact.uid(), newcontact ); | 134 | m_map.insert( newcontact.uid(), newcontact ); |
135 | m_dirty = true; | 135 | m_dirty = true; |
136 | return true; | 136 | return true; |
137 | } | 137 | } |
138 | 138 | ||
139 | bool OPimContactAccessBackend_VCard::remove ( int uid ) | 139 | bool OPimContactAccessBackend_VCard::remove ( int uid ) |
140 | { | 140 | { |
141 | m_map.remove( uid ); | 141 | m_map.remove( uid ); |
142 | m_dirty = true; | 142 | m_dirty = true; |
143 | return true; | 143 | return true; |
144 | } | 144 | } |
145 | 145 | ||
146 | bool OPimContactAccessBackend_VCard::replace ( const OPimContact &contact ) | 146 | bool OPimContactAccessBackend_VCard::replace ( const OPimContact &contact ) |
147 | { | 147 | { |
148 | m_map.replace( contact.uid(), contact ); | 148 | m_map.replace( contact.uid(), contact ); |
149 | m_dirty = true; | 149 | m_dirty = true; |
150 | return true; | 150 | return true; |
151 | } | 151 | } |
152 | 152 | ||
153 | OPimContact OPimContactAccessBackend_VCard::find ( int uid ) const | 153 | OPimContact OPimContactAccessBackend_VCard::find ( int uid ) const |
154 | { | 154 | { |
155 | return m_map[uid]; | 155 | return m_map[uid]; |
156 | } | 156 | } |
157 | 157 | ||
158 | QArray<int> OPimContactAccessBackend_VCard::allRecords() const | 158 | QArray<int> OPimContactAccessBackend_VCard::allRecords() const |
159 | { | 159 | { |
160 | QArray<int> ar( m_map.count() ); | 160 | QArray<int> ar( m_map.count() ); |
161 | QMap<int, OPimContact>::ConstIterator it; | 161 | QMap<int, OPimContact>::ConstIterator it; |
162 | int i = 0; | 162 | int i = 0; |
163 | for ( it = m_map.begin(); it != m_map.end(); ++it ) { | 163 | for ( it = m_map.begin(); it != m_map.end(); ++it ) { |
164 | ar[i] = it.key(); | 164 | ar[i] = it.key(); |
165 | i++; | 165 | i++; |
166 | } | 166 | } |
167 | return ar; | 167 | return ar; |
168 | } | 168 | } |
169 | 169 | ||
170 | // Not implemented | ||
171 | QArray<int> OPimContactAccessBackend_VCard::queryByExample ( const OPimContact&, int, const QDateTime& ) | ||
172 | { | ||
173 | QArray<int> ar(0); | ||
174 | return ar; | ||
175 | } | ||
176 | |||
177 | // Not implemented | ||
178 | QArray<int> OPimContactAccessBackend_VCard::matchRegexp( const QRegExp& ) const | ||
179 | { | ||
180 | QArray<int> ar(0); | ||
181 | return ar; | ||
182 | } | ||
183 | |||
184 | const uint OPimContactAccessBackend_VCard::querySettings() | 170 | const uint OPimContactAccessBackend_VCard::querySettings() |
185 | { | 171 | { |
186 | return 0; // No search possible | 172 | return 0; // No search possible |
187 | } | 173 | } |
188 | 174 | ||
189 | bool OPimContactAccessBackend_VCard::hasQuerySettings (uint ) const | 175 | bool OPimContactAccessBackend_VCard::hasQuerySettings (uint ) const |
190 | { | 176 | { |
191 | return false; // No search possible, therefore all settings invalid ;) | 177 | return false; // No search possible, therefore all settings invalid ;) |
192 | } | 178 | } |
193 | 179 | ||
194 | bool OPimContactAccessBackend_VCard::wasChangedExternally() | 180 | bool OPimContactAccessBackend_VCard::wasChangedExternally() |
195 | { | 181 | { |
196 | return false; // Don't expect concurrent access | 182 | return false; // Don't expect concurrent access |
197 | } | 183 | } |
198 | 184 | ||
199 | // Not implemented | ||
200 | QArray<int> OPimContactAccessBackend_VCard::sorted( bool , int, int, int ) | ||
201 | { | ||
202 | QArray<int> ar(0); | ||
203 | return ar; | ||
204 | } | ||
205 | |||
206 | // *** Private stuff *** | 185 | // *** Private stuff *** |
207 | |||
208 | |||
209 | OPimContact OPimContactAccessBackend_VCard::parseVObject( VObject *obj ) | 186 | OPimContact OPimContactAccessBackend_VCard::parseVObject( VObject *obj ) |
210 | { | 187 | { |
211 | OPimContact c; | 188 | OPimContact c; |
212 | 189 | ||
213 | VObjectIterator it; | 190 | VObjectIterator it; |
214 | initPropIterator( &it, obj ); | 191 | initPropIterator( &it, obj ); |
215 | while( moreIteration( &it ) ) { | 192 | while( moreIteration( &it ) ) { |
216 | VObject *o = nextVObject( &it ); | 193 | VObject *o = nextVObject( &it ); |
217 | QCString name = vObjectName( o ); | 194 | QCString name = vObjectName( o ); |
218 | QString value = QString::fromUtf8( vObjectStringZValue( o ) ); | 195 | QString value = QString::fromUtf8( vObjectStringZValue( o ) ); |
219 | odebug << "(1)Read: %s" << QString( value ).latin1() << oendl; | 196 | odebug << "(1)Read: %s" << QString( value ).latin1() << oendl; |
220 | if ( name == VCNameProp ) { | 197 | if ( name == VCNameProp ) { |
221 | VObjectIterator nit; | 198 | VObjectIterator nit; |
222 | initPropIterator( &nit, o ); | 199 | initPropIterator( &nit, o ); |
223 | while( moreIteration( &nit ) ) { | 200 | while( moreIteration( &nit ) ) { |
224 | VObject *o = nextVObject( &nit ); | 201 | VObject *o = nextVObject( &nit ); |
225 | QCString name = vObjectTypeInfo( o ); | 202 | QCString name = vObjectTypeInfo( o ); |
226 | QString value = QString::fromUtf8( vObjectStringZValue( o ) ); | 203 | QString value = QString::fromUtf8( vObjectStringZValue( o ) ); |
227 | odebug << "(2)Read: %s" << value.latin1() << oendl; | 204 | odebug << "(2)Read: %s" << value.latin1() << oendl; |
228 | if ( name == VCNamePrefixesProp ) | 205 | if ( name == VCNamePrefixesProp ) |
229 | c.setTitle( value ); | 206 | c.setTitle( value ); |
230 | else if ( name == VCNameSuffixesProp ) | 207 | else if ( name == VCNameSuffixesProp ) |
231 | c.setSuffix( value ); | 208 | c.setSuffix( value ); |
232 | else if ( name == VCFamilyNameProp ) | 209 | else if ( name == VCFamilyNameProp ) |
233 | c.setLastName( value ); | 210 | c.setLastName( value ); |
234 | else if ( name == VCGivenNameProp ) | 211 | else if ( name == VCGivenNameProp ) |
235 | c.setFirstName( value ); | 212 | c.setFirstName( value ); |
236 | else if ( name == VCAdditionalNamesProp ) | 213 | else if ( name == VCAdditionalNamesProp ) |
237 | c.setMiddleName( value ); | 214 | c.setMiddleName( value ); |
238 | } | 215 | } |
239 | } | 216 | } |
240 | else if ( name == VCAdrProp ) { | 217 | else if ( name == VCAdrProp ) { |
241 | bool work = TRUE; // default address is work address | 218 | bool work = TRUE; // default address is work address |
242 | QString street; | 219 | QString street; |
243 | QString city; | 220 | QString city; |
244 | QString region; | 221 | QString region; |
245 | QString postal; | 222 | QString postal; |
246 | QString country; | 223 | QString country; |
247 | 224 | ||
248 | VObjectIterator nit; | 225 | VObjectIterator nit; |
249 | initPropIterator( &nit, o ); | 226 | initPropIterator( &nit, o ); |
250 | while( moreIteration( &nit ) ) { | 227 | while( moreIteration( &nit ) ) { |
251 | VObject *o = nextVObject( &nit ); | 228 | VObject *o = nextVObject( &nit ); |
252 | QCString name = vObjectName( o ); | 229 | QCString name = vObjectName( o ); |
253 | QString value = QString::fromUtf8( vObjectStringZValue( o ) ); | 230 | QString value = QString::fromUtf8( vObjectStringZValue( o ) ); |
254 | if ( name == VCHomeProp ) | 231 | if ( name == VCHomeProp ) |
255 | work = FALSE; | 232 | work = FALSE; |
256 | else if ( name == VCWorkProp ) | 233 | else if ( name == VCWorkProp ) |
257 | work = TRUE; | 234 | work = TRUE; |
258 | else if ( name == VCStreetAddressProp ) | 235 | else if ( name == VCStreetAddressProp ) |
259 | street = value; | 236 | street = value; |
260 | else if ( name == VCCityProp ) | 237 | else if ( name == VCCityProp ) |
261 | city = value; | 238 | city = value; |
262 | else if ( name == VCRegionProp ) | 239 | else if ( name == VCRegionProp ) |
263 | region = value; | 240 | region = value; |
264 | else if ( name == VCPostalCodeProp ) | 241 | else if ( name == VCPostalCodeProp ) |
265 | postal = value; | 242 | postal = value; |
266 | else if ( name == VCCountryNameProp ) | 243 | else if ( name == VCCountryNameProp ) |
267 | country = value; | 244 | country = value; |
268 | } | 245 | } |
269 | if ( work ) { | 246 | if ( work ) { |
270 | c.setBusinessStreet( street ); | 247 | c.setBusinessStreet( street ); |
271 | c.setBusinessCity( city ); | 248 | c.setBusinessCity( city ); |
272 | c.setBusinessCountry( country ); | 249 | c.setBusinessCountry( country ); |
273 | c.setBusinessZip( postal ); | 250 | c.setBusinessZip( postal ); |
274 | c.setBusinessState( region ); | 251 | c.setBusinessState( region ); |
275 | } else { | 252 | } else { |
276 | c.setHomeStreet( street ); | 253 | c.setHomeStreet( street ); |
277 | c.setHomeCity( city ); | 254 | c.setHomeCity( city ); |
278 | c.setHomeCountry( country ); | 255 | c.setHomeCountry( country ); |
279 | c.setHomeZip( postal ); | 256 | c.setHomeZip( postal ); |
280 | c.setHomeState( region ); | 257 | c.setHomeState( region ); |
281 | } | 258 | } |
282 | } | 259 | } |
283 | else if ( name == VCTelephoneProp ) { | 260 | else if ( name == VCTelephoneProp ) { |
284 | enum { | 261 | enum { |
285 | HOME = 0x01, | 262 | HOME = 0x01, |
286 | WORK = 0x02, | 263 | WORK = 0x02, |
287 | VOICE = 0x04, | 264 | VOICE = 0x04, |
288 | CELL = 0x08, | 265 | CELL = 0x08, |
289 | FAX = 0x10, | 266 | FAX = 0x10, |
290 | PAGER = 0x20, | 267 | PAGER = 0x20, |
291 | UNKNOWN = 0x80 | 268 | UNKNOWN = 0x80 |
292 | }; | 269 | }; |
293 | int type = 0; | 270 | int type = 0; |
294 | 271 | ||
295 | VObjectIterator nit; | 272 | VObjectIterator nit; |
296 | initPropIterator( &nit, o ); | 273 | initPropIterator( &nit, o ); |
297 | while( moreIteration( &nit ) ) { | 274 | while( moreIteration( &nit ) ) { |
298 | VObject *o = nextVObject( &nit ); | 275 | VObject *o = nextVObject( &nit ); |
299 | QCString name = vObjectTypeInfo( o ); | 276 | QCString name = vObjectTypeInfo( o ); |
300 | if ( name == VCHomeProp ) | 277 | if ( name == VCHomeProp ) |
301 | type |= HOME; | 278 | type |= HOME; |
302 | else if ( name == VCWorkProp ) | 279 | else if ( name == VCWorkProp ) |
303 | type |= WORK; | 280 | type |= WORK; |
304 | else if ( name == VCVoiceProp ) | 281 | else if ( name == VCVoiceProp ) |
305 | type |= VOICE; | 282 | type |= VOICE; |
306 | else if ( name == VCCellularProp ) | 283 | else if ( name == VCCellularProp ) |
307 | type |= CELL; | 284 | type |= CELL; |
308 | else if ( name == VCFaxProp ) | 285 | else if ( name == VCFaxProp ) |
309 | type |= FAX; | 286 | type |= FAX; |
310 | else if ( name == VCPagerProp ) | 287 | else if ( name == VCPagerProp ) |
311 | type |= PAGER; | 288 | type |= PAGER; |
312 | else if ( name == VCPreferredProp ) | 289 | else if ( name == VCPreferredProp ) |
313 | ; | 290 | ; |
314 | else | 291 | else |
315 | type |= UNKNOWN; | 292 | type |= UNKNOWN; |
316 | } | 293 | } |
317 | if ( (type & UNKNOWN) != UNKNOWN ) { | 294 | if ( (type & UNKNOWN) != UNKNOWN ) { |
318 | if ( ( type & (HOME|WORK) ) == 0 ) // default | 295 | if ( ( type & (HOME|WORK) ) == 0 ) // default |
319 | type |= HOME; | 296 | type |= HOME; |
320 | if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default | 297 | if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default |
321 | type |= VOICE; | 298 | type |= VOICE; |
322 | 299 | ||
323 | owarn << "value %s %d" << value.data() << type << oendl; | ||
324 | if ( (type & (VOICE|HOME) ) == (VOICE|HOME) && (type & (CELL|HOME) ) != (CELL|HOME) ) | 300 | if ( (type & (VOICE|HOME) ) == (VOICE|HOME) && (type & (CELL|HOME) ) != (CELL|HOME) ) |
325 | c.setHomePhone( value ); | 301 | c.setHomePhone( value ); |
326 | if ( ( type & (FAX|HOME) ) == (FAX|HOME) ) | 302 | if ( ( type & (FAX|HOME) ) == (FAX|HOME) ) |
327 | c.setHomeFax( value ); | 303 | c.setHomeFax( value ); |
328 | if ( ( type & (CELL|HOME) ) == (CELL|HOME) ) | 304 | if ( ( type & (CELL|HOME) ) == (CELL|HOME) ) |
329 | c.setHomeMobile( value ); | 305 | c.setHomeMobile( value ); |
330 | if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) && (type & (CELL|WORK) ) != (CELL|WORK) ) | 306 | if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) && (type & (CELL|WORK) ) != (CELL|WORK) ) |
331 | c.setBusinessPhone( value ); | 307 | c.setBusinessPhone( value ); |
332 | if ( ( type & (FAX|WORK) ) == (FAX|WORK) ) | 308 | if ( ( type & (FAX|WORK) ) == (FAX|WORK) ) |
333 | c.setBusinessFax( value ); | 309 | c.setBusinessFax( value ); |
334 | if ( ( type & (CELL|WORK) ) == (CELL|WORK) ) | 310 | if ( ( type & (CELL|WORK) ) == (CELL|WORK) ) |
335 | c.setBusinessMobile( value ); | 311 | c.setBusinessMobile( value ); |
336 | if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) ) | 312 | if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) ) |
337 | c.setBusinessPager( value ); | 313 | c.setBusinessPager( value ); |
338 | } | 314 | } |
339 | } | 315 | } |
340 | else if ( name == VCEmailAddressProp ) { | 316 | else if ( name == VCEmailAddressProp ) { |
341 | QString email = QString::fromUtf8( vObjectStringZValue( o ) ); | 317 | QString email = QString::fromUtf8( vObjectStringZValue( o ) ); |
342 | bool valid = TRUE; | 318 | bool valid = TRUE; |
343 | VObjectIterator nit; | 319 | VObjectIterator nit; |
344 | initPropIterator( &nit, o ); | 320 | initPropIterator( &nit, o ); |
345 | while( moreIteration( &nit ) ) { | 321 | while( moreIteration( &nit ) ) { |
346 | VObject *o = nextVObject( &nit ); | 322 | VObject *o = nextVObject( &nit ); |
347 | QCString name = vObjectTypeInfo( o ); | 323 | QCString name = vObjectTypeInfo( o ); |
348 | if ( name != VCInternetProp && name != VCHomeProp && | 324 | if ( name != VCInternetProp && name != VCHomeProp && |
349 | name != VCWorkProp && | 325 | name != VCWorkProp && |
350 | name != VCPreferredProp ) | 326 | name != VCPreferredProp ) |
351 | // ### preffered should map to default email | 327 | // ### preffered should map to default email |
352 | valid = FALSE; | 328 | valid = FALSE; |
353 | } | 329 | } |
354 | if ( valid ) { | 330 | if ( valid ) { |
355 | c.insertEmail( email ); | 331 | c.insertEmail( email ); |
356 | } | 332 | } |
357 | } | 333 | } |
358 | else if ( name == VCURLProp ) { | 334 | else if ( name == VCURLProp ) { |
359 | VObjectIterator nit; | 335 | VObjectIterator nit; |
360 | initPropIterator( &nit, o ); | 336 | initPropIterator( &nit, o ); |
361 | while( moreIteration( &nit ) ) { | 337 | while( moreIteration( &nit ) ) { |
362 | VObject *o = nextVObject( &nit ); | 338 | VObject *o = nextVObject( &nit ); |
363 | QCString name = vObjectTypeInfo( o ); | 339 | QCString name = vObjectTypeInfo( o ); |
364 | if ( name == VCHomeProp ) | 340 | if ( name == VCHomeProp ) |
365 | c.setHomeWebpage( value ); | 341 | c.setHomeWebpage( value ); |
366 | else if ( name == VCWorkProp ) | 342 | else if ( name == VCWorkProp ) |
367 | c.setBusinessWebpage( value ); | 343 | c.setBusinessWebpage( value ); |
368 | } | 344 | } |
369 | } | 345 | } |
370 | else if ( name == VCOrgProp ) { | 346 | else if ( name == VCOrgProp ) { |
371 | VObjectIterator nit; | 347 | VObjectIterator nit; |
372 | initPropIterator( &nit, o ); | 348 | initPropIterator( &nit, o ); |
373 | while( moreIteration( &nit ) ) { | 349 | while( moreIteration( &nit ) ) { |
374 | VObject *o = nextVObject( &nit ); | 350 | VObject *o = nextVObject( &nit ); |
375 | QCString name = vObjectName( o ); | 351 | QCString name = vObjectName( o ); |
376 | QString value = QString::fromUtf8( vObjectStringZValue( o ) ); | 352 | QString value = QString::fromUtf8( vObjectStringZValue( o ) ); |
377 | if ( name == VCOrgNameProp ) | 353 | if ( name == VCOrgNameProp ) |
378 | c.setCompany( value ); | 354 | c.setCompany( value ); |
379 | else if ( name == VCOrgUnitProp ) | 355 | else if ( name == VCOrgUnitProp ) |
380 | c.setDepartment( value ); | 356 | c.setDepartment( value ); |
381 | else if ( name == VCOrgUnit2Prop ) | 357 | else if ( name == VCOrgUnit2Prop ) |
382 | c.setOffice( value ); | 358 | c.setOffice( value ); |
383 | } | 359 | } |
384 | } | 360 | } |
385 | else if ( name == VCTitleProp ) { | 361 | else if ( name == VCTitleProp ) { |
386 | c.setJobTitle( value ); | 362 | c.setJobTitle( value ); |
387 | } | 363 | } |
388 | else if ( name == "X-Qtopia-Profession" ) { | 364 | else if ( name == "X-Qtopia-Profession" ) { |
389 | c.setProfession( value ); | 365 | c.setProfession( value ); |
390 | } | 366 | } |
391 | else if ( name == "X-Qtopia-Manager" ) { | 367 | else if ( name == "X-Qtopia-Manager" ) { |
392 | c.setManager( value ); | 368 | c.setManager( value ); |
393 | } | 369 | } |
394 | else if ( name == "X-Qtopia-Assistant" ) { | 370 | else if ( name == "X-Qtopia-Assistant" ) { |
395 | c.setAssistant( value ); | 371 | c.setAssistant( value ); |
396 | } | 372 | } |
397 | else if ( name == "X-Qtopia-Spouse" ) { | 373 | else if ( name == "X-Qtopia-Spouse" ) { |
398 | c.setSpouse( value ); | 374 | c.setSpouse( value ); |
399 | } | 375 | } |
400 | else if ( name == "X-Qtopia-Gender" ) { | 376 | else if ( name == "X-Qtopia-Gender" ) { |
401 | c.setGender( value ); | 377 | c.setGender( value ); |
402 | } | 378 | } |
403 | else if ( name == "X-Qtopia-Anniversary" ) { | 379 | else if ( name == "X-Qtopia-Anniversary" ) { |
404 | c.setAnniversary( convVCardDateToDate( value ) ); | 380 | c.setAnniversary( convVCardDateToDate( value ) ); |
405 | } | 381 | } |
406 | else if ( name == "X-Qtopia-Nickname" ) { | 382 | else if ( name == "X-Qtopia-Nickname" ) { |
407 | c.setNickname( value ); | 383 | c.setNickname( value ); |
408 | } | 384 | } |
409 | else if ( name == "X-Qtopia-Children" ) { | 385 | else if ( name == "X-Qtopia-Children" ) { |
410 | c.setChildren( value ); | 386 | c.setChildren( value ); |
411 | } | 387 | } |
412 | else if ( name == VCBirthDateProp ) { | 388 | else if ( name == VCBirthDateProp ) { |
413 | // Reading Birthdate regarding RFC 2425 (5.8.4) | 389 | // Reading Birthdate regarding RFC 2425 (5.8.4) |
414 | c.setBirthday( convVCardDateToDate( value ) ); | 390 | c.setBirthday( convVCardDateToDate( value ) ); |
415 | 391 | ||
416 | } | 392 | } |
417 | else if ( name == VCCommentProp ) { | 393 | else if ( name == VCCommentProp ) { |
418 | c.setNotes( value ); | 394 | c.setNotes( value ); |
419 | } | 395 | } |
420 | #if 0 | 396 | #if 0 |
421 | else { | 397 | else { |
422 | printf("Name: %s, value=%s\n", name.data(), QString::fromUtf8( vObjectStringZValue( o ) ) ); | 398 | printf("Name: %s, value=%s\n", name.data(), QString::fromUtf8( vObjectStringZValue( o ) ) ); |
423 | VObjectIterator nit; | 399 | VObjectIterator nit; |
424 | initPropIterator( &nit, o ); | 400 | initPropIterator( &nit, o ); |
425 | while( moreIteration( &nit ) ) { | 401 | while( moreIteration( &nit ) ) { |
426 | VObject *o = nextVObject( &nit ); | 402 | VObject *o = nextVObject( &nit ); |
427 | QCString name = vObjectName( o ); | 403 | QCString name = vObjectName( o ); |
428 | QString value = QString::fromUtf8( vObjectStringZValue( o ) ); | 404 | QString value = QString::fromUtf8( vObjectStringZValue( o ) ); |
429 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); | 405 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); |
430 | } | 406 | } |
431 | } | 407 | } |
432 | else { | 408 | else { |
433 | printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); | 409 | printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); |
434 | VObjectIterator nit; | 410 | VObjectIterator nit; |
435 | initPropIterator( &nit, o ); | 411 | initPropIterator( &nit, o ); |
436 | while( moreIteration( &nit ) ) { | 412 | while( moreIteration( &nit ) ) { |
437 | VObject *o = nextVObject( &nit ); | 413 | VObject *o = nextVObject( &nit ); |
438 | QCString name = vObjectName( o ); | 414 | QCString name = vObjectName( o ); |
439 | QString value = vObjectStringZValue( o ); | 415 | QString value = vObjectStringZValue( o ); |
440 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); | 416 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); |
441 | } | 417 | } |
442 | } | 418 | } |
443 | #endif | 419 | #endif |
444 | } | 420 | } |
445 | c.setFileAs(); | 421 | c.setFileAs(); |
446 | return c; | 422 | return c; |
447 | } | 423 | } |
448 | 424 | ||
449 | 425 | ||
450 | VObject* OPimContactAccessBackend_VCard::createVObject( const OPimContact &c ) | 426 | VObject* OPimContactAccessBackend_VCard::createVObject( const OPimContact &c ) |
451 | { | 427 | { |
452 | VObject *vcard = newVObject( VCCardProp ); | 428 | VObject *vcard = newVObject( VCCardProp ); |
453 | safeAddPropValue( vcard, VCVersionProp, "2.1" ); | 429 | safeAddPropValue( vcard, VCVersionProp, "2.1" ); |
454 | safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) ); | 430 | safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) ); |
455 | safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) ); | 431 | safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) ); |
456 | 432 | ||
457 | // full name | 433 | // full name |
458 | safeAddPropValue( vcard, VCFullNameProp, c.fullName() ); | 434 | safeAddPropValue( vcard, VCFullNameProp, c.fullName() ); |
459 | 435 | ||
460 | // name properties | 436 | // name properties |
461 | VObject *name = safeAddProp( vcard, VCNameProp ); | 437 | VObject *name = safeAddProp( vcard, VCNameProp ); |
462 | safeAddPropValue( name, VCFamilyNameProp, c.lastName() ); | 438 | safeAddPropValue( name, VCFamilyNameProp, c.lastName() ); |
463 | safeAddPropValue( name, VCGivenNameProp, c.firstName() ); | 439 | safeAddPropValue( name, VCGivenNameProp, c.firstName() ); |
464 | safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() ); | 440 | safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() ); |
465 | safeAddPropValue( name, VCNamePrefixesProp, c.title() ); | 441 | safeAddPropValue( name, VCNamePrefixesProp, c.title() ); |
466 | safeAddPropValue( name, VCNameSuffixesProp, c.suffix() ); | 442 | safeAddPropValue( name, VCNameSuffixesProp, c.suffix() ); |
467 | 443 | ||
468 | // home properties | 444 | // home properties |
469 | VObject *home_adr= safeAddProp( vcard, VCAdrProp ); | 445 | VObject *home_adr= safeAddProp( vcard, VCAdrProp ); |
470 | safeAddProp( home_adr, VCHomeProp ); | 446 | safeAddProp( home_adr, VCHomeProp ); |
471 | safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() ); | 447 | safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() ); |
472 | safeAddPropValue( home_adr, VCCityProp, c.homeCity() ); | 448 | safeAddPropValue( home_adr, VCCityProp, c.homeCity() ); |
473 | safeAddPropValue( home_adr, VCRegionProp, c.homeState() ); | 449 | safeAddPropValue( home_adr, VCRegionProp, c.homeState() ); |
474 | safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() ); | 450 | safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() ); |
475 | safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() ); | 451 | safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() ); |
476 | 452 | ||
477 | VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() ); | 453 | VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() ); |
478 | safeAddProp( home_phone, VCHomeProp ); | 454 | safeAddProp( home_phone, VCHomeProp ); |
479 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() ); | 455 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() ); |
480 | safeAddProp( home_phone, VCHomeProp ); | 456 | safeAddProp( home_phone, VCHomeProp ); |
481 | safeAddProp( home_phone, VCCellularProp ); | 457 | safeAddProp( home_phone, VCCellularProp ); |
482 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() ); | 458 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() ); |
483 | safeAddProp( home_phone, VCHomeProp ); | 459 | safeAddProp( home_phone, VCHomeProp ); |
484 | safeAddProp( home_phone, VCFaxProp ); | 460 | safeAddProp( home_phone, VCFaxProp ); |
485 | 461 | ||
486 | VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() ); | 462 | VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() ); |
487 | safeAddProp( url, VCHomeProp ); | 463 | safeAddProp( url, VCHomeProp ); |
488 | 464 | ||
489 | // work properties | 465 | // work properties |
490 | VObject *work_adr= safeAddProp( vcard, VCAdrProp ); | 466 | VObject *work_adr= safeAddProp( vcard, VCAdrProp ); |
491 | safeAddProp( work_adr, VCWorkProp ); | 467 | safeAddProp( work_adr, VCWorkProp ); |
492 | safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() ); | 468 | safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() ); |
493 | safeAddPropValue( work_adr, VCCityProp, c.businessCity() ); | 469 | safeAddPropValue( work_adr, VCCityProp, c.businessCity() ); |
494 | safeAddPropValue( work_adr, VCRegionProp, c.businessState() ); | 470 | safeAddPropValue( work_adr, VCRegionProp, c.businessState() ); |
495 | safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() ); | 471 | safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() ); |
496 | safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() ); | 472 | safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() ); |
497 | 473 | ||
498 | VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() ); | 474 | VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() ); |
499 | safeAddProp( work_phone, VCWorkProp ); | 475 | safeAddProp( work_phone, VCWorkProp ); |
500 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() ); | 476 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() ); |
501 | safeAddProp( work_phone, VCWorkProp ); | 477 | safeAddProp( work_phone, VCWorkProp ); |
502 | safeAddProp( work_phone, VCCellularProp ); | 478 | safeAddProp( work_phone, VCCellularProp ); |
503 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() ); | 479 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() ); |
504 | safeAddProp( work_phone, VCWorkProp ); | 480 | safeAddProp( work_phone, VCWorkProp ); |
505 | safeAddProp( work_phone, VCFaxProp ); | 481 | safeAddProp( work_phone, VCFaxProp ); |
506 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() ); | 482 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() ); |
507 | safeAddProp( work_phone, VCWorkProp ); | 483 | safeAddProp( work_phone, VCWorkProp ); |
508 | safeAddProp( work_phone, VCPagerProp ); | 484 | safeAddProp( work_phone, VCPagerProp ); |
509 | 485 | ||
510 | url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() ); | 486 | url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() ); |
511 | safeAddProp( url, VCWorkProp ); | 487 | safeAddProp( url, VCWorkProp ); |
512 | 488 | ||
513 | VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() ); | 489 | VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() ); |
514 | safeAddProp( title, VCWorkProp ); | 490 | safeAddProp( title, VCWorkProp ); |
515 | 491 | ||
516 | 492 | ||
517 | QStringList emails = c.emailList(); | 493 | QStringList emails = c.emailList(); |
518 | // emails.prepend( c.defaultEmail() ); Fix for bugreport #1045 | 494 | // emails.prepend( c.defaultEmail() ); Fix for bugreport #1045 |
519 | for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { | 495 | for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { |
520 | VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it ); | 496 | VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it ); |
521 | safeAddProp( email, VCInternetProp ); | 497 | safeAddProp( email, VCInternetProp ); |
522 | } | 498 | } |
523 | 499 | ||
524 | safeAddPropValue( vcard, VCNoteProp, c.notes() ); | 500 | safeAddPropValue( vcard, VCNoteProp, c.notes() ); |
525 | 501 | ||
526 | // Exporting Birthday regarding RFC 2425 (5.8.4) | 502 | // Exporting Birthday regarding RFC 2425 (5.8.4) |
527 | if ( c.birthday().isValid() ){ | 503 | if ( c.birthday().isValid() ){ |
528 | owarn << "Exporting birthday as: " << convDateToVCardDate( c.birthday() ) << "" << oendl; | ||
529 | safeAddPropValue( vcard, VCBirthDateProp, convDateToVCardDate( c.birthday() ) ); | 504 | safeAddPropValue( vcard, VCBirthDateProp, convDateToVCardDate( c.birthday() ) ); |
530 | } | 505 | } |
531 | 506 | ||
532 | if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) { | 507 | if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) { |
533 | VObject *org = safeAddProp( vcard, VCOrgProp ); | 508 | VObject *org = safeAddProp( vcard, VCOrgProp ); |
534 | safeAddPropValue( org, VCOrgNameProp, c.company() ); | 509 | safeAddPropValue( org, VCOrgNameProp, c.company() ); |
535 | safeAddPropValue( org, VCOrgUnitProp, c.department() ); | 510 | safeAddPropValue( org, VCOrgUnitProp, c.department() ); |
536 | safeAddPropValue( org, VCOrgUnit2Prop, c.office() ); | 511 | safeAddPropValue( org, VCOrgUnit2Prop, c.office() ); |
537 | } | 512 | } |
538 | 513 | ||
539 | // some values we have to export as custom fields | 514 | // some values we have to export as custom fields |
540 | safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() ); | 515 | safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() ); |
541 | safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() ); | 516 | safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() ); |
542 | safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() ); | 517 | safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() ); |
543 | 518 | ||
544 | safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() ); | 519 | safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() ); |
545 | safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() ); | 520 | safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() ); |
546 | if ( c.anniversary().isValid() ){ | 521 | if ( c.anniversary().isValid() ){ |
547 | owarn << "Exporting anniversary as: " << convDateToVCardDate( c.anniversary() ) << "" << oendl; | ||
548 | safeAddPropValue( vcard, "X-Qtopia-Anniversary", convDateToVCardDate( c.anniversary() ) ); | 522 | safeAddPropValue( vcard, "X-Qtopia-Anniversary", convDateToVCardDate( c.anniversary() ) ); |
549 | } | 523 | } |
550 | safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() ); | 524 | safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() ); |
551 | safeAddPropValue( vcard, "X-Qtopia-Children", c.children() ); | 525 | safeAddPropValue( vcard, "X-Qtopia-Children", c.children() ); |
552 | 526 | ||
553 | return vcard; | 527 | return vcard; |
554 | } | 528 | } |
555 | 529 | ||
556 | QString OPimContactAccessBackend_VCard::convDateToVCardDate( const QDate& d ) const | 530 | QString OPimContactAccessBackend_VCard::convDateToVCardDate( const QDate& d ) const |
557 | { | 531 | { |
558 | QString str_rfc2425 = QString("%1-%2-%3") | 532 | QString str_rfc2425 = QString("%1-%2-%3") |
559 | .arg( d.year() ) | 533 | .arg( d.year() ) |
560 | .arg( d.month(), 2 ) | 534 | .arg( d.month(), 2 ) |
561 | .arg( d.day(), 2 ); | 535 | .arg( d.day(), 2 ); |
562 | // Now replace spaces with "0"... | 536 | // Now replace spaces with "0"... |
563 | int pos = 0; | 537 | int pos = 0; |
564 | while ( ( pos = str_rfc2425.find (' ') ) > 0 ) | 538 | while ( ( pos = str_rfc2425.find (' ') ) > 0 ) |
565 | str_rfc2425.replace( pos, 1, "0" ); | 539 | str_rfc2425.replace( pos, 1, "0" ); |
566 | 540 | ||
567 | return str_rfc2425; | 541 | return str_rfc2425; |
568 | } | 542 | } |
569 | 543 | ||
570 | QDate OPimContactAccessBackend_VCard::convVCardDateToDate( const QString& datestr ) | 544 | QDate OPimContactAccessBackend_VCard::convVCardDateToDate( const QString& datestr ) |
571 | { | 545 | { |
572 | int monthPos = datestr.find('-'); | 546 | int monthPos = datestr.find('-'); |
573 | int dayPos = datestr.find('-', monthPos+1 ); | 547 | int dayPos = datestr.find('-', monthPos+1 ); |
574 | int sep_ignore = 1; | 548 | int sep_ignore = 1; |
575 | if ( monthPos == -1 || dayPos == -1 ) { | 549 | if ( monthPos == -1 || dayPos == -1 ) { |
576 | odebug << "fromString didn't find - in str = " << datestr << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl; | 550 | odebug << "fromString didn't find - in str = " << datestr << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl; |
577 | // Ok.. No "-" found, therefore we will try to read other format ( YYYYMMDD ) | 551 | // Ok.. No "-" found, therefore we will try to read other format ( YYYYMMDD ) |
578 | if ( datestr.length() == 8 ){ | 552 | if ( datestr.length() == 8 ){ |
579 | monthPos = 4; | 553 | monthPos = 4; |
580 | dayPos = 6; | 554 | dayPos = 6; |
581 | sep_ignore = 0; | 555 | sep_ignore = 0; |
582 | odebug << "Try with follwing positions str = " << datestr << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl; | 556 | odebug << "Try with follwing positions str = " << datestr << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl; |
583 | } else { | 557 | } else { |
584 | return QDate(); | 558 | return QDate(); |
585 | } | 559 | } |
586 | } | 560 | } |
587 | int y = datestr.left( monthPos ).toInt(); | 561 | int y = datestr.left( monthPos ).toInt(); |
588 | int m = datestr.mid( monthPos + sep_ignore, dayPos - monthPos - sep_ignore ).toInt(); | 562 | int m = datestr.mid( monthPos + sep_ignore, dayPos - monthPos - sep_ignore ).toInt(); |
589 | int d = datestr.mid( dayPos + sep_ignore ).toInt(); | 563 | int d = datestr.mid( dayPos + sep_ignore ).toInt(); |
590 | odebug << "TimeConversion::fromString ymd = " << datestr << " => " << y << " " << m << " " << d << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl; | 564 | odebug << "TimeConversion::fromString ymd = " << datestr << " => " << y << " " << m << " " << d << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl; |
591 | QDate date ( y,m,d ); | 565 | QDate date ( y,m,d ); |
592 | return date; | 566 | return date; |
593 | } | 567 | } |
594 | 568 | ||
595 | VObject* OPimContactAccessBackend_VCard::safeAddPropValue( VObject *o, const char *prop, const QString &value ) | 569 | VObject* OPimContactAccessBackend_VCard::safeAddPropValue( VObject *o, const char *prop, const QString &value ) |
596 | { | 570 | { |
597 | VObject *ret = 0; | 571 | VObject *ret = 0; |
598 | if ( o && !value.isEmpty() ) | 572 | if ( o && !value.isEmpty() ) |
599 | ret = addPropValue( o, prop, value.utf8() ); | 573 | ret = addPropValue( o, prop, value.utf8() ); |
600 | return ret; | 574 | return ret; |
601 | } | 575 | } |
602 | 576 | ||
603 | VObject* OPimContactAccessBackend_VCard::safeAddProp( VObject *o, const char *prop) | 577 | VObject* OPimContactAccessBackend_VCard::safeAddProp( VObject *o, const char *prop) |
604 | { | 578 | { |
605 | VObject *ret = 0; | 579 | VObject *ret = 0; |
606 | if ( o ) | 580 | if ( o ) |
607 | ret = addProp( o, prop ); | 581 | ret = addProp( o, prop ); |
608 | return ret; | 582 | return ret; |
609 | } | 583 | } |
610 | 584 | ||
611 | } | 585 | } |
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h index 2a786af..1faf747 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h | |||
@@ -1,85 +1,82 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) The Main Author <main-author@whereever.org> | 3 | Copyright (C) The Main Author <main-author@whereever.org> |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | /* | 29 | /* |
30 | * VCard Backend for the OPIE-Contact Database. | 30 | * VCard Backend for the OPIE-Contact Database. |
31 | */ | 31 | */ |
32 | #ifndef __OCONTACTACCESSBACKEND_VCARD_H_ | 32 | #ifndef __OCONTACTACCESSBACKEND_VCARD_H_ |
33 | #define __OCONTACTACCESSBACKEND_VCARD_H_ | 33 | #define __OCONTACTACCESSBACKEND_VCARD_H_ |
34 | 34 | ||
35 | #include <opie2/opimcontact.h> | 35 | #include <opie2/opimcontact.h> |
36 | 36 | ||
37 | #include <opie2/ocontactaccessbackend.h> | 37 | #include <opie2/ocontactaccessbackend.h> |
38 | 38 | ||
39 | class VObject; | 39 | class VObject; |
40 | 40 | ||
41 | namespace Opie { | 41 | namespace Opie { |
42 | /** | 42 | /** |
43 | * This is the vCard 2.1 implementation of the Contact Storage | 43 | * This is the vCard 2.1 implementation of the Contact Storage |
44 | * @see OPimContactAccessBackend_XML | 44 | * @see OPimContactAccessBackend_XML |
45 | * @see OPimAccessBackend | 45 | * @see OPimAccessBackend |
46 | */ | 46 | */ |
47 | class OPimContactAccessBackend_VCard : public OPimContactAccessBackend { | 47 | class OPimContactAccessBackend_VCard : public OPimContactAccessBackend { |
48 | public: | 48 | public: |
49 | OPimContactAccessBackend_VCard ( const QString& appname, const QString& filename = QString::null ); | 49 | OPimContactAccessBackend_VCard ( const QString& appname, const QString& filename = QString::null ); |
50 | 50 | ||
51 | bool load (); | 51 | bool load (); |
52 | bool reload(); | 52 | bool reload(); |
53 | bool save(); | 53 | bool save(); |
54 | void clear (); | 54 | void clear (); |
55 | 55 | ||
56 | bool add ( const OPimContact& newcontact ); | 56 | bool add ( const OPimContact& newcontact ); |
57 | bool remove ( int uid ); | 57 | bool remove ( int uid ); |
58 | bool replace ( const OPimContact& contact ); | 58 | bool replace ( const OPimContact& contact ); |
59 | 59 | ||
60 | OPimContact find ( int uid ) const; | 60 | OPimContact find ( int uid ) const; |
61 | QArray<int> allRecords() const; | 61 | QArray<int> allRecords() const; |
62 | QArray<int> queryByExample ( const OPimContact &query, int settings, const QDateTime& d = QDateTime() ); | ||
63 | QArray<int> matchRegexp( const QRegExp &r ) const; | ||
64 | 62 | ||
65 | const uint querySettings(); | 63 | const uint querySettings(); |
66 | bool hasQuerySettings (uint querySettings) const; | 64 | bool hasQuerySettings (uint querySettings) const; |
67 | QArray<int> sorted( bool ascending, int sortOrder, int sortFilter, int cat ); | ||
68 | bool wasChangedExternally(); | 65 | bool wasChangedExternally(); |
69 | 66 | ||
70 | private: | 67 | private: |
71 | OPimContact parseVObject( VObject* obj ); | 68 | OPimContact parseVObject( VObject* obj ); |
72 | VObject* createVObject( const OPimContact& c ); | 69 | VObject* createVObject( const OPimContact& c ); |
73 | QString convDateToVCardDate( const QDate& c ) const; | 70 | QString convDateToVCardDate( const QDate& c ) const; |
74 | QDate convVCardDateToDate( const QString& datestr ); | 71 | QDate convVCardDateToDate( const QString& datestr ); |
75 | VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value ); | 72 | VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value ); |
76 | VObject *safeAddProp( VObject* o, const char* prop); | 73 | VObject *safeAddProp( VObject* o, const char* prop); |
77 | 74 | ||
78 | bool m_dirty : 1; | 75 | bool m_dirty : 1; |
79 | QString m_file; | 76 | QString m_file; |
80 | QMap<int, OPimContact> m_map; | 77 | QMap<int, OPimContact> m_map; |
81 | }; | 78 | }; |
82 | 79 | ||
83 | } | 80 | } |
84 | 81 | ||
85 | #endif | 82 | #endif |
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp index 18113c2..5df7253 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp | |||
@@ -1,750 +1,729 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | /* | 29 | /* |
30 | * XML Backend for the OPIE-Contact Database. | 30 | * XML Backend for the OPIE-Contact Database. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | 33 | ||
34 | /* OPIE */ | 34 | /* OPIE */ |
35 | #include <opie2/ocontactaccessbackend_xml.h> | 35 | #include <opie2/ocontactaccessbackend_xml.h> |
36 | #include <opie2/xmltree.h> | 36 | #include <opie2/xmltree.h> |
37 | #include <opie2/ocontactaccessbackend.h> | 37 | #include <opie2/ocontactaccessbackend.h> |
38 | #include <opie2/ocontactaccess.h> | 38 | #include <opie2/ocontactaccess.h> |
39 | #include <opie2/odebug.h> | 39 | #include <opie2/odebug.h> |
40 | 40 | ||
41 | #include <qpe/global.h> | 41 | #include <qpe/global.h> |
42 | 42 | ||
43 | /* QT */ | 43 | /* QT */ |
44 | #include <qasciidict.h> | 44 | #include <qasciidict.h> |
45 | #include <qfile.h> | 45 | #include <qfile.h> |
46 | #include <qfileinfo.h> | 46 | #include <qfileinfo.h> |
47 | #include <qregexp.h> | 47 | #include <qregexp.h> |
48 | #include <qarray.h> | 48 | #include <qarray.h> |
49 | #include <qmap.h> | 49 | #include <qmap.h> |
50 | 50 | ||
51 | /* STD */ | 51 | /* STD */ |
52 | #include <stdlib.h> | 52 | #include <stdlib.h> |
53 | #include <errno.h> | 53 | #include <errno.h> |
54 | 54 | ||
55 | using namespace Opie::Core; | 55 | using namespace Opie::Core; |
56 | 56 | ||
57 | 57 | ||
58 | namespace Opie { | 58 | namespace Opie { |
59 | OPimContactAccessBackend_XML::OPimContactAccessBackend_XML ( const QString& appname, const QString& filename ): | 59 | OPimContactAccessBackend_XML::OPimContactAccessBackend_XML ( const QString& appname, const QString& filename ): |
60 | m_changed( false ) | 60 | m_changed( false ) |
61 | { | 61 | { |
62 | // Just m_contactlist should call delete if an entry | 62 | // Just m_contactlist should call delete if an entry |
63 | // is removed. | 63 | // is removed. |
64 | m_contactList.setAutoDelete( true ); | 64 | m_contactList.setAutoDelete( true ); |
65 | m_uidToContact.setAutoDelete( false ); | 65 | m_uidToContact.setAutoDelete( false ); |
66 | 66 | ||
67 | m_appName = appname; | 67 | m_appName = appname; |
68 | 68 | ||
69 | /* Set journalfile name ... */ | 69 | /* Set journalfile name ... */ |
70 | m_journalName = getenv("HOME"); | 70 | m_journalName = getenv("HOME"); |
71 | m_journalName +="/.abjournal" + appname; | 71 | m_journalName +="/.abjournal" + appname; |
72 | 72 | ||
73 | /* Expecting to access the default filename if nothing else is set */ | 73 | /* Expecting to access the default filename if nothing else is set */ |
74 | if ( filename.isEmpty() ){ | 74 | if ( filename.isEmpty() ){ |
75 | m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); | 75 | m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); |
76 | } else | 76 | } else |
77 | m_fileName = filename; | 77 | m_fileName = filename; |
78 | 78 | ||
79 | /* Load Database now */ | 79 | /* Load Database now */ |
80 | load (); | 80 | load (); |
81 | } | 81 | } |
82 | 82 | ||
83 | bool OPimContactAccessBackend_XML::save() | 83 | bool OPimContactAccessBackend_XML::save() |
84 | { | 84 | { |
85 | 85 | ||
86 | if ( !m_changed ) | 86 | if ( !m_changed ) |
87 | return true; | 87 | return true; |
88 | 88 | ||
89 | QString strNewFile = m_fileName + ".new"; | 89 | QString strNewFile = m_fileName + ".new"; |
90 | QFile f( strNewFile ); | 90 | QFile f( strNewFile ); |
91 | if ( !f.open( IO_WriteOnly|IO_Raw ) ) | 91 | if ( !f.open( IO_WriteOnly|IO_Raw ) ) |
92 | return false; | 92 | return false; |
93 | 93 | ||
94 | int total_written; | 94 | int total_written; |
95 | int idx_offset = 0; | 95 | int idx_offset = 0; |
96 | QString out; | 96 | QString out; |
97 | 97 | ||
98 | // Write Header | 98 | // Write Header |
99 | out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" | 99 | out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" |
100 | " <Groups>\n" | 100 | " <Groups>\n" |
101 | " </Groups>\n" | 101 | " </Groups>\n" |
102 | " <Contacts>\n"; | 102 | " <Contacts>\n"; |
103 | QCString cstr = out.utf8(); | 103 | QCString cstr = out.utf8(); |
104 | f.writeBlock( cstr.data(), cstr.length() ); | 104 | f.writeBlock( cstr.data(), cstr.length() ); |
105 | idx_offset += cstr.length(); | 105 | idx_offset += cstr.length(); |
106 | out = ""; | 106 | out = ""; |
107 | 107 | ||
108 | // Write all contacts | 108 | // Write all contacts |
109 | QListIterator<OPimContact> it( m_contactList ); | 109 | QListIterator<OPimContact> it( m_contactList ); |
110 | for ( ; it.current(); ++it ) { | 110 | for ( ; it.current(); ++it ) { |
111 | // owarn << " Uid " << (*it)->uid() << " at Offset: " << idx_offset << "" << oendl; | ||
112 | out += "<Contact "; | 111 | out += "<Contact "; |
113 | (*it)->save( out ); | 112 | (*it)->save( out ); |
114 | out += "/>\n"; | 113 | out += "/>\n"; |
115 | cstr = out.utf8(); | 114 | cstr = out.utf8(); |
116 | total_written = f.writeBlock( cstr.data(), cstr.length() ); | 115 | total_written = f.writeBlock( cstr.data(), cstr.length() ); |
117 | idx_offset += cstr.length(); | 116 | idx_offset += cstr.length(); |
118 | if ( total_written != int(cstr.length()) ) { | 117 | if ( total_written != int(cstr.length()) ) { |
119 | f.close(); | 118 | f.close(); |
120 | QFile::remove( strNewFile ); | 119 | QFile::remove( strNewFile ); |
121 | return false; | 120 | return false; |
122 | } | 121 | } |
123 | out = ""; | 122 | out = ""; |
124 | } | 123 | } |
125 | out += " </Contacts>\n</AddressBook>\n"; | 124 | out += " </Contacts>\n</AddressBook>\n"; |
126 | 125 | ||
127 | // Write Footer | 126 | // Write Footer |
128 | cstr = out.utf8(); | 127 | cstr = out.utf8(); |
129 | total_written = f.writeBlock( cstr.data(), cstr.length() ); | 128 | total_written = f.writeBlock( cstr.data(), cstr.length() ); |
130 | if ( total_written != int( cstr.length() ) ) { | 129 | if ( total_written != int( cstr.length() ) ) { |
131 | f.close(); | 130 | f.close(); |
132 | QFile::remove( strNewFile ); | 131 | QFile::remove( strNewFile ); |
133 | return false; | 132 | return false; |
134 | } | 133 | } |
135 | f.close(); | 134 | f.close(); |
136 | 135 | ||
137 | // move the file over, I'm just going to use the system call | 136 | // move the file over, I'm just going to use the system call |
138 | // because, I don't feel like using QDir. | 137 | // because, I don't feel like using QDir. |
139 | if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { | 138 | if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { |
140 | owarn << "problem renaming file " << strNewFile << " to " << m_journalName | ||
141 | << ", errno: " << errno << oendl; | ||
142 | // remove the tmp file... | 139 | // remove the tmp file... |
143 | QFile::remove( strNewFile ); | 140 | QFile::remove( strNewFile ); |
144 | } | 141 | } |
145 | 142 | ||
146 | /* The journalfile should be removed now... */ | 143 | /* The journalfile should be removed now... */ |
147 | removeJournal(); | 144 | removeJournal(); |
148 | 145 | ||
149 | m_changed = false; | 146 | m_changed = false; |
150 | return true; | 147 | return true; |
151 | } | 148 | } |
152 | 149 | ||
153 | bool OPimContactAccessBackend_XML::load () | 150 | bool OPimContactAccessBackend_XML::load () |
154 | { | 151 | { |
155 | m_contactList.clear(); | 152 | m_contactList.clear(); |
156 | m_uidToContact.clear(); | 153 | m_uidToContact.clear(); |
157 | 154 | ||
158 | /* Load XML-File and journal if it exists */ | 155 | /* Load XML-File and journal if it exists */ |
159 | if ( !load ( m_fileName, false ) ) | 156 | if ( !load ( m_fileName, false ) ) |
160 | return false; | 157 | return false; |
161 | /* The returncode of the journalfile is ignored due to the | 158 | /* The returncode of the journalfile is ignored due to the |
162 | * fact that it does not exist when this class is instantiated ! | 159 | * fact that it does not exist when this class is instantiated ! |
163 | * But there may such a file exist, if the application crashed. | 160 | * But there may such a file exist, if the application crashed. |
164 | * Therefore we try to load it to get the changes before the # | 161 | * Therefore we try to load it to get the changes before the # |
165 | * crash happened... | 162 | * crash happened... |
166 | */ | 163 | */ |
167 | load (m_journalName, true); | 164 | load (m_journalName, true); |
168 | 165 | ||
169 | return true; | 166 | return true; |
170 | } | 167 | } |
171 | 168 | ||
172 | void OPimContactAccessBackend_XML::clear () | 169 | void OPimContactAccessBackend_XML::clear () |
173 | { | 170 | { |
174 | m_contactList.clear(); | 171 | m_contactList.clear(); |
175 | m_uidToContact.clear(); | 172 | m_uidToContact.clear(); |
176 | 173 | ||
177 | m_changed = false; | 174 | m_changed = false; |
178 | } | 175 | } |
179 | 176 | ||
180 | bool OPimContactAccessBackend_XML::wasChangedExternally() | 177 | bool OPimContactAccessBackend_XML::wasChangedExternally() |
181 | { | 178 | { |
182 | QFileInfo fi( m_fileName ); | 179 | QFileInfo fi( m_fileName ); |
183 | 180 | ||
184 | QDateTime lastmod = fi.lastModified (); | 181 | QDateTime lastmod = fi.lastModified (); |
185 | 182 | ||
186 | return (lastmod != m_readtime); | 183 | return (lastmod != m_readtime); |
187 | } | 184 | } |
188 | 185 | ||
189 | QArray<int> OPimContactAccessBackend_XML::allRecords() const | 186 | QArray<int> OPimContactAccessBackend_XML::allRecords() const |
190 | { | 187 | { |
191 | QArray<int> uid_list( m_contactList.count() ); | 188 | QArray<int> uid_list( m_contactList.count() ); |
192 | 189 | ||
193 | uint counter = 0; | 190 | uint counter = 0; |
194 | QListIterator<OPimContact> it( m_contactList ); | 191 | QListIterator<OPimContact> it( m_contactList ); |
195 | for( ; it.current(); ++it ){ | 192 | for( ; it.current(); ++it ){ |
196 | uid_list[counter++] = (*it)->uid(); | 193 | uid_list[counter++] = (*it)->uid(); |
197 | } | 194 | } |
198 | 195 | ||
199 | return ( uid_list ); | 196 | return ( uid_list ); |
200 | } | 197 | } |
201 | 198 | ||
202 | OPimContact OPimContactAccessBackend_XML::find ( int uid ) const | 199 | OPimContact OPimContactAccessBackend_XML::find ( int uid ) const |
203 | { | 200 | { |
204 | OPimContact foundContact; //Create empty contact | 201 | OPimContact foundContact; //Create empty contact |
205 | 202 | ||
206 | OPimContact* found = m_uidToContact.find( QString().setNum( uid ) ); | 203 | OPimContact* found = m_uidToContact.find( QString().setNum( uid ) ); |
207 | 204 | ||
208 | if ( found ){ | 205 | if ( found ){ |
209 | foundContact = *found; | 206 | foundContact = *found; |
210 | } | 207 | } |
211 | 208 | ||
212 | return ( foundContact ); | 209 | return ( foundContact ); |
213 | } | 210 | } |
214 | 211 | ||
215 | QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings, | 212 | QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings, |
216 | const QDateTime& d ) | 213 | const QDateTime& d )const |
217 | { | 214 | { |
218 | |||
219 | QArray<int> m_currentQuery( m_contactList.count() ); | 215 | QArray<int> m_currentQuery( m_contactList.count() ); |
220 | QListIterator<OPimContact> it( m_contactList ); | 216 | QListIterator<OPimContact> it( m_contactList ); |
221 | uint arraycounter = 0; | 217 | uint arraycounter = 0; |
222 | 218 | ||
223 | for( ; it.current(); ++it ){ | 219 | for( ; it.current(); ++it ){ |
224 | /* Search all fields and compare them with query object. Store them into list | 220 | /* Search all fields and compare them with query object. Store them into list |
225 | * if all fields matches. | 221 | * if all fields matches. |
226 | */ | 222 | */ |
227 | QDate* queryDate = 0l; | 223 | QDate* queryDate = 0l; |
228 | QDate* checkDate = 0l; | 224 | QDate* checkDate = 0l; |
229 | bool allcorrect = true; | 225 | bool allcorrect = true; |
230 | for ( int i = 0; i < Qtopia::Groups; i++ ) { | 226 | for ( int i = 0; i < Qtopia::Groups; i++ ) { |
231 | // Birthday and anniversary are special nonstring fields and should | 227 | // Birthday and anniversary are special nonstring fields and should |
232 | // be handled specially | 228 | // be handled specially |
233 | switch ( i ){ | 229 | switch ( i ){ |
234 | case Qtopia::Birthday: | 230 | case Qtopia::Birthday: |
235 | queryDate = new QDate( query.birthday() ); | 231 | queryDate = new QDate( query.birthday() ); |
236 | checkDate = new QDate( (*it)->birthday() ); | 232 | checkDate = new QDate( (*it)->birthday() ); |
237 | // fall through | 233 | // fall through |
238 | case Qtopia::Anniversary: | 234 | case Qtopia::Anniversary: |
239 | if ( queryDate == 0l ){ | 235 | if ( queryDate == 0l ){ |
240 | queryDate = new QDate( query.anniversary() ); | 236 | queryDate = new QDate( query.anniversary() ); |
241 | checkDate = new QDate( (*it)->anniversary() ); | 237 | checkDate = new QDate( (*it)->anniversary() ); |
242 | } | 238 | } |
243 | 239 | ||
244 | if ( queryDate->isValid() ){ | 240 | if ( queryDate->isValid() ){ |
245 | if( checkDate->isValid() ){ | 241 | if( checkDate->isValid() ){ |
246 | if ( settings & OPimContactAccess::DateYear ){ | 242 | if ( settings & OPimContactAccess::DateYear ){ |
247 | if ( queryDate->year() != checkDate->year() ) | 243 | if ( queryDate->year() != checkDate->year() ) |
248 | allcorrect = false; | 244 | allcorrect = false; |
249 | } | 245 | } |
250 | if ( settings & OPimContactAccess::DateMonth ){ | 246 | if ( settings & OPimContactAccess::DateMonth ){ |
251 | if ( queryDate->month() != checkDate->month() ) | 247 | if ( queryDate->month() != checkDate->month() ) |
252 | allcorrect = false; | 248 | allcorrect = false; |
253 | } | 249 | } |
254 | if ( settings & OPimContactAccess::DateDay ){ | 250 | if ( settings & OPimContactAccess::DateDay ){ |
255 | if ( queryDate->day() != checkDate->day() ) | 251 | if ( queryDate->day() != checkDate->day() ) |
256 | allcorrect = false; | 252 | allcorrect = false; |
257 | } | 253 | } |
258 | if ( settings & OPimContactAccess::DateDiff ) { | 254 | if ( settings & OPimContactAccess::DateDiff ) { |
259 | QDate current; | 255 | QDate current; |
260 | // If we get an additional date, we | 256 | // If we get an additional date, we |
261 | // will take this date instead of | 257 | // will take this date instead of |
262 | // the current one.. | 258 | // the current one.. |
263 | if ( !d.date().isValid() ) | 259 | if ( !d.date().isValid() ) |
264 | current = QDate::currentDate(); | 260 | current = QDate::currentDate(); |
265 | else | 261 | else |
266 | current = d.date(); | 262 | current = d.date(); |
267 | 263 | ||
268 | // We have to equalize the year, otherwise | 264 | // We have to equalize the year, otherwise |
269 | // the search will fail.. | 265 | // the search will fail.. |
270 | checkDate->setYMD( current.year(), | 266 | checkDate->setYMD( current.year(), |
271 | checkDate->month(), | 267 | checkDate->month(), |
272 | checkDate->day() ); | 268 | checkDate->day() ); |
273 | if ( *checkDate < current ) | 269 | if ( *checkDate < current ) |
274 | checkDate->setYMD( current.year()+1, | 270 | checkDate->setYMD( current.year()+1, |
275 | checkDate->month(), | 271 | checkDate->month(), |
276 | checkDate->day() ); | 272 | checkDate->day() ); |
277 | 273 | ||
278 | // Check whether the birthday/anniversary date is between | 274 | // Check whether the birthday/anniversary date is between |
279 | // the current/given date and the maximum date | 275 | // the current/given date and the maximum date |
280 | // ( maximum time range ) ! | 276 | // ( maximum time range ) ! |
281 | owarn << "Checking if " << checkDate->toString() << " is between " << current.toString() | ||
282 | << " and " << queryDate->toString() << " ! " << oendl; | ||
283 | if ( current.daysTo( *queryDate ) >= 0 ){ | 277 | if ( current.daysTo( *queryDate ) >= 0 ){ |
284 | if ( !( ( *checkDate >= current ) && | 278 | if ( !( ( *checkDate >= current ) && |
285 | ( *checkDate <= *queryDate ) ) ){ | 279 | ( *checkDate <= *queryDate ) ) ){ |
286 | allcorrect = false; | 280 | allcorrect = false; |
287 | owarn << " Nope!.." << oendl; | ||
288 | } | 281 | } |
289 | } | 282 | } |
290 | } | 283 | } |
291 | } else{ | 284 | } else{ |
292 | // checkDate is invalid. Therefore this entry is always rejected | 285 | // checkDate is invalid. Therefore this entry is always rejected |
293 | allcorrect = false; | 286 | allcorrect = false; |
294 | } | 287 | } |
295 | } | 288 | } |
296 | 289 | ||
297 | delete queryDate; | 290 | delete queryDate; |
298 | queryDate = 0l; | 291 | queryDate = 0l; |
299 | delete checkDate; | 292 | delete checkDate; |
300 | checkDate = 0l; | 293 | checkDate = 0l; |
301 | break; | 294 | break; |
302 | default: | 295 | default: |
303 | /* Just compare fields which are not empty in the query object */ | 296 | /* Just compare fields which are not empty in the query object */ |
304 | if ( !query.field(i).isEmpty() ){ | 297 | if ( !query.field(i).isEmpty() ){ |
305 | switch ( settings & ~( OPimContactAccess::IgnoreCase | 298 | switch ( settings & ~( OPimContactAccess::IgnoreCase |
306 | | OPimContactAccess::DateDiff | 299 | | OPimContactAccess::DateDiff |
307 | | OPimContactAccess::DateYear | 300 | | OPimContactAccess::DateYear |
308 | | OPimContactAccess::DateMonth | 301 | | OPimContactAccess::DateMonth |
309 | | OPimContactAccess::DateDay | 302 | | OPimContactAccess::DateDay |
310 | | OPimContactAccess::MatchOne | 303 | | OPimContactAccess::MatchOne |
311 | ) ){ | 304 | ) ){ |
312 | 305 | ||
313 | case OPimContactAccess::RegExp:{ | 306 | case OPimContactAccess::RegExp:{ |
314 | QRegExp expr ( query.field(i), | 307 | QRegExp expr ( query.field(i), |
315 | !(settings & OPimContactAccess::IgnoreCase), | 308 | !(settings & OPimContactAccess::IgnoreCase), |
316 | false ); | 309 | false ); |
317 | if ( expr.find ( (*it)->field(i), 0 ) == -1 ) | 310 | if ( expr.find ( (*it)->field(i), 0 ) == -1 ) |
318 | allcorrect = false; | 311 | allcorrect = false; |
319 | } | 312 | } |
320 | break; | 313 | break; |
321 | case OPimContactAccess::WildCards:{ | 314 | case OPimContactAccess::WildCards:{ |
322 | QRegExp expr ( query.field(i), | 315 | QRegExp expr ( query.field(i), |
323 | !(settings & OPimContactAccess::IgnoreCase), | 316 | !(settings & OPimContactAccess::IgnoreCase), |
324 | true ); | 317 | true ); |
325 | if ( expr.find ( (*it)->field(i), 0 ) == -1 ) | 318 | if ( expr.find ( (*it)->field(i), 0 ) == -1 ) |
326 | allcorrect = false; | 319 | allcorrect = false; |
327 | } | 320 | } |
328 | break; | 321 | break; |
329 | case OPimContactAccess::ExactMatch:{ | 322 | case OPimContactAccess::ExactMatch:{ |
330 | if (settings & OPimContactAccess::IgnoreCase){ | 323 | if (settings & OPimContactAccess::IgnoreCase){ |
331 | if ( query.field(i).upper() != | 324 | if ( query.field(i).upper() != |
332 | (*it)->field(i).upper() ) | 325 | (*it)->field(i).upper() ) |
333 | allcorrect = false; | 326 | allcorrect = false; |
334 | }else{ | 327 | }else{ |
335 | if ( query.field(i) != (*it)->field(i) ) | 328 | if ( query.field(i) != (*it)->field(i) ) |
336 | allcorrect = false; | 329 | allcorrect = false; |
337 | } | 330 | } |
338 | } | 331 | } |
339 | break; | 332 | break; |
340 | } | 333 | } |
341 | } | 334 | } |
342 | } | 335 | } |
343 | } | 336 | } |
344 | if ( allcorrect ){ | 337 | if ( allcorrect ){ |
345 | m_currentQuery[arraycounter++] = (*it)->uid(); | 338 | m_currentQuery[arraycounter++] = (*it)->uid(); |
346 | } | 339 | } |
347 | } | 340 | } |
348 | 341 | ||
349 | // Shrink to fit.. | 342 | // Shrink to fit.. |
350 | m_currentQuery.resize(arraycounter); | 343 | m_currentQuery.resize(arraycounter); |
351 | 344 | ||
352 | return m_currentQuery; | 345 | return m_currentQuery; |
353 | } | 346 | } |
354 | 347 | ||
355 | QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const | 348 | QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const |
356 | { | 349 | { |
357 | QArray<int> m_currentQuery( m_contactList.count() ); | 350 | QArray<int> m_currentQuery( m_contactList.count() ); |
358 | QListIterator<OPimContact> it( m_contactList ); | 351 | QListIterator<OPimContact> it( m_contactList ); |
359 | uint arraycounter = 0; | 352 | uint arraycounter = 0; |
360 | 353 | ||
361 | for( ; it.current(); ++it ){ | 354 | for( ; it.current(); ++it ){ |
362 | if ( (*it)->match( r ) ){ | 355 | if ( (*it)->match( r ) ){ |
363 | m_currentQuery[arraycounter++] = (*it)->uid(); | 356 | m_currentQuery[arraycounter++] = (*it)->uid(); |
364 | } | 357 | } |
365 | 358 | ||
366 | } | 359 | } |
367 | // Shrink to fit.. | 360 | // Shrink to fit.. |
368 | m_currentQuery.resize(arraycounter); | 361 | m_currentQuery.resize(arraycounter); |
369 | 362 | ||
370 | return m_currentQuery; | 363 | return m_currentQuery; |
371 | } | 364 | } |
372 | 365 | ||
373 | const uint OPimContactAccessBackend_XML::querySettings() | 366 | const uint OPimContactAccessBackend_XML::querySettings() |
374 | { | 367 | { |
375 | return ( OPimContactAccess::WildCards | 368 | return ( OPimContactAccess::WildCards |
376 | | OPimContactAccess::IgnoreCase | 369 | | OPimContactAccess::IgnoreCase |
377 | | OPimContactAccess::RegExp | 370 | | OPimContactAccess::RegExp |
378 | | OPimContactAccess::ExactMatch | 371 | | OPimContactAccess::ExactMatch |
379 | | OPimContactAccess::DateDiff | 372 | | OPimContactAccess::DateDiff |
380 | | OPimContactAccess::DateYear | 373 | | OPimContactAccess::DateYear |
381 | | OPimContactAccess::DateMonth | 374 | | OPimContactAccess::DateMonth |
382 | | OPimContactAccess::DateDay | 375 | | OPimContactAccess::DateDay |
383 | ); | 376 | ); |
384 | } | 377 | } |
385 | 378 | ||
386 | bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const | 379 | bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const |
387 | { | 380 | { |
388 | /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay | 381 | /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay |
389 | * may be added with any of the other settings. IgnoreCase should never used alone. | 382 | * may be added with any of the other settings. IgnoreCase should never used alone. |
390 | * Wildcards, RegExp, ExactMatch should never used at the same time... | 383 | * Wildcards, RegExp, ExactMatch should never used at the same time... |
391 | */ | 384 | */ |
392 | 385 | ||
393 | // Step 1: Check whether the given settings are supported by this backend | 386 | // Step 1: Check whether the given settings are supported by this backend |
394 | if ( ( querySettings & ( | 387 | if ( ( querySettings & ( |
395 | OPimContactAccess::IgnoreCase | 388 | OPimContactAccess::IgnoreCase |
396 | | OPimContactAccess::WildCards | 389 | | OPimContactAccess::WildCards |
397 | | OPimContactAccess::DateDiff | 390 | | OPimContactAccess::DateDiff |
398 | | OPimContactAccess::DateYear | 391 | | OPimContactAccess::DateYear |
399 | | OPimContactAccess::DateMonth | 392 | | OPimContactAccess::DateMonth |
400 | | OPimContactAccess::DateDay | 393 | | OPimContactAccess::DateDay |
401 | | OPimContactAccess::RegExp | 394 | | OPimContactAccess::RegExp |
402 | | OPimContactAccess::ExactMatch | 395 | | OPimContactAccess::ExactMatch |
403 | ) ) != querySettings ) | 396 | ) ) != querySettings ) |
404 | return false; | 397 | return false; |
405 | 398 | ||
406 | // Step 2: Check whether the given combinations are ok.. | 399 | // Step 2: Check whether the given combinations are ok.. |
407 | 400 | ||
408 | // IngoreCase alone is invalid | 401 | // IngoreCase alone is invalid |
409 | if ( querySettings == OPimContactAccess::IgnoreCase ) | 402 | if ( querySettings == OPimContactAccess::IgnoreCase ) |
410 | return false; | 403 | return false; |
411 | 404 | ||
412 | // WildCards, RegExp and ExactMatch should never used at the same time | 405 | // WildCards, RegExp and ExactMatch should never used at the same time |
413 | switch ( querySettings & ~( OPimContactAccess::IgnoreCase | 406 | switch ( querySettings & ~( OPimContactAccess::IgnoreCase |
414 | | OPimContactAccess::DateDiff | 407 | | OPimContactAccess::DateDiff |
415 | | OPimContactAccess::DateYear | 408 | | OPimContactAccess::DateYear |
416 | | OPimContactAccess::DateMonth | 409 | | OPimContactAccess::DateMonth |
417 | | OPimContactAccess::DateDay | 410 | | OPimContactAccess::DateDay |
418 | ) | 411 | ) |
419 | ){ | 412 | ){ |
420 | case OPimContactAccess::RegExp: | 413 | case OPimContactAccess::RegExp: |
421 | return ( true ); | 414 | return ( true ); |
422 | case OPimContactAccess::WildCards: | 415 | case OPimContactAccess::WildCards: |
423 | return ( true ); | 416 | return ( true ); |
424 | case OPimContactAccess::ExactMatch: | 417 | case OPimContactAccess::ExactMatch: |
425 | return ( true ); | 418 | return ( true ); |
426 | case 0: // one of the upper removed bits were set.. | 419 | case 0: // one of the upper removed bits were set.. |
427 | return ( true ); | 420 | return ( true ); |
428 | default: | 421 | default: |
429 | return ( false ); | 422 | return ( false ); |
430 | } | 423 | } |
431 | } | 424 | } |
432 | 425 | ||
426 | #if 0 | ||
433 | // Currently only asc implemented.. | 427 | // Currently only asc implemented.. |
434 | QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) | 428 | QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) |
435 | { | 429 | { |
436 | QMap<QString, int> nameToUid; | 430 | QMap<QString, int> nameToUid; |
437 | QStringList names; | 431 | QStringList names; |
438 | QArray<int> m_currentQuery( m_contactList.count() ); | 432 | QArray<int> m_currentQuery( m_contactList.count() ); |
439 | 433 | ||
440 | // First fill map and StringList with all Names | 434 | // First fill map and StringList with all Names |
441 | // Afterwards sort namelist and use map to fill array to return.. | 435 | // Afterwards sort namelist and use map to fill array to return.. |
442 | QListIterator<OPimContact> it( m_contactList ); | 436 | QListIterator<OPimContact> it( m_contactList ); |
443 | for( ; it.current(); ++it ){ | 437 | for( ; it.current(); ++it ){ |
444 | names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); | 438 | names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); |
445 | nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); | 439 | nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); |
446 | } | 440 | } |
447 | names.sort(); | 441 | names.sort(); |
448 | 442 | ||
449 | int i = 0; | 443 | int i = 0; |
450 | if ( asc ){ | 444 | if ( asc ){ |
451 | for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) | 445 | for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) |
452 | m_currentQuery[i++] = nameToUid[ (*it) ]; | 446 | m_currentQuery[i++] = nameToUid[ (*it) ]; |
453 | }else{ | 447 | }else{ |
454 | for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) | 448 | for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) |
455 | m_currentQuery[i++] = nameToUid[ (*it) ]; | 449 | m_currentQuery[i++] = nameToUid[ (*it) ]; |
456 | } | 450 | } |
457 | 451 | ||
458 | return m_currentQuery; | 452 | return m_currentQuery; |
459 | 453 | ||
460 | } | 454 | } |
455 | #endif | ||
456 | |||
461 | 457 | ||
462 | bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact ) | 458 | bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact ) |
463 | { | 459 | { |
464 | //owarn << "odefaultbackend: ACTION::ADD" << oendl; | ||
465 | updateJournal (newcontact, ACTION_ADD); | 460 | updateJournal (newcontact, ACTION_ADD); |
466 | addContact_p( newcontact ); | 461 | addContact_p( newcontact ); |
467 | 462 | ||
468 | m_changed = true; | 463 | m_changed = true; |
469 | 464 | ||
470 | return true; | 465 | return true; |
471 | } | 466 | } |
472 | 467 | ||
473 | bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact ) | 468 | bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact ) |
474 | { | 469 | { |
475 | m_changed = true; | 470 | m_changed = true; |
476 | 471 | ||
477 | OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); | 472 | OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); |
478 | 473 | ||
479 | if ( found ) { | 474 | if ( found ) { |
480 | OPimContact* newCont = new OPimContact( contact ); | 475 | OPimContact* newCont = new OPimContact( contact ); |
481 | 476 | ||
482 | updateJournal ( *newCont, ACTION_REPLACE); | 477 | updateJournal ( *newCont, ACTION_REPLACE); |
483 | m_contactList.removeRef ( found ); | 478 | m_contactList.removeRef ( found ); |
484 | m_contactList.append ( newCont ); | 479 | m_contactList.append ( newCont ); |
485 | m_uidToContact.remove( QString().setNum( contact.uid() ) ); | 480 | m_uidToContact.remove( QString().setNum( contact.uid() ) ); |
486 | m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); | 481 | m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); |
487 | 482 | ||
488 | owarn << "Nur zur Sicherheit: " << contact.uid() << " == " << newCont->uid() << " ?" << oendl; | ||
489 | |||
490 | return true; | 483 | return true; |
491 | } else | 484 | } else |
492 | return false; | 485 | return false; |
493 | } | 486 | } |
494 | 487 | ||
495 | bool OPimContactAccessBackend_XML::remove ( int uid ) | 488 | bool OPimContactAccessBackend_XML::remove ( int uid ) |
496 | { | 489 | { |
497 | m_changed = true; | 490 | m_changed = true; |
498 | 491 | ||
499 | OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) ); | 492 | OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) ); |
500 | 493 | ||
501 | if ( found ) { | 494 | if ( found ) { |
502 | updateJournal ( *found, ACTION_REMOVE); | 495 | updateJournal ( *found, ACTION_REMOVE); |
503 | m_contactList.removeRef ( found ); | 496 | m_contactList.removeRef ( found ); |
504 | m_uidToContact.remove( QString().setNum( uid ) ); | 497 | m_uidToContact.remove( QString().setNum( uid ) ); |
505 | 498 | ||
506 | return true; | 499 | return true; |
507 | } else | 500 | } else |
508 | return false; | 501 | return false; |
509 | } | 502 | } |
510 | 503 | ||
511 | bool OPimContactAccessBackend_XML::reload(){ | 504 | bool OPimContactAccessBackend_XML::reload(){ |
512 | /* Reload is the same as load in this implementation */ | 505 | /* Reload is the same as load in this implementation */ |
513 | return ( load() ); | 506 | return ( load() ); |
514 | } | 507 | } |
515 | 508 | ||
516 | void OPimContactAccessBackend_XML::addContact_p( const OPimContact &newcontact ) | 509 | void OPimContactAccessBackend_XML::addContact_p( const OPimContact &newcontact ) |
517 | { | 510 | { |
518 | OPimContact* contRef = new OPimContact( newcontact ); | 511 | OPimContact* contRef = new OPimContact( newcontact ); |
519 | 512 | ||
520 | m_contactList.append ( contRef ); | 513 | m_contactList.append ( contRef ); |
521 | m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); | 514 | m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); |
522 | } | 515 | } |
523 | 516 | ||
524 | /* This function loads the xml-database and the journalfile */ | 517 | /* This function loads the xml-database and the journalfile */ |
525 | bool OPimContactAccessBackend_XML::load( const QString filename, bool isJournal ) | 518 | bool OPimContactAccessBackend_XML::load( const QString filename, bool isJournal ) |
526 | { | 519 | { |
527 | 520 | ||
528 | /* We use the time of the last read to check if the file was | 521 | /* We use the time of the last read to check if the file was |
529 | * changed externally. | 522 | * changed externally. |
530 | */ | 523 | */ |
531 | if ( !isJournal ){ | 524 | if ( !isJournal ){ |
532 | QFileInfo fi( filename ); | 525 | QFileInfo fi( filename ); |
533 | m_readtime = fi.lastModified (); | 526 | m_readtime = fi.lastModified (); |
534 | } | 527 | } |
535 | 528 | ||
536 | const int JOURNALACTION = Qtopia::Notes + 1; | 529 | const int JOURNALACTION = Qtopia::Notes + 1; |
537 | const int JOURNALROW = JOURNALACTION + 1; | 530 | const int JOURNALROW = JOURNALACTION + 1; |
538 | 531 | ||
539 | bool foundAction = false; | 532 | bool foundAction = false; |
540 | journal_action action = ACTION_ADD; | 533 | journal_action action = ACTION_ADD; |
541 | int journalKey = 0; | 534 | int journalKey = 0; |
542 | QMap<int, QString> contactMap; | 535 | QMap<int, QString> contactMap; |
543 | QMap<QString, QString> customMap; | 536 | QMap<QString, QString> customMap; |
544 | QMap<QString, QString>::Iterator customIt; | 537 | QMap<QString, QString>::Iterator customIt; |
545 | QAsciiDict<int> dict( 47 ); | 538 | QAsciiDict<int> dict( 47 ); |
546 | 539 | ||
547 | dict.setAutoDelete( TRUE ); | 540 | dict.setAutoDelete( TRUE ); |
548 | dict.insert( "Uid", new int(Qtopia::AddressUid) ); | 541 | dict.insert( "Uid", new int(Qtopia::AddressUid) ); |
549 | dict.insert( "Title", new int(Qtopia::Title) ); | 542 | dict.insert( "Title", new int(Qtopia::Title) ); |
550 | dict.insert( "FirstName", new int(Qtopia::FirstName) ); | 543 | dict.insert( "FirstName", new int(Qtopia::FirstName) ); |
551 | dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); | 544 | dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); |
552 | dict.insert( "LastName", new int(Qtopia::LastName) ); | 545 | dict.insert( "LastName", new int(Qtopia::LastName) ); |
553 | dict.insert( "Suffix", new int(Qtopia::Suffix) ); | 546 | dict.insert( "Suffix", new int(Qtopia::Suffix) ); |
554 | dict.insert( "FileAs", new int(Qtopia::FileAs) ); | 547 | dict.insert( "FileAs", new int(Qtopia::FileAs) ); |
555 | dict.insert( "Categories", new int(Qtopia::AddressCategory) ); | 548 | dict.insert( "Categories", new int(Qtopia::AddressCategory) ); |
556 | dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); | 549 | dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); |
557 | dict.insert( "Emails", new int(Qtopia::Emails) ); | 550 | dict.insert( "Emails", new int(Qtopia::Emails) ); |
558 | dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); | 551 | dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); |
559 | dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); | 552 | dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); |
560 | dict.insert( "HomeState", new int(Qtopia::HomeState) ); | 553 | dict.insert( "HomeState", new int(Qtopia::HomeState) ); |
561 | dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); | 554 | dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); |
562 | dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); | 555 | dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); |
563 | dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); | 556 | dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); |
564 | dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); | 557 | dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); |
565 | dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); | 558 | dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); |
566 | dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); | 559 | dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); |
567 | dict.insert( "Company", new int(Qtopia::Company) ); | 560 | dict.insert( "Company", new int(Qtopia::Company) ); |
568 | dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); | 561 | dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); |
569 | dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); | 562 | dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); |
570 | dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); | 563 | dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); |
571 | dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); | 564 | dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); |
572 | dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); | 565 | dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); |
573 | dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); | 566 | dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); |
574 | dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); | 567 | dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); |
575 | dict.insert( "Department", new int(Qtopia::Department) ); | 568 | dict.insert( "Department", new int(Qtopia::Department) ); |
576 | dict.insert( "Office", new int(Qtopia::Office) ); | 569 | dict.insert( "Office", new int(Qtopia::Office) ); |
577 | dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); | 570 | dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); |
578 | dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); | 571 | dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); |
579 | dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); | 572 | dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); |
580 | dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); | 573 | dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); |
581 | dict.insert( "Profession", new int(Qtopia::Profession) ); | 574 | dict.insert( "Profession", new int(Qtopia::Profession) ); |
582 | dict.insert( "Assistant", new int(Qtopia::Assistant) ); | 575 | dict.insert( "Assistant", new int(Qtopia::Assistant) ); |
583 | dict.insert( "Manager", new int(Qtopia::Manager) ); | 576 | dict.insert( "Manager", new int(Qtopia::Manager) ); |
584 | dict.insert( "Spouse", new int(Qtopia::Spouse) ); | 577 | dict.insert( "Spouse", new int(Qtopia::Spouse) ); |
585 | dict.insert( "Children", new int(Qtopia::Children) ); | 578 | dict.insert( "Children", new int(Qtopia::Children) ); |
586 | dict.insert( "Gender", new int(Qtopia::Gender) ); | 579 | dict.insert( "Gender", new int(Qtopia::Gender) ); |
587 | dict.insert( "Birthday", new int(Qtopia::Birthday) ); | 580 | dict.insert( "Birthday", new int(Qtopia::Birthday) ); |
588 | dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); | 581 | dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); |
589 | dict.insert( "Nickname", new int(Qtopia::Nickname) ); | 582 | dict.insert( "Nickname", new int(Qtopia::Nickname) ); |
590 | dict.insert( "Notes", new int(Qtopia::Notes) ); | 583 | dict.insert( "Notes", new int(Qtopia::Notes) ); |
591 | dict.insert( "action", new int(JOURNALACTION) ); | 584 | dict.insert( "action", new int(JOURNALACTION) ); |
592 | dict.insert( "actionrow", new int(JOURNALROW) ); | 585 | dict.insert( "actionrow", new int(JOURNALROW) ); |
593 | 586 | ||
594 | //owarn << "OPimContactDefaultBackEnd::loading " << filename << "" << oendl; | ||
595 | |||
596 | XMLElement *root = XMLElement::load( filename ); | 587 | XMLElement *root = XMLElement::load( filename ); |
597 | if(root != 0l ){ // start parsing | 588 | if(root != 0l ){ // start parsing |
598 | /* Parse all XML-Elements and put the data into the | 589 | /* Parse all XML-Elements and put the data into the |
599 | * Contact-Class | 590 | * Contact-Class |
600 | */ | 591 | */ |
601 | XMLElement *element = root->firstChild(); | 592 | XMLElement *element = root->firstChild(); |
602 | //owarn << "OPimContactAccess::load tagName(): " << root->tagName() << "" << oendl; | ||
603 | element = element ? element->firstChild() : 0; | 593 | element = element ? element->firstChild() : 0; |
604 | 594 | ||
605 | /* Search Tag "Contacts" which is the parent of all Contacts */ | 595 | /* Search Tag "Contacts" which is the parent of all Contacts */ |
606 | while( element && !isJournal ){ | 596 | while( element && !isJournal ){ |
607 | if( element->tagName() != QString::fromLatin1("Contacts") ){ | 597 | if( element->tagName() != QString::fromLatin1("Contacts") ){ |
608 | //owarn << "OPimContactDefBack::Searching for Tag \"Contacts\"! Found: " | ||
609 | // << element->tagName() << oendl; | ||
610 | element = element->nextChild(); | 598 | element = element->nextChild(); |
611 | } else { | 599 | } else { |
612 | element = element->firstChild(); | 600 | element = element->firstChild(); |
613 | break; | 601 | break; |
614 | } | 602 | } |
615 | } | 603 | } |
616 | /* Parse all Contacts and ignore unknown tags */ | 604 | /* Parse all Contacts and ignore unknown tags */ |
617 | while( element ){ | 605 | while( element ){ |
618 | if( element->tagName() != QString::fromLatin1("Contact") ){ | 606 | if( element->tagName() != QString::fromLatin1("Contact") ){ |
619 | //owarn << "OPimContactDefBack::Searching for Tag \"Contact\"! Found: " | ||
620 | // << element->tagName() << oendl; | ||
621 | element = element->nextChild(); | 607 | element = element->nextChild(); |
622 | continue; | 608 | continue; |
623 | } | 609 | } |
624 | /* Found alement with tagname "contact", now parse and store all | 610 | /* Found alement with tagname "contact", now parse and store all |
625 | * attributes contained | 611 | * attributes contained |
626 | */ | 612 | */ |
627 | //owarn << "OPimContactDefBack::load element tagName() : " | ||
628 | // << element->tagName() << oendl; | ||
629 | QString dummy; | 613 | QString dummy; |
630 | foundAction = false; | 614 | foundAction = false; |
631 | 615 | ||
632 | XMLElement::AttributeMap aMap = element->attributes(); | 616 | XMLElement::AttributeMap aMap = element->attributes(); |
633 | XMLElement::AttributeMap::Iterator it; | 617 | XMLElement::AttributeMap::Iterator it; |
634 | contactMap.clear(); | 618 | contactMap.clear(); |
635 | customMap.clear(); | 619 | customMap.clear(); |
636 | for( it = aMap.begin(); it != aMap.end(); ++it ){ | 620 | for( it = aMap.begin(); it != aMap.end(); ++it ){ |
637 | // owarn << "Read Attribute: " << it.key() << "=" << it.data() << oendl; | ||
638 | |||
639 | int *find = dict[ it.key() ]; | 621 | int *find = dict[ it.key() ]; |
640 | /* Unknown attributes will be stored as "Custom" elements */ | 622 | /* Unknown attributes will be stored as "Custom" elements */ |
641 | if ( !find ) { | 623 | if ( !find ) { |
642 | // owarn << "Attribute " << it.key() << " not known." << oendl; | ||
643 | //contact.setCustomField(it.key(), it.data()); | 624 | //contact.setCustomField(it.key(), it.data()); |
644 | customMap.insert( it.key(), it.data() ); | 625 | customMap.insert( it.key(), it.data() ); |
645 | continue; | 626 | continue; |
646 | } | 627 | } |
647 | 628 | ||
648 | /* Check if special conversion is needed and add attribute | 629 | /* Check if special conversion is needed and add attribute |
649 | * into Contact class | 630 | * into Contact class |
650 | */ | 631 | */ |
651 | switch( *find ) { | 632 | switch( *find ) { |
652 | /* | 633 | /* |
653 | case Qtopia::AddressUid: | 634 | case Qtopia::AddressUid: |
654 | contact.setUid( it.data().toInt() ); | 635 | contact.setUid( it.data().toInt() ); |
655 | break; | 636 | break; |
656 | case Qtopia::AddressCategory: | 637 | case Qtopia::AddressCategory: |
657 | contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); | 638 | contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); |
658 | break; | 639 | break; |
659 | */ | 640 | */ |
660 | case JOURNALACTION: | 641 | case JOURNALACTION: |
661 | action = journal_action(it.data().toInt()); | 642 | action = journal_action(it.data().toInt()); |
662 | foundAction = true; | 643 | foundAction = true; |
663 | owarn << "ODefBack(journal)::ACTION found: " << action << oendl; | 644 | owarn << "ODefBack(journal)::ACTION found: " << action << oendl; |
664 | break; | 645 | break; |
665 | case JOURNALROW: | 646 | case JOURNALROW: |
666 | journalKey = it.data().toInt(); | 647 | journalKey = it.data().toInt(); |
667 | break; | 648 | break; |
668 | default: // no conversion needed add them to the map | 649 | default: // no conversion needed add them to the map |
669 | contactMap.insert( *find, it.data() ); | 650 | contactMap.insert( *find, it.data() ); |
670 | break; | 651 | break; |
671 | } | 652 | } |
672 | } | 653 | } |
673 | /* now generate the Contact contact */ | 654 | /* now generate the Contact contact */ |
674 | OPimContact contact( contactMap ); | 655 | OPimContact contact( contactMap ); |
675 | 656 | ||
676 | for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { | 657 | for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { |
677 | contact.setCustomField( customIt.key(), customIt.data() ); | 658 | contact.setCustomField( customIt.key(), customIt.data() ); |
678 | } | 659 | } |
679 | 660 | ||
680 | if (foundAction){ | 661 | if (foundAction){ |
681 | foundAction = false; | 662 | foundAction = false; |
682 | switch ( action ) { | 663 | switch ( action ) { |
683 | case ACTION_ADD: | 664 | case ACTION_ADD: |
684 | addContact_p (contact); | 665 | addContact_p (contact); |
685 | break; | 666 | break; |
686 | case ACTION_REMOVE: | 667 | case ACTION_REMOVE: |
687 | if ( !remove (contact.uid()) ) | 668 | if ( !remove (contact.uid()) ) |
688 | owarn << "ODefBack(journal)::Unable to remove uid: " << contact.uid() << oendl; | 669 | owarn << "ODefBack(journal)::Unable to remove uid: " << contact.uid() << oendl; |
689 | break; | 670 | break; |
690 | case ACTION_REPLACE: | 671 | case ACTION_REPLACE: |
691 | if ( !replace ( contact ) ) | 672 | if ( !replace ( contact ) ) |
692 | owarn << "ODefBack(journal)::Unable to replace uid: " << contact.uid() << oendl; | 673 | owarn << "ODefBack(journal)::Unable to replace uid: " << contact.uid() << oendl; |
693 | break; | 674 | break; |
694 | default: | 675 | default: |
695 | owarn << "Unknown action: ignored !" << oendl; | 676 | owarn << "Unknown action: ignored !" << oendl; |
696 | break; | 677 | break; |
697 | } | 678 | } |
698 | }else{ | 679 | }else{ |
699 | /* Add contact to list */ | 680 | /* Add contact to list */ |
700 | addContact_p (contact); | 681 | addContact_p (contact); |
701 | } | 682 | } |
702 | 683 | ||
703 | /* Move to next element */ | 684 | /* Move to next element */ |
704 | element = element->nextChild(); | 685 | element = element->nextChild(); |
705 | } | 686 | } |
706 | }else { | 687 | }else { |
707 | owarn << "ODefBack::could not load" << oendl; | ||
708 | } | 688 | } |
709 | delete root; | 689 | delete root; |
710 | owarn << "returning from loading" << oendl; | ||
711 | return true; | 690 | return true; |
712 | } | 691 | } |
713 | 692 | ||
714 | 693 | ||
715 | void OPimContactAccessBackend_XML::updateJournal( const OPimContact& cnt, | 694 | void OPimContactAccessBackend_XML::updateJournal( const OPimContact& cnt, |
716 | journal_action action ) | 695 | journal_action action ) |
717 | { | 696 | { |
718 | QFile f( m_journalName ); | 697 | QFile f( m_journalName ); |
719 | bool created = !f.exists(); | 698 | bool created = !f.exists(); |
720 | if ( !f.open(IO_WriteOnly|IO_Append) ) | 699 | if ( !f.open(IO_WriteOnly|IO_Append) ) |
721 | return; | 700 | return; |
722 | 701 | ||
723 | QString buf; | 702 | QString buf; |
724 | QCString str; | 703 | QCString str; |
725 | 704 | ||
726 | // if the file was created, we have to set the Tag "<CONTACTS>" to | 705 | // if the file was created, we have to set the Tag "<CONTACTS>" to |
727 | // get a XML-File which is readable by our parser. | 706 | // get a XML-File which is readable by our parser. |
728 | // This is just a cheat, but better than rewrite the parser. | 707 | // This is just a cheat, but better than rewrite the parser. |
729 | if ( created ){ | 708 | if ( created ){ |
730 | buf = "<Contacts>"; | 709 | buf = "<Contacts>"; |
731 | QCString cstr = buf.utf8(); | 710 | QCString cstr = buf.utf8(); |
732 | f.writeBlock( cstr.data(), cstr.length() ); | 711 | f.writeBlock( cstr.data(), cstr.length() ); |
733 | } | 712 | } |
734 | 713 | ||
735 | buf = "<Contact "; | 714 | buf = "<Contact "; |
736 | cnt.save( buf ); | 715 | cnt.save( buf ); |
737 | buf += " action=\"" + QString::number( (int)action ) + "\" "; | 716 | buf += " action=\"" + QString::number( (int)action ) + "\" "; |
738 | buf += "/>\n"; | 717 | buf += "/>\n"; |
739 | QCString cstr = buf.utf8(); | 718 | QCString cstr = buf.utf8(); |
740 | f.writeBlock( cstr.data(), cstr.length() ); | 719 | f.writeBlock( cstr.data(), cstr.length() ); |
741 | } | 720 | } |
742 | 721 | ||
743 | void OPimContactAccessBackend_XML::removeJournal() | 722 | void OPimContactAccessBackend_XML::removeJournal() |
744 | { | 723 | { |
745 | QFile f ( m_journalName ); | 724 | QFile f ( m_journalName ); |
746 | if ( f.exists() ) | 725 | if ( f.exists() ) |
747 | f.remove(); | 726 | f.remove(); |
748 | } | 727 | } |
749 | 728 | ||
750 | } | 729 | } |
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h index eaea352..3e4f1e1 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h | |||
@@ -1,108 +1,105 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | /* | 29 | /* |
30 | * XML Backend for the OPIE-Contact Database. | 30 | * XML Backend for the OPIE-Contact Database. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #ifndef _OPimContactAccessBackend_XML_ | 33 | #ifndef _OPimContactAccessBackend_XML_ |
34 | #define _OPimContactAccessBackend_XML_ | 34 | #define _OPimContactAccessBackend_XML_ |
35 | 35 | ||
36 | #include <opie2/ocontactaccessbackend.h> | 36 | #include <opie2/ocontactaccessbackend.h> |
37 | #include <opie2/ocontactaccess.h> | 37 | #include <opie2/ocontactaccess.h> |
38 | 38 | ||
39 | #include <qlist.h> | 39 | #include <qlist.h> |
40 | #include <qdict.h> | 40 | #include <qdict.h> |
41 | 41 | ||
42 | namespace Opie { | 42 | namespace Opie { |
43 | /* the default xml implementation */ | 43 | /* the default xml implementation */ |
44 | /** | 44 | /** |
45 | * This class is the XML implementation of a Contact backend | 45 | * This class is the XML implementation of a Contact backend |
46 | * it does implement everything available for OPimContact. | 46 | * it does implement everything available for OPimContact. |
47 | * @see OPimAccessBackend for more information of available methods | 47 | * @see OPimAccessBackend for more information of available methods |
48 | */ | 48 | */ |
49 | class OPimContactAccessBackend_XML : public OPimContactAccessBackend { | 49 | class OPimContactAccessBackend_XML : public OPimContactAccessBackend { |
50 | public: | 50 | public: |
51 | OPimContactAccessBackend_XML ( const QString& appname, const QString& filename = QString::null ); | 51 | OPimContactAccessBackend_XML ( const QString& appname, const QString& filename = QString::null ); |
52 | 52 | ||
53 | bool save(); | 53 | bool save(); |
54 | 54 | ||
55 | bool load (); | 55 | bool load (); |
56 | 56 | ||
57 | void clear (); | 57 | void clear (); |
58 | 58 | ||
59 | bool wasChangedExternally(); | 59 | bool wasChangedExternally(); |
60 | 60 | ||
61 | QArray<int> allRecords() const; | 61 | QArray<int> allRecords() const; |
62 | 62 | ||
63 | OPimContact find ( int uid ) const; | 63 | OPimContact find ( int uid ) const; |
64 | 64 | ||
65 | QArray<int> queryByExample ( const OPimContact &query, int settings, const QDateTime& d = QDateTime() ); | 65 | QArray<int> queryByExample ( const OPimContact &query, int settings, const QDateTime& d )const; |
66 | |||
67 | QArray<int> matchRegexp( const QRegExp &r ) const; | 66 | QArray<int> matchRegexp( const QRegExp &r ) const; |
68 | 67 | ||
69 | const uint querySettings(); | 68 | const uint querySettings(); |
70 | 69 | ||
71 | bool hasQuerySettings (uint querySettings) const; | 70 | bool hasQuerySettings (uint querySettings) const; |
72 | 71 | ||
73 | // Currently only asc implemented.. | ||
74 | QArray<int> sorted( bool asc, int , int , int ); | ||
75 | bool add ( const OPimContact &newcontact ); | 72 | bool add ( const OPimContact &newcontact ); |
76 | 73 | ||
77 | bool replace ( const OPimContact &contact ); | 74 | bool replace ( const OPimContact &contact ); |
78 | 75 | ||
79 | bool remove ( int uid ); | 76 | bool remove ( int uid ); |
80 | bool reload(); | 77 | bool reload(); |
81 | 78 | ||
82 | private: | 79 | private: |
83 | 80 | ||
84 | enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; | 81 | enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; |
85 | 82 | ||
86 | void addContact_p( const OPimContact &newcontact ); | 83 | void addContact_p( const OPimContact &newcontact ); |
87 | 84 | ||
88 | /* This function loads the xml-database and the journalfile */ | 85 | /* This function loads the xml-database and the journalfile */ |
89 | bool load( const QString filename, bool isJournal ); | 86 | bool load( const QString filename, bool isJournal ); |
90 | 87 | ||
91 | 88 | ||
92 | void updateJournal( const OPimContact& cnt, journal_action action ); | 89 | void updateJournal( const OPimContact& cnt, journal_action action ); |
93 | void removeJournal(); | 90 | void removeJournal(); |
94 | 91 | ||
95 | protected: | 92 | protected: |
96 | bool m_changed; | 93 | bool m_changed; |
97 | QString m_journalName; | 94 | QString m_journalName; |
98 | QString m_fileName; | 95 | QString m_fileName; |
99 | QString m_appName; | 96 | QString m_appName; |
100 | QList<OPimContact> m_contactList; | 97 | QList<OPimContact> m_contactList; |
101 | QDateTime m_readtime; | 98 | QDateTime m_readtime; |
102 | 99 | ||
103 | QDict<OPimContact> m_uidToContact; | 100 | QDict<OPimContact> m_uidToContact; |
104 | }; | 101 | }; |
105 | 102 | ||
106 | } | 103 | } |
107 | 104 | ||
108 | #endif | 105 | #endif |
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend.cpp b/libopie2/opiepim/backend/odatebookaccessbackend.cpp index f3b7b5f..73c7059 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend.cpp | |||
@@ -1,216 +1,164 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | #include <qtl.h> | 29 | #include <qtl.h> |
30 | 30 | ||
31 | #include <opie2/opimrecurrence.h> | 31 | #include <opie2/opimrecurrence.h> |
32 | 32 | ||
33 | #include <opie2/odatebookaccessbackend.h> | 33 | #include <opie2/odatebookaccessbackend.h> |
34 | 34 | ||
35 | using namespace Opie; | 35 | using namespace Opie; |
36 | 36 | ||
37 | namespace { | 37 | namespace { |
38 | /* a small helper to get all NonRepeating events for a range of time */ | 38 | /* a small helper to get all NonRepeating events for a range of time */ |
39 | void events( OEffectiveEvent::ValueList& tmpList, const OPimEvent::ValueList& events, | 39 | void events( OPimBackendOccurrence::List& tmpList, |
40 | const QDate& from, const QDate& to ) { | 40 | const OPimEvent::ValueList& events, |
41 | QDateTime dtStart, dtEnd; | 41 | const QDate& from, const QDate& to ) { |
42 | 42 | QDateTime dtStart, dtEnd; | |
43 | for ( OPimEvent::ValueList::ConstIterator it = events.begin(); it != events.end(); ++it ) { | 43 | |
44 | dtStart = (*it).startDateTime(); | 44 | for ( OPimEvent::ValueList::ConstIterator it = events.begin(); it != events.end(); ++it ) { |
45 | dtEnd = (*it).endDateTime(); | 45 | dtStart = (*it).startDateTime(); |
46 | 46 | dtEnd = (*it).endDateTime(); | |
47 | /* | 47 | |
48 | * If in range | 48 | /* |
49 | */ | 49 | * If in range |
50 | if (dtStart.date() >= from && dtEnd.date() <= to ) { | 50 | */ |
51 | OEffectiveEvent eff; | 51 | if (dtStart.date() >= from && dtEnd.date() <= to ) { |
52 | eff.setEvent( (*it) ); | 52 | OPimBackendOccurrence eff( dtStart, dtEnd, (*it).uid() );; |
53 | eff.setDate( dtStart.date() ); | 53 | tmpList.append( eff ); |
54 | eff.setStartTime( dtStart.time() ); | ||
55 | |||
56 | /* if not on the same day */ | ||
57 | if ( dtStart.date() != dtEnd.date() ) | ||
58 | eff.setEndTime( QTime(23, 59, 0 ) ); | ||
59 | else | ||
60 | eff.setEndTime( dtEnd.time() ); | ||
61 | |||
62 | tmpList.append( eff ); | ||
63 | } | ||
64 | |||
65 | /* we must also check for end date information... */ | ||
66 | if ( dtEnd.date() != dtStart.date() && dtEnd.date() >= from ) { | ||
67 | QDateTime dt = dtStart.addDays( 1 ); | ||
68 | dt.setTime( QTime(0, 0, 0 ) ); | ||
69 | QDateTime dtStop; | ||
70 | if ( dtEnd > to ) | ||
71 | dtStop = to; | ||
72 | else | ||
73 | dtStop = dtEnd; | ||
74 | |||
75 | while ( dt <= dtStop ) { | ||
76 | OEffectiveEvent eff; | ||
77 | eff.setEvent( (*it) ); | ||
78 | eff.setDate( dt.date() ); | ||
79 | |||
80 | if ( dt >= from ) { | ||
81 | eff.setStartTime( QTime(0, 0, 0 ) ); | ||
82 | if ( dt.date() == dtEnd.date() ) | ||
83 | eff.setEndTime( dtEnd.time() ); | ||
84 | else | ||
85 | eff.setEndTime( QTime(23, 59, 0 ) ); | ||
86 | tmpList.append( eff ); | ||
87 | } | ||
88 | dt = dt.addDays( 1 ); | ||
89 | } | ||
90 | } | ||
91 | } | 54 | } |
92 | } | 55 | } |
56 | } | ||
93 | 57 | ||
94 | void repeat( OEffectiveEvent::ValueList& tmpList, const OPimEvent::ValueList& list, | 58 | void repeat( OPimBackendOccurrence::List& tmpList, const OPimEvent::ValueList& list, |
95 | const QDate& from, const QDate& to ) { | 59 | const QDate& from, const QDate& to ) { |
96 | QDate repeat; | 60 | QDate repeat; |
97 | for ( OPimEvent::ValueList::ConstIterator it = list.begin(); it != list.end(); ++it ) { | 61 | for ( OPimEvent::ValueList::ConstIterator it = list.begin(); it != list.end(); ++it ) { |
98 | int dur = (*it).startDateTime().date().daysTo( (*it).endDateTime().date() ); | 62 | int dur = (*it).startDateTime().date().daysTo( (*it).endDateTime().date() ); |
99 | QDate itDate = from.addDays(-dur ); | 63 | QDate itDate = from.addDays(-dur ); |
100 | OPimRecurrence rec = (*it).recurrence(); | 64 | OPimRecurrence rec = (*it).recurrence(); |
101 | if ( !rec.hasEndDate() || rec.endDate() > to ) { | 65 | if ( !rec.hasEndDate() || rec.endDate() > to ) { |
102 | rec.setEndDate( to ); | 66 | rec.setEndDate( to ); |
103 | rec.setHasEndDate( true ); | 67 | rec.setHasEndDate( true ); |
104 | } | 68 | } |
105 | while (rec.nextOcurrence(itDate, repeat ) ) { | 69 | |
106 | if (repeat > to ) break; | 70 | QDateTime start, end; |
107 | OEffectiveEvent eff; | 71 | while (rec.nextOcurrence(itDate, repeat ) ) { |
108 | eff.setDate( repeat ); | 72 | if (repeat > to ) break; |
109 | if ( (*it).isAllDay() ) { | 73 | |
110 | eff.setStartTime( QTime(0, 0, 0 ) ); | 74 | OPimEvent event = *it; |
111 | eff.setEndTime( QTime(23, 59, 59 ) ); | 75 | start = QDateTime( repeat, event.startDateTime().time() ); |
112 | }else { | 76 | end = QDateTime( repeat.addDays(dur), event.endDateTime().time() ); |
113 | /* we only occur by days, not hours/minutes/seconds. Hence | 77 | OPimBackendOccurrence eff(start, end, event.uid() ); |
114 | * the actual end and start times will be the same for | 78 | tmpList.append( eff ); |
115 | * every repeated event. For multi day events this is | ||
116 | * fixed up later if on wronge day span | ||
117 | */ | ||
118 | eff.setStartTime( (*it).startDateTime().time() ); | ||
119 | eff.setEndTime( (*it).endDateTime().time() ); | ||
120 | } | ||
121 | if ( dur != 0 ) { | ||
122 | // multi-day repeating events | ||
123 | QDate sub_it = QMAX( repeat, from ); | ||
124 | QDate startDate = repeat; | ||
125 | QDate endDate = startDate.addDays( dur ); | ||
126 | |||
127 | while ( sub_it <= endDate && sub_it <= to ) { | ||
128 | OEffectiveEvent tmpEff = eff; | ||
129 | tmpEff.setEvent( (*it) ); | ||
130 | if ( sub_it != startDate ) | ||
131 | tmpEff.setStartTime( QTime(0, 0, 0 ) ); | ||
132 | if ( sub_it != endDate ) | ||
133 | tmpEff.setEndTime( QTime( 23, 59, 59 ) ); | ||
134 | |||
135 | tmpEff.setDate( sub_it ); | ||
136 | tmpEff.setEffectiveDates( startDate, endDate ); | ||
137 | tmpList.append( tmpEff ); | ||
138 | |||
139 | sub_it = sub_it.addDays( 1 ); | ||
140 | } | ||
141 | itDate = endDate; | ||
142 | }else { | ||
143 | eff.setEvent( (*it) ); | ||
144 | tmpList.append( eff ); | ||
145 | itDate = repeat.addDays( 1 ); | ||
146 | } | ||
147 | } | ||
148 | } | 79 | } |
149 | } | 80 | } |
150 | } | 81 | } |
82 | } | ||
151 | 83 | ||
152 | namespace Opie { | 84 | namespace Opie { |
153 | 85 | ||
154 | ODateBookAccessBackend::ODateBookAccessBackend() | 86 | ODateBookAccessBackend::ODateBookAccessBackend() |
155 | : OPimAccessBackend<OPimEvent>() | 87 | : OPimAccessBackend<OPimEvent>() |
156 | { | 88 | { |
157 | 89 | ||
158 | } | 90 | } |
159 | ODateBookAccessBackend::~ODateBookAccessBackend() { | 91 | ODateBookAccessBackend::~ODateBookAccessBackend() { |
160 | 92 | ||
161 | } | 93 | } |
162 | OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDate& from, | 94 | OPimBackendOccurrence::List ODateBookAccessBackend::occurrences( const QDate& from, |
163 | const QDate& to ) { | 95 | const QDate& to )const { |
164 | OEffectiveEvent::ValueList tmpList; | 96 | OPimBackendOccurrence::List tmpList; |
165 | OPimEvent::ValueList list = directNonRepeats(); | ||
166 | 97 | ||
167 | events( tmpList, list, from, to ); | 98 | events( tmpList, directNonRepeats(), from, to ); |
168 | repeat( tmpList, directRawRepeats(),from,to ); | 99 | repeat( tmpList, directRawRepeats(),from,to ); |
169 | 100 | ||
170 | list = directRawRepeats(); // Useless, isn't it ? (eilers) | ||
171 | |||
172 | qHeapSort( tmpList ); | ||
173 | return tmpList; | 101 | return tmpList; |
174 | } | 102 | } |
175 | OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDateTime& dt ) { | 103 | OPimBackendOccurrence::List ODateBookAccessBackend::occurrences( const QDateTime& dt )const { |
176 | OEffectiveEvent::ValueList day = effectiveEvents( dt.date(), dt.date() ); | 104 | OPimBackendOccurrence::List day = occurrences( dt.date(), dt.date() ); |
177 | OEffectiveEvent::ValueList::Iterator it; | ||
178 | |||
179 | OEffectiveEvent::ValueList tmpList; | ||
180 | QDateTime dtTmp; | ||
181 | for ( it = day.begin(); it != day.end(); ++it ) { | ||
182 | dtTmp = QDateTime( (*it).date(), (*it).startTime() ); | ||
183 | if ( QABS(dt.secsTo(dtTmp) ) < 60 ) | ||
184 | tmpList.append( (*it) ); | ||
185 | } | ||
186 | 105 | ||
187 | return tmpList; | 106 | return filterOccurrences( day, dt ); |
188 | } | 107 | } |
189 | 108 | ||
190 | OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDate& from, | 109 | OPimBackendOccurrence::List ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDate& from, |
191 | const QDate& to ) { | 110 | const QDate& to )const { |
192 | OEffectiveEvent::ValueList tmpList; | 111 | OPimBackendOccurrence::List tmpList; |
193 | OPimEvent::ValueList list = directNonRepeats(); | 112 | OPimEvent::ValueList list = directNonRepeats(); |
194 | 113 | ||
195 | events( tmpList, list, from, to ); | 114 | events( tmpList, list, from, to ); |
196 | 115 | ||
197 | qHeapSort( tmpList ); | ||
198 | return tmpList; | 116 | return tmpList; |
199 | } | 117 | } |
200 | 118 | ||
201 | OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDateTime& dt ) { | 119 | OPimBackendOccurrence::List ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDateTime& dt )const { |
202 | OEffectiveEvent::ValueList day = effectiveNonRepeatingEvents( dt.date(), dt.date() ); | 120 | OPimBackendOccurrence::List day = effectiveNonRepeatingEvents( dt.date(), dt.date() ); |
203 | OEffectiveEvent::ValueList::Iterator it; | 121 | return filterOccurrences( day,dt ); |
122 | } | ||
123 | |||
124 | |||
125 | UIDArray ODateBookAccessBackend::queryByExample( const OPimEvent&, int settings, | ||
126 | const QDateTime& d )const { | ||
127 | return UIDArray(); | ||
128 | } | ||
129 | |||
130 | UIDArray ODateBookAccessBackend::sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const { | ||
131 | return UIDArray(); | ||
132 | } | ||
204 | 133 | ||
205 | OEffectiveEvent::ValueList tmpList; | 134 | OPimBackendOccurrence::List ODateBookAccessBackend::filterOccurrences( const OPimBackendOccurrence::List dayList, |
206 | QDateTime dtTmp; | 135 | const QDateTime& dt ) { |
207 | for ( it = day.begin(); it != day.end(); ++it ) { | 136 | OPimBackendOccurrence::List tmpList; |
208 | dtTmp = QDateTime( (*it).date(), (*it).startTime() ); | 137 | OPimBackendOccurrence::List::ConstIterator it; |
209 | if ( QABS(dt.secsTo(dtTmp) ) < 60 ) | 138 | |
210 | tmpList.append( (*it) ); | 139 | for ( it = dayList.begin(); it != dayList.end(); ++it ) { |
140 | OPimBackendOccurrence occ = *it; | ||
141 | |||
142 | /* | ||
143 | * Let us find occurrences that are 'now'! | ||
144 | * If the dt.date() is on the same day as start or end of the Occurrence | ||
145 | * check how near start/end are. | ||
146 | * If it is in the middle of a multiday occurrence list it. | ||
147 | * | ||
148 | * We might want to 'lose' the sixty second offset and list | ||
149 | * all Events which are active at that time. | ||
150 | */ | ||
151 | if ( dt.date() == occ.startDateTime().date() ) { | ||
152 | if ( QABS( dt.time().secsTo( occ.startDateTime().time() ) ) < 60 ) | ||
153 | tmpList.append( occ ); | ||
154 | }else if ( dt.date() == occ.endDateTime().date() ) { | ||
155 | if ( QABS( dt.time().secsTo( occ.endDateTime().time() ) ) < 60 ) | ||
156 | tmpList.append( occ ); | ||
157 | }else if ( dt.date() >= occ.startDateTime().date() && | ||
158 | dt.date() >= occ.endDateTime().date() ) | ||
159 | tmpList.append( occ ); | ||
211 | } | 160 | } |
212 | 161 | ||
213 | return tmpList; | 162 | return tmpList; |
214 | } | 163 | } |
215 | |||
216 | } | 164 | } |
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend.h b/libopie2/opiepim/backend/odatebookaccessbackend.h index a9cce6a..8927ca1 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend.h +++ b/libopie2/opiepim/backend/odatebookaccessbackend.h | |||
@@ -1,121 +1,114 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_H | 29 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_H |
30 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_H | 30 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_H |
31 | 31 | ||
32 | #include <qarray.h> | 32 | #include <qarray.h> |
33 | 33 | ||
34 | #include <opie2/opimaccessbackend.h> | 34 | #include <opie2/opimaccessbackend.h> |
35 | #include <opie2/opimevent.h> | 35 | #include <opie2/opimevent.h> |
36 | 36 | ||
37 | namespace Opie { | 37 | namespace Opie { |
38 | /** | 38 | /** |
39 | * This class is the interface to the storage of Events. | 39 | * This class is the interface to the storage of Events. |
40 | * @see OPimAccessBackend | 40 | * @see OPimAccessBackend |
41 | * | 41 | * |
42 | */ | 42 | */ |
43 | class ODateBookAccessBackend : public OPimAccessBackend<OPimEvent> { | 43 | class ODateBookAccessBackend : public OPimAccessBackend<OPimEvent> { |
44 | public: | 44 | public: |
45 | typedef int UID; | ||
46 | |||
47 | /** | 45 | /** |
48 | * c'tor without parameter | 46 | * c'tor without parameter |
49 | */ | 47 | */ |
50 | ODateBookAccessBackend(); | 48 | ODateBookAccessBackend(); |
51 | ~ODateBookAccessBackend(); | 49 | ~ODateBookAccessBackend(); |
52 | 50 | ||
53 | /** | 51 | /** |
54 | * This method should return a list of UIDs containing | 52 | * This method should return a list of UIDs containing |
55 | * all events. No filter should be applied | ||
56 | * @return list of events | ||
57 | */ | ||
58 | virtual QArray<UID> rawEvents()const = 0; | ||
59 | |||
60 | /** | ||
61 | * This method should return a list of UIDs containing | ||
62 | * all repeating events. No filter should be applied | 53 | * all repeating events. No filter should be applied |
63 | * @return list of repeating events | 54 | * @return list of repeating events |
64 | */ | 55 | */ |
65 | virtual QArray<UID> rawRepeats()const = 0; | 56 | virtual UIDArray rawRepeats()const = 0; |
66 | 57 | ||
67 | /** | 58 | /** |
68 | * This mthod should return a list of UIDs containing all non | 59 | * This mthod should return a list of UIDs containing all non |
69 | * repeating events. No filter should be applied | 60 | * repeating events. No filter should be applied |
70 | * @return list of nonrepeating events | 61 | * @return list of nonrepeating events |
71 | */ | 62 | */ |
72 | virtual QArray<UID> nonRepeats() const = 0; | 63 | virtual UIDArray nonRepeats() const = 0; |
73 | 64 | ||
74 | /** | 65 | /** |
75 | * If you do not want to implement the effectiveEvents methods below | 66 | * If you do not want to implement the effectiveEvents methods below |
76 | * you need to supply it with directNonRepeats. | 67 | * you need to supply it with directNonRepeats. |
77 | * This method can return empty lists if effectiveEvents is implememted | 68 | * This method can return empty lists if effectiveEvents is implememted |
78 | */ | 69 | */ |
79 | virtual OPimEvent::ValueList directNonRepeats() = 0; | 70 | virtual OPimEvent::ValueList directNonRepeats()const = 0; |
80 | 71 | ||
81 | /** | 72 | /** |
82 | * Same as above but return raw repeats! | 73 | * Same as above but return raw repeats! |
83 | */ | 74 | */ |
84 | virtual OPimEvent::ValueList directRawRepeats() = 0; | 75 | virtual OPimEvent::ValueList directRawRepeats()const = 0; |
85 | 76 | ||
86 | /* is implemented by default but you can reimplement it*/ | 77 | /* is implemented by default but you can reimplement it*/ |
87 | /** | 78 | /** |
88 | * Effective Events are special event occuring during a time frame. This method does calcualte | 79 | * Effective Events are special event occuring during a time frame. This method does calcualte |
89 | * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method | 80 | * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method |
90 | * yourself | 81 | * yourself |
91 | */ | 82 | */ |
92 | virtual OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ); | 83 | virtual OPimBackendOccurrence::List effectiveNonRepeatingEvents( const QDate& from, const QDate& to )const; |
93 | 84 | ||
94 | /** | 85 | /** |
95 | * this is an overloaded member function | 86 | * this is an overloaded member function |
96 | * @see effectiveEvents( const QDate& from, const QDate& to ) | 87 | * @see effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) |
97 | */ | ||
98 | virtual OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ); | ||
99 | |||
100 | /** | ||
101 | * Effective Events are special event occuring during a time frame. This method does calcualte | ||
102 | * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method | ||
103 | * yourself | ||
104 | */ | 88 | */ |
105 | virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDate& from, const QDate& to ); | 89 | virtual OPimBackendOccurrence::List effectiveNonRepeatingEvents( const QDateTime& start )const; |
106 | 90 | ||
107 | /** | 91 | /** |
108 | * this is an overloaded member function | 92 | * Common and probably inefficent implementation |
109 | * @see effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) | 93 | * for queryByExample, sorted |
94 | * and occurrences | ||
110 | */ | 95 | */ |
111 | virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDateTime& start ); | 96 | //@{ |
112 | 97 | UIDArray queryByExample( const OPimEvent&, int settings, const QDateTime& d = QDateTime() )const; | |
98 | UIDArray sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const; | ||
99 | OPimBackendOccurrence::List occurrences( const QDate&, const QDate& end )const; | ||
100 | OPimBackendOccurrence::List occurrences( const QDateTime& )const; | ||
101 | //@} | ||
102 | |||
103 | protected: | ||
104 | static OPimBackendOccurrence::List filterOccurrences(const OPimBackendOccurrence::List, | ||
105 | const QDateTime& time ); | ||
113 | private: | 106 | private: |
114 | class Private; | 107 | class Private; |
115 | Private *d; | 108 | Private *d; |
116 | 109 | ||
117 | }; | 110 | }; |
118 | 111 | ||
119 | } | 112 | } |
120 | 113 | ||
121 | #endif | 114 | #endif |
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp index 105c106..41b714e 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp | |||
@@ -1,459 +1,448 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | /* | 29 | /* |
30 | * SQL Backend for the OPIE-Calender Database. | 30 | * SQL Backend for the OPIE-Calender Database. |
31 | * | 31 | * |
32 | */ | 32 | */ |
33 | 33 | ||
34 | /* OPIE */ | 34 | /* OPIE */ |
35 | #include <opie2/osqldriver.h> | 35 | #include <opie2/osqldriver.h> |
36 | #include <opie2/osqlmanager.h> | 36 | #include <opie2/osqlmanager.h> |
37 | #include <opie2/osqlquery.h> | 37 | #include <opie2/osqlquery.h> |
38 | 38 | ||
39 | #include <opie2/opimrecurrence.h> | 39 | #include <opie2/opimrecurrence.h> |
40 | #include <opie2/odatebookaccessbackend_sql.h> | 40 | #include <opie2/odatebookaccessbackend_sql.h> |
41 | #include <opie2/odebug.h> | 41 | #include <opie2/odebug.h> |
42 | 42 | ||
43 | #include <qpe/global.h> | 43 | #include <qpe/global.h> |
44 | 44 | ||
45 | /* QT */ | 45 | /* QT */ |
46 | #include <qarray.h> | 46 | #include <qarray.h> |
47 | #include <qstringlist.h> | 47 | #include <qstringlist.h> |
48 | 48 | ||
49 | /* STD */ | 49 | /* STD */ |
50 | #include <stdio.h> | 50 | #include <stdio.h> |
51 | #include <stdlib.h> | 51 | #include <stdlib.h> |
52 | 52 | ||
53 | 53 | ||
54 | using namespace Opie::DB; | 54 | using namespace Opie::DB; |
55 | 55 | ||
56 | namespace { | 56 | namespace { |
57 | /** | 57 | /** |
58 | * a find query for custom elements | 58 | * a find query for custom elements |
59 | */ | 59 | */ |
60 | class FindCustomQuery : public OSQLQuery { | 60 | class FindCustomQuery : public OSQLQuery { |
61 | public: | 61 | public: |
62 | FindCustomQuery(int uid); | 62 | FindCustomQuery(int uid); |
63 | FindCustomQuery(const QArray<int>& ); | 63 | FindCustomQuery(const QArray<int>& ); |
64 | ~FindCustomQuery(); | 64 | ~FindCustomQuery(); |
65 | QString query()const; | 65 | QString query()const; |
66 | private: | 66 | private: |
67 | QString single()const; | 67 | QString single()const; |
68 | QString multi()const; | 68 | QString multi()const; |
69 | QArray<int> m_uids; | 69 | QArray<int> m_uids; |
70 | int m_uid; | 70 | int m_uid; |
71 | }; | 71 | }; |
72 | 72 | ||
73 | FindCustomQuery::FindCustomQuery(int uid) | 73 | FindCustomQuery::FindCustomQuery(int uid) |
74 | : OSQLQuery(), m_uid( uid ) { | 74 | : OSQLQuery(), m_uid( uid ) { |
75 | } | 75 | } |
76 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) | 76 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) |
77 | : OSQLQuery(), m_uids( ints ){ | 77 | : OSQLQuery(), m_uids( ints ){ |
78 | } | 78 | } |
79 | FindCustomQuery::~FindCustomQuery() { | 79 | FindCustomQuery::~FindCustomQuery() { |
80 | } | 80 | } |
81 | QString FindCustomQuery::query()const{ | 81 | QString FindCustomQuery::query()const{ |
82 | // if ( m_uids.count() == 0 ) | 82 | // if ( m_uids.count() == 0 ) |
83 | return single(); | 83 | return single(); |
84 | } | 84 | } |
85 | QString FindCustomQuery::single()const{ | 85 | QString FindCustomQuery::single()const{ |
86 | QString qu = "select uid, type, value from custom_data where uid = "; | 86 | QString qu = "select uid, type, value from custom_data where uid = "; |
87 | qu += QString::number(m_uid); | 87 | qu += QString::number(m_uid); |
88 | return qu; | 88 | return qu; |
89 | } | 89 | } |
90 | } | 90 | } |
91 | 91 | ||
92 | 92 | ||
93 | namespace Opie { | 93 | namespace Opie { |
94 | 94 | ||
95 | 95 | ||
96 | ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , | 96 | ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , |
97 | const QString& fileName ) | 97 | const QString& fileName ) |
98 | : ODateBookAccessBackend(), m_driver( NULL ) | 98 | : ODateBookAccessBackend(), m_driver( NULL ) |
99 | { | 99 | { |
100 | m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; | 100 | m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; |
101 | 101 | ||
102 | // Get the standart sql-driver from the OSQLManager.. | 102 | // Get the standart sql-driver from the OSQLManager.. |
103 | OSQLManager man; | 103 | OSQLManager man; |
104 | m_driver = man.standard(); | 104 | m_driver = man.standard(); |
105 | m_driver->setUrl( m_fileName ); | 105 | m_driver->setUrl( m_fileName ); |
106 | 106 | ||
107 | initFields(); | 107 | initFields(); |
108 | 108 | ||
109 | load(); | 109 | load(); |
110 | } | 110 | } |
111 | 111 | ||
112 | ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { | 112 | ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { |
113 | if( m_driver ) | 113 | if( m_driver ) |
114 | delete m_driver; | 114 | delete m_driver; |
115 | } | 115 | } |
116 | 116 | ||
117 | void ODateBookAccessBackend_SQL::initFields() | 117 | void ODateBookAccessBackend_SQL::initFields() |
118 | { | 118 | { |
119 | 119 | ||
120 | // This map contains the translation of the fieldtype id's to | 120 | // This map contains the translation of the fieldtype id's to |
121 | // the names of the table columns | 121 | // the names of the table columns |
122 | m_fieldMap.insert( OPimEvent::FUid, "uid" ); | 122 | m_fieldMap.insert( OPimEvent::FUid, "uid" ); |
123 | m_fieldMap.insert( OPimEvent::FCategories, "Categories" ); | 123 | m_fieldMap.insert( OPimEvent::FCategories, "Categories" ); |
124 | m_fieldMap.insert( OPimEvent::FDescription, "Description" ); | 124 | m_fieldMap.insert( OPimEvent::FDescription, "Description" ); |
125 | m_fieldMap.insert( OPimEvent::FLocation, "Location" ); | 125 | m_fieldMap.insert( OPimEvent::FLocation, "Location" ); |
126 | m_fieldMap.insert( OPimEvent::FType, "Type" ); | 126 | m_fieldMap.insert( OPimEvent::FType, "Type" ); |
127 | m_fieldMap.insert( OPimEvent::FAlarm, "Alarm" ); | 127 | m_fieldMap.insert( OPimEvent::FAlarm, "Alarm" ); |
128 | m_fieldMap.insert( OPimEvent::FSound, "Sound" ); | 128 | m_fieldMap.insert( OPimEvent::FSound, "Sound" ); |
129 | m_fieldMap.insert( OPimEvent::FRType, "RType" ); | 129 | m_fieldMap.insert( OPimEvent::FRType, "RType" ); |
130 | m_fieldMap.insert( OPimEvent::FRWeekdays, "RWeekdays" ); | 130 | m_fieldMap.insert( OPimEvent::FRWeekdays, "RWeekdays" ); |
131 | m_fieldMap.insert( OPimEvent::FRPosition, "RPosition" ); | 131 | m_fieldMap.insert( OPimEvent::FRPosition, "RPosition" ); |
132 | m_fieldMap.insert( OPimEvent::FRFreq, "RFreq" ); | 132 | m_fieldMap.insert( OPimEvent::FRFreq, "RFreq" ); |
133 | m_fieldMap.insert( OPimEvent::FRHasEndDate, "RHasEndDate" ); | 133 | m_fieldMap.insert( OPimEvent::FRHasEndDate, "RHasEndDate" ); |
134 | m_fieldMap.insert( OPimEvent::FREndDate, "REndDate" ); | 134 | m_fieldMap.insert( OPimEvent::FREndDate, "REndDate" ); |
135 | m_fieldMap.insert( OPimEvent::FRCreated, "RCreated" ); | 135 | m_fieldMap.insert( OPimEvent::FRCreated, "RCreated" ); |
136 | m_fieldMap.insert( OPimEvent::FRExceptions, "RExceptions" ); | 136 | m_fieldMap.insert( OPimEvent::FRExceptions, "RExceptions" ); |
137 | m_fieldMap.insert( OPimEvent::FStart, "Start" ); | 137 | m_fieldMap.insert( OPimEvent::FStart, "Start" ); |
138 | m_fieldMap.insert( OPimEvent::FEnd, "End" ); | 138 | m_fieldMap.insert( OPimEvent::FEnd, "End" ); |
139 | m_fieldMap.insert( OPimEvent::FNote, "Note" ); | 139 | m_fieldMap.insert( OPimEvent::FNote, "Note" ); |
140 | m_fieldMap.insert( OPimEvent::FTimeZone, "TimeZone" ); | 140 | m_fieldMap.insert( OPimEvent::FTimeZone, "TimeZone" ); |
141 | m_fieldMap.insert( OPimEvent::FRecParent, "RecParent" ); | 141 | m_fieldMap.insert( OPimEvent::FRecParent, "RecParent" ); |
142 | m_fieldMap.insert( OPimEvent::FRecChildren, "Recchildren" ); | 142 | m_fieldMap.insert( OPimEvent::FRecChildren, "Recchildren" ); |
143 | 143 | ||
144 | // Create a map that maps the column name to the id | 144 | // Create a map that maps the column name to the id |
145 | QMapConstIterator<int, QString> it; | 145 | QMapConstIterator<int, QString> it; |
146 | for ( it = m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | 146 | for ( it = m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ |
147 | m_reverseFieldMap.insert( it.data(), it.key() ); | 147 | m_reverseFieldMap.insert( it.data(), it.key() ); |
148 | } | 148 | } |
149 | 149 | ||
150 | } | 150 | } |
151 | 151 | ||
152 | bool ODateBookAccessBackend_SQL::load() | 152 | bool ODateBookAccessBackend_SQL::load() |
153 | { | 153 | { |
154 | if (!m_driver->open() ) | 154 | if (!m_driver->open() ) |
155 | return false; | 155 | return false; |
156 | 156 | ||
157 | // Don't expect that the database exists. | 157 | // Don't expect that the database exists. |
158 | // It is save here to create the table, even if it | 158 | // It is save here to create the table, even if it |
159 | // do exist. ( Is that correct for all databases ?? ) | 159 | // do exist. ( Is that correct for all databases ?? ) |
160 | QString qu = "create table datebook( uid INTEGER PRIMARY KEY "; | 160 | QString qu = "create table datebook( uid INTEGER PRIMARY KEY "; |
161 | 161 | ||
162 | QMap<int, QString>::Iterator it; | 162 | QMap<int, QString>::Iterator it; |
163 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | 163 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ |
164 | qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() ); | 164 | qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() ); |
165 | } | 165 | } |
166 | qu += " );"; | 166 | qu += " );"; |
167 | 167 | ||
168 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; | 168 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; |
169 | 169 | ||
170 | owarn << "command: " << qu << "" << oendl; | ||
171 | |||
172 | OSQLRawQuery raw( qu ); | 170 | OSQLRawQuery raw( qu ); |
173 | OSQLResult res = m_driver->query( &raw ); | 171 | OSQLResult res = m_driver->query( &raw ); |
174 | if ( res.state() != OSQLResult::Success ) | 172 | if ( res.state() != OSQLResult::Success ) |
175 | return false; | 173 | return false; |
176 | 174 | ||
177 | update(); | 175 | update(); |
178 | 176 | ||
179 | return true; | 177 | return true; |
180 | } | 178 | } |
181 | 179 | ||
182 | void ODateBookAccessBackend_SQL::update() | 180 | void ODateBookAccessBackend_SQL::update() |
183 | { | 181 | { |
184 | 182 | ||
185 | QString qu = "select uid from datebook"; | 183 | QString qu = "select uid from datebook"; |
186 | OSQLRawQuery raw( qu ); | 184 | OSQLRawQuery raw( qu ); |
187 | OSQLResult res = m_driver->query( &raw ); | 185 | OSQLResult res = m_driver->query( &raw ); |
188 | if ( res.state() != OSQLResult::Success ){ | 186 | if ( res.state() != OSQLResult::Success ){ |
189 | // m_uids.clear(); | 187 | // m_uids.clear(); |
190 | return; | 188 | return; |
191 | } | 189 | } |
192 | 190 | ||
193 | m_uids = extractUids( res ); | 191 | m_uids = extractUids( res ); |
194 | 192 | ||
195 | } | 193 | } |
196 | 194 | ||
197 | bool ODateBookAccessBackend_SQL::reload() | 195 | bool ODateBookAccessBackend_SQL::reload() |
198 | { | 196 | { |
199 | return load(); | 197 | return load(); |
200 | } | 198 | } |
201 | 199 | ||
202 | bool ODateBookAccessBackend_SQL::save() | 200 | bool ODateBookAccessBackend_SQL::save() |
203 | { | 201 | { |
204 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) | 202 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) |
205 | } | 203 | } |
206 | 204 | ||
207 | QArray<int> ODateBookAccessBackend_SQL::allRecords()const | 205 | QArray<int> ODateBookAccessBackend_SQL::allRecords()const |
208 | { | 206 | { |
209 | return m_uids; | 207 | return m_uids; |
210 | } | 208 | } |
211 | 209 | ||
212 | QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OPimEvent&, int, const QDateTime& ) { | 210 | QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OPimEvent&, int, const QDateTime& ) { |
213 | return QArray<int>(); | 211 | return QArray<int>(); |
214 | } | 212 | } |
215 | 213 | ||
216 | void ODateBookAccessBackend_SQL::clear() | 214 | void ODateBookAccessBackend_SQL::clear() |
217 | { | 215 | { |
218 | QString qu = "drop table datebook;"; | 216 | QString qu = "drop table datebook;"; |
219 | qu += "drop table custom_data;"; | 217 | qu += "drop table custom_data;"; |
220 | 218 | ||
221 | OSQLRawQuery raw( qu ); | 219 | OSQLRawQuery raw( qu ); |
222 | OSQLResult res = m_driver->query( &raw ); | 220 | OSQLResult res = m_driver->query( &raw ); |
223 | 221 | ||
224 | reload(); | 222 | reload(); |
225 | } | 223 | } |
226 | 224 | ||
227 | 225 | ||
228 | OPimEvent ODateBookAccessBackend_SQL::find( int uid ) const{ | 226 | OPimEvent ODateBookAccessBackend_SQL::find( int uid ) const{ |
229 | odebug << "ODateBookAccessBackend_SQL::find( " << uid << " )" << oendl; | 227 | odebug << "ODateBookAccessBackend_SQL::find( " << uid << " )" << oendl; |
230 | 228 | ||
231 | QString qu = "select *"; | 229 | QString qu = "select *"; |
232 | qu += "from datebook where uid = " + QString::number(uid); | 230 | qu += "from datebook where uid = " + QString::number(uid); |
233 | 231 | ||
234 | odebug << "Query: " << qu << "" << oendl; | 232 | odebug << "Query: " << qu << "" << oendl; |
235 | 233 | ||
236 | OSQLRawQuery raw( qu ); | 234 | OSQLRawQuery raw( qu ); |
237 | OSQLResult res = m_driver->query( &raw ); | 235 | OSQLResult res = m_driver->query( &raw ); |
238 | 236 | ||
239 | OSQLResultItem resItem = res.first(); | 237 | OSQLResultItem resItem = res.first(); |
240 | 238 | ||
241 | // Create Map for date event and insert UID | 239 | // Create Map for date event and insert UID |
242 | QMap<int,QString> dateEventMap; | 240 | QMap<int,QString> dateEventMap; |
243 | dateEventMap.insert( OPimEvent::FUid, QString::number( uid ) ); | 241 | dateEventMap.insert( OPimEvent::FUid, QString::number( uid ) ); |
244 | 242 | ||
245 | // Now insert the data out of the columns into the map. | 243 | // Now insert the data out of the columns into the map. |
246 | QMapConstIterator<int, QString> it; | 244 | QMapConstIterator<int, QString> it; |
247 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | 245 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ |
248 | dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) ); | 246 | dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) ); |
249 | } | 247 | } |
250 | 248 | ||
251 | // Last step: Put map into date event, add custom map and return it | 249 | // Last step: Put map into date event, add custom map and return it |
252 | OPimEvent retDate( dateEventMap ); | 250 | OPimEvent retDate( dateEventMap ); |
253 | retDate.setExtraMap( requestCustom( uid ) ); | 251 | retDate.setExtraMap( requestCustom( uid ) ); |
254 | 252 | ||
255 | odebug << "ODateBookAccessBackend_SQL::find( " << uid << " ) end" << oendl; | 253 | odebug << "ODateBookAccessBackend_SQL::find( " << uid << " ) end" << oendl; |
256 | return retDate; | 254 | return retDate; |
257 | } | 255 | } |
258 | 256 | ||
259 | // FIXME: Speed up update of uid's.. | 257 | // FIXME: Speed up update of uid's.. |
260 | bool ODateBookAccessBackend_SQL::add( const OPimEvent& ev ) | 258 | bool ODateBookAccessBackend_SQL::add( const OPimEvent& ev ) |
261 | { | 259 | { |
262 | QMap<int,QString> eventMap = ev.toMap(); | 260 | QMap<int,QString> eventMap = ev.toMap(); |
263 | 261 | ||
264 | QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() ); | 262 | QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() ); |
265 | QMap<int, QString>::Iterator it; | 263 | QMap<int, QString>::Iterator it; |
266 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | 264 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ |
267 | if ( !eventMap[it.key()].isEmpty() ) | 265 | if ( !eventMap[it.key()].isEmpty() ) |
268 | qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] ); | 266 | qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] ); |
269 | else | 267 | else |
270 | qu += QString( ",\"\"" ); | 268 | qu += QString( ",\"\"" ); |
271 | } | 269 | } |
272 | qu += " );"; | 270 | qu += " );"; |
273 | 271 | ||
274 | // Add custom entries | 272 | // Add custom entries |
275 | int id = 0; | 273 | int id = 0; |
276 | QMap<QString, QString> customMap = ev.toExtraMap(); | 274 | QMap<QString, QString> customMap = ev.toExtraMap(); |
277 | for( QMap<QString, QString>::Iterator it = customMap.begin(); | 275 | for( QMap<QString, QString>::Iterator it = customMap.begin(); |
278 | it != customMap.end(); ++it ){ | 276 | it != customMap.end(); ++it ){ |
279 | qu += "insert into custom_data VALUES(" | 277 | qu += "insert into custom_data VALUES(" |
280 | + QString::number( ev.uid() ) | 278 | + QString::number( ev.uid() ) |
281 | + "," | 279 | + "," |
282 | + QString::number( id++ ) | 280 | + QString::number( id++ ) |
283 | + ",'" | 281 | + ",'" |
284 | + it.key() //.latin1() | 282 | + it.key() //.latin1() |
285 | + "'," | 283 | + "'," |
286 | + "0" // Priority for future enhancements | 284 | + "0" // Priority for future enhancements |
287 | + ",'" | 285 | + ",'" |
288 | + it.data() //.latin1() | 286 | + it.data() //.latin1() |
289 | + "');"; | 287 | + "');"; |
290 | } | 288 | } |
291 | owarn << "add " << qu << "" << oendl; | ||
292 | 289 | ||
293 | OSQLRawQuery raw( qu ); | 290 | OSQLRawQuery raw( qu ); |
294 | OSQLResult res = m_driver->query( &raw ); | 291 | OSQLResult res = m_driver->query( &raw ); |
295 | if ( res.state() != OSQLResult::Success ){ | 292 | if ( res.state() != OSQLResult::Success ){ |
296 | return false; | 293 | return false; |
297 | } | 294 | } |
298 | 295 | ||
299 | // Update list of uid's | 296 | // Update list of uid's |
300 | update(); | 297 | update(); |
301 | 298 | ||
302 | return true; | 299 | return true; |
303 | } | 300 | } |
304 | 301 | ||
305 | // FIXME: Speed up update of uid's.. | 302 | // FIXME: Speed up update of uid's.. |
306 | bool ODateBookAccessBackend_SQL::remove( int uid ) | 303 | bool ODateBookAccessBackend_SQL::remove( int uid ) |
307 | { | 304 | { |
308 | QString qu = "DELETE from datebook where uid = " | 305 | QString qu = "DELETE from datebook where uid = " |
309 | + QString::number( uid ) + ";"; | 306 | + QString::number( uid ) + ";"; |
310 | qu += "DELETE from custom_data where uid = " | 307 | qu += "DELETE from custom_data where uid = " |
311 | + QString::number( uid ) + ";"; | 308 | + QString::number( uid ) + ";"; |
312 | 309 | ||
313 | OSQLRawQuery raw( qu ); | 310 | OSQLRawQuery raw( qu ); |
314 | OSQLResult res = m_driver->query( &raw ); | 311 | OSQLResult res = m_driver->query( &raw ); |
315 | if ( res.state() != OSQLResult::Success ){ | 312 | if ( res.state() != OSQLResult::Success ){ |
316 | return false; | 313 | return false; |
317 | } | 314 | } |
318 | 315 | ||
319 | // Update list of uid's | 316 | // Update list of uid's |
320 | update(); | 317 | update(); |
321 | 318 | ||
322 | return true; | 319 | return true; |
323 | } | 320 | } |
324 | 321 | ||
325 | bool ODateBookAccessBackend_SQL::replace( const OPimEvent& ev ) | 322 | bool ODateBookAccessBackend_SQL::replace( const OPimEvent& ev ) |
326 | { | 323 | { |
327 | remove( ev.uid() ); | 324 | remove( ev.uid() ); |
328 | return add( ev ); | 325 | return add( ev ); |
329 | } | 326 | } |
330 | 327 | ||
331 | QArray<int> ODateBookAccessBackend_SQL::rawEvents()const | ||
332 | { | ||
333 | return allRecords(); | ||
334 | } | ||
335 | 328 | ||
336 | QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const | 329 | QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const |
337 | { | 330 | { |
338 | QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\""; | 331 | QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\""; |
339 | OSQLRawQuery raw( qu ); | 332 | OSQLRawQuery raw( qu ); |
340 | OSQLResult res = m_driver->query( &raw ); | 333 | OSQLResult res = m_driver->query( &raw ); |
341 | if ( res.state() != OSQLResult::Success ){ | 334 | if ( res.state() != OSQLResult::Success ){ |
342 | QArray<int> nix; | 335 | QArray<int> nix; |
343 | return nix; | 336 | return nix; |
344 | } | 337 | } |
345 | 338 | ||
346 | return extractUids( res ); | 339 | return extractUids( res ); |
347 | } | 340 | } |
348 | 341 | ||
349 | QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const | 342 | QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const |
350 | { | 343 | { |
351 | QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\""; | 344 | QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\""; |
352 | OSQLRawQuery raw( qu ); | 345 | OSQLRawQuery raw( qu ); |
353 | OSQLResult res = m_driver->query( &raw ); | 346 | OSQLResult res = m_driver->query( &raw ); |
354 | if ( res.state() != OSQLResult::Success ){ | 347 | if ( res.state() != OSQLResult::Success ){ |
355 | QArray<int> nix; | 348 | QArray<int> nix; |
356 | return nix; | 349 | return nix; |
357 | } | 350 | } |
358 | 351 | ||
359 | return extractUids( res ); | 352 | return extractUids( res ); |
360 | } | 353 | } |
361 | 354 | ||
362 | OPimEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() | 355 | OPimEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats()const |
363 | { | 356 | { |
364 | QArray<int> nonRepUids = nonRepeats(); | 357 | QArray<int> nonRepUids = nonRepeats(); |
365 | OPimEvent::ValueList list; | 358 | OPimEvent::ValueList list; |
366 | 359 | ||
367 | for (uint i = 0; i < nonRepUids.count(); ++i ){ | 360 | for (uint i = 0; i < nonRepUids.count(); ++i ){ |
368 | list.append( find( nonRepUids[i] ) ); | 361 | list.append( find( nonRepUids[i] ) ); |
369 | } | 362 | } |
370 | 363 | ||
371 | return list; | 364 | return list; |
372 | 365 | ||
373 | } | 366 | } |
374 | OPimEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() | 367 | OPimEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats()const |
375 | { | 368 | { |
376 | QArray<int> rawRepUids = rawRepeats(); | 369 | QArray<int> rawRepUids = rawRepeats(); |
377 | OPimEvent::ValueList list; | 370 | OPimEvent::ValueList list; |
378 | 371 | ||
379 | for (uint i = 0; i < rawRepUids.count(); ++i ){ | 372 | for (uint i = 0; i < rawRepUids.count(); ++i ){ |
380 | list.append( find( rawRepUids[i] ) ); | 373 | list.append( find( rawRepUids[i] ) ); |
381 | } | 374 | } |
382 | 375 | ||
383 | return list; | 376 | return list; |
384 | } | 377 | } |
385 | 378 | ||
386 | 379 | ||
387 | QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | 380 | QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const |
388 | { | 381 | { |
389 | 382 | ||
390 | QString qu = "SELECT uid FROM datebook WHERE ("; | 383 | QString qu = "SELECT uid FROM datebook WHERE ("; |
391 | 384 | ||
392 | // Do it make sense to search other fields, too ? | 385 | // Do it make sense to search other fields, too ? |
393 | qu += " rlike(\""+ r.pattern() + "\", Location ) OR"; | 386 | qu += " rlike(\""+ r.pattern() + "\", Location ) OR"; |
394 | qu += " rlike(\""+ r.pattern() + "\", Note )"; | 387 | qu += " rlike(\""+ r.pattern() + "\", Note )"; |
395 | 388 | ||
396 | qu += " )"; | 389 | qu += " )"; |
397 | 390 | ||
398 | odebug << "query: " << qu << "" << oendl; | 391 | odebug << "query: " << qu << "" << oendl; |
399 | 392 | ||
400 | OSQLRawQuery raw( qu ); | 393 | OSQLRawQuery raw( qu ); |
401 | OSQLResult res = m_driver->query( &raw ); | 394 | OSQLResult res = m_driver->query( &raw ); |
402 | 395 | ||
403 | return extractUids( res ); | 396 | return extractUids( res ); |
404 | 397 | ||
405 | 398 | ||
406 | 399 | ||
407 | } | 400 | } |
408 | 401 | ||
409 | /* ===== Private Functions ========================================== */ | 402 | /* ===== Private Functions ========================================== */ |
410 | 403 | ||
411 | QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const | 404 | QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const |
412 | { | 405 | { |
413 | owarn << "extractUids" << oendl; | ||
414 | QTime t; | 406 | QTime t; |
415 | t.start(); | 407 | t.start(); |
416 | OSQLResultItem::ValueList list = res.results(); | 408 | OSQLResultItem::ValueList list = res.results(); |
417 | OSQLResultItem::ValueList::Iterator it; | 409 | OSQLResultItem::ValueList::Iterator it; |
418 | QArray<int> ints(list.count() ); | 410 | QArray<int> ints(list.count() ); |
419 | owarn << " count = " << list.count() << "" << oendl; | ||
420 | 411 | ||
421 | int i = 0; | 412 | int i = 0; |
422 | for (it = list.begin(); it != list.end(); ++it ) { | 413 | for (it = list.begin(); it != list.end(); ++it ) { |
423 | ints[i] = (*it).data("uid").toInt(); | 414 | ints[i] = (*it).data("uid").toInt(); |
424 | i++; | 415 | i++; |
425 | } | 416 | } |
426 | owarn << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl; | ||
427 | 417 | ||
428 | return ints; | 418 | return ints; |
429 | 419 | ||
430 | } | 420 | } |
431 | 421 | ||
432 | QMap<QString, QString> ODateBookAccessBackend_SQL::requestCustom( int uid ) const | 422 | QMap<QString, QString> ODateBookAccessBackend_SQL::requestCustom( int uid ) const |
433 | { | 423 | { |
434 | QTime t; | 424 | QTime t; |
435 | t.start(); | 425 | t.start(); |
436 | 426 | ||
437 | QMap<QString, QString> customMap; | 427 | QMap<QString, QString> customMap; |
438 | 428 | ||
439 | FindCustomQuery query( uid ); | 429 | FindCustomQuery query( uid ); |
440 | OSQLResult res_custom = m_driver->query( &query ); | 430 | OSQLResult res_custom = m_driver->query( &query ); |
441 | 431 | ||
442 | if ( res_custom.state() == OSQLResult::Failure ) { | 432 | if ( res_custom.state() == OSQLResult::Failure ) { |
443 | owarn << "OSQLResult::Failure in find query !!" << oendl; | ||
444 | QMap<QString, QString> empty; | 433 | QMap<QString, QString> empty; |
445 | return empty; | 434 | return empty; |
446 | } | 435 | } |
447 | 436 | ||
448 | OSQLResultItem::ValueList list = res_custom.results(); | 437 | OSQLResultItem::ValueList list = res_custom.results(); |
449 | OSQLResultItem::ValueList::Iterator it = list.begin(); | 438 | OSQLResultItem::ValueList::Iterator it = list.begin(); |
450 | for ( ; it != list.end(); ++it ) { | 439 | for ( ; it != list.end(); ++it ) { |
451 | customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); | 440 | customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); |
452 | } | 441 | } |
453 | 442 | ||
454 | odebug << "RequestCustom needed: " << t.elapsed() << " ms" << oendl; | 443 | odebug << "RequestCustom needed: " << t.elapsed() << " ms" << oendl; |
455 | return customMap; | 444 | return customMap; |
456 | } | 445 | } |
457 | 446 | ||
458 | 447 | ||
459 | } | 448 | } |
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h index b624159..a649d25 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h | |||
@@ -1,99 +1,98 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | 29 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H |
30 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | 30 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H |
31 | 31 | ||
32 | #include <qmap.h> | 32 | #include <qmap.h> |
33 | #include <opie2/osqlresult.h> | 33 | #include <opie2/osqlresult.h> |
34 | 34 | ||
35 | #include <opie2/odatebookaccessbackend.h> | 35 | #include <opie2/odatebookaccessbackend.h> |
36 | 36 | ||
37 | namespace Opie { | 37 | namespace Opie { |
38 | namespace DB { | 38 | namespace DB { |
39 | class OSQLDriver; | 39 | class OSQLDriver; |
40 | } | 40 | } |
41 | } | 41 | } |
42 | 42 | ||
43 | namespace Opie { | 43 | namespace Opie { |
44 | /** | 44 | /** |
45 | * This is the default SQL implementation for DateBoook SQL storage | 45 | * This is the default SQL implementation for DateBoook SQL storage |
46 | * It fully implements the interface | 46 | * It fully implements the interface |
47 | * @see ODateBookAccessBackend | 47 | * @see ODateBookAccessBackend |
48 | * @see OPimAccessBackend | 48 | * @see OPimAccessBackend |
49 | */ | 49 | */ |
50 | class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { | 50 | class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { |
51 | public: | 51 | public: |
52 | ODateBookAccessBackend_SQL( const QString& appName, | 52 | ODateBookAccessBackend_SQL( const QString& appName, |
53 | const QString& fileName = QString::null); | 53 | const QString& fileName = QString::null); |
54 | ~ODateBookAccessBackend_SQL(); | 54 | ~ODateBookAccessBackend_SQL(); |
55 | 55 | ||
56 | bool load(); | 56 | bool load(); |
57 | bool reload(); | 57 | bool reload(); |
58 | bool save(); | 58 | bool save(); |
59 | 59 | ||
60 | QArray<int> allRecords()const; | 60 | QArray<int> allRecords()const; |
61 | QArray<int> matchRegexp(const QRegExp &r) const; | 61 | QArray<int> matchRegexp(const QRegExp &r) const; |
62 | QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() ); | 62 | QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() ); |
63 | OPimEvent find( int uid )const; | 63 | OPimEvent find( int uid )const; |
64 | void clear(); | 64 | void clear(); |
65 | bool add( const OPimEvent& ev ); | 65 | bool add( const OPimEvent& ev ); |
66 | bool remove( int uid ); | 66 | bool remove( int uid ); |
67 | bool replace( const OPimEvent& ev ); | 67 | bool replace( const OPimEvent& ev ); |
68 | 68 | ||
69 | QArray<UID> rawEvents()const; | ||
70 | QArray<UID> rawRepeats()const; | 69 | QArray<UID> rawRepeats()const; |
71 | QArray<UID> nonRepeats()const; | 70 | QArray<UID> nonRepeats()const; |
72 | 71 | ||
73 | OPimEvent::ValueList directNonRepeats(); | 72 | OPimEvent::ValueList directNonRepeats()const; |
74 | OPimEvent::ValueList directRawRepeats(); | 73 | OPimEvent::ValueList directRawRepeats()const; |
75 | 74 | ||
76 | private: | 75 | private: |
77 | bool loadFile(); | 76 | bool loadFile(); |
78 | QString m_fileName; | 77 | QString m_fileName; |
79 | QArray<int> m_uids; | 78 | QArray<int> m_uids; |
80 | 79 | ||
81 | QMap<int, QString> m_fieldMap; | 80 | QMap<int, QString> m_fieldMap; |
82 | QMap<QString, int> m_reverseFieldMap; | 81 | QMap<QString, int> m_reverseFieldMap; |
83 | 82 | ||
84 | Opie::DB::OSQLDriver* m_driver; | 83 | Opie::DB::OSQLDriver* m_driver; |
85 | 84 | ||
86 | class Private; | 85 | class Private; |
87 | Private *d; | 86 | Private *d; |
88 | 87 | ||
89 | void initFields(); | 88 | void initFields(); |
90 | void update(); | 89 | void update(); |
91 | 90 | ||
92 | QArray<int> extractUids( Opie::DB::OSQLResult& res ) const; | 91 | QArray<int> extractUids( Opie::DB::OSQLResult& res ) const; |
93 | QMap<QString, QString> requestCustom( int uid ) const; | 92 | QMap<QString, QString> requestCustom( int uid ) const; |
94 | 93 | ||
95 | }; | 94 | }; |
96 | 95 | ||
97 | } | 96 | } |
98 | 97 | ||
99 | #endif | 98 | #endif |
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp index 0f99d50..55e47e2 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp | |||
@@ -1,670 +1,664 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | /* OPIE */ | 30 | /* OPIE */ |
31 | #include <opie2/opimnotifymanager.h> | 31 | #include <opie2/opimnotifymanager.h> |
32 | #include <opie2/opimrecurrence.h> | 32 | #include <opie2/opimrecurrence.h> |
33 | #include <opie2/opimtimezone.h> | 33 | #include <opie2/opimtimezone.h> |
34 | #include <opie2/odatebookaccessbackend_xml.h> | 34 | #include <opie2/odatebookaccessbackend_xml.h> |
35 | #include <opie2/odebug.h> | 35 | #include <opie2/odebug.h> |
36 | 36 | ||
37 | #include <qtopia/global.h> | 37 | #include <qtopia/global.h> |
38 | #include <qtopia/stringutil.h> | 38 | #include <qtopia/stringutil.h> |
39 | #include <qtopia/timeconversion.h> | 39 | #include <qtopia/timeconversion.h> |
40 | 40 | ||
41 | /* QT */ | 41 | /* QT */ |
42 | #include <qasciidict.h> | 42 | #include <qasciidict.h> |
43 | #include <qfile.h> | 43 | #include <qfile.h> |
44 | 44 | ||
45 | /* STD */ | 45 | /* STD */ |
46 | #include <errno.h> | 46 | #include <errno.h> |
47 | #include <fcntl.h> | 47 | #include <fcntl.h> |
48 | 48 | ||
49 | #include <stdio.h> | 49 | #include <stdio.h> |
50 | #include <stdlib.h> | 50 | #include <stdlib.h> |
51 | 51 | ||
52 | #include <sys/types.h> | 52 | #include <sys/types.h> |
53 | #include <sys/mman.h> | 53 | #include <sys/mman.h> |
54 | #include <sys/stat.h> | 54 | #include <sys/stat.h> |
55 | 55 | ||
56 | #include <unistd.h> | 56 | #include <unistd.h> |
57 | 57 | ||
58 | 58 | ||
59 | using namespace Opie; | 59 | using namespace Opie; |
60 | 60 | ||
61 | namespace { | 61 | namespace { |
62 | // FROM TT again | 62 | // FROM TT again |
63 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) | 63 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) |
64 | { | 64 | { |
65 | char needleChar; | 65 | char needleChar; |
66 | char haystackChar; | 66 | char haystackChar; |
67 | if (!needle || !haystack || !hLen || !nLen) | 67 | if (!needle || !haystack || !hLen || !nLen) |
68 | return 0; | 68 | return 0; |
69 | 69 | ||
70 | const char* hsearch = haystack; | 70 | const char* hsearch = haystack; |
71 | 71 | ||
72 | if ((needleChar = *needle++) != 0) { | 72 | if ((needleChar = *needle++) != 0) { |
73 | nLen--; //(to make up for needle++) | 73 | nLen--; //(to make up for needle++) |
74 | do { | 74 | do { |
75 | do { | 75 | do { |
76 | if ((haystackChar = *hsearch++) == 0) | 76 | if ((haystackChar = *hsearch++) == 0) |
77 | return (0); | 77 | return (0); |
78 | if (hsearch >= haystack + hLen) | 78 | if (hsearch >= haystack + hLen) |
79 | return (0); | 79 | return (0); |
80 | } while (haystackChar != needleChar); | 80 | } while (haystackChar != needleChar); |
81 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); | 81 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); |
82 | hsearch--; | 82 | hsearch--; |
83 | } | 83 | } |
84 | return ((char *)hsearch); | 84 | return ((char *)hsearch); |
85 | } | 85 | } |
86 | } | 86 | } |
87 | 87 | ||
88 | namespace { | 88 | namespace { |
89 | time_t start, end, created, rp_end; | 89 | time_t start, end, created, rp_end; |
90 | OPimRecurrence* rec; | 90 | OPimRecurrence* rec; |
91 | static OPimRecurrence* recur() { | 91 | static OPimRecurrence* recur() { |
92 | if (!rec) | 92 | if (!rec) |
93 | rec = new OPimRecurrence; | 93 | rec = new OPimRecurrence; |
94 | 94 | ||
95 | return rec; | 95 | return rec; |
96 | } | 96 | } |
97 | int alarmTime; | 97 | int alarmTime; |
98 | int snd; | 98 | int snd; |
99 | enum Attribute{ | 99 | enum Attribute{ |
100 | FDescription = 0, | 100 | FDescription = 0, |
101 | FLocation, | 101 | FLocation, |
102 | FCategories, | 102 | FCategories, |
103 | FUid, | 103 | FUid, |
104 | FType, | 104 | FType, |
105 | FAlarm, | 105 | FAlarm, |
106 | FSound, | 106 | FSound, |
107 | FRType, | 107 | FRType, |
108 | FRWeekdays, | 108 | FRWeekdays, |
109 | FRPosition, | 109 | FRPosition, |
110 | FRFreq, | 110 | FRFreq, |
111 | FRHasEndDate, | 111 | FRHasEndDate, |
112 | FREndDate, | 112 | FREndDate, |
113 | FRStart, | 113 | FRStart, |
114 | FREnd, | 114 | FREnd, |
115 | FNote, | 115 | FNote, |
116 | FCreated, // Should't this be called FRCreated ? | 116 | FCreated, // Should't this be called FRCreated ? |
117 | FTimeZone, | 117 | FTimeZone, |
118 | FRecParent, | 118 | FRecParent, |
119 | FRecChildren, | 119 | FRecChildren, |
120 | FExceptions | 120 | FExceptions |
121 | }; | 121 | }; |
122 | 122 | ||
123 | // FIXME: Use OPimEvent::toMap() here !! (eilers) | 123 | // FIXME: Use OPimEvent::toMap() here !! (eilers) |
124 | static void save( const OPimEvent& ev, QString& buf ) { | 124 | static void save( const OPimEvent& ev, QString& buf ) { |
125 | owarn << "Saving " << ev.uid() << " " << ev.description() << "" << oendl; | ||
126 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; | 125 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; |
127 | if (!ev.location().isEmpty() ) | 126 | if (!ev.location().isEmpty() ) |
128 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; | 127 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; |
129 | 128 | ||
130 | if (!ev.categories().isEmpty() ) | 129 | if (!ev.categories().isEmpty() ) |
131 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; | 130 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; |
132 | 131 | ||
133 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; | 132 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; |
134 | 133 | ||
135 | if (ev.isAllDay() ) | 134 | if (ev.isAllDay() ) |
136 | buf += " type=\"AllDay\""; // is that all ?? (eilers) | 135 | buf += " type=\"AllDay\""; // is that all ?? (eilers) |
137 | 136 | ||
138 | if (ev.hasNotifiers() ) { | 137 | if (ev.hasNotifiers() ) { |
139 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first | 138 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first |
140 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; | 139 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; |
141 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; | 140 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; |
142 | if ( alarm.sound() == OPimAlarm::Loud ) | 141 | if ( alarm.sound() == OPimAlarm::Loud ) |
143 | buf += "loud"; | 142 | buf += "loud"; |
144 | else | 143 | else |
145 | buf += "silent"; | 144 | buf += "silent"; |
146 | buf += "\""; | 145 | buf += "\""; |
147 | } | 146 | } |
148 | if ( ev.hasRecurrence() ) { | 147 | if ( ev.hasRecurrence() ) { |
149 | buf += ev.recurrence().toString(); | 148 | buf += ev.recurrence().toString(); |
150 | } | 149 | } |
151 | 150 | ||
152 | /* | 151 | /* |
153 | * fscking timezones :) well, we'll first convert | 152 | * fscking timezones :) well, we'll first convert |
154 | * the QDateTime to a QDateTime in UTC time | 153 | * the QDateTime to a QDateTime in UTC time |
155 | * and then we'll create a nice time_t | 154 | * and then we'll create a nice time_t |
156 | */ | 155 | */ |
157 | OPimTimeZone zone( (ev.timeZone().isEmpty()||ev.isAllDay()) ? OPimTimeZone::utc() : OPimTimeZone::current() ); | 156 | OPimTimeZone zone( (ev.timeZone().isEmpty()||ev.isAllDay()) ? OPimTimeZone::utc() : OPimTimeZone::current() ); |
158 | buf += " start=\"" + QString::number( zone.fromDateTime( ev.startDateTime())) + "\""; | 157 | buf += " start=\"" + QString::number( zone.fromDateTime( ev.startDateTime())) + "\""; |
159 | buf += " end=\"" + QString::number( zone.fromDateTime( ev.endDateTime() )) + "\""; | 158 | buf += " end=\"" + QString::number( zone.fromDateTime( ev.endDateTime() )) + "\""; |
160 | if (!ev.note().isEmpty() ) { | 159 | if (!ev.note().isEmpty() ) { |
161 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; | 160 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; |
162 | } | 161 | } |
163 | 162 | ||
164 | /* | 163 | /* |
165 | * Don't save a timezone if AllDay Events | 164 | * Don't save a timezone if AllDay Events |
166 | * as they're UTC only anyway | 165 | * as they're UTC only anyway |
167 | */ | 166 | */ |
168 | if (!ev.isAllDay() ) { | 167 | if (!ev.isAllDay() ) { |
169 | 168 | ||
170 | buf += " timezone=\""; | 169 | buf += " timezone=\""; |
171 | if ( ev.timeZone().isEmpty() ) | 170 | if ( ev.timeZone().isEmpty() ) |
172 | buf += "None"; | 171 | buf += "None"; |
173 | else | 172 | else |
174 | buf += ev.timeZone(); | 173 | buf += ev.timeZone(); |
175 | buf += "\""; | 174 | buf += "\""; |
176 | } | 175 | } |
177 | 176 | ||
178 | if (ev.parent() != 0 ) { | 177 | if (ev.parent() != 0 ) { |
179 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; | 178 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; |
180 | } | 179 | } |
181 | 180 | ||
182 | if (ev.children().count() != 0 ) { | 181 | if (ev.children().count() != 0 ) { |
183 | QArray<int> children = ev.children(); | 182 | QArray<int> children = ev.children(); |
184 | buf += " recchildren=\""; | 183 | buf += " recchildren=\""; |
185 | for ( uint i = 0; i < children.count(); i++ ) { | 184 | for ( uint i = 0; i < children.count(); i++ ) { |
186 | if ( i != 0 ) buf += " "; | 185 | if ( i != 0 ) buf += " "; |
187 | buf += QString::number( children[i] ); | 186 | buf += QString::number( children[i] ); |
188 | } | 187 | } |
189 | buf+= "\""; | 188 | buf+= "\""; |
190 | } | 189 | } |
191 | 190 | ||
192 | // skip custom writing | 191 | // skip custom writing |
193 | } | 192 | } |
194 | 193 | ||
195 | static bool saveEachEvent( const QMap<int, OPimEvent>& list, QFile& file ) { | 194 | static bool saveEachEvent( const QMap<int, OPimEvent>& list, QFile& file ) { |
196 | QMap<int, OPimEvent>::ConstIterator it; | 195 | QMap<int, OPimEvent>::ConstIterator it; |
197 | QString buf; | 196 | QString buf; |
198 | QCString str; | 197 | QCString str; |
199 | int total_written; | 198 | int total_written; |
200 | for ( it = list.begin(); it != list.end(); ++it ) { | 199 | for ( it = list.begin(); it != list.end(); ++it ) { |
201 | buf = "<event"; | 200 | buf = "<event"; |
202 | save( it.data(), buf ); | 201 | save( it.data(), buf ); |
203 | buf += " />\n"; | 202 | buf += " />\n"; |
204 | str = buf.utf8(); | 203 | str = buf.utf8(); |
205 | 204 | ||
206 | total_written = file.writeBlock(str.data(), str.length() ); | 205 | total_written = file.writeBlock(str.data(), str.length() ); |
207 | if ( total_written != int(str.length() ) ) | 206 | if ( total_written != int(str.length() ) ) |
208 | return false; | 207 | return false; |
209 | } | 208 | } |
210 | return true; | 209 | return true; |
211 | } | 210 | } |
212 | } | 211 | } |
213 | 212 | ||
214 | namespace Opie { | 213 | namespace Opie { |
215 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , | 214 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , |
216 | const QString& fileName ) | 215 | const QString& fileName ) |
217 | : ODateBookAccessBackend() { | 216 | : ODateBookAccessBackend() { |
218 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; | 217 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; |
219 | m_changed = false; | 218 | m_changed = false; |
220 | } | 219 | } |
221 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { | 220 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { |
222 | } | 221 | } |
223 | bool ODateBookAccessBackend_XML::load() { | 222 | bool ODateBookAccessBackend_XML::load() { |
224 | return loadFile(); | 223 | return loadFile(); |
225 | } | 224 | } |
226 | bool ODateBookAccessBackend_XML::reload() { | 225 | bool ODateBookAccessBackend_XML::reload() { |
227 | clear(); | 226 | clear(); |
228 | return load(); | 227 | return load(); |
229 | } | 228 | } |
230 | bool ODateBookAccessBackend_XML::save() { | 229 | bool ODateBookAccessBackend_XML::save() { |
231 | if (!m_changed) return true; | 230 | if (!m_changed) return true; |
232 | 231 | ||
233 | int total_written; | 232 | int total_written; |
234 | QString strFileNew = m_name + ".new"; | 233 | QString strFileNew = m_name + ".new"; |
235 | 234 | ||
236 | QFile f( strFileNew ); | 235 | QFile f( strFileNew ); |
237 | if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; | 236 | if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; |
238 | 237 | ||
239 | QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); | 238 | QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); |
240 | buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; | 239 | buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; |
241 | buf += "<events>\n"; | 240 | buf += "<events>\n"; |
242 | QCString str = buf.utf8(); | 241 | QCString str = buf.utf8(); |
243 | total_written = f.writeBlock( str.data(), str.length() ); | 242 | total_written = f.writeBlock( str.data(), str.length() ); |
244 | if ( total_written != int(str.length() ) ) { | 243 | if ( total_written != int(str.length() ) ) { |
245 | f.close(); | 244 | f.close(); |
246 | QFile::remove( strFileNew ); | 245 | QFile::remove( strFileNew ); |
247 | return false; | 246 | return false; |
248 | } | 247 | } |
249 | 248 | ||
250 | if (!saveEachEvent( m_raw, f ) ) { | 249 | if (!saveEachEvent( m_raw, f ) ) { |
251 | f.close(); | 250 | f.close(); |
252 | QFile::remove( strFileNew ); | 251 | QFile::remove( strFileNew ); |
253 | return false; | 252 | return false; |
254 | } | 253 | } |
255 | if (!saveEachEvent( m_rep, f ) ) { | 254 | if (!saveEachEvent( m_rep, f ) ) { |
256 | f.close(); | 255 | f.close(); |
257 | QFile::remove( strFileNew ); | 256 | QFile::remove( strFileNew ); |
258 | return false; | 257 | return false; |
259 | } | 258 | } |
260 | 259 | ||
261 | buf = "</events>\n</DATEBOOK>\n"; | 260 | buf = "</events>\n</DATEBOOK>\n"; |
262 | str = buf.utf8(); | 261 | str = buf.utf8(); |
263 | total_written = f.writeBlock( str.data(), str.length() ); | 262 | total_written = f.writeBlock( str.data(), str.length() ); |
264 | if ( total_written != int(str.length() ) ) { | 263 | if ( total_written != int(str.length() ) ) { |
265 | f.close(); | 264 | f.close(); |
266 | QFile::remove( strFileNew ); | 265 | QFile::remove( strFileNew ); |
267 | return false; | 266 | return false; |
268 | } | 267 | } |
269 | f.close(); | 268 | f.close(); |
270 | 269 | ||
271 | if ( ::rename( strFileNew, m_name ) < 0 ) { | 270 | if ( ::rename( strFileNew, m_name ) < 0 ) { |
272 | QFile::remove( strFileNew ); | 271 | QFile::remove( strFileNew ); |
273 | return false; | 272 | return false; |
274 | } | 273 | } |
275 | 274 | ||
276 | m_changed = false; | 275 | m_changed = false; |
277 | return true; | 276 | return true; |
278 | } | 277 | } |
279 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { | 278 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { |
280 | QArray<int> ints( m_raw.count()+ m_rep.count() ); | 279 | QArray<int> ints( m_raw.count()+ m_rep.count() ); |
281 | uint i = 0; | 280 | uint i = 0; |
282 | QMap<int, OPimEvent>::ConstIterator it; | 281 | QMap<int, OPimEvent>::ConstIterator it; |
283 | 282 | ||
284 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 283 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
285 | ints[i] = it.key(); | 284 | ints[i] = it.key(); |
286 | i++; | 285 | i++; |
287 | } | 286 | } |
288 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 287 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
289 | ints[i] = it.key(); | 288 | ints[i] = it.key(); |
290 | i++; | 289 | i++; |
291 | } | 290 | } |
292 | 291 | ||
293 | return ints; | 292 | return ints; |
294 | } | 293 | } |
295 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OPimEvent&, int, const QDateTime& ) { | 294 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OPimEvent&, int, const QDateTime& ) { |
296 | return QArray<int>(); | 295 | return QArray<int>(); |
297 | } | 296 | } |
298 | void ODateBookAccessBackend_XML::clear() { | 297 | void ODateBookAccessBackend_XML::clear() { |
299 | m_changed = true; | 298 | m_changed = true; |
300 | m_raw.clear(); | 299 | m_raw.clear(); |
301 | m_rep.clear(); | 300 | m_rep.clear(); |
302 | } | 301 | } |
303 | OPimEvent ODateBookAccessBackend_XML::find( int uid ) const{ | 302 | OPimEvent ODateBookAccessBackend_XML::find( int uid ) const{ |
304 | if ( m_raw.contains( uid ) ) | 303 | if ( m_raw.contains( uid ) ) |
305 | return m_raw[uid]; | 304 | return m_raw[uid]; |
306 | else | 305 | else |
307 | return m_rep[uid]; | 306 | return m_rep[uid]; |
308 | } | 307 | } |
309 | bool ODateBookAccessBackend_XML::add( const OPimEvent& ev ) { | 308 | bool ODateBookAccessBackend_XML::add( const OPimEvent& ev ) { |
310 | m_changed = true; | 309 | m_changed = true; |
311 | if (ev.hasRecurrence() ) | 310 | if (ev.hasRecurrence() ) |
312 | m_rep.insert( ev.uid(), ev ); | 311 | m_rep.insert( ev.uid(), ev ); |
313 | else | 312 | else |
314 | m_raw.insert( ev.uid(), ev ); | 313 | m_raw.insert( ev.uid(), ev ); |
315 | 314 | ||
316 | return true; | 315 | return true; |
317 | } | 316 | } |
318 | bool ODateBookAccessBackend_XML::remove( int uid ) { | 317 | bool ODateBookAccessBackend_XML::remove( int uid ) { |
319 | m_changed = true; | 318 | m_changed = true; |
320 | m_raw.remove( uid ); | 319 | m_raw.remove( uid ); |
321 | m_rep.remove( uid ); | 320 | m_rep.remove( uid ); |
322 | 321 | ||
323 | return true; | 322 | return true; |
324 | } | 323 | } |
325 | bool ODateBookAccessBackend_XML::replace( const OPimEvent& ev ) { | 324 | bool ODateBookAccessBackend_XML::replace( const OPimEvent& ev ) { |
326 | replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers) | 325 | replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers) |
327 | return add( ev ); | 326 | return add( ev ); |
328 | } | 327 | } |
329 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { | 328 | |
330 | return allRecords(); | ||
331 | } | ||
332 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { | 329 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { |
333 | QArray<int> ints( m_rep.count() ); | 330 | QArray<int> ints( m_rep.count() ); |
334 | uint i = 0; | 331 | uint i = 0; |
335 | QMap<int, OPimEvent>::ConstIterator it; | 332 | QMap<int, OPimEvent>::ConstIterator it; |
336 | 333 | ||
337 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 334 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
338 | ints[i] = it.key(); | 335 | ints[i] = it.key(); |
339 | i++; | 336 | i++; |
340 | } | 337 | } |
341 | 338 | ||
342 | return ints; | 339 | return ints; |
343 | } | 340 | } |
344 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { | 341 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { |
345 | QArray<int> ints( m_raw.count() ); | 342 | QArray<int> ints( m_raw.count() ); |
346 | uint i = 0; | 343 | uint i = 0; |
347 | QMap<int, OPimEvent>::ConstIterator it; | 344 | QMap<int, OPimEvent>::ConstIterator it; |
348 | 345 | ||
349 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 346 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
350 | ints[i] = it.key(); | 347 | ints[i] = it.key(); |
351 | i++; | 348 | i++; |
352 | } | 349 | } |
353 | 350 | ||
354 | return ints; | 351 | return ints; |
355 | } | 352 | } |
356 | OPimEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { | 353 | OPimEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats()const { |
357 | OPimEvent::ValueList list; | 354 | OPimEvent::ValueList list; |
358 | QMap<int, OPimEvent>::ConstIterator it; | 355 | QMap<int, OPimEvent>::ConstIterator it; |
359 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) | 356 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) |
360 | list.append( it.data() ); | 357 | list.append( it.data() ); |
361 | 358 | ||
362 | return list; | 359 | return list; |
363 | } | 360 | } |
364 | OPimEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { | 361 | OPimEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats()const { |
365 | OPimEvent::ValueList list; | 362 | OPimEvent::ValueList list; |
366 | QMap<int, OPimEvent>::ConstIterator it; | 363 | QMap<int, OPimEvent>::ConstIterator it; |
367 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) | 364 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) |
368 | list.append( it.data() ); | 365 | list.append( it.data() ); |
369 | 366 | ||
370 | return list; | 367 | return list; |
371 | } | 368 | } |
372 | 369 | ||
373 | // FIXME: Use OPimEvent::fromMap() (eilers) | 370 | // FIXME: Use OPimEvent::fromMap() (eilers) |
374 | bool ODateBookAccessBackend_XML::loadFile() { | 371 | bool ODateBookAccessBackend_XML::loadFile() { |
375 | m_changed = false; | 372 | m_changed = false; |
376 | 373 | ||
377 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); | 374 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); |
378 | if ( fd < 0 ) return false; | 375 | if ( fd < 0 ) return false; |
379 | 376 | ||
380 | struct stat attribute; | 377 | struct stat attribute; |
381 | if ( ::fstat(fd, &attribute ) == -1 ) { | 378 | if ( ::fstat(fd, &attribute ) == -1 ) { |
382 | ::close( fd ); | 379 | ::close( fd ); |
383 | return false; | 380 | return false; |
384 | } | 381 | } |
385 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 382 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
386 | if ( map_addr == ( (caddr_t)-1) ) { | 383 | if ( map_addr == ( (caddr_t)-1) ) { |
387 | ::close( fd ); | 384 | ::close( fd ); |
388 | return false; | 385 | return false; |
389 | } | 386 | } |
390 | 387 | ||
391 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); | 388 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); |
392 | ::close( fd ); | 389 | ::close( fd ); |
393 | 390 | ||
394 | QAsciiDict<int> dict(FExceptions+1); | 391 | QAsciiDict<int> dict(FExceptions+1); |
395 | dict.setAutoDelete( true ); | 392 | dict.setAutoDelete( true ); |
396 | dict.insert( "description", new int(FDescription) ); | 393 | dict.insert( "description", new int(FDescription) ); |
397 | dict.insert( "location", new int(FLocation) ); | 394 | dict.insert( "location", new int(FLocation) ); |
398 | dict.insert( "categories", new int(FCategories) ); | 395 | dict.insert( "categories", new int(FCategories) ); |
399 | dict.insert( "uid", new int(FUid) ); | 396 | dict.insert( "uid", new int(FUid) ); |
400 | dict.insert( "type", new int(FType) ); | 397 | dict.insert( "type", new int(FType) ); |
401 | dict.insert( "alarm", new int(FAlarm) ); | 398 | dict.insert( "alarm", new int(FAlarm) ); |
402 | dict.insert( "sound", new int(FSound) ); | 399 | dict.insert( "sound", new int(FSound) ); |
403 | dict.insert( "rtype", new int(FRType) ); | 400 | dict.insert( "rtype", new int(FRType) ); |
404 | dict.insert( "rweekdays", new int(FRWeekdays) ); | 401 | dict.insert( "rweekdays", new int(FRWeekdays) ); |
405 | dict.insert( "rposition", new int(FRPosition) ); | 402 | dict.insert( "rposition", new int(FRPosition) ); |
406 | dict.insert( "rfreq", new int(FRFreq) ); | 403 | dict.insert( "rfreq", new int(FRFreq) ); |
407 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); | 404 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); |
408 | dict.insert( "enddt", new int(FREndDate) ); | 405 | dict.insert( "enddt", new int(FREndDate) ); |
409 | dict.insert( "start", new int(FRStart) ); | 406 | dict.insert( "start", new int(FRStart) ); |
410 | dict.insert( "end", new int(FREnd) ); | 407 | dict.insert( "end", new int(FREnd) ); |
411 | dict.insert( "note", new int(FNote) ); | 408 | dict.insert( "note", new int(FNote) ); |
412 | dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? | 409 | dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? |
413 | dict.insert( "recparent", new int(FRecParent) ); | 410 | dict.insert( "recparent", new int(FRecParent) ); |
414 | dict.insert( "recchildren", new int(FRecChildren) ); | 411 | dict.insert( "recchildren", new int(FRecChildren) ); |
415 | dict.insert( "exceptions", new int(FExceptions) ); | 412 | dict.insert( "exceptions", new int(FExceptions) ); |
416 | dict.insert( "timezone", new int(FTimeZone) ); | 413 | dict.insert( "timezone", new int(FTimeZone) ); |
417 | 414 | ||
418 | 415 | ||
419 | // initialiaze db hack | 416 | // initialiaze db hack |
420 | m_noTimeZone = true; | 417 | m_noTimeZone = true; |
421 | 418 | ||
422 | char* dt = (char*)map_addr; | 419 | char* dt = (char*)map_addr; |
423 | int len = attribute.st_size; | 420 | int len = attribute.st_size; |
424 | int i = 0; | 421 | int i = 0; |
425 | char* point; | 422 | char* point; |
426 | const char* collectionString = "<event "; | 423 | const char* collectionString = "<event "; |
427 | int strLen = ::strlen(collectionString); | 424 | int strLen = ::strlen(collectionString); |
428 | int *find; | 425 | int *find; |
429 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { | 426 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { |
430 | i = point -dt; | 427 | i = point -dt; |
431 | i+= strLen; | 428 | i+= strLen; |
432 | 429 | ||
433 | alarmTime = -1; | 430 | alarmTime = -1; |
434 | snd = 0; // silent | 431 | snd = 0; // silent |
435 | 432 | ||
436 | OPimEvent ev; | 433 | OPimEvent ev; |
437 | rec = 0; | 434 | rec = 0; |
438 | 435 | ||
439 | while ( TRUE ) { | 436 | while ( TRUE ) { |
440 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 437 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
441 | ++i; | 438 | ++i; |
442 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 439 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
443 | break; | 440 | break; |
444 | 441 | ||
445 | 442 | ||
446 | // we have another attribute, read it. | 443 | // we have another attribute, read it. |
447 | int j = i; | 444 | int j = i; |
448 | while ( j < len && dt[j] != '=' ) | 445 | while ( j < len && dt[j] != '=' ) |
449 | ++j; | 446 | ++j; |
450 | QCString attr( dt+i, j-i+1); | 447 | QCString attr( dt+i, j-i+1); |
451 | 448 | ||
452 | i = ++j; // skip = | 449 | i = ++j; // skip = |
453 | 450 | ||
454 | // find the start of quotes | 451 | // find the start of quotes |
455 | while ( i < len && dt[i] != '"' ) | 452 | while ( i < len && dt[i] != '"' ) |
456 | ++i; | 453 | ++i; |
457 | j = ++i; | 454 | j = ++i; |
458 | 455 | ||
459 | bool haveUtf = FALSE; | 456 | bool haveUtf = FALSE; |
460 | bool haveEnt = FALSE; | 457 | bool haveEnt = FALSE; |
461 | while ( j < len && dt[j] != '"' ) { | 458 | while ( j < len && dt[j] != '"' ) { |
462 | if ( ((unsigned char)dt[j]) > 0x7f ) | 459 | if ( ((unsigned char)dt[j]) > 0x7f ) |
463 | haveUtf = TRUE; | 460 | haveUtf = TRUE; |
464 | if ( dt[j] == '&' ) | 461 | if ( dt[j] == '&' ) |
465 | haveEnt = TRUE; | 462 | haveEnt = TRUE; |
466 | ++j; | 463 | ++j; |
467 | } | 464 | } |
468 | if ( i == j ) { | 465 | if ( i == j ) { |
469 | // empty value | 466 | // empty value |
470 | i = j + 1; | 467 | i = j + 1; |
471 | continue; | 468 | continue; |
472 | } | 469 | } |
473 | 470 | ||
474 | QCString value( dt+i, j-i+1 ); | 471 | QCString value( dt+i, j-i+1 ); |
475 | i = j + 1; | 472 | i = j + 1; |
476 | 473 | ||
477 | QString str = (haveUtf ? QString::fromUtf8( value ) | 474 | QString str = (haveUtf ? QString::fromUtf8( value ) |
478 | : QString::fromLatin1( value ) ); | 475 | : QString::fromLatin1( value ) ); |
479 | if ( haveEnt ) | 476 | if ( haveEnt ) |
480 | str = Qtopia::plainString( str ); | 477 | str = Qtopia::plainString( str ); |
481 | 478 | ||
482 | /* | 479 | /* |
483 | * add key + value | 480 | * add key + value |
484 | */ | 481 | */ |
485 | find = dict[attr.data()]; | 482 | find = dict[attr.data()]; |
486 | if (!find) | 483 | if (!find) |
487 | ev.setCustomField( attr, str ); | 484 | ev.setCustomField( attr, str ); |
488 | else { | 485 | else { |
489 | setField( ev, *find, str ); | 486 | setField( ev, *find, str ); |
490 | } | 487 | } |
491 | } | 488 | } |
492 | /* time to finalize */ | 489 | /* time to finalize */ |
493 | finalizeRecord( ev ); | 490 | finalizeRecord( ev ); |
494 | delete rec; | 491 | delete rec; |
495 | m_noTimeZone = true; | 492 | m_noTimeZone = true; |
496 | } | 493 | } |
497 | ::munmap(map_addr, attribute.st_size ); | 494 | ::munmap(map_addr, attribute.st_size ); |
498 | m_changed = false; // changed during add | 495 | m_changed = false; // changed during add |
499 | 496 | ||
500 | return true; | 497 | return true; |
501 | } | 498 | } |
502 | 499 | ||
503 | // FIXME: Use OPimEvent::fromMap() which makes this obsolete.. (eilers) | 500 | // FIXME: Use OPimEvent::fromMap() which makes this obsolete.. (eilers) |
504 | void ODateBookAccessBackend_XML::finalizeRecord( OPimEvent& ev ) { | 501 | void ODateBookAccessBackend_XML::finalizeRecord( OPimEvent& ev ) { |
505 | 502 | ||
506 | /* | 503 | /* |
507 | * quirk to import datebook files. They normally don't have a | 504 | * quirk to import datebook files. They normally don't have a |
508 | * timeZone attribute and we treat this as to use OPimTimeZone::current() | 505 | * timeZone attribute and we treat this as to use OPimTimeZone::current() |
509 | */ | 506 | */ |
510 | if (m_noTimeZone ) | 507 | if (m_noTimeZone ) |
511 | ev.setTimeZone( OPimTimeZone::current().timeZone() ); | 508 | ev.setTimeZone( OPimTimeZone::current().timeZone() ); |
512 | 509 | ||
513 | 510 | ||
514 | 511 | ||
515 | /* AllDay is alway in UTC */ | 512 | /* AllDay is alway in UTC */ |
516 | if ( ev.isAllDay() ) { | 513 | if ( ev.isAllDay() ) { |
517 | OPimTimeZone utc = OPimTimeZone::utc(); | 514 | OPimTimeZone utc = OPimTimeZone::utc(); |
518 | ev.setStartDateTime( utc.toDateTime( start ) ); | 515 | ev.setStartDateTime( utc.toDateTime( start ) ); |
519 | ev.setEndDateTime ( utc.toDateTime( end ) ); | 516 | ev.setEndDateTime ( utc.toDateTime( end ) ); |
520 | }else { | 517 | }else { |
521 | /* to current date time */ | 518 | /* to current date time */ |
522 | OPimTimeZone to_zone( ev.timeZone().isEmpty() ? OPimTimeZone::utc() : OPimTimeZone::current() ); | 519 | OPimTimeZone to_zone( ev.timeZone().isEmpty() ? OPimTimeZone::utc() : OPimTimeZone::current() ); |
523 | 520 | ||
524 | ev.setStartDateTime(to_zone.toDateTime( start)); | 521 | ev.setStartDateTime(to_zone.toDateTime( start)); |
525 | ev.setEndDateTime (to_zone.toDateTime( end)); | 522 | ev.setEndDateTime (to_zone.toDateTime( end)); |
526 | } | 523 | } |
527 | if ( rec && rec->doesRecur() ) { | 524 | if ( rec && rec->doesRecur() ) { |
528 | OPimTimeZone utc = OPimTimeZone::utc(); | 525 | OPimTimeZone utc = OPimTimeZone::utc(); |
529 | OPimRecurrence recu( *rec ); // call copy c'tor; | 526 | OPimRecurrence recu( *rec ); // call copy c'tor; |
530 | recu.setEndDate ( utc.toDateTime( rp_end ).date() ); | 527 | recu.setEndDate ( utc.toDateTime( rp_end ).date() ); |
531 | recu.setCreatedDateTime( utc.toDateTime( created ) ); | 528 | recu.setCreatedDateTime( utc.toDateTime( created ) ); |
532 | recu.setStart( ev.startDateTime().date() ); | 529 | recu.setStart( ev.startDateTime().date() ); |
533 | ev.setRecurrence( recu ); | 530 | ev.setRecurrence( recu ); |
534 | } | 531 | } |
535 | 532 | ||
536 | if (alarmTime != -1 ) { | 533 | if (alarmTime != -1 ) { |
537 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); | 534 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); |
538 | OPimAlarm al( snd , dt ); | 535 | OPimAlarm al( snd , dt ); |
539 | ev.notifiers().add( al ); | 536 | ev.notifiers().add( al ); |
540 | } | 537 | } |
541 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { | 538 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { |
542 | owarn << "already contains assign uid" << oendl; | ||
543 | ev.setUid( 1 ); | 539 | ev.setUid( 1 ); |
544 | } | 540 | } |
545 | 541 | ||
546 | if ( ev.hasRecurrence() ) | 542 | if ( ev.hasRecurrence() ) |
547 | m_rep.insert( ev.uid(), ev ); | 543 | m_rep.insert( ev.uid(), ev ); |
548 | else | 544 | else |
549 | m_raw.insert( ev.uid(), ev ); | 545 | m_raw.insert( ev.uid(), ev ); |
550 | 546 | ||
551 | } | 547 | } |
552 | void ODateBookAccessBackend_XML::setField( OPimEvent& e, int id, const QString& value) { | 548 | void ODateBookAccessBackend_XML::setField( OPimEvent& e, int id, const QString& value) { |
553 | // owarn << " setting " << value << "" << oendl; | ||
554 | switch( id ) { | 549 | switch( id ) { |
555 | case FDescription: | 550 | case FDescription: |
556 | e.setDescription( value ); | 551 | e.setDescription( value ); |
557 | break; | 552 | break; |
558 | case FLocation: | 553 | case FLocation: |
559 | e.setLocation( value ); | 554 | e.setLocation( value ); |
560 | break; | 555 | break; |
561 | case FCategories: | 556 | case FCategories: |
562 | e.setCategories( e.idsFromString( value ) ); | 557 | e.setCategories( e.idsFromString( value ) ); |
563 | break; | 558 | break; |
564 | case FUid: | 559 | case FUid: |
565 | e.setUid( value.toInt() ); | 560 | e.setUid( value.toInt() ); |
566 | break; | 561 | break; |
567 | case FType: | 562 | case FType: |
568 | if ( value == "AllDay" ) { | 563 | if ( value == "AllDay" ) { |
569 | e.setAllDay( true ); | 564 | e.setAllDay( true ); |
570 | } | 565 | } |
571 | break; | 566 | break; |
572 | case FAlarm: | 567 | case FAlarm: |
573 | alarmTime = value.toInt(); | 568 | alarmTime = value.toInt(); |
574 | break; | 569 | break; |
575 | case FSound: | 570 | case FSound: |
576 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; | 571 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; |
577 | break; | 572 | break; |
578 | // recurrence stuff | 573 | // recurrence stuff |
579 | case FRType: | 574 | case FRType: |
580 | if ( value == "Daily" ) | 575 | if ( value == "Daily" ) |
581 | recur()->setType( OPimRecurrence::Daily ); | 576 | recur()->setType( OPimRecurrence::Daily ); |
582 | else if ( value == "Weekly" ) | 577 | else if ( value == "Weekly" ) |
583 | recur()->setType( OPimRecurrence::Weekly); | 578 | recur()->setType( OPimRecurrence::Weekly); |
584 | else if ( value == "MonthlyDay" ) | 579 | else if ( value == "MonthlyDay" ) |
585 | recur()->setType( OPimRecurrence::MonthlyDay ); | 580 | recur()->setType( OPimRecurrence::MonthlyDay ); |
586 | else if ( value == "MonthlyDate" ) | 581 | else if ( value == "MonthlyDate" ) |
587 | recur()->setType( OPimRecurrence::MonthlyDate ); | 582 | recur()->setType( OPimRecurrence::MonthlyDate ); |
588 | else if ( value == "Yearly" ) | 583 | else if ( value == "Yearly" ) |
589 | recur()->setType( OPimRecurrence::Yearly ); | 584 | recur()->setType( OPimRecurrence::Yearly ); |
590 | else | 585 | else |
591 | recur()->setType( OPimRecurrence::NoRepeat ); | 586 | recur()->setType( OPimRecurrence::NoRepeat ); |
592 | break; | 587 | break; |
593 | case FRWeekdays: | 588 | case FRWeekdays: |
594 | recur()->setDays( value.toInt() ); | 589 | recur()->setDays( value.toInt() ); |
595 | break; | 590 | break; |
596 | case FRPosition: | 591 | case FRPosition: |
597 | recur()->setPosition( value.toInt() ); | 592 | recur()->setPosition( value.toInt() ); |
598 | break; | 593 | break; |
599 | case FRFreq: | 594 | case FRFreq: |
600 | recur()->setFrequency( value.toInt() ); | 595 | recur()->setFrequency( value.toInt() ); |
601 | break; | 596 | break; |
602 | case FRHasEndDate: | 597 | case FRHasEndDate: |
603 | recur()->setHasEndDate( value.toInt() ); | 598 | recur()->setHasEndDate( value.toInt() ); |
604 | break; | 599 | break; |
605 | case FREndDate: { | 600 | case FREndDate: { |
606 | rp_end = (time_t) value.toLong(); | 601 | rp_end = (time_t) value.toLong(); |
607 | break; | 602 | break; |
608 | } | 603 | } |
609 | case FRStart: { | 604 | case FRStart: { |
610 | start = (time_t) value.toLong(); | 605 | start = (time_t) value.toLong(); |
611 | break; | 606 | break; |
612 | } | 607 | } |
613 | case FREnd: { | 608 | case FREnd: { |
614 | end = ( (time_t) value.toLong() ); | 609 | end = ( (time_t) value.toLong() ); |
615 | break; | 610 | break; |
616 | } | 611 | } |
617 | case FNote: | 612 | case FNote: |
618 | e.setNote( value ); | 613 | e.setNote( value ); |
619 | break; | 614 | break; |
620 | case FCreated: | 615 | case FCreated: |
621 | created = value.toInt(); | 616 | created = value.toInt(); |
622 | break; | 617 | break; |
623 | case FRecParent: | 618 | case FRecParent: |
624 | e.setParent( value.toInt() ); | 619 | e.setParent( value.toInt() ); |
625 | break; | 620 | break; |
626 | case FRecChildren:{ | 621 | case FRecChildren:{ |
627 | QStringList list = QStringList::split(' ', value ); | 622 | QStringList list = QStringList::split(' ', value ); |
628 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | 623 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { |
629 | e.addChild( (*it).toInt() ); | 624 | e.addChild( (*it).toInt() ); |
630 | } | 625 | } |
631 | } | 626 | } |
632 | break; | 627 | break; |
633 | case FExceptions:{ | 628 | case FExceptions:{ |
634 | QStringList list = QStringList::split(' ', value ); | 629 | QStringList list = QStringList::split(' ', value ); |
635 | for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | 630 | for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { |
636 | QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); | 631 | QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); |
637 | owarn << "adding exception " << date.toString() << "" << oendl; | ||
638 | recur()->exceptions().append( date ); | 632 | recur()->exceptions().append( date ); |
639 | } | 633 | } |
640 | } | 634 | } |
641 | break; | 635 | break; |
642 | case FTimeZone: | 636 | case FTimeZone: |
643 | m_noTimeZone = false; | 637 | m_noTimeZone = false; |
644 | if ( value != "None" ) | 638 | if ( value != "None" ) |
645 | e.setTimeZone( value ); | 639 | e.setTimeZone( value ); |
646 | break; | 640 | break; |
647 | default: | 641 | default: |
648 | break; | 642 | break; |
649 | } | 643 | } |
650 | } | 644 | } |
651 | QArray<int> ODateBookAccessBackend_XML::matchRegexp( const QRegExp &r ) const | 645 | QArray<int> ODateBookAccessBackend_XML::matchRegexp( const QRegExp &r ) const |
652 | { | 646 | { |
653 | QArray<int> m_currentQuery( m_raw.count()+ m_rep.count() ); | 647 | QArray<int> m_currentQuery( m_raw.count()+ m_rep.count() ); |
654 | uint arraycounter = 0; | 648 | uint arraycounter = 0; |
655 | QMap<int, OPimEvent>::ConstIterator it; | 649 | QMap<int, OPimEvent>::ConstIterator it; |
656 | 650 | ||
657 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) | 651 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) |
658 | if ( it.data().match( r ) ) | 652 | if ( it.data().match( r ) ) |
659 | m_currentQuery[arraycounter++] = it.data().uid(); | 653 | m_currentQuery[arraycounter++] = it.data().uid(); |
660 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) | 654 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) |
661 | if ( it.data().match( r ) ) | 655 | if ( it.data().match( r ) ) |
662 | m_currentQuery[arraycounter++] = it.data().uid(); | 656 | m_currentQuery[arraycounter++] = it.data().uid(); |
663 | 657 | ||
664 | // Shrink to fit.. | 658 | // Shrink to fit.. |
665 | m_currentQuery.resize(arraycounter); | 659 | m_currentQuery.resize(arraycounter); |
666 | 660 | ||
667 | return m_currentQuery; | 661 | return m_currentQuery; |
668 | } | 662 | } |
669 | 663 | ||
670 | } | 664 | } |
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.h b/libopie2/opiepim/backend/odatebookaccessbackend_xml.h index af5b114..cb19f76 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.h +++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.h | |||
@@ -1,88 +1,88 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H | 29 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H |
30 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H | 30 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H |
31 | 31 | ||
32 | #include <qmap.h> | 32 | #include <qmap.h> |
33 | 33 | ||
34 | #include <opie2/odatebookaccessbackend.h> | 34 | #include <opie2/odatebookaccessbackend.h> |
35 | 35 | ||
36 | namespace Opie { | 36 | namespace Opie { |
37 | /** | 37 | /** |
38 | * This is the default XML implementation for DateBoook XML storage | 38 | * This is the default XML implementation for DateBoook XML storage |
39 | * It fully implements the interface | 39 | * It fully implements the interface |
40 | * @see ODateBookAccessBackend | 40 | * @see ODateBookAccessBackend |
41 | * @see OPimAccessBackend | 41 | * @see OPimAccessBackend |
42 | */ | 42 | */ |
43 | class ODateBookAccessBackend_XML : public ODateBookAccessBackend { | 43 | class ODateBookAccessBackend_XML : public ODateBookAccessBackend { |
44 | public: | 44 | public: |
45 | ODateBookAccessBackend_XML( const QString& appName, | 45 | ODateBookAccessBackend_XML( const QString& appName, |
46 | const QString& fileName = QString::null); | 46 | const QString& fileName = QString::null); |
47 | ~ODateBookAccessBackend_XML(); | 47 | ~ODateBookAccessBackend_XML(); |
48 | 48 | ||
49 | bool load(); | 49 | bool load(); |
50 | bool reload(); | 50 | bool reload(); |
51 | bool save(); | 51 | bool save(); |
52 | 52 | ||
53 | QArray<int> allRecords()const; | 53 | QArray<int> allRecords()const; |
54 | QArray<int> matchRegexp(const QRegExp &r) const; | 54 | QArray<int> matchRegexp(const QRegExp &r) const; |
55 | QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() ); | 55 | QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() ); |
56 | OPimEvent find( int uid )const; | 56 | OPimEvent find( int uid )const; |
57 | void clear(); | 57 | void clear(); |
58 | bool add( const OPimEvent& ev ); | 58 | bool add( const OPimEvent& ev ); |
59 | bool remove( int uid ); | 59 | bool remove( int uid ); |
60 | bool replace( const OPimEvent& ev ); | 60 | bool replace( const OPimEvent& ev ); |
61 | 61 | ||
62 | QArray<UID> rawEvents()const; | 62 | QArray<UID> rawEvents()const; |
63 | QArray<UID> rawRepeats()const; | 63 | QArray<UID> rawRepeats()const; |
64 | QArray<UID> nonRepeats()const; | 64 | QArray<UID> nonRepeats()const; |
65 | 65 | ||
66 | OPimEvent::ValueList directNonRepeats(); | 66 | OPimEvent::ValueList directNonRepeats()const; |
67 | OPimEvent::ValueList directRawRepeats(); | 67 | OPimEvent::ValueList directRawRepeats()const; |
68 | 68 | ||
69 | private: | 69 | private: |
70 | bool m_changed :1 ; | 70 | bool m_changed :1 ; |
71 | bool m_noTimeZone : 1; | 71 | bool m_noTimeZone : 1; |
72 | 72 | ||
73 | bool loadFile(); | 73 | bool loadFile(); |
74 | inline void finalizeRecord( OPimEvent& ev ); | 74 | inline void finalizeRecord( OPimEvent& ev ); |
75 | inline void setField( OPimEvent&, int field, const QString& val ); | 75 | inline void setField( OPimEvent&, int field, const QString& val ); |
76 | QString m_name; | 76 | QString m_name; |
77 | QMap<int, OPimEvent> m_raw; | 77 | QMap<int, OPimEvent> m_raw; |
78 | QMap<int, OPimEvent> m_rep; | 78 | QMap<int, OPimEvent> m_rep; |
79 | 79 | ||
80 | struct Data; | 80 | struct Data; |
81 | Data* data; | 81 | Data* data; |
82 | class Private; | 82 | class Private; |
83 | Private *d; | 83 | Private *d; |
84 | }; | 84 | }; |
85 | 85 | ||
86 | } | 86 | } |
87 | 87 | ||
88 | #endif | 88 | #endif |
diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h index 26af762..0d112c9 100644 --- a/libopie2/opiepim/backend/opimaccessbackend.h +++ b/libopie2/opiepim/backend/opimaccessbackend.h | |||
@@ -1,196 +1,423 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) The Main Author <main-author@whereever.org> | 3 | Copyright (C) The Main Author <main-author@whereever.org> |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | #ifndef OPIE_PIM_ACCESS_BACKEND | 29 | #ifndef OPIE_PIM_ACCESS_BACKEND |
30 | #define OPIE_PIM_ACCESS_BACKEND | 30 | #define OPIE_PIM_ACCESS_BACKEND |
31 | 31 | ||
32 | #include <qarray.h> | 32 | #include <qarray.h> |
33 | #include <qdatetime.h> | 33 | #include <qdatetime.h> |
34 | 34 | ||
35 | #include <opie2/opimtemplatebase.h> | 35 | #include <opie2/opimtemplatebase.h> |
36 | #include <opie2/opimrecord.h> | 36 | #include <opie2/opimrecord.h> |
37 | 37 | #include <opie2/opimbackendoccurrence.h> | |
38 | 38 | ||
39 | namespace Opie { | 39 | namespace Opie { |
40 | class OPimAccessBackendPrivate; | 40 | class OPimAccessBackendPrivate; |
41 | |||
41 | /** | 42 | /** |
42 | * OPimAccessBackend is the base class | 43 | * OPimAccessBackend is the Backend Interface to be used |
43 | * for all private backends | 44 | * by OTemplateBase based Frontends. |
44 | * it operates on OPimRecord as the base class | 45 | * For efficency reasons and to support delayed loading |
45 | * and it's responsible for fast manipulating | 46 | * most of the Frontend functions can be implemented |
46 | * the resource the implementation takes care | 47 | * by this backend. |
47 | * of | 48 | * This allows to utilise the best method on each backend. |
49 | * For example we can use SQL queries instead of self made | ||
50 | * query which is first more efficent and also uses less memory. | ||
48 | */ | 51 | */ |
49 | template <class T = OPimRecord> | 52 | template <class T = OPimRecord> |
50 | class OPimAccessBackend { | 53 | class OPimAccessBackend { |
51 | public: | 54 | public: |
52 | typedef OTemplateBase<T> Frontend; | 55 | typedef OTemplateBase<T> Frontend; |
53 | 56 | ||
54 | /** The access hint from the frontend */ | 57 | //@{ |
55 | OPimAccessBackend(int access = 0); | 58 | OPimAccessBackend(int access = 0); |
56 | virtual ~OPimAccessBackend(); | 59 | virtual ~OPimAccessBackend(); |
60 | //@} | ||
57 | 61 | ||
58 | /** | 62 | //@{ |
59 | * load the resource | ||
60 | */ | ||
61 | virtual bool load() = 0; | 63 | virtual bool load() = 0; |
62 | |||
63 | /** | ||
64 | * reload the resource | ||
65 | */ | ||
66 | virtual bool reload() = 0; | 64 | virtual bool reload() = 0; |
67 | |||
68 | /** | ||
69 | * save the resource and | ||
70 | * all it's changes | ||
71 | */ | ||
72 | virtual bool save() = 0; | 65 | virtual bool save() = 0; |
66 | virtual void clear() = 0; | ||
67 | //@} | ||
73 | 68 | ||
74 | /** | ||
75 | * return an array of | ||
76 | * all available uids | ||
77 | */ | ||
78 | virtual QArray<int> allRecords()const = 0; | ||
79 | 69 | ||
80 | /** | 70 | //@{ |
81 | * return a List of records | 71 | virtual UIDArray allRecords()const = 0; |
82 | * that match the regex | 72 | virtual UIDArray matchRegexp(const QRegExp &r) const; |
83 | */ | 73 | virtual UIDArray queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() )const = 0; |
84 | virtual QArray<int> matchRegexp(const QRegExp &r) const = 0; | 74 | virtual UIDArray queryByExample( const OPimRecord* rec, int, const QDateTime& d = QDateTime() )const; |
75 | virtual UIDArray sorted( const UIDArray&, bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const; | ||
76 | virtual UIDArray sorted( bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const; | ||
77 | virtual OPimBackendOccurrence::List occurrences( const QDate& start, const QDate& end)const; | ||
78 | virtual OPimBackendOccurrence::List occurrences( const QDateTime& dt )const; | ||
79 | //@} | ||
85 | 80 | ||
86 | /** | ||
87 | * queryByExample for T with the given Settings | ||
88 | * | ||
89 | */ | ||
90 | virtual QArray<int> queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() ) = 0; | ||
91 | 81 | ||
92 | /** | 82 | //@{ |
93 | * find the OPimRecord with uid @param uid | 83 | virtual T find(UID uid )const = 0; |
94 | * returns T and T.isEmpty() if nothing was found | 84 | virtual T find(UID uid, const QArray<UID>& items, |
95 | */ | 85 | uint current, typename Frontend::CacheDirection )const ; |
96 | virtual T find( int uid )const = 0; | 86 | //@} |
97 | 87 | ||
98 | virtual T find( int uid, const QArray<int>& items, | ||
99 | uint current, typename Frontend::CacheDirection ) const; | ||
100 | /** | ||
101 | * clear the back end | ||
102 | */ | ||
103 | virtual void clear() = 0; | ||
104 | 88 | ||
105 | /** | 89 | //@{ |
106 | * add T | ||
107 | */ | ||
108 | virtual bool add( const T& t ) = 0; | 90 | virtual bool add( const T& t ) = 0; |
91 | virtual bool remove( UID uid ) = 0; | ||
92 | virtual bool replace( const T& t ) = 0; | ||
93 | //@} | ||
109 | 94 | ||
110 | /** | ||
111 | * remove | ||
112 | */ | ||
113 | virtual bool remove( int uid ) = 0; | ||
114 | 95 | ||
115 | /** | ||
116 | * replace a record with T.uid() | ||
117 | */ | ||
118 | virtual bool replace( const T& t ) = 0; | ||
119 | 96 | ||
120 | /* | ||
121 | * setTheFrontEnd!!! | ||
122 | */ | ||
123 | void setFrontend( Frontend* front ); | 97 | void setFrontend( Frontend* front ); |
124 | 98 | ||
125 | /** | 99 | /** |
126 | * set the read ahead count | 100 | * set the read ahead count |
127 | */ | 101 | */ |
128 | void setReadAhead( uint count ); | 102 | void setReadAhead( uint count ); |
129 | protected: | 103 | protected: |
104 | //@{ | ||
130 | int access()const; | 105 | int access()const; |
131 | |||
132 | void cache( const T& t )const; | 106 | void cache( const T& t )const; |
133 | |||
134 | /** | ||
135 | * use a prime number here! | ||
136 | */ | ||
137 | void setSaneCacheSize( int ); | 107 | void setSaneCacheSize( int ); |
138 | |||
139 | uint readAhead()const; | 108 | uint readAhead()const; |
109 | //@} | ||
140 | 110 | ||
141 | private: | 111 | private: |
142 | OPimAccessBackendPrivate *d; | 112 | OPimAccessBackendPrivate *d; |
143 | Frontend* m_front; | 113 | Frontend* m_front; |
144 | uint m_read; | 114 | uint m_read; |
145 | int m_acc; | 115 | int m_acc; |
146 | 116 | ||
147 | }; | 117 | }; |
148 | 118 | ||
149 | template <class T> | 119 | template <class T> |
150 | OPimAccessBackend<T>::OPimAccessBackend(int acc) | 120 | OPimAccessBackend<T>::OPimAccessBackend(int acc) |
151 | : m_acc( acc ) | 121 | : m_acc( acc ) |
152 | { | 122 | { |
153 | m_front = 0l; | 123 | m_front = 0l; |
154 | } | 124 | } |
155 | template <class T> | 125 | template <class T> |
156 | OPimAccessBackend<T>::~OPimAccessBackend() { | 126 | OPimAccessBackend<T>::~OPimAccessBackend() { |
157 | 127 | ||
158 | } | 128 | } |
129 | |||
130 | /* | ||
131 | * Slow but default matchRegexp Implementation | ||
132 | * Create a Big Enough QArray and then iterate | ||
133 | * over all Records and matchRegexp them. | ||
134 | * At the end we will resize the array to the actual | ||
135 | * number of items | ||
136 | */ | ||
137 | template <class T> | ||
138 | UIDArray OPimAccessBackend<T>::matchRegexp( const QRegExp& reg )const { | ||
139 | UIDArray all_rec = allRecords(); | ||
140 | UIDArray result( all_rec.count() ); | ||
141 | uint used_records = 0, all_rec_count = all_rec.count(); | ||
142 | |||
143 | for ( uint i = 0; i < all_rec_count; ++i ) | ||
144 | if (find( all_rec[i], all_rec, i, Frontend::Forward ).match( reg ) ) | ||
145 | result[used_records++] = all_rec[i]; | ||
146 | |||
147 | /* shrink to fit */ | ||
148 | result.resize( used_records ); | ||
149 | return result; | ||
150 | } | ||
151 | |||
152 | template <class T> | ||
153 | UIDArray OPimAccessBackend<T>::queryByExample( const OPimRecord* rec, int settings, | ||
154 | const QDateTime& datetime )const { | ||
155 | T* tmp_rec = T::safeCast( rec ); | ||
156 | UIDArray ar; | ||
157 | if ( tmp_rec ) | ||
158 | ar = queryByExample( *tmp_rec, settings, datetime ); | ||
159 | |||
160 | return ar; | ||
161 | } | ||
162 | |||
163 | template <class T> | ||
164 | UIDArray OPimAccessBackend<T>::sorted( const UIDArray& ids, bool, | ||
165 | int, int, const QArray<int>& ) const { | ||
166 | return ids; | ||
167 | } | ||
168 | |||
169 | template <class T> | ||
170 | UIDArray OPimAccessBackend<T>::sorted( bool asc, int order, int filter, | ||
171 | const QArray<int>& cats )const { | ||
172 | return sorted( allRecords(), asc, order, filter, cats ); | ||
173 | } | ||
174 | |||
175 | template<class T> | ||
176 | OPimBackendOccurrence::List OPimAccessBackend<T>::occurrences( const QDate&, | ||
177 | const QDate& )const { | ||
178 | return OPimBackendOccurrence::List(); | ||
179 | } | ||
180 | |||
181 | template<class T> | ||
182 | OPimBackendOccurrence::List OPimAccessBackend<T>::occurrences( const QDateTime& dt )const { | ||
183 | QDate date = dt.date(); | ||
184 | return occurrences( date, date ); | ||
185 | } | ||
186 | |||
159 | template <class T> | 187 | template <class T> |
160 | void OPimAccessBackend<T>::setFrontend( Frontend* fr ) { | 188 | void OPimAccessBackend<T>::setFrontend( Frontend* fr ) { |
161 | m_front = fr; | 189 | m_front = fr; |
162 | } | 190 | } |
163 | template <class T> | 191 | template <class T> |
164 | void OPimAccessBackend<T>::cache( const T& t )const { | 192 | void OPimAccessBackend<T>::cache( const T& t )const { |
165 | if ( m_front ) | 193 | if ( m_front ) |
166 | m_front->cache( t ); | 194 | m_front->cache( t ); |
167 | } | 195 | } |
168 | 196 | ||
169 | |||
170 | template <class T> | 197 | template <class T> |
171 | void OPimAccessBackend<T>::setSaneCacheSize( int size) { | 198 | void OPimAccessBackend<T>::setSaneCacheSize( int size) { |
172 | if ( m_front ) | 199 | if ( m_front ) |
173 | m_front->setSaneCacheSize( size ); | 200 | m_front->setSaneCacheSize( size ); |
174 | } | 201 | } |
175 | template <class T> | 202 | template <class T> |
176 | T OPimAccessBackend<T>::find( int uid, const QArray<int>&, | 203 | T OPimAccessBackend<T>::find( int uid, const QArray<int>&, |
177 | uint, typename Frontend::CacheDirection ) const{ | 204 | uint, typename Frontend::CacheDirection ) const{ |
178 | qDebug( "*** Lookahead feature not supported. Fallback to default find!!" ); | 205 | qDebug( "*** Lookahead feature not supported. Fallback to default find!!" ); |
179 | return find( uid ); | 206 | return find( uid ); |
180 | } | 207 | } |
181 | template <class T> | 208 | template <class T> |
182 | void OPimAccessBackend<T>::setReadAhead( uint count ) { | 209 | void OPimAccessBackend<T>::setReadAhead( uint count ) { |
183 | m_read = count; | 210 | m_read = count; |
184 | } | 211 | } |
185 | template <class T> | 212 | template <class T> |
186 | uint OPimAccessBackend<T>::readAhead()const { | 213 | uint OPimAccessBackend<T>::readAhead()const { |
187 | return m_read; | 214 | return m_read; |
188 | } | 215 | } |
189 | template <class T> | 216 | template <class T> |
190 | int OPimAccessBackend<T>::access()const { | 217 | int OPimAccessBackend<T>::access()const { |
191 | return m_acc; | 218 | return m_acc; |
192 | } | 219 | } |
193 | 220 | ||
194 | } | 221 | } |
195 | 222 | ||
223 | /** | ||
224 | * \fn template <class T> OPimAccessBackend<T>::OPimAccessBackend(int hint ) | ||
225 | * @param hint The access hint from the frontend | ||
226 | */ | ||
227 | |||
228 | /** | ||
229 | * \fn template <class T> bool OPimAccessBackend<T>::load() | ||
230 | * Opens the DataBase and does necessary | ||
231 | * initialisation of internal structures. | ||
232 | * | ||
233 | * @return true If the DataBase could be opened and | ||
234 | * Information was successfully loaded | ||
235 | */ | ||
236 | |||
237 | /** | ||
238 | * \fn template <class T> bool OPimAccessBackend<T>::reload() | ||
239 | * Reinitialise the DataBase and merges the external changes | ||
240 | * with your local changes. | ||
241 | * | ||
242 | * @return True if the DataBase was reloaded. | ||
243 | * | ||
244 | */ | ||
245 | |||
246 | /** | ||
247 | * \fn template <class T> bool OPimAccessBackend<T>::save() | ||
248 | * | ||
249 | * Save the changes to storage. In case of memory or | ||
250 | * disk shortage, return false. | ||
251 | * | ||
252 | * | ||
253 | * @return True if the DataBase could be saved to storage. | ||
254 | */ | ||
255 | |||
256 | /** | ||
257 | * \fn template <class T> bool OPimAccessBackend<T>::clear() | ||
258 | * Until a \sa save() changes shouldn't be comitted | ||
259 | * | ||
260 | * | ||
261 | * @return True if the DataBase could be cleared | ||
262 | * @todo Introduce a 'Commit' | ||
263 | */ | ||
264 | |||
265 | /** | ||
266 | * \fn template <class T> QArray<UID> OPimAccessBackend<T>::allRecords()const | ||
267 | * Return an array of all available uids in the loaded | ||
268 | * DataBase. | ||
269 | * @see load | ||
270 | */ | ||
271 | |||
272 | /** | ||
273 | * \fn template <class T> QArray<UID> OPimAccessBackend<T>::matchRegexp(const QRegExp& r)const | ||
274 | * Return a List of records that match the regex \par r. | ||
275 | * | ||
276 | * @param r The QRegExp to match. | ||
277 | */ | ||
278 | |||
279 | /** | ||
280 | * \fn template <class T> QArray<UID> OPimAccessBackend<T>::queryByExample(const T& t, int settings, const QDateTime& d = QDateTime() ) | ||
281 | * | ||
282 | * Implement QueryByExample. An Example record is filled and with the | ||
283 | * settings and QDateTime it is determined how the query should be executed. | ||
284 | * Return a list of UIDs that match the Example | ||
285 | * | ||
286 | * @param t The Example record | ||
287 | * @param settings Gives | ||
288 | * | ||
289 | */ | ||
290 | |||
291 | /** | ||
292 | * \fn template<class T> QArray<UID> OPimAccessBackend<T>::sorted(const QArray<UID>& ids, bool asc, int sortOrder, int sortFilter, int cat) | ||
293 | * \brief Sort the List of records according to the preference | ||
294 | * | ||
295 | * Implement sorting in your backend. The default implementation is | ||
296 | * to return the list as it was passed. | ||
297 | * The default Backend Implementation should do unaccelerated filtering | ||
298 | * | ||
299 | * | ||
300 | * @param ids The Records to sort | ||
301 | * @param asc Sort ascending or descending | ||
302 | * @param sortOrder | ||
303 | * @param sortFilter Sort filter | ||
304 | * @param cat The Category to include | ||
305 | */ | ||
306 | |||
307 | /** | ||
308 | * \fn template <class T> T OPimAccessBackend<T>::find(UID uid)const | ||
309 | * \brief Find the Record with the UID | ||
310 | * | ||
311 | * Find the UID in the database and return the record. | ||
312 | * @param uid The uid to be searched for | ||
313 | * @return The record or an empty record (T.isEmpty()) | ||
314 | * | ||
315 | */ | ||
316 | |||
317 | /** | ||
318 | * \fn template <class T> T OPimAccessBackend<T>::find( UID uid, const QArray<UID>& items, uint current, typename Frontend::CacheDirection d)const | ||
319 | * \brief find a Record and do a read ahead or read behind | ||
320 | * | ||
321 | * @param uid The UID to search for | ||
322 | * @param items The list of items from where your search | ||
323 | * @param current The index of \param uid | ||
324 | * @param d The direction to search for | ||
325 | * | ||
326 | * @see find | ||
327 | */ | ||
328 | |||
329 | |||
330 | /** | ||
331 | * \fn template<class T> bool OPimAccessBackend<T>::add(const T& t) | ||
332 | * | ||
333 | * \brief Add the record to the internal database | ||
334 | * | ||
335 | * If an record with the same t.uid() is already present internally | ||
336 | * the behaviour is undefined but the state of the database | ||
337 | * needs to be stable. | ||
338 | * For modifying a record use \sa replace. | ||
339 | * | ||
340 | * | ||
341 | * @return true if the record could be added or false if not | ||
342 | * @todo Eilers your opinion on readd/replace | ||
343 | */ | ||
344 | |||
345 | /** | ||
346 | * \fn template<class T> bool OPimAccessBackend<T>::remove(UID uid) | ||
347 | * \brief Remove a record by its UID | ||
348 | * | ||
349 | * Remove the records with UID from the internal Database. | ||
350 | * | ||
351 | * @return True if the record could be removed. | ||
352 | * | ||
353 | */ | ||
354 | |||
355 | /** | ||
356 | * \fn template<class T> bool OPimAccessBackend<T>::replace(const T& t) | ||
357 | * \brief Take this Record and replace the old version. | ||
358 | * | ||
359 | * Take \param t as the new record for t.uid(). It is not described | ||
360 | * what happens if the record is not present in the database. | ||
361 | * Normally the record is determined by the UID. | ||
362 | * | ||
363 | * @param t The record to use internally. | ||
364 | */ | ||
365 | |||
366 | /** | ||
367 | * \fn template<class T> void OPimAccessBackend<T>::setFrontend( Frontend* fron) | ||
368 | * \@aram fron The Frontend that uses this backend | ||
369 | * | ||
370 | * This function is called by the frontend and is used | ||
371 | */ | ||
372 | |||
373 | /** | ||
374 | * \fn template<class T> void OPimAccessBackend<T>::setReadAhead(uint count) | ||
375 | * \brief Set the number of items to Read-Ahead/Read-Behind | ||
376 | * | ||
377 | * @param count The number of records to read ahead | ||
378 | */ | ||
379 | |||
380 | /** | ||
381 | * \fn template<class T> void OPimAccessBackend<T>::cache( const T& t)const | ||
382 | * \brief Add the Record to the PIM Cache | ||
383 | * | ||
384 | * This will add the Record to the PIM cache, which is owned | ||
385 | * by the FrontEnd. If no FrontEnd is available the item will | ||
386 | * not be cached. | ||
387 | * | ||
388 | * | ||
389 | * @param t The Item to be added to the Cache | ||
390 | */ | ||
391 | |||
392 | /** | ||
393 | * \fn template<class T> void OPimAccessBackend<T>::setSaneCacheSize(int items) | ||
394 | * \brief Give a hint on the number of too cached items | ||
395 | * | ||
396 | * Give the Frontend a hint on the number of items to be cached. Use | ||
397 | * a prime number for best performance. | ||
398 | * | ||
399 | * @param items The number of items to be cached | ||
400 | */ | ||
401 | |||
402 | /** | ||
403 | * \fn template<class T> uint OPimAccessBackend<T>::readAhead()const | ||
404 | * \brief Return the number of Items to be ReadAhead | ||
405 | * | ||
406 | * @return The number of Items to read ahead/read behind | ||
407 | */ | ||
408 | |||
409 | /** | ||
410 | * \fn template<class T> QArray<OPimBackendOccurence> OPimAccessBackend<T>::occurrences(const QDateTime& start,const QDateTime& end) | ||
411 | * \brief Get a List of Occurrences for a period of time | ||
412 | * | ||
413 | * Return an Array of OPimBackendOccurence for a period of time. If start == end date | ||
414 | * return only occurrences for the start date. If end is smaller the start date | ||
415 | * the result is not defined. You could switch dates or return an empty list. | ||
416 | * | ||
417 | * @return Return an array of OPimBackendOccurence for the period specified by the parameters | ||
418 | * @param start The start of the period. | ||
419 | * @param end The end of the period. | ||
420 | * | ||
421 | */ | ||
422 | |||
196 | #endif | 423 | #endif |
diff --git a/libopie2/opiepim/backend/opimbackendoccurrence.cpp b/libopie2/opiepim/backend/opimbackendoccurrence.cpp new file mode 100644 index 0000000..8af930d --- a/dev/null +++ b/libopie2/opiepim/backend/opimbackendoccurrence.cpp | |||
@@ -0,0 +1,241 @@ | |||
1 | /* | ||
2 | This file is part of the Opie Project | ||
3 | Copyright (C) 2004 Holger Hans Peter Freyther <zecke@handhelds.org> | ||
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | ||
5 | .=l. | ||
6 | .>+-= | ||
7 | _;:, .> :=|. This program is free software; you can | ||
8 | .> <`_, > . <= redistribute it and/or modify it under | ||
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | ||
10 | .="- .-=="i, .._ License as published by the Free Software | ||
11 | - . .-<_> .<> Foundation; either version 2 of the License, | ||
12 | ._= =} : or (at your option) any later version. | ||
13 | .%`+i> _;_. | ||
14 | .i_,=:_. -<s. This program is distributed in the hope that | ||
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | ||
16 | : .. .:, . . . without even the implied warranty of | ||
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | ||
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | ||
19 | ..}^=.= = ; Library General Public License for more | ||
20 | ++= -. .` .: details. | ||
21 | : = ...= . :.=- | ||
22 | -. .:....=;==+<; You should have received a copy of the GNU | ||
23 | -_. . . )=. = Library General Public License along with | ||
24 | -- :-=` this library; see the file COPYING.LIB. | ||
25 | If not, write to the Free Software Foundation, | ||
26 | Inc., 59 Temple Place - Suite 330, | ||
27 | Boston, MA 02111-1307, USA. | ||
28 | */ | ||
29 | |||
30 | #include "opimbackendoccurrence.h" | ||
31 | |||
32 | namespace Opie { | ||
33 | |||
34 | OPimBackendOccurrence::OPimBackendOccurrence() {} | ||
35 | /** | ||
36 | * \brief The occurence is only on the specefic Day | ||
37 | * | ||
38 | * If an occurrence is only a day without any time associated | ||
39 | * use this Constructor. | ||
40 | * \sa timeAssociated() will return false. | ||
41 | * | ||
42 | * @param date The Date this Occurence takes place | ||
43 | * @param uid The \sa UID of the associated OPimRecord | ||
44 | * @param sum The optional summary | ||
45 | * | ||
46 | */ | ||
47 | OPimBackendOccurrence::OPimBackendOccurrence( const QDate& date, | ||
48 | const UID& uid, | ||
49 | const QString& sum ) | ||
50 | : m_start( date ), m_end( date ), m_uid( uid ), | ||
51 | m_haveTime(false ), m_summary( sum ) | ||
52 | {} | ||
53 | |||
54 | /** | ||
55 | * \brief An Occurrence with a start day and end day without time | ||
56 | * | ||
57 | * Overloaded Constructor. Use this if you've a start date and | ||
58 | * end date but no time. If you need to overwrite the summary | ||
59 | * use setSummary. | ||
60 | * \sa timeAssociated() will return false. | ||
61 | * | ||
62 | * @param date The Start Date | ||
63 | * @param end Tne End Date | ||
64 | * @param uid The UID of the associated record | ||
65 | * | ||
66 | * @see setSummary | ||
67 | */ | ||
68 | OPimBackendOccurrence::OPimBackendOccurrence( const QDate& date, | ||
69 | const QDate& end, | ||
70 | const UID& uid) | ||
71 | : m_start( date ), m_end( end ), m_uid( uid ), m_haveTime( false ) | ||
72 | {} | ||
73 | |||
74 | |||
75 | /** | ||
76 | * \brief Use Start and End Date with Time | ||
77 | * | ||
78 | * Overloaded Constructor to use Dates with Time time associated | ||
79 | * to it. \sa timeAssociated() will return true. | ||
80 | * | ||
81 | * @param date The Start Date and Time of the occurrence | ||
82 | * @param end The End Date and Time of the occurrence | ||
83 | * @param uid The UID of the \sa OPimRecord. | ||
84 | */ | ||
85 | OPimBackendOccurrence::OPimBackendOccurrence( const QDateTime& date, | ||
86 | const QDateTime& end, | ||
87 | const UID& uid ) | ||
88 | : m_start( date ), m_end( end ), m_uid( uid ), m_haveTime( true ) | ||
89 | {} | ||
90 | |||
91 | /** | ||
92 | * \brief Return the Start Date and Time | ||
93 | * | ||
94 | * @return This method will return the start | ||
95 | * Date and Time. Time is only valid if | ||
96 | * \sa timeAssociated() is true. | ||
97 | * | ||
98 | */ | ||
99 | QDateTime OPimBackendOccurrence::startDateTime()const { | ||
100 | return m_start; | ||
101 | } | ||
102 | |||
103 | /** | ||
104 | * \brief Return the Start Date and Time | ||
105 | * | ||
106 | * @return This will return the end Date and Time. The | ||
107 | * limitation for Time is the same as in startDateTime | ||
108 | * | ||
109 | * @see startDateTime() | ||
110 | */ | ||
111 | QDateTime OPimBackendOccurrence::endDateTime()const { | ||
112 | return m_end; | ||
113 | } | ||
114 | |||
115 | /** | ||
116 | * \brief Return the UID of the Associated OPimRecord | ||
117 | * | ||
118 | * @return the associated OPimRecord | ||
119 | */ | ||
120 | UID OPimBackendOccurrence::uid()const { | ||
121 | return m_uid; | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * \brief Return if there is a time associated or not | ||
126 | * | ||
127 | * If a time is present with start and end date this method | ||
128 | * will return true. There is no direct way to manipulate | ||
129 | * that attribute. But \sa setStartDate and \sa setStartDateTime | ||
130 | * will change it. | ||
131 | * | ||
132 | * @return Return true if a time is available with the date | ||
133 | * | ||
134 | */ | ||
135 | bool OPimBackendOccurrence::isAllDay()const { | ||
136 | return m_haveTime; | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * @return The special summary that will overwrite OPimRecord::summary | ||
141 | */ | ||
142 | QString OPimBackendOccurrence::summary()const { | ||
143 | return m_summary; | ||
144 | } | ||
145 | |||
146 | QString OPimBackendOccurrence::location()const { | ||
147 | return m_location; | ||
148 | } | ||
149 | |||
150 | QString OPimBackendOccurrence::note()const { | ||
151 | return m_note; | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * \brief Set the Start Date | ||
156 | * | ||
157 | * This method will set the start date and internally will mark | ||
158 | * this occurrence to have no time associated to both start | ||
159 | * and end date. | ||
160 | * A call to timeAssociated will return false after using this | ||
161 | * method. | ||
162 | * | ||
163 | * @param start The Start Date | ||
164 | * | ||
165 | */ | ||
166 | void OPimBackendOccurrence::setStartDate( const QDate& start) { | ||
167 | m_start = start; | ||
168 | m_haveTime = false; | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * \brief Set the Start Date and Time | ||
173 | * | ||
174 | * Set the Start Date and Time. After this call | ||
175 | * \sa timeAssociated will return true. | ||
176 | * | ||
177 | * @param dt The Start Date and Time to be set | ||
178 | */ | ||
179 | void OPimBackendOccurrence::setStartDateTime( const QDateTime& dt ) { | ||
180 | m_start = dt; | ||
181 | m_haveTime = true; | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * \brief This will set the End Date. | ||
186 | * | ||
187 | * This method will set the End Date. The timeAssociated attribute | ||
188 | * will not be changed. | ||
189 | * | ||
190 | * @param end The End Date to be set | ||
191 | */ | ||
192 | void OPimBackendOccurrence::setEndDate( const QDate& end ) { | ||
193 | m_end = end; | ||
194 | } | ||
195 | |||
196 | /** | ||
197 | * \brief Set the End Date and Time of the occurrence | ||
198 | * | ||
199 | * This will set the End Date and Time but will not change | ||
200 | * the timeAssociated attribute. | ||
201 | * | ||
202 | * @param dt The End Date and Time to be set. | ||
203 | */ | ||
204 | void OPimBackendOccurrence::setEndDateTime( const QDateTime& dt ) { | ||
205 | m_end = dt; | ||
206 | } | ||
207 | |||
208 | /** | ||
209 | * \brief This method will set the UID of the Record | ||
210 | * | ||
211 | * Set the UID of the OPimRecord to be associated with | ||
212 | * this OPimRecurrence. | ||
213 | * | ||
214 | * @param uid The UID of the associated OPimRecord to be set | ||
215 | */ | ||
216 | void OPimBackendOccurrence::setUid( const UID& uid ) { | ||
217 | m_uid = uid; | ||
218 | } | ||
219 | |||
220 | |||
221 | /** | ||
222 | * \brief Set a special summary instead of \sa OPimRecord::summary() | ||
223 | * | ||
224 | * If \sa OPimRecord::summary() doesn't describe the occurrence | ||
225 | * reason you can set a custom summary for the Occurrence. | ||
226 | * | ||
227 | * @param str The to be set Summary | ||
228 | */ | ||
229 | void OPimBackendOccurrence::setSummary( const QString& str ) { | ||
230 | m_summary = str; | ||
231 | } | ||
232 | |||
233 | void OPimBackendOccurrence::setLocation( const QString& str ) { | ||
234 | m_location = str; | ||
235 | } | ||
236 | |||
237 | void OPimBackendOccurrence::setNote( const QString& str ) { | ||
238 | m_note = str; | ||
239 | } | ||
240 | |||
241 | } | ||
diff --git a/libopie2/opiepim/backend/opimbackendoccurrence.h b/libopie2/opiepim/backend/opimbackendoccurrence.h new file mode 100644 index 0000000..08c3cdf --- a/dev/null +++ b/libopie2/opiepim/backend/opimbackendoccurrence.h | |||
@@ -0,0 +1,108 @@ | |||
1 | /* | ||
2 | This file is part of the Opie Project | ||
3 | Copyright (C) 2004 Holger Hans Peter Freyther <zecke@handhelds.org> | ||
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | ||
5 | .=l. | ||
6 | .>+-= | ||
7 | _;:, .> :=|. This program is free software; you can | ||
8 | .> <`_, > . <= redistribute it and/or modify it under | ||
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | ||
10 | .="- .-=="i, .._ License as published by the Free Software | ||
11 | - . .-<_> .<> Foundation; either version 2 of the License, | ||
12 | ._= =} : or (at your option) any later version. | ||
13 | .%`+i> _;_. | ||
14 | .i_,=:_. -<s. This program is distributed in the hope that | ||
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | ||
16 | : .. .:, . . . without even the implied warranty of | ||
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | ||
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | ||
19 | ..}^=.= = ; Library General Public License for more | ||
20 | ++= -. .` .: details. | ||
21 | : = ...= . :.=- | ||
22 | -. .:....=;==+<; You should have received a copy of the GNU | ||
23 | -_. . . )=. = Library General Public License along with | ||
24 | -- :-=` this library; see the file COPYING.LIB. | ||
25 | If not, write to the Free Software Foundation, | ||
26 | Inc., 59 Temple Place - Suite 330, | ||
27 | Boston, MA 02111-1307, USA. | ||
28 | */ | ||
29 | |||
30 | #ifndef OPIE_PIM_BACKEND_OCCURRENCE_H | ||
31 | #define OPIE_PIM_BACKEND_OCCURRENCE_H | ||
32 | |||
33 | #include <opie2/opimglobal.h> | ||
34 | |||
35 | #include <qarray.h> | ||
36 | #include <qdatetime.h> | ||
37 | #include <qvaluelist.h> | ||
38 | |||
39 | namespace Opie { | ||
40 | |||
41 | /** | ||
42 | * \brief Internal representation of an Occurence | ||
43 | * | ||
44 | * This class is used by the Backends to express | ||
45 | * Occurences for the Period Based Query to | ||
46 | * the by the Backend represanted Database. | ||
47 | * In the Frontend this single representation is splitted | ||
48 | * into per day \sa OPimOccurrence 's. | ||
49 | * OPimBackendOccurrence can be understand as a hint to | ||
50 | * the Frontend and must contain the \sa UID, the Start Date | ||
51 | * and End Date of the Occurence. If you have no time associated | ||
52 | * to the datetime use the QDate constructors. | ||
53 | * If OPimRecord::summary() does not describe the Occurrence | ||
54 | * right you can call setSummary() and then the supplied | ||
55 | * summary will be used. | ||
56 | * All Dates and Times are in the local time. | ||
57 | * | ||
58 | * @version 1.0 | ||
59 | * @author Holger Hans Peter Freyther zecke@handhelds.org | ||
60 | */ | ||
61 | class OPimBackendOccurrence { | ||
62 | public: | ||
63 | typedef QValueList<OPimBackendOccurrence> List; | ||
64 | |||
65 | //@{ | ||
66 | OPimBackendOccurrence(); | ||
67 | OPimBackendOccurrence( const QDate& date, | ||
68 | const UID& , const QString& = QString::null ); | ||
69 | OPimBackendOccurrence( const QDate& date, const QDate& end, | ||
70 | const UID& ); | ||
71 | OPimBackendOccurrence( const QDateTime& start, | ||
72 | const QDateTime& end, | ||
73 | const UID& uid ); | ||
74 | //@} | ||
75 | |||
76 | //@{ | ||
77 | QDateTime startDateTime()const; | ||
78 | QDateTime endDateTime()const; | ||
79 | UID uid()const; | ||
80 | bool isAllDay()const; | ||
81 | QString summary()const; | ||
82 | QString location()const; | ||
83 | QString note()const; | ||
84 | //@} | ||
85 | |||
86 | //@{ | ||
87 | void setStartDate( const QDate& ); | ||
88 | void setStartDateTime( const QDateTime& dt ); | ||
89 | void setEndDate( const QDate& ); | ||
90 | void setEndDateTime( const QDateTime& dt ); | ||
91 | void setUid( const UID& ); | ||
92 | void setSummary( const QString& ); | ||
93 | void setLocation( const QString& ); | ||
94 | void setNote( const QString& ); | ||
95 | //@} | ||
96 | |||
97 | private: | ||
98 | QDateTime m_start, m_end; | ||
99 | UID m_uid; | ||
100 | bool m_haveTime : 1; | ||
101 | QString m_summary, m_note, m_location; | ||
102 | |||
103 | struct Private; | ||
104 | Private *d; | ||
105 | }; | ||
106 | } | ||
107 | |||
108 | #endif | ||
diff --git a/libopie2/opiepim/backend/otodoaccessbackend.cpp b/libopie2/opiepim/backend/otodoaccessbackend.cpp index 790a764..5f86be9 100644 --- a/libopie2/opiepim/backend/otodoaccessbackend.cpp +++ b/libopie2/opiepim/backend/otodoaccessbackend.cpp | |||
@@ -1,41 +1,155 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) The Main Author <main-author@whereever.org> | 3 | Copyright (C) The Main Author <main-author@whereever.org> |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <opie2/otodoaccessbackend.h> | 30 | #include <opie2/otodoaccessbackend.h> |
31 | #include <opie2/private/opimtodosortvector.h> | ||
32 | #include <opie2/otodoaccess.h> | ||
33 | |||
34 | #include <qintdict.h> | ||
31 | 35 | ||
32 | namespace Opie { | 36 | namespace Opie { |
33 | OPimTodoAccessBackend::OPimTodoAccessBackend() | 37 | OPimTodoAccessBackend::OPimTodoAccessBackend() |
34 | : OPimAccessBackend<OPimTodo>() | 38 | : OPimAccessBackend<OPimTodo>() |
35 | { | 39 | { |
36 | } | 40 | } |
37 | OPimTodoAccessBackend::~OPimTodoAccessBackend() { | 41 | OPimTodoAccessBackend::~OPimTodoAccessBackend() { |
38 | 42 | ||
39 | } | 43 | } |
40 | 44 | ||
45 | UIDArray OPimTodoAccessBackend::queryByExample( const OPimTodo&, int settings, | ||
46 | const QDateTime& d)const { | ||
47 | return UIDArray(); | ||
48 | } | ||
49 | |||
50 | UIDArray OPimTodoAccessBackend::sorted( const UIDArray& events, bool asc, | ||
51 | int sortOrder, int sortFilter, | ||
52 | const QArray<int>& categories )const { | ||
53 | odebug << "Using Unaccelerated TodoList sorted Implementation" << oendl; | ||
54 | Internal::OPimTodoSortVector vector(events.count(), asc,sortOrder ); | ||
55 | int item = 0; | ||
56 | |||
57 | bool bCat = sortFilter & OPimTodoAccess::FilterCategory ? true : false; | ||
58 | bool bOnly = sortFilter & OPimTodoAccess::OnlyOverDue ? true : false; | ||
59 | bool comp = sortFilter & OPimTodoAccess::DoNotShowCompleted ? true : false; | ||
60 | bool catPassed = false; | ||
61 | int cat; | ||
62 | |||
63 | for ( uint i = 0; i < events.count(); ++i ) { | ||
64 | OPimTodo todo = find( events[i], events, i, Frontend::Forward ); | ||
65 | if ( todo.isEmpty() ) | ||
66 | continue; | ||
67 | |||
68 | /* show category */ | ||
69 | /* -1 == unfiled */ | ||
70 | catPassed = false; | ||
71 | for ( uint cat_nu = 0; cat_nu < categories.count(); ++cat_nu ) { | ||
72 | cat = categories[cat_nu]; | ||
73 | if ( bCat && cat == -1 ) { | ||
74 | if(!todo.categories().isEmpty() ) | ||
75 | continue; | ||
76 | } else if ( bCat && cat != 0) | ||
77 | if (!todo.categories().contains( cat ) ) | ||
78 | continue; | ||
79 | catPassed = true; | ||
80 | break; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * If none of the Categories matched | ||
85 | * continue | ||
86 | */ | ||
87 | if ( !catPassed ) | ||
88 | continue; | ||
89 | if ( !todo.isOverdue() && bOnly ) | ||
90 | continue; | ||
91 | if (todo.isCompleted() && comp ) | ||
92 | continue; | ||
93 | |||
94 | vector.insert(item++, todo ); | ||
95 | } | ||
96 | |||
97 | vector.resize( item ); | ||
98 | /* sort it now */ | ||
99 | vector.sort(); | ||
100 | /* now get the uids */ | ||
101 | UIDArray array( vector.count() ); | ||
102 | for (uint i= 0; i < vector.count(); i++ ) | ||
103 | array[i] = vector.uidAt( i ); | ||
104 | |||
105 | return array; | ||
106 | } | ||
107 | |||
108 | OPimBackendOccurrence::List OPimTodoAccessBackend::occurrences( const QDate& start, | ||
109 | const QDate& end )const { | ||
110 | OPimBackendOccurrence::List lst; | ||
111 | UIDArray effective = effectiveToDos( start, end, false ); | ||
112 | UIDArray overdue = overDue(); | ||
113 | uint count = effective.count(); | ||
114 | int uid; | ||
115 | QIntDict<int> hash; | ||
116 | hash.setAutoDelete( true ); | ||
117 | OPimTodo todo; | ||
118 | |||
119 | for ( uint i = 0; i < count; ++i ) { | ||
120 | uid = effective[i]; | ||
121 | todo = find( uid, effective, i, Frontend::Forward ); | ||
122 | /* | ||
123 | * If isOverdue but in the 'normal' range we will fill | ||
124 | * the hash so we won't have duplicates in OPimBackendOccurrence | ||
125 | */ | ||
126 | if ( todo.isOverdue() ) | ||
127 | hash.insert( uid, new int(6) ); | ||
128 | OPimBackendOccurrence oc = todo.hasStartDate() ? | ||
129 | OPimBackendOccurrence( todo.startDate(), | ||
130 | todo.dueDate(), uid ) : | ||
131 | OPimBackendOccurrence( todo.dueDate(), uid, QString::null ); | ||
132 | oc.setSummary( todo.summary() ); | ||
133 | lst.append( oc ); | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Create the OverDue items but skip | ||
138 | * the already handled Records | ||
139 | */ | ||
140 | if ( !overdue.isEmpty() ) { | ||
141 | QDate today = QDate::currentDate(); | ||
142 | QDate dueDate = (start >= today && today <= end ) ? today : start; | ||
143 | count = overdue.count(); | ||
144 | for ( uint i = 0; i < count; ++i ) { | ||
145 | uid = overdue[i]; | ||
146 | if (!hash.find( uid ) ) | ||
147 | continue; | ||
148 | todo = find( uid, overdue, i, Frontend::Forward ); | ||
149 | lst.append( OPimBackendOccurrence(dueDate, uid, todo.summary() ) ); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | return lst; | ||
154 | } | ||
41 | } | 155 | } |
diff --git a/libopie2/opiepim/backend/otodoaccessbackend.h b/libopie2/opiepim/backend/otodoaccessbackend.h index 9dfda45..66297bb 100644 --- a/libopie2/opiepim/backend/otodoaccessbackend.h +++ b/libopie2/opiepim/backend/otodoaccessbackend.h | |||
@@ -1,59 +1,79 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) The Main Author <main-author@whereever.org> | 3 | Copyright (C) The Main Author <main-author@whereever.org> |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | #ifndef OPIE_TODO_ACCESS_BACKEND_H | 29 | #ifndef OPIE_TODO_ACCESS_BACKEND_H |
30 | #define OPIE_TODO_ACCESS_BACKEND_H | 30 | #define OPIE_TODO_ACCESS_BACKEND_H |
31 | 31 | ||
32 | #include <qbitarray.h> | 32 | #include <qbitarray.h> |
33 | 33 | ||
34 | #include <opie2/opimtodo.h> | 34 | #include <opie2/opimtodo.h> |
35 | #include <opie2/opimaccessbackend.h> | 35 | #include <opie2/opimaccessbackend.h> |
36 | 36 | ||
37 | namespace Opie { | 37 | namespace Opie { |
38 | class OPimTodoAccessBackend : public OPimAccessBackend<OPimTodo> { | 38 | class OPimTodoAccessBackend : public OPimAccessBackend<OPimTodo> { |
39 | public: | 39 | public: |
40 | OPimTodoAccessBackend(); | 40 | OPimTodoAccessBackend(); |
41 | ~OPimTodoAccessBackend(); | 41 | ~OPimTodoAccessBackend(); |
42 | virtual QArray<int> effectiveToDos( const QDate& start, | 42 | virtual UIDArray effectiveToDos( const QDate& start, |
43 | const QDate& end, | 43 | const QDate& end, |
44 | bool includeNoDates ) = 0; | 44 | bool includeNoDates )const = 0; |
45 | virtual QArray<int> overDue() = 0; | 45 | virtual UIDArray overDue()const = 0; |
46 | virtual QArray<int> sorted( bool asc, int sortOrder, int sortFilter, | 46 | virtual void removeAllCompleted() = 0; |
47 | int cat ) = 0; | 47 | |
48 | virtual void removeAllCompleted() = 0; | 48 | /** |
49 | virtual QBitArray supports()const = 0; | 49 | * Common and probably inefficent implementation |
50 | 50 | * for queryByExample, matchRegexp, sorted | |
51 | * and occurrences | ||
52 | */ | ||
53 | //@{ | ||
54 | UIDArray queryByExample( const OPimTodo&, int settings, const QDateTime& d = QDateTime() )const; | ||
55 | UIDArray sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const; | ||
56 | OPimBackendOccurrence::List occurrences( const QDate&, const QDate& )const; | ||
57 | //@} | ||
58 | |||
51 | private: | 59 | private: |
52 | class Private; | 60 | class Private; |
53 | Private *d; | 61 | Private *d; |
54 | 62 | ||
55 | }; | 63 | }; |
56 | |||
57 | } | 64 | } |
58 | 65 | ||
66 | |||
67 | /** | ||
68 | * \fn Opie::OPimBackendOccurrence::List Opie::OPimTodoAccessBackend::occurrences(const QDate& start,const QDate& end)const | ||
69 | * \brief Return occurrences for a period of time | ||
70 | * | ||
71 | * This method will return the 'effective' Todos and also | ||
72 | * 'Overdue' Todos. Overdues will be shown on the 'current' | ||
73 | * day if it is in the range or on \par start. If the overdue | ||
74 | * is inside the 'Effective Todos' we will skip the | ||
75 | * special overdue handling. | ||
76 | * | ||
77 | * | ||
78 | */ | ||
59 | #endif | 79 | #endif |
diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp index 4e3e47b..2bcab29 100644 --- a/libopie2/opiepim/backend/otodoaccesssql.cpp +++ b/libopie2/opiepim/backend/otodoaccesssql.cpp | |||
@@ -74,822 +74,757 @@ namespace { | |||
74 | * LoadQuery | 74 | * LoadQuery |
75 | * this one queries for all uids | 75 | * this one queries for all uids |
76 | */ | 76 | */ |
77 | class LoadQuery : public OSQLQuery { | 77 | class LoadQuery : public OSQLQuery { |
78 | public: | 78 | public: |
79 | LoadQuery(); | 79 | LoadQuery(); |
80 | ~LoadQuery(); | 80 | ~LoadQuery(); |
81 | QString query()const; | 81 | QString query()const; |
82 | }; | 82 | }; |
83 | 83 | ||
84 | /** | 84 | /** |
85 | * inserts/adds a OPimTodo to the table | 85 | * inserts/adds a OPimTodo to the table |
86 | */ | 86 | */ |
87 | class InsertQuery : public OSQLQuery { | 87 | class InsertQuery : public OSQLQuery { |
88 | public: | 88 | public: |
89 | InsertQuery(const OPimTodo& ); | 89 | InsertQuery(const OPimTodo& ); |
90 | ~InsertQuery(); | 90 | ~InsertQuery(); |
91 | QString query()const; | 91 | QString query()const; |
92 | private: | 92 | private: |
93 | OPimTodo m_todo; | 93 | OPimTodo m_todo; |
94 | }; | 94 | }; |
95 | 95 | ||
96 | /** | 96 | /** |
97 | * removes one from the table | 97 | * removes one from the table |
98 | */ | 98 | */ |
99 | class RemoveQuery : public OSQLQuery { | 99 | class RemoveQuery : public OSQLQuery { |
100 | public: | 100 | public: |
101 | RemoveQuery(int uid ); | 101 | RemoveQuery(int uid ); |
102 | ~RemoveQuery(); | 102 | ~RemoveQuery(); |
103 | QString query()const; | 103 | QString query()const; |
104 | private: | 104 | private: |
105 | int m_uid; | 105 | int m_uid; |
106 | }; | 106 | }; |
107 | 107 | ||
108 | /** | 108 | /** |
109 | * Clears (delete) a Table | 109 | * Clears (delete) a Table |
110 | */ | 110 | */ |
111 | class ClearQuery : public OSQLQuery { | 111 | class ClearQuery : public OSQLQuery { |
112 | public: | 112 | public: |
113 | ClearQuery(); | 113 | ClearQuery(); |
114 | ~ClearQuery(); | 114 | ~ClearQuery(); |
115 | QString query()const; | 115 | QString query()const; |
116 | 116 | ||
117 | }; | 117 | }; |
118 | 118 | ||
119 | /** | 119 | /** |
120 | * a find query | 120 | * a find query |
121 | */ | 121 | */ |
122 | class FindQuery : public OSQLQuery { | 122 | class FindQuery : public OSQLQuery { |
123 | public: | 123 | public: |
124 | FindQuery(int uid); | 124 | FindQuery(int uid); |
125 | FindQuery(const QArray<int>& ); | 125 | FindQuery(const QArray<int>& ); |
126 | ~FindQuery(); | 126 | ~FindQuery(); |
127 | QString query()const; | 127 | QString query()const; |
128 | private: | 128 | private: |
129 | QString single()const; | 129 | QString single()const; |
130 | QString multi()const; | 130 | QString multi()const; |
131 | QArray<int> m_uids; | 131 | QArray<int> m_uids; |
132 | int m_uid; | 132 | int m_uid; |
133 | }; | 133 | }; |
134 | 134 | ||
135 | /** | 135 | /** |
136 | * overdue query | 136 | * overdue query |
137 | */ | 137 | */ |
138 | class OverDueQuery : public OSQLQuery { | 138 | class OverDueQuery : public OSQLQuery { |
139 | public: | 139 | public: |
140 | OverDueQuery(); | 140 | OverDueQuery(); |
141 | ~OverDueQuery(); | 141 | ~OverDueQuery(); |
142 | QString query()const; | 142 | QString query()const; |
143 | }; | 143 | }; |
144 | class EffQuery : public OSQLQuery { | 144 | class EffQuery : public OSQLQuery { |
145 | public: | 145 | public: |
146 | EffQuery( const QDate&, const QDate&, bool inc ); | 146 | EffQuery( const QDate&, const QDate&, bool inc ); |
147 | ~EffQuery(); | 147 | ~EffQuery(); |
148 | QString query()const; | 148 | QString query()const; |
149 | private: | 149 | private: |
150 | QString with()const; | 150 | QString with()const; |
151 | QString out()const; | 151 | QString out()const; |
152 | QDate m_start; | 152 | QDate m_start; |
153 | QDate m_end; | 153 | QDate m_end; |
154 | bool m_inc :1; | 154 | bool m_inc :1; |
155 | }; | 155 | }; |
156 | 156 | ||
157 | 157 | ||
158 | /** | 158 | /** |
159 | * a find query for custom elements | 159 | * a find query for custom elements |
160 | */ | 160 | */ |
161 | class FindCustomQuery : public OSQLQuery { | 161 | class FindCustomQuery : public OSQLQuery { |
162 | public: | 162 | public: |
163 | FindCustomQuery(int uid); | 163 | FindCustomQuery(int uid); |
164 | FindCustomQuery(const QArray<int>& ); | 164 | FindCustomQuery(const QArray<int>& ); |
165 | ~FindCustomQuery(); | 165 | ~FindCustomQuery(); |
166 | QString query()const; | 166 | QString query()const; |
167 | private: | 167 | private: |
168 | QString single()const; | 168 | QString single()const; |
169 | QString multi()const; | 169 | QString multi()const; |
170 | QArray<int> m_uids; | 170 | QArray<int> m_uids; |
171 | int m_uid; | 171 | int m_uid; |
172 | }; | 172 | }; |
173 | 173 | ||
174 | 174 | ||
175 | 175 | ||
176 | CreateQuery::CreateQuery() : OSQLQuery() {} | 176 | CreateQuery::CreateQuery() : OSQLQuery() {} |
177 | CreateQuery::~CreateQuery() {} | 177 | CreateQuery::~CreateQuery() {} |
178 | QString CreateQuery::query()const { | 178 | QString CreateQuery::query()const { |
179 | QString qu; | 179 | QString qu; |
180 | qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; | 180 | qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; |
181 | qu += "description, summary, priority, DueDate, progress , state, "; | 181 | qu += "description, summary, priority, DueDate, progress , state, "; |
182 | // This is the recurrance-stuff .. Exceptions are currently not supported (see OPimRecurrence.cpp) ! (eilers) | 182 | // This is the recurrance-stuff .. Exceptions are currently not supported (see OPimRecurrence.cpp) ! (eilers) |
183 | qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, "; | 183 | qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, "; |
184 | qu += "reminders, alarms, maintainer, startdate, completeddate);"; | 184 | qu += "reminders, alarms, maintainer, startdate, completeddate);"; |
185 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; | 185 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; |
186 | return qu; | 186 | return qu; |
187 | } | 187 | } |
188 | 188 | ||
189 | LoadQuery::LoadQuery() : OSQLQuery() {} | 189 | LoadQuery::LoadQuery() : OSQLQuery() {} |
190 | LoadQuery::~LoadQuery() {} | 190 | LoadQuery::~LoadQuery() {} |
191 | QString LoadQuery::query()const { | 191 | QString LoadQuery::query()const { |
192 | QString qu; | 192 | QString qu; |
193 | // We do not need "distinct" here. The primary key is always unique.. | 193 | // We do not need "distinct" here. The primary key is always unique.. |
194 | //qu += "select distinct uid from todolist"; | 194 | //qu += "select distinct uid from todolist"; |
195 | qu += "select uid from todolist"; | 195 | qu += "select uid from todolist"; |
196 | 196 | ||
197 | return qu; | 197 | return qu; |
198 | } | 198 | } |
199 | 199 | ||
200 | InsertQuery::InsertQuery( const OPimTodo& todo ) | 200 | InsertQuery::InsertQuery( const OPimTodo& todo ) |
201 | : OSQLQuery(), m_todo( todo ) { | 201 | : OSQLQuery(), m_todo( todo ) { |
202 | } | 202 | } |
203 | InsertQuery::~InsertQuery() { | 203 | InsertQuery::~InsertQuery() { |
204 | } | 204 | } |
205 | /* | 205 | /* |
206 | * converts from a OPimTodo to a query | 206 | * converts from a OPimTodo to a query |
207 | * we leave out X-Ref + Maintainer | 207 | * we leave out X-Ref + Maintainer |
208 | * FIXME: Implement/Finish toMap()/fromMap() into OpimTodo to move the encoding | 208 | * FIXME: Implement/Finish toMap()/fromMap() into OpimTodo to move the encoding |
209 | * decoding stuff there.. (eilers) | 209 | * decoding stuff there.. (eilers) |
210 | */ | 210 | */ |
211 | QString InsertQuery::query()const{ | 211 | QString InsertQuery::query()const{ |
212 | 212 | ||
213 | int year, month, day; | 213 | int year, month, day; |
214 | year = month = day = 0; | 214 | year = month = day = 0; |
215 | if (m_todo.hasDueDate() ) { | 215 | if (m_todo.hasDueDate() ) { |
216 | QDate date = m_todo.dueDate(); | 216 | QDate date = m_todo.dueDate(); |
217 | year = date.year(); | 217 | year = date.year(); |
218 | month = date.month(); | 218 | month = date.month(); |
219 | day = date.day(); | 219 | day = date.day(); |
220 | } | 220 | } |
221 | int sYear = 0, sMonth = 0, sDay = 0; | 221 | int sYear = 0, sMonth = 0, sDay = 0; |
222 | if( m_todo.hasStartDate() ){ | 222 | if( m_todo.hasStartDate() ){ |
223 | QDate sDate = m_todo.startDate(); | 223 | QDate sDate = m_todo.startDate(); |
224 | sYear = sDate.year(); | 224 | sYear = sDate.year(); |
225 | sMonth= sDate.month(); | 225 | sMonth= sDate.month(); |
226 | sDay = sDate.day(); | 226 | sDay = sDate.day(); |
227 | } | 227 | } |
228 | 228 | ||
229 | int eYear = 0, eMonth = 0, eDay = 0; | 229 | int eYear = 0, eMonth = 0, eDay = 0; |
230 | if( m_todo.hasCompletedDate() ){ | 230 | if( m_todo.hasCompletedDate() ){ |
231 | QDate eDate = m_todo.completedDate(); | 231 | QDate eDate = m_todo.completedDate(); |
232 | eYear = eDate.year(); | 232 | eYear = eDate.year(); |
233 | eMonth= eDate.month(); | 233 | eMonth= eDate.month(); |
234 | eDay = eDate.day(); | 234 | eDay = eDate.day(); |
235 | } | 235 | } |
236 | QString qu; | 236 | QString qu; |
237 | QMap<int, QString> recMap = m_todo.recurrence().toMap(); | 237 | QMap<int, QString> recMap = m_todo.recurrence().toMap(); |
238 | qu = "insert into todolist VALUES(" | 238 | qu = "insert into todolist VALUES(" |
239 | + QString::number( m_todo.uid() ) + "," | 239 | + QString::number( m_todo.uid() ) + "," |
240 | + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," | 240 | + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," |
241 | + QString::number( m_todo.isCompleted() ) + "," | 241 | + QString::number( m_todo.isCompleted() ) + "," |
242 | + "'" + m_todo.description() + "'" + "," | 242 | + "'" + m_todo.description() + "'" + "," |
243 | + "'" + m_todo.summary() + "'" + "," | 243 | + "'" + m_todo.summary() + "'" + "," |
244 | + QString::number(m_todo.priority() ) + "," | 244 | + QString::number(m_todo.priority() ) + "," |
245 | + "'" + QString::number(year).rightJustify( 4, '0' ) + "-" | 245 | + "'" + QString::number(year).rightJustify( 4, '0' ) + "-" |
246 | + QString::number(month).rightJustify( 2, '0' ) | 246 | + QString::number(month).rightJustify( 2, '0' ) |
247 | + "-" + QString::number( day ).rightJustify( 2, '0' )+ "'" + "," | 247 | + "-" + QString::number( day ).rightJustify( 2, '0' )+ "'" + "," |
248 | + QString::number( m_todo.progress() ) + "," | 248 | + QString::number( m_todo.progress() ) + "," |
249 | + QString::number( m_todo.state().state() ) + "," | 249 | + QString::number( m_todo.state().state() ) + "," |
250 | + "'" + recMap[ OPimRecurrence::RType ] + "'" + "," | 250 | + "'" + recMap[ OPimRecurrence::RType ] + "'" + "," |
251 | + "'" + recMap[ OPimRecurrence::RWeekdays ] + "'" + "," | 251 | + "'" + recMap[ OPimRecurrence::RWeekdays ] + "'" + "," |
252 | + "'" + recMap[ OPimRecurrence::RPosition ] + "'" + "," | 252 | + "'" + recMap[ OPimRecurrence::RPosition ] + "'" + "," |
253 | + "'" + recMap[ OPimRecurrence::RFreq ] + "'" + "," | 253 | + "'" + recMap[ OPimRecurrence::RFreq ] + "'" + "," |
254 | + "'" + recMap[ OPimRecurrence::RHasEndDate ] + "'" + "," | 254 | + "'" + recMap[ OPimRecurrence::RHasEndDate ] + "'" + "," |
255 | + "'" + recMap[ OPimRecurrence::EndDate ] + "'" + "," | 255 | + "'" + recMap[ OPimRecurrence::EndDate ] + "'" + "," |
256 | + "'" + recMap[ OPimRecurrence::Created ] + "'" + "," | 256 | + "'" + recMap[ OPimRecurrence::Created ] + "'" + "," |
257 | + "'" + recMap[ OPimRecurrence::Exceptions ] + "'" + ","; | 257 | + "'" + recMap[ OPimRecurrence::Exceptions ] + "'" + ","; |
258 | 258 | ||
259 | if ( m_todo.hasNotifiers() ) { | 259 | if ( m_todo.hasNotifiers() ) { |
260 | OPimNotifyManager manager = m_todo.notifiers(); | 260 | OPimNotifyManager manager = m_todo.notifiers(); |
261 | qu += "'" + manager.remindersToString() + "'" + "," | 261 | qu += "'" + manager.remindersToString() + "'" + "," |
262 | + "'" + manager.alarmsToString() + "'" + ","; | 262 | + "'" + manager.alarmsToString() + "'" + ","; |
263 | } | 263 | } |
264 | else{ | 264 | else{ |
265 | qu += QString( "''" ) + "," | 265 | qu += QString( "''" ) + "," |
266 | + "''" + ","; | 266 | + "''" + ","; |
267 | } | 267 | } |
268 | 268 | ||
269 | qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) | 269 | qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) |
270 | + "'" + QString::number(sYear).rightJustify( 4, '0' ) + "-" | 270 | + "'" + QString::number(sYear).rightJustify( 4, '0' ) + "-" |
271 | + QString::number(sMonth).rightJustify( 2, '0' ) | 271 | + QString::number(sMonth).rightJustify( 2, '0' ) |
272 | + "-" + QString::number(sDay).rightJustify( 2, '0' )+ "'" + "," | 272 | + "-" + QString::number(sDay).rightJustify( 2, '0' )+ "'" + "," |
273 | + "'" + QString::number(eYear).rightJustify( 4, '0' ) + "-" | 273 | + "'" + QString::number(eYear).rightJustify( 4, '0' ) + "-" |
274 | + QString::number(eMonth).rightJustify( 2, '0' ) | 274 | + QString::number(eMonth).rightJustify( 2, '0' ) |
275 | + "-"+QString::number(eDay).rightJustify( 2, '0' ) + "'" | 275 | + "-"+QString::number(eDay).rightJustify( 2, '0' ) + "'" |
276 | + "); "; | 276 | + "); "; |
277 | 277 | ||
278 | // Save custom Entries: | 278 | // Save custom Entries: |
279 | int id = 0; | 279 | int id = 0; |
280 | id = 0; | 280 | id = 0; |
281 | QMap<QString, QString> customMap = m_todo.toExtraMap(); | 281 | QMap<QString, QString> customMap = m_todo.toExtraMap(); |
282 | for( QMap<QString, QString>::Iterator it = customMap.begin(); | 282 | for( QMap<QString, QString>::Iterator it = customMap.begin(); |
283 | it != customMap.end(); ++it ){ | 283 | it != customMap.end(); ++it ){ |
284 | qu += "insert into custom_data VALUES(" | 284 | qu += "insert into custom_data VALUES(" |
285 | + QString::number( m_todo.uid() ) | 285 | + QString::number( m_todo.uid() ) |
286 | + "," | 286 | + "," |
287 | + QString::number( id++ ) | 287 | + QString::number( id++ ) |
288 | + ",'" | 288 | + ",'" |
289 | + it.key() | 289 | + it.key() |
290 | + "'," | 290 | + "'," |
291 | + "0" // Priority for future enhancements | 291 | + "0" // Priority for future enhancements |
292 | + ",'" | 292 | + ",'" |
293 | + it.data() | 293 | + it.data() |
294 | + "');"; | 294 | + "');"; |
295 | } | 295 | } |
296 | 296 | ||
297 | 297 | ||
298 | odebug << "add " << qu << "" << oendl; | 298 | odebug << "add " << qu << "" << oendl; |
299 | return qu; | 299 | return qu; |
300 | } | 300 | } |
301 | 301 | ||
302 | RemoveQuery::RemoveQuery(int uid ) | 302 | RemoveQuery::RemoveQuery(int uid ) |
303 | : OSQLQuery(), m_uid( uid ) {} | 303 | : OSQLQuery(), m_uid( uid ) {} |
304 | RemoveQuery::~RemoveQuery() {} | 304 | RemoveQuery::~RemoveQuery() {} |
305 | QString RemoveQuery::query()const { | 305 | QString RemoveQuery::query()const { |
306 | QString qu = "DELETE FROM todolist WHERE uid = " + QString::number(m_uid) + " ;"; | 306 | QString qu = "DELETE FROM todolist WHERE uid = " + QString::number(m_uid) + " ;"; |
307 | qu += "DELETE FROM custom_data WHERE uid = " + QString::number(m_uid); | 307 | qu += "DELETE FROM custom_data WHERE uid = " + QString::number(m_uid); |
308 | return qu; | 308 | return qu; |
309 | } | 309 | } |
310 | 310 | ||
311 | 311 | ||
312 | ClearQuery::ClearQuery() | 312 | ClearQuery::ClearQuery() |
313 | : OSQLQuery() {} | 313 | : OSQLQuery() {} |
314 | ClearQuery::~ClearQuery() {} | 314 | ClearQuery::~ClearQuery() {} |
315 | QString ClearQuery::query()const { | 315 | QString ClearQuery::query()const { |
316 | QString qu = "drop table todolist"; | 316 | QString qu = "drop table todolist"; |
317 | return qu; | 317 | return qu; |
318 | } | 318 | } |
319 | FindQuery::FindQuery(int uid) | 319 | FindQuery::FindQuery(int uid) |
320 | : OSQLQuery(), m_uid(uid ) { | 320 | : OSQLQuery(), m_uid(uid ) { |
321 | } | 321 | } |
322 | FindQuery::FindQuery(const QArray<int>& ints) | 322 | FindQuery::FindQuery(const QArray<int>& ints) |
323 | : OSQLQuery(), m_uids(ints){ | 323 | : OSQLQuery(), m_uids(ints){ |
324 | } | 324 | } |
325 | FindQuery::~FindQuery() { | 325 | FindQuery::~FindQuery() { |
326 | } | 326 | } |
327 | QString FindQuery::query()const{ | 327 | QString FindQuery::query()const{ |
328 | if (m_uids.count() == 0 ) | 328 | if (m_uids.count() == 0 ) |
329 | return single(); | 329 | return single(); |
330 | else | 330 | else |
331 | return multi(); | 331 | return multi(); |
332 | } | 332 | } |
333 | QString FindQuery::single()const{ | 333 | QString FindQuery::single()const{ |
334 | QString qu = "select * from todolist where uid = " + QString::number(m_uid); | 334 | QString qu = "select * from todolist where uid = " + QString::number(m_uid); |
335 | return qu; | 335 | return qu; |
336 | } | 336 | } |
337 | QString FindQuery::multi()const { | 337 | QString FindQuery::multi()const { |
338 | QString qu = "select * from todolist where "; | 338 | QString qu = "select * from todolist where "; |
339 | for (uint i = 0; i < m_uids.count(); i++ ) { | 339 | for (uint i = 0; i < m_uids.count(); i++ ) { |
340 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | 340 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; |
341 | } | 341 | } |
342 | qu.remove( qu.length()-2, 2 ); | 342 | qu.remove( qu.length()-2, 2 ); |
343 | return qu; | 343 | return qu; |
344 | } | 344 | } |
345 | 345 | ||
346 | OverDueQuery::OverDueQuery(): OSQLQuery() {} | 346 | OverDueQuery::OverDueQuery(): OSQLQuery() {} |
347 | OverDueQuery::~OverDueQuery() {} | 347 | OverDueQuery::~OverDueQuery() {} |
348 | QString OverDueQuery::query()const { | 348 | QString OverDueQuery::query()const { |
349 | QDate date = QDate::currentDate(); | 349 | QDate date = QDate::currentDate(); |
350 | QString str; | 350 | QString str; |
351 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'") | 351 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'") |
352 | .arg( QString::number( date.year() ).rightJustify( 4, '0' ) ) | 352 | .arg( QString::number( date.year() ).rightJustify( 4, '0' ) ) |
353 | .arg( QString::number( date.month() ).rightJustify( 2, '0' ) ) | 353 | .arg( QString::number( date.month() ).rightJustify( 2, '0' ) ) |
354 | .arg( QString::number( date.day() ) .rightJustify( 2, '0' ) ); | 354 | .arg( QString::number( date.day() ) .rightJustify( 2, '0' ) ); |
355 | 355 | ||
356 | return str; | 356 | return str; |
357 | } | 357 | } |
358 | 358 | ||
359 | 359 | ||
360 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) | 360 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) |
361 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} | 361 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} |
362 | EffQuery::~EffQuery() {} | 362 | EffQuery::~EffQuery() {} |
363 | QString EffQuery::query()const { | 363 | QString EffQuery::query()const { |
364 | return m_inc ? with() : out(); | 364 | return m_inc ? with() : out(); |
365 | } | 365 | } |
366 | QString EffQuery::with()const { | 366 | QString EffQuery::with()const { |
367 | QString str; | 367 | QString str; |
368 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") | 368 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") |
369 | .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) ) | 369 | .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) ) |
370 | .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) ) | 370 | .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) ) |
371 | .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) ) | 371 | .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) ) |
372 | .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) ) | 372 | .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) ) |
373 | .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) ) | 373 | .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) ) |
374 | .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) ); | 374 | .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) ); |
375 | return str; | 375 | return str; |
376 | } | 376 | } |
377 | QString EffQuery::out()const { | 377 | QString EffQuery::out()const { |
378 | QString str; | 378 | QString str; |
379 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") | 379 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") |
380 | .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) ) | 380 | .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) ) |
381 | .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) ) | 381 | .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) ) |
382 | .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) ) | 382 | .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) ) |
383 | .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) ) | 383 | .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) ) |
384 | .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) ) | 384 | .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) ) |
385 | .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) ); | 385 | .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) ); |
386 | 386 | ||
387 | return str; | 387 | return str; |
388 | } | 388 | } |
389 | 389 | ||
390 | FindCustomQuery::FindCustomQuery(int uid) | 390 | FindCustomQuery::FindCustomQuery(int uid) |
391 | : OSQLQuery(), m_uid( uid ) { | 391 | : OSQLQuery(), m_uid( uid ) { |
392 | } | 392 | } |
393 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) | 393 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) |
394 | : OSQLQuery(), m_uids( ints ){ | 394 | : OSQLQuery(), m_uids( ints ){ |
395 | } | 395 | } |
396 | FindCustomQuery::~FindCustomQuery() { | 396 | FindCustomQuery::~FindCustomQuery() { |
397 | } | 397 | } |
398 | QString FindCustomQuery::query()const{ | 398 | QString FindCustomQuery::query()const{ |
399 | return single(); // Multiple requests not supported ! | 399 | return single(); // Multiple requests not supported ! |
400 | } | 400 | } |
401 | QString FindCustomQuery::single()const{ | 401 | QString FindCustomQuery::single()const{ |
402 | QString qu = "select uid, type, value from custom_data where uid = "; | 402 | QString qu = "select uid, type, value from custom_data where uid = "; |
403 | qu += QString::number(m_uid); | 403 | qu += QString::number(m_uid); |
404 | return qu; | 404 | return qu; |
405 | } | 405 | } |
406 | 406 | ||
407 | }; | 407 | }; |
408 | 408 | ||
409 | 409 | ||
410 | namespace Opie { | 410 | namespace Opie { |
411 | OPimTodoAccessBackendSQL::OPimTodoAccessBackendSQL( const QString& file ) | 411 | OPimTodoAccessBackendSQL::OPimTodoAccessBackendSQL( const QString& file ) |
412 | : OPimTodoAccessBackend(),/* m_dict(15),*/ m_driver(NULL), m_dirty(true) | 412 | : OPimTodoAccessBackend(),/* m_dict(15),*/ m_driver(NULL), m_dirty(true) |
413 | { | 413 | { |
414 | QString fi = file; | 414 | QString fi = file; |
415 | if ( fi.isEmpty() ) | 415 | if ( fi.isEmpty() ) |
416 | fi = Global::applicationFileName( "todolist", "todolist.db" ); | 416 | fi = Global::applicationFileName( "todolist", "todolist.db" ); |
417 | OSQLManager man; | 417 | OSQLManager man; |
418 | m_driver = man.standard(); | 418 | m_driver = man.standard(); |
419 | m_driver->setUrl(fi); | 419 | m_driver->setUrl(fi); |
420 | // fillDict(); | 420 | // fillDict(); |
421 | } | 421 | } |
422 | 422 | ||
423 | OPimTodoAccessBackendSQL::~OPimTodoAccessBackendSQL(){ | 423 | OPimTodoAccessBackendSQL::~OPimTodoAccessBackendSQL(){ |
424 | if( m_driver ) | 424 | if( m_driver ) |
425 | delete m_driver; | 425 | delete m_driver; |
426 | } | 426 | } |
427 | 427 | ||
428 | bool OPimTodoAccessBackendSQL::load(){ | 428 | bool OPimTodoAccessBackendSQL::load(){ |
429 | if (!m_driver->open() ) | 429 | if (!m_driver->open() ) |
430 | return false; | 430 | return false; |
431 | 431 | ||
432 | CreateQuery creat; | 432 | CreateQuery creat; |
433 | OSQLResult res = m_driver->query(&creat ); | 433 | OSQLResult res = m_driver->query(&creat ); |
434 | 434 | ||
435 | m_dirty = true; | 435 | m_dirty = true; |
436 | return true; | 436 | return true; |
437 | } | 437 | } |
438 | bool OPimTodoAccessBackendSQL::reload(){ | 438 | bool OPimTodoAccessBackendSQL::reload(){ |
439 | return load(); | 439 | return load(); |
440 | } | 440 | } |
441 | 441 | ||
442 | bool OPimTodoAccessBackendSQL::save(){ | 442 | bool OPimTodoAccessBackendSQL::save(){ |
443 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) | 443 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) |
444 | } | 444 | } |
445 | QArray<int> OPimTodoAccessBackendSQL::allRecords()const { | 445 | QArray<int> OPimTodoAccessBackendSQL::allRecords()const { |
446 | if (m_dirty ) | 446 | if (m_dirty ) |
447 | update(); | 447 | update(); |
448 | 448 | ||
449 | return m_uids; | 449 | return m_uids; |
450 | } | 450 | } |
451 | QArray<int> OPimTodoAccessBackendSQL::queryByExample( const OPimTodo& , int, const QDateTime& ){ | 451 | QArray<int> OPimTodoAccessBackendSQL::queryByExample( const OPimTodo& , int, const QDateTime& ){ |
452 | QArray<int> ints(0); | 452 | QArray<int> ints(0); |
453 | return ints; | 453 | return ints; |
454 | } | 454 | } |
455 | OPimTodo OPimTodoAccessBackendSQL::find(int uid ) const{ | 455 | OPimTodo OPimTodoAccessBackendSQL::find(int uid ) const{ |
456 | FindQuery query( uid ); | 456 | FindQuery query( uid ); |
457 | return parseResultAndCache( uid, m_driver->query(&query) ); | 457 | return parseResultAndCache( uid, m_driver->query(&query) ); |
458 | |||
459 | } | 458 | } |
460 | 459 | ||
461 | // Remember: uid is already in the list of uids, called ints ! | 460 | // Remember: uid is already in the list of uids, called ints ! |
462 | OPimTodo OPimTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, | 461 | OPimTodo OPimTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, |
463 | uint cur, Frontend::CacheDirection dir ) const{ | 462 | uint cur, Frontend::CacheDirection dir ) const{ |
464 | uint CACHE = readAhead(); | 463 | uint CACHE = readAhead(); |
465 | odebug << "searching for " << uid << "" << oendl; | 464 | odebug << "searching for " << uid << "" << oendl; |
466 | QArray<int> search( CACHE ); | 465 | QArray<int> search( CACHE ); |
467 | uint size =0; | 466 | uint size =0; |
468 | OPimTodo to; | ||
469 | 467 | ||
470 | // we try to cache CACHE items | 468 | // we try to cache CACHE items |
471 | switch( dir ) { | 469 | switch( dir ) { |
472 | /* forward */ | 470 | /* forward */ |
473 | case Frontend::Forward: | 471 | case Frontend::Forward: |
474 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { | 472 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { |
475 | odebug << "size " << size << " " << ints[i] << "" << oendl; | ||
476 | search[size] = ints[i]; | 473 | search[size] = ints[i]; |
477 | size++; | 474 | size++; |
478 | } | 475 | } |
479 | break; | 476 | break; |
480 | /* reverse */ | 477 | /* reverse */ |
481 | case Frontend::Reverse: | 478 | case Frontend::Reverse: |
482 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { | 479 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { |
483 | search[size] = ints[i]; | 480 | search[size] = ints[i]; |
484 | size++; | 481 | size++; |
485 | } | 482 | } |
486 | break; | 483 | break; |
487 | } | 484 | } |
488 | 485 | ||
489 | search.resize( size ); | 486 | search.resize( size ); |
490 | FindQuery query( search ); | 487 | FindQuery query( search ); |
491 | OSQLResult res = m_driver->query( &query ); | 488 | OSQLResult res = m_driver->query( &query ); |
492 | if ( res.state() != OSQLResult::Success ) | 489 | if ( res.state() != OSQLResult::Success ) |
493 | return to; | 490 | return OPimTodo(); |
494 | 491 | ||
495 | return parseResultAndCache( uid, res ); | 492 | return parseResultAndCache( uid, res ); |
496 | } | 493 | } |
497 | 494 | ||
498 | void OPimTodoAccessBackendSQL::clear() { | 495 | void OPimTodoAccessBackendSQL::clear() { |
499 | ClearQuery cle; | 496 | ClearQuery cle; |
500 | OSQLResult res = m_driver->query( &cle ); | 497 | OSQLResult res = m_driver->query( &cle ); |
501 | CreateQuery qu; | 498 | CreateQuery qu; |
502 | res = m_driver->query(&qu); | 499 | res = m_driver->query(&qu); |
503 | } | 500 | } |
504 | bool OPimTodoAccessBackendSQL::add( const OPimTodo& t) { | 501 | bool OPimTodoAccessBackendSQL::add( const OPimTodo& t) { |
505 | InsertQuery ins( t ); | 502 | InsertQuery ins( t ); |
506 | OSQLResult res = m_driver->query( &ins ); | 503 | OSQLResult res = m_driver->query( &ins ); |
507 | 504 | ||
508 | if ( res.state() == OSQLResult::Failure ) | 505 | if ( res.state() == OSQLResult::Failure ) |
509 | return false; | 506 | return false; |
507 | |||
510 | int c = m_uids.count(); | 508 | int c = m_uids.count(); |
511 | m_uids.resize( c+1 ); | 509 | m_uids.resize( c+1 ); |
512 | m_uids[c] = t.uid(); | 510 | m_uids[c] = t.uid(); |
513 | 511 | ||
514 | return true; | 512 | return true; |
515 | } | 513 | } |
516 | bool OPimTodoAccessBackendSQL::remove( int uid ) { | 514 | bool OPimTodoAccessBackendSQL::remove( int uid ) { |
517 | RemoveQuery rem( uid ); | 515 | RemoveQuery rem( uid ); |
518 | OSQLResult res = m_driver->query(&rem ); | 516 | OSQLResult res = m_driver->query(&rem ); |
519 | 517 | ||
520 | if ( res.state() == OSQLResult::Failure ) | 518 | if ( res.state() == OSQLResult::Failure ) |
521 | return false; | 519 | return false; |
522 | 520 | ||
523 | m_dirty = true; | 521 | m_dirty = true; |
524 | return true; | 522 | return true; |
525 | } | 523 | } |
526 | /* | 524 | /* |
527 | * FIXME better set query | 525 | * FIXME better set query |
528 | * but we need the cache for that | 526 | * but we need the cache for that |
529 | * now we remove | 527 | * now we remove |
530 | */ | 528 | */ |
531 | bool OPimTodoAccessBackendSQL::replace( const OPimTodo& t) { | 529 | bool OPimTodoAccessBackendSQL::replace( const OPimTodo& t) { |
532 | remove( t.uid() ); | 530 | remove( t.uid() ); |
533 | bool b= add(t); | 531 | bool b= add(t); |
534 | m_dirty = false; // we changed some stuff but the UID stayed the same | 532 | m_dirty = false; // we changed some stuff but the UID stayed the same |
535 | return b; | 533 | return b; |
536 | } | 534 | } |
537 | QArray<int> OPimTodoAccessBackendSQL::overDue() { | 535 | QArray<int> OPimTodoAccessBackendSQL::overDue()const { |
538 | OverDueQuery qu; | 536 | OverDueQuery qu; |
539 | return uids( m_driver->query(&qu ) ); | 537 | return uids( m_driver->query(&qu ) ); |
540 | } | 538 | } |
541 | QArray<int> OPimTodoAccessBackendSQL::effectiveToDos( const QDate& s, | 539 | QArray<int> OPimTodoAccessBackendSQL::effectiveToDos( const QDate& s, |
542 | const QDate& t, | 540 | const QDate& t, |
543 | bool u) { | 541 | bool u)const { |
544 | EffQuery ef(s, t, u ); | 542 | EffQuery ef(s, t, u ); |
545 | return uids (m_driver->query(&ef) ); | 543 | return uids (m_driver->query(&ef) ); |
546 | } | 544 | } |
545 | |||
546 | #if 0 | ||
547 | /* | 547 | /* |
548 | * | 548 | * |
549 | */ | 549 | */ |
550 | QArray<int> OPimTodoAccessBackendSQL::sorted( bool asc, int sortOrder, | 550 | QArray<int> OPimTodoAccessBackendSQL::sorted( bool asc, int sortOrder, |
551 | int sortFilter, int cat ) { | 551 | int sortFilter, int cat ) { |
552 | odebug << "sorted " << asc << ", " << sortOrder << "" << oendl; | 552 | odebug << "sorted " << asc << ", " << sortOrder << "" << oendl; |
553 | QString query; | 553 | QString query; |
554 | query = "select uid from todolist WHERE "; | 554 | query = "select uid from todolist WHERE "; |
555 | 555 | ||
556 | /* | 556 | /* |
557 | * Sort Filter stuff | 557 | * Sort Filter stuff |
558 | * not that straight forward | 558 | * not that straight forward |
559 | * FIXME: Replace magic numbers | 559 | * FIXME: Replace magic numbers |
560 | * | 560 | * |
561 | */ | 561 | */ |
562 | /* Category */ | 562 | /* Category */ |
563 | if ( sortFilter & 1 ) { | 563 | if ( sortFilter & OPimTodoAccess::FilterCategory ) { |
564 | QString str; | 564 | QString str; |
565 | if (cat != 0 ) str = QString::number( cat ); | 565 | if (cat != 0 ) str = QString::number( cat ); |
566 | query += " categories like '%" +str+"%' AND"; | 566 | query += " categories like '%" +str+"%' AND"; |
567 | } | 567 | } |
568 | /* Show only overdue */ | 568 | /* Show only overdue */ |
569 | if ( sortFilter & 2 ) { | 569 | if ( sortFilter & OPimTodoAccess::OnlyOverDue ) { |
570 | QDate date = QDate::currentDate(); | 570 | QDate date = QDate::currentDate(); |
571 | QString due; | 571 | QString due; |
572 | QString base; | 572 | QString base; |
573 | base = QString("DueDate <= '%1-%2-%3' AND completed = 0") | 573 | base = QString("DueDate <= '%1-%2-%3' AND completed = 0") |
574 | .arg( QString::number( date.year() ).rightJustify( 4, '0' ) ) | 574 | .arg( QString::number( date.year() ).rightJustify( 4, '0' ) ) |
575 | .arg( QString::number( date.month() ).rightJustify( 2, '0' ) ) | 575 | .arg( QString::number( date.month() ).rightJustify( 2, '0' ) ) |
576 | .arg( QString::number( date.day() ).rightJustify( 2, '0' ) ); | 576 | .arg( QString::number( date.day() ).rightJustify( 2, '0' ) ); |
577 | query += " " + base + " AND"; | 577 | query += " " + base + " AND"; |
578 | } | 578 | } |
579 | /* not show completed */ | 579 | /* not show completed */ |
580 | if ( sortFilter & 4 ) { | 580 | if ( sortFilter & OPimTodoAccess::DoNotShowCompleted ) { |
581 | query += " completed = 0 AND"; | 581 | query += " completed = 0 AND"; |
582 | }else{ | 582 | }else{ |
583 | query += " ( completed = 1 OR completed = 0) AND"; | 583 | query += " ( completed = 1 OR completed = 0) AND"; |
584 | } | 584 | } |
585 | /* strip the end */ | 585 | /* strip the end */ |
586 | query = query.remove( query.length()-3, 3 ); | 586 | query = query.remove( query.length()-3, 3 ); |
587 | 587 | ||
588 | 588 | ||
589 | /* | 589 | /* |
590 | * sort order stuff | 590 | * sort order stuff |
591 | * quite straight forward | 591 | * quite straight forward |
592 | */ | 592 | */ |
593 | query += "ORDER BY "; | 593 | query += "ORDER BY "; |
594 | switch( sortOrder ) { | 594 | switch( sortOrder ) { |
595 | /* completed */ | 595 | /* completed */ |
596 | case 0: | 596 | case OPimTodoAccess::Completed: |
597 | query += "completed"; | 597 | query += "completed"; |
598 | break; | 598 | break; |
599 | case 1: | 599 | case OPimTodoAccess::Priority: |
600 | query += "priority"; | 600 | query += "priority"; |
601 | break; | 601 | break; |
602 | case 2: | 602 | case OPimTodoAccess::SortSummary: |
603 | query += "summary"; | 603 | query += "summary"; |
604 | break; | 604 | break; |
605 | case 3: | 605 | case OPimTodoAccess::Deadline: |
606 | query += "DueDate"; | 606 | query += "DueDate"; |
607 | break; | 607 | break; |
608 | } | 608 | } |
609 | 609 | ||
610 | if ( !asc ) { | 610 | if ( !asc ) |
611 | odebug << "not ascending!" << oendl; | ||
612 | query += " DESC"; | 611 | query += " DESC"; |
613 | } | 612 | |
614 | 613 | ||
615 | odebug << query << oendl; | 614 | odebug << query << oendl; |
616 | OSQLRawQuery raw(query ); | 615 | OSQLRawQuery raw(query ); |
617 | return uids( m_driver->query(&raw) ); | 616 | return uids( m_driver->query(&raw) ); |
618 | } | 617 | } |
618 | #endif | ||
619 | |||
620 | |||
619 | bool OPimTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ | 621 | bool OPimTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ |
620 | if ( str == "0-0-0" ) | 622 | if ( str == "0-0-0" ) |
621 | return false; | 623 | return false; |
622 | else{ | 624 | else{ |
623 | int day, year, month; | 625 | int day, year, month; |
624 | QStringList list = QStringList::split("-", str ); | 626 | QStringList list = QStringList::split("-", str ); |
625 | year = list[0].toInt(); | 627 | year = list[0].toInt(); |
626 | month = list[1].toInt(); | 628 | month = list[1].toInt(); |
627 | day = list[2].toInt(); | 629 | day = list[2].toInt(); |
628 | da.setYMD( year, month, day ); | 630 | da.setYMD( year, month, day ); |
629 | return true; | 631 | return true; |
630 | } | 632 | } |
631 | } | 633 | } |
634 | |||
635 | |||
632 | OPimTodo OPimTodoAccessBackendSQL::parseResultAndCache( int uid, const OSQLResult& res ) const{ | 636 | OPimTodo OPimTodoAccessBackendSQL::parseResultAndCache( int uid, const OSQLResult& res ) const{ |
633 | if ( res.state() == OSQLResult::Failure ) { | 637 | if ( res.state() == OSQLResult::Failure ) { |
634 | OPimTodo to; | 638 | OPimTodo to; |
635 | return to; | 639 | return to; |
636 | } | 640 | } |
637 | 641 | ||
638 | OPimTodo retTodo; | 642 | OPimTodo retTodo; |
639 | 643 | ||
640 | OSQLResultItem::ValueList list = res.results(); | 644 | OSQLResultItem::ValueList list = res.results(); |
641 | OSQLResultItem::ValueList::Iterator it = list.begin(); | 645 | OSQLResultItem::ValueList::Iterator it = list.begin(); |
642 | odebug << "todo1" << oendl; | 646 | OPimTodo to, tmp; |
643 | OPimTodo to = todo( (*it) ); | ||
644 | cache( to ); | ||
645 | ++it; | ||
646 | 647 | ||
647 | for ( ; it != list.end(); ++it ) { | 648 | for ( ; it != list.end(); ++it ) { |
648 | odebug << "caching" << oendl; | 649 | OPimTodo newTodo = parse( (*it) ); |
649 | OPimTodo newTodo = todo( (*it) ); | ||
650 | cache( newTodo ); | 650 | cache( newTodo ); |
651 | if ( newTodo.uid() == uid ) | 651 | if ( newTodo.uid() == uid ) |
652 | retTodo = newTodo; | 652 | retTodo = newTodo; |
653 | } | 653 | } |
654 | return retTodo; | 654 | return retTodo; |
655 | } | 655 | } |
656 | OPimTodo OPimTodoAccessBackendSQL::todo( OSQLResultItem& item )const { | 656 | OPimTodo OPimTodoAccessBackendSQL::parse( OSQLResultItem& item )const { |
657 | odebug << "todo(ResultItem)" << oendl; | ||
658 | 657 | ||
659 | // Request information from addressbook table and create the OPimTodo-object. | 658 | // Request information from addressbook table and create the OPimTodo-object. |
660 | 659 | ||
661 | bool hasDueDate = false; QDate dueDate = QDate::currentDate(); | 660 | bool hasDueDate = false; QDate dueDate = QDate::currentDate(); |
662 | hasDueDate = date( dueDate, item.data("DueDate") ); | 661 | hasDueDate = date( dueDate, item.data("DueDate") ); |
663 | QStringList cats = QStringList::split(";", item.data("categories") ); | 662 | QStringList cats = QStringList::split(";", item.data("categories") ); |
664 | 663 | ||
665 | odebug << "Item is completed: " << item.data("completed").toInt() << "" << oendl; | ||
666 | |||
667 | OPimTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), | 664 | OPimTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), |
668 | cats, item.data("summary"), item.data("description"), | 665 | cats, item.data("summary"), item.data("description"), |
669 | item.data("progress").toUShort(), hasDueDate, dueDate, | 666 | item.data("progress").toUShort(), hasDueDate, dueDate, |
670 | item.data("uid").toInt() ); | 667 | item.data("uid").toInt() ); |
671 | 668 | ||
672 | bool isOk; | 669 | bool isOk; |
673 | int prioInt = QString( item.data("priority") ).toInt( &isOk ); | 670 | int prioInt = QString( item.data("priority") ).toInt( &isOk ); |
674 | if ( isOk ) | 671 | if ( isOk ) |
675 | to.setPriority( prioInt ); | 672 | to.setPriority( prioInt ); |
676 | 673 | ||
677 | bool hasStartDate = false; QDate startDate = QDate::currentDate(); | 674 | bool hasStartDate = false; QDate startDate = QDate::currentDate(); |
678 | hasStartDate = date( startDate, item.data("startdate") ); | 675 | hasStartDate = date( startDate, item.data("startdate") ); |
679 | bool hasCompletedDate = false; QDate completedDate = QDate::currentDate(); | 676 | bool hasCompletedDate = false; QDate completedDate = QDate::currentDate(); |
680 | hasCompletedDate = date( completedDate, item.data("completeddate") ); | 677 | hasCompletedDate = date( completedDate, item.data("completeddate") ); |
681 | 678 | ||
682 | if ( hasStartDate ) | 679 | if ( hasStartDate ) |
683 | to.setStartDate( startDate ); | 680 | to.setStartDate( startDate ); |
684 | if ( hasCompletedDate ) | 681 | if ( hasCompletedDate ) |
685 | to.setCompletedDate( completedDate ); | 682 | to.setCompletedDate( completedDate ); |
686 | 683 | ||
687 | OPimNotifyManager& manager = to.notifiers(); | 684 | OPimNotifyManager& manager = to.notifiers(); |
688 | manager.alarmsFromString( item.data("alarms") ); | 685 | manager.alarmsFromString( item.data("alarms") ); |
689 | manager.remindersFromString( item.data("reminders") ); | 686 | manager.remindersFromString( item.data("reminders") ); |
690 | 687 | ||
691 | OPimState pimState; | 688 | OPimState pimState; |
692 | pimState.setState( QString( item.data("state") ).toInt() ); | 689 | pimState.setState( QString( item.data("state") ).toInt() ); |
693 | to.setState( pimState ); | 690 | to.setState( pimState ); |
694 | 691 | ||
695 | QMap<int, QString> recMap; | 692 | QMap<int, QString> recMap; |
696 | recMap.insert( OPimRecurrence::RType , item.data("RType") ); | 693 | recMap.insert( OPimRecurrence::RType , item.data("RType") ); |
697 | recMap.insert( OPimRecurrence::RWeekdays , item.data("RWeekdays") ); | 694 | recMap.insert( OPimRecurrence::RWeekdays , item.data("RWeekdays") ); |
698 | recMap.insert( OPimRecurrence::RPosition , item.data("RPosition") ); | 695 | recMap.insert( OPimRecurrence::RPosition , item.data("RPosition") ); |
699 | recMap.insert( OPimRecurrence::RFreq , item.data("RFreq") ); | 696 | recMap.insert( OPimRecurrence::RFreq , item.data("RFreq") ); |
700 | recMap.insert( OPimRecurrence::RHasEndDate, item.data("RHasEndDate") ); | 697 | recMap.insert( OPimRecurrence::RHasEndDate, item.data("RHasEndDate") ); |
701 | recMap.insert( OPimRecurrence::EndDate , item.data("EndDate") ); | 698 | recMap.insert( OPimRecurrence::EndDate , item.data("EndDate") ); |
702 | recMap.insert( OPimRecurrence::Created , item.data("Created") ); | 699 | recMap.insert( OPimRecurrence::Created , item.data("Created") ); |
703 | recMap.insert( OPimRecurrence::Exceptions , item.data("Exceptions") ); | 700 | recMap.insert( OPimRecurrence::Exceptions , item.data("Exceptions") ); |
704 | 701 | ||
705 | OPimRecurrence recur; | 702 | OPimRecurrence recur; |
706 | recur.fromMap( recMap ); | 703 | recur.fromMap( recMap ); |
707 | to.setRecurrence( recur ); | 704 | to.setRecurrence( recur ); |
708 | 705 | ||
709 | // Finally load the custom-entries for this UID and put it into the created object | 706 | // Finally load the custom-entries for this UID and put it into the created object |
710 | to.setExtraMap( requestCustom( to.uid() ) ); | 707 | to.setExtraMap( requestCustom( to.uid() ) ); |
711 | 708 | ||
712 | return to; | 709 | return to; |
713 | } | 710 | } |
714 | 711 | ||
715 | // FIXME: Where is the difference to "find" ? (eilers) | 712 | // FIXME: Where is the difference to "find" ? (eilers) |
716 | OPimTodo OPimTodoAccessBackendSQL::todo( int uid )const { | 713 | OPimTodo OPimTodoAccessBackendSQL::todo( int uid )const { |
717 | FindQuery find( uid ); | 714 | FindQuery find( uid ); |
718 | return parseResultAndCache( uid, m_driver->query(&find) ); | 715 | return parseResultAndCache( uid, m_driver->query(&find) ); |
719 | } | 716 | } |
720 | /* | ||
721 | * update the dict | ||
722 | */ | ||
723 | void OPimTodoAccessBackendSQL::fillDict() { | ||
724 | 717 | ||
725 | #if 0 | ||
726 | /* initialize dict */ | ||
727 | /* | ||
728 | * UPDATE dict if you change anything!!! | ||
729 | * FIXME: Isn't this dict obsolete ? (eilers) | ||
730 | */ | ||
731 | m_dict.setAutoDelete( TRUE ); | ||
732 | m_dict.insert("Categories" , new int(OPimTodo::Category) ); | ||
733 | m_dict.insert("Uid" , new int(OPimTodo::Uid) ); | ||
734 | m_dict.insert("HasDate" , new int(OPimTodo::HasDate) ); | ||
735 | m_dict.insert("Completed" , new int(OPimTodo::Completed) ); | ||
736 | m_dict.insert("Description" , new int(OPimTodo::Description) ); | ||
737 | m_dict.insert("Summary" , new int(OPimTodo::Summary) ); | ||
738 | m_dict.insert("Priority" , new int(OPimTodo::Priority) ); | ||
739 | m_dict.insert("DateDay" , new int(OPimTodo::DateDay) ); | ||
740 | m_dict.insert("DateMonth" , new int(OPimTodo::DateMonth) ); | ||
741 | m_dict.insert("DateYear" , new int(OPimTodo::DateYear) ); | ||
742 | m_dict.insert("Progress" , new int(OPimTodo::Progress) ); | ||
743 | m_dict.insert("Completed", new int(OPimTodo::Completed) ); // Why twice ? (eilers) | ||
744 | m_dict.insert("CrossReference", new int(OPimTodo::CrossReference) ); | ||
745 | // m_dict.insert("HasAlarmDateTime",new int(OPimTodo::HasAlarmDateTime) ); // old stuff (eilers) | ||
746 | // m_dict.insert("AlarmDateTime", new int(OPimTodo::AlarmDateTime) ); // old stuff (eilers) | ||
747 | 718 | ||
748 | #endif | ||
749 | } | ||
750 | /* | 719 | /* |
751 | * need to be const so let's fool the | 720 | * need to be const so let's fool the |
752 | * compiler :( | 721 | * compiler :( |
753 | */ | 722 | */ |
754 | void OPimTodoAccessBackendSQL::update()const { | 723 | void OPimTodoAccessBackendSQL::update()const { |
755 | ((OPimTodoAccessBackendSQL*)this)->m_dirty = false; | 724 | ((OPimTodoAccessBackendSQL*)this)->m_dirty = false; |
756 | LoadQuery lo; | 725 | LoadQuery lo; |
757 | OSQLResult res = m_driver->query(&lo); | 726 | OSQLResult res = m_driver->query(&lo); |
758 | if ( res.state() != OSQLResult::Success ) | 727 | if ( res.state() != OSQLResult::Success ) |
759 | return; | 728 | return; |
760 | 729 | ||
761 | ((OPimTodoAccessBackendSQL*)this)->m_uids = uids( res ); | 730 | ((OPimTodoAccessBackendSQL*)this)->m_uids = uids( res ); |
762 | } | 731 | } |
763 | QArray<int> OPimTodoAccessBackendSQL::uids( const OSQLResult& res) const{ | 732 | QArray<int> OPimTodoAccessBackendSQL::uids( const OSQLResult& res) const{ |
764 | 733 | ||
765 | OSQLResultItem::ValueList list = res.results(); | 734 | OSQLResultItem::ValueList list = res.results(); |
766 | OSQLResultItem::ValueList::Iterator it; | 735 | OSQLResultItem::ValueList::Iterator it; |
767 | QArray<int> ints(list.count() ); | 736 | QArray<int> ints(list.count() ); |
768 | odebug << " count = " << list.count() << "" << oendl; | ||
769 | 737 | ||
770 | int i = 0; | 738 | int i = 0; |
771 | for (it = list.begin(); it != list.end(); ++it ) { | 739 | for (it = list.begin(); it != list.end(); ++it ) { |
772 | ints[i] = (*it).data("uid").toInt(); | 740 | ints[i] = (*it).data("uid").toInt(); |
773 | i++; | 741 | i++; |
774 | } | 742 | } |
775 | return ints; | 743 | return ints; |
776 | } | 744 | } |
777 | 745 | ||
778 | QArray<int> OPimTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const | 746 | QArray<int> OPimTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const |
779 | { | 747 | { |
780 | |||
781 | #if 0 | ||
782 | QArray<int> empty; | ||
783 | return empty; | ||
784 | |||
785 | #else | ||
786 | QString qu = "SELECT uid FROM todolist WHERE ("; | 748 | QString qu = "SELECT uid FROM todolist WHERE ("; |
787 | 749 | ||
788 | // Do it make sense to search other fields, too ? | 750 | // Does it make sense to search other fields, too ? |
789 | qu += " rlike(\""+ r.pattern() + "\",\"description\") OR"; | 751 | qu += " rlike(\""+ r.pattern() + "\",\"description\") OR"; |
790 | qu += " rlike(\""+ r.pattern() + "\",\"summary\")"; | 752 | qu += " rlike(\""+ r.pattern() + "\",\"summary\")"; |
791 | 753 | ||
792 | qu += ")"; | 754 | qu += ")"; |
793 | 755 | ||
794 | odebug << "query: " << qu << "" << oendl; | ||
795 | |||
796 | OSQLRawQuery raw( qu ); | 756 | OSQLRawQuery raw( qu ); |
797 | OSQLResult res = m_driver->query( &raw ); | 757 | OSQLResult res = m_driver->query( &raw ); |
798 | 758 | ||
799 | return uids( res ); | 759 | return uids( res ); |
800 | |||
801 | |||
802 | #endif | ||
803 | |||
804 | } | ||
805 | QBitArray OPimTodoAccessBackendSQL::supports()const { | ||
806 | |||
807 | return sup(); | ||
808 | } | ||
809 | |||
810 | QBitArray OPimTodoAccessBackendSQL::sup() const{ | ||
811 | |||
812 | QBitArray ar( OPimTodo::CompletedDate + 1 ); | ||
813 | ar.fill( true ); | ||
814 | ar[OPimTodo::CrossReference] = false; | ||
815 | ar[OPimTodo::State ] = false; | ||
816 | ar[OPimTodo::Reminders] = false; | ||
817 | ar[OPimTodo::Notifiers] = false; | ||
818 | ar[OPimTodo::Maintainer] = false; | ||
819 | |||
820 | return ar; | ||
821 | } | 760 | } |
822 | 761 | ||
823 | void OPimTodoAccessBackendSQL::removeAllCompleted(){ | 762 | void OPimTodoAccessBackendSQL::removeAllCompleted(){ |
824 | // First we need the uids from all entries which are | 763 | // First we need the uids from all entries which are |
825 | // completed. Then, we just have to remove them... | 764 | // completed. Then, we just have to remove them... |
826 | 765 | ||
827 | QString qu = "SELECT uid FROM todolist WHERE completed = 1"; | 766 | QString qu = "SELECT uid FROM todolist WHERE completed = 1"; |
828 | 767 | ||
829 | OSQLRawQuery raw( qu ); | 768 | OSQLRawQuery raw( qu ); |
830 | OSQLResult res = m_driver->query( &raw ); | 769 | OSQLResult res = m_driver->query( &raw ); |
831 | 770 | ||
832 | QArray<int> completed_uids = uids( res ); | 771 | QArray<int> completed_uids = uids( res ); |
833 | 772 | ||
834 | odebug << "Number of completed: " << completed_uids.size() << "" << oendl; | ||
835 | |||
836 | if ( completed_uids.size() == 0 ) | 773 | if ( completed_uids.size() == 0 ) |
837 | return; | 774 | return; |
838 | 775 | ||
839 | qu = "DELETE FROM todolist WHERE ("; | 776 | qu = "DELETE FROM todolist WHERE ("; |
840 | QString query; | 777 | QString query; |
841 | 778 | ||
842 | for ( int i = 0; i < completed_uids.size(); i++ ){ | 779 | for ( uint i = 0; i < completed_uids.size(); i++ ){ |
843 | if ( !query.isEmpty() ) | 780 | if ( !query.isEmpty() ) |
844 | query += " OR "; | 781 | query += " OR "; |
845 | query += QString( "uid = %1" ).arg( completed_uids[i] ); | 782 | query += QString( "uid = %1" ).arg( completed_uids[i] ); |
846 | } | 783 | } |
847 | qu += query + " );"; | 784 | qu += query + " );"; |
848 | 785 | ||
849 | // Put remove of custom entries in this query to speed up.. | 786 | // Put remove of custom entries in this query to speed up.. |
850 | qu += "DELETE FORM custom_data WHERE ("; | 787 | qu += "DELETE FORM custom_data WHERE ("; |
851 | query = ""; | 788 | query = ""; |
852 | 789 | ||
853 | for ( int i = 0; i < completed_uids.size(); i++ ){ | 790 | for ( uint i = 0; i < completed_uids.size(); i++ ){ |
854 | if ( !query.isEmpty() ) | 791 | if ( !query.isEmpty() ) |
855 | query += " OR "; | 792 | query += " OR "; |
856 | query += QString( "uid = %1" ).arg( completed_uids[i] ); | 793 | query += QString( "uid = %1" ).arg( completed_uids[i] ); |
857 | } | 794 | } |
858 | qu += query + " );"; | 795 | qu += query + " );"; |
859 | 796 | ||
860 | odebug << "query: " << qu << "" << oendl; | ||
861 | |||
862 | OSQLRawQuery raw2( qu ); | 797 | OSQLRawQuery raw2( qu ); |
863 | res = m_driver->query( &raw2 ); | 798 | res = m_driver->query( &raw2 ); |
864 | if ( res.state() == OSQLResult::Failure ) { | 799 | |
800 | if ( res.state() == OSQLResult::Failure ) | ||
865 | owarn << "OPimTodoAccessBackendSQL::removeAllCompleted():Failure in query: " << qu << "" << oendl; | 801 | owarn << "OPimTodoAccessBackendSQL::removeAllCompleted():Failure in query: " << qu << "" << oendl; |
866 | } | 802 | |
867 | } | 803 | } |
868 | 804 | ||
869 | 805 | ||
870 | QMap<QString, QString> OPimTodoAccessBackendSQL::requestCustom( int uid ) const | 806 | QMap<QString, QString> OPimTodoAccessBackendSQL::requestCustom( int uid ) const |
871 | { | 807 | { |
872 | QMap<QString, QString> customMap; | 808 | QMap<QString, QString> customMap; |
873 | 809 | ||
874 | FindCustomQuery query( uid ); | 810 | FindCustomQuery query( uid ); |
875 | OSQLResult res_custom = m_driver->query( &query ); | 811 | OSQLResult res_custom = m_driver->query( &query ); |
876 | 812 | ||
877 | if ( res_custom.state() == OSQLResult::Failure ) { | 813 | if ( res_custom.state() == OSQLResult::Failure ) { |
878 | owarn << "OSQLResult::Failure in find query !!" << oendl; | 814 | owarn << "OSQLResult::Failure in find query !!" << oendl; |
879 | QMap<QString, QString> empty; | 815 | return QMap<QString, QString>(); |
880 | return empty; | ||
881 | } | 816 | } |
882 | 817 | ||
883 | OSQLResultItem::ValueList list = res_custom.results(); | 818 | OSQLResultItem::ValueList list = res_custom.results(); |
884 | OSQLResultItem::ValueList::Iterator it = list.begin(); | 819 | OSQLResultItem::ValueList::Iterator it = list.begin(); |
885 | for ( ; it != list.end(); ++it ) { | 820 | for ( ; it != list.end(); ++it ) |
886 | customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); | 821 | customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); |
887 | } | 822 | |
888 | 823 | ||
889 | return customMap; | 824 | return customMap; |
890 | } | 825 | } |
891 | 826 | ||
892 | 827 | ||
893 | 828 | ||
894 | 829 | ||
895 | } | 830 | } |
diff --git a/libopie2/opiepim/backend/otodoaccesssql.h b/libopie2/opiepim/backend/otodoaccesssql.h index 415f791..0ba8f3a 100644 --- a/libopie2/opiepim/backend/otodoaccesssql.h +++ b/libopie2/opiepim/backend/otodoaccesssql.h | |||
@@ -1,93 +1,88 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | #ifndef OPIE_PIM_ACCESS_SQL_H | 29 | #ifndef OPIE_PIM_ACCESS_SQL_H |
30 | #define OPIE_PIM_ACCESS_SQL_H | 30 | #define OPIE_PIM_ACCESS_SQL_H |
31 | 31 | ||
32 | /* #include <qasciidict.h> */ | 32 | /* #include <qasciidict.h> */ |
33 | 33 | ||
34 | #include <opie2/otodoaccessbackend.h> | 34 | #include <opie2/otodoaccessbackend.h> |
35 | 35 | ||
36 | namespace Opie { | 36 | namespace Opie { |
37 | namespace DB { | 37 | namespace DB { |
38 | class OSQLDriver; | 38 | class OSQLDriver; |
39 | class OSQLResult; | 39 | class OSQLResult; |
40 | class OSQLResultItem; | 40 | class OSQLResultItem; |
41 | } | 41 | } |
42 | } | 42 | } |
43 | 43 | ||
44 | namespace Opie { | 44 | namespace Opie { |
45 | 45 | ||
46 | class OPimTodoAccessBackendSQL : public OPimTodoAccessBackend { | 46 | class OPimTodoAccessBackendSQL : public OPimTodoAccessBackend { |
47 | public: | 47 | public: |
48 | OPimTodoAccessBackendSQL( const QString& file ); | 48 | OPimTodoAccessBackendSQL( const QString& file ); |
49 | ~OPimTodoAccessBackendSQL(); | 49 | ~OPimTodoAccessBackendSQL(); |
50 | 50 | ||
51 | bool load(); | 51 | bool load(); |
52 | bool reload(); | 52 | bool reload(); |
53 | bool save(); | 53 | bool save(); |
54 | QArray<int> allRecords()const; | 54 | QArray<UID> allRecords()const; |
55 | 55 | ||
56 | QArray<int> queryByExample( const OPimTodo& t, int settings, const QDateTime& d = QDateTime() ); | 56 | QArray<UID> queryByExample( const OPimTodo& t, int settings, const QDateTime& d = QDateTime() ); |
57 | OPimTodo find(int uid)const; | 57 | OPimTodo find(UID uid)const; |
58 | OPimTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; | 58 | OPimTodo find(UID uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; |
59 | void clear(); | 59 | void clear(); |
60 | bool add( const OPimTodo& t ); | 60 | bool add( const OPimTodo& t ); |
61 | bool remove( int uid ); | 61 | bool remove( UID uid ); |
62 | bool replace( const OPimTodo& t ); | 62 | bool replace( const OPimTodo& t ); |
63 | 63 | ||
64 | QArray<int> overDue(); | 64 | QArray<UID> overDue()const; |
65 | QArray<int> effectiveToDos( const QDate& start, | 65 | QArray<UID> effectiveToDos( const QDate& start, |
66 | const QDate& end, bool includeNoDates ); | 66 | const QDate& end, bool includeNoDates )const; |
67 | QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat ); | 67 | QArray<UID> matchRegexp( const QRegExp &r ) const; |
68 | |||
69 | QBitArray supports()const; | ||
70 | QArray<int> matchRegexp( const QRegExp &r ) const; | ||
71 | void removeAllCompleted(); | 68 | void removeAllCompleted(); |
72 | 69 | ||
73 | 70 | ||
74 | private: | 71 | private: |
75 | void update()const; | 72 | void update()const; |
76 | void fillDict(); | ||
77 | inline bool date( QDate& date, const QString& )const; | 73 | inline bool date( QDate& date, const QString& )const; |
78 | inline OPimTodo parseResultAndCache( int uid, const Opie::DB::OSQLResult& )const; | 74 | inline OPimTodo parseResultAndCache( UID uid, const Opie::DB::OSQLResult& )const; |
79 | inline OPimTodo todo( Opie::DB::OSQLResultItem& )const; | 75 | inline OPimTodo parse( Opie::DB::OSQLResultItem& )const; |
80 | inline QArray<int> uids( const Opie::DB::OSQLResult& )const; | 76 | inline QArray<UID> uids( const Opie::DB::OSQLResult& )const; |
81 | OPimTodo todo( int uid )const; | 77 | OPimTodo todo( UID uid )const; |
82 | QBitArray sup() const; | 78 | QMap<QString, QString> requestCustom( UID uid ) const; |
83 | QMap<QString, QString> requestCustom( int uid ) const; | ||
84 | 79 | ||
85 | // QAsciiDict<int> m_dict; | 80 | // QAsciiDict<int> m_dict; |
86 | Opie::DB::OSQLDriver* m_driver; | 81 | Opie::DB::OSQLDriver* m_driver; |
87 | QArray<int> m_uids; | 82 | QArray<UID> m_uids; |
88 | bool m_dirty : 1; | 83 | bool m_dirty : 1; |
89 | }; | 84 | }; |
90 | 85 | ||
91 | } | 86 | } |
92 | 87 | ||
93 | #endif | 88 | #endif |
diff --git a/libopie2/opiepim/backend/otodoaccessvcal.cpp b/libopie2/opiepim/backend/otodoaccessvcal.cpp index 7d58a40..aa8a7eb 100644 --- a/libopie2/opiepim/backend/otodoaccessvcal.cpp +++ b/libopie2/opiepim/backend/otodoaccessvcal.cpp | |||
@@ -1,289 +1,259 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <opie2/private/vobject_p.h> | 30 | #include <opie2/private/vobject_p.h> |
31 | 31 | ||
32 | /* OPIE */ | 32 | /* OPIE */ |
33 | #include <opie2/otodoaccessvcal.h> | 33 | #include <opie2/otodoaccessvcal.h> |
34 | #include <opie2/odebug.h> | 34 | #include <opie2/odebug.h> |
35 | 35 | ||
36 | #include <qpe/timeconversion.h> | 36 | #include <qpe/timeconversion.h> |
37 | 37 | ||
38 | /* QT */ | 38 | /* QT */ |
39 | //FIXME: Hack to allow direct access to FILE* fh. Rewrite this! | 39 | //FIXME: Hack to allow direct access to FILE* fh. Rewrite this! |
40 | #define protected public | 40 | #define protected public |
41 | #include <qfile.h> | 41 | #include <qfile.h> |
42 | #undef protected | 42 | #undef protected |
43 | 43 | ||
44 | using namespace Opie; | 44 | using namespace Opie; |
45 | 45 | ||
46 | namespace { | 46 | namespace { |
47 | static OPimTodo eventByVObj( VObject *obj ){ | 47 | static OPimTodo eventByVObj( VObject *obj ){ |
48 | OPimTodo event; | 48 | OPimTodo event; |
49 | VObject *ob; | 49 | VObject *ob; |
50 | QCString name; | 50 | QCString name; |
51 | // no uid, attendees, ... and no fun | 51 | // no uid, attendees, ... and no fun |
52 | // description | 52 | // description |
53 | if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){ | 53 | if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){ |
54 | name = vObjectStringZValue( ob ); | 54 | name = vObjectStringZValue( ob ); |
55 | #if 0 | 55 | #if 0 |
56 | event.setDescription( name ); | 56 | event.setDescription( name ); |
57 | #else | 57 | #else |
58 | event.setSummary( name ); | 58 | event.setSummary( name ); |
59 | #endif | 59 | #endif |
60 | } | 60 | } |
61 | // summary | 61 | // summary |
62 | if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) { | 62 | if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) { |
63 | name = vObjectStringZValue( ob ); | 63 | name = vObjectStringZValue( ob ); |
64 | #if 0 | 64 | #if 0 |
65 | event.setSummary( name ); | 65 | event.setSummary( name ); |
66 | #else | 66 | #else |
67 | event.setDescription( name ); | 67 | event.setDescription( name ); |
68 | #endif | 68 | #endif |
69 | } | 69 | } |
70 | // completed | 70 | // completed |
71 | if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){ | 71 | if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){ |
72 | name = vObjectStringZValue( ob ); | 72 | name = vObjectStringZValue( ob ); |
73 | if( name == "COMPLETED" ){ | 73 | if( name == "COMPLETED" ){ |
74 | event.setCompleted( true ); | 74 | event.setCompleted( true ); |
75 | }else{ | 75 | }else{ |
76 | event.setCompleted( false ); | 76 | event.setCompleted( false ); |
77 | } | 77 | } |
78 | }else | 78 | }else |
79 | event.setCompleted( false ); | 79 | event.setCompleted( false ); |
80 | // priority | 80 | // priority |
81 | if ((ob = isAPropertyOf(obj, VCPriorityProp))) { | 81 | if ((ob = isAPropertyOf(obj, VCPriorityProp))) { |
82 | name = vObjectStringZValue( ob ); | 82 | name = vObjectStringZValue( ob ); |
83 | bool ok; | 83 | bool ok; |
84 | event.setPriority(name.toInt(&ok) ); | 84 | event.setPriority(name.toInt(&ok) ); |
85 | } | 85 | } |
86 | //due date | 86 | //due date |
87 | if((ob = isAPropertyOf(obj, VCDueProp)) ){ | 87 | if((ob = isAPropertyOf(obj, VCDueProp)) ){ |
88 | event.setHasDueDate( true ); | 88 | event.setHasDueDate( true ); |
89 | name = vObjectStringZValue( ob ); | 89 | name = vObjectStringZValue( ob ); |
90 | event.setDueDate( TimeConversion::fromISO8601( name).date() ); | 90 | event.setDueDate( TimeConversion::fromISO8601( name).date() ); |
91 | } | 91 | } |
92 | // categories | 92 | // categories |
93 | if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){ | 93 | if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){ |
94 | name = vObjectStringZValue( ob ); | 94 | name = vObjectStringZValue( ob ); |
95 | owarn << "Categories:" << name.data() << "" << oendl; | ||
96 | } | 95 | } |
97 | 96 | ||
98 | event.setUid( 1 ); | 97 | event.setUid( 1 ); |
99 | return event; | 98 | return event; |
100 | }; | 99 | }; |
101 | static VObject *vobjByEvent( const OPimTodo &event ) { | 100 | static VObject *vobjByEvent( const OPimTodo &event ) { |
102 | VObject *task = newVObject( VCTodoProp ); | 101 | VObject *task = newVObject( VCTodoProp ); |
103 | if( task == 0 ) | 102 | if( task == 0 ) |
104 | return 0l; | 103 | return 0l; |
105 | 104 | ||
106 | if( event.hasDueDate() ) { | 105 | if( event.hasDueDate() ) { |
107 | QTime time(0, 0, 0); | 106 | QTime time(0, 0, 0); |
108 | QDateTime date(event.dueDate(), time ); | 107 | QDateTime date(event.dueDate(), time ); |
109 | addPropValue( task, VCDueProp, | 108 | addPropValue( task, VCDueProp, |
110 | TimeConversion::toISO8601( date ) ); | 109 | TimeConversion::toISO8601( date ) ); |
111 | } | 110 | } |
112 | 111 | ||
113 | if( event.isCompleted() ) | 112 | if( event.isCompleted() ) |
114 | addPropValue( task, VCStatusProp, "COMPLETED"); | 113 | addPropValue( task, VCStatusProp, "COMPLETED"); |
115 | 114 | ||
116 | QString string = QString::number(event.priority() ); | 115 | QString string = QString::number(event.priority() ); |
117 | addPropValue( task, VCPriorityProp, string.local8Bit() ); | 116 | addPropValue( task, VCPriorityProp, string.local8Bit() ); |
118 | 117 | ||
119 | addPropValue( task, VCCategoriesProp, | 118 | addPropValue( task, VCCategoriesProp, |
120 | event.idsToString( event.categories() ).local8Bit() ); | 119 | event.idsToString( event.categories() ).local8Bit() ); |
121 | 120 | ||
122 | #if 0 | 121 | #if 0 |
123 | 122 | ||
124 | // There seems a misrepresentation between summary in otodoevent | 123 | // There seems a misrepresentation between summary in otodoevent |
125 | // and summary in vcard. | 124 | // and summary in vcard. |
126 | // The same with description.. | 125 | // The same with description.. |
127 | // Description is summary and vice versa.. Argh.. (eilers) | 126 | // Description is summary and vice versa.. Argh.. (eilers) |
128 | 127 | ||
129 | 128 | ||
130 | addPropValue( task, VCDescriptionProp, | 129 | addPropValue( task, VCDescriptionProp, |
131 | event.description().local8Bit() ); | 130 | event.description().local8Bit() ); |
132 | 131 | ||
133 | addPropValue( task, VCSummaryProp, | 132 | addPropValue( task, VCSummaryProp, |
134 | event.summary().local8Bit() ); | 133 | event.summary().local8Bit() ); |
135 | 134 | ||
136 | #else | 135 | #else |
137 | addPropValue( task, VCDescriptionProp, | 136 | addPropValue( task, VCDescriptionProp, |
138 | event.summary().local8Bit() ); | 137 | event.summary().local8Bit() ); |
139 | 138 | ||
140 | addPropValue( task, VCSummaryProp, | 139 | addPropValue( task, VCSummaryProp, |
141 | event.description().local8Bit() ); | 140 | event.description().local8Bit() ); |
142 | #endif | 141 | #endif |
143 | return task; | 142 | return task; |
144 | }; | 143 | }; |
145 | } | 144 | } |
146 | 145 | ||
147 | namespace Opie { | 146 | namespace Opie { |
148 | OPimTodoAccessVCal::OPimTodoAccessVCal( const QString& path ) | 147 | OPimTodoAccessVCal::OPimTodoAccessVCal( const QString& path ) |
149 | : m_dirty(false), m_file( path ) | 148 | : m_dirty(false), m_file( path ) |
150 | { | 149 | { |
151 | } | 150 | } |
152 | OPimTodoAccessVCal::~OPimTodoAccessVCal() { | 151 | OPimTodoAccessVCal::~OPimTodoAccessVCal() { |
153 | } | 152 | } |
154 | bool OPimTodoAccessVCal::load() { | 153 | bool OPimTodoAccessVCal::load() { |
155 | m_map.clear(); | 154 | m_map.clear(); |
156 | m_dirty = false; | 155 | m_dirty = false; |
157 | 156 | ||
158 | VObject* vcal = 0l; | 157 | VObject* vcal = 0l; |
159 | vcal = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); | 158 | vcal = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); |
160 | if (!vcal ) | 159 | if (!vcal ) |
161 | return false; | 160 | return false; |
162 | 161 | ||
163 | // Iterate over the list | 162 | // Iterate over the list |
164 | VObjectIterator it; | 163 | VObjectIterator it; |
165 | VObject* vobj; | 164 | VObject* vobj; |
166 | 165 | ||
167 | initPropIterator(&it, vcal); | 166 | initPropIterator(&it, vcal); |
168 | 167 | ||
169 | while( moreIteration( &it ) ) { | 168 | while( moreIteration( &it ) ) { |
170 | vobj = ::nextVObject( &it ); | 169 | vobj = ::nextVObject( &it ); |
171 | QCString name = ::vObjectName( vobj ); | 170 | QCString name = ::vObjectName( vobj ); |
172 | if( name == VCTodoProp ){ | 171 | if( name == VCTodoProp ){ |
173 | OPimTodo to = eventByVObj( vobj ); | 172 | OPimTodo to = eventByVObj( vobj ); |
174 | m_map.insert( to.uid(), to ); | 173 | m_map.insert( to.uid(), to ); |
175 | } | 174 | } |
176 | } | 175 | } |
177 | 176 | ||
178 | // Should I do a delete vcal? | 177 | // Should I do a delete vcal? |
179 | 178 | ||
180 | return true; | 179 | return true; |
181 | } | 180 | } |
182 | bool OPimTodoAccessVCal::reload() { | 181 | bool OPimTodoAccessVCal::reload() { |
183 | return load(); | 182 | return load(); |
184 | } | 183 | } |
185 | bool OPimTodoAccessVCal::save() { | 184 | bool OPimTodoAccessVCal::save() { |
186 | if (!m_dirty ) | 185 | if (!m_dirty ) |
187 | return true; | 186 | return true; |
188 | 187 | ||
189 | QFile file( m_file ); | 188 | QFile file( m_file ); |
190 | if (!file.open(IO_WriteOnly ) ) | 189 | if (!file.open(IO_WriteOnly ) ) |
191 | return false; | 190 | return false; |
192 | 191 | ||
193 | VObject *obj; | 192 | VObject *obj; |
194 | obj = newVObject( VCCalProp ); | 193 | obj = newVObject( VCCalProp ); |
195 | addPropValue( obj, VCVersionProp, "1.0" ); | 194 | addPropValue( obj, VCVersionProp, "1.0" ); |
196 | VObject *vo; | 195 | VObject *vo; |
197 | for(QMap<int, OPimTodo>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ | 196 | for(QMap<int, OPimTodo>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ |
198 | vo = vobjByEvent( it.data() ); | 197 | vo = vobjByEvent( it.data() ); |
199 | addVObjectProp(obj, vo ); | 198 | addVObjectProp(obj, vo ); |
200 | } | 199 | } |
201 | writeVObject( file.fh, obj ); //FIXME: HACK!!! | 200 | writeVObject( file.fh, obj ); //FIXME: HACK!!! |
202 | cleanVObject( obj ); | 201 | cleanVObject( obj ); |
203 | cleanStrTbl(); | 202 | cleanStrTbl(); |
204 | 203 | ||
205 | m_dirty = false; | 204 | m_dirty = false; |
206 | return true; | 205 | return true; |
207 | } | 206 | } |
208 | void OPimTodoAccessVCal::clear() { | 207 | void OPimTodoAccessVCal::clear() { |
209 | m_map.clear(); | 208 | m_map.clear(); |
210 | m_dirty = true; | 209 | m_dirty = true; |
211 | } | 210 | } |
212 | bool OPimTodoAccessVCal::add( const OPimTodo& to ) { | 211 | bool OPimTodoAccessVCal::add( const OPimTodo& to ) { |
213 | m_map.insert( to.uid(), to ); | 212 | m_map.insert( to.uid(), to ); |
214 | m_dirty = true; | 213 | m_dirty = true; |
215 | return true; | 214 | return true; |
216 | } | 215 | } |
217 | bool OPimTodoAccessVCal::remove( int uid ) { | 216 | bool OPimTodoAccessVCal::remove( int uid ) { |
218 | m_map.remove( uid ); | 217 | m_map.remove( uid ); |
219 | m_dirty = true; | 218 | m_dirty = true; |
220 | return true; | 219 | return true; |
221 | } | 220 | } |
222 | void OPimTodoAccessVCal::removeAllCompleted() { | 221 | void OPimTodoAccessVCal::removeAllCompleted() { |
223 | for ( QMap<int, OPimTodo>::Iterator it = m_map.begin(); it != m_map.end(); ++it ) { | 222 | for ( QMap<int, OPimTodo>::Iterator it = m_map.begin(); it != m_map.end(); ++it ) { |
224 | if ( (*it).isCompleted() ) | 223 | if ( (*it).isCompleted() ) |
225 | m_map.remove( it ); | 224 | m_map.remove( it ); |
226 | } | 225 | } |
227 | } | 226 | } |
228 | bool OPimTodoAccessVCal::replace( const OPimTodo& to ) { | 227 | bool OPimTodoAccessVCal::replace( const OPimTodo& to ) { |
229 | m_map.replace( to.uid(), to ); | 228 | m_map.replace( to.uid(), to ); |
230 | m_dirty = true; | 229 | m_dirty = true; |
231 | return true; | 230 | return true; |
232 | } | 231 | } |
233 | OPimTodo OPimTodoAccessVCal::find(int uid )const { | 232 | OPimTodo OPimTodoAccessVCal::find(int uid )const { |
234 | return m_map[uid]; | 233 | return m_map[uid]; |
235 | } | 234 | } |
236 | QArray<int> OPimTodoAccessVCal::sorted( bool, int, int, int ) { | 235 | |
237 | QArray<int> ar(0); | ||
238 | return ar; | ||
239 | } | ||
240 | QArray<int> OPimTodoAccessVCal::allRecords()const { | 236 | QArray<int> OPimTodoAccessVCal::allRecords()const { |
241 | QArray<int> ar( m_map.count() ); | 237 | QArray<int> ar( m_map.count() ); |
242 | QMap<int, OPimTodo>::ConstIterator it; | 238 | QMap<int, OPimTodo>::ConstIterator it; |
243 | int i = 0; | 239 | int i = 0; |
244 | for ( it = m_map.begin(); it != m_map.end(); ++it ) { | 240 | for ( it = m_map.begin(); it != m_map.end(); ++it ) { |
245 | ar[i] = it.key(); | 241 | ar[i] = it.key(); |
246 | i++; | 242 | i++; |
247 | } | 243 | } |
248 | return ar; | 244 | return ar; |
249 | } | 245 | } |
250 | QArray<int> OPimTodoAccessVCal::matchRegexp(const QRegExp& /* r */)const { | 246 | |
251 | QArray<int> ar(0); | ||
252 | return ar; | ||
253 | } | ||
254 | QArray<int> OPimTodoAccessVCal::queryByExample( const OPimTodo&, int, const QDateTime& ) { | ||
255 | QArray<int> ar(0); | ||
256 | return ar; | ||
257 | } | ||
258 | QArray<int> OPimTodoAccessVCal::effectiveToDos( const QDate& , | 247 | QArray<int> OPimTodoAccessVCal::effectiveToDos( const QDate& , |
259 | const QDate& , | 248 | const QDate& , |
260 | bool ) { | 249 | bool )const { |
261 | QArray<int> ar(0); | ||
262 | return ar; | ||
263 | } | ||
264 | QArray<int> OPimTodoAccessVCal::overDue() { | ||
265 | QArray<int> ar(0); | 250 | QArray<int> ar(0); |
266 | return ar; | 251 | return ar; |
267 | } | 252 | } |
268 | QBitArray OPimTodoAccessVCal::supports()const { | ||
269 | static QBitArray ar = sup(); | ||
270 | |||
271 | return ar; | ||
272 | } | ||
273 | QBitArray OPimTodoAccessVCal::sup() { | ||
274 | QBitArray ar ( OPimTodo::CompletedDate +1 ); | ||
275 | ar.fill( true ); | ||
276 | |||
277 | ar[OPimTodo::CrossReference] = false; | ||
278 | ar[OPimTodo::State ] = false; | ||
279 | ar[OPimTodo::Reminders] = false; | ||
280 | ar[OPimTodo::Notifiers] = false; | ||
281 | ar[OPimTodo::Maintainer] = false; | ||
282 | ar[OPimTodo::Progress] = false; | ||
283 | ar[OPimTodo::Alarms ] = false; | ||
284 | ar[OPimTodo::Recurrence] = false; | ||
285 | 253 | ||
254 | QArray<int> OPimTodoAccessVCal::overDue()const { | ||
255 | QArray<int> ar(0); | ||
286 | return ar; | 256 | return ar; |
287 | } | 257 | } |
288 | 258 | ||
289 | } | 259 | } |
diff --git a/libopie2/opiepim/backend/otodoaccessvcal.h b/libopie2/opiepim/backend/otodoaccessvcal.h index 1e106d3..05dd76b 100644 --- a/libopie2/opiepim/backend/otodoaccessvcal.h +++ b/libopie2/opiepim/backend/otodoaccessvcal.h | |||
@@ -1,72 +1,66 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | #ifndef OPIE_OTODO_ACCESS_VCAL_H | 29 | #ifndef OPIE_OTODO_ACCESS_VCAL_H |
30 | #define OPIE_OTODO_ACCESS_VCAL_H | 30 | #define OPIE_OTODO_ACCESS_VCAL_H |
31 | 31 | ||
32 | #include <opie2/otodoaccessbackend.h> | 32 | #include <opie2/otodoaccessbackend.h> |
33 | 33 | ||
34 | namespace Opie { | 34 | namespace Opie { |
35 | 35 | ||
36 | class OPimTodoAccessVCal : public OPimTodoAccessBackend { | 36 | class OPimTodoAccessVCal : public OPimTodoAccessBackend { |
37 | public: | 37 | public: |
38 | OPimTodoAccessVCal(const QString& ); | 38 | OPimTodoAccessVCal(const QString& ); |
39 | ~OPimTodoAccessVCal(); | 39 | ~OPimTodoAccessVCal(); |
40 | 40 | ||
41 | bool load(); | 41 | bool load(); |
42 | bool reload(); | 42 | bool reload(); |
43 | bool save(); | 43 | bool save(); |
44 | 44 | ||
45 | QArray<int> allRecords()const; | 45 | QArray<int> allRecords()const; |
46 | QArray<int> matchRegexp(const QRegExp &r) const; | ||
47 | QArray<int> queryByExample( const OPimTodo& t, int sort, const QDateTime& d = QDateTime() ); | ||
48 | QArray<int> effectiveToDos( const QDate& start, | 46 | QArray<int> effectiveToDos( const QDate& start, |
49 | const QDate& end, | 47 | const QDate& end, |
50 | bool includeNoDates ); | 48 | bool includeNoDates )const; |
51 | QArray<int> overDue(); | 49 | QArray<int> overDue()const; |
52 | QArray<int> sorted( bool asc, int sortOrder, int sortFilter, | ||
53 | int cat ); | ||
54 | OPimTodo find(int uid)const; | 50 | OPimTodo find(int uid)const; |
55 | void clear(); | 51 | void clear(); |
56 | bool add( const OPimTodo& ); | 52 | bool add( const OPimTodo& ); |
57 | bool remove( int uid ); | 53 | bool remove( int uid ); |
58 | bool replace( const OPimTodo& ); | 54 | bool replace( const OPimTodo& ); |
59 | 55 | ||
60 | void removeAllCompleted(); | 56 | void removeAllCompleted(); |
61 | virtual QBitArray supports()const; | ||
62 | 57 | ||
63 | private: | 58 | private: |
64 | static QBitArray sup(); | ||
65 | bool m_dirty : 1; | 59 | bool m_dirty : 1; |
66 | QString m_file; | 60 | QString m_file; |
67 | QMap<int, OPimTodo> m_map; | 61 | QMap<int, OPimTodo> m_map; |
68 | }; | 62 | }; |
69 | 63 | ||
70 | } | 64 | } |
71 | 65 | ||
72 | #endif | 66 | #endif |
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp index 3e06d88..273f91a 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.cpp +++ b/libopie2/opiepim/backend/otodoaccessxml.cpp | |||
@@ -1,914 +1,720 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | /* OPIE */ | 30 | /* OPIE */ |
31 | #include <opie2/opimdateconversion.h> | 31 | #include <opie2/opimdateconversion.h> |
32 | #include <opie2/opimstate.h> | 32 | #include <opie2/opimstate.h> |
33 | #include <opie2/opimtimezone.h> | 33 | #include <opie2/opimtimezone.h> |
34 | #include <opie2/opimnotifymanager.h> | 34 | #include <opie2/opimnotifymanager.h> |
35 | #include <opie2/opimrecurrence.h> | 35 | #include <opie2/opimrecurrence.h> |
36 | #include <opie2/otodoaccessxml.h> | 36 | #include <opie2/otodoaccessxml.h> |
37 | #include <opie2/otodoaccess.h> | ||
37 | #include <opie2/odebug.h> | 38 | #include <opie2/odebug.h> |
38 | 39 | ||
40 | #include <opie2/private/opimtodosortvector.h> | ||
41 | |||
39 | #include <qpe/global.h> | 42 | #include <qpe/global.h> |
40 | #include <qpe/stringutil.h> | 43 | #include <qpe/stringutil.h> |
41 | #include <qpe/timeconversion.h> | 44 | #include <qpe/timeconversion.h> |
42 | 45 | ||
43 | /* QT */ | 46 | /* QT */ |
44 | #include <qfile.h> | 47 | #include <qfile.h> |
45 | #include <qvector.h> | 48 | #include <qvector.h> |
46 | 49 | ||
47 | /* STD */ | 50 | /* STD */ |
48 | #include <errno.h> | 51 | #include <errno.h> |
49 | #include <fcntl.h> | 52 | #include <fcntl.h> |
50 | 53 | ||
51 | #include <sys/mman.h> | 54 | #include <sys/mman.h> |
52 | #include <sys/stat.h> | 55 | #include <sys/stat.h> |
53 | #include <sys/types.h> | 56 | #include <sys/types.h> |
54 | 57 | ||
55 | #include <unistd.h> | 58 | #include <unistd.h> |
56 | 59 | ||
57 | 60 | ||
58 | using namespace Opie; | 61 | using namespace Opie; |
59 | 62 | ||
60 | namespace { | 63 | namespace { |
61 | time_t rp_end; | 64 | time_t rp_end; |
62 | OPimRecurrence* rec; | 65 | OPimRecurrence* rec; |
63 | OPimRecurrence *recur() { | 66 | OPimRecurrence *recur() { |
64 | if (!rec ) rec = new OPimRecurrence; | 67 | if (!rec ) rec = new OPimRecurrence; |
65 | return rec; | 68 | return rec; |
66 | } | 69 | } |
67 | int snd; | 70 | int snd; |
68 | enum MoreAttributes { | 71 | enum MoreAttributes { |
69 | FRType = OPimTodo::CompletedDate + 2, | 72 | FRType = OPimTodo::CompletedDate + 2, |
70 | FRWeekdays, | 73 | FRWeekdays, |
71 | FRPosition, | 74 | FRPosition, |
72 | FRFreq, | 75 | FRFreq, |
73 | FRHasEndDate, | 76 | FRHasEndDate, |
74 | FREndDate, | 77 | FREndDate, |
75 | FRStart, | 78 | FRStart, |
76 | FREnd | 79 | FREnd |
77 | }; | 80 | }; |
78 | // FROM TT again | 81 | // FROM TT again |
79 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) | 82 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) |
80 | { | 83 | { |
81 | char needleChar; | 84 | char needleChar; |
82 | char haystackChar; | 85 | char haystackChar; |
83 | if (!needle || !haystack || !hLen || !nLen) | 86 | if (!needle || !haystack || !hLen || !nLen) |
84 | return 0; | 87 | return 0; |
85 | 88 | ||
86 | const char* hsearch = haystack; | 89 | const char* hsearch = haystack; |
87 | 90 | ||
88 | if ((needleChar = *needle++) != 0) { | 91 | if ((needleChar = *needle++) != 0) { |
89 | nLen--; //(to make up for needle++) | 92 | nLen--; //(to make up for needle++) |
90 | do { | 93 | do { |
91 | do { | 94 | do { |
92 | if ((haystackChar = *hsearch++) == 0) | 95 | if ((haystackChar = *hsearch++) == 0) |
93 | return (0); | 96 | return (0); |
94 | if (hsearch >= haystack + hLen) | 97 | if (hsearch >= haystack + hLen) |
95 | return (0); | 98 | return (0); |
96 | } while (haystackChar != needleChar); | 99 | } while (haystackChar != needleChar); |
97 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); | 100 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); |
98 | hsearch--; | 101 | hsearch--; |
99 | } | 102 | } |
100 | return ((char *)hsearch); | 103 | return ((char *)hsearch); |
101 | } | 104 | } |
102 | } | 105 | } |
103 | 106 | ||
104 | namespace Opie { | 107 | namespace Opie { |
105 | 108 | ||
106 | OPimTodoAccessXML::OPimTodoAccessXML( const QString& appName, | 109 | OPimTodoAccessXML::OPimTodoAccessXML( const QString& appName, |
107 | const QString& fileName ) | 110 | const QString& fileName ) |
108 | : OPimTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) | 111 | : OPimTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) |
109 | { | 112 | { |
110 | if (!fileName.isEmpty() ) | 113 | if (!fileName.isEmpty() ) |
111 | m_file = fileName; | 114 | m_file = fileName; |
112 | else | 115 | else |
113 | m_file = Global::applicationFileName( "todolist", "todolist.xml" ); | 116 | m_file = Global::applicationFileName( "todolist", "todolist.xml" ); |
114 | } | 117 | } |
115 | OPimTodoAccessXML::~OPimTodoAccessXML() { | 118 | OPimTodoAccessXML::~OPimTodoAccessXML() { |
116 | 119 | ||
117 | } | 120 | } |
118 | bool OPimTodoAccessXML::load() { | 121 | bool OPimTodoAccessXML::load() { |
119 | rec = 0; | 122 | rec = 0; |
120 | m_opened = true; | 123 | m_opened = true; |
121 | m_changed = false; | 124 | m_changed = false; |
122 | /* initialize dict */ | 125 | /* initialize dict */ |
123 | /* | 126 | /* |
124 | * UPDATE dict if you change anything!!! | 127 | * UPDATE dict if you change anything!!! |
125 | */ | 128 | */ |
126 | QAsciiDict<int> dict(26); | 129 | QAsciiDict<int> dict(26); |
127 | dict.setAutoDelete( TRUE ); | 130 | dict.setAutoDelete( TRUE ); |
128 | dict.insert("Categories" , new int(OPimTodo::Category) ); | 131 | dict.insert("Categories" , new int(OPimTodo::Category) ); |
129 | dict.insert("Uid" , new int(OPimTodo::Uid) ); | 132 | dict.insert("Uid" , new int(OPimTodo::Uid) ); |
130 | dict.insert("HasDate" , new int(OPimTodo::HasDate) ); | 133 | dict.insert("HasDate" , new int(OPimTodo::HasDate) ); |
131 | dict.insert("Completed" , new int(OPimTodo::Completed) ); | 134 | dict.insert("Completed" , new int(OPimTodo::Completed) ); |
132 | dict.insert("Description" , new int(OPimTodo::Description) ); | 135 | dict.insert("Description" , new int(OPimTodo::Description) ); |
133 | dict.insert("Summary" , new int(OPimTodo::Summary) ); | 136 | dict.insert("Summary" , new int(OPimTodo::Summary) ); |
134 | dict.insert("Priority" , new int(OPimTodo::Priority) ); | 137 | dict.insert("Priority" , new int(OPimTodo::Priority) ); |
135 | dict.insert("DateDay" , new int(OPimTodo::DateDay) ); | 138 | dict.insert("DateDay" , new int(OPimTodo::DateDay) ); |
136 | dict.insert("DateMonth" , new int(OPimTodo::DateMonth) ); | 139 | dict.insert("DateMonth" , new int(OPimTodo::DateMonth) ); |
137 | dict.insert("DateYear" , new int(OPimTodo::DateYear) ); | 140 | dict.insert("DateYear" , new int(OPimTodo::DateYear) ); |
138 | dict.insert("Progress" , new int(OPimTodo::Progress) ); | 141 | dict.insert("Progress" , new int(OPimTodo::Progress) ); |
139 | dict.insert("CompletedDate", new int(OPimTodo::CompletedDate) ); | 142 | dict.insert("CompletedDate", new int(OPimTodo::CompletedDate) ); |
140 | dict.insert("StartDate", new int(OPimTodo::StartDate) ); | 143 | dict.insert("StartDate", new int(OPimTodo::StartDate) ); |
141 | dict.insert("CrossReference", new int(OPimTodo::CrossReference) ); | 144 | dict.insert("CrossReference", new int(OPimTodo::CrossReference) ); |
142 | dict.insert("State", new int(OPimTodo::State) ); | 145 | dict.insert("State", new int(OPimTodo::State) ); |
143 | dict.insert("Alarms", new int(OPimTodo::Alarms) ); | 146 | dict.insert("Alarms", new int(OPimTodo::Alarms) ); |
144 | dict.insert("Reminders", new int(OPimTodo::Reminders) ); | 147 | dict.insert("Reminders", new int(OPimTodo::Reminders) ); |
145 | dict.insert("Notifiers", new int(OPimTodo::Notifiers) ); | ||
146 | dict.insert("Maintainer", new int(OPimTodo::Maintainer) ); | 148 | dict.insert("Maintainer", new int(OPimTodo::Maintainer) ); |
147 | dict.insert("rtype", new int(FRType) ); | 149 | dict.insert("rtype", new int(FRType) ); |
148 | dict.insert("rweekdays", new int(FRWeekdays) ); | 150 | dict.insert("rweekdays", new int(FRWeekdays) ); |
149 | dict.insert("rposition", new int(FRPosition) ); | 151 | dict.insert("rposition", new int(FRPosition) ); |
150 | dict.insert("rfreq", new int(FRFreq) ); | 152 | dict.insert("rfreq", new int(FRFreq) ); |
151 | dict.insert("start", new int(FRStart) ); | 153 | dict.insert("start", new int(FRStart) ); |
152 | dict.insert("rhasenddate", new int(FRHasEndDate) ); | 154 | dict.insert("rhasenddate", new int(FRHasEndDate) ); |
153 | dict.insert("enddt", new int(FREndDate) ); | 155 | dict.insert("enddt", new int(FREndDate) ); |
154 | 156 | ||
155 | // here the custom XML parser from TT it's GPL | 157 | // here the custom XML parser from TT it's GPL |
156 | // but we want to push OpiePIM... to TT..... | 158 | // but we want to push OpiePIM... to TT..... |
157 | // mmap part from zecke :) | 159 | // mmap part from zecke :) |
158 | int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); | 160 | int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); |
159 | struct stat attribut; | 161 | struct stat attribut; |
160 | if ( fd < 0 ) return false; | 162 | if ( fd < 0 ) return false; |
161 | 163 | ||
162 | if ( fstat(fd, &attribut ) == -1 ) { | 164 | if ( fstat(fd, &attribut ) == -1 ) { |
163 | ::close( fd ); | 165 | ::close( fd ); |
164 | return false; | 166 | return false; |
165 | } | 167 | } |
166 | void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 168 | void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
167 | if ( map_addr == ( (caddr_t)-1) ) { | 169 | if ( map_addr == ( (caddr_t)-1) ) { |
168 | ::close(fd ); | 170 | ::close(fd ); |
169 | return false; | 171 | return false; |
170 | } | 172 | } |
171 | /* advise the kernel who we want to read it */ | 173 | /* advise the kernel who we want to read it */ |
172 | ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); | 174 | ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); |
173 | /* we do not the file any more */ | 175 | /* we do not the file any more */ |
174 | ::close( fd ); | 176 | ::close( fd ); |
175 | 177 | ||
176 | char* dt = (char*)map_addr; | 178 | char* dt = (char*)map_addr; |
177 | int len = attribut.st_size; | 179 | int len = attribut.st_size; |
178 | int i = 0; | 180 | int i = 0; |
179 | char *point; | 181 | char *point; |
180 | const char* collectionString = "<Task "; | 182 | const char* collectionString = "<Task "; |
181 | int strLen = strlen(collectionString); | 183 | int strLen = strlen(collectionString); |
182 | while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { | 184 | while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { |
183 | i = point -dt; | 185 | i = point -dt; |
184 | i+= strLen; | 186 | i+= strLen; |
185 | owarn << "Found a start at " << i << " " << (point-dt) << "" << oendl; | ||
186 | 187 | ||
187 | OPimTodo ev; | 188 | OPimTodo ev; |
188 | m_year = m_month = m_day = 0; | 189 | m_year = m_month = m_day = 0; |
189 | 190 | ||
190 | while ( TRUE ) { | 191 | while ( TRUE ) { |
191 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 192 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
192 | ++i; | 193 | ++i; |
193 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 194 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
194 | break; | 195 | break; |
195 | 196 | ||
196 | // we have another attribute, read it. | 197 | // we have another attribute, read it. |
197 | int j = i; | 198 | int j = i; |
198 | while ( j < len && dt[j] != '=' ) | 199 | while ( j < len && dt[j] != '=' ) |
199 | ++j; | 200 | ++j; |
200 | QCString attr( dt+i, j-i+1); | 201 | QCString attr( dt+i, j-i+1); |
201 | 202 | ||
202 | i = ++j; // skip = | 203 | i = ++j; // skip = |
203 | 204 | ||
204 | // find the start of quotes | 205 | // find the start of quotes |
205 | while ( i < len && dt[i] != '"' ) | 206 | while ( i < len && dt[i] != '"' ) |
206 | ++i; | 207 | ++i; |
207 | j = ++i; | 208 | j = ++i; |
208 | 209 | ||
209 | bool haveUtf = FALSE; | 210 | bool haveUtf = FALSE; |
210 | bool haveEnt = FALSE; | 211 | bool haveEnt = FALSE; |
211 | while ( j < len && dt[j] != '"' ) { | 212 | while ( j < len && dt[j] != '"' ) { |
212 | if ( ((unsigned char)dt[j]) > 0x7f ) | 213 | if ( ((unsigned char)dt[j]) > 0x7f ) |
213 | haveUtf = TRUE; | 214 | haveUtf = TRUE; |
214 | if ( dt[j] == '&' ) | 215 | if ( dt[j] == '&' ) |
215 | haveEnt = TRUE; | 216 | haveEnt = TRUE; |
216 | ++j; | 217 | ++j; |
217 | } | 218 | } |
218 | if ( i == j ) { | 219 | if ( i == j ) { |
219 | // empty value | 220 | // empty value |
220 | i = j + 1; | 221 | i = j + 1; |
221 | continue; | 222 | continue; |
222 | } | 223 | } |
223 | 224 | ||
224 | QCString value( dt+i, j-i+1 ); | 225 | QCString value( dt+i, j-i+1 ); |
225 | i = j + 1; | 226 | i = j + 1; |
226 | 227 | ||
227 | QString str = (haveUtf ? QString::fromUtf8( value ) | 228 | QString str = (haveUtf ? QString::fromUtf8( value ) |
228 | : QString::fromLatin1( value ) ); | 229 | : QString::fromLatin1( value ) ); |
229 | if ( haveEnt ) | 230 | if ( haveEnt ) |
230 | str = Qtopia::plainString( str ); | 231 | str = Qtopia::plainString( str ); |
231 | 232 | ||
232 | /* | 233 | /* |
233 | * add key + value | 234 | * add key + value |
234 | */ | 235 | */ |
235 | todo( &dict, ev, attr, str ); | 236 | todo( &dict, ev, attr, str ); |
236 | 237 | ||
237 | } | 238 | } |
238 | /* | 239 | /* |
239 | * now add it | 240 | * now add it |
240 | */ | 241 | */ |
241 | owarn << "End at " << i << "" << oendl; | ||
242 | if (m_events.contains( ev.uid() ) || ev.uid() == 0) { | 242 | if (m_events.contains( ev.uid() ) || ev.uid() == 0) { |
243 | ev.setUid( 1 ); | 243 | ev.setUid( 1 ); |
244 | m_changed = true; | 244 | m_changed = true; |
245 | } | 245 | } |
246 | if ( ev.hasDueDate() ) { | 246 | if ( ev.hasDueDate() ) { |
247 | ev.setDueDate( QDate(m_year, m_month, m_day) ); | 247 | ev.setDueDate( QDate(m_year, m_month, m_day) ); |
248 | } | 248 | } |
249 | if ( rec && rec->doesRecur() ) { | 249 | if ( rec && rec->doesRecur() ) { |
250 | OPimTimeZone utc = OPimTimeZone::utc(); | 250 | OPimTimeZone utc = OPimTimeZone::utc(); |
251 | OPimRecurrence recu( *rec ); // call copy c'tor | 251 | OPimRecurrence recu( *rec ); // call copy c'tor |
252 | recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() ); | 252 | recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() ); |
253 | recu.setStart( ev.dueDate() ); | 253 | recu.setStart( ev.dueDate() ); |
254 | ev.setRecurrence( recu ); | 254 | ev.setRecurrence( recu ); |
255 | } | 255 | } |
256 | m_events.insert(ev.uid(), ev ); | 256 | m_events.insert(ev.uid(), ev ); |
257 | m_year = m_month = m_day = -1; | 257 | m_year = m_month = m_day = -1; |
258 | delete rec; | 258 | delete rec; |
259 | rec = 0; | 259 | rec = 0; |
260 | } | 260 | } |
261 | 261 | ||
262 | munmap(map_addr, attribut.st_size ); | 262 | munmap(map_addr, attribut.st_size ); |
263 | 263 | ||
264 | owarn << "counts " << m_events.count() << " records loaded!" << oendl; | ||
265 | return true; | 264 | return true; |
266 | } | 265 | } |
267 | bool OPimTodoAccessXML::reload() { | 266 | bool OPimTodoAccessXML::reload() { |
268 | m_events.clear(); | 267 | m_events.clear(); |
269 | return load(); | 268 | return load(); |
270 | } | 269 | } |
271 | bool OPimTodoAccessXML::save() { | 270 | bool OPimTodoAccessXML::save() { |
272 | // owarn << "saving" << oendl; | ||
273 | if (!m_opened || !m_changed ) { | 271 | if (!m_opened || !m_changed ) { |
274 | // owarn << "not saving" << oendl; | ||
275 | return true; | 272 | return true; |
276 | } | 273 | } |
277 | QString strNewFile = m_file + ".new"; | 274 | QString strNewFile = m_file + ".new"; |
278 | QFile f( strNewFile ); | 275 | QFile f( strNewFile ); |
279 | if (!f.open( IO_WriteOnly|IO_Raw ) ) | 276 | if (!f.open( IO_WriteOnly|IO_Raw ) ) |
280 | return false; | 277 | return false; |
281 | 278 | ||
282 | int written; | 279 | int written; |
283 | QString out; | 280 | QString out; |
284 | out = "<!DOCTYPE Tasks>\n<Tasks>\n"; | 281 | out = "<!DOCTYPE Tasks>\n<Tasks>\n"; |
285 | 282 | ||
286 | // for all todos | 283 | // for all todos |
287 | QMap<int, OPimTodo>::Iterator it; | 284 | QMap<int, OPimTodo>::Iterator it; |
288 | for (it = m_events.begin(); it != m_events.end(); ++it ) { | 285 | for (it = m_events.begin(); it != m_events.end(); ++it ) { |
289 | out+= "<Task " + toString( (*it) ) + " />\n"; | 286 | out+= "<Task " + toString( (*it) ) + " />\n"; |
290 | QCString cstr = out.utf8(); | 287 | QCString cstr = out.utf8(); |
291 | written = f.writeBlock( cstr.data(), cstr.length() ); | 288 | written = f.writeBlock( cstr.data(), cstr.length() ); |
292 | 289 | ||
293 | /* less written then we wanted */ | 290 | /* less written then we wanted */ |
294 | if ( written != (int)cstr.length() ) { | 291 | if ( written != (int)cstr.length() ) { |
295 | f.close(); | 292 | f.close(); |
296 | QFile::remove( strNewFile ); | 293 | QFile::remove( strNewFile ); |
297 | return false; | 294 | return false; |
298 | } | 295 | } |
299 | out = QString::null; | 296 | out = QString::null; |
300 | } | 297 | } |
301 | 298 | ||
302 | out += "</Tasks>"; | 299 | out += "</Tasks>"; |
303 | QCString cstr = out.utf8(); | 300 | QCString cstr = out.utf8(); |
304 | written = f.writeBlock( cstr.data(), cstr.length() ); | 301 | written = f.writeBlock( cstr.data(), cstr.length() ); |
305 | 302 | ||
306 | if ( written != (int)cstr.length() ) { | 303 | if ( written != (int)cstr.length() ) { |
307 | f.close(); | 304 | f.close(); |
308 | QFile::remove( strNewFile ); | 305 | QFile::remove( strNewFile ); |
309 | return false; | 306 | return false; |
310 | } | 307 | } |
311 | /* flush before renaming */ | 308 | /* flush before renaming */ |
312 | f.close(); | 309 | f.close(); |
313 | 310 | ||
314 | if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { | 311 | if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { |
315 | // owarn << "error renaming" << oendl; | ||
316 | QFile::remove( strNewFile ); | 312 | QFile::remove( strNewFile ); |
317 | } | 313 | } |
318 | 314 | ||
319 | m_changed = false; | 315 | m_changed = false; |
320 | return true; | 316 | return true; |
321 | } | 317 | } |
322 | QArray<int> OPimTodoAccessXML::allRecords()const { | 318 | QArray<int> OPimTodoAccessXML::allRecords()const { |
323 | QArray<int> ids( m_events.count() ); | 319 | QArray<int> ids( m_events.count() ); |
324 | QMap<int, OPimTodo>::ConstIterator it; | 320 | QMap<int, OPimTodo>::ConstIterator it; |
325 | int i = 0; | 321 | int i = 0; |
326 | 322 | ||
327 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | 323 | for ( it = m_events.begin(); it != m_events.end(); ++it ) |
328 | ids[i] = it.key(); | 324 | ids[i++] = it.key(); |
329 | i++; | 325 | |
330 | } | 326 | |
331 | return ids; | 327 | return ids; |
332 | } | 328 | } |
333 | QArray<int> OPimTodoAccessXML::queryByExample( const OPimTodo&, int, const QDateTime& ) { | 329 | QArray<int> OPimTodoAccessXML::queryByExample( const OPimTodo&, int, const QDateTime& ) { |
334 | QArray<int> ids(0); | 330 | QArray<int> ids(0); |
335 | return ids; | 331 | return ids; |
336 | } | 332 | } |
337 | OPimTodo OPimTodoAccessXML::find( int uid )const { | 333 | OPimTodo OPimTodoAccessXML::find( int uid )const { |
338 | OPimTodo todo; | 334 | OPimTodo todo; |
339 | todo.setUid( 0 ); // isEmpty() | 335 | todo.setUid( 0 ); // isEmpty() |
340 | QMap<int, OPimTodo>::ConstIterator it = m_events.find( uid ); | 336 | QMap<int, OPimTodo>::ConstIterator it = m_events.find( uid ); |
341 | if ( it != m_events.end() ) | 337 | if ( it != m_events.end() ) |
342 | todo = it.data(); | 338 | todo = it.data(); |
343 | 339 | ||
344 | return todo; | 340 | return todo; |
345 | } | 341 | } |
346 | void OPimTodoAccessXML::clear() { | 342 | void OPimTodoAccessXML::clear() { |
347 | if (m_opened ) | 343 | if (m_opened ) |
348 | m_changed = true; | 344 | m_changed = true; |
349 | 345 | ||
350 | m_events.clear(); | 346 | m_events.clear(); |
351 | } | 347 | } |
352 | bool OPimTodoAccessXML::add( const OPimTodo& todo ) { | 348 | bool OPimTodoAccessXML::add( const OPimTodo& todo ) { |
353 | // owarn << "add" << oendl; | ||
354 | m_changed = true; | 349 | m_changed = true; |
355 | m_events.insert( todo.uid(), todo ); | 350 | m_events.insert( todo.uid(), todo ); |
356 | 351 | ||
357 | return true; | 352 | return true; |
358 | } | 353 | } |
359 | bool OPimTodoAccessXML::remove( int uid ) { | 354 | bool OPimTodoAccessXML::remove( int uid ) { |
360 | m_changed = true; | 355 | m_changed = true; |
361 | m_events.remove( uid ); | 356 | m_events.remove( uid ); |
362 | 357 | ||
363 | return true; | 358 | return true; |
364 | } | 359 | } |
365 | bool OPimTodoAccessXML::replace( const OPimTodo& todo) { | 360 | bool OPimTodoAccessXML::replace( const OPimTodo& todo) { |
366 | m_changed = true; | 361 | m_changed = true; |
367 | m_events.replace( todo.uid(), todo ); | 362 | m_events.replace( todo.uid(), todo ); |
368 | 363 | ||
369 | return true; | 364 | return true; |
370 | } | 365 | } |
371 | QArray<int> OPimTodoAccessXML::effectiveToDos( const QDate& start, | 366 | QArray<int> OPimTodoAccessXML::effectiveToDos( const QDate& start, |
372 | const QDate& end, | 367 | const QDate& end, |
373 | bool includeNoDates ) { | 368 | bool includeNoDates )const { |
374 | QArray<int> ids( m_events.count() ); | 369 | QArray<int> ids( m_events.count() ); |
375 | QMap<int, OPimTodo>::Iterator it; | 370 | QMap<int, OPimTodo>::ConstIterator it; |
376 | 371 | ||
377 | int i = 0; | 372 | int i = 0; |
378 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | 373 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { |
379 | if ( !it.data().hasDueDate() ) { | 374 | if ( !it.data().hasDueDate() && includeNoDates) { |
380 | if ( includeNoDates ) { | 375 | ids[i++] = it.key(); |
381 | ids[i] = it.key(); | ||
382 | i++; | ||
383 | } | ||
384 | }else if ( it.data().dueDate() >= start && | 376 | }else if ( it.data().dueDate() >= start && |
385 | it.data().dueDate() <= end ) { | 377 | it.data().dueDate() <= end ) { |
386 | ids[i] = it.key(); | 378 | ids[i++] = it.key(); |
387 | i++; | ||
388 | } | 379 | } |
389 | } | 380 | } |
390 | ids.resize( i ); | 381 | ids.resize( i ); |
391 | return ids; | 382 | return ids; |
392 | } | 383 | } |
393 | QArray<int> OPimTodoAccessXML::overDue() { | 384 | QArray<int> OPimTodoAccessXML::overDue()const { |
394 | QArray<int> ids( m_events.count() ); | 385 | QArray<int> ids( m_events.count() ); |
395 | int i = 0; | 386 | int i = 0; |
396 | 387 | ||
397 | QMap<int, OPimTodo>::Iterator it; | 388 | QMap<int, OPimTodo>::ConstIterator it; |
398 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | 389 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { |
399 | if ( it.data().isOverdue() ) { | 390 | if ( it.data().isOverdue() ) { |
400 | ids[i] = it.key(); | 391 | ids[i] = it.key(); |
401 | i++; | 392 | i++; |
402 | } | 393 | } |
403 | } | 394 | } |
404 | ids.resize( i ); | 395 | ids.resize( i ); |
405 | return ids; | 396 | return ids; |
406 | } | 397 | } |
407 | 398 | ||
408 | 399 | ||
409 | /* private */ | 400 | /* private */ |
410 | void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev, | 401 | void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev, |
411 | const QCString& attr, const QString& val) { | 402 | const QCString& attr, const QString& val) { |
412 | // owarn << "parse to do from XMLElement" << oendl; | ||
413 | 403 | ||
414 | int *find=0; | 404 | int *find=0; |
415 | 405 | ||
416 | find = (*dict)[ attr.data() ]; | 406 | find = (*dict)[ attr.data() ]; |
417 | if (!find ) { | 407 | if (!find ) { |
418 | // owarn << "Unknown option" + it.key() << oendl; | ||
419 | ev.setCustomField( attr, val ); | 408 | ev.setCustomField( attr, val ); |
420 | return; | 409 | return; |
421 | } | 410 | } |
422 | 411 | ||
423 | switch( *find ) { | 412 | switch( *find ) { |
424 | case OPimTodo::Uid: | 413 | case OPimTodo::Uid: |
425 | ev.setUid( val.toInt() ); | 414 | ev.setUid( val.toInt() ); |
426 | break; | 415 | break; |
427 | case OPimTodo::Category: | 416 | case OPimTodo::Category: |
428 | ev.setCategories( ev.idsFromString( val ) ); | 417 | ev.setCategories( ev.idsFromString( val ) ); |
429 | break; | 418 | break; |
430 | case OPimTodo::HasDate: | 419 | case OPimTodo::HasDate: |
431 | ev.setHasDueDate( val.toInt() ); | 420 | ev.setHasDueDate( val.toInt() ); |
432 | break; | 421 | break; |
433 | case OPimTodo::Completed: | 422 | case OPimTodo::Completed: |
434 | ev.setCompleted( val.toInt() ); | 423 | ev.setCompleted( val.toInt() ); |
435 | break; | 424 | break; |
436 | case OPimTodo::Description: | 425 | case OPimTodo::Description: |
437 | ev.setDescription( val ); | 426 | ev.setDescription( val ); |
438 | break; | 427 | break; |
439 | case OPimTodo::Summary: | 428 | case OPimTodo::Summary: |
440 | ev.setSummary( val ); | 429 | ev.setSummary( val ); |
441 | break; | 430 | break; |
442 | case OPimTodo::Priority: | 431 | case OPimTodo::Priority: |
443 | ev.setPriority( val.toInt() ); | 432 | ev.setPriority( val.toInt() ); |
444 | break; | 433 | break; |
445 | case OPimTodo::DateDay: | 434 | case OPimTodo::DateDay: |
446 | m_day = val.toInt(); | 435 | m_day = val.toInt(); |
447 | break; | 436 | break; |
448 | case OPimTodo::DateMonth: | 437 | case OPimTodo::DateMonth: |
449 | m_month = val.toInt(); | 438 | m_month = val.toInt(); |
450 | break; | 439 | break; |
451 | case OPimTodo::DateYear: | 440 | case OPimTodo::DateYear: |
452 | m_year = val.toInt(); | 441 | m_year = val.toInt(); |
453 | break; | 442 | break; |
454 | case OPimTodo::Progress: | 443 | case OPimTodo::Progress: |
455 | ev.setProgress( val.toInt() ); | 444 | ev.setProgress( val.toInt() ); |
456 | break; | 445 | break; |
457 | case OPimTodo::CompletedDate: | 446 | case OPimTodo::CompletedDate: |
458 | ev.setCompletedDate( OPimDateConversion::dateFromString( val ) ); | 447 | ev.setCompletedDate( OPimDateConversion::dateFromString( val ) ); |
459 | break; | 448 | break; |
460 | case OPimTodo::StartDate: | 449 | case OPimTodo::StartDate: |
461 | ev.setStartDate( OPimDateConversion::dateFromString( val ) ); | 450 | ev.setStartDate( OPimDateConversion::dateFromString( val ) ); |
462 | break; | 451 | break; |
463 | case OPimTodo::State: | 452 | case OPimTodo::State: |
464 | ev.setState( val.toInt() ); | 453 | ev.setState( val.toInt() ); |
465 | break; | 454 | break; |
466 | case OPimTodo::Alarms:{ | 455 | case OPimTodo::Alarms:{ |
467 | OPimNotifyManager &manager = ev.notifiers(); | 456 | OPimNotifyManager &manager = ev.notifiers(); |
468 | QStringList als = QStringList::split(";", val ); | 457 | QStringList als = QStringList::split(";", val ); |
469 | for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) { | 458 | for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) { |
470 | QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty | 459 | QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty |
471 | owarn << "alarm: " << alarm.join("___") << "" << oendl; | ||
472 | owarn << "alarm[0]: " << alarm[0] << " " << OPimDateConversion::dateTimeFromString( alarm[0] ).toString() << "" << oendl; | ||
473 | OPimAlarm al( alarm[2].toInt(), OPimDateConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() ); | 460 | OPimAlarm al( alarm[2].toInt(), OPimDateConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() ); |
474 | manager.add( al ); | 461 | manager.add( al ); |
475 | } | 462 | } |
476 | } | 463 | } |
477 | break; | 464 | break; |
478 | case OPimTodo::Reminders:{ | 465 | case OPimTodo::Reminders:{ |
479 | OPimNotifyManager &manager = ev.notifiers(); | 466 | OPimNotifyManager &manager = ev.notifiers(); |
480 | QStringList rems = QStringList::split(";", val ); | 467 | QStringList rems = QStringList::split(";", val ); |
481 | for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) { | 468 | for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) { |
482 | OPimReminder rem( (*it).toInt() ); | 469 | OPimReminder rem( (*it).toInt() ); |
483 | manager.add( rem ); | 470 | manager.add( rem ); |
484 | } | 471 | } |
485 | } | 472 | } |
486 | break; | 473 | break; |
487 | case OPimTodo::CrossReference: | 474 | case OPimTodo::CrossReference: |
488 | { | 475 | { |
489 | /* | 476 | /* |
490 | * A cross refernce looks like | 477 | * A cross refernce looks like |
491 | * appname,id;appname,id | 478 | * appname,id;appname,id |
492 | * we need to split it up | 479 | * we need to split it up |
493 | */ | 480 | */ |
494 | QStringList refs = QStringList::split(';', val ); | 481 | QStringList refs = QStringList::split(';', val ); |
495 | QStringList::Iterator strIt; | 482 | QStringList::Iterator strIt; |
496 | for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { | 483 | for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { |
497 | int pos = (*strIt).find(','); | 484 | int pos = (*strIt).find(','); |
498 | if ( pos > -1 ) | 485 | if ( pos > -1 ) |
499 | ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); | 486 | ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); |
500 | 487 | ||
501 | } | 488 | } |
502 | break; | 489 | break; |
503 | } | 490 | } |
504 | /* Recurrence stuff below + post processing later */ | 491 | /* Recurrence stuff below + post processing later */ |
505 | case FRType: | 492 | case FRType: |
506 | if ( val == "Daily" ) | 493 | if ( val == "Daily" ) |
507 | recur()->setType( OPimRecurrence::Daily ); | 494 | recur()->setType( OPimRecurrence::Daily ); |
508 | else if ( val == "Weekly" ) | 495 | else if ( val == "Weekly" ) |
509 | recur()->setType( OPimRecurrence::Weekly); | 496 | recur()->setType( OPimRecurrence::Weekly); |
510 | else if ( val == "MonthlyDay" ) | 497 | else if ( val == "MonthlyDay" ) |
511 | recur()->setType( OPimRecurrence::MonthlyDay ); | 498 | recur()->setType( OPimRecurrence::MonthlyDay ); |
512 | else if ( val == "MonthlyDate" ) | 499 | else if ( val == "MonthlyDate" ) |
513 | recur()->setType( OPimRecurrence::MonthlyDate ); | 500 | recur()->setType( OPimRecurrence::MonthlyDate ); |
514 | else if ( val == "Yearly" ) | 501 | else if ( val == "Yearly" ) |
515 | recur()->setType( OPimRecurrence::Yearly ); | 502 | recur()->setType( OPimRecurrence::Yearly ); |
516 | else | 503 | else |
517 | recur()->setType( OPimRecurrence::NoRepeat ); | 504 | recur()->setType( OPimRecurrence::NoRepeat ); |
518 | break; | 505 | break; |
519 | case FRWeekdays: | 506 | case FRWeekdays: |
520 | recur()->setDays( val.toInt() ); | 507 | recur()->setDays( val.toInt() ); |
521 | break; | 508 | break; |
522 | case FRPosition: | 509 | case FRPosition: |
523 | recur()->setPosition( val.toInt() ); | 510 | recur()->setPosition( val.toInt() ); |
524 | break; | 511 | break; |
525 | case FRFreq: | 512 | case FRFreq: |
526 | recur()->setFrequency( val.toInt() ); | 513 | recur()->setFrequency( val.toInt() ); |
527 | break; | 514 | break; |
528 | case FRHasEndDate: | 515 | case FRHasEndDate: |
529 | recur()->setHasEndDate( val.toInt() ); | 516 | recur()->setHasEndDate( val.toInt() ); |
530 | break; | 517 | break; |
531 | case FREndDate: { | 518 | case FREndDate: { |
532 | rp_end = (time_t) val.toLong(); | 519 | rp_end = (time_t) val.toLong(); |
533 | break; | 520 | break; |
534 | } | 521 | } |
535 | default: | 522 | default: |
536 | ev.setCustomField( attr, val ); | 523 | ev.setCustomField( attr, val ); |
537 | break; | 524 | break; |
538 | } | 525 | } |
539 | } | 526 | } |
540 | 527 | ||
541 | // from PalmtopRecord... GPL ### FIXME | 528 | // from PalmtopRecord... GPL ### FIXME |
542 | namespace { | 529 | namespace { |
543 | QString customToXml(const QMap<QString, QString>& customMap ) | 530 | QString customToXml(const QMap<QString, QString>& customMap ) |
544 | { | 531 | { |
545 | //owarn << QString("writing custom %1").arg(customMap.count()) << oendl; | ||
546 | QString buf(" "); | 532 | QString buf(" "); |
547 | for ( QMap<QString, QString>::ConstIterator cit = customMap.begin(); | 533 | for ( QMap<QString, QString>::ConstIterator cit = customMap.begin(); |
548 | cit != customMap.end(); ++cit) { | 534 | cit != customMap.end(); ++cit) { |
549 | // owarn << ".ITEM." << oendl; | ||
550 | buf += cit.key(); | 535 | buf += cit.key(); |
551 | buf += "=\""; | 536 | buf += "=\""; |
552 | buf += Qtopia::escapeString(cit.data()); | 537 | buf += Qtopia::escapeString(cit.data()); |
553 | buf += "\" "; | 538 | buf += "\" "; |
554 | } | 539 | } |
555 | return buf; | 540 | return buf; |
556 | } | 541 | } |
557 | 542 | ||
558 | 543 | ||
559 | } | 544 | } |
560 | 545 | ||
561 | QString OPimTodoAccessXML::toString( const OPimTodo& ev )const { | 546 | QString OPimTodoAccessXML::toString( const OPimTodo& ev )const { |
562 | QString str; | 547 | QString str; |
563 | 548 | ||
564 | str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; | 549 | str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; |
565 | str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; | 550 | str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; |
566 | str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; | 551 | str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; |
567 | str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; | 552 | str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; |
568 | 553 | ||
569 | str += "Categories=\"" + toString( ev.categories() ) + "\" "; | 554 | str += "Categories=\"" + toString( ev.categories() ) + "\" "; |
570 | str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; | 555 | str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; |
571 | str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; | 556 | str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; |
572 | 557 | ||
573 | if ( ev.hasDueDate() ) { | 558 | if ( ev.hasDueDate() ) { |
574 | str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; | 559 | str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; |
575 | str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; | 560 | str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; |
576 | str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; | 561 | str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; |
577 | } | 562 | } |
578 | // owarn << "Uid " << ev.uid() << "" << oendl; | ||
579 | str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; | 563 | str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; |
580 | 564 | ||
581 | // append the extra options | 565 | // append the extra options |
582 | /* FIXME Qtopia::Record this is currently not | 566 | /* FIXME Qtopia::Record this is currently not |
583 | * possible you can set custom fields | 567 | * possible you can set custom fields |
584 | * but don' iterate over the list | 568 | * but don' iterate over the list |
585 | * I may do #define private protected | 569 | * I may do #define private protected |
586 | * for this case - cough --zecke | 570 | * for this case - cough --zecke |
587 | */ | 571 | */ |
588 | /* | 572 | /* |
589 | QMap<QString, QString> extras = ev.extras(); | 573 | QMap<QString, QString> extras = ev.extras(); |
590 | QMap<QString, QString>::Iterator extIt; | 574 | QMap<QString, QString>::Iterator extIt; |
591 | for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) | 575 | for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) |
592 | str += extIt.key() + "=\"" + extIt.data() + "\" "; | 576 | str += extIt.key() + "=\"" + extIt.data() + "\" "; |
593 | */ | 577 | */ |
594 | // cross refernce | 578 | // cross refernce |
595 | if ( ev.hasRecurrence() ) { | 579 | if ( ev.hasRecurrence() ) { |
596 | str += ev.recurrence().toString(); | 580 | str += ev.recurrence().toString(); |
597 | } | 581 | } |
598 | if ( ev.hasStartDate() ) | 582 | if ( ev.hasStartDate() ) |
599 | str += "StartDate=\""+ OPimDateConversion::dateToString( ev.startDate() ) +"\" "; | 583 | str += "StartDate=\""+ OPimDateConversion::dateToString( ev.startDate() ) +"\" "; |
600 | if ( ev.hasCompletedDate() ) | 584 | if ( ev.hasCompletedDate() ) |
601 | str += "CompletedDate=\""+ OPimDateConversion::dateToString( ev.completedDate() ) +"\" "; | 585 | str += "CompletedDate=\""+ OPimDateConversion::dateToString( ev.completedDate() ) +"\" "; |
602 | if ( ev.hasState() ) | 586 | if ( ev.hasState() ) |
603 | str += "State=\""+QString::number( ev.state().state() )+"\" "; | 587 | str += "State=\""+QString::number( ev.state().state() )+"\" "; |
604 | 588 | ||
605 | /* | 589 | /* |
606 | * save reminders and notifiers! | 590 | * save reminders and notifiers! |
607 | * DATE_TIME:DURATION:SOUND:NOT_USED_YET;OTHER_DATE_TIME:OTHER_DURATION:SOUND:.... | 591 | * DATE_TIME:DURATION:SOUND:NOT_USED_YET;OTHER_DATE_TIME:OTHER_DURATION:SOUND:.... |
608 | */ | 592 | */ |
609 | if ( ev.hasNotifiers() ) { | 593 | if ( ev.hasNotifiers() ) { |
610 | OPimNotifyManager manager = ev.notifiers(); | 594 | OPimNotifyManager manager = ev.notifiers(); |
611 | OPimNotifyManager::Alarms alarms = manager.alarms(); | 595 | OPimNotifyManager::Alarms alarms = manager.alarms(); |
612 | if (!alarms.isEmpty() ) { | 596 | if (!alarms.isEmpty() ) { |
613 | QStringList als; | 597 | QStringList als; |
614 | OPimNotifyManager::Alarms::Iterator it = alarms.begin(); | 598 | OPimNotifyManager::Alarms::Iterator it = alarms.begin(); |
615 | for ( ; it != alarms.end(); ++it ) { | 599 | for ( ; it != alarms.end(); ++it ) { |
616 | /* only if time is valid */ | 600 | /* only if time is valid */ |
617 | if ( (*it).dateTime().isValid() ) { | 601 | if ( (*it).dateTime().isValid() ) { |
618 | als << OPimDateConversion::dateTimeToString( (*it).dateTime() ) | 602 | als << OPimDateConversion::dateTimeToString( (*it).dateTime() ) |
619 | + ":" + QString::number( (*it).duration() ) | 603 | + ":" + QString::number( (*it).duration() ) |
620 | + ":" + QString::number( (*it).sound() ) | 604 | + ":" + QString::number( (*it).sound() ) |
621 | + ":"; | 605 | + ":"; |
622 | } | 606 | } |
623 | } | 607 | } |
624 | // now write the list | 608 | // now write the list |
625 | owarn << "als: " << als.join("____________") << "" << oendl; | ||
626 | str += "Alarms=\""+als.join(";") +"\" "; | 609 | str += "Alarms=\""+als.join(";") +"\" "; |
627 | } | 610 | } |
628 | 611 | ||
629 | /* | 612 | /* |
630 | * now the same for reminders but more easy. We just save the uid of the OPimEvent. | 613 | * now the same for reminders but more easy. We just save the uid of the OPimEvent. |
631 | */ | 614 | */ |
632 | OPimNotifyManager::Reminders reminders = manager.reminders(); | 615 | OPimNotifyManager::Reminders reminders = manager.reminders(); |
633 | if (!reminders.isEmpty() ) { | 616 | if (!reminders.isEmpty() ) { |
634 | OPimNotifyManager::Reminders::Iterator it = reminders.begin(); | 617 | OPimNotifyManager::Reminders::Iterator it = reminders.begin(); |
635 | QStringList records; | 618 | QStringList records; |
636 | for ( ; it != reminders.end(); ++it ) { | 619 | for ( ; it != reminders.end(); ++it ) { |
637 | records << QString::number( (*it).recordUid() ); | 620 | records << QString::number( (*it).recordUid() ); |
638 | } | 621 | } |
639 | str += "Reminders=\""+ records.join(";") +"\" "; | 622 | str += "Reminders=\""+ records.join(";") +"\" "; |
640 | } | 623 | } |
641 | } | 624 | } |
642 | str += customToXml( ev.toExtraMap() ); | 625 | str += customToXml( ev.toExtraMap() ); |
643 | 626 | ||
644 | 627 | ||
645 | return str; | 628 | return str; |
646 | } | 629 | } |
647 | QString OPimTodoAccessXML::toString( const QArray<int>& ints ) const { | 630 | QString OPimTodoAccessXML::toString( const QArray<int>& ints ) const { |
648 | return Qtopia::Record::idsToString( ints ); | 631 | return Qtopia::Record::idsToString( ints ); |
649 | } | 632 | } |
650 | 633 | ||
651 | /* internal class for sorting | ||
652 | * | ||
653 | * Inspired by todoxmlio.cpp from TT | ||
654 | */ | ||
655 | 634 | ||
656 | struct OPimTodoXMLContainer { | 635 | QArray<int> OPimTodoAccessXML::sorted( const UIDArray& events, bool asc, |
657 | OPimTodo todo; | 636 | int sortOrder,int sortFilter, |
658 | }; | 637 | const QArray<int>& categories )const { |
638 | Internal::OPimTodoSortVector vector(events.count(), asc,sortOrder ); | ||
639 | int item = 0; | ||
659 | 640 | ||
660 | namespace { | 641 | bool bCat = sortFilter & OPimTodoAccess::FilterCategory ? true : false; |
661 | inline QString string( const OPimTodo& todo) { | 642 | bool bOnly = sortFilter & OPimTodoAccess::OnlyOverDue ? true : false; |
662 | return todo.summary().isEmpty() ? | 643 | bool comp = sortFilter & OPimTodoAccess::DoNotShowCompleted ? true : false; |
663 | todo.description().left(20 ) : | 644 | bool catPassed = false; |
664 | todo.summary(); | 645 | int cat; |
665 | } | ||
666 | inline int completed( const OPimTodo& todo1, const OPimTodo& todo2) { | ||
667 | int ret = 0; | ||
668 | if ( todo1.isCompleted() ) ret++; | ||
669 | if ( todo2.isCompleted() ) ret--; | ||
670 | return ret; | ||
671 | } | ||
672 | inline int priority( const OPimTodo& t1, const OPimTodo& t2) { | ||
673 | return ( t1.priority() - t2.priority() ); | ||
674 | } | ||
675 | inline int description( const OPimTodo& t1, const OPimTodo& t2) { | ||
676 | return QString::compare( string(t1), string(t2) ); | ||
677 | } | ||
678 | inline int deadline( const OPimTodo& t1, const OPimTodo& t2) { | ||
679 | int ret = 0; | ||
680 | if ( t1.hasDueDate() && | ||
681 | t2.hasDueDate() ) | ||
682 | ret = t2.dueDate().daysTo( t1.dueDate() ); | ||
683 | else if ( t1.hasDueDate() ) | ||
684 | ret = -1; | ||
685 | else if ( t2.hasDueDate() ) | ||
686 | ret = 1; | ||
687 | else | ||
688 | ret = 0; | ||
689 | 646 | ||
690 | return ret; | 647 | for ( uint i = 0; i < events.count(); ++i ) { |
691 | } | 648 | /* Guard against creating a new item... */ |
649 | if ( !m_events.contains( events[i] ) ) | ||
650 | continue; | ||
692 | 651 | ||
693 | }; | 652 | OPimTodo todo = m_events[events[i]]; |
694 | 653 | ||
695 | /* | 654 | /* show category */ |
696 | * Returns: | 655 | /* -1 == unfiled */ |
697 | * 0 if item1 == item2 | 656 | catPassed = false; |
698 | * | 657 | for ( uint cat_nu = 0; cat_nu < categories.count(); ++cat_nu ) { |
699 | * non-zero if item1 != item2 | 658 | cat = categories[cat_nu]; |
700 | * | 659 | if ( bCat && cat == -1 ) { |
701 | * This function returns int rather than bool so that reimplementations | 660 | if(!todo.categories().isEmpty() ) |
702 | * can return one of three values and use it to sort by: | 661 | continue; |
703 | * | 662 | } else if ( bCat && cat != 0) |
704 | * 0 if item1 == item2 | 663 | if (!todo.categories().contains( cat ) ) |
705 | * | 664 | continue; |
706 | * > 0 (positive integer) if item1 > item2 | 665 | catPassed = true; |
707 | * | ||
708 | * < 0 (negative integer) if item1 < item2 | ||
709 | * | ||
710 | */ | ||
711 | class OPimTodoXMLVector : public QVector<OPimTodoXMLContainer> { | ||
712 | public: | ||
713 | OPimTodoXMLVector(int size, bool asc, int sort) | ||
714 | : QVector<OPimTodoXMLContainer>( size ) | ||
715 | { | ||
716 | setAutoDelete( true ); | ||
717 | m_asc = asc; | ||
718 | m_sort = sort; | ||
719 | } | ||
720 | /* return the summary/description */ | ||
721 | QString string( const OPimTodo& todo) { | ||
722 | return todo.summary().isEmpty() ? | ||
723 | todo.description().left(20 ) : | ||
724 | todo.summary(); | ||
725 | } | ||
726 | /** | ||
727 | * we take the sortorder( switch on it ) | ||
728 | * | ||
729 | */ | ||
730 | int compareItems( Item d1, Item d2 ) { | ||
731 | bool seComp, sePrio, seDesc, seDeadline; | ||
732 | seComp = sePrio = seDeadline = seDesc = false; | ||
733 | int ret =0; | ||
734 | OPimTodoXMLContainer* con1 = (OPimTodoXMLContainer*)d1; | ||
735 | OPimTodoXMLContainer* con2 = (OPimTodoXMLContainer*)d2; | ||
736 | |||
737 | /* same item */ | ||
738 | if ( con1->todo.uid() == con2->todo.uid() ) | ||
739 | return 0; | ||
740 | |||
741 | switch ( m_sort ) { | ||
742 | /* completed */ | ||
743 | case 0: { | ||
744 | ret = completed( con1->todo, con2->todo ); | ||
745 | seComp = TRUE; | ||
746 | break; | ||
747 | } | ||
748 | /* priority */ | ||
749 | case 1: { | ||
750 | ret = priority( con1->todo, con2->todo ); | ||
751 | sePrio = TRUE; | ||
752 | break; | ||
753 | } | ||
754 | /* description */ | ||
755 | case 2: { | ||
756 | ret = description( con1->todo, con2->todo ); | ||
757 | seDesc = TRUE; | ||
758 | break; | ||
759 | } | ||
760 | /* deadline */ | ||
761 | case 3: { | ||
762 | ret = deadline( con1->todo, con2->todo ); | ||
763 | seDeadline = TRUE; | ||
764 | break; | 666 | break; |
765 | } | 667 | } |
766 | default: | ||
767 | ret = 0; | ||
768 | break; | ||
769 | }; | ||
770 | /* | ||
771 | * FIXME do better sorting if the first sort criteria | ||
772 | * ret equals 0 start with complete and so on... | ||
773 | */ | ||
774 | |||
775 | /* twist it we're not ascending*/ | ||
776 | if (!m_asc) | ||
777 | ret = ret * -1; | ||
778 | 668 | ||
779 | if ( ret ) | ||
780 | return ret; | ||
781 | |||
782 | // default did not gave difference let's try it other way around | ||
783 | /* | 669 | /* |
784 | * General try if already checked if not test | 670 | * If none of the Categories matched |
785 | * and return | 671 | * continue |
786 | * 1.Completed | ||
787 | * 2.Priority | ||
788 | * 3.Description | ||
789 | * 4.DueDate | ||
790 | */ | 672 | */ |
791 | if (!seComp ) { | 673 | if ( !catPassed ) |
792 | if ( (ret = completed( con1->todo, con2->todo ) ) ) { | ||
793 | if (!m_asc ) ret *= -1; | ||
794 | return ret; | ||
795 | } | ||
796 | } | ||
797 | if (!sePrio ) { | ||
798 | if ( (ret = priority( con1->todo, con2->todo ) ) ) { | ||
799 | if (!m_asc ) ret *= -1; | ||
800 | return ret; | ||
801 | } | ||
802 | } | ||
803 | if (!seDesc ) { | ||
804 | if ( (ret = description(con1->todo, con2->todo ) ) ) { | ||
805 | if (!m_asc) ret *= -1; | ||
806 | return ret; | ||
807 | } | ||
808 | } | ||
809 | if (!seDeadline) { | ||
810 | if ( (ret = deadline( con1->todo, con2->todo ) ) ) { | ||
811 | if (!m_asc) ret *= -1; | ||
812 | return ret; | ||
813 | } | ||
814 | } | ||
815 | |||
816 | return 0; | ||
817 | } | ||
818 | private: | ||
819 | bool m_asc; | ||
820 | int m_sort; | ||
821 | |||
822 | }; | ||
823 | |||
824 | QArray<int> OPimTodoAccessXML::sorted( bool asc, int sortOrder, | ||
825 | int sortFilter, int cat ) { | ||
826 | OPimTodoXMLVector vector(m_events.count(), asc,sortOrder ); | ||
827 | QMap<int, OPimTodo>::Iterator it; | ||
828 | int item = 0; | ||
829 | |||
830 | bool bCat = sortFilter & 1 ? true : false; | ||
831 | bool bOnly = sortFilter & 2 ? true : false; | ||
832 | bool comp = sortFilter & 4 ? true : false; | ||
833 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | ||
834 | |||
835 | /* show category */ | ||
836 | /* -1 == unfiled */ | ||
837 | if ( bCat && cat == -1 ) { | ||
838 | if(!(*it).categories().isEmpty() ) | ||
839 | continue; | ||
840 | }else if ( bCat && cat != 0) | ||
841 | if (!(*it).categories().contains( cat ) ) { | ||
842 | continue; | ||
843 | } | ||
844 | /* isOverdue but we should not show overdue - why?*/ | ||
845 | /* if ( (*it).isOverdue() && !bOnly ) { | ||
846 | owarn << "item is overdue but !bOnly" << oendl; | ||
847 | continue; | 674 | continue; |
848 | } | 675 | if ( !todo.isOverdue() && bOnly ) |
849 | */ | ||
850 | if ( !(*it).isOverdue() && bOnly ) { | ||
851 | continue; | 676 | continue; |
852 | } | 677 | if (todo.isCompleted() && comp ) |
853 | |||
854 | if ((*it).isCompleted() && comp ) { | ||
855 | continue; | 678 | continue; |
856 | } | ||
857 | 679 | ||
858 | 680 | vector.insert(item++, todo ); | |
859 | OPimTodoXMLContainer* con = new OPimTodoXMLContainer(); | ||
860 | con->todo = (*it); | ||
861 | vector.insert(item, con ); | ||
862 | item++; | ||
863 | } | 681 | } |
682 | |||
864 | vector.resize( item ); | 683 | vector.resize( item ); |
865 | /* sort it now */ | 684 | /* sort it now */ |
866 | vector.sort(); | 685 | vector.sort(); |
867 | /* now get the uids */ | 686 | /* now get the uids */ |
868 | QArray<int> array( vector.count() ); | 687 | UIDArray array( vector.count() ); |
869 | for (uint i= 0; i < vector.count(); i++ ) { | 688 | for (uint i= 0; i < vector.count(); i++ ) |
870 | array[i] = ( vector.at(i) )->todo.uid(); | 689 | array[i] = vector.uidAt( i ); |
871 | } | 690 | |
872 | return array; | 691 | return array; |
873 | }; | 692 | } |
693 | |||
874 | void OPimTodoAccessXML::removeAllCompleted() { | 694 | void OPimTodoAccessXML::removeAllCompleted() { |
875 | QMap<int, OPimTodo> events = m_events; | 695 | QMap<int, OPimTodo> events = m_events; |
876 | for ( QMap<int, OPimTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { | 696 | for ( QMap<int, OPimTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { |
877 | if ( (*it).isCompleted() ) | 697 | if ( (*it).isCompleted() ) |
878 | events.remove( it.key() ); | 698 | events.remove( it.key() ); |
879 | } | 699 | } |
880 | m_events = events; | 700 | m_events = events; |
881 | } | 701 | } |
882 | QBitArray OPimTodoAccessXML::supports()const { | 702 | |
883 | static QBitArray ar = sup(); | ||
884 | return ar; | ||
885 | } | ||
886 | QBitArray OPimTodoAccessXML::sup() { | ||
887 | QBitArray ar( OPimTodo::CompletedDate +1 ); | ||
888 | ar.fill( true ); | ||
889 | ar[OPimTodo::CrossReference] = false; | ||
890 | ar[OPimTodo::State ] = false; | ||
891 | ar[OPimTodo::Reminders] = false; | ||
892 | ar[OPimTodo::Notifiers] = false; | ||
893 | ar[OPimTodo::Maintainer] = false; | ||
894 | |||
895 | return ar; | ||
896 | } | ||
897 | QArray<int> OPimTodoAccessXML::matchRegexp( const QRegExp &r ) const | 703 | QArray<int> OPimTodoAccessXML::matchRegexp( const QRegExp &r ) const |
898 | { | 704 | { |
899 | QArray<int> m_currentQuery( m_events.count() ); | 705 | QArray<int> currentQuery( m_events.count() ); |
900 | uint arraycounter = 0; | 706 | uint arraycounter = 0; |
901 | 707 | ||
902 | QMap<int, OPimTodo>::ConstIterator it; | 708 | QMap<int, OPimTodo>::ConstIterator it; |
903 | for (it = m_events.begin(); it != m_events.end(); ++it ) { | 709 | for (it = m_events.begin(); it != m_events.end(); ++it ) { |
904 | if ( it.data().match( r ) ) | 710 | if ( it.data().match( r ) ) |
905 | m_currentQuery[arraycounter++] = it.data().uid(); | 711 | currentQuery[arraycounter++] = it.data().uid(); |
906 | 712 | ||
907 | } | 713 | } |
908 | // Shrink to fit.. | 714 | // Shrink to fit.. |
909 | m_currentQuery.resize(arraycounter); | 715 | currentQuery.resize(arraycounter); |
910 | 716 | ||
911 | return m_currentQuery; | 717 | return currentQuery; |
912 | } | 718 | } |
913 | 719 | ||
914 | } | 720 | } |
diff --git a/libopie2/opiepim/backend/otodoaccessxml.h b/libopie2/opiepim/backend/otodoaccessxml.h index 3a51543..134a21a 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.h +++ b/libopie2/opiepim/backend/otodoaccessxml.h | |||
@@ -1,89 +1,88 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) | 3 | Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | #ifndef OPIE_TODO_ACCESS_XML_H | 29 | #ifndef OPIE_TODO_ACCESS_XML_H |
30 | #define OPIE_TODO_ACCESS_XML_H | 30 | #define OPIE_TODO_ACCESS_XML_H |
31 | 31 | ||
32 | #include <qasciidict.h> | 32 | #include <qasciidict.h> |
33 | #include <qmap.h> | 33 | #include <qmap.h> |
34 | 34 | ||
35 | #include <opie2/otodoaccessbackend.h> | 35 | #include <opie2/otodoaccessbackend.h> |
36 | 36 | ||
37 | namespace Opie { | 37 | namespace Opie { |
38 | class XMLElement; | 38 | class XMLElement; |
39 | 39 | ||
40 | class OPimTodoAccessXML : public OPimTodoAccessBackend { | 40 | class OPimTodoAccessXML : public OPimTodoAccessBackend { |
41 | public: | 41 | public: |
42 | /** | 42 | /** |
43 | * fileName if Empty we will use the default path | 43 | * fileName if Empty we will use the default path |
44 | */ | 44 | */ |
45 | OPimTodoAccessXML( const QString& appName, | 45 | OPimTodoAccessXML( const QString& appName, |
46 | const QString& fileName = QString::null ); | 46 | const QString& fileName = QString::null ); |
47 | ~OPimTodoAccessXML(); | 47 | ~OPimTodoAccessXML(); |
48 | 48 | ||
49 | bool load(); | 49 | bool load(); |
50 | bool reload(); | 50 | bool reload(); |
51 | bool save(); | 51 | bool save(); |
52 | 52 | ||
53 | QArray<int> allRecords()const; | 53 | QArray<int> allRecords()const; |
54 | QArray<int> matchRegexp(const QRegExp &r) const; | 54 | QArray<int> matchRegexp(const QRegExp &r) const; |
55 | QArray<int> queryByExample( const OPimTodo&, int querysettings, const QDateTime& d = QDateTime() ); | 55 | QArray<int> queryByExample( const OPimTodo&, int querysettings, const QDateTime& d = QDateTime() ); |
56 | OPimTodo find( int uid )const; | 56 | OPimTodo find( int uid )const; |
57 | void clear(); | 57 | void clear(); |
58 | bool add( const OPimTodo& ); | 58 | bool add( const OPimTodo& ); |
59 | bool remove( int uid ); | 59 | bool remove( int uid ); |
60 | void removeAllCompleted(); | 60 | void removeAllCompleted(); |
61 | bool replace( const OPimTodo& ); | 61 | bool replace( const OPimTodo& ); |
62 | 62 | ||
63 | /* our functions */ | 63 | /* our functions */ |
64 | QArray<int> effectiveToDos( const QDate& start, | 64 | QArray<int> effectiveToDos( const QDate& start, |
65 | const QDate& end, | 65 | const QDate& end, |
66 | bool includeNoDates ); | 66 | bool includeNoDates )const; |
67 | QArray<int> overDue(); | 67 | QArray<int> overDue()const; |
68 | QArray<int> sorted( bool asc, int sortOrder, | 68 | |
69 | int sortFilter, int cat ); | 69 | //@{ |
70 | QBitArray supports()const; | 70 | UIDArray sorted( const UIDArray&, bool, int, int, const QArray<int>& )const; |
71 | //@} | ||
71 | private: | 72 | private: |
72 | static QBitArray sup(); | ||
73 | void todo( QAsciiDict<int>*, OPimTodo&,const QCString&,const QString& ); | 73 | void todo( QAsciiDict<int>*, OPimTodo&,const QCString&,const QString& ); |
74 | QString toString( const OPimTodo& )const; | 74 | QString toString( const OPimTodo& )const; |
75 | QString toString( const QArray<int>& ints ) const; | 75 | QString toString( const QArray<int>& ints ) const; |
76 | QMap<int, OPimTodo> m_events; | 76 | QMap<int, OPimTodo> m_events; |
77 | QString m_file; | 77 | QString m_file; |
78 | QString m_app; | 78 | QString m_app; |
79 | bool m_opened : 1; | 79 | bool m_opened : 1; |
80 | bool m_changed : 1; | 80 | bool m_changed : 1; |
81 | class OPimTodoAccessXMLPrivate; | 81 | class OPimTodoAccessXMLPrivate; |
82 | OPimTodoAccessXMLPrivate* d; | 82 | OPimTodoAccessXMLPrivate* d; |
83 | int m_year, m_month, m_day; | 83 | int m_year, m_month, m_day; |
84 | |||
85 | }; | 84 | }; |
86 | 85 | ||
87 | }; | 86 | }; |
88 | 87 | ||
89 | #endif | 88 | #endif |