author | eilers <eilers> | 2003-12-08 15:18:10 (UTC) |
---|---|---|
committer | eilers <eilers> | 2003-12-08 15:18:10 (UTC) |
commit | 6974a4bbdc674a2a5d41d801f80035a183faedb5 (patch) (unidiff) | |
tree | 09a719ef263047e92ffb866da13168b7f7d41f23 | |
parent | 7f2f736597490fd1592d7ed1f40e4abf824673c0 (diff) | |
download | opie-6974a4bbdc674a2a5d41d801f80035a183faedb5.zip opie-6974a4bbdc674a2a5d41d801f80035a183faedb5.tar.gz opie-6974a4bbdc674a2a5d41d801f80035a183faedb5.tar.bz2 |
Committing unfinished sql implementation before merging to libopie2 starts..
-rw-r--r-- | libopie/pim/ocontactaccessbackend_sql.cpp | 11 | ||||
-rw-r--r-- | libopie/pim/ocontactaccessbackend_sql.h | 5 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend_sql.cpp | 221 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend_sql.h | 60 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend_xml.cpp | 12 | ||||
-rw-r--r-- | libopie/pim/oevent.cpp | 131 | ||||
-rw-r--r-- | libopie/pim/oevent.h | 38 | ||||
-rw-r--r-- | libopie/pim/orecur.cpp | 8 | ||||
-rw-r--r-- | libopie/pim/orecur.h | 1 | ||||
-rw-r--r-- | libopie/pim/otodoaccesssql.cpp | 5 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | 11 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.h | 5 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp | 221 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_sql.h | 60 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp | 12 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccesssql.cpp | 5 | ||||
-rw-r--r-- | libopie2/opiepim/core/orecur.cpp | 8 | ||||
-rw-r--r-- | libopie2/opiepim/core/orecur.h | 1 | ||||
-rw-r--r-- | libopie2/opiepim/oevent.cpp | 131 | ||||
-rw-r--r-- | libopie2/opiepim/oevent.h | 38 |
20 files changed, 942 insertions, 42 deletions
diff --git a/libopie/pim/ocontactaccessbackend_sql.cpp b/libopie/pim/ocontactaccessbackend_sql.cpp index 132c9fc..dd9dbde 100644 --- a/libopie/pim/ocontactaccessbackend_sql.cpp +++ b/libopie/pim/ocontactaccessbackend_sql.cpp | |||
@@ -1,208 +1,211 @@ | |||
1 | /* | 1 | /* |
2 | * SQL Backend for the OPIE-Contact Database. | 2 | * SQL Backend for the OPIE-Contact Database. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | 4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) |
5 | * | 5 | * |
6 | * ===================================================================== | 6 | * ===================================================================== |
7 | *This program is free software; you can redistribute it and/or | 7 | *This program is free software; you can redistribute it and/or |
8 | *modify it under the terms of the GNU Library General Public | 8 | *modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either | 9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. | 10 | * version 2 of the License, or (at your option) any later version. |
11 | * ===================================================================== | 11 | * ===================================================================== |
12 | * ===================================================================== | 12 | * ===================================================================== |
13 | * Version: $Id$ | 13 | * Version: $Id$ |
14 | * ===================================================================== | 14 | * ===================================================================== |
15 | * History: | 15 | * History: |
16 | * $Log$ | 16 | * $Log$ |
17 | * Revision 1.3 2003/12/08 15:18:10 eilers | ||
18 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
19 | * | ||
17 | * Revision 1.2 2003/09/29 07:44:26 eilers | 20 | * Revision 1.2 2003/09/29 07:44:26 eilers |
18 | * Improvement of PIM-SQL Databases, but search queries are still limited. | 21 | * Improvement of PIM-SQL Databases, but search queries are still limited. |
19 | * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. | 22 | * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. |
20 | * Todo: Started to add new attributes. Some type conversions missing. | 23 | * Todo: Started to add new attributes. Some type conversions missing. |
21 | * | 24 | * |
22 | * Revision 1.1 2003/09/22 14:31:16 eilers | 25 | * Revision 1.1 2003/09/22 14:31:16 eilers |
23 | * Added first experimental incarnation of sql-backend for addressbook. | 26 | * Added first experimental incarnation of sql-backend for addressbook. |
24 | * Some modifications to be able to compile the todo sql-backend. | 27 | * Some modifications to be able to compile the todo sql-backend. |
25 | * A lot of changes fill follow... | 28 | * A lot of changes fill follow... |
26 | * | 29 | * |
27 | */ | 30 | */ |
28 | 31 | ||
29 | #include "ocontactaccessbackend_sql.h" | 32 | #include "ocontactaccessbackend_sql.h" |
30 | 33 | ||
31 | #include <qarray.h> | 34 | #include <qarray.h> |
32 | #include <qdatetime.h> | 35 | #include <qdatetime.h> |
33 | #include <qstringlist.h> | 36 | #include <qstringlist.h> |
34 | 37 | ||
35 | #include <qpe/global.h> | 38 | #include <qpe/global.h> |
36 | #include <qpe/recordfields.h> | 39 | #include <qpe/recordfields.h> |
37 | 40 | ||
38 | #include <opie/ocontactfields.h> | 41 | #include <opie/ocontactfields.h> |
39 | #include <opie/oconversion.h> | 42 | #include <opie/oconversion.h> |
40 | #include <opie2/osqldriver.h> | 43 | #include <opie2/osqldriver.h> |
41 | #include <opie2/osqlresult.h> | 44 | #include <opie2/osqlresult.h> |
42 | #include <opie2/osqlmanager.h> | 45 | #include <opie2/osqlmanager.h> |
43 | #include <opie2/osqlquery.h> | 46 | #include <opie2/osqlquery.h> |
44 | 47 | ||
45 | 48 | ||
46 | 49 | ||
47 | 50 | ||
48 | // If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead | 51 | // If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead |
49 | // vertical like "uid, type, value". | 52 | // vertical like "uid, type, value". |
50 | // DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! | 53 | // DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! |
51 | #define __STORE_HORIZONTAL_ | 54 | #define __STORE_HORIZONTAL_ |
52 | 55 | ||
53 | // Distinct loading is not very fast. If I expect that every person has just | 56 | // Distinct loading is not very fast. If I expect that every person has just |
54 | // one (and always one) 'Last Name', I can request all uid's for existing lastnames, | 57 | // one (and always one) 'Last Name', I can request all uid's for existing lastnames, |
55 | // which is faster.. | 58 | // which is faster.. |
56 | // But this may not be true for all entries, like company contacts.. | 59 | // But this may not be true for all entries, like company contacts.. |
57 | // The current AddressBook application handles this problem, but other may not.. (eilers) | 60 | // The current AddressBook application handles this problem, but other may not.. (eilers) |
58 | #define __USE_SUPERFAST_LOADQUERY | 61 | #define __USE_SUPERFAST_LOADQUERY |
59 | 62 | ||
60 | 63 | ||
61 | /* | 64 | /* |
62 | * Implementation of used query types | 65 | * Implementation of used query types |
63 | * CREATE query | 66 | * CREATE query |
64 | * LOAD query | 67 | * LOAD query |
65 | * INSERT | 68 | * INSERT |
66 | * REMOVE | 69 | * REMOVE |
67 | * CLEAR | 70 | * CLEAR |
68 | */ | 71 | */ |
69 | namespace { | 72 | namespace { |
70 | /** | 73 | /** |
71 | * CreateQuery for the Todolist Table | 74 | * CreateQuery for the Todolist Table |
72 | */ | 75 | */ |
73 | class CreateQuery : public OSQLQuery { | 76 | class CreateQuery : public OSQLQuery { |
74 | public: | 77 | public: |
75 | CreateQuery(); | 78 | CreateQuery(); |
76 | ~CreateQuery(); | 79 | ~CreateQuery(); |
77 | QString query()const; | 80 | QString query()const; |
78 | }; | 81 | }; |
79 | 82 | ||
80 | /** | 83 | /** |
81 | * Clears (delete) a Table | 84 | * Clears (delete) a Table |
82 | */ | 85 | */ |
83 | class ClearQuery : public OSQLQuery { | 86 | class ClearQuery : public OSQLQuery { |
84 | public: | 87 | public: |
85 | ClearQuery(); | 88 | ClearQuery(); |
86 | ~ClearQuery(); | 89 | ~ClearQuery(); |
87 | QString query()const; | 90 | QString query()const; |
88 | 91 | ||
89 | }; | 92 | }; |
90 | 93 | ||
91 | 94 | ||
92 | /** | 95 | /** |
93 | * LoadQuery | 96 | * LoadQuery |
94 | * this one queries for all uids | 97 | * this one queries for all uids |
95 | */ | 98 | */ |
96 | class LoadQuery : public OSQLQuery { | 99 | class LoadQuery : public OSQLQuery { |
97 | public: | 100 | public: |
98 | LoadQuery(); | 101 | LoadQuery(); |
99 | ~LoadQuery(); | 102 | ~LoadQuery(); |
100 | QString query()const; | 103 | QString query()const; |
101 | }; | 104 | }; |
102 | 105 | ||
103 | /** | 106 | /** |
104 | * inserts/adds a OContact to the table | 107 | * inserts/adds a OContact to the table |
105 | */ | 108 | */ |
106 | class InsertQuery : public OSQLQuery { | 109 | class InsertQuery : public OSQLQuery { |
107 | public: | 110 | public: |
108 | InsertQuery(const OContact& ); | 111 | InsertQuery(const OContact& ); |
109 | ~InsertQuery(); | 112 | ~InsertQuery(); |
110 | QString query()const; | 113 | QString query()const; |
111 | private: | 114 | private: |
112 | OContact m_contact; | 115 | OContact m_contact; |
113 | }; | 116 | }; |
114 | 117 | ||
115 | 118 | ||
116 | /** | 119 | /** |
117 | * removes one from the table | 120 | * removes one from the table |
118 | */ | 121 | */ |
119 | class RemoveQuery : public OSQLQuery { | 122 | class RemoveQuery : public OSQLQuery { |
120 | public: | 123 | public: |
121 | RemoveQuery(int uid ); | 124 | RemoveQuery(int uid ); |
122 | ~RemoveQuery(); | 125 | ~RemoveQuery(); |
123 | QString query()const; | 126 | QString query()const; |
124 | private: | 127 | private: |
125 | int m_uid; | 128 | int m_uid; |
126 | }; | 129 | }; |
127 | 130 | ||
128 | /** | 131 | /** |
129 | * a find query for noncustom elements | 132 | * a find query for noncustom elements |
130 | */ | 133 | */ |
131 | class FindQuery : public OSQLQuery { | 134 | class FindQuery : public OSQLQuery { |
132 | public: | 135 | public: |
133 | FindQuery(int uid); | 136 | FindQuery(int uid); |
134 | FindQuery(const QArray<int>& ); | 137 | FindQuery(const QArray<int>& ); |
135 | ~FindQuery(); | 138 | ~FindQuery(); |
136 | QString query()const; | 139 | QString query()const; |
137 | private: | 140 | private: |
138 | QString single()const; | 141 | QString single()const; |
139 | QString multi()const; | 142 | QString multi()const; |
140 | QArray<int> m_uids; | 143 | QArray<int> m_uids; |
141 | int m_uid; | 144 | int m_uid; |
142 | }; | 145 | }; |
143 | 146 | ||
144 | /** | 147 | /** |
145 | * a find query for custom elements | 148 | * a find query for custom elements |
146 | */ | 149 | */ |
147 | class FindCustomQuery : public OSQLQuery { | 150 | class FindCustomQuery : public OSQLQuery { |
148 | public: | 151 | public: |
149 | FindCustomQuery(int uid); | 152 | FindCustomQuery(int uid); |
150 | FindCustomQuery(const QArray<int>& ); | 153 | FindCustomQuery(const QArray<int>& ); |
151 | ~FindCustomQuery(); | 154 | ~FindCustomQuery(); |
152 | QString query()const; | 155 | QString query()const; |
153 | private: | 156 | private: |
154 | QString single()const; | 157 | QString single()const; |
155 | QString multi()const; | 158 | QString multi()const; |
156 | QArray<int> m_uids; | 159 | QArray<int> m_uids; |
157 | int m_uid; | 160 | int m_uid; |
158 | }; | 161 | }; |
159 | 162 | ||
160 | 163 | ||
161 | 164 | ||
162 | // We using three tables to store the information: | 165 | // We using three tables to store the information: |
163 | // 1. addressbook : It contains General information about the contact (non custom) | 166 | // 1. addressbook : It contains General information about the contact (non custom) |
164 | // 2. custom_data : Not official supported entries | 167 | // 2. custom_data : Not official supported entries |
165 | // All tables are connected by the uid of the contact. | 168 | // All tables are connected by the uid of the contact. |
166 | // Maybe I should add a table for meta-information ? | 169 | // Maybe I should add a table for meta-information ? |
167 | CreateQuery::CreateQuery() : OSQLQuery() {} | 170 | CreateQuery::CreateQuery() : OSQLQuery() {} |
168 | CreateQuery::~CreateQuery() {} | 171 | CreateQuery::~CreateQuery() {} |
169 | QString CreateQuery::query()const { | 172 | QString CreateQuery::query()const { |
170 | QString qu; | 173 | QString qu; |
171 | #ifdef __STORE_HORIZONTAL_ | 174 | #ifdef __STORE_HORIZONTAL_ |
172 | 175 | ||
173 | qu += "create table addressbook( uid PRIMARY KEY "; | 176 | qu += "create table addressbook( uid PRIMARY KEY "; |
174 | 177 | ||
175 | QStringList fieldList = OContactFields::untrfields( false ); | 178 | QStringList fieldList = OContactFields::untrfields( false ); |
176 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 179 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
177 | qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); | 180 | qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); |
178 | } | 181 | } |
179 | qu += " );"; | 182 | qu += " );"; |
180 | 183 | ||
181 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; | 184 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; |
182 | 185 | ||
183 | #else | 186 | #else |
184 | 187 | ||
185 | qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));"; | 188 | qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));"; |
186 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; | 189 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; |
187 | // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );"; | 190 | // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );"; |
188 | 191 | ||
189 | #endif // __STORE_HORIZONTAL_ | 192 | #endif // __STORE_HORIZONTAL_ |
190 | return qu; | 193 | return qu; |
191 | } | 194 | } |
192 | 195 | ||
193 | ClearQuery::ClearQuery() | 196 | ClearQuery::ClearQuery() |
194 | : OSQLQuery() {} | 197 | : OSQLQuery() {} |
195 | ClearQuery::~ClearQuery() {} | 198 | ClearQuery::~ClearQuery() {} |
196 | QString ClearQuery::query()const { | 199 | QString ClearQuery::query()const { |
197 | QString qu = "drop table addressbook;"; | 200 | QString qu = "drop table addressbook;"; |
198 | qu += "drop table custom_data;"; | 201 | qu += "drop table custom_data;"; |
199 | // qu += "drop table dates;"; | 202 | // qu += "drop table dates;"; |
200 | return qu; | 203 | return qu; |
201 | } | 204 | } |
202 | 205 | ||
203 | 206 | ||
204 | LoadQuery::LoadQuery() : OSQLQuery() {} | 207 | LoadQuery::LoadQuery() : OSQLQuery() {} |
205 | LoadQuery::~LoadQuery() {} | 208 | LoadQuery::~LoadQuery() {} |
206 | QString LoadQuery::query()const { | 209 | QString LoadQuery::query()const { |
207 | QString qu; | 210 | QString qu; |
208 | #ifdef __STORE_HORIZONTAL_ | 211 | #ifdef __STORE_HORIZONTAL_ |
@@ -265,406 +268,412 @@ namespace { | |||
265 | // These entries should stored in a special format | 268 | // These entries should stored in a special format |
266 | // year-month-day | 269 | // year-month-day |
267 | QDate day = m_contact.anniversary(); | 270 | QDate day = m_contact.anniversary(); |
268 | if ( day.isValid() ){ | 271 | if ( day.isValid() ){ |
269 | qu += QString(",\"%1-%2-%3\"") | 272 | qu += QString(",\"%1-%2-%3\"") |
270 | .arg( day.year() ) | 273 | .arg( day.year() ) |
271 | .arg( day.month() ) | 274 | .arg( day.month() ) |
272 | .arg( day.day() ); | 275 | .arg( day.day() ); |
273 | } else { | 276 | } else { |
274 | qu += ",\"\""; | 277 | qu += ",\"\""; |
275 | } | 278 | } |
276 | } | 279 | } |
277 | break; | 280 | break; |
278 | 281 | ||
279 | default: | 282 | default: |
280 | qu += QString( ",\"%1\"" ).arg( contactMap[id] ); | 283 | qu += QString( ",\"%1\"" ).arg( contactMap[id] ); |
281 | } | 284 | } |
282 | } | 285 | } |
283 | qu += " );"; | 286 | qu += " );"; |
284 | 287 | ||
285 | 288 | ||
286 | #else | 289 | #else |
287 | // Get all information out of the contact-class | 290 | // Get all information out of the contact-class |
288 | // Remember: The category is stored in contactMap, too ! | 291 | // Remember: The category is stored in contactMap, too ! |
289 | QMap<int, QString> contactMap = m_contact.toMap(); | 292 | QMap<int, QString> contactMap = m_contact.toMap(); |
290 | 293 | ||
291 | QMap<QString, QString> addressbook_db; | 294 | QMap<QString, QString> addressbook_db; |
292 | 295 | ||
293 | // Get the translation from the ID to the String | 296 | // Get the translation from the ID to the String |
294 | QMap<int, QString> transMap = OContactFields::idToUntrFields(); | 297 | QMap<int, QString> transMap = OContactFields::idToUntrFields(); |
295 | 298 | ||
296 | for( QMap<int, QString>::Iterator it = contactMap.begin(); | 299 | for( QMap<int, QString>::Iterator it = contactMap.begin(); |
297 | it != contactMap.end(); ++it ){ | 300 | it != contactMap.end(); ++it ){ |
298 | switch ( it.key() ){ | 301 | switch ( it.key() ){ |
299 | case Qtopia::Birthday:{ | 302 | case Qtopia::Birthday:{ |
300 | // These entries should stored in a special format | 303 | // These entries should stored in a special format |
301 | // year-month-day | 304 | // year-month-day |
302 | QDate day = m_contact.birthday(); | 305 | QDate day = m_contact.birthday(); |
303 | addressbook_db.insert( transMap[it.key()], | 306 | addressbook_db.insert( transMap[it.key()], |
304 | QString("%1-%2-%3") | 307 | QString("%1-%2-%3") |
305 | .arg( day.year() ) | 308 | .arg( day.year() ) |
306 | .arg( day.month() ) | 309 | .arg( day.month() ) |
307 | .arg( day.day() ) ); | 310 | .arg( day.day() ) ); |
308 | } | 311 | } |
309 | break; | 312 | break; |
310 | case Qtopia::Anniversary:{ | 313 | case Qtopia::Anniversary:{ |
311 | // These entries should stored in a special format | 314 | // These entries should stored in a special format |
312 | // year-month-day | 315 | // year-month-day |
313 | QDate day = m_contact.anniversary(); | 316 | QDate day = m_contact.anniversary(); |
314 | addressbook_db.insert( transMap[it.key()], | 317 | addressbook_db.insert( transMap[it.key()], |
315 | QString("%1-%2-%3") | 318 | QString("%1-%2-%3") |
316 | .arg( day.year() ) | 319 | .arg( day.year() ) |
317 | .arg( day.month() ) | 320 | .arg( day.month() ) |
318 | .arg( day.day() ) ); | 321 | .arg( day.day() ) ); |
319 | } | 322 | } |
320 | break; | 323 | break; |
321 | case Qtopia::AddressUid: // Ignore UID | 324 | case Qtopia::AddressUid: // Ignore UID |
322 | break; | 325 | break; |
323 | default: // Translate id to String | 326 | default: // Translate id to String |
324 | addressbook_db.insert( transMap[it.key()], it.data() ); | 327 | addressbook_db.insert( transMap[it.key()], it.data() ); |
325 | break; | 328 | break; |
326 | } | 329 | } |
327 | 330 | ||
328 | } | 331 | } |
329 | 332 | ||
330 | // Now convert this whole stuff into a SQL String, beginning with | 333 | // Now convert this whole stuff into a SQL String, beginning with |
331 | // the addressbook table.. | 334 | // the addressbook table.. |
332 | QString qu; | 335 | QString qu; |
333 | // qu += "begin transaction;"; | 336 | // qu += "begin transaction;"; |
334 | int id = 0; | 337 | int id = 0; |
335 | for( QMap<QString, QString>::Iterator it = addressbook_db.begin(); | 338 | for( QMap<QString, QString>::Iterator it = addressbook_db.begin(); |
336 | it != addressbook_db.end(); ++it ){ | 339 | it != addressbook_db.end(); ++it ){ |
337 | qu += "insert into addressbook VALUES(" | 340 | qu += "insert into addressbook VALUES(" |
338 | + QString::number( m_contact.uid() ) | 341 | + QString::number( m_contact.uid() ) |
339 | + "," | 342 | + "," |
340 | + QString::number( id++ ) | 343 | + QString::number( id++ ) |
341 | + ",'" | 344 | + ",'" |
342 | + it.key() //.latin1() | 345 | + it.key() //.latin1() |
343 | + "'," | 346 | + "'," |
344 | + "0" // Priority for future enhancements | 347 | + "0" // Priority for future enhancements |
345 | + ",'" | 348 | + ",'" |
346 | + it.data() //.latin1() | 349 | + it.data() //.latin1() |
347 | + "');"; | 350 | + "');"; |
348 | } | 351 | } |
349 | 352 | ||
350 | #endif //__STORE_HORIZONTAL_ | 353 | #endif //__STORE_HORIZONTAL_ |
351 | // Now add custom data.. | 354 | // Now add custom data.. |
352 | #ifdef __STORE_HORIZONTAL_ | 355 | #ifdef __STORE_HORIZONTAL_ |
353 | int id = 0; | 356 | int id = 0; |
354 | #endif | 357 | #endif |
355 | id = 0; | 358 | id = 0; |
356 | QMap<QString, QString> customMap = m_contact.toExtraMap(); | 359 | QMap<QString, QString> customMap = m_contact.toExtraMap(); |
357 | for( QMap<QString, QString>::Iterator it = customMap.begin(); | 360 | for( QMap<QString, QString>::Iterator it = customMap.begin(); |
358 | it != customMap.end(); ++it ){ | 361 | it != customMap.end(); ++it ){ |
359 | qu += "insert into custom_data VALUES(" | 362 | qu += "insert into custom_data VALUES(" |
360 | + QString::number( m_contact.uid() ) | 363 | + QString::number( m_contact.uid() ) |
361 | + "," | 364 | + "," |
362 | + QString::number( id++ ) | 365 | + QString::number( id++ ) |
363 | + ",'" | 366 | + ",'" |
364 | + it.key() //.latin1() | 367 | + it.key() //.latin1() |
365 | + "'," | 368 | + "'," |
366 | + "0" // Priority for future enhancements | 369 | + "0" // Priority for future enhancements |
367 | + ",'" | 370 | + ",'" |
368 | + it.data() //.latin1() | 371 | + it.data() //.latin1() |
369 | + "');"; | 372 | + "');"; |
370 | } | 373 | } |
371 | // qu += "commit;"; | 374 | // qu += "commit;"; |
372 | qWarning("add %s", qu.latin1() ); | 375 | qWarning("add %s", qu.latin1() ); |
373 | return qu; | 376 | return qu; |
374 | } | 377 | } |
375 | 378 | ||
376 | 379 | ||
377 | RemoveQuery::RemoveQuery(int uid ) | 380 | RemoveQuery::RemoveQuery(int uid ) |
378 | : OSQLQuery(), m_uid( uid ) {} | 381 | : OSQLQuery(), m_uid( uid ) {} |
379 | RemoveQuery::~RemoveQuery() {} | 382 | RemoveQuery::~RemoveQuery() {} |
380 | QString RemoveQuery::query()const { | 383 | QString RemoveQuery::query()const { |
381 | QString qu = "DELETE from addressbook where uid = " | 384 | QString qu = "DELETE from addressbook where uid = " |
382 | + QString::number(m_uid) + ";"; | 385 | + QString::number(m_uid) + ";"; |
383 | qu += "DELETE from custom_data where uid = " | 386 | qu += "DELETE from custom_data where uid = " |
384 | + QString::number(m_uid) + ";"; | 387 | + QString::number(m_uid) + ";"; |
385 | return qu; | 388 | return qu; |
386 | } | 389 | } |
387 | 390 | ||
388 | 391 | ||
389 | 392 | ||
390 | 393 | ||
391 | FindQuery::FindQuery(int uid) | 394 | FindQuery::FindQuery(int uid) |
392 | : OSQLQuery(), m_uid( uid ) { | 395 | : OSQLQuery(), m_uid( uid ) { |
393 | } | 396 | } |
394 | FindQuery::FindQuery(const QArray<int>& ints) | 397 | FindQuery::FindQuery(const QArray<int>& ints) |
395 | : OSQLQuery(), m_uids( ints ){ | 398 | : OSQLQuery(), m_uids( ints ){ |
396 | } | 399 | } |
397 | FindQuery::~FindQuery() { | 400 | FindQuery::~FindQuery() { |
398 | } | 401 | } |
399 | QString FindQuery::query()const{ | 402 | QString FindQuery::query()const{ |
400 | // if ( m_uids.count() == 0 ) | 403 | // if ( m_uids.count() == 0 ) |
401 | return single(); | 404 | return single(); |
402 | } | 405 | } |
403 | /* | 406 | /* |
404 | else | 407 | else |
405 | return multi(); | 408 | return multi(); |
406 | } | 409 | } |
407 | QString FindQuery::multi()const { | 410 | QString FindQuery::multi()const { |
408 | QString qu = "select uid, type, value from addressbook where"; | 411 | QString qu = "select uid, type, value from addressbook where"; |
409 | for (uint i = 0; i < m_uids.count(); i++ ) { | 412 | for (uint i = 0; i < m_uids.count(); i++ ) { |
410 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | 413 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; |
411 | } | 414 | } |
412 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. | 415 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. |
413 | return qu; | 416 | return qu; |
414 | } | 417 | } |
415 | */ | 418 | */ |
416 | #ifdef __STORE_HORIZONTAL_ | 419 | #ifdef __STORE_HORIZONTAL_ |
417 | QString FindQuery::single()const{ | 420 | QString FindQuery::single()const{ |
418 | QString qu = "select *"; | 421 | QString qu = "select *"; |
419 | qu += " from addressbook where uid = " + QString::number(m_uid); | 422 | qu += " from addressbook where uid = " + QString::number(m_uid); |
420 | 423 | ||
421 | // qWarning("find query: %s", qu.latin1() ); | 424 | // qWarning("find query: %s", qu.latin1() ); |
422 | return qu; | 425 | return qu; |
423 | } | 426 | } |
424 | #else | 427 | #else |
425 | QString FindQuery::single()const{ | 428 | QString FindQuery::single()const{ |
426 | QString qu = "select uid, type, value from addressbook where uid = "; | 429 | QString qu = "select uid, type, value from addressbook where uid = "; |
427 | qu += QString::number(m_uid); | 430 | qu += QString::number(m_uid); |
428 | return qu; | 431 | return qu; |
429 | } | 432 | } |
430 | #endif | 433 | #endif |
431 | 434 | ||
432 | 435 | ||
433 | FindCustomQuery::FindCustomQuery(int uid) | 436 | FindCustomQuery::FindCustomQuery(int uid) |
434 | : OSQLQuery(), m_uid( uid ) { | 437 | : OSQLQuery(), m_uid( uid ) { |
435 | } | 438 | } |
436 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) | 439 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) |
437 | : OSQLQuery(), m_uids( ints ){ | 440 | : OSQLQuery(), m_uids( ints ){ |
438 | } | 441 | } |
439 | FindCustomQuery::~FindCustomQuery() { | 442 | FindCustomQuery::~FindCustomQuery() { |
440 | } | 443 | } |
441 | QString FindCustomQuery::query()const{ | 444 | QString FindCustomQuery::query()const{ |
442 | // if ( m_uids.count() == 0 ) | 445 | // if ( m_uids.count() == 0 ) |
443 | return single(); | 446 | return single(); |
444 | } | 447 | } |
445 | QString FindCustomQuery::single()const{ | 448 | QString FindCustomQuery::single()const{ |
446 | QString qu = "select uid, type, value from custom_data where uid = "; | 449 | QString qu = "select uid, type, value from custom_data where uid = "; |
447 | qu += QString::number(m_uid); | 450 | qu += QString::number(m_uid); |
448 | return qu; | 451 | return qu; |
449 | } | 452 | } |
450 | 453 | ||
451 | }; | 454 | }; |
452 | 455 | ||
453 | 456 | ||
454 | /* --------------------------------------------------------------------------- */ | 457 | /* --------------------------------------------------------------------------- */ |
455 | 458 | ||
456 | OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, | 459 | OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, |
457 | const QString& filename ): m_changed(false) | 460 | const QString& filename ): |
461 | OContactAccessBackend(), m_changed(false), m_driver( NULL ) | ||
458 | { | 462 | { |
459 | qWarning("C'tor OContactAccessBackend_SQL starts"); | 463 | qWarning("C'tor OContactAccessBackend_SQL starts"); |
460 | QTime t; | 464 | QTime t; |
461 | t.start(); | 465 | t.start(); |
462 | 466 | ||
463 | /* Expecting to access the default filename if nothing else is set */ | 467 | /* Expecting to access the default filename if nothing else is set */ |
464 | if ( filename.isEmpty() ){ | 468 | if ( filename.isEmpty() ){ |
465 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); | 469 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); |
466 | } else | 470 | } else |
467 | m_fileName = filename; | 471 | m_fileName = filename; |
468 | 472 | ||
469 | // Get the standart sql-driver from the OSQLManager.. | 473 | // Get the standart sql-driver from the OSQLManager.. |
470 | OSQLManager man; | 474 | OSQLManager man; |
471 | m_driver = man.standard(); | 475 | m_driver = man.standard(); |
472 | m_driver->setUrl( m_fileName ); | 476 | m_driver->setUrl( m_fileName ); |
473 | 477 | ||
474 | load(); | 478 | load(); |
475 | 479 | ||
476 | qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); | 480 | qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); |
477 | } | 481 | } |
478 | 482 | ||
483 | OContactAccessBackend_SQL::~OContactAccessBackend_SQL () | ||
484 | { | ||
485 | if( m_driver ) | ||
486 | delete m_driver; | ||
487 | } | ||
479 | 488 | ||
480 | bool OContactAccessBackend_SQL::load () | 489 | bool OContactAccessBackend_SQL::load () |
481 | { | 490 | { |
482 | if (!m_driver->open() ) | 491 | if (!m_driver->open() ) |
483 | return false; | 492 | return false; |
484 | 493 | ||
485 | // Don't expect that the database exists. | 494 | // Don't expect that the database exists. |
486 | // It is save here to create the table, even if it | 495 | // It is save here to create the table, even if it |
487 | // do exist. ( Is that correct for all databases ?? ) | 496 | // do exist. ( Is that correct for all databases ?? ) |
488 | CreateQuery creat; | 497 | CreateQuery creat; |
489 | OSQLResult res = m_driver->query( &creat ); | 498 | OSQLResult res = m_driver->query( &creat ); |
490 | 499 | ||
491 | update(); | 500 | update(); |
492 | 501 | ||
493 | return true; | 502 | return true; |
494 | 503 | ||
495 | } | 504 | } |
496 | 505 | ||
497 | bool OContactAccessBackend_SQL::reload() | 506 | bool OContactAccessBackend_SQL::reload() |
498 | { | 507 | { |
499 | return load(); | 508 | return load(); |
500 | } | 509 | } |
501 | 510 | ||
502 | bool OContactAccessBackend_SQL::save() | 511 | bool OContactAccessBackend_SQL::save() |
503 | { | 512 | { |
504 | return m_driver->close(); | 513 | return m_driver->close(); |
505 | } | 514 | } |
506 | 515 | ||
507 | 516 | ||
508 | void OContactAccessBackend_SQL::clear () | 517 | void OContactAccessBackend_SQL::clear () |
509 | { | 518 | { |
510 | ClearQuery cle; | 519 | ClearQuery cle; |
511 | OSQLResult res = m_driver->query( &cle ); | 520 | OSQLResult res = m_driver->query( &cle ); |
512 | CreateQuery qu; | 521 | CreateQuery qu; |
513 | res = m_driver->query(&qu); | 522 | res = m_driver->query(&qu); |
514 | } | 523 | } |
515 | 524 | ||
516 | bool OContactAccessBackend_SQL::wasChangedExternally() | 525 | bool OContactAccessBackend_SQL::wasChangedExternally() |
517 | { | 526 | { |
518 | return false; | 527 | return false; |
519 | } | 528 | } |
520 | 529 | ||
521 | QArray<int> OContactAccessBackend_SQL::allRecords() const | 530 | QArray<int> OContactAccessBackend_SQL::allRecords() const |
522 | { | 531 | { |
523 | 532 | ||
524 | // FIXME: Think about cute handling of changed tables.. | 533 | // FIXME: Think about cute handling of changed tables.. |
525 | // Thus, we don't have to call update here... | 534 | // Thus, we don't have to call update here... |
526 | if ( m_changed ) | 535 | if ( m_changed ) |
527 | ((OContactAccessBackend_SQL*)this)->update(); | 536 | ((OContactAccessBackend_SQL*)this)->update(); |
528 | 537 | ||
529 | return m_uids; | 538 | return m_uids; |
530 | } | 539 | } |
531 | 540 | ||
532 | bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) | 541 | bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) |
533 | { | 542 | { |
534 | InsertQuery ins( newcontact ); | 543 | InsertQuery ins( newcontact ); |
535 | OSQLResult res = m_driver->query( &ins ); | 544 | OSQLResult res = m_driver->query( &ins ); |
536 | 545 | ||
537 | if ( res.state() == OSQLResult::Failure ) | 546 | if ( res.state() == OSQLResult::Failure ) |
538 | return false; | 547 | return false; |
539 | 548 | ||
540 | int c = m_uids.count(); | 549 | int c = m_uids.count(); |
541 | m_uids.resize( c+1 ); | 550 | m_uids.resize( c+1 ); |
542 | m_uids[c] = newcontact.uid(); | 551 | m_uids[c] = newcontact.uid(); |
543 | 552 | ||
544 | return true; | 553 | return true; |
545 | } | 554 | } |
546 | 555 | ||
547 | 556 | ||
548 | bool OContactAccessBackend_SQL::remove ( int uid ) | 557 | bool OContactAccessBackend_SQL::remove ( int uid ) |
549 | { | 558 | { |
550 | RemoveQuery rem( uid ); | 559 | RemoveQuery rem( uid ); |
551 | OSQLResult res = m_driver->query(&rem ); | 560 | OSQLResult res = m_driver->query(&rem ); |
552 | 561 | ||
553 | if ( res.state() == OSQLResult::Failure ) | 562 | if ( res.state() == OSQLResult::Failure ) |
554 | return false; | 563 | return false; |
555 | 564 | ||
556 | m_changed = true; | 565 | m_changed = true; |
557 | 566 | ||
558 | return true; | 567 | return true; |
559 | } | 568 | } |
560 | 569 | ||
561 | bool OContactAccessBackend_SQL::replace ( const OContact &contact ) | 570 | bool OContactAccessBackend_SQL::replace ( const OContact &contact ) |
562 | { | 571 | { |
563 | if ( !remove( contact.uid() ) ) | 572 | if ( !remove( contact.uid() ) ) |
564 | return false; | 573 | return false; |
565 | 574 | ||
566 | return add( contact ); | 575 | return add( contact ); |
567 | } | 576 | } |
568 | 577 | ||
569 | 578 | ||
570 | OContact OContactAccessBackend_SQL::find ( int uid ) const | 579 | OContact OContactAccessBackend_SQL::find ( int uid ) const |
571 | { | 580 | { |
572 | qWarning("OContactAccessBackend_SQL::find()"); | 581 | qWarning("OContactAccessBackend_SQL::find()"); |
573 | QTime t; | 582 | QTime t; |
574 | t.start(); | 583 | t.start(); |
575 | 584 | ||
576 | OContact retContact( requestNonCustom( uid ) ); | 585 | OContact retContact( requestNonCustom( uid ) ); |
577 | retContact.setExtraMap( requestCustom( uid ) ); | 586 | retContact.setExtraMap( requestCustom( uid ) ); |
578 | 587 | ||
579 | qWarning("OContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() ); | 588 | qWarning("OContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() ); |
580 | return retContact; | 589 | return retContact; |
581 | } | 590 | } |
582 | 591 | ||
583 | 592 | ||
584 | 593 | ||
585 | QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ) | 594 | QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ) |
586 | { | 595 | { |
587 | QString qu = "SELECT uid FROM addressbook WHERE"; | 596 | QString qu = "SELECT uid FROM addressbook WHERE"; |
588 | 597 | ||
589 | QMap<int, QString> queryFields = query.toMap(); | 598 | QMap<int, QString> queryFields = query.toMap(); |
590 | QStringList fieldList = OContactFields::untrfields( false ); | 599 | QStringList fieldList = OContactFields::untrfields( false ); |
591 | QMap<QString, int> translate = OContactFields::untrFieldsToId(); | 600 | QMap<QString, int> translate = OContactFields::untrFieldsToId(); |
592 | 601 | ||
593 | // Convert every filled field to a SQL-Query | 602 | // Convert every filled field to a SQL-Query |
594 | bool isAnyFieldSelected = false; | 603 | bool isAnyFieldSelected = false; |
595 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 604 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
596 | int id = translate[*it]; | 605 | int id = translate[*it]; |
597 | QString queryStr = queryFields[id]; | 606 | QString queryStr = queryFields[id]; |
598 | if ( !queryStr.isEmpty() ){ | 607 | if ( !queryStr.isEmpty() ){ |
599 | isAnyFieldSelected = true; | 608 | isAnyFieldSelected = true; |
600 | switch( id ){ | 609 | switch( id ){ |
601 | default: | 610 | default: |
602 | // Switching between case sensitive and insensitive... | 611 | // Switching between case sensitive and insensitive... |
603 | // LIKE is not case sensitive, GLOB is case sensitive | 612 | // LIKE is not case sensitive, GLOB is case sensitive |
604 | // Do exist a better solution to switch this ? | 613 | // Do exist a better solution to switch this ? |
605 | if ( settings & OContactAccess::IgnoreCase ) | 614 | if ( settings & OContactAccess::IgnoreCase ) |
606 | qu += "(\"" + *it + "\"" + " LIKE " + "'" | 615 | qu += "(\"" + *it + "\"" + " LIKE " + "'" |
607 | + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND "; | 616 | + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND "; |
608 | else | 617 | else |
609 | qu += "(\"" + *it + "\"" + " GLOB " + "'" | 618 | qu += "(\"" + *it + "\"" + " GLOB " + "'" |
610 | + queryStr + "'" + ") AND "; | 619 | + queryStr + "'" + ") AND "; |
611 | 620 | ||
612 | } | 621 | } |
613 | } | 622 | } |
614 | } | 623 | } |
615 | // Skip trailing "AND" | 624 | // Skip trailing "AND" |
616 | if ( isAnyFieldSelected ) | 625 | if ( isAnyFieldSelected ) |
617 | qu = qu.left( qu.length() - 4 ); | 626 | qu = qu.left( qu.length() - 4 ); |
618 | 627 | ||
619 | qWarning( "queryByExample query: %s", qu.latin1() ); | 628 | qWarning( "queryByExample query: %s", qu.latin1() ); |
620 | 629 | ||
621 | // Execute query and return the received uid's | 630 | // Execute query and return the received uid's |
622 | OSQLRawQuery raw( qu ); | 631 | OSQLRawQuery raw( qu ); |
623 | OSQLResult res = m_driver->query( &raw ); | 632 | OSQLResult res = m_driver->query( &raw ); |
624 | if ( res.state() != OSQLResult::Success ){ | 633 | if ( res.state() != OSQLResult::Success ){ |
625 | QArray<int> empty; | 634 | QArray<int> empty; |
626 | return empty; | 635 | return empty; |
627 | } | 636 | } |
628 | 637 | ||
629 | QArray<int> list = extractUids( res ); | 638 | QArray<int> list = extractUids( res ); |
630 | 639 | ||
631 | return list; | 640 | return list; |
632 | } | 641 | } |
633 | 642 | ||
634 | QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | 643 | QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const |
635 | { | 644 | { |
636 | QArray<int> nix(0); | 645 | QArray<int> nix(0); |
637 | return nix; | 646 | return nix; |
638 | } | 647 | } |
639 | 648 | ||
640 | const uint OContactAccessBackend_SQL::querySettings() | 649 | const uint OContactAccessBackend_SQL::querySettings() |
641 | { | 650 | { |
642 | return OContactAccess::IgnoreCase | 651 | return OContactAccess::IgnoreCase |
643 | || OContactAccess::WildCards; | 652 | || OContactAccess::WildCards; |
644 | } | 653 | } |
645 | 654 | ||
646 | bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const | 655 | bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const |
647 | { | 656 | { |
648 | /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay | 657 | /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay |
649 | * may be added with any of the other settings. IgnoreCase should never used alone. | 658 | * may be added with any of the other settings. IgnoreCase should never used alone. |
650 | * Wildcards, RegExp, ExactMatch should never used at the same time... | 659 | * Wildcards, RegExp, ExactMatch should never used at the same time... |
651 | */ | 660 | */ |
652 | 661 | ||
653 | // Step 1: Check whether the given settings are supported by this backend | 662 | // Step 1: Check whether the given settings are supported by this backend |
654 | if ( ( querySettings & ( | 663 | if ( ( querySettings & ( |
655 | OContactAccess::IgnoreCase | 664 | OContactAccess::IgnoreCase |
656 | | OContactAccess::WildCards | 665 | | OContactAccess::WildCards |
657 | // | OContactAccess::DateDiff | 666 | // | OContactAccess::DateDiff |
658 | // | OContactAccess::DateYear | 667 | // | OContactAccess::DateYear |
659 | // | OContactAccess::DateMonth | 668 | // | OContactAccess::DateMonth |
660 | // | OContactAccess::DateDay | 669 | // | OContactAccess::DateDay |
661 | // | OContactAccess::RegExp | 670 | // | OContactAccess::RegExp |
662 | // | OContactAccess::ExactMatch | 671 | // | OContactAccess::ExactMatch |
663 | ) ) != querySettings ) | 672 | ) ) != querySettings ) |
664 | return false; | 673 | return false; |
665 | 674 | ||
666 | // Step 2: Check whether the given combinations are ok.. | 675 | // Step 2: Check whether the given combinations are ok.. |
667 | 676 | ||
668 | // IngoreCase alone is invalid | 677 | // IngoreCase alone is invalid |
669 | if ( querySettings == OContactAccess::IgnoreCase ) | 678 | if ( querySettings == OContactAccess::IgnoreCase ) |
670 | return false; | 679 | return false; |
diff --git a/libopie/pim/ocontactaccessbackend_sql.h b/libopie/pim/ocontactaccessbackend_sql.h index bb22551..b8f1d8d 100644 --- a/libopie/pim/ocontactaccessbackend_sql.h +++ b/libopie/pim/ocontactaccessbackend_sql.h | |||
@@ -1,96 +1,101 @@ | |||
1 | /* | 1 | /* |
2 | * SQL Backend for the OPIE-Contact Database. | 2 | * SQL Backend for the OPIE-Contact Database. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | 4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) |
5 | * | 5 | * |
6 | * ===================================================================== | 6 | * ===================================================================== |
7 | *This program is free software; you can redistribute it and/or | 7 | *This program is free software; you can redistribute it and/or |
8 | *modify it under the terms of the GNU Library General Public | 8 | *modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either | 9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. | 10 | * version 2 of the License, or (at your option) any later version. |
11 | * ===================================================================== | 11 | * ===================================================================== |
12 | * | 12 | * |
13 | * | 13 | * |
14 | * ===================================================================== | 14 | * ===================================================================== |
15 | * Version: $Id$ | 15 | * Version: $Id$ |
16 | * ===================================================================== | 16 | * ===================================================================== |
17 | * History: | 17 | * History: |
18 | * $Log$ | 18 | * $Log$ |
19 | * Revision 1.2 2003/12/08 15:18:11 eilers | ||
20 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
21 | * | ||
19 | * Revision 1.1 2003/09/22 14:31:16 eilers | 22 | * Revision 1.1 2003/09/22 14:31:16 eilers |
20 | * Added first experimental incarnation of sql-backend for addressbook. | 23 | * Added first experimental incarnation of sql-backend for addressbook. |
21 | * Some modifications to be able to compile the todo sql-backend. | 24 | * Some modifications to be able to compile the todo sql-backend. |
22 | * A lot of changes fill follow... | 25 | * A lot of changes fill follow... |
23 | * | 26 | * |
24 | * | 27 | * |
25 | */ | 28 | */ |
26 | 29 | ||
27 | #ifndef _OContactAccessBackend_SQL_ | 30 | #ifndef _OContactAccessBackend_SQL_ |
28 | #define _OContactAccessBackend_SQL_ | 31 | #define _OContactAccessBackend_SQL_ |
29 | 32 | ||
30 | #include "ocontactaccessbackend.h" | 33 | #include "ocontactaccessbackend.h" |
31 | #include "ocontactaccess.h" | 34 | #include "ocontactaccess.h" |
32 | 35 | ||
33 | #include <qlist.h> | 36 | #include <qlist.h> |
34 | #include <qdict.h> | 37 | #include <qdict.h> |
35 | 38 | ||
36 | class OSQLDriver; | 39 | class OSQLDriver; |
37 | class OSQLResult; | 40 | class OSQLResult; |
38 | class OSQLResultItem; | 41 | class OSQLResultItem; |
39 | 42 | ||
40 | /* the default xml implementation */ | 43 | /* the default xml implementation */ |
41 | /** | 44 | /** |
42 | * This class is the SQL implementation of a Contact backend | 45 | * This class is the SQL implementation of a Contact backend |
43 | * it does implement everything available for OContact. | 46 | * it does implement everything available for OContact. |
44 | * @see OPimAccessBackend for more information of available methods | 47 | * @see OPimAccessBackend for more information of available methods |
45 | */ | 48 | */ |
46 | class OContactAccessBackend_SQL : public OContactAccessBackend { | 49 | class OContactAccessBackend_SQL : public OContactAccessBackend { |
47 | public: | 50 | public: |
48 | OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); | 51 | OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); |
49 | 52 | ||
53 | ~OContactAccessBackend_SQL (); | ||
54 | |||
50 | bool save(); | 55 | bool save(); |
51 | 56 | ||
52 | bool load (); | 57 | bool load (); |
53 | 58 | ||
54 | void clear (); | 59 | void clear (); |
55 | 60 | ||
56 | bool wasChangedExternally(); | 61 | bool wasChangedExternally(); |
57 | 62 | ||
58 | QArray<int> allRecords() const; | 63 | QArray<int> allRecords() const; |
59 | 64 | ||
60 | OContact find ( int uid ) const; | 65 | OContact find ( int uid ) const; |
61 | // FIXME: Add lookahead-cache support ! | 66 | // FIXME: Add lookahead-cache support ! |
62 | //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; | 67 | //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; |
63 | 68 | ||
64 | QArray<int> queryByExample ( const OContact &query, int settings, | 69 | QArray<int> queryByExample ( const OContact &query, int settings, |
65 | const QDateTime& d ); | 70 | const QDateTime& d ); |
66 | 71 | ||
67 | QArray<int> matchRegexp( const QRegExp &r ) const; | 72 | QArray<int> matchRegexp( const QRegExp &r ) const; |
68 | 73 | ||
69 | const uint querySettings(); | 74 | const uint querySettings(); |
70 | 75 | ||
71 | bool hasQuerySettings (uint querySettings) const; | 76 | bool hasQuerySettings (uint querySettings) const; |
72 | 77 | ||
73 | // Currently only asc implemented.. | 78 | // Currently only asc implemented.. |
74 | QArray<int> sorted( bool asc, int , int , int ); | 79 | QArray<int> sorted( bool asc, int , int , int ); |
75 | bool add ( const OContact &newcontact ); | 80 | bool add ( const OContact &newcontact ); |
76 | 81 | ||
77 | bool replace ( const OContact &contact ); | 82 | bool replace ( const OContact &contact ); |
78 | 83 | ||
79 | bool remove ( int uid ); | 84 | bool remove ( int uid ); |
80 | bool reload(); | 85 | bool reload(); |
81 | 86 | ||
82 | private: | 87 | private: |
83 | QArray<int> extractUids( OSQLResult& res ) const; | 88 | QArray<int> extractUids( OSQLResult& res ) const; |
84 | QMap<int, QString> requestNonCustom( int uid ) const; | 89 | QMap<int, QString> requestNonCustom( int uid ) const; |
85 | QMap<QString, QString> requestCustom( int uid ) const; | 90 | QMap<QString, QString> requestCustom( int uid ) const; |
86 | void update(); | 91 | void update(); |
87 | 92 | ||
88 | protected: | 93 | protected: |
89 | bool m_changed; | 94 | bool m_changed; |
90 | QString m_fileName; | 95 | QString m_fileName; |
91 | QArray<int> m_uids; | 96 | QArray<int> m_uids; |
92 | 97 | ||
93 | OSQLDriver* m_driver; | 98 | OSQLDriver* m_driver; |
94 | }; | 99 | }; |
95 | 100 | ||
96 | #endif | 101 | #endif |
diff --git a/libopie/pim/odatebookaccessbackend_sql.cpp b/libopie/pim/odatebookaccessbackend_sql.cpp new file mode 100644 index 0000000..9769bf7 --- a/dev/null +++ b/libopie/pim/odatebookaccessbackend_sql.cpp | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * SQL Backend for the OPIE-Calender Database. | ||
3 | * | ||
4 | * Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * | ||
6 | * ===================================================================== | ||
7 | *This program is free software; you can redistribute it and/or | ||
8 | *modify it under the terms of the GNU Library General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2 of the License, or (at your option) any later version. | ||
11 | * ===================================================================== | ||
12 | * ===================================================================== | ||
13 | * Version: $Id$ | ||
14 | * ===================================================================== | ||
15 | * History: | ||
16 | * $Log$ | ||
17 | * Revision 1.1 2003/12/08 15:18:12 eilers | ||
18 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
19 | * | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | |||
26 | #include <qarray.h> | ||
27 | #include <qstringlist.h> | ||
28 | |||
29 | #include "orecur.h" | ||
30 | #include "odatebookaccessbackend_sql.h" | ||
31 | |||
32 | #include <opie2/osqldriver.h> | ||
33 | #include <opie2/osqlresult.h> | ||
34 | #include <opie2/osqlmanager.h> | ||
35 | #include <opie2/osqlquery.h> | ||
36 | |||
37 | namespace { | ||
38 | |||
39 | |||
40 | |||
41 | }; | ||
42 | |||
43 | ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , | ||
44 | const QString& fileName ) | ||
45 | : ODateBookAccessBackend(), m_driver( NULL ) | ||
46 | { | ||
47 | m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; | ||
48 | |||
49 | // Get the standart sql-driver from the OSQLManager.. | ||
50 | OSQLManager man; | ||
51 | m_driver = man.standard(); | ||
52 | m_driver->setUrl( m_fileName ); | ||
53 | |||
54 | initFields(); | ||
55 | |||
56 | load(); | ||
57 | } | ||
58 | |||
59 | ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { | ||
60 | } | ||
61 | |||
62 | void ODateBookAccessBackend_SQL::initFields() | ||
63 | { | ||
64 | |||
65 | // This map contains the translation of the fieldtype id's to | ||
66 | // the names of the table columns | ||
67 | m_fieldMap.insert( OEvent::FUid, "uid" ); | ||
68 | m_fieldMap.insert( OEvent::FCategories, "Categories" ); | ||
69 | m_fieldMap.insert( OEvent::FDescription, "Description" ); | ||
70 | m_fieldMap.insert( OEvent::FLocation, "Location" ); | ||
71 | m_fieldMap.insert( OEvent::FType, "Type" ); | ||
72 | m_fieldMap.insert( OEvent::FAlarm, "Alarm" ); | ||
73 | m_fieldMap.insert( OEvent::FSound, "Sound" ); | ||
74 | m_fieldMap.insert( OEvent::FRType, "RType" ); | ||
75 | m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" ); | ||
76 | m_fieldMap.insert( OEvent::FRPosition, "RPosition" ); | ||
77 | m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); | ||
78 | m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); | ||
79 | m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); | ||
80 | m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); | ||
81 | m_fieldMap.insert( OEvent::FRExeptions, "RExceptions" ); | ||
82 | m_fieldMap.insert( OEvent::FStart, "Start" ); | ||
83 | m_fieldMap.insert( OEvent::FEnd, "End" ); | ||
84 | m_fieldMap.insert( OEvent::FNote, "Note" ); | ||
85 | m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); | ||
86 | m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); | ||
87 | m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); | ||
88 | } | ||
89 | |||
90 | bool ODateBookAccessBackend_SQL::load() | ||
91 | { | ||
92 | if (!m_driver->open() ) | ||
93 | return false; | ||
94 | |||
95 | // Don't expect that the database exists. | ||
96 | // It is save here to create the table, even if it | ||
97 | // do exist. ( Is that correct for all databases ?? ) | ||
98 | QStringqu = "create table datebook( uid INTEGER PRIMARY KEY "; | ||
99 | |||
100 | QMap<int, QString>::Iterator it; | ||
101 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | ||
102 | qu += QString( ",\"%1\" VARCHAR(10)" ).arg( it.data() ); | ||
103 | } | ||
104 | qu += " );"; | ||
105 | |||
106 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; | ||
107 | |||
108 | OSQLRawQuery raw( qu ); | ||
109 | OSQLResult res = m_driver->query( &raw ); | ||
110 | if ( res.state() != OSQLResult::Success ) | ||
111 | return false; | ||
112 | |||
113 | update(); | ||
114 | |||
115 | return true; | ||
116 | } | ||
117 | |||
118 | void ODateBookAccessBackend_SQL::update() | ||
119 | { | ||
120 | |||
121 | QString qu = "select uid from datebook"; | ||
122 | OSQLRawQuery raw( qu ); | ||
123 | OSQLResult res = m_driver->query( &raw ); | ||
124 | if ( res.state() != OSQLResult::Success ){ | ||
125 | m_uids.clear(); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | m_uids = extractUids( res ); | ||
130 | |||
131 | } | ||
132 | |||
133 | QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const | ||
134 | { | ||
135 | qWarning("extractUids"); | ||
136 | |||
137 | OSQLResultItem::ValueList list = res.results(); | ||
138 | OSQLResultItem::ValueList::Iterator it; | ||
139 | QArray<int> ints(list.count() ); | ||
140 | qWarning(" count = %d", list.count() ); | ||
141 | |||
142 | int i = 0; | ||
143 | for (it = list.begin(); it != list.end(); ++it ) { | ||
144 | ints[i] = (*it).data("uid").toInt(); | ||
145 | i++; | ||
146 | } | ||
147 | |||
148 | return ints; | ||
149 | |||
150 | } | ||
151 | |||
152 | bool ODateBookAccessBackend_SQL::reload() | ||
153 | { | ||
154 | return load(); | ||
155 | } | ||
156 | |||
157 | bool ODateBookAccessBackend_SQL::save() | ||
158 | { | ||
159 | return m_driver->close(); | ||
160 | } | ||
161 | |||
162 | QArray<int> ODateBookAccessBackend_SQL::allRecords()const | ||
163 | { | ||
164 | return m_uids; | ||
165 | } | ||
166 | |||
167 | QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) { | ||
168 | return QArray<int>(); | ||
169 | } | ||
170 | |||
171 | void ODateBookAccessBackend_SQL::clear() | ||
172 | { | ||
173 | QString qu = "drop table datebook;"; | ||
174 | qu += "drop table custom_data;"; | ||
175 | |||
176 | OSQLRawQuery raw( qu ); | ||
177 | OSQLResult res = m_driver->query( &raw ); | ||
178 | |||
179 | } | ||
180 | |||
181 | |||
182 | OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ | ||
183 | } | ||
184 | |||
185 | bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) { | ||
186 | return true; | ||
187 | } | ||
188 | bool ODateBookAccessBackend_SQL::remove( int uid ) { | ||
189 | |||
190 | return true; | ||
191 | } | ||
192 | bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) { | ||
193 | remove( ev.uid() ); | ||
194 | return add( ev ); | ||
195 | } | ||
196 | QArray<int> ODateBookAccessBackend_SQL::rawEvents()const { | ||
197 | return allRecords(); | ||
198 | } | ||
199 | QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const { | ||
200 | |||
201 | return ints; | ||
202 | } | ||
203 | QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const { | ||
204 | |||
205 | return ints; | ||
206 | } | ||
207 | OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() { | ||
208 | |||
209 | return list; | ||
210 | } | ||
211 | OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() { | ||
212 | |||
213 | return list; | ||
214 | } | ||
215 | |||
216 | |||
217 | QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | ||
218 | { | ||
219 | |||
220 | return m_currentQuery; | ||
221 | } | ||
diff --git a/libopie/pim/odatebookaccessbackend_sql.h b/libopie/pim/odatebookaccessbackend_sql.h new file mode 100644 index 0000000..85e0d4f --- a/dev/null +++ b/libopie/pim/odatebookaccessbackend_sql.h | |||
@@ -0,0 +1,60 @@ | |||
1 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | ||
2 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | ||
3 | |||
4 | #include <qmap.h> | ||
5 | |||
6 | #include "odatebookaccessbackend.h" | ||
7 | |||
8 | class OSQLDriver; | ||
9 | |||
10 | /** | ||
11 | * This is the default SQL implementation for DateBoook SQL storage | ||
12 | * It fully implements the interface | ||
13 | * @see ODateBookAccessBackend | ||
14 | * @see OPimAccessBackend | ||
15 | */ | ||
16 | class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { | ||
17 | public: | ||
18 | ODateBookAccessBackend_SQL( const QString& appName, | ||
19 | const QString& fileName = QString::null); | ||
20 | ~ODateBookAccessBackend_SQL(); | ||
21 | |||
22 | bool load(); | ||
23 | bool reload(); | ||
24 | bool save(); | ||
25 | |||
26 | QArray<int> allRecords()const; | ||
27 | QArray<int> matchRegexp(const QRegExp &r) const; | ||
28 | QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() ); | ||
29 | OEvent find( int uid )const; | ||
30 | void clear(); | ||
31 | bool add( const OEvent& ev ); | ||
32 | bool remove( int uid ); | ||
33 | bool replace( const OEvent& ev ); | ||
34 | |||
35 | QArray<UID> rawEvents()const; | ||
36 | QArray<UID> rawRepeats()const; | ||
37 | QArray<UID> nonRepeats()const; | ||
38 | |||
39 | OEvent::ValueList directNonRepeats(); | ||
40 | OEvent::ValueList directRawRepeats(); | ||
41 | |||
42 | private: | ||
43 | bool loadFile(); | ||
44 | QString m_fileName; | ||
45 | QArray<int> m_uids; | ||
46 | |||
47 | QMap<int, QString> m_fieldMap; | ||
48 | |||
49 | OSQLDriver* m_driver; | ||
50 | |||
51 | class Private; | ||
52 | Private *d; | ||
53 | |||
54 | void initFields(); | ||
55 | void update(); | ||
56 | QArray<int> extractUids( OSQLResult& res ) const; | ||
57 | |||
58 | }; | ||
59 | |||
60 | #endif | ||
diff --git a/libopie/pim/odatebookaccessbackend_xml.cpp b/libopie/pim/odatebookaccessbackend_xml.cpp index 39c43c5..929d004 100644 --- a/libopie/pim/odatebookaccessbackend_xml.cpp +++ b/libopie/pim/odatebookaccessbackend_xml.cpp | |||
@@ -1,606 +1,612 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <fcntl.h> | 2 | #include <fcntl.h> |
3 | 3 | ||
4 | #include <stdio.h> | 4 | #include <stdio.h> |
5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | 6 | ||
7 | #include <sys/types.h> | 7 | #include <sys/types.h> |
8 | #include <sys/mman.h> | 8 | #include <sys/mman.h> |
9 | #include <sys/stat.h> | 9 | #include <sys/stat.h> |
10 | 10 | ||
11 | #include <unistd.h> | 11 | #include <unistd.h> |
12 | 12 | ||
13 | #include <qasciidict.h> | 13 | #include <qasciidict.h> |
14 | #include <qfile.h> | 14 | #include <qfile.h> |
15 | 15 | ||
16 | #include <qtopia/global.h> | 16 | #include <qtopia/global.h> |
17 | #include <qtopia/stringutil.h> | 17 | #include <qtopia/stringutil.h> |
18 | #include <qtopia/timeconversion.h> | 18 | #include <qtopia/timeconversion.h> |
19 | 19 | ||
20 | #include "opimnotifymanager.h" | 20 | #include "opimnotifymanager.h" |
21 | #include "orecur.h" | 21 | #include "orecur.h" |
22 | #include "otimezone.h" | 22 | #include "otimezone.h" |
23 | #include "odatebookaccessbackend_xml.h" | 23 | #include "odatebookaccessbackend_xml.h" |
24 | 24 | ||
25 | namespace { | 25 | namespace { |
26 | // FROM TT again | 26 | // FROM TT again |
27 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) | 27 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) |
28 | { | 28 | { |
29 | char needleChar; | 29 | char needleChar; |
30 | char haystackChar; | 30 | char haystackChar; |
31 | if (!needle || !haystack || !hLen || !nLen) | 31 | if (!needle || !haystack || !hLen || !nLen) |
32 | return 0; | 32 | return 0; |
33 | 33 | ||
34 | const char* hsearch = haystack; | 34 | const char* hsearch = haystack; |
35 | 35 | ||
36 | if ((needleChar = *needle++) != 0) { | 36 | if ((needleChar = *needle++) != 0) { |
37 | nLen--; //(to make up for needle++) | 37 | nLen--; //(to make up for needle++) |
38 | do { | 38 | do { |
39 | do { | 39 | do { |
40 | if ((haystackChar = *hsearch++) == 0) | 40 | if ((haystackChar = *hsearch++) == 0) |
41 | return (0); | 41 | return (0); |
42 | if (hsearch >= haystack + hLen) | 42 | if (hsearch >= haystack + hLen) |
43 | return (0); | 43 | return (0); |
44 | } while (haystackChar != needleChar); | 44 | } while (haystackChar != needleChar); |
45 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); | 45 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); |
46 | hsearch--; | 46 | hsearch--; |
47 | } | 47 | } |
48 | return ((char *)hsearch); | 48 | return ((char *)hsearch); |
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
52 | namespace { | 52 | namespace { |
53 | time_t start, end, created, rp_end; | 53 | time_t start, end, created, rp_end; |
54 | ORecur* rec; | 54 | ORecur* rec; |
55 | ORecur* recur() { | 55 | ORecur* recur() { |
56 | if (!rec) | 56 | if (!rec) |
57 | rec = new ORecur; | 57 | rec = new ORecur; |
58 | 58 | ||
59 | return rec; | 59 | return rec; |
60 | } | 60 | } |
61 | int alarmTime; | 61 | int alarmTime; |
62 | int snd; | 62 | int snd; |
63 | enum Attribute{ | 63 | enum Attribute{ |
64 | FDescription = 0, | 64 | FDescription = 0, |
65 | FLocation, | 65 | FLocation, |
66 | FCategories, | 66 | FCategories, |
67 | FUid, | 67 | FUid, |
68 | FType, | 68 | FType, |
69 | FAlarm, | 69 | FAlarm, |
70 | FSound, | 70 | FSound, |
71 | FRType, | 71 | FRType, |
72 | FRWeekdays, | 72 | FRWeekdays, |
73 | FRPosition, | 73 | FRPosition, |
74 | FRFreq, | 74 | FRFreq, |
75 | FRHasEndDate, | 75 | FRHasEndDate, |
76 | FREndDate, | 76 | FREndDate, |
77 | FRStart, | 77 | FRStart, |
78 | FREnd, | 78 | FREnd, |
79 | FNote, | 79 | FNote, |
80 | FCreated, | 80 | FCreated, // Should't this be called FRCreated ? |
81 | FTimeZone, | 81 | FTimeZone, |
82 | FRecParent, | 82 | FRecParent, |
83 | FRecChildren, | 83 | FRecChildren, |
84 | FExceptions | 84 | FExceptions |
85 | }; | 85 | }; |
86 | |||
87 | // FIXME: Use OEvent::toMap() here !! (eilers) | ||
86 | inline void save( const OEvent& ev, QString& buf ) { | 88 | inline void save( const OEvent& ev, QString& buf ) { |
87 | qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); | 89 | qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); |
88 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; | 90 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; |
89 | if (!ev.location().isEmpty() ) | 91 | if (!ev.location().isEmpty() ) |
90 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; | 92 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; |
91 | 93 | ||
92 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; | 94 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; |
93 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; | 95 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; |
94 | 96 | ||
95 | if (ev.isAllDay() ) | 97 | if (ev.isAllDay() ) |
96 | buf += " type=\"AllDay\""; // is that all ?? (eilers) | 98 | buf += " type=\"AllDay\""; // is that all ?? (eilers) |
97 | 99 | ||
98 | if (ev.hasNotifiers() ) { | 100 | if (ev.hasNotifiers() ) { |
99 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first | 101 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first |
100 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; | 102 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; |
101 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; | 103 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; |
102 | if ( alarm.sound() == OPimAlarm::Loud ) | 104 | if ( alarm.sound() == OPimAlarm::Loud ) |
103 | buf += "loud"; | 105 | buf += "loud"; |
104 | else | 106 | else |
105 | buf += "silent"; | 107 | buf += "silent"; |
106 | buf += "\""; | 108 | buf += "\""; |
107 | } | 109 | } |
108 | if ( ev.hasRecurrence() ) { | 110 | if ( ev.hasRecurrence() ) { |
109 | buf += ev.recurrence().toString(); | 111 | buf += ev.recurrence().toString(); |
110 | } | 112 | } |
111 | 113 | ||
112 | /* | 114 | /* |
113 | * fscking timezones :) well, we'll first convert | 115 | * fscking timezones :) well, we'll first convert |
114 | * the QDateTime to a QDateTime in UTC time | 116 | * the QDateTime to a QDateTime in UTC time |
115 | * and then we'll create a nice time_t | 117 | * and then we'll create a nice time_t |
116 | */ | 118 | */ |
117 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | 119 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); |
118 | buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; | 120 | buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; |
119 | buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; | 121 | buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; |
120 | if (!ev.note().isEmpty() ) { | 122 | if (!ev.note().isEmpty() ) { |
121 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; | 123 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; |
122 | } | 124 | } |
123 | 125 | ||
124 | buf += " timezone=\""; | 126 | buf += " timezone=\""; |
125 | if ( ev.timeZone().isEmpty() ) | 127 | if ( ev.timeZone().isEmpty() ) |
126 | buf += "None"; | 128 | buf += "None"; |
127 | else | 129 | else |
128 | buf += ev.timeZone(); | 130 | buf += ev.timeZone(); |
129 | buf += "\""; | 131 | buf += "\""; |
130 | 132 | ||
131 | if (ev.parent() != 0 ) { | 133 | if (ev.parent() != 0 ) { |
132 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; | 134 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; |
133 | } | 135 | } |
134 | 136 | ||
135 | if (ev.children().count() != 0 ) { | 137 | if (ev.children().count() != 0 ) { |
136 | QArray<int> children = ev.children(); | 138 | QArray<int> children = ev.children(); |
137 | buf += " recchildren=\""; | 139 | buf += " recchildren=\""; |
138 | for ( uint i = 0; i < children.count(); i++ ) { | 140 | for ( uint i = 0; i < children.count(); i++ ) { |
139 | if ( i != 0 ) buf += " "; | 141 | if ( i != 0 ) buf += " "; |
140 | buf += QString::number( children[i] ); | 142 | buf += QString::number( children[i] ); |
141 | } | 143 | } |
142 | buf+= "\""; | 144 | buf+= "\""; |
143 | } | 145 | } |
144 | 146 | ||
145 | // skip custom writing | 147 | // skip custom writing |
146 | } | 148 | } |
147 | 149 | ||
148 | inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) { | 150 | inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) { |
149 | QMap<int, OEvent>::ConstIterator it; | 151 | QMap<int, OEvent>::ConstIterator it; |
150 | QString buf; | 152 | QString buf; |
151 | QCString str; | 153 | QCString str; |
152 | int total_written; | 154 | int total_written; |
153 | for ( it = list.begin(); it != list.end(); ++it ) { | 155 | for ( it = list.begin(); it != list.end(); ++it ) { |
154 | buf = "<event"; | 156 | buf = "<event"; |
155 | save( it.data(), buf ); | 157 | save( it.data(), buf ); |
156 | buf += " />\n"; | 158 | buf += " />\n"; |
157 | str = buf.utf8(); | 159 | str = buf.utf8(); |
158 | 160 | ||
159 | total_written = file.writeBlock(str.data(), str.length() ); | 161 | total_written = file.writeBlock(str.data(), str.length() ); |
160 | if ( total_written != int(str.length() ) ) | 162 | if ( total_written != int(str.length() ) ) |
161 | return false; | 163 | return false; |
162 | } | 164 | } |
163 | return true; | 165 | return true; |
164 | } | 166 | } |
165 | } | 167 | } |
166 | 168 | ||
167 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , | 169 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , |
168 | const QString& fileName ) | 170 | const QString& fileName ) |
169 | : ODateBookAccessBackend() { | 171 | : ODateBookAccessBackend() { |
170 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; | 172 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; |
171 | m_changed = false; | 173 | m_changed = false; |
172 | } | 174 | } |
173 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { | 175 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { |
174 | } | 176 | } |
175 | bool ODateBookAccessBackend_XML::load() { | 177 | bool ODateBookAccessBackend_XML::load() { |
176 | return loadFile(); | 178 | return loadFile(); |
177 | } | 179 | } |
178 | bool ODateBookAccessBackend_XML::reload() { | 180 | bool ODateBookAccessBackend_XML::reload() { |
179 | clear(); | 181 | clear(); |
180 | return load(); | 182 | return load(); |
181 | } | 183 | } |
182 | bool ODateBookAccessBackend_XML::save() { | 184 | bool ODateBookAccessBackend_XML::save() { |
183 | if (!m_changed) return true; | 185 | if (!m_changed) return true; |
184 | 186 | ||
185 | int total_written; | 187 | int total_written; |
186 | QString strFileNew = m_name + ".new"; | 188 | QString strFileNew = m_name + ".new"; |
187 | 189 | ||
188 | QFile f( strFileNew ); | 190 | QFile f( strFileNew ); |
189 | if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; | 191 | if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; |
190 | 192 | ||
191 | QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); | 193 | QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); |
192 | buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; | 194 | buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; |
193 | buf += "<events>\n"; | 195 | buf += "<events>\n"; |
194 | QCString str = buf.utf8(); | 196 | QCString str = buf.utf8(); |
195 | total_written = f.writeBlock( str.data(), str.length() ); | 197 | total_written = f.writeBlock( str.data(), str.length() ); |
196 | if ( total_written != int(str.length() ) ) { | 198 | if ( total_written != int(str.length() ) ) { |
197 | f.close(); | 199 | f.close(); |
198 | QFile::remove( strFileNew ); | 200 | QFile::remove( strFileNew ); |
199 | return false; | 201 | return false; |
200 | } | 202 | } |
201 | 203 | ||
202 | if (!forAll( m_raw, f ) ) { | 204 | if (!forAll( m_raw, f ) ) { |
203 | f.close(); | 205 | f.close(); |
204 | QFile::remove( strFileNew ); | 206 | QFile::remove( strFileNew ); |
205 | return false; | 207 | return false; |
206 | } | 208 | } |
207 | if (!forAll( m_rep, f ) ) { | 209 | if (!forAll( m_rep, f ) ) { |
208 | f.close(); | 210 | f.close(); |
209 | QFile::remove( strFileNew ); | 211 | QFile::remove( strFileNew ); |
210 | return false; | 212 | return false; |
211 | } | 213 | } |
212 | 214 | ||
213 | buf = "</events>\n</DATEBOOK>\n"; | 215 | buf = "</events>\n</DATEBOOK>\n"; |
214 | str = buf.utf8(); | 216 | str = buf.utf8(); |
215 | total_written = f.writeBlock( str.data(), str.length() ); | 217 | total_written = f.writeBlock( str.data(), str.length() ); |
216 | if ( total_written != int(str.length() ) ) { | 218 | if ( total_written != int(str.length() ) ) { |
217 | f.close(); | 219 | f.close(); |
218 | QFile::remove( strFileNew ); | 220 | QFile::remove( strFileNew ); |
219 | return false; | 221 | return false; |
220 | } | 222 | } |
221 | f.close(); | 223 | f.close(); |
222 | 224 | ||
223 | if ( ::rename( strFileNew, m_name ) < 0 ) { | 225 | if ( ::rename( strFileNew, m_name ) < 0 ) { |
224 | QFile::remove( strFileNew ); | 226 | QFile::remove( strFileNew ); |
225 | return false; | 227 | return false; |
226 | } | 228 | } |
227 | 229 | ||
228 | m_changed = false; | 230 | m_changed = false; |
229 | return true; | 231 | return true; |
230 | } | 232 | } |
231 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { | 233 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { |
232 | QArray<int> ints( m_raw.count()+ m_rep.count() ); | 234 | QArray<int> ints( m_raw.count()+ m_rep.count() ); |
233 | uint i = 0; | 235 | uint i = 0; |
234 | QMap<int, OEvent>::ConstIterator it; | 236 | QMap<int, OEvent>::ConstIterator it; |
235 | 237 | ||
236 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 238 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
237 | ints[i] = it.key(); | 239 | ints[i] = it.key(); |
238 | i++; | 240 | i++; |
239 | } | 241 | } |
240 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 242 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
241 | ints[i] = it.key(); | 243 | ints[i] = it.key(); |
242 | i++; | 244 | i++; |
243 | } | 245 | } |
244 | 246 | ||
245 | return ints; | 247 | return ints; |
246 | } | 248 | } |
247 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int, const QDateTime& ) { | 249 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int, const QDateTime& ) { |
248 | return QArray<int>(); | 250 | return QArray<int>(); |
249 | } | 251 | } |
250 | void ODateBookAccessBackend_XML::clear() { | 252 | void ODateBookAccessBackend_XML::clear() { |
251 | m_changed = true; | 253 | m_changed = true; |
252 | m_raw.clear(); | 254 | m_raw.clear(); |
253 | m_rep.clear(); | 255 | m_rep.clear(); |
254 | } | 256 | } |
255 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ | 257 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ |
256 | if ( m_raw.contains( uid ) ) | 258 | if ( m_raw.contains( uid ) ) |
257 | return m_raw[uid]; | 259 | return m_raw[uid]; |
258 | else | 260 | else |
259 | return m_rep[uid]; | 261 | return m_rep[uid]; |
260 | } | 262 | } |
261 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { | 263 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { |
262 | m_changed = true; | 264 | m_changed = true; |
263 | if (ev.hasRecurrence() ) | 265 | if (ev.hasRecurrence() ) |
264 | m_rep.insert( ev.uid(), ev ); | 266 | m_rep.insert( ev.uid(), ev ); |
265 | else | 267 | else |
266 | m_raw.insert( ev.uid(), ev ); | 268 | m_raw.insert( ev.uid(), ev ); |
267 | 269 | ||
268 | return true; | 270 | return true; |
269 | } | 271 | } |
270 | bool ODateBookAccessBackend_XML::remove( int uid ) { | 272 | bool ODateBookAccessBackend_XML::remove( int uid ) { |
271 | m_changed = true; | 273 | m_changed = true; |
272 | m_rep.remove( uid ); | 274 | m_rep.remove( uid ); |
273 | m_rep.remove( uid ); | 275 | m_rep.remove( uid ); |
274 | 276 | ||
275 | return true; | 277 | return true; |
276 | } | 278 | } |
277 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { | 279 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { |
278 | replace( ev.uid() ); | 280 | replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers) |
279 | return add( ev ); | 281 | return add( ev ); |
280 | } | 282 | } |
281 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { | 283 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { |
282 | return allRecords(); | 284 | return allRecords(); |
283 | } | 285 | } |
284 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { | 286 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { |
285 | QArray<int> ints( m_rep.count() ); | 287 | QArray<int> ints( m_rep.count() ); |
286 | uint i = 0; | 288 | uint i = 0; |
287 | QMap<int, OEvent>::ConstIterator it; | 289 | QMap<int, OEvent>::ConstIterator it; |
288 | 290 | ||
289 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 291 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
290 | ints[i] = it.key(); | 292 | ints[i] = it.key(); |
291 | i++; | 293 | i++; |
292 | } | 294 | } |
293 | 295 | ||
294 | return ints; | 296 | return ints; |
295 | } | 297 | } |
296 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { | 298 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { |
297 | QArray<int> ints( m_raw.count() ); | 299 | QArray<int> ints( m_raw.count() ); |
298 | uint i = 0; | 300 | uint i = 0; |
299 | QMap<int, OEvent>::ConstIterator it; | 301 | QMap<int, OEvent>::ConstIterator it; |
300 | 302 | ||
301 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 303 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
302 | ints[i] = it.key(); | 304 | ints[i] = it.key(); |
303 | i++; | 305 | i++; |
304 | } | 306 | } |
305 | 307 | ||
306 | return ints; | 308 | return ints; |
307 | } | 309 | } |
308 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { | 310 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { |
309 | OEvent::ValueList list; | 311 | OEvent::ValueList list; |
310 | QMap<int, OEvent>::ConstIterator it; | 312 | QMap<int, OEvent>::ConstIterator it; |
311 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) | 313 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) |
312 | list.append( it.data() ); | 314 | list.append( it.data() ); |
313 | 315 | ||
314 | return list; | 316 | return list; |
315 | } | 317 | } |
316 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { | 318 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { |
317 | OEvent::ValueList list; | 319 | OEvent::ValueList list; |
318 | QMap<int, OEvent>::ConstIterator it; | 320 | QMap<int, OEvent>::ConstIterator it; |
319 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) | 321 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) |
320 | list.append( it.data() ); | 322 | list.append( it.data() ); |
321 | 323 | ||
322 | return list; | 324 | return list; |
323 | } | 325 | } |
326 | |||
327 | // FIXME: Use OEvent::fromMap() (eilers) | ||
324 | bool ODateBookAccessBackend_XML::loadFile() { | 328 | bool ODateBookAccessBackend_XML::loadFile() { |
325 | m_changed = false; | 329 | m_changed = false; |
326 | 330 | ||
327 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); | 331 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); |
328 | if ( fd < 0 ) return false; | 332 | if ( fd < 0 ) return false; |
329 | 333 | ||
330 | struct stat attribute; | 334 | struct stat attribute; |
331 | if ( ::fstat(fd, &attribute ) == -1 ) { | 335 | if ( ::fstat(fd, &attribute ) == -1 ) { |
332 | ::close( fd ); | 336 | ::close( fd ); |
333 | return false; | 337 | return false; |
334 | } | 338 | } |
335 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 339 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
336 | if ( map_addr == ( (caddr_t)-1) ) { | 340 | if ( map_addr == ( (caddr_t)-1) ) { |
337 | ::close( fd ); | 341 | ::close( fd ); |
338 | return false; | 342 | return false; |
339 | } | 343 | } |
340 | 344 | ||
341 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); | 345 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); |
342 | ::close( fd ); | 346 | ::close( fd ); |
343 | 347 | ||
344 | QAsciiDict<int> dict(FExceptions+1); | 348 | QAsciiDict<int> dict(FExceptions+1); |
345 | dict.setAutoDelete( true ); | 349 | dict.setAutoDelete( true ); |
346 | dict.insert( "description", new int(FDescription) ); | 350 | dict.insert( "description", new int(FDescription) ); |
347 | dict.insert( "location", new int(FLocation) ); | 351 | dict.insert( "location", new int(FLocation) ); |
348 | dict.insert( "categories", new int(FCategories) ); | 352 | dict.insert( "categories", new int(FCategories) ); |
349 | dict.insert( "uid", new int(FUid) ); | 353 | dict.insert( "uid", new int(FUid) ); |
350 | dict.insert( "type", new int(FType) ); | 354 | dict.insert( "type", new int(FType) ); |
351 | dict.insert( "alarm", new int(FAlarm) ); | 355 | dict.insert( "alarm", new int(FAlarm) ); |
352 | dict.insert( "sound", new int(FSound) ); | 356 | dict.insert( "sound", new int(FSound) ); |
353 | dict.insert( "rtype", new int(FRType) ); | 357 | dict.insert( "rtype", new int(FRType) ); |
354 | dict.insert( "rweekdays", new int(FRWeekdays) ); | 358 | dict.insert( "rweekdays", new int(FRWeekdays) ); |
355 | dict.insert( "rposition", new int(FRPosition) ); | 359 | dict.insert( "rposition", new int(FRPosition) ); |
356 | dict.insert( "rfreq", new int(FRFreq) ); | 360 | dict.insert( "rfreq", new int(FRFreq) ); |
357 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); | 361 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); |
358 | dict.insert( "enddt", new int(FREndDate) ); | 362 | dict.insert( "enddt", new int(FREndDate) ); |
359 | dict.insert( "start", new int(FRStart) ); | 363 | dict.insert( "start", new int(FRStart) ); |
360 | dict.insert( "end", new int(FREnd) ); | 364 | dict.insert( "end", new int(FREnd) ); |
361 | dict.insert( "note", new int(FNote) ); | 365 | dict.insert( "note", new int(FNote) ); |
362 | dict.insert( "created", new int(FCreated) ); | 366 | dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? |
363 | dict.insert( "recparent", new int(FRecParent) ); | 367 | dict.insert( "recparent", new int(FRecParent) ); |
364 | dict.insert( "recchildren", new int(FRecChildren) ); | 368 | dict.insert( "recchildren", new int(FRecChildren) ); |
365 | dict.insert( "exceptions", new int(FExceptions) ); | 369 | dict.insert( "exceptions", new int(FExceptions) ); |
366 | dict.insert( "timezone", new int(FTimeZone) ); | 370 | dict.insert( "timezone", new int(FTimeZone) ); |
367 | 371 | ||
368 | char* dt = (char*)map_addr; | 372 | char* dt = (char*)map_addr; |
369 | int len = attribute.st_size; | 373 | int len = attribute.st_size; |
370 | int i = 0; | 374 | int i = 0; |
371 | char* point; | 375 | char* point; |
372 | const char* collectionString = "<event "; | 376 | const char* collectionString = "<event "; |
373 | int strLen = ::strlen(collectionString); | 377 | int strLen = ::strlen(collectionString); |
374 | int *find; | 378 | int *find; |
375 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { | 379 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { |
376 | i = point -dt; | 380 | i = point -dt; |
377 | i+= strLen; | 381 | i+= strLen; |
378 | 382 | ||
379 | alarmTime = -1; | 383 | alarmTime = -1; |
380 | snd = 0; // silent | 384 | snd = 0; // silent |
381 | 385 | ||
382 | OEvent ev; | 386 | OEvent ev; |
383 | rec = 0; | 387 | rec = 0; |
384 | 388 | ||
385 | while ( TRUE ) { | 389 | while ( TRUE ) { |
386 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 390 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
387 | ++i; | 391 | ++i; |
388 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 392 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
389 | break; | 393 | break; |
390 | 394 | ||
391 | 395 | ||
392 | // we have another attribute, read it. | 396 | // we have another attribute, read it. |
393 | int j = i; | 397 | int j = i; |
394 | while ( j < len && dt[j] != '=' ) | 398 | while ( j < len && dt[j] != '=' ) |
395 | ++j; | 399 | ++j; |
396 | QCString attr( dt+i, j-i+1); | 400 | QCString attr( dt+i, j-i+1); |
397 | 401 | ||
398 | i = ++j; // skip = | 402 | i = ++j; // skip = |
399 | 403 | ||
400 | // find the start of quotes | 404 | // find the start of quotes |
401 | while ( i < len && dt[i] != '"' ) | 405 | while ( i < len && dt[i] != '"' ) |
402 | ++i; | 406 | ++i; |
403 | j = ++i; | 407 | j = ++i; |
404 | 408 | ||
405 | bool haveUtf = FALSE; | 409 | bool haveUtf = FALSE; |
406 | bool haveEnt = FALSE; | 410 | bool haveEnt = FALSE; |
407 | while ( j < len && dt[j] != '"' ) { | 411 | while ( j < len && dt[j] != '"' ) { |
408 | if ( ((unsigned char)dt[j]) > 0x7f ) | 412 | if ( ((unsigned char)dt[j]) > 0x7f ) |
409 | haveUtf = TRUE; | 413 | haveUtf = TRUE; |
410 | if ( dt[j] == '&' ) | 414 | if ( dt[j] == '&' ) |
411 | haveEnt = TRUE; | 415 | haveEnt = TRUE; |
412 | ++j; | 416 | ++j; |
413 | } | 417 | } |
414 | if ( i == j ) { | 418 | if ( i == j ) { |
415 | // empty value | 419 | // empty value |
416 | i = j + 1; | 420 | i = j + 1; |
417 | continue; | 421 | continue; |
418 | } | 422 | } |
419 | 423 | ||
420 | QCString value( dt+i, j-i+1 ); | 424 | QCString value( dt+i, j-i+1 ); |
421 | i = j + 1; | 425 | i = j + 1; |
422 | 426 | ||
423 | QString str = (haveUtf ? QString::fromUtf8( value ) | 427 | QString str = (haveUtf ? QString::fromUtf8( value ) |
424 | : QString::fromLatin1( value ) ); | 428 | : QString::fromLatin1( value ) ); |
425 | if ( haveEnt ) | 429 | if ( haveEnt ) |
426 | str = Qtopia::plainString( str ); | 430 | str = Qtopia::plainString( str ); |
427 | 431 | ||
428 | /* | 432 | /* |
429 | * add key + value | 433 | * add key + value |
430 | */ | 434 | */ |
431 | find = dict[attr.data()]; | 435 | find = dict[attr.data()]; |
432 | if (!find) | 436 | if (!find) |
433 | ev.setCustomField( attr, str ); | 437 | ev.setCustomField( attr, str ); |
434 | else { | 438 | else { |
435 | setField( ev, *find, str ); | 439 | setField( ev, *find, str ); |
436 | } | 440 | } |
437 | } | 441 | } |
438 | /* time to finalize */ | 442 | /* time to finalize */ |
439 | finalizeRecord( ev ); | 443 | finalizeRecord( ev ); |
440 | delete rec; | 444 | delete rec; |
441 | } | 445 | } |
442 | ::munmap(map_addr, attribute.st_size ); | 446 | ::munmap(map_addr, attribute.st_size ); |
443 | m_changed = false; // changed during add | 447 | m_changed = false; // changed during add |
444 | 448 | ||
445 | return true; | 449 | return true; |
446 | } | 450 | } |
451 | |||
452 | // FIXME: Use OEvent::fromMap() which makes this obsolete.. (eilers) | ||
447 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { | 453 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { |
448 | /* AllDay is alway in UTC */ | 454 | /* AllDay is alway in UTC */ |
449 | if ( ev.isAllDay() ) { | 455 | if ( ev.isAllDay() ) { |
450 | OTimeZone utc = OTimeZone::utc(); | 456 | OTimeZone utc = OTimeZone::utc(); |
451 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); | 457 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); |
452 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); | 458 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); |
453 | ev.setTimeZone( "UTC"); // make sure it is really utc | 459 | ev.setTimeZone( "UTC"); // make sure it is really utc |
454 | }else { | 460 | }else { |
455 | /* to current date time */ | 461 | /* to current date time */ |
456 | // qWarning(" Start is %d", start ); | 462 | // qWarning(" Start is %d", start ); |
457 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | 463 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); |
458 | QDateTime date = zone.toDateTime( start ); | 464 | QDateTime date = zone.toDateTime( start ); |
459 | qWarning(" Start is %s", date.toString().latin1() ); | 465 | qWarning(" Start is %s", date.toString().latin1() ); |
460 | ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); | 466 | ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); |
461 | 467 | ||
462 | date = zone.toDateTime( end ); | 468 | date = zone.toDateTime( end ); |
463 | ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); | 469 | ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); |
464 | } | 470 | } |
465 | if ( rec && rec->doesRecur() ) { | 471 | if ( rec && rec->doesRecur() ) { |
466 | OTimeZone utc = OTimeZone::utc(); | 472 | OTimeZone utc = OTimeZone::utc(); |
467 | ORecur recu( *rec ); // call copy c'tor; | 473 | ORecur recu( *rec ); // call copy c'tor; |
468 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); | 474 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); |
469 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); | 475 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); |
470 | recu.setStart( ev.startDateTime().date() ); | 476 | recu.setStart( ev.startDateTime().date() ); |
471 | ev.setRecurrence( recu ); | 477 | ev.setRecurrence( recu ); |
472 | } | 478 | } |
473 | 479 | ||
474 | if (alarmTime != -1 ) { | 480 | if (alarmTime != -1 ) { |
475 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); | 481 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); |
476 | OPimAlarm al( snd , dt ); | 482 | OPimAlarm al( snd , dt ); |
477 | ev.notifiers().add( al ); | 483 | ev.notifiers().add( al ); |
478 | } | 484 | } |
479 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { | 485 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { |
480 | qWarning("already contains assign uid"); | 486 | qWarning("already contains assign uid"); |
481 | ev.setUid( 1 ); | 487 | ev.setUid( 1 ); |
482 | } | 488 | } |
483 | qWarning("addind %d %s", ev.uid(), ev.description().latin1() ); | 489 | qWarning("addind %d %s", ev.uid(), ev.description().latin1() ); |
484 | if ( ev.hasRecurrence() ) | 490 | if ( ev.hasRecurrence() ) |
485 | m_rep.insert( ev.uid(), ev ); | 491 | m_rep.insert( ev.uid(), ev ); |
486 | else | 492 | else |
487 | m_raw.insert( ev.uid(), ev ); | 493 | m_raw.insert( ev.uid(), ev ); |
488 | 494 | ||
489 | } | 495 | } |
490 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { | 496 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { |
491 | // qWarning(" setting %s", value.latin1() ); | 497 | // qWarning(" setting %s", value.latin1() ); |
492 | switch( id ) { | 498 | switch( id ) { |
493 | case FDescription: | 499 | case FDescription: |
494 | e.setDescription( value ); | 500 | e.setDescription( value ); |
495 | break; | 501 | break; |
496 | case FLocation: | 502 | case FLocation: |
497 | e.setLocation( value ); | 503 | e.setLocation( value ); |
498 | break; | 504 | break; |
499 | case FCategories: | 505 | case FCategories: |
500 | e.setCategories( e.idsFromString( value ) ); | 506 | e.setCategories( e.idsFromString( value ) ); |
501 | break; | 507 | break; |
502 | case FUid: | 508 | case FUid: |
503 | e.setUid( value.toInt() ); | 509 | e.setUid( value.toInt() ); |
504 | break; | 510 | break; |
505 | case FType: | 511 | case FType: |
506 | if ( value == "AllDay" ) { | 512 | if ( value == "AllDay" ) { |
507 | e.setAllDay( true ); | 513 | e.setAllDay( true ); |
508 | e.setTimeZone( "UTC" ); | 514 | e.setTimeZone( "UTC" ); |
509 | } | 515 | } |
510 | break; | 516 | break; |
511 | case FAlarm: | 517 | case FAlarm: |
512 | alarmTime = value.toInt(); | 518 | alarmTime = value.toInt(); |
513 | break; | 519 | break; |
514 | case FSound: | 520 | case FSound: |
515 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; | 521 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; |
516 | break; | 522 | break; |
517 | // recurrence stuff | 523 | // recurrence stuff |
518 | case FRType: | 524 | case FRType: |
519 | if ( value == "Daily" ) | 525 | if ( value == "Daily" ) |
520 | recur()->setType( ORecur::Daily ); | 526 | recur()->setType( ORecur::Daily ); |
521 | else if ( value == "Weekly" ) | 527 | else if ( value == "Weekly" ) |
522 | recur()->setType( ORecur::Weekly); | 528 | recur()->setType( ORecur::Weekly); |
523 | else if ( value == "MonthlyDay" ) | 529 | else if ( value == "MonthlyDay" ) |
524 | recur()->setType( ORecur::MonthlyDay ); | 530 | recur()->setType( ORecur::MonthlyDay ); |
525 | else if ( value == "MonthlyDate" ) | 531 | else if ( value == "MonthlyDate" ) |
526 | recur()->setType( ORecur::MonthlyDate ); | 532 | recur()->setType( ORecur::MonthlyDate ); |
527 | else if ( value == "Yearly" ) | 533 | else if ( value == "Yearly" ) |
528 | recur()->setType( ORecur::Yearly ); | 534 | recur()->setType( ORecur::Yearly ); |
529 | else | 535 | else |
530 | recur()->setType( ORecur::NoRepeat ); | 536 | recur()->setType( ORecur::NoRepeat ); |
531 | break; | 537 | break; |
532 | case FRWeekdays: | 538 | case FRWeekdays: |
533 | recur()->setDays( value.toInt() ); | 539 | recur()->setDays( value.toInt() ); |
534 | break; | 540 | break; |
535 | case FRPosition: | 541 | case FRPosition: |
536 | recur()->setPosition( value.toInt() ); | 542 | recur()->setPosition( value.toInt() ); |
537 | break; | 543 | break; |
538 | case FRFreq: | 544 | case FRFreq: |
539 | recur()->setFrequency( value.toInt() ); | 545 | recur()->setFrequency( value.toInt() ); |
540 | break; | 546 | break; |
541 | case FRHasEndDate: | 547 | case FRHasEndDate: |
542 | recur()->setHasEndDate( value.toInt() ); | 548 | recur()->setHasEndDate( value.toInt() ); |
543 | break; | 549 | break; |
544 | case FREndDate: { | 550 | case FREndDate: { |
545 | rp_end = (time_t) value.toLong(); | 551 | rp_end = (time_t) value.toLong(); |
546 | break; | 552 | break; |
547 | } | 553 | } |
548 | case FRStart: { | 554 | case FRStart: { |
549 | start = (time_t) value.toLong(); | 555 | start = (time_t) value.toLong(); |
550 | break; | 556 | break; |
551 | } | 557 | } |
552 | case FREnd: { | 558 | case FREnd: { |
553 | end = ( (time_t) value.toLong() ); | 559 | end = ( (time_t) value.toLong() ); |
554 | break; | 560 | break; |
555 | } | 561 | } |
556 | case FNote: | 562 | case FNote: |
557 | e.setNote( value ); | 563 | e.setNote( value ); |
558 | break; | 564 | break; |
559 | case FCreated: | 565 | case FCreated: |
560 | created = value.toInt(); | 566 | created = value.toInt(); |
561 | break; | 567 | break; |
562 | case FRecParent: | 568 | case FRecParent: |
563 | e.setParent( value.toInt() ); | 569 | e.setParent( value.toInt() ); |
564 | break; | 570 | break; |
565 | case FRecChildren:{ | 571 | case FRecChildren:{ |
566 | QStringList list = QStringList::split(' ', value ); | 572 | QStringList list = QStringList::split(' ', value ); |
567 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | 573 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { |
568 | e.addChild( (*it).toInt() ); | 574 | e.addChild( (*it).toInt() ); |
569 | } | 575 | } |
570 | } | 576 | } |
571 | break; | 577 | break; |
572 | case FExceptions:{ | 578 | case FExceptions:{ |
573 | QStringList list = QStringList::split(' ', value ); | 579 | QStringList list = QStringList::split(' ', value ); |
574 | for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | 580 | for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { |
575 | QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); | 581 | QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); |
576 | qWarning("adding exception %s", date.toString().latin1() ); | 582 | qWarning("adding exception %s", date.toString().latin1() ); |
577 | recur()->exceptions().append( date ); | 583 | recur()->exceptions().append( date ); |
578 | } | 584 | } |
579 | } | 585 | } |
580 | break; | 586 | break; |
581 | case FTimeZone: | 587 | case FTimeZone: |
582 | if ( value != "None" ) | 588 | if ( value != "None" ) |
583 | e.setTimeZone( value ); | 589 | e.setTimeZone( value ); |
584 | break; | 590 | break; |
585 | default: | 591 | default: |
586 | break; | 592 | break; |
587 | } | 593 | } |
588 | } | 594 | } |
589 | QArray<int> ODateBookAccessBackend_XML::matchRegexp( const QRegExp &r ) const | 595 | QArray<int> ODateBookAccessBackend_XML::matchRegexp( const QRegExp &r ) const |
590 | { | 596 | { |
591 | QArray<int> m_currentQuery( m_raw.count()+ m_rep.count() ); | 597 | QArray<int> m_currentQuery( m_raw.count()+ m_rep.count() ); |
592 | uint arraycounter = 0; | 598 | uint arraycounter = 0; |
593 | QMap<int, OEvent>::ConstIterator it; | 599 | QMap<int, OEvent>::ConstIterator it; |
594 | 600 | ||
595 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) | 601 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) |
596 | if ( it.data().match( r ) ) | 602 | if ( it.data().match( r ) ) |
597 | m_currentQuery[arraycounter++] = it.data().uid(); | 603 | m_currentQuery[arraycounter++] = it.data().uid(); |
598 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) | 604 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) |
599 | if ( it.data().match( r ) ) | 605 | if ( it.data().match( r ) ) |
600 | m_currentQuery[arraycounter++] = it.data().uid(); | 606 | m_currentQuery[arraycounter++] = it.data().uid(); |
601 | 607 | ||
602 | // Shrink to fit.. | 608 | // Shrink to fit.. |
603 | m_currentQuery.resize(arraycounter); | 609 | m_currentQuery.resize(arraycounter); |
604 | 610 | ||
605 | return m_currentQuery; | 611 | return m_currentQuery; |
606 | } | 612 | } |
diff --git a/libopie/pim/oevent.cpp b/libopie/pim/oevent.cpp index 7bcf944..c916297 100644 --- a/libopie/pim/oevent.cpp +++ b/libopie/pim/oevent.cpp | |||
@@ -1,554 +1,681 @@ | |||
1 | #include <qshared.h> | 1 | #include <qshared.h> |
2 | #include <qarray.h> | ||
2 | 3 | ||
3 | #include <qpe/palmtopuidgen.h> | 4 | #include <qpe/palmtopuidgen.h> |
4 | #include <qpe/categories.h> | 5 | #include <qpe/categories.h> |
5 | #include <qpe/stringutil.h> | 6 | #include <qpe/stringutil.h> |
6 | 7 | ||
7 | #include "orecur.h" | 8 | #include "orecur.h" |
8 | #include "opimresolver.h" | 9 | #include "opimresolver.h" |
9 | #include "opimnotifymanager.h" | 10 | #include "opimnotifymanager.h" |
10 | 11 | ||
11 | #include "oevent.h" | 12 | #include "oevent.h" |
12 | 13 | ||
13 | int OCalendarHelper::week( const QDate& date) { | 14 | int OCalendarHelper::week( const QDate& date) { |
14 | // Calculates the week this date is in within that | 15 | // Calculates the week this date is in within that |
15 | // month. Equals the "row" is is in in the month view | 16 | // month. Equals the "row" is is in in the month view |
16 | int week = 1; | 17 | int week = 1; |
17 | QDate tmp( date.year(), date.month(), 1 ); | 18 | QDate tmp( date.year(), date.month(), 1 ); |
18 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) | 19 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) |
19 | ++week; | 20 | ++week; |
20 | 21 | ||
21 | week += ( date.day() - 1 ) / 7; | 22 | week += ( date.day() - 1 ) / 7; |
22 | 23 | ||
23 | return week; | 24 | return week; |
24 | } | 25 | } |
25 | int OCalendarHelper::ocurrence( const QDate& date) { | 26 | int OCalendarHelper::ocurrence( const QDate& date) { |
26 | // calculates the number of occurrances of this day of the | 27 | // calculates the number of occurrances of this day of the |
27 | // week till the given date (e.g 3rd Wednesday of the month) | 28 | // week till the given date (e.g 3rd Wednesday of the month) |
28 | return ( date.day() - 1 ) / 7 + 1; | 29 | return ( date.day() - 1 ) / 7 + 1; |
29 | } | 30 | } |
30 | int OCalendarHelper::dayOfWeek( char day ) { | 31 | int OCalendarHelper::dayOfWeek( char day ) { |
31 | int dayOfWeek = 1; | 32 | int dayOfWeek = 1; |
32 | char i = ORecur::MON; | 33 | char i = ORecur::MON; |
33 | while ( !( i & day ) && i <= ORecur::SUN ) { | 34 | while ( !( i & day ) && i <= ORecur::SUN ) { |
34 | i <<= 1; | 35 | i <<= 1; |
35 | ++dayOfWeek; | 36 | ++dayOfWeek; |
36 | } | 37 | } |
37 | return dayOfWeek; | 38 | return dayOfWeek; |
38 | } | 39 | } |
39 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { | 40 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { |
40 | return ( second.year() - first.year() ) * 12 + | 41 | return ( second.year() - first.year() ) * 12 + |
41 | second.month() - first.month(); | 42 | second.month() - first.month(); |
42 | } | 43 | } |
43 | 44 | ||
44 | struct OEvent::Data : public QShared { | 45 | struct OEvent::Data : public QShared { |
45 | Data() : QShared() { | 46 | Data() : QShared() { |
46 | child = 0; | 47 | child = 0; |
47 | recur = 0; | 48 | recur = 0; |
48 | manager = 0; | 49 | manager = 0; |
49 | isAllDay = false; | 50 | isAllDay = false; |
50 | parent = 0; | 51 | parent = 0; |
51 | } | 52 | } |
52 | ~Data() { | 53 | ~Data() { |
53 | delete manager; | 54 | delete manager; |
54 | delete recur; | 55 | delete recur; |
55 | } | 56 | } |
56 | QString description; | 57 | QString description; |
57 | QString location; | 58 | QString location; |
58 | OPimNotifyManager* manager; | 59 | OPimNotifyManager* manager; |
59 | ORecur* recur; | 60 | ORecur* recur; |
60 | QString note; | 61 | QString note; |
61 | QDateTime created; | 62 | QDateTime created; |
62 | QDateTime start; | 63 | QDateTime start; |
63 | QDateTime end; | 64 | QDateTime end; |
64 | bool isAllDay : 1; | 65 | bool isAllDay : 1; |
65 | QString timezone; | 66 | QString timezone; |
66 | QArray<int>* child; | 67 | QArray<int>* child; |
67 | int parent; | 68 | int parent; |
68 | }; | 69 | }; |
69 | 70 | ||
70 | OEvent::OEvent( int uid ) | 71 | OEvent::OEvent( int uid ) |
71 | : OPimRecord( uid ) { | 72 | : OPimRecord( uid ) { |
72 | data = new Data; | 73 | data = new Data; |
73 | } | 74 | } |
74 | OEvent::OEvent( const OEvent& ev) | 75 | OEvent::OEvent( const OEvent& ev) |
75 | : OPimRecord( ev ), data( ev.data ) | 76 | : OPimRecord( ev ), data( ev.data ) |
76 | { | 77 | { |
77 | data->ref(); | 78 | data->ref(); |
78 | } | 79 | } |
79 | OEvent::~OEvent() { | 80 | OEvent::~OEvent() { |
80 | if ( data->deref() ) { | 81 | if ( data->deref() ) { |
81 | delete data; | 82 | delete data; |
82 | data = 0; | 83 | data = 0; |
83 | } | 84 | } |
84 | } | 85 | } |
85 | OEvent& OEvent::operator=( const OEvent& ev) { | 86 | OEvent& OEvent::operator=( const OEvent& ev) { |
86 | if ( this == &ev ) return *this; | 87 | if ( this == &ev ) return *this; |
87 | 88 | ||
88 | OPimRecord::operator=( ev ); | 89 | OPimRecord::operator=( ev ); |
89 | ev.data->ref(); | 90 | ev.data->ref(); |
90 | deref(); | 91 | deref(); |
91 | data = ev.data; | 92 | data = ev.data; |
92 | 93 | ||
93 | 94 | ||
94 | return *this; | 95 | return *this; |
95 | } | 96 | } |
96 | QString OEvent::description()const { | 97 | QString OEvent::description()const { |
97 | return data->description; | 98 | return data->description; |
98 | } | 99 | } |
99 | void OEvent::setDescription( const QString& description ) { | 100 | void OEvent::setDescription( const QString& description ) { |
100 | changeOrModify(); | 101 | changeOrModify(); |
101 | data->description = description; | 102 | data->description = description; |
102 | } | 103 | } |
103 | void OEvent::setLocation( const QString& loc ) { | 104 | void OEvent::setLocation( const QString& loc ) { |
104 | changeOrModify(); | 105 | changeOrModify(); |
105 | data->location = loc; | 106 | data->location = loc; |
106 | } | 107 | } |
107 | QString OEvent::location()const { | 108 | QString OEvent::location()const { |
108 | return data->location; | 109 | return data->location; |
109 | } | 110 | } |
110 | OPimNotifyManager &OEvent::notifiers()const { | 111 | OPimNotifyManager &OEvent::notifiers()const { |
111 | // I hope we can skip the changeOrModify here | 112 | // I hope we can skip the changeOrModify here |
112 | // the notifier should take care of it | 113 | // the notifier should take care of it |
113 | // and OPimNotify is shared too | 114 | // and OPimNotify is shared too |
114 | if (!data->manager ) | 115 | if (!data->manager ) |
115 | data->manager = new OPimNotifyManager; | 116 | data->manager = new OPimNotifyManager; |
116 | 117 | ||
117 | return *data->manager; | 118 | return *data->manager; |
118 | } | 119 | } |
119 | bool OEvent::hasNotifiers()const { | 120 | bool OEvent::hasNotifiers()const { |
120 | if (!data->manager ) | 121 | if (!data->manager ) |
121 | return false; | 122 | return false; |
122 | if (data->manager->reminders().isEmpty() && | 123 | if (data->manager->reminders().isEmpty() && |
123 | data->manager->alarms().isEmpty() ) | 124 | data->manager->alarms().isEmpty() ) |
124 | return false; | 125 | return false; |
125 | 126 | ||
126 | return true; | 127 | return true; |
127 | } | 128 | } |
128 | ORecur OEvent::recurrence()const { | 129 | ORecur OEvent::recurrence()const { |
129 | if (!data->recur) | 130 | if (!data->recur) |
130 | data->recur = new ORecur; | 131 | data->recur = new ORecur; |
131 | 132 | ||
132 | return *data->recur; | 133 | return *data->recur; |
133 | } | 134 | } |
134 | void OEvent::setRecurrence( const ORecur& rec) { | 135 | void OEvent::setRecurrence( const ORecur& rec) { |
135 | changeOrModify(); | 136 | changeOrModify(); |
136 | if (data->recur ) | 137 | if (data->recur ) |
137 | (*data->recur) = rec; | 138 | (*data->recur) = rec; |
138 | else | 139 | else |
139 | data->recur = new ORecur( rec ); | 140 | data->recur = new ORecur( rec ); |
140 | } | 141 | } |
141 | bool OEvent::hasRecurrence()const { | 142 | bool OEvent::hasRecurrence()const { |
142 | if (!data->recur ) return false; | 143 | if (!data->recur ) return false; |
143 | return data->recur->doesRecur(); | 144 | return data->recur->doesRecur(); |
144 | } | 145 | } |
145 | QString OEvent::note()const { | 146 | QString OEvent::note()const { |
146 | return data->note; | 147 | return data->note; |
147 | } | 148 | } |
148 | void OEvent::setNote( const QString& note ) { | 149 | void OEvent::setNote( const QString& note ) { |
149 | changeOrModify(); | 150 | changeOrModify(); |
150 | data->note = note; | 151 | data->note = note; |
151 | } | 152 | } |
152 | QDateTime OEvent::createdDateTime()const { | 153 | QDateTime OEvent::createdDateTime()const { |
153 | return data->created; | 154 | return data->created; |
154 | } | 155 | } |
155 | void OEvent::setCreatedDateTime( const QDateTime& time ) { | 156 | void OEvent::setCreatedDateTime( const QDateTime& time ) { |
156 | changeOrModify(); | 157 | changeOrModify(); |
157 | data->created = time; | 158 | data->created = time; |
158 | } | 159 | } |
159 | QDateTime OEvent::startDateTime()const { | 160 | QDateTime OEvent::startDateTime()const { |
160 | if ( data->isAllDay ) | 161 | if ( data->isAllDay ) |
161 | return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); | 162 | return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); |
162 | return data->start; | 163 | return data->start; |
163 | } | 164 | } |
164 | QDateTime OEvent::startDateTimeInZone()const { | 165 | QDateTime OEvent::startDateTimeInZone()const { |
165 | /* if no timezone, or all day event or if the current and this timeZone match... */ | 166 | /* if no timezone, or all day event or if the current and this timeZone match... */ |
166 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); | 167 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); |
167 | 168 | ||
168 | OTimeZone zone(data->timezone ); | 169 | OTimeZone zone(data->timezone ); |
169 | return zone.toDateTime( data->start, OTimeZone::current() ); | 170 | return zone.toDateTime( data->start, OTimeZone::current() ); |
170 | } | 171 | } |
171 | void OEvent::setStartDateTime( const QDateTime& dt ) { | 172 | void OEvent::setStartDateTime( const QDateTime& dt ) { |
172 | changeOrModify(); | 173 | changeOrModify(); |
173 | data->start = dt; | 174 | data->start = dt; |
174 | } | 175 | } |
175 | QDateTime OEvent::endDateTime()const { | 176 | QDateTime OEvent::endDateTime()const { |
176 | /* | 177 | /* |
177 | * if all Day event the end time needs | 178 | * if all Day event the end time needs |
178 | * to be on the same day as the start | 179 | * to be on the same day as the start |
179 | */ | 180 | */ |
180 | if ( data->isAllDay ) | 181 | if ( data->isAllDay ) |
181 | return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); | 182 | return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); |
182 | return data->end; | 183 | return data->end; |
183 | } | 184 | } |
184 | QDateTime OEvent::endDateTimeInZone()const { | 185 | QDateTime OEvent::endDateTimeInZone()const { |
185 | /* if no timezone, or all day event or if the current and this timeZone match... */ | 186 | /* if no timezone, or all day event or if the current and this timeZone match... */ |
186 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); | 187 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); |
187 | 188 | ||
188 | OTimeZone zone(data->timezone ); | 189 | OTimeZone zone(data->timezone ); |
189 | return zone.toDateTime( data->end, OTimeZone::current() ); | 190 | return zone.toDateTime( data->end, OTimeZone::current() ); |
190 | } | 191 | } |
191 | void OEvent::setEndDateTime( const QDateTime& dt ) { | 192 | void OEvent::setEndDateTime( const QDateTime& dt ) { |
192 | changeOrModify(); | 193 | changeOrModify(); |
193 | data->end = dt; | 194 | data->end = dt; |
194 | } | 195 | } |
195 | bool OEvent::isMultipleDay()const { | 196 | bool OEvent::isMultipleDay()const { |
196 | return data->end.date().day() - data->start.date().day(); | 197 | return data->end.date().day() - data->start.date().day(); |
197 | } | 198 | } |
198 | bool OEvent::isAllDay()const { | 199 | bool OEvent::isAllDay()const { |
199 | return data->isAllDay; | 200 | return data->isAllDay; |
200 | } | 201 | } |
201 | void OEvent::setAllDay( bool allDay ) { | 202 | void OEvent::setAllDay( bool allDay ) { |
202 | changeOrModify(); | 203 | changeOrModify(); |
203 | data->isAllDay = allDay; | 204 | data->isAllDay = allDay; |
204 | if (allDay ) data->timezone = "UTC"; | 205 | if (allDay ) data->timezone = "UTC"; |
205 | } | 206 | } |
206 | void OEvent::setTimeZone( const QString& tz ) { | 207 | void OEvent::setTimeZone( const QString& tz ) { |
207 | changeOrModify(); | 208 | changeOrModify(); |
208 | data->timezone = tz; | 209 | data->timezone = tz; |
209 | } | 210 | } |
210 | QString OEvent::timeZone()const { | 211 | QString OEvent::timeZone()const { |
211 | if (data->isAllDay ) return QString::fromLatin1("UTC"); | 212 | if (data->isAllDay ) return QString::fromLatin1("UTC"); |
212 | return data->timezone; | 213 | return data->timezone; |
213 | } | 214 | } |
214 | bool OEvent::match( const QRegExp& re )const { | 215 | bool OEvent::match( const QRegExp& re )const { |
215 | if ( re.match( data->description ) != -1 ){ | 216 | if ( re.match( data->description ) != -1 ){ |
216 | setLastHitField( Qtopia::DatebookDescription ); | 217 | setLastHitField( Qtopia::DatebookDescription ); |
217 | return true; | 218 | return true; |
218 | } | 219 | } |
219 | if ( re.match( data->note ) != -1 ){ | 220 | if ( re.match( data->note ) != -1 ){ |
220 | setLastHitField( Qtopia::Note ); | 221 | setLastHitField( Qtopia::Note ); |
221 | return true; | 222 | return true; |
222 | } | 223 | } |
223 | if ( re.match( data->location ) != -1 ){ | 224 | if ( re.match( data->location ) != -1 ){ |
224 | setLastHitField( Qtopia::Location ); | 225 | setLastHitField( Qtopia::Location ); |
225 | return true; | 226 | return true; |
226 | } | 227 | } |
227 | if ( re.match( data->start.toString() ) != -1 ){ | 228 | if ( re.match( data->start.toString() ) != -1 ){ |
228 | setLastHitField( Qtopia::StartDateTime ); | 229 | setLastHitField( Qtopia::StartDateTime ); |
229 | return true; | 230 | return true; |
230 | } | 231 | } |
231 | if ( re.match( data->end.toString() ) != -1 ){ | 232 | if ( re.match( data->end.toString() ) != -1 ){ |
232 | setLastHitField( Qtopia::EndDateTime ); | 233 | setLastHitField( Qtopia::EndDateTime ); |
233 | return true; | 234 | return true; |
234 | } | 235 | } |
235 | return false; | 236 | return false; |
236 | } | 237 | } |
237 | QString OEvent::toRichText()const { | 238 | QString OEvent::toRichText()const { |
238 | QString text, value; | 239 | QString text, value; |
239 | 240 | ||
240 | // description | 241 | // description |
241 | text += "<b><h3><img src=\"datebook/DateBook\">"; | 242 | text += "<b><h3><img src=\"datebook/DateBook\">"; |
242 | if ( !description().isEmpty() ) { | 243 | if ( !description().isEmpty() ) { |
243 | text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "" ); | 244 | text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "" ); |
244 | } | 245 | } |
245 | text += "</h3></b><br><hr><br>"; | 246 | text += "</h3></b><br><hr><br>"; |
246 | 247 | ||
247 | // location | 248 | // location |
248 | if ( !(value = location()).isEmpty() ) { | 249 | if ( !(value = location()).isEmpty() ) { |
249 | text += "<b>" + QObject::tr( "Location:" ) + "</b> "; | 250 | text += "<b>" + QObject::tr( "Location:" ) + "</b> "; |
250 | text += Qtopia::escapeString(value) + "<br>"; | 251 | text += Qtopia::escapeString(value) + "<br>"; |
251 | } | 252 | } |
252 | 253 | ||
253 | // all day event | 254 | // all day event |
254 | if ( isAllDay() ) { | 255 | if ( isAllDay() ) { |
255 | text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>"; | 256 | text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>"; |
256 | } | 257 | } |
257 | // multiple day event | 258 | // multiple day event |
258 | else if ( isMultipleDay () ) { | 259 | else if ( isMultipleDay () ) { |
259 | text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>"; | 260 | text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>"; |
260 | } | 261 | } |
261 | // start & end times | 262 | // start & end times |
262 | else { | 263 | else { |
263 | // start time | 264 | // start time |
264 | if ( startDateTime().isValid() ) { | 265 | if ( startDateTime().isValid() ) { |
265 | text += "<b>" + QObject::tr( "Start:") + "</b> "; | 266 | text += "<b>" + QObject::tr( "Start:") + "</b> "; |
266 | text += Qtopia::escapeString(startDateTime().toString() ). | 267 | text += Qtopia::escapeString(startDateTime().toString() ). |
267 | replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; | 268 | replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; |
268 | } | 269 | } |
269 | 270 | ||
270 | // end time | 271 | // end time |
271 | if ( endDateTime().isValid() ) { | 272 | if ( endDateTime().isValid() ) { |
272 | text += "<b>" + QObject::tr( "End:") + "</b> "; | 273 | text += "<b>" + QObject::tr( "End:") + "</b> "; |
273 | text += Qtopia::escapeString(endDateTime().toString() ). | 274 | text += Qtopia::escapeString(endDateTime().toString() ). |
274 | replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; | 275 | replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; |
275 | } | 276 | } |
276 | } | 277 | } |
277 | 278 | ||
278 | // categories | 279 | // categories |
279 | if ( categoryNames("Calendar").count() ){ | 280 | if ( categoryNames("Calendar").count() ){ |
280 | text += "<b>" + QObject::tr( "Category:") + "</b> "; | 281 | text += "<b>" + QObject::tr( "Category:") + "</b> "; |
281 | text += categoryNames("Calendar").join(", "); | 282 | text += categoryNames("Calendar").join(", "); |
282 | text += "<br>"; | 283 | text += "<br>"; |
283 | } | 284 | } |
284 | 285 | ||
285 | //notes | 286 | //notes |
286 | if ( !note().isEmpty() ) { | 287 | if ( !note().isEmpty() ) { |
287 | text += "<b>" + QObject::tr( "Note:") + "</b><br>"; | 288 | text += "<b>" + QObject::tr( "Note:") + "</b><br>"; |
288 | text += note(); | 289 | text += note(); |
289 | // text += Qtopia::escapeString(note() ). | 290 | // text += Qtopia::escapeString(note() ). |
290 | // replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; | 291 | // replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; |
291 | } | 292 | } |
292 | return text; | 293 | return text; |
293 | } | 294 | } |
294 | QString OEvent::toShortText()const { | 295 | QString OEvent::toShortText()const { |
295 | QString text; | 296 | QString text; |
296 | text += QString::number( startDateTime().date().day() ); | 297 | text += QString::number( startDateTime().date().day() ); |
297 | text += "."; | 298 | text += "."; |
298 | text += QString::number( startDateTime().date().month() ); | 299 | text += QString::number( startDateTime().date().month() ); |
299 | text += "."; | 300 | text += "."; |
300 | text += QString::number( startDateTime().date().year() ); | 301 | text += QString::number( startDateTime().date().year() ); |
301 | text += " "; | 302 | text += " "; |
302 | text += QString::number( startDateTime().time().hour() ); | 303 | text += QString::number( startDateTime().time().hour() ); |
303 | text += ":"; | 304 | text += ":"; |
304 | text += QString::number( startDateTime().time().minute() ); | 305 | text += QString::number( startDateTime().time().minute() ); |
305 | text += " - "; | 306 | text += " - "; |
306 | text += description(); | 307 | text += description(); |
307 | return text; | 308 | return text; |
308 | } | 309 | } |
309 | QString OEvent::type()const { | 310 | QString OEvent::type()const { |
310 | return QString::fromLatin1("OEvent"); | 311 | return QString::fromLatin1("OEvent"); |
311 | } | 312 | } |
312 | QString OEvent::recordField( int /*id */ )const { | 313 | QString OEvent::recordField( int /*id */ )const { |
313 | return QString::null; | 314 | return QString::null; |
314 | } | 315 | } |
315 | int OEvent::rtti() { | 316 | int OEvent::rtti() { |
316 | return OPimResolver::DateBook; | 317 | return OPimResolver::DateBook; |
317 | } | 318 | } |
318 | bool OEvent::loadFromStream( QDataStream& ) { | 319 | bool OEvent::loadFromStream( QDataStream& ) { |
319 | return true; | 320 | return true; |
320 | } | 321 | } |
321 | bool OEvent::saveToStream( QDataStream& )const { | 322 | bool OEvent::saveToStream( QDataStream& )const { |
322 | return true; | 323 | return true; |
323 | } | 324 | } |
324 | void OEvent::changeOrModify() { | 325 | void OEvent::changeOrModify() { |
325 | if ( data->count != 1 ) { | 326 | if ( data->count != 1 ) { |
326 | data->deref(); | 327 | data->deref(); |
327 | Data* d2 = new Data; | 328 | Data* d2 = new Data; |
328 | d2->description = data->description; | 329 | d2->description = data->description; |
329 | d2->location = data->location; | 330 | d2->location = data->location; |
330 | 331 | ||
331 | if (data->manager ) | 332 | if (data->manager ) |
332 | d2->manager = new OPimNotifyManager( *data->manager ); | 333 | d2->manager = new OPimNotifyManager( *data->manager ); |
333 | 334 | ||
334 | if ( data->recur ) | 335 | if ( data->recur ) |
335 | d2->recur = new ORecur( *data->recur ); | 336 | d2->recur = new ORecur( *data->recur ); |
336 | 337 | ||
337 | d2->note = data->note; | 338 | d2->note = data->note; |
338 | d2->created = data->created; | 339 | d2->created = data->created; |
339 | d2->start = data->start; | 340 | d2->start = data->start; |
340 | d2->end = data->end; | 341 | d2->end = data->end; |
341 | d2->isAllDay = data->isAllDay; | 342 | d2->isAllDay = data->isAllDay; |
342 | d2->timezone = data->timezone; | 343 | d2->timezone = data->timezone; |
343 | d2->parent = data->parent; | 344 | d2->parent = data->parent; |
344 | 345 | ||
345 | if ( data->child ) { | 346 | if ( data->child ) { |
346 | d2->child = new QArray<int>( *data->child ); | 347 | d2->child = new QArray<int>( *data->child ); |
347 | d2->child->detach(); | 348 | d2->child->detach(); |
348 | } | 349 | } |
349 | 350 | ||
350 | data = d2; | 351 | data = d2; |
351 | } | 352 | } |
352 | } | 353 | } |
353 | void OEvent::deref() { | 354 | void OEvent::deref() { |
354 | if ( data->deref() ) { | 355 | if ( data->deref() ) { |
355 | delete data; | 356 | delete data; |
356 | data = 0; | 357 | data = 0; |
357 | } | 358 | } |
358 | } | 359 | } |
359 | // FIXME | 360 | // Exporting Event data to map. Using the same |
361 | // encoding as ODateBookAccessBackend_xml does.. | ||
362 | // Thus, we could remove the stuff there and use this | ||
363 | // for it and for all other places.. | ||
364 | // Encoding should happen at one place, only ! (eilers) | ||
360 | QMap<int, QString> OEvent::toMap()const { | 365 | QMap<int, QString> OEvent::toMap()const { |
361 | return QMap<int, QString>(); | 366 | QMap<int, QString> retMap; |
367 | |||
368 | retMap.insert( OEvent::FUid, QString::number( uid() ) ); | ||
369 | retMap.insert( OEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) )); | ||
370 | retMap.insert( OEvent::FDescription, Qtopia::escapeString( description() ) ); | ||
371 | retMap.insert( OEvent::FLocation, Qtopia::escapeString( location() ) ); | ||
372 | retMap.insert( OEvent::FType, isAllDay() ? "AllDay" : "" ); | ||
373 | OPimAlarm alarm = notifiers().alarms()[0]; | ||
374 | retMap.insert( OEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); | ||
375 | retMap.insert( OEvent::FSound, (alarm.sound() == OPimAlarm::Loud) ? "loud" : "silent" ); | ||
376 | |||
377 | OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); | ||
378 | retMap.insert( OEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OTimeZone::utc() ) ) ) ); | ||
379 | retMap.insert( OEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OTimeZone::utc() ) ) ) ); | ||
380 | retMap.insert( OEvent::FNote, Qtopia::escapeString( note() ) ); | ||
381 | retMap.insert( OEvent::FTimeZone, timeZone().isEmpty() ? "None" : timeZone() ); | ||
382 | if( parent() ) | ||
383 | retMap.insert( OEvent::FRecParent, QString::number( parent() ) ); | ||
384 | if( children().count() ){ | ||
385 | QArray<int> childr = children(); | ||
386 | QString buf; | ||
387 | for ( uint i = 0; i < childr.count(); i++ ) { | ||
388 | if ( i != 0 ) buf += " "; | ||
389 | buf += QString::number( childr[i] ); | ||
390 | } | ||
391 | retMap.insert( OEvent::FRecChildren, buf ); | ||
392 | } | ||
393 | |||
394 | // Add recurrence stuff | ||
395 | if( hasRecurrence() ){ | ||
396 | ORecur recur = recurrence(); | ||
397 | QMap<int, QString> recFields = recur.toMap(); | ||
398 | retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); | ||
399 | retMap.insert( OEvent::FRWeekdays, recFields[ORecur::RWeekdays] ); | ||
400 | retMap.insert( OEvent::FRPosition, recFields[ORecur::RPosition] ); | ||
401 | retMap.insert( OEvent::FRFreq, recFields[ORecur::RFreq] ); | ||
402 | retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] ); | ||
403 | retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] ); | ||
404 | retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] ); | ||
405 | retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] ); | ||
406 | } | ||
407 | |||
408 | return retMap; | ||
409 | } | ||
410 | |||
411 | void OEvent::fromMap( const QMap<int, QString>& map ) | ||
412 | { | ||
413 | |||
414 | // We just want to set the UID if it is really stored. | ||
415 | if ( !map[OEvent::FUid].isEmpty() ) | ||
416 | setUid( map[OEvent::FUid].toInt() ); | ||
417 | |||
418 | setCategories( idsFromString( map[OEvent::FCategories] ) ); | ||
419 | setDescription( map[OEvent::FDescription] ); | ||
420 | setLocation( map[OEvent::FLocation] ); | ||
421 | |||
422 | if ( map[OEvent::FType] == "AllDay" ) | ||
423 | setAllDay( true ); | ||
424 | else | ||
425 | setAllDay( false ); | ||
426 | |||
427 | int alarmTime = -1; | ||
428 | if( !map[OEvent::FAlarm].isEmpty() ) | ||
429 | alarmTime = map[OEvent::FAlarm].toInt(); | ||
430 | |||
431 | int sound = ( ( map[OEvent::FSound] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent ); | ||
432 | if ( ( alarmTime != -1 ) ){ | ||
433 | QDateTime dt = startDateTime().addSecs( -1*alarmTime*60 ); | ||
434 | OPimAlarm al( sound , dt ); | ||
435 | notifiers().add( al ); | ||
436 | } | ||
437 | if ( !map[OEvent::FTimeZone].isEmpty() && ( map[OEvent::FTimeZone] != "None" ) ){ | ||
438 | setTimeZone( map[OEvent::FTimeZone] ); | ||
439 | } | ||
440 | |||
441 | time_t start = (time_t) map[OEvent::FStart].toLong(); | ||
442 | time_t end = (time_t) map[OEvent::FEnd].toLong(); | ||
443 | |||
444 | /* AllDay is always in UTC */ | ||
445 | if ( isAllDay() ) { | ||
446 | OTimeZone utc = OTimeZone::utc(); | ||
447 | setStartDateTime( utc.fromUTCDateTime( start ) ); | ||
448 | setEndDateTime ( utc.fromUTCDateTime( end ) ); | ||
449 | setTimeZone( "UTC"); // make sure it is really utc | ||
450 | }else { | ||
451 | /* to current date time */ | ||
452 | // qWarning(" Start is %d", start ); | ||
453 | OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); | ||
454 | QDateTime date = zone.toDateTime( start ); | ||
455 | qWarning(" Start is %s", date.toString().latin1() ); | ||
456 | setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); | ||
457 | |||
458 | date = zone.toDateTime( end ); | ||
459 | setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); | ||
460 | } | ||
461 | |||
462 | if ( !map[OEvent::FRecParent].isEmpty() ) | ||
463 | setParent( map[OEvent::FRecParent].toInt() ); | ||
464 | |||
465 | if ( !map[OEvent::FRecChildren].isEmpty() ){ | ||
466 | QStringList list = QStringList::split(' ', map[OEvent::FRecChildren] ); | ||
467 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | ||
468 | addChild( (*it).toInt() ); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | // Fill recurrence stuff and put it directly into the ORecur-Object using fromMap.. | ||
473 | if( !map[OEvent::FRType].isEmpty() ){ | ||
474 | QMap<int, QString> recFields; | ||
475 | recFields.insert( ORecur::RType, map[OEvent::FRType] ); | ||
476 | recFields.insert( ORecur::RWeekdays, map[OEvent::FRWeekdays] ); | ||
477 | recFields.insert( ORecur::RPosition, map[OEvent::FRPosition] ); | ||
478 | recFields.insert( ORecur::RFreq, map[OEvent::FRFreq] ); | ||
479 | recFields.insert( ORecur::RHasEndDate, map[OEvent::FRHasEndDate] ); | ||
480 | recFields.insert( ORecur::EndDate, map[OEvent::FREndDate] ); | ||
481 | recFields.insert( ORecur::Created, map[OEvent::FRCreated] ); | ||
482 | recFields.insert( ORecur::Exceptions, map[OEvent::FRExceptions] ); | ||
483 | ORecur recur( recFields ); | ||
484 | setRecurrence( recur ); | ||
485 | } | ||
486 | |||
362 | } | 487 | } |
488 | |||
489 | |||
363 | int OEvent::parent()const { | 490 | int OEvent::parent()const { |
364 | return data->parent; | 491 | return data->parent; |
365 | } | 492 | } |
366 | void OEvent::setParent( int uid ) { | 493 | void OEvent::setParent( int uid ) { |
367 | changeOrModify(); | 494 | changeOrModify(); |
368 | data->parent = uid; | 495 | data->parent = uid; |
369 | } | 496 | } |
370 | QArray<int> OEvent::children() const{ | 497 | QArray<int> OEvent::children() const{ |
371 | if (!data->child) return QArray<int>(); | 498 | if (!data->child) return QArray<int>(); |
372 | else | 499 | else |
373 | return data->child->copy(); | 500 | return data->child->copy(); |
374 | } | 501 | } |
375 | void OEvent::setChildren( const QArray<int>& arr ) { | 502 | void OEvent::setChildren( const QArray<int>& arr ) { |
376 | changeOrModify(); | 503 | changeOrModify(); |
377 | if (data->child) delete data->child; | 504 | if (data->child) delete data->child; |
378 | 505 | ||
379 | data->child = new QArray<int>( arr ); | 506 | data->child = new QArray<int>( arr ); |
380 | data->child->detach(); | 507 | data->child->detach(); |
381 | } | 508 | } |
382 | void OEvent::addChild( int uid ) { | 509 | void OEvent::addChild( int uid ) { |
383 | changeOrModify(); | 510 | changeOrModify(); |
384 | if (!data->child ) { | 511 | if (!data->child ) { |
385 | data->child = new QArray<int>(1); | 512 | data->child = new QArray<int>(1); |
386 | (*data->child)[0] = uid; | 513 | (*data->child)[0] = uid; |
387 | }else{ | 514 | }else{ |
388 | int count = data->child->count(); | 515 | int count = data->child->count(); |
389 | data->child->resize( count + 1 ); | 516 | data->child->resize( count + 1 ); |
390 | (*data->child)[count] = uid; | 517 | (*data->child)[count] = uid; |
391 | } | 518 | } |
392 | } | 519 | } |
393 | void OEvent::removeChild( int uid ) { | 520 | void OEvent::removeChild( int uid ) { |
394 | if (!data->child || !data->child->contains( uid ) ) return; | 521 | if (!data->child || !data->child->contains( uid ) ) return; |
395 | changeOrModify(); | 522 | changeOrModify(); |
396 | QArray<int> newAr( data->child->count() - 1 ); | 523 | QArray<int> newAr( data->child->count() - 1 ); |
397 | int j = 0; | 524 | int j = 0; |
398 | uint count = data->child->count(); | 525 | uint count = data->child->count(); |
399 | for ( uint i = 0; i < count; i++ ) { | 526 | for ( uint i = 0; i < count; i++ ) { |
400 | if ( (*data->child)[i] != uid ) { | 527 | if ( (*data->child)[i] != uid ) { |
401 | newAr[j] = (*data->child)[i]; | 528 | newAr[j] = (*data->child)[i]; |
402 | j++; | 529 | j++; |
403 | } | 530 | } |
404 | } | 531 | } |
405 | (*data->child) = newAr; | 532 | (*data->child) = newAr; |
406 | } | 533 | } |
407 | struct OEffectiveEvent::Data : public QShared { | 534 | struct OEffectiveEvent::Data : public QShared { |
408 | Data() : QShared() { | 535 | Data() : QShared() { |
409 | } | 536 | } |
410 | OEvent event; | 537 | OEvent event; |
411 | QDate date; | 538 | QDate date; |
412 | QTime start, end; | 539 | QTime start, end; |
413 | QDate startDate, endDate; | 540 | QDate startDate, endDate; |
414 | bool dates : 1; | 541 | bool dates : 1; |
415 | }; | 542 | }; |
416 | 543 | ||
417 | OEffectiveEvent::OEffectiveEvent() { | 544 | OEffectiveEvent::OEffectiveEvent() { |
418 | data = new Data; | 545 | data = new Data; |
419 | data->date = QDate::currentDate(); | 546 | data->date = QDate::currentDate(); |
420 | data->start = data->end = QTime::currentTime(); | 547 | data->start = data->end = QTime::currentTime(); |
421 | data->dates = false; | 548 | data->dates = false; |
422 | } | 549 | } |
423 | OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, | 550 | OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, |
424 | Position pos ) { | 551 | Position pos ) { |
425 | data = new Data; | 552 | data = new Data; |
426 | data->event = ev; | 553 | data->event = ev; |
427 | data->date = startDate; | 554 | data->date = startDate; |
428 | if ( pos & Start ) | 555 | if ( pos & Start ) |
429 | data->start = ev.startDateTime().time(); | 556 | data->start = ev.startDateTime().time(); |
430 | else | 557 | else |
431 | data->start = QTime( 0, 0, 0 ); | 558 | data->start = QTime( 0, 0, 0 ); |
432 | 559 | ||
433 | if ( pos & End ) | 560 | if ( pos & End ) |
434 | data->end = ev.endDateTime().time(); | 561 | data->end = ev.endDateTime().time(); |
435 | else | 562 | else |
436 | data->end = QTime( 23, 59, 59 ); | 563 | data->end = QTime( 23, 59, 59 ); |
437 | 564 | ||
438 | data->dates = false; | 565 | data->dates = false; |
439 | } | 566 | } |
440 | OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { | 567 | OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { |
441 | data = ev.data; | 568 | data = ev.data; |
442 | data->ref(); | 569 | data->ref(); |
443 | } | 570 | } |
444 | OEffectiveEvent::~OEffectiveEvent() { | 571 | OEffectiveEvent::~OEffectiveEvent() { |
445 | if ( data->deref() ) { | 572 | if ( data->deref() ) { |
446 | delete data; | 573 | delete data; |
447 | data = 0; | 574 | data = 0; |
448 | } | 575 | } |
449 | } | 576 | } |
450 | OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { | 577 | OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { |
451 | if ( *this == ev ) return *this; | 578 | if ( *this == ev ) return *this; |
452 | 579 | ||
453 | ev.data->ref(); | 580 | ev.data->ref(); |
454 | deref(); | 581 | deref(); |
455 | data = ev.data; | 582 | data = ev.data; |
456 | 583 | ||
457 | return *this; | 584 | return *this; |
458 | } | 585 | } |
459 | 586 | ||
460 | void OEffectiveEvent::setStartTime( const QTime& ti) { | 587 | void OEffectiveEvent::setStartTime( const QTime& ti) { |
461 | changeOrModify(); | 588 | changeOrModify(); |
462 | data->start = ti; | 589 | data->start = ti; |
463 | } | 590 | } |
464 | void OEffectiveEvent::setEndTime( const QTime& en) { | 591 | void OEffectiveEvent::setEndTime( const QTime& en) { |
465 | changeOrModify(); | 592 | changeOrModify(); |
466 | data->end = en; | 593 | data->end = en; |
467 | } | 594 | } |
468 | void OEffectiveEvent::setEvent( const OEvent& ev) { | 595 | void OEffectiveEvent::setEvent( const OEvent& ev) { |
469 | changeOrModify(); | 596 | changeOrModify(); |
470 | data->event = ev; | 597 | data->event = ev; |
471 | } | 598 | } |
472 | void OEffectiveEvent::setDate( const QDate& da) { | 599 | void OEffectiveEvent::setDate( const QDate& da) { |
473 | changeOrModify(); | 600 | changeOrModify(); |
474 | data->date = da; | 601 | data->date = da; |
475 | } | 602 | } |
476 | void OEffectiveEvent::setEffectiveDates( const QDate& from, | 603 | void OEffectiveEvent::setEffectiveDates( const QDate& from, |
477 | const QDate& to ) { | 604 | const QDate& to ) { |
478 | if (!from.isValid() ) { | 605 | if (!from.isValid() ) { |
479 | data->dates = false; | 606 | data->dates = false; |
480 | return; | 607 | return; |
481 | } | 608 | } |
482 | 609 | ||
483 | data->startDate = from; | 610 | data->startDate = from; |
484 | data->endDate = to; | 611 | data->endDate = to; |
485 | } | 612 | } |
486 | QString OEffectiveEvent::description()const { | 613 | QString OEffectiveEvent::description()const { |
487 | return data->event.description(); | 614 | return data->event.description(); |
488 | } | 615 | } |
489 | QString OEffectiveEvent::location()const { | 616 | QString OEffectiveEvent::location()const { |
490 | return data->event.location(); | 617 | return data->event.location(); |
491 | } | 618 | } |
492 | QString OEffectiveEvent::note()const { | 619 | QString OEffectiveEvent::note()const { |
493 | return data->event.note(); | 620 | return data->event.note(); |
494 | } | 621 | } |
495 | OEvent OEffectiveEvent::event()const { | 622 | OEvent OEffectiveEvent::event()const { |
496 | return data->event; | 623 | return data->event; |
497 | } | 624 | } |
498 | QTime OEffectiveEvent::startTime()const { | 625 | QTime OEffectiveEvent::startTime()const { |
499 | return data->start; | 626 | return data->start; |
500 | } | 627 | } |
501 | QTime OEffectiveEvent::endTime()const { | 628 | QTime OEffectiveEvent::endTime()const { |
502 | return data->end; | 629 | return data->end; |
503 | } | 630 | } |
504 | QDate OEffectiveEvent::date()const { | 631 | QDate OEffectiveEvent::date()const { |
505 | return data->date; | 632 | return data->date; |
506 | } | 633 | } |
507 | int OEffectiveEvent::length()const { | 634 | int OEffectiveEvent::length()const { |
508 | return (data->end.hour() * 60 - data->start.hour() * 60) | 635 | return (data->end.hour() * 60 - data->start.hour() * 60) |
509 | + QABS(data->start.minute() - data->end.minute() ); | 636 | + QABS(data->start.minute() - data->end.minute() ); |
510 | } | 637 | } |
511 | int OEffectiveEvent::size()const { | 638 | int OEffectiveEvent::size()const { |
512 | return ( data->end.hour() - data->start.hour() ) * 3600 | 639 | return ( data->end.hour() - data->start.hour() ) * 3600 |
513 | + (data->end.minute() - data->start.minute() * 60 | 640 | + (data->end.minute() - data->start.minute() * 60 |
514 | + data->end.second() - data->start.second() ); | 641 | + data->end.second() - data->start.second() ); |
515 | } | 642 | } |
516 | QDate OEffectiveEvent::startDate()const { | 643 | QDate OEffectiveEvent::startDate()const { |
517 | if ( data->dates ) | 644 | if ( data->dates ) |
518 | return data->startDate; | 645 | return data->startDate; |
519 | else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer | 646 | else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer |
520 | return data->date; | 647 | return data->date; |
521 | else | 648 | else |
522 | return data->event.startDateTime().date(); | 649 | return data->event.startDateTime().date(); |
523 | } | 650 | } |
524 | QDate OEffectiveEvent::endDate()const { | 651 | QDate OEffectiveEvent::endDate()const { |
525 | if ( data->dates ) | 652 | if ( data->dates ) |
526 | return data->endDate; | 653 | return data->endDate; |
527 | else if ( data->event.hasRecurrence() ) | 654 | else if ( data->event.hasRecurrence() ) |
528 | return data->date; | 655 | return data->date; |
529 | else | 656 | else |
530 | return data->event.endDateTime().date(); | 657 | return data->event.endDateTime().date(); |
531 | } | 658 | } |
532 | void OEffectiveEvent::deref() { | 659 | void OEffectiveEvent::deref() { |
533 | if ( data->deref() ) { | 660 | if ( data->deref() ) { |
534 | delete data; | 661 | delete data; |
535 | data = 0; | 662 | data = 0; |
536 | } | 663 | } |
537 | } | 664 | } |
538 | void OEffectiveEvent::changeOrModify() { | 665 | void OEffectiveEvent::changeOrModify() { |
539 | if ( data->count != 1 ) { | 666 | if ( data->count != 1 ) { |
540 | data->deref(); | 667 | data->deref(); |
541 | Data* d2 = new Data; | 668 | Data* d2 = new Data; |
542 | d2->event = data->event; | 669 | d2->event = data->event; |
543 | d2->date = data->date; | 670 | d2->date = data->date; |
544 | d2->start = data->start; | 671 | d2->start = data->start; |
545 | d2->end = data->end; | 672 | d2->end = data->end; |
546 | d2->startDate = data->startDate; | 673 | d2->startDate = data->startDate; |
547 | d2->endDate = data->endDate; | 674 | d2->endDate = data->endDate; |
548 | d2->dates = data->dates; | 675 | d2->dates = data->dates; |
549 | data = d2; | 676 | data = d2; |
550 | } | 677 | } |
551 | } | 678 | } |
552 | bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{ | 679 | bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{ |
553 | if ( data->date < e.date() ) | 680 | if ( data->date < e.date() ) |
554 | return TRUE; | 681 | return TRUE; |
diff --git a/libopie/pim/oevent.h b/libopie/pim/oevent.h index 30f442e..9218c97 100644 --- a/libopie/pim/oevent.h +++ b/libopie/pim/oevent.h | |||
@@ -1,220 +1,230 @@ | |||
1 | // CONTAINS GPLed code of TT | 1 | // CONTAINS GPLed code of TT |
2 | 2 | ||
3 | #ifndef OPIE_PIM_EVENT_H | 3 | #ifndef OPIE_PIM_EVENT_H |
4 | #define OPIE_PIM_EVENT_H | 4 | #define OPIE_PIM_EVENT_H |
5 | 5 | ||
6 | #include <qstring.h> | 6 | #include <qstring.h> |
7 | #include <qdatetime.h> | 7 | #include <qdatetime.h> |
8 | #include <qvaluelist.h> | 8 | #include <qvaluelist.h> |
9 | 9 | ||
10 | #include <qpe/recordfields.h> | 10 | #include <qpe/recordfields.h> |
11 | #include <qpe/palmtopuidgen.h> | 11 | #include <qpe/palmtopuidgen.h> |
12 | 12 | ||
13 | #include "otimezone.h" | 13 | #include "otimezone.h" |
14 | #include "opimrecord.h" | 14 | #include "opimrecord.h" |
15 | 15 | ||
16 | struct OCalendarHelper { | 16 | struct OCalendarHelper { |
17 | /** calculate the week number of the date */ | 17 | /** calculate the week number of the date */ |
18 | static int week( const QDate& ); | 18 | static int week( const QDate& ); |
19 | /** calculate the occurence of week days since the start of the month */ | 19 | /** calculate the occurence of week days since the start of the month */ |
20 | static int ocurrence( const QDate& ); | 20 | static int ocurrence( const QDate& ); |
21 | 21 | ||
22 | // returns the dayOfWeek for the *first* day it finds (ignores | 22 | // returns the dayOfWeek for the *first* day it finds (ignores |
23 | // any further days!). Returns 1 (Monday) if there isn't any day found | 23 | // any further days!). Returns 1 (Monday) if there isn't any day found |
24 | static int dayOfWeek( char day ); | 24 | static int dayOfWeek( char day ); |
25 | 25 | ||
26 | /** returns the diff of month */ | 26 | /** returns the diff of month */ |
27 | static int monthDiff( const QDate& first, const QDate& second ); | 27 | static int monthDiff( const QDate& first, const QDate& second ); |
28 | 28 | ||
29 | }; | 29 | }; |
30 | 30 | ||
31 | class OPimNotifyManager; | 31 | class OPimNotifyManager; |
32 | class ORecur; | 32 | class ORecur; |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * This is the container for all Events. It encapsules all | 35 | * This is the container for all Events. It encapsules all |
36 | * available information for a single Event | 36 | * available information for a single Event |
37 | * @short container for events. | 37 | * @short container for events. |
38 | */ | 38 | */ |
39 | class OEvent : public OPimRecord { | 39 | class OEvent : public OPimRecord { |
40 | public: | 40 | public: |
41 | typedef QValueList<OEvent> ValueList; | 41 | typedef QValueList<OEvent> ValueList; |
42 | /** | 42 | /** |
43 | * RecordFields contain possible attributes | 43 | * RecordFields contain possible attributes |
44 | * used in the Results of toMap().. | ||
44 | */ | 45 | */ |
45 | enum RecordFields { | 46 | enum RecordFields { |
46 | Uid = Qtopia::UID_ID, | 47 | FUid = Qtopia::UID_ID, |
47 | Category = Qtopia::CATEGORY_ID, | 48 | FCategories = Qtopia::CATEGORY_ID, |
48 | Description, | 49 | FDescription = 0, |
49 | Location, | 50 | FLocation, |
50 | Alarm, | 51 | FType, |
51 | Reminder, | 52 | FAlarm, |
52 | Recurrence, | 53 | FSound, |
53 | Note, | 54 | FRType, |
54 | Created, | 55 | FRWeekdays, |
55 | StartDate, | 56 | FRPosition, |
56 | EndDate, | 57 | FRFreq, |
57 | AllDay, | 58 | FRHasEndDate, |
58 | TimeZone | 59 | FREndDate, |
60 | FRCreated, | ||
61 | FRExceptions, | ||
62 | FStart, | ||
63 | FEnd, | ||
64 | FNote, | ||
65 | FTimeZone, | ||
66 | FRecParent, | ||
67 | FRecChildren, | ||
59 | }; | 68 | }; |
60 | 69 | ||
61 | /** | 70 | /** |
62 | * Start with an Empty OEvent. UID == 0 means that it is empty | 71 | * Start with an Empty OEvent. UID == 0 means that it is empty |
63 | */ | 72 | */ |
64 | OEvent(int uid = 0); | 73 | OEvent(int uid = 0); |
65 | 74 | ||
66 | /** | 75 | /** |
67 | * copy c'tor | 76 | * copy c'tor |
68 | */ | 77 | */ |
69 | OEvent( const OEvent& ); | 78 | OEvent( const OEvent& ); |
70 | ~OEvent(); | 79 | ~OEvent(); |
71 | OEvent &operator=( const OEvent& ); | 80 | OEvent &operator=( const OEvent& ); |
72 | 81 | ||
73 | QString description()const; | 82 | QString description()const; |
74 | void setDescription( const QString& description ); | 83 | void setDescription( const QString& description ); |
75 | 84 | ||
76 | QString location()const; | 85 | QString location()const; |
77 | void setLocation( const QString& loc ); | 86 | void setLocation( const QString& loc ); |
78 | 87 | ||
79 | bool hasNotifiers()const; | 88 | bool hasNotifiers()const; |
80 | OPimNotifyManager ¬ifiers()const; | 89 | OPimNotifyManager ¬ifiers()const; |
81 | 90 | ||
82 | ORecur recurrence()const; | 91 | ORecur recurrence()const; |
83 | void setRecurrence( const ORecur& ); | 92 | void setRecurrence( const ORecur& ); |
84 | bool hasRecurrence()const; | 93 | bool hasRecurrence()const; |
85 | 94 | ||
86 | QString note()const; | 95 | QString note()const; |
87 | void setNote( const QString& note ); | 96 | void setNote( const QString& note ); |
88 | 97 | ||
89 | 98 | ||
90 | QDateTime createdDateTime()const; | 99 | QDateTime createdDateTime()const; |
91 | void setCreatedDateTime( const QDateTime& dt); | 100 | void setCreatedDateTime( const QDateTime& dt); |
92 | 101 | ||
93 | /** set the date to dt. dt is the QDateTime in localtime */ | 102 | /** set the date to dt. dt is the QDateTime in localtime */ |
94 | void setStartDateTime( const QDateTime& ); | 103 | void setStartDateTime( const QDateTime& ); |
95 | /** returns the datetime in the local timeZone */ | 104 | /** returns the datetime in the local timeZone */ |
96 | QDateTime startDateTime()const; | 105 | QDateTime startDateTime()const; |
97 | 106 | ||
98 | /** returns the start datetime in the current zone */ | 107 | /** returns the start datetime in the current zone */ |
99 | QDateTime startDateTimeInZone()const; | 108 | QDateTime startDateTimeInZone()const; |
100 | 109 | ||
101 | /** in current timezone */ | 110 | /** in current timezone */ |
102 | void setEndDateTime( const QDateTime& ); | 111 | void setEndDateTime( const QDateTime& ); |
103 | /** in current timezone */ | 112 | /** in current timezone */ |
104 | QDateTime endDateTime()const; | 113 | QDateTime endDateTime()const; |
105 | QDateTime endDateTimeInZone()const; | 114 | QDateTime endDateTimeInZone()const; |
106 | 115 | ||
107 | bool isMultipleDay()const; | 116 | bool isMultipleDay()const; |
108 | bool isAllDay()const; | 117 | bool isAllDay()const; |
109 | void setAllDay( bool isAllDay ); | 118 | void setAllDay( bool isAllDay ); |
110 | 119 | ||
111 | /* pin this event to a timezone! FIXME */ | 120 | /* pin this event to a timezone! FIXME */ |
112 | void setTimeZone( const QString& timeZone ); | 121 | void setTimeZone( const QString& timeZone ); |
113 | QString timeZone()const; | 122 | QString timeZone()const; |
114 | 123 | ||
115 | 124 | ||
116 | virtual bool match( const QRegExp& )const; | 125 | virtual bool match( const QRegExp& )const; |
117 | 126 | ||
118 | /** For exception to recurrence here is a list of children... */ | 127 | /** For exception to recurrence here is a list of children... */ |
119 | QArray<int> children()const; | 128 | QArray<int> children()const; |
120 | void setChildren( const QArray<int>& ); | 129 | void setChildren( const QArray<int>& ); |
121 | void addChild( int uid ); | 130 | void addChild( int uid ); |
122 | void removeChild( int uid ); | 131 | void removeChild( int uid ); |
123 | 132 | ||
124 | /** return the parent OEvent */ | 133 | /** return the parent OEvent */ |
125 | int parent()const; | 134 | int parent()const; |
126 | void setParent( int uid ); | 135 | void setParent( int uid ); |
127 | 136 | ||
128 | 137 | ||
129 | /* needed reimp */ | 138 | /* needed reimp */ |
130 | QString toRichText()const; | 139 | QString toRichText()const; |
131 | QString toShortText()const; | 140 | QString toShortText()const; |
132 | QString type()const; | 141 | QString type()const; |
133 | 142 | ||
134 | QMap<int, QString> toMap()const; | 143 | QMap<int, QString> toMap()const; |
144 | void fromMap( const QMap<int, QString>& map ); | ||
135 | QString recordField(int )const; | 145 | QString recordField(int )const; |
136 | 146 | ||
137 | static int rtti(); | 147 | static int rtti(); |
138 | 148 | ||
139 | bool loadFromStream( QDataStream& ); | 149 | bool loadFromStream( QDataStream& ); |
140 | bool saveToStream( QDataStream& )const; | 150 | bool saveToStream( QDataStream& )const; |
141 | 151 | ||
142 | /* bool operator==( const OEvent& ); | 152 | /* bool operator==( const OEvent& ); |
143 | bool operator!=( const OEvent& ); | 153 | bool operator!=( const OEvent& ); |
144 | bool operator<( const OEvent& ); | 154 | bool operator<( const OEvent& ); |
145 | bool operator<=( const OEvent& ); | 155 | bool operator<=( const OEvent& ); |
146 | bool operator>( const OEvent& ); | 156 | bool operator>( const OEvent& ); |
147 | bool operator>=(const OEvent& ); | 157 | bool operator>=(const OEvent& ); |
148 | */ | 158 | */ |
149 | private: | 159 | private: |
150 | inline void changeOrModify(); | 160 | inline void changeOrModify(); |
151 | void deref(); | 161 | void deref(); |
152 | struct Data; | 162 | struct Data; |
153 | Data* data; | 163 | Data* data; |
154 | class Private; | 164 | class Private; |
155 | Private* priv; | 165 | Private* priv; |
156 | 166 | ||
157 | }; | 167 | }; |
158 | 168 | ||
159 | /** | 169 | /** |
160 | * AN Event can span through multiple days. We split up a multiday eve | 170 | * AN Event can span through multiple days. We split up a multiday eve |
161 | */ | 171 | */ |
162 | class OEffectiveEvent { | 172 | class OEffectiveEvent { |
163 | public: | 173 | public: |
164 | typedef QValueList<OEffectiveEvent> ValueList; | 174 | typedef QValueList<OEffectiveEvent> ValueList; |
165 | enum Position { MidWay, Start, End, StartEnd }; | 175 | enum Position { MidWay, Start, End, StartEnd }; |
166 | // If we calculate the effective event of a multi-day event | 176 | // If we calculate the effective event of a multi-day event |
167 | // we have to figure out whether we are at the first day, | 177 | // we have to figure out whether we are at the first day, |
168 | // at the end, or anywhere else ("middle"). This is important | 178 | // at the end, or anywhere else ("middle"). This is important |
169 | // for the start/end times (00:00/23:59) | 179 | // for the start/end times (00:00/23:59) |
170 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- | 180 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- |
171 | // day event | 181 | // day event |
172 | // Start: start time -> 23:59 | 182 | // Start: start time -> 23:59 |
173 | // End: 00:00 -> end time | 183 | // End: 00:00 -> end time |
174 | // Start | End == StartEnd: for single-day events (default) | 184 | // Start | End == StartEnd: for single-day events (default) |
175 | // here we draw start time -> end time | 185 | // here we draw start time -> end time |
176 | OEffectiveEvent(); | 186 | OEffectiveEvent(); |
177 | OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); | 187 | OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); |
178 | OEffectiveEvent( const OEffectiveEvent& ); | 188 | OEffectiveEvent( const OEffectiveEvent& ); |
179 | OEffectiveEvent &operator=(const OEffectiveEvent& ); | 189 | OEffectiveEvent &operator=(const OEffectiveEvent& ); |
180 | ~OEffectiveEvent(); | 190 | ~OEffectiveEvent(); |
181 | 191 | ||
182 | void setStartTime( const QTime& ); | 192 | void setStartTime( const QTime& ); |
183 | void setEndTime( const QTime& ); | 193 | void setEndTime( const QTime& ); |
184 | void setEvent( const OEvent& ); | 194 | void setEvent( const OEvent& ); |
185 | void setDate( const QDate& ); | 195 | void setDate( const QDate& ); |
186 | 196 | ||
187 | void setEffectiveDates( const QDate& from, const QDate& to ); | 197 | void setEffectiveDates( const QDate& from, const QDate& to ); |
188 | 198 | ||
189 | QString description()const; | 199 | QString description()const; |
190 | QString location()const; | 200 | QString location()const; |
191 | QString note()const; | 201 | QString note()const; |
192 | OEvent event()const; | 202 | OEvent event()const; |
193 | QTime startTime()const; | 203 | QTime startTime()const; |
194 | QTime endTime()const; | 204 | QTime endTime()const; |
195 | QDate date()const; | 205 | QDate date()const; |
196 | 206 | ||
197 | /* return the length in hours */ | 207 | /* return the length in hours */ |
198 | int length()const; | 208 | int length()const; |
199 | int size()const; | 209 | int size()const; |
200 | 210 | ||
201 | QDate startDate()const; | 211 | QDate startDate()const; |
202 | QDate endDate()const; | 212 | QDate endDate()const; |
203 | 213 | ||
204 | bool operator<( const OEffectiveEvent &e ) const; | 214 | bool operator<( const OEffectiveEvent &e ) const; |
205 | bool operator<=( const OEffectiveEvent &e ) const; | 215 | bool operator<=( const OEffectiveEvent &e ) const; |
206 | bool operator==( const OEffectiveEvent &e ) const; | 216 | bool operator==( const OEffectiveEvent &e ) const; |
207 | bool operator!=( const OEffectiveEvent &e ) const; | 217 | bool operator!=( const OEffectiveEvent &e ) const; |
208 | bool operator>( const OEffectiveEvent &e ) const; | 218 | bool operator>( const OEffectiveEvent &e ) const; |
209 | bool operator>= ( const OEffectiveEvent &e ) const; | 219 | bool operator>= ( const OEffectiveEvent &e ) const; |
210 | 220 | ||
211 | private: | 221 | private: |
212 | void deref(); | 222 | void deref(); |
213 | inline void changeOrModify(); | 223 | inline void changeOrModify(); |
214 | class Private; | 224 | class Private; |
215 | Private* priv; | 225 | Private* priv; |
216 | struct Data; | 226 | struct Data; |
217 | Data* data; | 227 | Data* data; |
218 | 228 | ||
219 | }; | 229 | }; |
220 | #endif | 230 | #endif |
diff --git a/libopie/pim/orecur.cpp b/libopie/pim/orecur.cpp index 8c9ad46..f46f22e 100644 --- a/libopie/pim/orecur.cpp +++ b/libopie/pim/orecur.cpp | |||
@@ -1,228 +1,236 @@ | |||
1 | #include <time.h> | 1 | #include <time.h> |
2 | 2 | ||
3 | #include <qshared.h> | 3 | #include <qshared.h> |
4 | 4 | ||
5 | #include <qtopia/timeconversion.h> | 5 | #include <qtopia/timeconversion.h> |
6 | 6 | ||
7 | #include "otimezone.h" | 7 | #include "otimezone.h" |
8 | #include "orecur.h" | 8 | #include "orecur.h" |
9 | 9 | ||
10 | struct ORecur::Data : public QShared { | 10 | struct ORecur::Data : public QShared { |
11 | Data() : QShared() { | 11 | Data() : QShared() { |
12 | type = ORecur::NoRepeat; | 12 | type = ORecur::NoRepeat; |
13 | freq = -1; | 13 | freq = -1; |
14 | days = 0; | 14 | days = 0; |
15 | pos = 0; | 15 | pos = 0; |
16 | create = QDateTime::currentDateTime(); | 16 | create = QDateTime::currentDateTime(); |
17 | hasEnd = FALSE; | 17 | hasEnd = FALSE; |
18 | end = QDate::currentDate(); | 18 | end = QDate::currentDate(); |
19 | } | 19 | } |
20 | char days; // Q_UINT8 for 8 seven days;) | 20 | char days; // Q_UINT8 for 8 seven days;) |
21 | ORecur::RepeatType type; | 21 | ORecur::RepeatType type; |
22 | int freq; | 22 | int freq; |
23 | int pos; | 23 | int pos; |
24 | bool hasEnd : 1; | 24 | bool hasEnd : 1; |
25 | QDate end; | 25 | QDate end; |
26 | QDateTime create; | 26 | QDateTime create; |
27 | int rep; | 27 | int rep; |
28 | QString app; | 28 | QString app; |
29 | ExceptionList list; | 29 | ExceptionList list; |
30 | QDate start; | 30 | QDate start; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | 33 | ||
34 | ORecur::ORecur() { | 34 | ORecur::ORecur() { |
35 | data = new Data; | 35 | data = new Data; |
36 | } | 36 | } |
37 | |||
38 | ORecur::ORecur( const QMap<int, QString>& map ) | ||
39 | { | ||
40 | ORecur(); | ||
41 | fromMap( map ); | ||
42 | } | ||
43 | |||
44 | |||
37 | ORecur::ORecur( const ORecur& rec) | 45 | ORecur::ORecur( const ORecur& rec) |
38 | : data( rec.data ) | 46 | : data( rec.data ) |
39 | { | 47 | { |
40 | data->ref(); | 48 | data->ref(); |
41 | } | 49 | } |
42 | ORecur::~ORecur() { | 50 | ORecur::~ORecur() { |
43 | if ( data->deref() ) { | 51 | if ( data->deref() ) { |
44 | delete data; | 52 | delete data; |
45 | data = 0l; | 53 | data = 0l; |
46 | } | 54 | } |
47 | } | 55 | } |
48 | void ORecur::deref() { | 56 | void ORecur::deref() { |
49 | if ( data->deref() ) { | 57 | if ( data->deref() ) { |
50 | delete data; | 58 | delete data; |
51 | data = 0l; | 59 | data = 0l; |
52 | } | 60 | } |
53 | } | 61 | } |
54 | bool ORecur::operator==( const ORecur& )const { | 62 | bool ORecur::operator==( const ORecur& )const { |
55 | return false; | 63 | return false; |
56 | } | 64 | } |
57 | ORecur &ORecur::operator=( const ORecur& re) { | 65 | ORecur &ORecur::operator=( const ORecur& re) { |
58 | if ( *this == re ) return *this; | 66 | if ( *this == re ) return *this; |
59 | 67 | ||
60 | re.data->ref(); | 68 | re.data->ref(); |
61 | deref(); | 69 | deref(); |
62 | data = re.data; | 70 | data = re.data; |
63 | 71 | ||
64 | return *this; | 72 | return *this; |
65 | } | 73 | } |
66 | bool ORecur::doesRecur()const { | 74 | bool ORecur::doesRecur()const { |
67 | return !( type() == NoRepeat ); | 75 | return !( type() == NoRepeat ); |
68 | } | 76 | } |
69 | /* | 77 | /* |
70 | * we try to be smart here | 78 | * we try to be smart here |
71 | * | 79 | * |
72 | */ | 80 | */ |
73 | bool ORecur::doesRecur( const QDate& date ) { | 81 | bool ORecur::doesRecur( const QDate& date ) { |
74 | /* the day before the recurrance */ | 82 | /* the day before the recurrance */ |
75 | QDate da = date.addDays(-1); | 83 | QDate da = date.addDays(-1); |
76 | 84 | ||
77 | QDate recur; | 85 | QDate recur; |
78 | if (!nextOcurrence( da, recur ) ) | 86 | if (!nextOcurrence( da, recur ) ) |
79 | return false; | 87 | return false; |
80 | 88 | ||
81 | return (recur == date); | 89 | return (recur == date); |
82 | } | 90 | } |
83 | // FIXME unuglify! | 91 | // FIXME unuglify! |
84 | // GPL from Datebookdb.cpp | 92 | // GPL from Datebookdb.cpp |
85 | // FIXME exception list! | 93 | // FIXME exception list! |
86 | bool ORecur::nextOcurrence( const QDate& from, QDate& next ) { | 94 | bool ORecur::nextOcurrence( const QDate& from, QDate& next ) { |
87 | bool stillLooking; | 95 | bool stillLooking; |
88 | stillLooking = p_nextOccurrence( from, next ); | 96 | stillLooking = p_nextOccurrence( from, next ); |
89 | while ( stillLooking && data->list.contains(next) ) | 97 | while ( stillLooking && data->list.contains(next) ) |
90 | stillLooking = p_nextOccurrence( next.addDays(1), next ); | 98 | stillLooking = p_nextOccurrence( next.addDays(1), next ); |
91 | 99 | ||
92 | return stillLooking; | 100 | return stillLooking; |
93 | } | 101 | } |
94 | bool ORecur::p_nextOccurrence( const QDate& from, QDate& next ) { | 102 | bool ORecur::p_nextOccurrence( const QDate& from, QDate& next ) { |
95 | 103 | ||
96 | // easy checks, first are we too far in the future or too far in the past? | 104 | // easy checks, first are we too far in the future or too far in the past? |
97 | QDate tmpDate; | 105 | QDate tmpDate; |
98 | int freq = frequency(); | 106 | int freq = frequency(); |
99 | int diff, diff2, a; | 107 | int diff, diff2, a; |
100 | int iday, imonth, iyear; | 108 | int iday, imonth, iyear; |
101 | int dayOfWeek = 0; | 109 | int dayOfWeek = 0; |
102 | int firstOfWeek = 0; | 110 | int firstOfWeek = 0; |
103 | int weekOfMonth; | 111 | int weekOfMonth; |
104 | 112 | ||
105 | 113 | ||
106 | if (hasEndDate() && endDate() < from) | 114 | if (hasEndDate() && endDate() < from) |
107 | return FALSE; | 115 | return FALSE; |
108 | 116 | ||
109 | if (start() >= from ) { | 117 | if (start() >= from ) { |
110 | next = start(); | 118 | next = start(); |
111 | return TRUE; | 119 | return TRUE; |
112 | } | 120 | } |
113 | 121 | ||
114 | switch ( type() ) { | 122 | switch ( type() ) { |
115 | case Weekly: | 123 | case Weekly: |
116 | /* weekly is just daily by 7 */ | 124 | /* weekly is just daily by 7 */ |
117 | /* first convert the repeatPattern.Days() mask to the next | 125 | /* first convert the repeatPattern.Days() mask to the next |
118 | day of week valid after from */ | 126 | day of week valid after from */ |
119 | dayOfWeek = from.dayOfWeek(); | 127 | dayOfWeek = from.dayOfWeek(); |
120 | dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ | 128 | dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ |
121 | 129 | ||
122 | /* this is done in case freq > 1 and from in week not | 130 | /* this is done in case freq > 1 and from in week not |
123 | for this round */ | 131 | for this round */ |
124 | // firstOfWeek = 0; this is already done at decl. | 132 | // firstOfWeek = 0; this is already done at decl. |
125 | while(!((1 << firstOfWeek) & days() )) | 133 | while(!((1 << firstOfWeek) & days() )) |
126 | firstOfWeek++; | 134 | firstOfWeek++; |
127 | 135 | ||
128 | /* there is at least one 'day', or there would be no event */ | 136 | /* there is at least one 'day', or there would be no event */ |
129 | while(!((1 << (dayOfWeek % 7)) & days() )) | 137 | while(!((1 << (dayOfWeek % 7)) & days() )) |
130 | dayOfWeek++; | 138 | dayOfWeek++; |
131 | 139 | ||
132 | dayOfWeek = dayOfWeek % 7; /* the actual day of week */ | 140 | dayOfWeek = dayOfWeek % 7; /* the actual day of week */ |
133 | dayOfWeek -= start().dayOfWeek() -1; | 141 | dayOfWeek -= start().dayOfWeek() -1; |
134 | 142 | ||
135 | firstOfWeek = firstOfWeek % 7; /* the actual first of week */ | 143 | firstOfWeek = firstOfWeek % 7; /* the actual first of week */ |
136 | firstOfWeek -= start().dayOfWeek() -1; | 144 | firstOfWeek -= start().dayOfWeek() -1; |
137 | 145 | ||
138 | // dayOfWeek may be negitive now | 146 | // dayOfWeek may be negitive now |
139 | // day of week is number of days to add to start day | 147 | // day of week is number of days to add to start day |
140 | 148 | ||
141 | freq *= 7; | 149 | freq *= 7; |
142 | // FALL-THROUGH !!!!! | 150 | // FALL-THROUGH !!!!! |
143 | case Daily: | 151 | case Daily: |
144 | // the add is for the possible fall through from weekly */ | 152 | // the add is for the possible fall through from weekly */ |
145 | if(start().addDays(dayOfWeek) > from) { | 153 | if(start().addDays(dayOfWeek) > from) { |
146 | /* first week exception */ | 154 | /* first week exception */ |
147 | next = QDate(start().addDays(dayOfWeek) ); | 155 | next = QDate(start().addDays(dayOfWeek) ); |
148 | if ((next > endDate()) | 156 | if ((next > endDate()) |
149 | && hasEndDate() ) | 157 | && hasEndDate() ) |
150 | return FALSE; | 158 | return FALSE; |
151 | return TRUE; | 159 | return TRUE; |
152 | } | 160 | } |
153 | /* if from is middle of a non-week */ | 161 | /* if from is middle of a non-week */ |
154 | 162 | ||
155 | diff = start().addDays(dayOfWeek).daysTo(from) % freq; | 163 | diff = start().addDays(dayOfWeek).daysTo(from) % freq; |
156 | diff2 = start().addDays(firstOfWeek).daysTo(from) % freq; | 164 | diff2 = start().addDays(firstOfWeek).daysTo(from) % freq; |
157 | 165 | ||
158 | if(diff != 0) | 166 | if(diff != 0) |
159 | diff = freq - diff; | 167 | diff = freq - diff; |
160 | if(diff2 != 0) | 168 | if(diff2 != 0) |
161 | diff2 = freq - diff2; | 169 | diff2 = freq - diff2; |
162 | diff = QMIN(diff, diff2); | 170 | diff = QMIN(diff, diff2); |
163 | 171 | ||
164 | next = QDate(from.addDays(diff)); | 172 | next = QDate(from.addDays(diff)); |
165 | if ( (next > endDate()) | 173 | if ( (next > endDate()) |
166 | && hasEndDate() ) | 174 | && hasEndDate() ) |
167 | return FALSE; | 175 | return FALSE; |
168 | return TRUE; | 176 | return TRUE; |
169 | case MonthlyDay: | 177 | case MonthlyDay: |
170 | iday = from.day(); | 178 | iday = from.day(); |
171 | iyear = from.year(); | 179 | iyear = from.year(); |
172 | imonth = from.month(); | 180 | imonth = from.month(); |
173 | /* find equivelent day of month for this month */ | 181 | /* find equivelent day of month for this month */ |
174 | dayOfWeek = start().dayOfWeek(); | 182 | dayOfWeek = start().dayOfWeek(); |
175 | weekOfMonth = (start().day() - 1) / 7; | 183 | weekOfMonth = (start().day() - 1) / 7; |
176 | 184 | ||
177 | /* work out when the next valid month is */ | 185 | /* work out when the next valid month is */ |
178 | a = from.year() - start().year(); | 186 | a = from.year() - start().year(); |
179 | a *= 12; | 187 | a *= 12; |
180 | a = a + (imonth - start().month()); | 188 | a = a + (imonth - start().month()); |
181 | /* a is e.start()monthsFrom(from); */ | 189 | /* a is e.start()monthsFrom(from); */ |
182 | if(a % freq) { | 190 | if(a % freq) { |
183 | a = freq - (a % freq); | 191 | a = freq - (a % freq); |
184 | imonth = from.month() + a; | 192 | imonth = from.month() + a; |
185 | if (imonth > 12) { | 193 | if (imonth > 12) { |
186 | imonth--; | 194 | imonth--; |
187 | iyear += imonth / 12; | 195 | iyear += imonth / 12; |
188 | imonth = imonth % 12; | 196 | imonth = imonth % 12; |
189 | imonth++; | 197 | imonth++; |
190 | } | 198 | } |
191 | } | 199 | } |
192 | /* imonth is now the first month after or on | 200 | /* imonth is now the first month after or on |
193 | from that matches the frequency given */ | 201 | from that matches the frequency given */ |
194 | 202 | ||
195 | /* find for this month */ | 203 | /* find for this month */ |
196 | tmpDate = QDate( iyear, imonth, 1 ); | 204 | tmpDate = QDate( iyear, imonth, 1 ); |
197 | 205 | ||
198 | iday = 1; | 206 | iday = 1; |
199 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 207 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
200 | iday += 7 * weekOfMonth; | 208 | iday += 7 * weekOfMonth; |
201 | while (iday > tmpDate.daysInMonth()) { | 209 | while (iday > tmpDate.daysInMonth()) { |
202 | imonth += freq; | 210 | imonth += freq; |
203 | if (imonth > 12) { | 211 | if (imonth > 12) { |
204 | imonth--; | 212 | imonth--; |
205 | iyear += imonth / 12; | 213 | iyear += imonth / 12; |
206 | imonth = imonth % 12; | 214 | imonth = imonth % 12; |
207 | imonth++; | 215 | imonth++; |
208 | } | 216 | } |
209 | tmpDate = QDate( iyear, imonth, 1 ); | 217 | tmpDate = QDate( iyear, imonth, 1 ); |
210 | /* these loops could go for a while, check end case now */ | 218 | /* these loops could go for a while, check end case now */ |
211 | if ((tmpDate > endDate()) && hasEndDate() ) | 219 | if ((tmpDate > endDate()) && hasEndDate() ) |
212 | return FALSE; | 220 | return FALSE; |
213 | iday = 1; | 221 | iday = 1; |
214 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 222 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
215 | iday += 7 * weekOfMonth; | 223 | iday += 7 * weekOfMonth; |
216 | } | 224 | } |
217 | tmpDate = QDate(iyear, imonth, iday); | 225 | tmpDate = QDate(iyear, imonth, iday); |
218 | 226 | ||
219 | if (tmpDate >= from) { | 227 | if (tmpDate >= from) { |
220 | next = tmpDate; | 228 | next = tmpDate; |
221 | if ((next > endDate() ) && hasEndDate() ) | 229 | if ((next > endDate() ) && hasEndDate() ) |
222 | return FALSE; | 230 | return FALSE; |
223 | return TRUE; | 231 | return TRUE; |
224 | } | 232 | } |
225 | 233 | ||
226 | /* need to find the next iteration */ | 234 | /* need to find the next iteration */ |
227 | do { | 235 | do { |
228 | imonth += freq; | 236 | imonth += freq; |
diff --git a/libopie/pim/orecur.h b/libopie/pim/orecur.h index 47901b0..7750c12 100644 --- a/libopie/pim/orecur.h +++ b/libopie/pim/orecur.h | |||
@@ -1,101 +1,102 @@ | |||
1 | /* | 1 | /* |
2 | * GPL from TT | 2 | * GPL from TT |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #ifndef OPIE_RECUR_H | 5 | #ifndef OPIE_RECUR_H |
6 | #define OPIE_RECUR_H | 6 | #define OPIE_RECUR_H |
7 | 7 | ||
8 | #include <sys/types.h> | 8 | #include <sys/types.h> |
9 | 9 | ||
10 | #include <qdatetime.h> | 10 | #include <qdatetime.h> |
11 | #include <qvaluelist.h> | 11 | #include <qvaluelist.h> |
12 | #include <qmap.h> | 12 | #include <qmap.h> |
13 | 13 | ||
14 | class ORecur { | 14 | class ORecur { |
15 | public: | 15 | public: |
16 | typedef QValueList<QDate> ExceptionList; | 16 | typedef QValueList<QDate> ExceptionList; |
17 | enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, | 17 | enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, |
18 | MonthlyDate, Yearly }; | 18 | MonthlyDate, Yearly }; |
19 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, | 19 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, |
20 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; | 20 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; |
21 | enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate, | 21 | enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate, |
22 | EndDate, Created, Exceptions }; | 22 | EndDate, Created, Exceptions }; |
23 | 23 | ||
24 | ORecur(); | 24 | ORecur(); |
25 | ORecur( const QMap<int, QString>& map ); | ||
25 | ORecur( const ORecur& ); | 26 | ORecur( const ORecur& ); |
26 | ~ORecur(); | 27 | ~ORecur(); |
27 | 28 | ||
28 | ORecur &operator=( const ORecur& ); | 29 | ORecur &operator=( const ORecur& ); |
29 | bool operator==(const ORecur& )const; | 30 | bool operator==(const ORecur& )const; |
30 | 31 | ||
31 | bool doesRecur()const; | 32 | bool doesRecur()const; |
32 | /* if it recurrs on that day */ | 33 | /* if it recurrs on that day */ |
33 | bool doesRecur( const QDate& ); | 34 | bool doesRecur( const QDate& ); |
34 | RepeatType type()const; | 35 | RepeatType type()const; |
35 | int frequency()const; | 36 | int frequency()const; |
36 | int position()const; | 37 | int position()const; |
37 | char days()const; | 38 | char days()const; |
38 | bool hasEndDate()const; | 39 | bool hasEndDate()const; |
39 | QDate start()const; | 40 | QDate start()const; |
40 | QDate endDate()const; | 41 | QDate endDate()const; |
41 | QDateTime createdDateTime()const; | 42 | QDateTime createdDateTime()const; |
42 | /** | 43 | /** |
43 | * starting on monday=0, sunday=6 | 44 | * starting on monday=0, sunday=6 |
44 | * for convience | 45 | * for convience |
45 | */ | 46 | */ |
46 | bool repeatOnWeekDay( int day )const; | 47 | bool repeatOnWeekDay( int day )const; |
47 | 48 | ||
48 | /** | 49 | /** |
49 | * FromWhereToStart is not included!!! | 50 | * FromWhereToStart is not included!!! |
50 | */ | 51 | */ |
51 | bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); | 52 | bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); |
52 | 53 | ||
53 | /** | 54 | /** |
54 | * The module this ORecur belongs to | 55 | * The module this ORecur belongs to |
55 | */ | 56 | */ |
56 | QString service()const; | 57 | QString service()const; |
57 | 58 | ||
58 | /* | 59 | /* |
59 | * reference to the exception list | 60 | * reference to the exception list |
60 | */ | 61 | */ |
61 | ExceptionList &exceptions(); | 62 | ExceptionList &exceptions(); |
62 | 63 | ||
63 | /** | 64 | /** |
64 | * the current repetition | 65 | * the current repetition |
65 | */ | 66 | */ |
66 | int repetition()const; | 67 | int repetition()const; |
67 | 68 | ||
68 | void setType( const RepeatType& ); | 69 | void setType( const RepeatType& ); |
69 | void setFrequency( int freq ); | 70 | void setFrequency( int freq ); |
70 | void setPosition( int pos ); | 71 | void setPosition( int pos ); |
71 | void setDays( char c); | 72 | void setDays( char c); |
72 | void setEndDate( const QDate& dt ); | 73 | void setEndDate( const QDate& dt ); |
73 | void setStart( const QDate& dt ); | 74 | void setStart( const QDate& dt ); |
74 | void setCreatedDateTime( const QDateTime& ); | 75 | void setCreatedDateTime( const QDateTime& ); |
75 | void setHasEndDate( bool b ); | 76 | void setHasEndDate( bool b ); |
76 | void setRepitition(int ); | 77 | void setRepitition(int ); |
77 | 78 | ||
78 | void setService( const QString& ser ); | 79 | void setService( const QString& ser ); |
79 | 80 | ||
80 | QMap<int, QString> toMap() const; | 81 | QMap<int, QString> toMap() const; |
81 | void fromMap( const QMap<int, QString>& map ); | 82 | void fromMap( const QMap<int, QString>& map ); |
82 | 83 | ||
83 | /* almost internal */ | 84 | /* almost internal */ |
84 | QString toString()const; | 85 | QString toString()const; |
85 | private: | 86 | private: |
86 | bool p_nextOccurrence( const QDate& from, QDate& next ); | 87 | bool p_nextOccurrence( const QDate& from, QDate& next ); |
87 | void deref(); | 88 | void deref(); |
88 | inline void checkOrModify(); | 89 | inline void checkOrModify(); |
89 | 90 | ||
90 | /* Converts rType to String */ | 91 | /* Converts rType to String */ |
91 | QString rTypeString() const; | 92 | QString rTypeString() const; |
92 | /* Returns a map to convert Stringname for RType to RepeatType */ | 93 | /* Returns a map to convert Stringname for RType to RepeatType */ |
93 | QMap<QString, RepeatType> rTypeValueConvertMap() const; | 94 | QMap<QString, RepeatType> rTypeValueConvertMap() const; |
94 | 95 | ||
95 | class Data; | 96 | class Data; |
96 | Data* data; | 97 | Data* data; |
97 | class ORecurPrivate; | 98 | class ORecurPrivate; |
98 | ORecurPrivate *d; | 99 | ORecurPrivate *d; |
99 | }; | 100 | }; |
100 | 101 | ||
101 | #endif | 102 | #endif |
diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp index 3913661..75a0860 100644 --- a/libopie/pim/otodoaccesssql.cpp +++ b/libopie/pim/otodoaccesssql.cpp | |||
@@ -110,397 +110,400 @@ namespace { | |||
110 | QString query()const; | 110 | QString query()const; |
111 | private: | 111 | private: |
112 | QString with()const; | 112 | QString with()const; |
113 | QString out()const; | 113 | QString out()const; |
114 | QDate m_start; | 114 | QDate m_start; |
115 | QDate m_end; | 115 | QDate m_end; |
116 | bool m_inc :1; | 116 | bool m_inc :1; |
117 | }; | 117 | }; |
118 | 118 | ||
119 | 119 | ||
120 | CreateQuery::CreateQuery() : OSQLQuery() {} | 120 | CreateQuery::CreateQuery() : OSQLQuery() {} |
121 | CreateQuery::~CreateQuery() {} | 121 | CreateQuery::~CreateQuery() {} |
122 | QString CreateQuery::query()const { | 122 | QString CreateQuery::query()const { |
123 | QString qu; | 123 | QString qu; |
124 | qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; | 124 | qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; |
125 | qu += "description, summary, priority, DueDate, progress , state, "; | 125 | qu += "description, summary, priority, DueDate, progress , state, "; |
126 | // This is the recurrance-stuff .. Exceptions are currently not supported (see ORecur.cpp) ! (eilers) | 126 | // This is the recurrance-stuff .. Exceptions are currently not supported (see ORecur.cpp) ! (eilers) |
127 | qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, "; | 127 | qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, "; |
128 | qu += "reminders, alarms, maintainer, startdate, completeddate);"; | 128 | qu += "reminders, alarms, maintainer, startdate, completeddate);"; |
129 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; | 129 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; |
130 | return qu; | 130 | return qu; |
131 | } | 131 | } |
132 | 132 | ||
133 | LoadQuery::LoadQuery() : OSQLQuery() {} | 133 | LoadQuery::LoadQuery() : OSQLQuery() {} |
134 | LoadQuery::~LoadQuery() {} | 134 | LoadQuery::~LoadQuery() {} |
135 | QString LoadQuery::query()const { | 135 | QString LoadQuery::query()const { |
136 | QString qu; | 136 | QString qu; |
137 | // We do not need "distinct" here. The primary key is always unique.. | 137 | // We do not need "distinct" here. The primary key is always unique.. |
138 | //qu += "select distinct uid from todolist"; | 138 | //qu += "select distinct uid from todolist"; |
139 | qu += "select uid from todolist"; | 139 | qu += "select uid from todolist"; |
140 | 140 | ||
141 | return qu; | 141 | return qu; |
142 | } | 142 | } |
143 | 143 | ||
144 | InsertQuery::InsertQuery( const OTodo& todo ) | 144 | InsertQuery::InsertQuery( const OTodo& todo ) |
145 | : OSQLQuery(), m_todo( todo ) { | 145 | : OSQLQuery(), m_todo( todo ) { |
146 | } | 146 | } |
147 | InsertQuery::~InsertQuery() { | 147 | InsertQuery::~InsertQuery() { |
148 | } | 148 | } |
149 | /* | 149 | /* |
150 | * converts from a OTodo to a query | 150 | * converts from a OTodo to a query |
151 | * we leave out X-Ref + Alarms | 151 | * we leave out X-Ref + Alarms |
152 | */ | 152 | */ |
153 | QString InsertQuery::query()const{ | 153 | QString InsertQuery::query()const{ |
154 | 154 | ||
155 | int year, month, day; | 155 | int year, month, day; |
156 | year = month = day = 0; | 156 | year = month = day = 0; |
157 | if (m_todo.hasDueDate() ) { | 157 | if (m_todo.hasDueDate() ) { |
158 | QDate date = m_todo.dueDate(); | 158 | QDate date = m_todo.dueDate(); |
159 | year = date.year(); | 159 | year = date.year(); |
160 | month = date.month(); | 160 | month = date.month(); |
161 | day = date.day(); | 161 | day = date.day(); |
162 | } | 162 | } |
163 | int sYear = 0, sMonth = 0, sDay = 0; | 163 | int sYear = 0, sMonth = 0, sDay = 0; |
164 | if( m_todo.hasStartDate() ){ | 164 | if( m_todo.hasStartDate() ){ |
165 | QDate sDate = m_todo.startDate(); | 165 | QDate sDate = m_todo.startDate(); |
166 | sYear = sDate.year(); | 166 | sYear = sDate.year(); |
167 | sMonth= sDate.month(); | 167 | sMonth= sDate.month(); |
168 | sDay = sDate.day(); | 168 | sDay = sDate.day(); |
169 | } | 169 | } |
170 | 170 | ||
171 | int eYear = 0, eMonth = 0, eDay = 0; | 171 | int eYear = 0, eMonth = 0, eDay = 0; |
172 | if( m_todo.hasCompletedDate() ){ | 172 | if( m_todo.hasCompletedDate() ){ |
173 | QDate eDate = m_todo.completedDate(); | 173 | QDate eDate = m_todo.completedDate(); |
174 | eYear = eDate.year(); | 174 | eYear = eDate.year(); |
175 | eMonth= eDate.month(); | 175 | eMonth= eDate.month(); |
176 | eDay = eDate.day(); | 176 | eDay = eDate.day(); |
177 | } | 177 | } |
178 | QString qu; | 178 | QString qu; |
179 | QMap<int, QString> recMap = m_todo.recurrence().toMap(); | 179 | QMap<int, QString> recMap = m_todo.recurrence().toMap(); |
180 | qu = "insert into todolist VALUES(" | 180 | qu = "insert into todolist VALUES(" |
181 | + QString::number( m_todo.uid() ) + "," | 181 | + QString::number( m_todo.uid() ) + "," |
182 | + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," | 182 | + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," |
183 | + QString::number( m_todo.isCompleted() ) + "," | 183 | + QString::number( m_todo.isCompleted() ) + "," |
184 | + "'" + m_todo.description() + "'" + "," | 184 | + "'" + m_todo.description() + "'" + "," |
185 | + "'" + m_todo.summary() + "'" + "," | 185 | + "'" + m_todo.summary() + "'" + "," |
186 | + QString::number(m_todo.priority() ) + "," | 186 | + QString::number(m_todo.priority() ) + "," |
187 | + "'" + QString::number(year) + "-" | 187 | + "'" + QString::number(year) + "-" |
188 | + QString::number(month) | 188 | + QString::number(month) |
189 | + "-" + QString::number( day ) + "'" + "," | 189 | + "-" + QString::number( day ) + "'" + "," |
190 | + QString::number( m_todo.progress() ) + "," | 190 | + QString::number( m_todo.progress() ) + "," |
191 | + QString::number( m_todo.state().state() ) + "," | 191 | + QString::number( m_todo.state().state() ) + "," |
192 | + "'" + recMap[ ORecur::RType ] + "'" + "," | 192 | + "'" + recMap[ ORecur::RType ] + "'" + "," |
193 | + "'" + recMap[ ORecur::RWeekdays ] + "'" + "," | 193 | + "'" + recMap[ ORecur::RWeekdays ] + "'" + "," |
194 | + "'" + recMap[ ORecur::RPosition ] + "'" + "," | 194 | + "'" + recMap[ ORecur::RPosition ] + "'" + "," |
195 | + "'" + recMap[ ORecur::RFreq ] + "'" + "," | 195 | + "'" + recMap[ ORecur::RFreq ] + "'" + "," |
196 | + "'" + recMap[ ORecur::RHasEndDate ] + "'" + "," | 196 | + "'" + recMap[ ORecur::RHasEndDate ] + "'" + "," |
197 | + "'" + recMap[ ORecur::EndDate ] + "'" + "," | 197 | + "'" + recMap[ ORecur::EndDate ] + "'" + "," |
198 | + "'" + recMap[ ORecur::Created ] + "'" + "," | 198 | + "'" + recMap[ ORecur::Created ] + "'" + "," |
199 | + "'" + recMap[ ORecur::Exceptions ] + "'" + ","; | 199 | + "'" + recMap[ ORecur::Exceptions ] + "'" + ","; |
200 | 200 | ||
201 | if ( m_todo.hasNotifiers() ) { | 201 | if ( m_todo.hasNotifiers() ) { |
202 | OPimNotifyManager manager = m_todo.notifiers(); | 202 | OPimNotifyManager manager = m_todo.notifiers(); |
203 | qu += "'" + manager.remindersToString() + "'" + "," | 203 | qu += "'" + manager.remindersToString() + "'" + "," |
204 | + "'" + manager.alarmsToString() + "'" + ","; | 204 | + "'" + manager.alarmsToString() + "'" + ","; |
205 | } | 205 | } |
206 | else{ | 206 | else{ |
207 | qu += QString( "''" ) + "," | 207 | qu += QString( "''" ) + "," |
208 | + "''" + ","; | 208 | + "''" + ","; |
209 | } | 209 | } |
210 | 210 | ||
211 | qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) | 211 | qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) |
212 | + "'" + QString::number(sYear) + "-" | 212 | + "'" + QString::number(sYear) + "-" |
213 | + QString::number(sMonth) | 213 | + QString::number(sMonth) |
214 | + "-" + QString::number(sDay) + "'" + "," | 214 | + "-" + QString::number(sDay) + "'" + "," |
215 | + "'" + QString::number(eYear) + "-" | 215 | + "'" + QString::number(eYear) + "-" |
216 | + QString::number(eMonth) | 216 | + QString::number(eMonth) |
217 | + "-"+QString::number(eDay) + "'" | 217 | + "-"+QString::number(eDay) + "'" |
218 | + ")"; | 218 | + ")"; |
219 | 219 | ||
220 | qWarning("add %s", qu.latin1() ); | 220 | qWarning("add %s", qu.latin1() ); |
221 | return qu; | 221 | return qu; |
222 | } | 222 | } |
223 | 223 | ||
224 | RemoveQuery::RemoveQuery(int uid ) | 224 | RemoveQuery::RemoveQuery(int uid ) |
225 | : OSQLQuery(), m_uid( uid ) {} | 225 | : OSQLQuery(), m_uid( uid ) {} |
226 | RemoveQuery::~RemoveQuery() {} | 226 | RemoveQuery::~RemoveQuery() {} |
227 | QString RemoveQuery::query()const { | 227 | QString RemoveQuery::query()const { |
228 | QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); | 228 | QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); |
229 | return qu; | 229 | return qu; |
230 | } | 230 | } |
231 | 231 | ||
232 | 232 | ||
233 | ClearQuery::ClearQuery() | 233 | ClearQuery::ClearQuery() |
234 | : OSQLQuery() {} | 234 | : OSQLQuery() {} |
235 | ClearQuery::~ClearQuery() {} | 235 | ClearQuery::~ClearQuery() {} |
236 | QString ClearQuery::query()const { | 236 | QString ClearQuery::query()const { |
237 | QString qu = "drop table todolist"; | 237 | QString qu = "drop table todolist"; |
238 | return qu; | 238 | return qu; |
239 | } | 239 | } |
240 | FindQuery::FindQuery(int uid) | 240 | FindQuery::FindQuery(int uid) |
241 | : OSQLQuery(), m_uid(uid ) { | 241 | : OSQLQuery(), m_uid(uid ) { |
242 | } | 242 | } |
243 | FindQuery::FindQuery(const QArray<int>& ints) | 243 | FindQuery::FindQuery(const QArray<int>& ints) |
244 | : OSQLQuery(), m_uids(ints){ | 244 | : OSQLQuery(), m_uids(ints){ |
245 | } | 245 | } |
246 | FindQuery::~FindQuery() { | 246 | FindQuery::~FindQuery() { |
247 | } | 247 | } |
248 | QString FindQuery::query()const{ | 248 | QString FindQuery::query()const{ |
249 | if (m_uids.count() == 0 ) | 249 | if (m_uids.count() == 0 ) |
250 | return single(); | 250 | return single(); |
251 | else | 251 | else |
252 | return multi(); | 252 | return multi(); |
253 | } | 253 | } |
254 | QString FindQuery::single()const{ | 254 | QString FindQuery::single()const{ |
255 | QString qu = "select * from todolist where uid = " + QString::number(m_uid); | 255 | QString qu = "select * from todolist where uid = " + QString::number(m_uid); |
256 | return qu; | 256 | return qu; |
257 | } | 257 | } |
258 | QString FindQuery::multi()const { | 258 | QString FindQuery::multi()const { |
259 | QString qu = "select * from todolist where "; | 259 | QString qu = "select * from todolist where "; |
260 | for (uint i = 0; i < m_uids.count(); i++ ) { | 260 | for (uint i = 0; i < m_uids.count(); i++ ) { |
261 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | 261 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; |
262 | } | 262 | } |
263 | qu.remove( qu.length()-2, 2 ); | 263 | qu.remove( qu.length()-2, 2 ); |
264 | return qu; | 264 | return qu; |
265 | } | 265 | } |
266 | 266 | ||
267 | OverDueQuery::OverDueQuery(): OSQLQuery() {} | 267 | OverDueQuery::OverDueQuery(): OSQLQuery() {} |
268 | OverDueQuery::~OverDueQuery() {} | 268 | OverDueQuery::~OverDueQuery() {} |
269 | QString OverDueQuery::query()const { | 269 | QString OverDueQuery::query()const { |
270 | QDate date = QDate::currentDate(); | 270 | QDate date = QDate::currentDate(); |
271 | QString str; | 271 | QString str; |
272 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); | 272 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); |
273 | 273 | ||
274 | return str; | 274 | return str; |
275 | } | 275 | } |
276 | 276 | ||
277 | 277 | ||
278 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) | 278 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) |
279 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} | 279 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} |
280 | EffQuery::~EffQuery() {} | 280 | EffQuery::~EffQuery() {} |
281 | QString EffQuery::query()const { | 281 | QString EffQuery::query()const { |
282 | return m_inc ? with() : out(); | 282 | return m_inc ? with() : out(); |
283 | } | 283 | } |
284 | QString EffQuery::with()const { | 284 | QString EffQuery::with()const { |
285 | QString str; | 285 | QString str; |
286 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") | 286 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") |
287 | .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) | 287 | .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) |
288 | .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); | 288 | .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); |
289 | return str; | 289 | return str; |
290 | } | 290 | } |
291 | QString EffQuery::out()const { | 291 | QString EffQuery::out()const { |
292 | QString str; | 292 | QString str; |
293 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") | 293 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") |
294 | .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) | 294 | .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) |
295 | .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); | 295 | .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); |
296 | 296 | ||
297 | return str; | 297 | return str; |
298 | } | 298 | } |
299 | }; | 299 | }; |
300 | 300 | ||
301 | OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) | 301 | OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) |
302 | : OTodoAccessBackend(), m_dict(15), m_dirty(true) | 302 | : OTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true) |
303 | { | 303 | { |
304 | QString fi = file; | 304 | QString fi = file; |
305 | if ( fi.isEmpty() ) | 305 | if ( fi.isEmpty() ) |
306 | fi = Global::applicationFileName( "todolist", "todolist.db" ); | 306 | fi = Global::applicationFileName( "todolist", "todolist.db" ); |
307 | OSQLManager man; | 307 | OSQLManager man; |
308 | m_driver = man.standard(); | 308 | m_driver = man.standard(); |
309 | m_driver->setUrl(fi); | 309 | m_driver->setUrl(fi); |
310 | // fillDict(); | 310 | // fillDict(); |
311 | } | 311 | } |
312 | 312 | ||
313 | OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ | 313 | OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ |
314 | if( m_driver ) | ||
315 | delete m_driver; | ||
314 | } | 316 | } |
317 | |||
315 | bool OTodoAccessBackendSQL::load(){ | 318 | bool OTodoAccessBackendSQL::load(){ |
316 | if (!m_driver->open() ) | 319 | if (!m_driver->open() ) |
317 | return false; | 320 | return false; |
318 | 321 | ||
319 | CreateQuery creat; | 322 | CreateQuery creat; |
320 | OSQLResult res = m_driver->query(&creat ); | 323 | OSQLResult res = m_driver->query(&creat ); |
321 | 324 | ||
322 | m_dirty = true; | 325 | m_dirty = true; |
323 | return true; | 326 | return true; |
324 | } | 327 | } |
325 | bool OTodoAccessBackendSQL::reload(){ | 328 | bool OTodoAccessBackendSQL::reload(){ |
326 | return load(); | 329 | return load(); |
327 | } | 330 | } |
328 | 331 | ||
329 | bool OTodoAccessBackendSQL::save(){ | 332 | bool OTodoAccessBackendSQL::save(){ |
330 | return m_driver->close(); | 333 | return m_driver->close(); |
331 | } | 334 | } |
332 | QArray<int> OTodoAccessBackendSQL::allRecords()const { | 335 | QArray<int> OTodoAccessBackendSQL::allRecords()const { |
333 | if (m_dirty ) | 336 | if (m_dirty ) |
334 | update(); | 337 | update(); |
335 | 338 | ||
336 | return m_uids; | 339 | return m_uids; |
337 | } | 340 | } |
338 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ | 341 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ |
339 | QArray<int> ints(0); | 342 | QArray<int> ints(0); |
340 | return ints; | 343 | return ints; |
341 | } | 344 | } |
342 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ | 345 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ |
343 | FindQuery query( uid ); | 346 | FindQuery query( uid ); |
344 | return todo( m_driver->query(&query) ); | 347 | return todo( m_driver->query(&query) ); |
345 | 348 | ||
346 | } | 349 | } |
347 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, | 350 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, |
348 | uint cur, Frontend::CacheDirection dir ) const{ | 351 | uint cur, Frontend::CacheDirection dir ) const{ |
349 | uint CACHE = readAhead(); | 352 | uint CACHE = readAhead(); |
350 | qWarning("searching for %d", uid ); | 353 | qWarning("searching for %d", uid ); |
351 | QArray<int> search( CACHE ); | 354 | QArray<int> search( CACHE ); |
352 | uint size =0; | 355 | uint size =0; |
353 | OTodo to; | 356 | OTodo to; |
354 | 357 | ||
355 | // we try to cache CACHE items | 358 | // we try to cache CACHE items |
356 | switch( dir ) { | 359 | switch( dir ) { |
357 | /* forward */ | 360 | /* forward */ |
358 | case 0: // FIXME: Not a good style to use magic numbers here (eilers) | 361 | case 0: // FIXME: Not a good style to use magic numbers here (eilers) |
359 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { | 362 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { |
360 | qWarning("size %d %d", size, ints[i] ); | 363 | qWarning("size %d %d", size, ints[i] ); |
361 | search[size] = ints[i]; | 364 | search[size] = ints[i]; |
362 | size++; | 365 | size++; |
363 | } | 366 | } |
364 | break; | 367 | break; |
365 | /* reverse */ | 368 | /* reverse */ |
366 | case 1: // FIXME: Not a good style to use magic numbers here (eilers) | 369 | case 1: // FIXME: Not a good style to use magic numbers here (eilers) |
367 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { | 370 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { |
368 | search[size] = ints[i]; | 371 | search[size] = ints[i]; |
369 | size++; | 372 | size++; |
370 | } | 373 | } |
371 | break; | 374 | break; |
372 | } | 375 | } |
373 | search.resize( size ); | 376 | search.resize( size ); |
374 | FindQuery query( search ); | 377 | FindQuery query( search ); |
375 | OSQLResult res = m_driver->query( &query ); | 378 | OSQLResult res = m_driver->query( &query ); |
376 | if ( res.state() != OSQLResult::Success ) | 379 | if ( res.state() != OSQLResult::Success ) |
377 | return to; | 380 | return to; |
378 | 381 | ||
379 | return todo( res ); | 382 | return todo( res ); |
380 | } | 383 | } |
381 | void OTodoAccessBackendSQL::clear() { | 384 | void OTodoAccessBackendSQL::clear() { |
382 | ClearQuery cle; | 385 | ClearQuery cle; |
383 | OSQLResult res = m_driver->query( &cle ); | 386 | OSQLResult res = m_driver->query( &cle ); |
384 | CreateQuery qu; | 387 | CreateQuery qu; |
385 | res = m_driver->query(&qu); | 388 | res = m_driver->query(&qu); |
386 | } | 389 | } |
387 | bool OTodoAccessBackendSQL::add( const OTodo& t) { | 390 | bool OTodoAccessBackendSQL::add( const OTodo& t) { |
388 | InsertQuery ins( t ); | 391 | InsertQuery ins( t ); |
389 | OSQLResult res = m_driver->query( &ins ); | 392 | OSQLResult res = m_driver->query( &ins ); |
390 | 393 | ||
391 | if ( res.state() == OSQLResult::Failure ) | 394 | if ( res.state() == OSQLResult::Failure ) |
392 | return false; | 395 | return false; |
393 | int c = m_uids.count(); | 396 | int c = m_uids.count(); |
394 | m_uids.resize( c+1 ); | 397 | m_uids.resize( c+1 ); |
395 | m_uids[c] = t.uid(); | 398 | m_uids[c] = t.uid(); |
396 | 399 | ||
397 | return true; | 400 | return true; |
398 | } | 401 | } |
399 | bool OTodoAccessBackendSQL::remove( int uid ) { | 402 | bool OTodoAccessBackendSQL::remove( int uid ) { |
400 | RemoveQuery rem( uid ); | 403 | RemoveQuery rem( uid ); |
401 | OSQLResult res = m_driver->query(&rem ); | 404 | OSQLResult res = m_driver->query(&rem ); |
402 | 405 | ||
403 | if ( res.state() == OSQLResult::Failure ) | 406 | if ( res.state() == OSQLResult::Failure ) |
404 | return false; | 407 | return false; |
405 | 408 | ||
406 | m_dirty = true; | 409 | m_dirty = true; |
407 | return true; | 410 | return true; |
408 | } | 411 | } |
409 | /* | 412 | /* |
410 | * FIXME better set query | 413 | * FIXME better set query |
411 | * but we need the cache for that | 414 | * but we need the cache for that |
412 | * now we remove | 415 | * now we remove |
413 | */ | 416 | */ |
414 | bool OTodoAccessBackendSQL::replace( const OTodo& t) { | 417 | bool OTodoAccessBackendSQL::replace( const OTodo& t) { |
415 | remove( t.uid() ); | 418 | remove( t.uid() ); |
416 | bool b= add(t); | 419 | bool b= add(t); |
417 | m_dirty = false; // we changed some stuff but the UID stayed the same | 420 | m_dirty = false; // we changed some stuff but the UID stayed the same |
418 | return b; | 421 | return b; |
419 | } | 422 | } |
420 | QArray<int> OTodoAccessBackendSQL::overDue() { | 423 | QArray<int> OTodoAccessBackendSQL::overDue() { |
421 | OverDueQuery qu; | 424 | OverDueQuery qu; |
422 | return uids( m_driver->query(&qu ) ); | 425 | return uids( m_driver->query(&qu ) ); |
423 | } | 426 | } |
424 | QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, | 427 | QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, |
425 | const QDate& t, | 428 | const QDate& t, |
426 | bool u) { | 429 | bool u) { |
427 | EffQuery ef(s, t, u ); | 430 | EffQuery ef(s, t, u ); |
428 | return uids (m_driver->query(&ef) ); | 431 | return uids (m_driver->query(&ef) ); |
429 | } | 432 | } |
430 | /* | 433 | /* |
431 | * | 434 | * |
432 | */ | 435 | */ |
433 | QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, | 436 | QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, |
434 | int sortFilter, int cat ) { | 437 | int sortFilter, int cat ) { |
435 | qWarning("sorted %d, %d", asc, sortOrder ); | 438 | qWarning("sorted %d, %d", asc, sortOrder ); |
436 | QString query; | 439 | QString query; |
437 | query = "select uid from todolist WHERE "; | 440 | query = "select uid from todolist WHERE "; |
438 | 441 | ||
439 | /* | 442 | /* |
440 | * Sort Filter stuff | 443 | * Sort Filter stuff |
441 | * not that straight forward | 444 | * not that straight forward |
442 | * FIXME: Replace magic numbers | 445 | * FIXME: Replace magic numbers |
443 | * | 446 | * |
444 | */ | 447 | */ |
445 | /* Category */ | 448 | /* Category */ |
446 | if ( sortFilter & 1 ) { | 449 | if ( sortFilter & 1 ) { |
447 | QString str; | 450 | QString str; |
448 | if (cat != 0 ) str = QString::number( cat ); | 451 | if (cat != 0 ) str = QString::number( cat ); |
449 | query += " categories like '%" +str+"%' AND"; | 452 | query += " categories like '%" +str+"%' AND"; |
450 | } | 453 | } |
451 | /* Show only overdue */ | 454 | /* Show only overdue */ |
452 | if ( sortFilter & 2 ) { | 455 | if ( sortFilter & 2 ) { |
453 | QDate date = QDate::currentDate(); | 456 | QDate date = QDate::currentDate(); |
454 | QString due; | 457 | QString due; |
455 | QString base; | 458 | QString base; |
456 | base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); | 459 | base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); |
457 | query += " " + base + " AND"; | 460 | query += " " + base + " AND"; |
458 | } | 461 | } |
459 | /* not show completed */ | 462 | /* not show completed */ |
460 | if ( sortFilter & 4 ) { | 463 | if ( sortFilter & 4 ) { |
461 | query += " completed = 0 AND"; | 464 | query += " completed = 0 AND"; |
462 | }else{ | 465 | }else{ |
463 | query += " ( completed = 1 OR completed = 0) AND"; | 466 | query += " ( completed = 1 OR completed = 0) AND"; |
464 | } | 467 | } |
465 | /* srtip the end */ | 468 | /* srtip the end */ |
466 | query = query.remove( query.length()-3, 3 ); | 469 | query = query.remove( query.length()-3, 3 ); |
467 | 470 | ||
468 | 471 | ||
469 | /* | 472 | /* |
470 | * sort order stuff | 473 | * sort order stuff |
471 | * quite straight forward | 474 | * quite straight forward |
472 | */ | 475 | */ |
473 | query += "ORDER BY "; | 476 | query += "ORDER BY "; |
474 | switch( sortOrder ) { | 477 | switch( sortOrder ) { |
475 | /* completed */ | 478 | /* completed */ |
476 | case 0: | 479 | case 0: |
477 | query += "completed"; | 480 | query += "completed"; |
478 | break; | 481 | break; |
479 | case 1: | 482 | case 1: |
480 | query += "priority"; | 483 | query += "priority"; |
481 | break; | 484 | break; |
482 | case 2: | 485 | case 2: |
483 | query += "summary"; | 486 | query += "summary"; |
484 | break; | 487 | break; |
485 | case 3: | 488 | case 3: |
486 | query += "DueDate"; | 489 | query += "DueDate"; |
487 | break; | 490 | break; |
488 | } | 491 | } |
489 | 492 | ||
490 | if ( !asc ) { | 493 | if ( !asc ) { |
491 | qWarning("not ascending!"); | 494 | qWarning("not ascending!"); |
492 | query += " DESC"; | 495 | query += " DESC"; |
493 | } | 496 | } |
494 | 497 | ||
495 | qWarning( query ); | 498 | qWarning( query ); |
496 | OSQLRawQuery raw(query ); | 499 | OSQLRawQuery raw(query ); |
497 | return uids( m_driver->query(&raw) ); | 500 | return uids( m_driver->query(&raw) ); |
498 | } | 501 | } |
499 | bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ | 502 | bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ |
500 | if ( str == "0-0-0" ) | 503 | if ( str == "0-0-0" ) |
501 | return false; | 504 | return false; |
502 | else{ | 505 | else{ |
503 | int day, year, month; | 506 | int day, year, month; |
504 | QStringList list = QStringList::split("-", str ); | 507 | QStringList list = QStringList::split("-", str ); |
505 | year = list[0].toInt(); | 508 | year = list[0].toInt(); |
506 | month = list[1].toInt(); | 509 | month = list[1].toInt(); |
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp index 132c9fc..dd9dbde 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | |||
@@ -1,208 +1,211 @@ | |||
1 | /* | 1 | /* |
2 | * SQL Backend for the OPIE-Contact Database. | 2 | * SQL Backend for the OPIE-Contact Database. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | 4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) |
5 | * | 5 | * |
6 | * ===================================================================== | 6 | * ===================================================================== |
7 | *This program is free software; you can redistribute it and/or | 7 | *This program is free software; you can redistribute it and/or |
8 | *modify it under the terms of the GNU Library General Public | 8 | *modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either | 9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. | 10 | * version 2 of the License, or (at your option) any later version. |
11 | * ===================================================================== | 11 | * ===================================================================== |
12 | * ===================================================================== | 12 | * ===================================================================== |
13 | * Version: $Id$ | 13 | * Version: $Id$ |
14 | * ===================================================================== | 14 | * ===================================================================== |
15 | * History: | 15 | * History: |
16 | * $Log$ | 16 | * $Log$ |
17 | * Revision 1.3 2003/12/08 15:18:10 eilers | ||
18 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
19 | * | ||
17 | * Revision 1.2 2003/09/29 07:44:26 eilers | 20 | * Revision 1.2 2003/09/29 07:44:26 eilers |
18 | * Improvement of PIM-SQL Databases, but search queries are still limited. | 21 | * Improvement of PIM-SQL Databases, but search queries are still limited. |
19 | * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. | 22 | * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. |
20 | * Todo: Started to add new attributes. Some type conversions missing. | 23 | * Todo: Started to add new attributes. Some type conversions missing. |
21 | * | 24 | * |
22 | * Revision 1.1 2003/09/22 14:31:16 eilers | 25 | * Revision 1.1 2003/09/22 14:31:16 eilers |
23 | * Added first experimental incarnation of sql-backend for addressbook. | 26 | * Added first experimental incarnation of sql-backend for addressbook. |
24 | * Some modifications to be able to compile the todo sql-backend. | 27 | * Some modifications to be able to compile the todo sql-backend. |
25 | * A lot of changes fill follow... | 28 | * A lot of changes fill follow... |
26 | * | 29 | * |
27 | */ | 30 | */ |
28 | 31 | ||
29 | #include "ocontactaccessbackend_sql.h" | 32 | #include "ocontactaccessbackend_sql.h" |
30 | 33 | ||
31 | #include <qarray.h> | 34 | #include <qarray.h> |
32 | #include <qdatetime.h> | 35 | #include <qdatetime.h> |
33 | #include <qstringlist.h> | 36 | #include <qstringlist.h> |
34 | 37 | ||
35 | #include <qpe/global.h> | 38 | #include <qpe/global.h> |
36 | #include <qpe/recordfields.h> | 39 | #include <qpe/recordfields.h> |
37 | 40 | ||
38 | #include <opie/ocontactfields.h> | 41 | #include <opie/ocontactfields.h> |
39 | #include <opie/oconversion.h> | 42 | #include <opie/oconversion.h> |
40 | #include <opie2/osqldriver.h> | 43 | #include <opie2/osqldriver.h> |
41 | #include <opie2/osqlresult.h> | 44 | #include <opie2/osqlresult.h> |
42 | #include <opie2/osqlmanager.h> | 45 | #include <opie2/osqlmanager.h> |
43 | #include <opie2/osqlquery.h> | 46 | #include <opie2/osqlquery.h> |
44 | 47 | ||
45 | 48 | ||
46 | 49 | ||
47 | 50 | ||
48 | // If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead | 51 | // If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead |
49 | // vertical like "uid, type, value". | 52 | // vertical like "uid, type, value". |
50 | // DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! | 53 | // DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! |
51 | #define __STORE_HORIZONTAL_ | 54 | #define __STORE_HORIZONTAL_ |
52 | 55 | ||
53 | // Distinct loading is not very fast. If I expect that every person has just | 56 | // Distinct loading is not very fast. If I expect that every person has just |
54 | // one (and always one) 'Last Name', I can request all uid's for existing lastnames, | 57 | // one (and always one) 'Last Name', I can request all uid's for existing lastnames, |
55 | // which is faster.. | 58 | // which is faster.. |
56 | // But this may not be true for all entries, like company contacts.. | 59 | // But this may not be true for all entries, like company contacts.. |
57 | // The current AddressBook application handles this problem, but other may not.. (eilers) | 60 | // The current AddressBook application handles this problem, but other may not.. (eilers) |
58 | #define __USE_SUPERFAST_LOADQUERY | 61 | #define __USE_SUPERFAST_LOADQUERY |
59 | 62 | ||
60 | 63 | ||
61 | /* | 64 | /* |
62 | * Implementation of used query types | 65 | * Implementation of used query types |
63 | * CREATE query | 66 | * CREATE query |
64 | * LOAD query | 67 | * LOAD query |
65 | * INSERT | 68 | * INSERT |
66 | * REMOVE | 69 | * REMOVE |
67 | * CLEAR | 70 | * CLEAR |
68 | */ | 71 | */ |
69 | namespace { | 72 | namespace { |
70 | /** | 73 | /** |
71 | * CreateQuery for the Todolist Table | 74 | * CreateQuery for the Todolist Table |
72 | */ | 75 | */ |
73 | class CreateQuery : public OSQLQuery { | 76 | class CreateQuery : public OSQLQuery { |
74 | public: | 77 | public: |
75 | CreateQuery(); | 78 | CreateQuery(); |
76 | ~CreateQuery(); | 79 | ~CreateQuery(); |
77 | QString query()const; | 80 | QString query()const; |
78 | }; | 81 | }; |
79 | 82 | ||
80 | /** | 83 | /** |
81 | * Clears (delete) a Table | 84 | * Clears (delete) a Table |
82 | */ | 85 | */ |
83 | class ClearQuery : public OSQLQuery { | 86 | class ClearQuery : public OSQLQuery { |
84 | public: | 87 | public: |
85 | ClearQuery(); | 88 | ClearQuery(); |
86 | ~ClearQuery(); | 89 | ~ClearQuery(); |
87 | QString query()const; | 90 | QString query()const; |
88 | 91 | ||
89 | }; | 92 | }; |
90 | 93 | ||
91 | 94 | ||
92 | /** | 95 | /** |
93 | * LoadQuery | 96 | * LoadQuery |
94 | * this one queries for all uids | 97 | * this one queries for all uids |
95 | */ | 98 | */ |
96 | class LoadQuery : public OSQLQuery { | 99 | class LoadQuery : public OSQLQuery { |
97 | public: | 100 | public: |
98 | LoadQuery(); | 101 | LoadQuery(); |
99 | ~LoadQuery(); | 102 | ~LoadQuery(); |
100 | QString query()const; | 103 | QString query()const; |
101 | }; | 104 | }; |
102 | 105 | ||
103 | /** | 106 | /** |
104 | * inserts/adds a OContact to the table | 107 | * inserts/adds a OContact to the table |
105 | */ | 108 | */ |
106 | class InsertQuery : public OSQLQuery { | 109 | class InsertQuery : public OSQLQuery { |
107 | public: | 110 | public: |
108 | InsertQuery(const OContact& ); | 111 | InsertQuery(const OContact& ); |
109 | ~InsertQuery(); | 112 | ~InsertQuery(); |
110 | QString query()const; | 113 | QString query()const; |
111 | private: | 114 | private: |
112 | OContact m_contact; | 115 | OContact m_contact; |
113 | }; | 116 | }; |
114 | 117 | ||
115 | 118 | ||
116 | /** | 119 | /** |
117 | * removes one from the table | 120 | * removes one from the table |
118 | */ | 121 | */ |
119 | class RemoveQuery : public OSQLQuery { | 122 | class RemoveQuery : public OSQLQuery { |
120 | public: | 123 | public: |
121 | RemoveQuery(int uid ); | 124 | RemoveQuery(int uid ); |
122 | ~RemoveQuery(); | 125 | ~RemoveQuery(); |
123 | QString query()const; | 126 | QString query()const; |
124 | private: | 127 | private: |
125 | int m_uid; | 128 | int m_uid; |
126 | }; | 129 | }; |
127 | 130 | ||
128 | /** | 131 | /** |
129 | * a find query for noncustom elements | 132 | * a find query for noncustom elements |
130 | */ | 133 | */ |
131 | class FindQuery : public OSQLQuery { | 134 | class FindQuery : public OSQLQuery { |
132 | public: | 135 | public: |
133 | FindQuery(int uid); | 136 | FindQuery(int uid); |
134 | FindQuery(const QArray<int>& ); | 137 | FindQuery(const QArray<int>& ); |
135 | ~FindQuery(); | 138 | ~FindQuery(); |
136 | QString query()const; | 139 | QString query()const; |
137 | private: | 140 | private: |
138 | QString single()const; | 141 | QString single()const; |
139 | QString multi()const; | 142 | QString multi()const; |
140 | QArray<int> m_uids; | 143 | QArray<int> m_uids; |
141 | int m_uid; | 144 | int m_uid; |
142 | }; | 145 | }; |
143 | 146 | ||
144 | /** | 147 | /** |
145 | * a find query for custom elements | 148 | * a find query for custom elements |
146 | */ | 149 | */ |
147 | class FindCustomQuery : public OSQLQuery { | 150 | class FindCustomQuery : public OSQLQuery { |
148 | public: | 151 | public: |
149 | FindCustomQuery(int uid); | 152 | FindCustomQuery(int uid); |
150 | FindCustomQuery(const QArray<int>& ); | 153 | FindCustomQuery(const QArray<int>& ); |
151 | ~FindCustomQuery(); | 154 | ~FindCustomQuery(); |
152 | QString query()const; | 155 | QString query()const; |
153 | private: | 156 | private: |
154 | QString single()const; | 157 | QString single()const; |
155 | QString multi()const; | 158 | QString multi()const; |
156 | QArray<int> m_uids; | 159 | QArray<int> m_uids; |
157 | int m_uid; | 160 | int m_uid; |
158 | }; | 161 | }; |
159 | 162 | ||
160 | 163 | ||
161 | 164 | ||
162 | // We using three tables to store the information: | 165 | // We using three tables to store the information: |
163 | // 1. addressbook : It contains General information about the contact (non custom) | 166 | // 1. addressbook : It contains General information about the contact (non custom) |
164 | // 2. custom_data : Not official supported entries | 167 | // 2. custom_data : Not official supported entries |
165 | // All tables are connected by the uid of the contact. | 168 | // All tables are connected by the uid of the contact. |
166 | // Maybe I should add a table for meta-information ? | 169 | // Maybe I should add a table for meta-information ? |
167 | CreateQuery::CreateQuery() : OSQLQuery() {} | 170 | CreateQuery::CreateQuery() : OSQLQuery() {} |
168 | CreateQuery::~CreateQuery() {} | 171 | CreateQuery::~CreateQuery() {} |
169 | QString CreateQuery::query()const { | 172 | QString CreateQuery::query()const { |
170 | QString qu; | 173 | QString qu; |
171 | #ifdef __STORE_HORIZONTAL_ | 174 | #ifdef __STORE_HORIZONTAL_ |
172 | 175 | ||
173 | qu += "create table addressbook( uid PRIMARY KEY "; | 176 | qu += "create table addressbook( uid PRIMARY KEY "; |
174 | 177 | ||
175 | QStringList fieldList = OContactFields::untrfields( false ); | 178 | QStringList fieldList = OContactFields::untrfields( false ); |
176 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 179 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
177 | qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); | 180 | qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); |
178 | } | 181 | } |
179 | qu += " );"; | 182 | qu += " );"; |
180 | 183 | ||
181 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; | 184 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; |
182 | 185 | ||
183 | #else | 186 | #else |
184 | 187 | ||
185 | qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));"; | 188 | qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));"; |
186 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; | 189 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; |
187 | // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );"; | 190 | // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );"; |
188 | 191 | ||
189 | #endif // __STORE_HORIZONTAL_ | 192 | #endif // __STORE_HORIZONTAL_ |
190 | return qu; | 193 | return qu; |
191 | } | 194 | } |
192 | 195 | ||
193 | ClearQuery::ClearQuery() | 196 | ClearQuery::ClearQuery() |
194 | : OSQLQuery() {} | 197 | : OSQLQuery() {} |
195 | ClearQuery::~ClearQuery() {} | 198 | ClearQuery::~ClearQuery() {} |
196 | QString ClearQuery::query()const { | 199 | QString ClearQuery::query()const { |
197 | QString qu = "drop table addressbook;"; | 200 | QString qu = "drop table addressbook;"; |
198 | qu += "drop table custom_data;"; | 201 | qu += "drop table custom_data;"; |
199 | // qu += "drop table dates;"; | 202 | // qu += "drop table dates;"; |
200 | return qu; | 203 | return qu; |
201 | } | 204 | } |
202 | 205 | ||
203 | 206 | ||
204 | LoadQuery::LoadQuery() : OSQLQuery() {} | 207 | LoadQuery::LoadQuery() : OSQLQuery() {} |
205 | LoadQuery::~LoadQuery() {} | 208 | LoadQuery::~LoadQuery() {} |
206 | QString LoadQuery::query()const { | 209 | QString LoadQuery::query()const { |
207 | QString qu; | 210 | QString qu; |
208 | #ifdef __STORE_HORIZONTAL_ | 211 | #ifdef __STORE_HORIZONTAL_ |
@@ -265,406 +268,412 @@ namespace { | |||
265 | // These entries should stored in a special format | 268 | // These entries should stored in a special format |
266 | // year-month-day | 269 | // year-month-day |
267 | QDate day = m_contact.anniversary(); | 270 | QDate day = m_contact.anniversary(); |
268 | if ( day.isValid() ){ | 271 | if ( day.isValid() ){ |
269 | qu += QString(",\"%1-%2-%3\"") | 272 | qu += QString(",\"%1-%2-%3\"") |
270 | .arg( day.year() ) | 273 | .arg( day.year() ) |
271 | .arg( day.month() ) | 274 | .arg( day.month() ) |
272 | .arg( day.day() ); | 275 | .arg( day.day() ); |
273 | } else { | 276 | } else { |
274 | qu += ",\"\""; | 277 | qu += ",\"\""; |
275 | } | 278 | } |
276 | } | 279 | } |
277 | break; | 280 | break; |
278 | 281 | ||
279 | default: | 282 | default: |
280 | qu += QString( ",\"%1\"" ).arg( contactMap[id] ); | 283 | qu += QString( ",\"%1\"" ).arg( contactMap[id] ); |
281 | } | 284 | } |
282 | } | 285 | } |
283 | qu += " );"; | 286 | qu += " );"; |
284 | 287 | ||
285 | 288 | ||
286 | #else | 289 | #else |
287 | // Get all information out of the contact-class | 290 | // Get all information out of the contact-class |
288 | // Remember: The category is stored in contactMap, too ! | 291 | // Remember: The category is stored in contactMap, too ! |
289 | QMap<int, QString> contactMap = m_contact.toMap(); | 292 | QMap<int, QString> contactMap = m_contact.toMap(); |
290 | 293 | ||
291 | QMap<QString, QString> addressbook_db; | 294 | QMap<QString, QString> addressbook_db; |
292 | 295 | ||
293 | // Get the translation from the ID to the String | 296 | // Get the translation from the ID to the String |
294 | QMap<int, QString> transMap = OContactFields::idToUntrFields(); | 297 | QMap<int, QString> transMap = OContactFields::idToUntrFields(); |
295 | 298 | ||
296 | for( QMap<int, QString>::Iterator it = contactMap.begin(); | 299 | for( QMap<int, QString>::Iterator it = contactMap.begin(); |
297 | it != contactMap.end(); ++it ){ | 300 | it != contactMap.end(); ++it ){ |
298 | switch ( it.key() ){ | 301 | switch ( it.key() ){ |
299 | case Qtopia::Birthday:{ | 302 | case Qtopia::Birthday:{ |
300 | // These entries should stored in a special format | 303 | // These entries should stored in a special format |
301 | // year-month-day | 304 | // year-month-day |
302 | QDate day = m_contact.birthday(); | 305 | QDate day = m_contact.birthday(); |
303 | addressbook_db.insert( transMap[it.key()], | 306 | addressbook_db.insert( transMap[it.key()], |
304 | QString("%1-%2-%3") | 307 | QString("%1-%2-%3") |
305 | .arg( day.year() ) | 308 | .arg( day.year() ) |
306 | .arg( day.month() ) | 309 | .arg( day.month() ) |
307 | .arg( day.day() ) ); | 310 | .arg( day.day() ) ); |
308 | } | 311 | } |
309 | break; | 312 | break; |
310 | case Qtopia::Anniversary:{ | 313 | case Qtopia::Anniversary:{ |
311 | // These entries should stored in a special format | 314 | // These entries should stored in a special format |
312 | // year-month-day | 315 | // year-month-day |
313 | QDate day = m_contact.anniversary(); | 316 | QDate day = m_contact.anniversary(); |
314 | addressbook_db.insert( transMap[it.key()], | 317 | addressbook_db.insert( transMap[it.key()], |
315 | QString("%1-%2-%3") | 318 | QString("%1-%2-%3") |
316 | .arg( day.year() ) | 319 | .arg( day.year() ) |
317 | .arg( day.month() ) | 320 | .arg( day.month() ) |
318 | .arg( day.day() ) ); | 321 | .arg( day.day() ) ); |
319 | } | 322 | } |
320 | break; | 323 | break; |
321 | case Qtopia::AddressUid: // Ignore UID | 324 | case Qtopia::AddressUid: // Ignore UID |
322 | break; | 325 | break; |
323 | default: // Translate id to String | 326 | default: // Translate id to String |
324 | addressbook_db.insert( transMap[it.key()], it.data() ); | 327 | addressbook_db.insert( transMap[it.key()], it.data() ); |
325 | break; | 328 | break; |
326 | } | 329 | } |
327 | 330 | ||
328 | } | 331 | } |
329 | 332 | ||
330 | // Now convert this whole stuff into a SQL String, beginning with | 333 | // Now convert this whole stuff into a SQL String, beginning with |
331 | // the addressbook table.. | 334 | // the addressbook table.. |
332 | QString qu; | 335 | QString qu; |
333 | // qu += "begin transaction;"; | 336 | // qu += "begin transaction;"; |
334 | int id = 0; | 337 | int id = 0; |
335 | for( QMap<QString, QString>::Iterator it = addressbook_db.begin(); | 338 | for( QMap<QString, QString>::Iterator it = addressbook_db.begin(); |
336 | it != addressbook_db.end(); ++it ){ | 339 | it != addressbook_db.end(); ++it ){ |
337 | qu += "insert into addressbook VALUES(" | 340 | qu += "insert into addressbook VALUES(" |
338 | + QString::number( m_contact.uid() ) | 341 | + QString::number( m_contact.uid() ) |
339 | + "," | 342 | + "," |
340 | + QString::number( id++ ) | 343 | + QString::number( id++ ) |
341 | + ",'" | 344 | + ",'" |
342 | + it.key() //.latin1() | 345 | + it.key() //.latin1() |
343 | + "'," | 346 | + "'," |
344 | + "0" // Priority for future enhancements | 347 | + "0" // Priority for future enhancements |
345 | + ",'" | 348 | + ",'" |
346 | + it.data() //.latin1() | 349 | + it.data() //.latin1() |
347 | + "');"; | 350 | + "');"; |
348 | } | 351 | } |
349 | 352 | ||
350 | #endif //__STORE_HORIZONTAL_ | 353 | #endif //__STORE_HORIZONTAL_ |
351 | // Now add custom data.. | 354 | // Now add custom data.. |
352 | #ifdef __STORE_HORIZONTAL_ | 355 | #ifdef __STORE_HORIZONTAL_ |
353 | int id = 0; | 356 | int id = 0; |
354 | #endif | 357 | #endif |
355 | id = 0; | 358 | id = 0; |
356 | QMap<QString, QString> customMap = m_contact.toExtraMap(); | 359 | QMap<QString, QString> customMap = m_contact.toExtraMap(); |
357 | for( QMap<QString, QString>::Iterator it = customMap.begin(); | 360 | for( QMap<QString, QString>::Iterator it = customMap.begin(); |
358 | it != customMap.end(); ++it ){ | 361 | it != customMap.end(); ++it ){ |
359 | qu += "insert into custom_data VALUES(" | 362 | qu += "insert into custom_data VALUES(" |
360 | + QString::number( m_contact.uid() ) | 363 | + QString::number( m_contact.uid() ) |
361 | + "," | 364 | + "," |
362 | + QString::number( id++ ) | 365 | + QString::number( id++ ) |
363 | + ",'" | 366 | + ",'" |
364 | + it.key() //.latin1() | 367 | + it.key() //.latin1() |
365 | + "'," | 368 | + "'," |
366 | + "0" // Priority for future enhancements | 369 | + "0" // Priority for future enhancements |
367 | + ",'" | 370 | + ",'" |
368 | + it.data() //.latin1() | 371 | + it.data() //.latin1() |
369 | + "');"; | 372 | + "');"; |
370 | } | 373 | } |
371 | // qu += "commit;"; | 374 | // qu += "commit;"; |
372 | qWarning("add %s", qu.latin1() ); | 375 | qWarning("add %s", qu.latin1() ); |
373 | return qu; | 376 | return qu; |
374 | } | 377 | } |
375 | 378 | ||
376 | 379 | ||
377 | RemoveQuery::RemoveQuery(int uid ) | 380 | RemoveQuery::RemoveQuery(int uid ) |
378 | : OSQLQuery(), m_uid( uid ) {} | 381 | : OSQLQuery(), m_uid( uid ) {} |
379 | RemoveQuery::~RemoveQuery() {} | 382 | RemoveQuery::~RemoveQuery() {} |
380 | QString RemoveQuery::query()const { | 383 | QString RemoveQuery::query()const { |
381 | QString qu = "DELETE from addressbook where uid = " | 384 | QString qu = "DELETE from addressbook where uid = " |
382 | + QString::number(m_uid) + ";"; | 385 | + QString::number(m_uid) + ";"; |
383 | qu += "DELETE from custom_data where uid = " | 386 | qu += "DELETE from custom_data where uid = " |
384 | + QString::number(m_uid) + ";"; | 387 | + QString::number(m_uid) + ";"; |
385 | return qu; | 388 | return qu; |
386 | } | 389 | } |
387 | 390 | ||
388 | 391 | ||
389 | 392 | ||
390 | 393 | ||
391 | FindQuery::FindQuery(int uid) | 394 | FindQuery::FindQuery(int uid) |
392 | : OSQLQuery(), m_uid( uid ) { | 395 | : OSQLQuery(), m_uid( uid ) { |
393 | } | 396 | } |
394 | FindQuery::FindQuery(const QArray<int>& ints) | 397 | FindQuery::FindQuery(const QArray<int>& ints) |
395 | : OSQLQuery(), m_uids( ints ){ | 398 | : OSQLQuery(), m_uids( ints ){ |
396 | } | 399 | } |
397 | FindQuery::~FindQuery() { | 400 | FindQuery::~FindQuery() { |
398 | } | 401 | } |
399 | QString FindQuery::query()const{ | 402 | QString FindQuery::query()const{ |
400 | // if ( m_uids.count() == 0 ) | 403 | // if ( m_uids.count() == 0 ) |
401 | return single(); | 404 | return single(); |
402 | } | 405 | } |
403 | /* | 406 | /* |
404 | else | 407 | else |
405 | return multi(); | 408 | return multi(); |
406 | } | 409 | } |
407 | QString FindQuery::multi()const { | 410 | QString FindQuery::multi()const { |
408 | QString qu = "select uid, type, value from addressbook where"; | 411 | QString qu = "select uid, type, value from addressbook where"; |
409 | for (uint i = 0; i < m_uids.count(); i++ ) { | 412 | for (uint i = 0; i < m_uids.count(); i++ ) { |
410 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | 413 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; |
411 | } | 414 | } |
412 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. | 415 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. |
413 | return qu; | 416 | return qu; |
414 | } | 417 | } |
415 | */ | 418 | */ |
416 | #ifdef __STORE_HORIZONTAL_ | 419 | #ifdef __STORE_HORIZONTAL_ |
417 | QString FindQuery::single()const{ | 420 | QString FindQuery::single()const{ |
418 | QString qu = "select *"; | 421 | QString qu = "select *"; |
419 | qu += " from addressbook where uid = " + QString::number(m_uid); | 422 | qu += " from addressbook where uid = " + QString::number(m_uid); |
420 | 423 | ||
421 | // qWarning("find query: %s", qu.latin1() ); | 424 | // qWarning("find query: %s", qu.latin1() ); |
422 | return qu; | 425 | return qu; |
423 | } | 426 | } |
424 | #else | 427 | #else |
425 | QString FindQuery::single()const{ | 428 | QString FindQuery::single()const{ |
426 | QString qu = "select uid, type, value from addressbook where uid = "; | 429 | QString qu = "select uid, type, value from addressbook where uid = "; |
427 | qu += QString::number(m_uid); | 430 | qu += QString::number(m_uid); |
428 | return qu; | 431 | return qu; |
429 | } | 432 | } |
430 | #endif | 433 | #endif |
431 | 434 | ||
432 | 435 | ||
433 | FindCustomQuery::FindCustomQuery(int uid) | 436 | FindCustomQuery::FindCustomQuery(int uid) |
434 | : OSQLQuery(), m_uid( uid ) { | 437 | : OSQLQuery(), m_uid( uid ) { |
435 | } | 438 | } |
436 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) | 439 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) |
437 | : OSQLQuery(), m_uids( ints ){ | 440 | : OSQLQuery(), m_uids( ints ){ |
438 | } | 441 | } |
439 | FindCustomQuery::~FindCustomQuery() { | 442 | FindCustomQuery::~FindCustomQuery() { |
440 | } | 443 | } |
441 | QString FindCustomQuery::query()const{ | 444 | QString FindCustomQuery::query()const{ |
442 | // if ( m_uids.count() == 0 ) | 445 | // if ( m_uids.count() == 0 ) |
443 | return single(); | 446 | return single(); |
444 | } | 447 | } |
445 | QString FindCustomQuery::single()const{ | 448 | QString FindCustomQuery::single()const{ |
446 | QString qu = "select uid, type, value from custom_data where uid = "; | 449 | QString qu = "select uid, type, value from custom_data where uid = "; |
447 | qu += QString::number(m_uid); | 450 | qu += QString::number(m_uid); |
448 | return qu; | 451 | return qu; |
449 | } | 452 | } |
450 | 453 | ||
451 | }; | 454 | }; |
452 | 455 | ||
453 | 456 | ||
454 | /* --------------------------------------------------------------------------- */ | 457 | /* --------------------------------------------------------------------------- */ |
455 | 458 | ||
456 | OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, | 459 | OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, |
457 | const QString& filename ): m_changed(false) | 460 | const QString& filename ): |
461 | OContactAccessBackend(), m_changed(false), m_driver( NULL ) | ||
458 | { | 462 | { |
459 | qWarning("C'tor OContactAccessBackend_SQL starts"); | 463 | qWarning("C'tor OContactAccessBackend_SQL starts"); |
460 | QTime t; | 464 | QTime t; |
461 | t.start(); | 465 | t.start(); |
462 | 466 | ||
463 | /* Expecting to access the default filename if nothing else is set */ | 467 | /* Expecting to access the default filename if nothing else is set */ |
464 | if ( filename.isEmpty() ){ | 468 | if ( filename.isEmpty() ){ |
465 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); | 469 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); |
466 | } else | 470 | } else |
467 | m_fileName = filename; | 471 | m_fileName = filename; |
468 | 472 | ||
469 | // Get the standart sql-driver from the OSQLManager.. | 473 | // Get the standart sql-driver from the OSQLManager.. |
470 | OSQLManager man; | 474 | OSQLManager man; |
471 | m_driver = man.standard(); | 475 | m_driver = man.standard(); |
472 | m_driver->setUrl( m_fileName ); | 476 | m_driver->setUrl( m_fileName ); |
473 | 477 | ||
474 | load(); | 478 | load(); |
475 | 479 | ||
476 | qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); | 480 | qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); |
477 | } | 481 | } |
478 | 482 | ||
483 | OContactAccessBackend_SQL::~OContactAccessBackend_SQL () | ||
484 | { | ||
485 | if( m_driver ) | ||
486 | delete m_driver; | ||
487 | } | ||
479 | 488 | ||
480 | bool OContactAccessBackend_SQL::load () | 489 | bool OContactAccessBackend_SQL::load () |
481 | { | 490 | { |
482 | if (!m_driver->open() ) | 491 | if (!m_driver->open() ) |
483 | return false; | 492 | return false; |
484 | 493 | ||
485 | // Don't expect that the database exists. | 494 | // Don't expect that the database exists. |
486 | // It is save here to create the table, even if it | 495 | // It is save here to create the table, even if it |
487 | // do exist. ( Is that correct for all databases ?? ) | 496 | // do exist. ( Is that correct for all databases ?? ) |
488 | CreateQuery creat; | 497 | CreateQuery creat; |
489 | OSQLResult res = m_driver->query( &creat ); | 498 | OSQLResult res = m_driver->query( &creat ); |
490 | 499 | ||
491 | update(); | 500 | update(); |
492 | 501 | ||
493 | return true; | 502 | return true; |
494 | 503 | ||
495 | } | 504 | } |
496 | 505 | ||
497 | bool OContactAccessBackend_SQL::reload() | 506 | bool OContactAccessBackend_SQL::reload() |
498 | { | 507 | { |
499 | return load(); | 508 | return load(); |
500 | } | 509 | } |
501 | 510 | ||
502 | bool OContactAccessBackend_SQL::save() | 511 | bool OContactAccessBackend_SQL::save() |
503 | { | 512 | { |
504 | return m_driver->close(); | 513 | return m_driver->close(); |
505 | } | 514 | } |
506 | 515 | ||
507 | 516 | ||
508 | void OContactAccessBackend_SQL::clear () | 517 | void OContactAccessBackend_SQL::clear () |
509 | { | 518 | { |
510 | ClearQuery cle; | 519 | ClearQuery cle; |
511 | OSQLResult res = m_driver->query( &cle ); | 520 | OSQLResult res = m_driver->query( &cle ); |
512 | CreateQuery qu; | 521 | CreateQuery qu; |
513 | res = m_driver->query(&qu); | 522 | res = m_driver->query(&qu); |
514 | } | 523 | } |
515 | 524 | ||
516 | bool OContactAccessBackend_SQL::wasChangedExternally() | 525 | bool OContactAccessBackend_SQL::wasChangedExternally() |
517 | { | 526 | { |
518 | return false; | 527 | return false; |
519 | } | 528 | } |
520 | 529 | ||
521 | QArray<int> OContactAccessBackend_SQL::allRecords() const | 530 | QArray<int> OContactAccessBackend_SQL::allRecords() const |
522 | { | 531 | { |
523 | 532 | ||
524 | // FIXME: Think about cute handling of changed tables.. | 533 | // FIXME: Think about cute handling of changed tables.. |
525 | // Thus, we don't have to call update here... | 534 | // Thus, we don't have to call update here... |
526 | if ( m_changed ) | 535 | if ( m_changed ) |
527 | ((OContactAccessBackend_SQL*)this)->update(); | 536 | ((OContactAccessBackend_SQL*)this)->update(); |
528 | 537 | ||
529 | return m_uids; | 538 | return m_uids; |
530 | } | 539 | } |
531 | 540 | ||
532 | bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) | 541 | bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) |
533 | { | 542 | { |
534 | InsertQuery ins( newcontact ); | 543 | InsertQuery ins( newcontact ); |
535 | OSQLResult res = m_driver->query( &ins ); | 544 | OSQLResult res = m_driver->query( &ins ); |
536 | 545 | ||
537 | if ( res.state() == OSQLResult::Failure ) | 546 | if ( res.state() == OSQLResult::Failure ) |
538 | return false; | 547 | return false; |
539 | 548 | ||
540 | int c = m_uids.count(); | 549 | int c = m_uids.count(); |
541 | m_uids.resize( c+1 ); | 550 | m_uids.resize( c+1 ); |
542 | m_uids[c] = newcontact.uid(); | 551 | m_uids[c] = newcontact.uid(); |
543 | 552 | ||
544 | return true; | 553 | return true; |
545 | } | 554 | } |
546 | 555 | ||
547 | 556 | ||
548 | bool OContactAccessBackend_SQL::remove ( int uid ) | 557 | bool OContactAccessBackend_SQL::remove ( int uid ) |
549 | { | 558 | { |
550 | RemoveQuery rem( uid ); | 559 | RemoveQuery rem( uid ); |
551 | OSQLResult res = m_driver->query(&rem ); | 560 | OSQLResult res = m_driver->query(&rem ); |
552 | 561 | ||
553 | if ( res.state() == OSQLResult::Failure ) | 562 | if ( res.state() == OSQLResult::Failure ) |
554 | return false; | 563 | return false; |
555 | 564 | ||
556 | m_changed = true; | 565 | m_changed = true; |
557 | 566 | ||
558 | return true; | 567 | return true; |
559 | } | 568 | } |
560 | 569 | ||
561 | bool OContactAccessBackend_SQL::replace ( const OContact &contact ) | 570 | bool OContactAccessBackend_SQL::replace ( const OContact &contact ) |
562 | { | 571 | { |
563 | if ( !remove( contact.uid() ) ) | 572 | if ( !remove( contact.uid() ) ) |
564 | return false; | 573 | return false; |
565 | 574 | ||
566 | return add( contact ); | 575 | return add( contact ); |
567 | } | 576 | } |
568 | 577 | ||
569 | 578 | ||
570 | OContact OContactAccessBackend_SQL::find ( int uid ) const | 579 | OContact OContactAccessBackend_SQL::find ( int uid ) const |
571 | { | 580 | { |
572 | qWarning("OContactAccessBackend_SQL::find()"); | 581 | qWarning("OContactAccessBackend_SQL::find()"); |
573 | QTime t; | 582 | QTime t; |
574 | t.start(); | 583 | t.start(); |
575 | 584 | ||
576 | OContact retContact( requestNonCustom( uid ) ); | 585 | OContact retContact( requestNonCustom( uid ) ); |
577 | retContact.setExtraMap( requestCustom( uid ) ); | 586 | retContact.setExtraMap( requestCustom( uid ) ); |
578 | 587 | ||
579 | qWarning("OContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() ); | 588 | qWarning("OContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() ); |
580 | return retContact; | 589 | return retContact; |
581 | } | 590 | } |
582 | 591 | ||
583 | 592 | ||
584 | 593 | ||
585 | QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ) | 594 | QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ) |
586 | { | 595 | { |
587 | QString qu = "SELECT uid FROM addressbook WHERE"; | 596 | QString qu = "SELECT uid FROM addressbook WHERE"; |
588 | 597 | ||
589 | QMap<int, QString> queryFields = query.toMap(); | 598 | QMap<int, QString> queryFields = query.toMap(); |
590 | QStringList fieldList = OContactFields::untrfields( false ); | 599 | QStringList fieldList = OContactFields::untrfields( false ); |
591 | QMap<QString, int> translate = OContactFields::untrFieldsToId(); | 600 | QMap<QString, int> translate = OContactFields::untrFieldsToId(); |
592 | 601 | ||
593 | // Convert every filled field to a SQL-Query | 602 | // Convert every filled field to a SQL-Query |
594 | bool isAnyFieldSelected = false; | 603 | bool isAnyFieldSelected = false; |
595 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 604 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
596 | int id = translate[*it]; | 605 | int id = translate[*it]; |
597 | QString queryStr = queryFields[id]; | 606 | QString queryStr = queryFields[id]; |
598 | if ( !queryStr.isEmpty() ){ | 607 | if ( !queryStr.isEmpty() ){ |
599 | isAnyFieldSelected = true; | 608 | isAnyFieldSelected = true; |
600 | switch( id ){ | 609 | switch( id ){ |
601 | default: | 610 | default: |
602 | // Switching between case sensitive and insensitive... | 611 | // Switching between case sensitive and insensitive... |
603 | // LIKE is not case sensitive, GLOB is case sensitive | 612 | // LIKE is not case sensitive, GLOB is case sensitive |
604 | // Do exist a better solution to switch this ? | 613 | // Do exist a better solution to switch this ? |
605 | if ( settings & OContactAccess::IgnoreCase ) | 614 | if ( settings & OContactAccess::IgnoreCase ) |
606 | qu += "(\"" + *it + "\"" + " LIKE " + "'" | 615 | qu += "(\"" + *it + "\"" + " LIKE " + "'" |
607 | + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND "; | 616 | + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND "; |
608 | else | 617 | else |
609 | qu += "(\"" + *it + "\"" + " GLOB " + "'" | 618 | qu += "(\"" + *it + "\"" + " GLOB " + "'" |
610 | + queryStr + "'" + ") AND "; | 619 | + queryStr + "'" + ") AND "; |
611 | 620 | ||
612 | } | 621 | } |
613 | } | 622 | } |
614 | } | 623 | } |
615 | // Skip trailing "AND" | 624 | // Skip trailing "AND" |
616 | if ( isAnyFieldSelected ) | 625 | if ( isAnyFieldSelected ) |
617 | qu = qu.left( qu.length() - 4 ); | 626 | qu = qu.left( qu.length() - 4 ); |
618 | 627 | ||
619 | qWarning( "queryByExample query: %s", qu.latin1() ); | 628 | qWarning( "queryByExample query: %s", qu.latin1() ); |
620 | 629 | ||
621 | // Execute query and return the received uid's | 630 | // Execute query and return the received uid's |
622 | OSQLRawQuery raw( qu ); | 631 | OSQLRawQuery raw( qu ); |
623 | OSQLResult res = m_driver->query( &raw ); | 632 | OSQLResult res = m_driver->query( &raw ); |
624 | if ( res.state() != OSQLResult::Success ){ | 633 | if ( res.state() != OSQLResult::Success ){ |
625 | QArray<int> empty; | 634 | QArray<int> empty; |
626 | return empty; | 635 | return empty; |
627 | } | 636 | } |
628 | 637 | ||
629 | QArray<int> list = extractUids( res ); | 638 | QArray<int> list = extractUids( res ); |
630 | 639 | ||
631 | return list; | 640 | return list; |
632 | } | 641 | } |
633 | 642 | ||
634 | QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | 643 | QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const |
635 | { | 644 | { |
636 | QArray<int> nix(0); | 645 | QArray<int> nix(0); |
637 | return nix; | 646 | return nix; |
638 | } | 647 | } |
639 | 648 | ||
640 | const uint OContactAccessBackend_SQL::querySettings() | 649 | const uint OContactAccessBackend_SQL::querySettings() |
641 | { | 650 | { |
642 | return OContactAccess::IgnoreCase | 651 | return OContactAccess::IgnoreCase |
643 | || OContactAccess::WildCards; | 652 | || OContactAccess::WildCards; |
644 | } | 653 | } |
645 | 654 | ||
646 | bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const | 655 | bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const |
647 | { | 656 | { |
648 | /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay | 657 | /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay |
649 | * may be added with any of the other settings. IgnoreCase should never used alone. | 658 | * may be added with any of the other settings. IgnoreCase should never used alone. |
650 | * Wildcards, RegExp, ExactMatch should never used at the same time... | 659 | * Wildcards, RegExp, ExactMatch should never used at the same time... |
651 | */ | 660 | */ |
652 | 661 | ||
653 | // Step 1: Check whether the given settings are supported by this backend | 662 | // Step 1: Check whether the given settings are supported by this backend |
654 | if ( ( querySettings & ( | 663 | if ( ( querySettings & ( |
655 | OContactAccess::IgnoreCase | 664 | OContactAccess::IgnoreCase |
656 | | OContactAccess::WildCards | 665 | | OContactAccess::WildCards |
657 | // | OContactAccess::DateDiff | 666 | // | OContactAccess::DateDiff |
658 | // | OContactAccess::DateYear | 667 | // | OContactAccess::DateYear |
659 | // | OContactAccess::DateMonth | 668 | // | OContactAccess::DateMonth |
660 | // | OContactAccess::DateDay | 669 | // | OContactAccess::DateDay |
661 | // | OContactAccess::RegExp | 670 | // | OContactAccess::RegExp |
662 | // | OContactAccess::ExactMatch | 671 | // | OContactAccess::ExactMatch |
663 | ) ) != querySettings ) | 672 | ) ) != querySettings ) |
664 | return false; | 673 | return false; |
665 | 674 | ||
666 | // Step 2: Check whether the given combinations are ok.. | 675 | // Step 2: Check whether the given combinations are ok.. |
667 | 676 | ||
668 | // IngoreCase alone is invalid | 677 | // IngoreCase alone is invalid |
669 | if ( querySettings == OContactAccess::IgnoreCase ) | 678 | if ( querySettings == OContactAccess::IgnoreCase ) |
670 | return false; | 679 | return false; |
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h index bb22551..b8f1d8d 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h | |||
@@ -1,96 +1,101 @@ | |||
1 | /* | 1 | /* |
2 | * SQL Backend for the OPIE-Contact Database. | 2 | * SQL Backend for the OPIE-Contact Database. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | 4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) |
5 | * | 5 | * |
6 | * ===================================================================== | 6 | * ===================================================================== |
7 | *This program is free software; you can redistribute it and/or | 7 | *This program is free software; you can redistribute it and/or |
8 | *modify it under the terms of the GNU Library General Public | 8 | *modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either | 9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. | 10 | * version 2 of the License, or (at your option) any later version. |
11 | * ===================================================================== | 11 | * ===================================================================== |
12 | * | 12 | * |
13 | * | 13 | * |
14 | * ===================================================================== | 14 | * ===================================================================== |
15 | * Version: $Id$ | 15 | * Version: $Id$ |
16 | * ===================================================================== | 16 | * ===================================================================== |
17 | * History: | 17 | * History: |
18 | * $Log$ | 18 | * $Log$ |
19 | * Revision 1.2 2003/12/08 15:18:11 eilers | ||
20 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
21 | * | ||
19 | * Revision 1.1 2003/09/22 14:31:16 eilers | 22 | * Revision 1.1 2003/09/22 14:31:16 eilers |
20 | * Added first experimental incarnation of sql-backend for addressbook. | 23 | * Added first experimental incarnation of sql-backend for addressbook. |
21 | * Some modifications to be able to compile the todo sql-backend. | 24 | * Some modifications to be able to compile the todo sql-backend. |
22 | * A lot of changes fill follow... | 25 | * A lot of changes fill follow... |
23 | * | 26 | * |
24 | * | 27 | * |
25 | */ | 28 | */ |
26 | 29 | ||
27 | #ifndef _OContactAccessBackend_SQL_ | 30 | #ifndef _OContactAccessBackend_SQL_ |
28 | #define _OContactAccessBackend_SQL_ | 31 | #define _OContactAccessBackend_SQL_ |
29 | 32 | ||
30 | #include "ocontactaccessbackend.h" | 33 | #include "ocontactaccessbackend.h" |
31 | #include "ocontactaccess.h" | 34 | #include "ocontactaccess.h" |
32 | 35 | ||
33 | #include <qlist.h> | 36 | #include <qlist.h> |
34 | #include <qdict.h> | 37 | #include <qdict.h> |
35 | 38 | ||
36 | class OSQLDriver; | 39 | class OSQLDriver; |
37 | class OSQLResult; | 40 | class OSQLResult; |
38 | class OSQLResultItem; | 41 | class OSQLResultItem; |
39 | 42 | ||
40 | /* the default xml implementation */ | 43 | /* the default xml implementation */ |
41 | /** | 44 | /** |
42 | * This class is the SQL implementation of a Contact backend | 45 | * This class is the SQL implementation of a Contact backend |
43 | * it does implement everything available for OContact. | 46 | * it does implement everything available for OContact. |
44 | * @see OPimAccessBackend for more information of available methods | 47 | * @see OPimAccessBackend for more information of available methods |
45 | */ | 48 | */ |
46 | class OContactAccessBackend_SQL : public OContactAccessBackend { | 49 | class OContactAccessBackend_SQL : public OContactAccessBackend { |
47 | public: | 50 | public: |
48 | OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); | 51 | OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); |
49 | 52 | ||
53 | ~OContactAccessBackend_SQL (); | ||
54 | |||
50 | bool save(); | 55 | bool save(); |
51 | 56 | ||
52 | bool load (); | 57 | bool load (); |
53 | 58 | ||
54 | void clear (); | 59 | void clear (); |
55 | 60 | ||
56 | bool wasChangedExternally(); | 61 | bool wasChangedExternally(); |
57 | 62 | ||
58 | QArray<int> allRecords() const; | 63 | QArray<int> allRecords() const; |
59 | 64 | ||
60 | OContact find ( int uid ) const; | 65 | OContact find ( int uid ) const; |
61 | // FIXME: Add lookahead-cache support ! | 66 | // FIXME: Add lookahead-cache support ! |
62 | //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; | 67 | //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; |
63 | 68 | ||
64 | QArray<int> queryByExample ( const OContact &query, int settings, | 69 | QArray<int> queryByExample ( const OContact &query, int settings, |
65 | const QDateTime& d ); | 70 | const QDateTime& d ); |
66 | 71 | ||
67 | QArray<int> matchRegexp( const QRegExp &r ) const; | 72 | QArray<int> matchRegexp( const QRegExp &r ) const; |
68 | 73 | ||
69 | const uint querySettings(); | 74 | const uint querySettings(); |
70 | 75 | ||
71 | bool hasQuerySettings (uint querySettings) const; | 76 | bool hasQuerySettings (uint querySettings) const; |
72 | 77 | ||
73 | // Currently only asc implemented.. | 78 | // Currently only asc implemented.. |
74 | QArray<int> sorted( bool asc, int , int , int ); | 79 | QArray<int> sorted( bool asc, int , int , int ); |
75 | bool add ( const OContact &newcontact ); | 80 | bool add ( const OContact &newcontact ); |
76 | 81 | ||
77 | bool replace ( const OContact &contact ); | 82 | bool replace ( const OContact &contact ); |
78 | 83 | ||
79 | bool remove ( int uid ); | 84 | bool remove ( int uid ); |
80 | bool reload(); | 85 | bool reload(); |
81 | 86 | ||
82 | private: | 87 | private: |
83 | QArray<int> extractUids( OSQLResult& res ) const; | 88 | QArray<int> extractUids( OSQLResult& res ) const; |
84 | QMap<int, QString> requestNonCustom( int uid ) const; | 89 | QMap<int, QString> requestNonCustom( int uid ) const; |
85 | QMap<QString, QString> requestCustom( int uid ) const; | 90 | QMap<QString, QString> requestCustom( int uid ) const; |
86 | void update(); | 91 | void update(); |
87 | 92 | ||
88 | protected: | 93 | protected: |
89 | bool m_changed; | 94 | bool m_changed; |
90 | QString m_fileName; | 95 | QString m_fileName; |
91 | QArray<int> m_uids; | 96 | QArray<int> m_uids; |
92 | 97 | ||
93 | OSQLDriver* m_driver; | 98 | OSQLDriver* m_driver; |
94 | }; | 99 | }; |
95 | 100 | ||
96 | #endif | 101 | #endif |
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp new file mode 100644 index 0000000..9769bf7 --- a/dev/null +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * SQL Backend for the OPIE-Calender Database. | ||
3 | * | ||
4 | * Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * | ||
6 | * ===================================================================== | ||
7 | *This program is free software; you can redistribute it and/or | ||
8 | *modify it under the terms of the GNU Library General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2 of the License, or (at your option) any later version. | ||
11 | * ===================================================================== | ||
12 | * ===================================================================== | ||
13 | * Version: $Id$ | ||
14 | * ===================================================================== | ||
15 | * History: | ||
16 | * $Log$ | ||
17 | * Revision 1.1 2003/12/08 15:18:12 eilers | ||
18 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
19 | * | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | |||
26 | #include <qarray.h> | ||
27 | #include <qstringlist.h> | ||
28 | |||
29 | #include "orecur.h" | ||
30 | #include "odatebookaccessbackend_sql.h" | ||
31 | |||
32 | #include <opie2/osqldriver.h> | ||
33 | #include <opie2/osqlresult.h> | ||
34 | #include <opie2/osqlmanager.h> | ||
35 | #include <opie2/osqlquery.h> | ||
36 | |||
37 | namespace { | ||
38 | |||
39 | |||
40 | |||
41 | }; | ||
42 | |||
43 | ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , | ||
44 | const QString& fileName ) | ||
45 | : ODateBookAccessBackend(), m_driver( NULL ) | ||
46 | { | ||
47 | m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; | ||
48 | |||
49 | // Get the standart sql-driver from the OSQLManager.. | ||
50 | OSQLManager man; | ||
51 | m_driver = man.standard(); | ||
52 | m_driver->setUrl( m_fileName ); | ||
53 | |||
54 | initFields(); | ||
55 | |||
56 | load(); | ||
57 | } | ||
58 | |||
59 | ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { | ||
60 | } | ||
61 | |||
62 | void ODateBookAccessBackend_SQL::initFields() | ||
63 | { | ||
64 | |||
65 | // This map contains the translation of the fieldtype id's to | ||
66 | // the names of the table columns | ||
67 | m_fieldMap.insert( OEvent::FUid, "uid" ); | ||
68 | m_fieldMap.insert( OEvent::FCategories, "Categories" ); | ||
69 | m_fieldMap.insert( OEvent::FDescription, "Description" ); | ||
70 | m_fieldMap.insert( OEvent::FLocation, "Location" ); | ||
71 | m_fieldMap.insert( OEvent::FType, "Type" ); | ||
72 | m_fieldMap.insert( OEvent::FAlarm, "Alarm" ); | ||
73 | m_fieldMap.insert( OEvent::FSound, "Sound" ); | ||
74 | m_fieldMap.insert( OEvent::FRType, "RType" ); | ||
75 | m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" ); | ||
76 | m_fieldMap.insert( OEvent::FRPosition, "RPosition" ); | ||
77 | m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); | ||
78 | m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); | ||
79 | m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); | ||
80 | m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); | ||
81 | m_fieldMap.insert( OEvent::FRExeptions, "RExceptions" ); | ||
82 | m_fieldMap.insert( OEvent::FStart, "Start" ); | ||
83 | m_fieldMap.insert( OEvent::FEnd, "End" ); | ||
84 | m_fieldMap.insert( OEvent::FNote, "Note" ); | ||
85 | m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); | ||
86 | m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); | ||
87 | m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); | ||
88 | } | ||
89 | |||
90 | bool ODateBookAccessBackend_SQL::load() | ||
91 | { | ||
92 | if (!m_driver->open() ) | ||
93 | return false; | ||
94 | |||
95 | // Don't expect that the database exists. | ||
96 | // It is save here to create the table, even if it | ||
97 | // do exist. ( Is that correct for all databases ?? ) | ||
98 | QStringqu = "create table datebook( uid INTEGER PRIMARY KEY "; | ||
99 | |||
100 | QMap<int, QString>::Iterator it; | ||
101 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | ||
102 | qu += QString( ",\"%1\" VARCHAR(10)" ).arg( it.data() ); | ||
103 | } | ||
104 | qu += " );"; | ||
105 | |||
106 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; | ||
107 | |||
108 | OSQLRawQuery raw( qu ); | ||
109 | OSQLResult res = m_driver->query( &raw ); | ||
110 | if ( res.state() != OSQLResult::Success ) | ||
111 | return false; | ||
112 | |||
113 | update(); | ||
114 | |||
115 | return true; | ||
116 | } | ||
117 | |||
118 | void ODateBookAccessBackend_SQL::update() | ||
119 | { | ||
120 | |||
121 | QString qu = "select uid from datebook"; | ||
122 | OSQLRawQuery raw( qu ); | ||
123 | OSQLResult res = m_driver->query( &raw ); | ||
124 | if ( res.state() != OSQLResult::Success ){ | ||
125 | m_uids.clear(); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | m_uids = extractUids( res ); | ||
130 | |||
131 | } | ||
132 | |||
133 | QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const | ||
134 | { | ||
135 | qWarning("extractUids"); | ||
136 | |||
137 | OSQLResultItem::ValueList list = res.results(); | ||
138 | OSQLResultItem::ValueList::Iterator it; | ||
139 | QArray<int> ints(list.count() ); | ||
140 | qWarning(" count = %d", list.count() ); | ||
141 | |||
142 | int i = 0; | ||
143 | for (it = list.begin(); it != list.end(); ++it ) { | ||
144 | ints[i] = (*it).data("uid").toInt(); | ||
145 | i++; | ||
146 | } | ||
147 | |||
148 | return ints; | ||
149 | |||
150 | } | ||
151 | |||
152 | bool ODateBookAccessBackend_SQL::reload() | ||
153 | { | ||
154 | return load(); | ||
155 | } | ||
156 | |||
157 | bool ODateBookAccessBackend_SQL::save() | ||
158 | { | ||
159 | return m_driver->close(); | ||
160 | } | ||
161 | |||
162 | QArray<int> ODateBookAccessBackend_SQL::allRecords()const | ||
163 | { | ||
164 | return m_uids; | ||
165 | } | ||
166 | |||
167 | QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) { | ||
168 | return QArray<int>(); | ||
169 | } | ||
170 | |||
171 | void ODateBookAccessBackend_SQL::clear() | ||
172 | { | ||
173 | QString qu = "drop table datebook;"; | ||
174 | qu += "drop table custom_data;"; | ||
175 | |||
176 | OSQLRawQuery raw( qu ); | ||
177 | OSQLResult res = m_driver->query( &raw ); | ||
178 | |||
179 | } | ||
180 | |||
181 | |||
182 | OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ | ||
183 | } | ||
184 | |||
185 | bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) { | ||
186 | return true; | ||
187 | } | ||
188 | bool ODateBookAccessBackend_SQL::remove( int uid ) { | ||
189 | |||
190 | return true; | ||
191 | } | ||
192 | bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) { | ||
193 | remove( ev.uid() ); | ||
194 | return add( ev ); | ||
195 | } | ||
196 | QArray<int> ODateBookAccessBackend_SQL::rawEvents()const { | ||
197 | return allRecords(); | ||
198 | } | ||
199 | QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const { | ||
200 | |||
201 | return ints; | ||
202 | } | ||
203 | QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const { | ||
204 | |||
205 | return ints; | ||
206 | } | ||
207 | OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() { | ||
208 | |||
209 | return list; | ||
210 | } | ||
211 | OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() { | ||
212 | |||
213 | return list; | ||
214 | } | ||
215 | |||
216 | |||
217 | QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | ||
218 | { | ||
219 | |||
220 | return m_currentQuery; | ||
221 | } | ||
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h new file mode 100644 index 0000000..85e0d4f --- a/dev/null +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h | |||
@@ -0,0 +1,60 @@ | |||
1 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | ||
2 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | ||
3 | |||
4 | #include <qmap.h> | ||
5 | |||
6 | #include "odatebookaccessbackend.h" | ||
7 | |||
8 | class OSQLDriver; | ||
9 | |||
10 | /** | ||
11 | * This is the default SQL implementation for DateBoook SQL storage | ||
12 | * It fully implements the interface | ||
13 | * @see ODateBookAccessBackend | ||
14 | * @see OPimAccessBackend | ||
15 | */ | ||
16 | class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { | ||
17 | public: | ||
18 | ODateBookAccessBackend_SQL( const QString& appName, | ||
19 | const QString& fileName = QString::null); | ||
20 | ~ODateBookAccessBackend_SQL(); | ||
21 | |||
22 | bool load(); | ||
23 | bool reload(); | ||
24 | bool save(); | ||
25 | |||
26 | QArray<int> allRecords()const; | ||
27 | QArray<int> matchRegexp(const QRegExp &r) const; | ||
28 | QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() ); | ||
29 | OEvent find( int uid )const; | ||
30 | void clear(); | ||
31 | bool add( const OEvent& ev ); | ||
32 | bool remove( int uid ); | ||
33 | bool replace( const OEvent& ev ); | ||
34 | |||
35 | QArray<UID> rawEvents()const; | ||
36 | QArray<UID> rawRepeats()const; | ||
37 | QArray<UID> nonRepeats()const; | ||
38 | |||
39 | OEvent::ValueList directNonRepeats(); | ||
40 | OEvent::ValueList directRawRepeats(); | ||
41 | |||
42 | private: | ||
43 | bool loadFile(); | ||
44 | QString m_fileName; | ||
45 | QArray<int> m_uids; | ||
46 | |||
47 | QMap<int, QString> m_fieldMap; | ||
48 | |||
49 | OSQLDriver* m_driver; | ||
50 | |||
51 | class Private; | ||
52 | Private *d; | ||
53 | |||
54 | void initFields(); | ||
55 | void update(); | ||
56 | QArray<int> extractUids( OSQLResult& res ) const; | ||
57 | |||
58 | }; | ||
59 | |||
60 | #endif | ||
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp index 39c43c5..929d004 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp | |||
@@ -1,606 +1,612 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <fcntl.h> | 2 | #include <fcntl.h> |
3 | 3 | ||
4 | #include <stdio.h> | 4 | #include <stdio.h> |
5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | 6 | ||
7 | #include <sys/types.h> | 7 | #include <sys/types.h> |
8 | #include <sys/mman.h> | 8 | #include <sys/mman.h> |
9 | #include <sys/stat.h> | 9 | #include <sys/stat.h> |
10 | 10 | ||
11 | #include <unistd.h> | 11 | #include <unistd.h> |
12 | 12 | ||
13 | #include <qasciidict.h> | 13 | #include <qasciidict.h> |
14 | #include <qfile.h> | 14 | #include <qfile.h> |
15 | 15 | ||
16 | #include <qtopia/global.h> | 16 | #include <qtopia/global.h> |
17 | #include <qtopia/stringutil.h> | 17 | #include <qtopia/stringutil.h> |
18 | #include <qtopia/timeconversion.h> | 18 | #include <qtopia/timeconversion.h> |
19 | 19 | ||
20 | #include "opimnotifymanager.h" | 20 | #include "opimnotifymanager.h" |
21 | #include "orecur.h" | 21 | #include "orecur.h" |
22 | #include "otimezone.h" | 22 | #include "otimezone.h" |
23 | #include "odatebookaccessbackend_xml.h" | 23 | #include "odatebookaccessbackend_xml.h" |
24 | 24 | ||
25 | namespace { | 25 | namespace { |
26 | // FROM TT again | 26 | // FROM TT again |
27 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) | 27 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) |
28 | { | 28 | { |
29 | char needleChar; | 29 | char needleChar; |
30 | char haystackChar; | 30 | char haystackChar; |
31 | if (!needle || !haystack || !hLen || !nLen) | 31 | if (!needle || !haystack || !hLen || !nLen) |
32 | return 0; | 32 | return 0; |
33 | 33 | ||
34 | const char* hsearch = haystack; | 34 | const char* hsearch = haystack; |
35 | 35 | ||
36 | if ((needleChar = *needle++) != 0) { | 36 | if ((needleChar = *needle++) != 0) { |
37 | nLen--; //(to make up for needle++) | 37 | nLen--; //(to make up for needle++) |
38 | do { | 38 | do { |
39 | do { | 39 | do { |
40 | if ((haystackChar = *hsearch++) == 0) | 40 | if ((haystackChar = *hsearch++) == 0) |
41 | return (0); | 41 | return (0); |
42 | if (hsearch >= haystack + hLen) | 42 | if (hsearch >= haystack + hLen) |
43 | return (0); | 43 | return (0); |
44 | } while (haystackChar != needleChar); | 44 | } while (haystackChar != needleChar); |
45 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); | 45 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); |
46 | hsearch--; | 46 | hsearch--; |
47 | } | 47 | } |
48 | return ((char *)hsearch); | 48 | return ((char *)hsearch); |
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
52 | namespace { | 52 | namespace { |
53 | time_t start, end, created, rp_end; | 53 | time_t start, end, created, rp_end; |
54 | ORecur* rec; | 54 | ORecur* rec; |
55 | ORecur* recur() { | 55 | ORecur* recur() { |
56 | if (!rec) | 56 | if (!rec) |
57 | rec = new ORecur; | 57 | rec = new ORecur; |
58 | 58 | ||
59 | return rec; | 59 | return rec; |
60 | } | 60 | } |
61 | int alarmTime; | 61 | int alarmTime; |
62 | int snd; | 62 | int snd; |
63 | enum Attribute{ | 63 | enum Attribute{ |
64 | FDescription = 0, | 64 | FDescription = 0, |
65 | FLocation, | 65 | FLocation, |
66 | FCategories, | 66 | FCategories, |
67 | FUid, | 67 | FUid, |
68 | FType, | 68 | FType, |
69 | FAlarm, | 69 | FAlarm, |
70 | FSound, | 70 | FSound, |
71 | FRType, | 71 | FRType, |
72 | FRWeekdays, | 72 | FRWeekdays, |
73 | FRPosition, | 73 | FRPosition, |
74 | FRFreq, | 74 | FRFreq, |
75 | FRHasEndDate, | 75 | FRHasEndDate, |
76 | FREndDate, | 76 | FREndDate, |
77 | FRStart, | 77 | FRStart, |
78 | FREnd, | 78 | FREnd, |
79 | FNote, | 79 | FNote, |
80 | FCreated, | 80 | FCreated, // Should't this be called FRCreated ? |
81 | FTimeZone, | 81 | FTimeZone, |
82 | FRecParent, | 82 | FRecParent, |
83 | FRecChildren, | 83 | FRecChildren, |
84 | FExceptions | 84 | FExceptions |
85 | }; | 85 | }; |
86 | |||
87 | // FIXME: Use OEvent::toMap() here !! (eilers) | ||
86 | inline void save( const OEvent& ev, QString& buf ) { | 88 | inline void save( const OEvent& ev, QString& buf ) { |
87 | qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); | 89 | qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); |
88 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; | 90 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; |
89 | if (!ev.location().isEmpty() ) | 91 | if (!ev.location().isEmpty() ) |
90 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; | 92 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; |
91 | 93 | ||
92 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; | 94 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; |
93 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; | 95 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; |
94 | 96 | ||
95 | if (ev.isAllDay() ) | 97 | if (ev.isAllDay() ) |
96 | buf += " type=\"AllDay\""; // is that all ?? (eilers) | 98 | buf += " type=\"AllDay\""; // is that all ?? (eilers) |
97 | 99 | ||
98 | if (ev.hasNotifiers() ) { | 100 | if (ev.hasNotifiers() ) { |
99 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first | 101 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first |
100 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; | 102 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; |
101 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; | 103 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; |
102 | if ( alarm.sound() == OPimAlarm::Loud ) | 104 | if ( alarm.sound() == OPimAlarm::Loud ) |
103 | buf += "loud"; | 105 | buf += "loud"; |
104 | else | 106 | else |
105 | buf += "silent"; | 107 | buf += "silent"; |
106 | buf += "\""; | 108 | buf += "\""; |
107 | } | 109 | } |
108 | if ( ev.hasRecurrence() ) { | 110 | if ( ev.hasRecurrence() ) { |
109 | buf += ev.recurrence().toString(); | 111 | buf += ev.recurrence().toString(); |
110 | } | 112 | } |
111 | 113 | ||
112 | /* | 114 | /* |
113 | * fscking timezones :) well, we'll first convert | 115 | * fscking timezones :) well, we'll first convert |
114 | * the QDateTime to a QDateTime in UTC time | 116 | * the QDateTime to a QDateTime in UTC time |
115 | * and then we'll create a nice time_t | 117 | * and then we'll create a nice time_t |
116 | */ | 118 | */ |
117 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | 119 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); |
118 | buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; | 120 | buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; |
119 | buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; | 121 | buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; |
120 | if (!ev.note().isEmpty() ) { | 122 | if (!ev.note().isEmpty() ) { |
121 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; | 123 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; |
122 | } | 124 | } |
123 | 125 | ||
124 | buf += " timezone=\""; | 126 | buf += " timezone=\""; |
125 | if ( ev.timeZone().isEmpty() ) | 127 | if ( ev.timeZone().isEmpty() ) |
126 | buf += "None"; | 128 | buf += "None"; |
127 | else | 129 | else |
128 | buf += ev.timeZone(); | 130 | buf += ev.timeZone(); |
129 | buf += "\""; | 131 | buf += "\""; |
130 | 132 | ||
131 | if (ev.parent() != 0 ) { | 133 | if (ev.parent() != 0 ) { |
132 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; | 134 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; |
133 | } | 135 | } |
134 | 136 | ||
135 | if (ev.children().count() != 0 ) { | 137 | if (ev.children().count() != 0 ) { |
136 | QArray<int> children = ev.children(); | 138 | QArray<int> children = ev.children(); |
137 | buf += " recchildren=\""; | 139 | buf += " recchildren=\""; |
138 | for ( uint i = 0; i < children.count(); i++ ) { | 140 | for ( uint i = 0; i < children.count(); i++ ) { |
139 | if ( i != 0 ) buf += " "; | 141 | if ( i != 0 ) buf += " "; |
140 | buf += QString::number( children[i] ); | 142 | buf += QString::number( children[i] ); |
141 | } | 143 | } |
142 | buf+= "\""; | 144 | buf+= "\""; |
143 | } | 145 | } |
144 | 146 | ||
145 | // skip custom writing | 147 | // skip custom writing |
146 | } | 148 | } |
147 | 149 | ||
148 | inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) { | 150 | inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) { |
149 | QMap<int, OEvent>::ConstIterator it; | 151 | QMap<int, OEvent>::ConstIterator it; |
150 | QString buf; | 152 | QString buf; |
151 | QCString str; | 153 | QCString str; |
152 | int total_written; | 154 | int total_written; |
153 | for ( it = list.begin(); it != list.end(); ++it ) { | 155 | for ( it = list.begin(); it != list.end(); ++it ) { |
154 | buf = "<event"; | 156 | buf = "<event"; |
155 | save( it.data(), buf ); | 157 | save( it.data(), buf ); |
156 | buf += " />\n"; | 158 | buf += " />\n"; |
157 | str = buf.utf8(); | 159 | str = buf.utf8(); |
158 | 160 | ||
159 | total_written = file.writeBlock(str.data(), str.length() ); | 161 | total_written = file.writeBlock(str.data(), str.length() ); |
160 | if ( total_written != int(str.length() ) ) | 162 | if ( total_written != int(str.length() ) ) |
161 | return false; | 163 | return false; |
162 | } | 164 | } |
163 | return true; | 165 | return true; |
164 | } | 166 | } |
165 | } | 167 | } |
166 | 168 | ||
167 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , | 169 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , |
168 | const QString& fileName ) | 170 | const QString& fileName ) |
169 | : ODateBookAccessBackend() { | 171 | : ODateBookAccessBackend() { |
170 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; | 172 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; |
171 | m_changed = false; | 173 | m_changed = false; |
172 | } | 174 | } |
173 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { | 175 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { |
174 | } | 176 | } |
175 | bool ODateBookAccessBackend_XML::load() { | 177 | bool ODateBookAccessBackend_XML::load() { |
176 | return loadFile(); | 178 | return loadFile(); |
177 | } | 179 | } |
178 | bool ODateBookAccessBackend_XML::reload() { | 180 | bool ODateBookAccessBackend_XML::reload() { |
179 | clear(); | 181 | clear(); |
180 | return load(); | 182 | return load(); |
181 | } | 183 | } |
182 | bool ODateBookAccessBackend_XML::save() { | 184 | bool ODateBookAccessBackend_XML::save() { |
183 | if (!m_changed) return true; | 185 | if (!m_changed) return true; |
184 | 186 | ||
185 | int total_written; | 187 | int total_written; |
186 | QString strFileNew = m_name + ".new"; | 188 | QString strFileNew = m_name + ".new"; |
187 | 189 | ||
188 | QFile f( strFileNew ); | 190 | QFile f( strFileNew ); |
189 | if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; | 191 | if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; |
190 | 192 | ||
191 | QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); | 193 | QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); |
192 | buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; | 194 | buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; |
193 | buf += "<events>\n"; | 195 | buf += "<events>\n"; |
194 | QCString str = buf.utf8(); | 196 | QCString str = buf.utf8(); |
195 | total_written = f.writeBlock( str.data(), str.length() ); | 197 | total_written = f.writeBlock( str.data(), str.length() ); |
196 | if ( total_written != int(str.length() ) ) { | 198 | if ( total_written != int(str.length() ) ) { |
197 | f.close(); | 199 | f.close(); |
198 | QFile::remove( strFileNew ); | 200 | QFile::remove( strFileNew ); |
199 | return false; | 201 | return false; |
200 | } | 202 | } |
201 | 203 | ||
202 | if (!forAll( m_raw, f ) ) { | 204 | if (!forAll( m_raw, f ) ) { |
203 | f.close(); | 205 | f.close(); |
204 | QFile::remove( strFileNew ); | 206 | QFile::remove( strFileNew ); |
205 | return false; | 207 | return false; |
206 | } | 208 | } |
207 | if (!forAll( m_rep, f ) ) { | 209 | if (!forAll( m_rep, f ) ) { |
208 | f.close(); | 210 | f.close(); |
209 | QFile::remove( strFileNew ); | 211 | QFile::remove( strFileNew ); |
210 | return false; | 212 | return false; |
211 | } | 213 | } |
212 | 214 | ||
213 | buf = "</events>\n</DATEBOOK>\n"; | 215 | buf = "</events>\n</DATEBOOK>\n"; |
214 | str = buf.utf8(); | 216 | str = buf.utf8(); |
215 | total_written = f.writeBlock( str.data(), str.length() ); | 217 | total_written = f.writeBlock( str.data(), str.length() ); |
216 | if ( total_written != int(str.length() ) ) { | 218 | if ( total_written != int(str.length() ) ) { |
217 | f.close(); | 219 | f.close(); |
218 | QFile::remove( strFileNew ); | 220 | QFile::remove( strFileNew ); |
219 | return false; | 221 | return false; |
220 | } | 222 | } |
221 | f.close(); | 223 | f.close(); |
222 | 224 | ||
223 | if ( ::rename( strFileNew, m_name ) < 0 ) { | 225 | if ( ::rename( strFileNew, m_name ) < 0 ) { |
224 | QFile::remove( strFileNew ); | 226 | QFile::remove( strFileNew ); |
225 | return false; | 227 | return false; |
226 | } | 228 | } |
227 | 229 | ||
228 | m_changed = false; | 230 | m_changed = false; |
229 | return true; | 231 | return true; |
230 | } | 232 | } |
231 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { | 233 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { |
232 | QArray<int> ints( m_raw.count()+ m_rep.count() ); | 234 | QArray<int> ints( m_raw.count()+ m_rep.count() ); |
233 | uint i = 0; | 235 | uint i = 0; |
234 | QMap<int, OEvent>::ConstIterator it; | 236 | QMap<int, OEvent>::ConstIterator it; |
235 | 237 | ||
236 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 238 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
237 | ints[i] = it.key(); | 239 | ints[i] = it.key(); |
238 | i++; | 240 | i++; |
239 | } | 241 | } |
240 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 242 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
241 | ints[i] = it.key(); | 243 | ints[i] = it.key(); |
242 | i++; | 244 | i++; |
243 | } | 245 | } |
244 | 246 | ||
245 | return ints; | 247 | return ints; |
246 | } | 248 | } |
247 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int, const QDateTime& ) { | 249 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int, const QDateTime& ) { |
248 | return QArray<int>(); | 250 | return QArray<int>(); |
249 | } | 251 | } |
250 | void ODateBookAccessBackend_XML::clear() { | 252 | void ODateBookAccessBackend_XML::clear() { |
251 | m_changed = true; | 253 | m_changed = true; |
252 | m_raw.clear(); | 254 | m_raw.clear(); |
253 | m_rep.clear(); | 255 | m_rep.clear(); |
254 | } | 256 | } |
255 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ | 257 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ |
256 | if ( m_raw.contains( uid ) ) | 258 | if ( m_raw.contains( uid ) ) |
257 | return m_raw[uid]; | 259 | return m_raw[uid]; |
258 | else | 260 | else |
259 | return m_rep[uid]; | 261 | return m_rep[uid]; |
260 | } | 262 | } |
261 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { | 263 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { |
262 | m_changed = true; | 264 | m_changed = true; |
263 | if (ev.hasRecurrence() ) | 265 | if (ev.hasRecurrence() ) |
264 | m_rep.insert( ev.uid(), ev ); | 266 | m_rep.insert( ev.uid(), ev ); |
265 | else | 267 | else |
266 | m_raw.insert( ev.uid(), ev ); | 268 | m_raw.insert( ev.uid(), ev ); |
267 | 269 | ||
268 | return true; | 270 | return true; |
269 | } | 271 | } |
270 | bool ODateBookAccessBackend_XML::remove( int uid ) { | 272 | bool ODateBookAccessBackend_XML::remove( int uid ) { |
271 | m_changed = true; | 273 | m_changed = true; |
272 | m_rep.remove( uid ); | 274 | m_rep.remove( uid ); |
273 | m_rep.remove( uid ); | 275 | m_rep.remove( uid ); |
274 | 276 | ||
275 | return true; | 277 | return true; |
276 | } | 278 | } |
277 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { | 279 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { |
278 | replace( ev.uid() ); | 280 | replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers) |
279 | return add( ev ); | 281 | return add( ev ); |
280 | } | 282 | } |
281 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { | 283 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { |
282 | return allRecords(); | 284 | return allRecords(); |
283 | } | 285 | } |
284 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { | 286 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { |
285 | QArray<int> ints( m_rep.count() ); | 287 | QArray<int> ints( m_rep.count() ); |
286 | uint i = 0; | 288 | uint i = 0; |
287 | QMap<int, OEvent>::ConstIterator it; | 289 | QMap<int, OEvent>::ConstIterator it; |
288 | 290 | ||
289 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 291 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
290 | ints[i] = it.key(); | 292 | ints[i] = it.key(); |
291 | i++; | 293 | i++; |
292 | } | 294 | } |
293 | 295 | ||
294 | return ints; | 296 | return ints; |
295 | } | 297 | } |
296 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { | 298 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { |
297 | QArray<int> ints( m_raw.count() ); | 299 | QArray<int> ints( m_raw.count() ); |
298 | uint i = 0; | 300 | uint i = 0; |
299 | QMap<int, OEvent>::ConstIterator it; | 301 | QMap<int, OEvent>::ConstIterator it; |
300 | 302 | ||
301 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 303 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
302 | ints[i] = it.key(); | 304 | ints[i] = it.key(); |
303 | i++; | 305 | i++; |
304 | } | 306 | } |
305 | 307 | ||
306 | return ints; | 308 | return ints; |
307 | } | 309 | } |
308 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { | 310 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { |
309 | OEvent::ValueList list; | 311 | OEvent::ValueList list; |
310 | QMap<int, OEvent>::ConstIterator it; | 312 | QMap<int, OEvent>::ConstIterator it; |
311 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) | 313 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) |
312 | list.append( it.data() ); | 314 | list.append( it.data() ); |
313 | 315 | ||
314 | return list; | 316 | return list; |
315 | } | 317 | } |
316 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { | 318 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { |
317 | OEvent::ValueList list; | 319 | OEvent::ValueList list; |
318 | QMap<int, OEvent>::ConstIterator it; | 320 | QMap<int, OEvent>::ConstIterator it; |
319 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) | 321 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) |
320 | list.append( it.data() ); | 322 | list.append( it.data() ); |
321 | 323 | ||
322 | return list; | 324 | return list; |
323 | } | 325 | } |
326 | |||
327 | // FIXME: Use OEvent::fromMap() (eilers) | ||
324 | bool ODateBookAccessBackend_XML::loadFile() { | 328 | bool ODateBookAccessBackend_XML::loadFile() { |
325 | m_changed = false; | 329 | m_changed = false; |
326 | 330 | ||
327 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); | 331 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); |
328 | if ( fd < 0 ) return false; | 332 | if ( fd < 0 ) return false; |
329 | 333 | ||
330 | struct stat attribute; | 334 | struct stat attribute; |
331 | if ( ::fstat(fd, &attribute ) == -1 ) { | 335 | if ( ::fstat(fd, &attribute ) == -1 ) { |
332 | ::close( fd ); | 336 | ::close( fd ); |
333 | return false; | 337 | return false; |
334 | } | 338 | } |
335 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 339 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
336 | if ( map_addr == ( (caddr_t)-1) ) { | 340 | if ( map_addr == ( (caddr_t)-1) ) { |
337 | ::close( fd ); | 341 | ::close( fd ); |
338 | return false; | 342 | return false; |
339 | } | 343 | } |
340 | 344 | ||
341 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); | 345 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); |
342 | ::close( fd ); | 346 | ::close( fd ); |
343 | 347 | ||
344 | QAsciiDict<int> dict(FExceptions+1); | 348 | QAsciiDict<int> dict(FExceptions+1); |
345 | dict.setAutoDelete( true ); | 349 | dict.setAutoDelete( true ); |
346 | dict.insert( "description", new int(FDescription) ); | 350 | dict.insert( "description", new int(FDescription) ); |
347 | dict.insert( "location", new int(FLocation) ); | 351 | dict.insert( "location", new int(FLocation) ); |
348 | dict.insert( "categories", new int(FCategories) ); | 352 | dict.insert( "categories", new int(FCategories) ); |
349 | dict.insert( "uid", new int(FUid) ); | 353 | dict.insert( "uid", new int(FUid) ); |
350 | dict.insert( "type", new int(FType) ); | 354 | dict.insert( "type", new int(FType) ); |
351 | dict.insert( "alarm", new int(FAlarm) ); | 355 | dict.insert( "alarm", new int(FAlarm) ); |
352 | dict.insert( "sound", new int(FSound) ); | 356 | dict.insert( "sound", new int(FSound) ); |
353 | dict.insert( "rtype", new int(FRType) ); | 357 | dict.insert( "rtype", new int(FRType) ); |
354 | dict.insert( "rweekdays", new int(FRWeekdays) ); | 358 | dict.insert( "rweekdays", new int(FRWeekdays) ); |
355 | dict.insert( "rposition", new int(FRPosition) ); | 359 | dict.insert( "rposition", new int(FRPosition) ); |
356 | dict.insert( "rfreq", new int(FRFreq) ); | 360 | dict.insert( "rfreq", new int(FRFreq) ); |
357 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); | 361 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); |
358 | dict.insert( "enddt", new int(FREndDate) ); | 362 | dict.insert( "enddt", new int(FREndDate) ); |
359 | dict.insert( "start", new int(FRStart) ); | 363 | dict.insert( "start", new int(FRStart) ); |
360 | dict.insert( "end", new int(FREnd) ); | 364 | dict.insert( "end", new int(FREnd) ); |
361 | dict.insert( "note", new int(FNote) ); | 365 | dict.insert( "note", new int(FNote) ); |
362 | dict.insert( "created", new int(FCreated) ); | 366 | dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? |
363 | dict.insert( "recparent", new int(FRecParent) ); | 367 | dict.insert( "recparent", new int(FRecParent) ); |
364 | dict.insert( "recchildren", new int(FRecChildren) ); | 368 | dict.insert( "recchildren", new int(FRecChildren) ); |
365 | dict.insert( "exceptions", new int(FExceptions) ); | 369 | dict.insert( "exceptions", new int(FExceptions) ); |
366 | dict.insert( "timezone", new int(FTimeZone) ); | 370 | dict.insert( "timezone", new int(FTimeZone) ); |
367 | 371 | ||
368 | char* dt = (char*)map_addr; | 372 | char* dt = (char*)map_addr; |
369 | int len = attribute.st_size; | 373 | int len = attribute.st_size; |
370 | int i = 0; | 374 | int i = 0; |
371 | char* point; | 375 | char* point; |
372 | const char* collectionString = "<event "; | 376 | const char* collectionString = "<event "; |
373 | int strLen = ::strlen(collectionString); | 377 | int strLen = ::strlen(collectionString); |
374 | int *find; | 378 | int *find; |
375 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { | 379 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { |
376 | i = point -dt; | 380 | i = point -dt; |
377 | i+= strLen; | 381 | i+= strLen; |
378 | 382 | ||
379 | alarmTime = -1; | 383 | alarmTime = -1; |
380 | snd = 0; // silent | 384 | snd = 0; // silent |
381 | 385 | ||
382 | OEvent ev; | 386 | OEvent ev; |
383 | rec = 0; | 387 | rec = 0; |
384 | 388 | ||
385 | while ( TRUE ) { | 389 | while ( TRUE ) { |
386 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 390 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
387 | ++i; | 391 | ++i; |
388 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 392 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
389 | break; | 393 | break; |
390 | 394 | ||
391 | 395 | ||
392 | // we have another attribute, read it. | 396 | // we have another attribute, read it. |
393 | int j = i; | 397 | int j = i; |
394 | while ( j < len && dt[j] != '=' ) | 398 | while ( j < len && dt[j] != '=' ) |
395 | ++j; | 399 | ++j; |
396 | QCString attr( dt+i, j-i+1); | 400 | QCString attr( dt+i, j-i+1); |
397 | 401 | ||
398 | i = ++j; // skip = | 402 | i = ++j; // skip = |
399 | 403 | ||
400 | // find the start of quotes | 404 | // find the start of quotes |
401 | while ( i < len && dt[i] != '"' ) | 405 | while ( i < len && dt[i] != '"' ) |
402 | ++i; | 406 | ++i; |
403 | j = ++i; | 407 | j = ++i; |
404 | 408 | ||
405 | bool haveUtf = FALSE; | 409 | bool haveUtf = FALSE; |
406 | bool haveEnt = FALSE; | 410 | bool haveEnt = FALSE; |
407 | while ( j < len && dt[j] != '"' ) { | 411 | while ( j < len && dt[j] != '"' ) { |
408 | if ( ((unsigned char)dt[j]) > 0x7f ) | 412 | if ( ((unsigned char)dt[j]) > 0x7f ) |
409 | haveUtf = TRUE; | 413 | haveUtf = TRUE; |
410 | if ( dt[j] == '&' ) | 414 | if ( dt[j] == '&' ) |
411 | haveEnt = TRUE; | 415 | haveEnt = TRUE; |
412 | ++j; | 416 | ++j; |
413 | } | 417 | } |
414 | if ( i == j ) { | 418 | if ( i == j ) { |
415 | // empty value | 419 | // empty value |
416 | i = j + 1; | 420 | i = j + 1; |
417 | continue; | 421 | continue; |
418 | } | 422 | } |
419 | 423 | ||
420 | QCString value( dt+i, j-i+1 ); | 424 | QCString value( dt+i, j-i+1 ); |
421 | i = j + 1; | 425 | i = j + 1; |
422 | 426 | ||
423 | QString str = (haveUtf ? QString::fromUtf8( value ) | 427 | QString str = (haveUtf ? QString::fromUtf8( value ) |
424 | : QString::fromLatin1( value ) ); | 428 | : QString::fromLatin1( value ) ); |
425 | if ( haveEnt ) | 429 | if ( haveEnt ) |
426 | str = Qtopia::plainString( str ); | 430 | str = Qtopia::plainString( str ); |
427 | 431 | ||
428 | /* | 432 | /* |
429 | * add key + value | 433 | * add key + value |
430 | */ | 434 | */ |
431 | find = dict[attr.data()]; | 435 | find = dict[attr.data()]; |
432 | if (!find) | 436 | if (!find) |
433 | ev.setCustomField( attr, str ); | 437 | ev.setCustomField( attr, str ); |
434 | else { | 438 | else { |
435 | setField( ev, *find, str ); | 439 | setField( ev, *find, str ); |
436 | } | 440 | } |
437 | } | 441 | } |
438 | /* time to finalize */ | 442 | /* time to finalize */ |
439 | finalizeRecord( ev ); | 443 | finalizeRecord( ev ); |
440 | delete rec; | 444 | delete rec; |
441 | } | 445 | } |
442 | ::munmap(map_addr, attribute.st_size ); | 446 | ::munmap(map_addr, attribute.st_size ); |
443 | m_changed = false; // changed during add | 447 | m_changed = false; // changed during add |
444 | 448 | ||
445 | return true; | 449 | return true; |
446 | } | 450 | } |
451 | |||
452 | // FIXME: Use OEvent::fromMap() which makes this obsolete.. (eilers) | ||
447 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { | 453 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { |
448 | /* AllDay is alway in UTC */ | 454 | /* AllDay is alway in UTC */ |
449 | if ( ev.isAllDay() ) { | 455 | if ( ev.isAllDay() ) { |
450 | OTimeZone utc = OTimeZone::utc(); | 456 | OTimeZone utc = OTimeZone::utc(); |
451 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); | 457 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); |
452 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); | 458 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); |
453 | ev.setTimeZone( "UTC"); // make sure it is really utc | 459 | ev.setTimeZone( "UTC"); // make sure it is really utc |
454 | }else { | 460 | }else { |
455 | /* to current date time */ | 461 | /* to current date time */ |
456 | // qWarning(" Start is %d", start ); | 462 | // qWarning(" Start is %d", start ); |
457 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | 463 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); |
458 | QDateTime date = zone.toDateTime( start ); | 464 | QDateTime date = zone.toDateTime( start ); |
459 | qWarning(" Start is %s", date.toString().latin1() ); | 465 | qWarning(" Start is %s", date.toString().latin1() ); |
460 | ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); | 466 | ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); |
461 | 467 | ||
462 | date = zone.toDateTime( end ); | 468 | date = zone.toDateTime( end ); |
463 | ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); | 469 | ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); |
464 | } | 470 | } |
465 | if ( rec && rec->doesRecur() ) { | 471 | if ( rec && rec->doesRecur() ) { |
466 | OTimeZone utc = OTimeZone::utc(); | 472 | OTimeZone utc = OTimeZone::utc(); |
467 | ORecur recu( *rec ); // call copy c'tor; | 473 | ORecur recu( *rec ); // call copy c'tor; |
468 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); | 474 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); |
469 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); | 475 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); |
470 | recu.setStart( ev.startDateTime().date() ); | 476 | recu.setStart( ev.startDateTime().date() ); |
471 | ev.setRecurrence( recu ); | 477 | ev.setRecurrence( recu ); |
472 | } | 478 | } |
473 | 479 | ||
474 | if (alarmTime != -1 ) { | 480 | if (alarmTime != -1 ) { |
475 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); | 481 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); |
476 | OPimAlarm al( snd , dt ); | 482 | OPimAlarm al( snd , dt ); |
477 | ev.notifiers().add( al ); | 483 | ev.notifiers().add( al ); |
478 | } | 484 | } |
479 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { | 485 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { |
480 | qWarning("already contains assign uid"); | 486 | qWarning("already contains assign uid"); |
481 | ev.setUid( 1 ); | 487 | ev.setUid( 1 ); |
482 | } | 488 | } |
483 | qWarning("addind %d %s", ev.uid(), ev.description().latin1() ); | 489 | qWarning("addind %d %s", ev.uid(), ev.description().latin1() ); |
484 | if ( ev.hasRecurrence() ) | 490 | if ( ev.hasRecurrence() ) |
485 | m_rep.insert( ev.uid(), ev ); | 491 | m_rep.insert( ev.uid(), ev ); |
486 | else | 492 | else |
487 | m_raw.insert( ev.uid(), ev ); | 493 | m_raw.insert( ev.uid(), ev ); |
488 | 494 | ||
489 | } | 495 | } |
490 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { | 496 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { |
491 | // qWarning(" setting %s", value.latin1() ); | 497 | // qWarning(" setting %s", value.latin1() ); |
492 | switch( id ) { | 498 | switch( id ) { |
493 | case FDescription: | 499 | case FDescription: |
494 | e.setDescription( value ); | 500 | e.setDescription( value ); |
495 | break; | 501 | break; |
496 | case FLocation: | 502 | case FLocation: |
497 | e.setLocation( value ); | 503 | e.setLocation( value ); |
498 | break; | 504 | break; |
499 | case FCategories: | 505 | case FCategories: |
500 | e.setCategories( e.idsFromString( value ) ); | 506 | e.setCategories( e.idsFromString( value ) ); |
501 | break; | 507 | break; |
502 | case FUid: | 508 | case FUid: |
503 | e.setUid( value.toInt() ); | 509 | e.setUid( value.toInt() ); |
504 | break; | 510 | break; |
505 | case FType: | 511 | case FType: |
506 | if ( value == "AllDay" ) { | 512 | if ( value == "AllDay" ) { |
507 | e.setAllDay( true ); | 513 | e.setAllDay( true ); |
508 | e.setTimeZone( "UTC" ); | 514 | e.setTimeZone( "UTC" ); |
509 | } | 515 | } |
510 | break; | 516 | break; |
511 | case FAlarm: | 517 | case FAlarm: |
512 | alarmTime = value.toInt(); | 518 | alarmTime = value.toInt(); |
513 | break; | 519 | break; |
514 | case FSound: | 520 | case FSound: |
515 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; | 521 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; |
516 | break; | 522 | break; |
517 | // recurrence stuff | 523 | // recurrence stuff |
518 | case FRType: | 524 | case FRType: |
519 | if ( value == "Daily" ) | 525 | if ( value == "Daily" ) |
520 | recur()->setType( ORecur::Daily ); | 526 | recur()->setType( ORecur::Daily ); |
521 | else if ( value == "Weekly" ) | 527 | else if ( value == "Weekly" ) |
522 | recur()->setType( ORecur::Weekly); | 528 | recur()->setType( ORecur::Weekly); |
523 | else if ( value == "MonthlyDay" ) | 529 | else if ( value == "MonthlyDay" ) |
524 | recur()->setType( ORecur::MonthlyDay ); | 530 | recur()->setType( ORecur::MonthlyDay ); |
525 | else if ( value == "MonthlyDate" ) | 531 | else if ( value == "MonthlyDate" ) |
526 | recur()->setType( ORecur::MonthlyDate ); | 532 | recur()->setType( ORecur::MonthlyDate ); |
527 | else if ( value == "Yearly" ) | 533 | else if ( value == "Yearly" ) |
528 | recur()->setType( ORecur::Yearly ); | 534 | recur()->setType( ORecur::Yearly ); |
529 | else | 535 | else |
530 | recur()->setType( ORecur::NoRepeat ); | 536 | recur()->setType( ORecur::NoRepeat ); |
531 | break; | 537 | break; |
532 | case FRWeekdays: | 538 | case FRWeekdays: |
533 | recur()->setDays( value.toInt() ); | 539 | recur()->setDays( value.toInt() ); |
534 | break; | 540 | break; |
535 | case FRPosition: | 541 | case FRPosition: |
536 | recur()->setPosition( value.toInt() ); | 542 | recur()->setPosition( value.toInt() ); |
537 | break; | 543 | break; |
538 | case FRFreq: | 544 | case FRFreq: |
539 | recur()->setFrequency( value.toInt() ); | 545 | recur()->setFrequency( value.toInt() ); |
540 | break; | 546 | break; |
541 | case FRHasEndDate: | 547 | case FRHasEndDate: |
542 | recur()->setHasEndDate( value.toInt() ); | 548 | recur()->setHasEndDate( value.toInt() ); |
543 | break; | 549 | break; |
544 | case FREndDate: { | 550 | case FREndDate: { |
545 | rp_end = (time_t) value.toLong(); | 551 | rp_end = (time_t) value.toLong(); |
546 | break; | 552 | break; |
547 | } | 553 | } |
548 | case FRStart: { | 554 | case FRStart: { |
549 | start = (time_t) value.toLong(); | 555 | start = (time_t) value.toLong(); |
550 | break; | 556 | break; |
551 | } | 557 | } |
552 | case FREnd: { | 558 | case FREnd: { |
553 | end = ( (time_t) value.toLong() ); | 559 | end = ( (time_t) value.toLong() ); |
554 | break; | 560 | break; |
555 | } | 561 | } |
556 | case FNote: | 562 | case FNote: |
557 | e.setNote( value ); | 563 | e.setNote( value ); |
558 | break; | 564 | break; |
559 | case FCreated: | 565 | case FCreated: |
560 | created = value.toInt(); | 566 | created = value.toInt(); |
561 | break; | 567 | break; |
562 | case FRecParent: | 568 | case FRecParent: |
563 | e.setParent( value.toInt() ); | 569 | e.setParent( value.toInt() ); |
564 | break; | 570 | break; |
565 | case FRecChildren:{ | 571 | case FRecChildren:{ |
566 | QStringList list = QStringList::split(' ', value ); | 572 | QStringList list = QStringList::split(' ', value ); |
567 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | 573 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { |
568 | e.addChild( (*it).toInt() ); | 574 | e.addChild( (*it).toInt() ); |
569 | } | 575 | } |
570 | } | 576 | } |
571 | break; | 577 | break; |
572 | case FExceptions:{ | 578 | case FExceptions:{ |
573 | QStringList list = QStringList::split(' ', value ); | 579 | QStringList list = QStringList::split(' ', value ); |
574 | for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | 580 | for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { |
575 | QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); | 581 | QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); |
576 | qWarning("adding exception %s", date.toString().latin1() ); | 582 | qWarning("adding exception %s", date.toString().latin1() ); |
577 | recur()->exceptions().append( date ); | 583 | recur()->exceptions().append( date ); |
578 | } | 584 | } |
579 | } | 585 | } |
580 | break; | 586 | break; |
581 | case FTimeZone: | 587 | case FTimeZone: |
582 | if ( value != "None" ) | 588 | if ( value != "None" ) |
583 | e.setTimeZone( value ); | 589 | e.setTimeZone( value ); |
584 | break; | 590 | break; |
585 | default: | 591 | default: |
586 | break; | 592 | break; |
587 | } | 593 | } |
588 | } | 594 | } |
589 | QArray<int> ODateBookAccessBackend_XML::matchRegexp( const QRegExp &r ) const | 595 | QArray<int> ODateBookAccessBackend_XML::matchRegexp( const QRegExp &r ) const |
590 | { | 596 | { |
591 | QArray<int> m_currentQuery( m_raw.count()+ m_rep.count() ); | 597 | QArray<int> m_currentQuery( m_raw.count()+ m_rep.count() ); |
592 | uint arraycounter = 0; | 598 | uint arraycounter = 0; |
593 | QMap<int, OEvent>::ConstIterator it; | 599 | QMap<int, OEvent>::ConstIterator it; |
594 | 600 | ||
595 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) | 601 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) |
596 | if ( it.data().match( r ) ) | 602 | if ( it.data().match( r ) ) |
597 | m_currentQuery[arraycounter++] = it.data().uid(); | 603 | m_currentQuery[arraycounter++] = it.data().uid(); |
598 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) | 604 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) |
599 | if ( it.data().match( r ) ) | 605 | if ( it.data().match( r ) ) |
600 | m_currentQuery[arraycounter++] = it.data().uid(); | 606 | m_currentQuery[arraycounter++] = it.data().uid(); |
601 | 607 | ||
602 | // Shrink to fit.. | 608 | // Shrink to fit.. |
603 | m_currentQuery.resize(arraycounter); | 609 | m_currentQuery.resize(arraycounter); |
604 | 610 | ||
605 | return m_currentQuery; | 611 | return m_currentQuery; |
606 | } | 612 | } |
diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp index 3913661..75a0860 100644 --- a/libopie2/opiepim/backend/otodoaccesssql.cpp +++ b/libopie2/opiepim/backend/otodoaccesssql.cpp | |||
@@ -110,397 +110,400 @@ namespace { | |||
110 | QString query()const; | 110 | QString query()const; |
111 | private: | 111 | private: |
112 | QString with()const; | 112 | QString with()const; |
113 | QString out()const; | 113 | QString out()const; |
114 | QDate m_start; | 114 | QDate m_start; |
115 | QDate m_end; | 115 | QDate m_end; |
116 | bool m_inc :1; | 116 | bool m_inc :1; |
117 | }; | 117 | }; |
118 | 118 | ||
119 | 119 | ||
120 | CreateQuery::CreateQuery() : OSQLQuery() {} | 120 | CreateQuery::CreateQuery() : OSQLQuery() {} |
121 | CreateQuery::~CreateQuery() {} | 121 | CreateQuery::~CreateQuery() {} |
122 | QString CreateQuery::query()const { | 122 | QString CreateQuery::query()const { |
123 | QString qu; | 123 | QString qu; |
124 | qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; | 124 | qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; |
125 | qu += "description, summary, priority, DueDate, progress , state, "; | 125 | qu += "description, summary, priority, DueDate, progress , state, "; |
126 | // This is the recurrance-stuff .. Exceptions are currently not supported (see ORecur.cpp) ! (eilers) | 126 | // This is the recurrance-stuff .. Exceptions are currently not supported (see ORecur.cpp) ! (eilers) |
127 | qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, "; | 127 | qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, "; |
128 | qu += "reminders, alarms, maintainer, startdate, completeddate);"; | 128 | qu += "reminders, alarms, maintainer, startdate, completeddate);"; |
129 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; | 129 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; |
130 | return qu; | 130 | return qu; |
131 | } | 131 | } |
132 | 132 | ||
133 | LoadQuery::LoadQuery() : OSQLQuery() {} | 133 | LoadQuery::LoadQuery() : OSQLQuery() {} |
134 | LoadQuery::~LoadQuery() {} | 134 | LoadQuery::~LoadQuery() {} |
135 | QString LoadQuery::query()const { | 135 | QString LoadQuery::query()const { |
136 | QString qu; | 136 | QString qu; |
137 | // We do not need "distinct" here. The primary key is always unique.. | 137 | // We do not need "distinct" here. The primary key is always unique.. |
138 | //qu += "select distinct uid from todolist"; | 138 | //qu += "select distinct uid from todolist"; |
139 | qu += "select uid from todolist"; | 139 | qu += "select uid from todolist"; |
140 | 140 | ||
141 | return qu; | 141 | return qu; |
142 | } | 142 | } |
143 | 143 | ||
144 | InsertQuery::InsertQuery( const OTodo& todo ) | 144 | InsertQuery::InsertQuery( const OTodo& todo ) |
145 | : OSQLQuery(), m_todo( todo ) { | 145 | : OSQLQuery(), m_todo( todo ) { |
146 | } | 146 | } |
147 | InsertQuery::~InsertQuery() { | 147 | InsertQuery::~InsertQuery() { |
148 | } | 148 | } |
149 | /* | 149 | /* |
150 | * converts from a OTodo to a query | 150 | * converts from a OTodo to a query |
151 | * we leave out X-Ref + Alarms | 151 | * we leave out X-Ref + Alarms |
152 | */ | 152 | */ |
153 | QString InsertQuery::query()const{ | 153 | QString InsertQuery::query()const{ |
154 | 154 | ||
155 | int year, month, day; | 155 | int year, month, day; |
156 | year = month = day = 0; | 156 | year = month = day = 0; |
157 | if (m_todo.hasDueDate() ) { | 157 | if (m_todo.hasDueDate() ) { |
158 | QDate date = m_todo.dueDate(); | 158 | QDate date = m_todo.dueDate(); |
159 | year = date.year(); | 159 | year = date.year(); |
160 | month = date.month(); | 160 | month = date.month(); |
161 | day = date.day(); | 161 | day = date.day(); |
162 | } | 162 | } |
163 | int sYear = 0, sMonth = 0, sDay = 0; | 163 | int sYear = 0, sMonth = 0, sDay = 0; |
164 | if( m_todo.hasStartDate() ){ | 164 | if( m_todo.hasStartDate() ){ |
165 | QDate sDate = m_todo.startDate(); | 165 | QDate sDate = m_todo.startDate(); |
166 | sYear = sDate.year(); | 166 | sYear = sDate.year(); |
167 | sMonth= sDate.month(); | 167 | sMonth= sDate.month(); |
168 | sDay = sDate.day(); | 168 | sDay = sDate.day(); |
169 | } | 169 | } |
170 | 170 | ||
171 | int eYear = 0, eMonth = 0, eDay = 0; | 171 | int eYear = 0, eMonth = 0, eDay = 0; |
172 | if( m_todo.hasCompletedDate() ){ | 172 | if( m_todo.hasCompletedDate() ){ |
173 | QDate eDate = m_todo.completedDate(); | 173 | QDate eDate = m_todo.completedDate(); |
174 | eYear = eDate.year(); | 174 | eYear = eDate.year(); |
175 | eMonth= eDate.month(); | 175 | eMonth= eDate.month(); |
176 | eDay = eDate.day(); | 176 | eDay = eDate.day(); |
177 | } | 177 | } |
178 | QString qu; | 178 | QString qu; |
179 | QMap<int, QString> recMap = m_todo.recurrence().toMap(); | 179 | QMap<int, QString> recMap = m_todo.recurrence().toMap(); |
180 | qu = "insert into todolist VALUES(" | 180 | qu = "insert into todolist VALUES(" |
181 | + QString::number( m_todo.uid() ) + "," | 181 | + QString::number( m_todo.uid() ) + "," |
182 | + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," | 182 | + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," |
183 | + QString::number( m_todo.isCompleted() ) + "," | 183 | + QString::number( m_todo.isCompleted() ) + "," |
184 | + "'" + m_todo.description() + "'" + "," | 184 | + "'" + m_todo.description() + "'" + "," |
185 | + "'" + m_todo.summary() + "'" + "," | 185 | + "'" + m_todo.summary() + "'" + "," |
186 | + QString::number(m_todo.priority() ) + "," | 186 | + QString::number(m_todo.priority() ) + "," |
187 | + "'" + QString::number(year) + "-" | 187 | + "'" + QString::number(year) + "-" |
188 | + QString::number(month) | 188 | + QString::number(month) |
189 | + "-" + QString::number( day ) + "'" + "," | 189 | + "-" + QString::number( day ) + "'" + "," |
190 | + QString::number( m_todo.progress() ) + "," | 190 | + QString::number( m_todo.progress() ) + "," |
191 | + QString::number( m_todo.state().state() ) + "," | 191 | + QString::number( m_todo.state().state() ) + "," |
192 | + "'" + recMap[ ORecur::RType ] + "'" + "," | 192 | + "'" + recMap[ ORecur::RType ] + "'" + "," |
193 | + "'" + recMap[ ORecur::RWeekdays ] + "'" + "," | 193 | + "'" + recMap[ ORecur::RWeekdays ] + "'" + "," |
194 | + "'" + recMap[ ORecur::RPosition ] + "'" + "," | 194 | + "'" + recMap[ ORecur::RPosition ] + "'" + "," |
195 | + "'" + recMap[ ORecur::RFreq ] + "'" + "," | 195 | + "'" + recMap[ ORecur::RFreq ] + "'" + "," |
196 | + "'" + recMap[ ORecur::RHasEndDate ] + "'" + "," | 196 | + "'" + recMap[ ORecur::RHasEndDate ] + "'" + "," |
197 | + "'" + recMap[ ORecur::EndDate ] + "'" + "," | 197 | + "'" + recMap[ ORecur::EndDate ] + "'" + "," |
198 | + "'" + recMap[ ORecur::Created ] + "'" + "," | 198 | + "'" + recMap[ ORecur::Created ] + "'" + "," |
199 | + "'" + recMap[ ORecur::Exceptions ] + "'" + ","; | 199 | + "'" + recMap[ ORecur::Exceptions ] + "'" + ","; |
200 | 200 | ||
201 | if ( m_todo.hasNotifiers() ) { | 201 | if ( m_todo.hasNotifiers() ) { |
202 | OPimNotifyManager manager = m_todo.notifiers(); | 202 | OPimNotifyManager manager = m_todo.notifiers(); |
203 | qu += "'" + manager.remindersToString() + "'" + "," | 203 | qu += "'" + manager.remindersToString() + "'" + "," |
204 | + "'" + manager.alarmsToString() + "'" + ","; | 204 | + "'" + manager.alarmsToString() + "'" + ","; |
205 | } | 205 | } |
206 | else{ | 206 | else{ |
207 | qu += QString( "''" ) + "," | 207 | qu += QString( "''" ) + "," |
208 | + "''" + ","; | 208 | + "''" + ","; |
209 | } | 209 | } |
210 | 210 | ||
211 | qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) | 211 | qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) |
212 | + "'" + QString::number(sYear) + "-" | 212 | + "'" + QString::number(sYear) + "-" |
213 | + QString::number(sMonth) | 213 | + QString::number(sMonth) |
214 | + "-" + QString::number(sDay) + "'" + "," | 214 | + "-" + QString::number(sDay) + "'" + "," |
215 | + "'" + QString::number(eYear) + "-" | 215 | + "'" + QString::number(eYear) + "-" |
216 | + QString::number(eMonth) | 216 | + QString::number(eMonth) |
217 | + "-"+QString::number(eDay) + "'" | 217 | + "-"+QString::number(eDay) + "'" |
218 | + ")"; | 218 | + ")"; |
219 | 219 | ||
220 | qWarning("add %s", qu.latin1() ); | 220 | qWarning("add %s", qu.latin1() ); |
221 | return qu; | 221 | return qu; |
222 | } | 222 | } |
223 | 223 | ||
224 | RemoveQuery::RemoveQuery(int uid ) | 224 | RemoveQuery::RemoveQuery(int uid ) |
225 | : OSQLQuery(), m_uid( uid ) {} | 225 | : OSQLQuery(), m_uid( uid ) {} |
226 | RemoveQuery::~RemoveQuery() {} | 226 | RemoveQuery::~RemoveQuery() {} |
227 | QString RemoveQuery::query()const { | 227 | QString RemoveQuery::query()const { |
228 | QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); | 228 | QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); |
229 | return qu; | 229 | return qu; |
230 | } | 230 | } |
231 | 231 | ||
232 | 232 | ||
233 | ClearQuery::ClearQuery() | 233 | ClearQuery::ClearQuery() |
234 | : OSQLQuery() {} | 234 | : OSQLQuery() {} |
235 | ClearQuery::~ClearQuery() {} | 235 | ClearQuery::~ClearQuery() {} |
236 | QString ClearQuery::query()const { | 236 | QString ClearQuery::query()const { |
237 | QString qu = "drop table todolist"; | 237 | QString qu = "drop table todolist"; |
238 | return qu; | 238 | return qu; |
239 | } | 239 | } |
240 | FindQuery::FindQuery(int uid) | 240 | FindQuery::FindQuery(int uid) |
241 | : OSQLQuery(), m_uid(uid ) { | 241 | : OSQLQuery(), m_uid(uid ) { |
242 | } | 242 | } |
243 | FindQuery::FindQuery(const QArray<int>& ints) | 243 | FindQuery::FindQuery(const QArray<int>& ints) |
244 | : OSQLQuery(), m_uids(ints){ | 244 | : OSQLQuery(), m_uids(ints){ |
245 | } | 245 | } |
246 | FindQuery::~FindQuery() { | 246 | FindQuery::~FindQuery() { |
247 | } | 247 | } |
248 | QString FindQuery::query()const{ | 248 | QString FindQuery::query()const{ |
249 | if (m_uids.count() == 0 ) | 249 | if (m_uids.count() == 0 ) |
250 | return single(); | 250 | return single(); |
251 | else | 251 | else |
252 | return multi(); | 252 | return multi(); |
253 | } | 253 | } |
254 | QString FindQuery::single()const{ | 254 | QString FindQuery::single()const{ |
255 | QString qu = "select * from todolist where uid = " + QString::number(m_uid); | 255 | QString qu = "select * from todolist where uid = " + QString::number(m_uid); |
256 | return qu; | 256 | return qu; |
257 | } | 257 | } |
258 | QString FindQuery::multi()const { | 258 | QString FindQuery::multi()const { |
259 | QString qu = "select * from todolist where "; | 259 | QString qu = "select * from todolist where "; |
260 | for (uint i = 0; i < m_uids.count(); i++ ) { | 260 | for (uint i = 0; i < m_uids.count(); i++ ) { |
261 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | 261 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; |
262 | } | 262 | } |
263 | qu.remove( qu.length()-2, 2 ); | 263 | qu.remove( qu.length()-2, 2 ); |
264 | return qu; | 264 | return qu; |
265 | } | 265 | } |
266 | 266 | ||
267 | OverDueQuery::OverDueQuery(): OSQLQuery() {} | 267 | OverDueQuery::OverDueQuery(): OSQLQuery() {} |
268 | OverDueQuery::~OverDueQuery() {} | 268 | OverDueQuery::~OverDueQuery() {} |
269 | QString OverDueQuery::query()const { | 269 | QString OverDueQuery::query()const { |
270 | QDate date = QDate::currentDate(); | 270 | QDate date = QDate::currentDate(); |
271 | QString str; | 271 | QString str; |
272 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); | 272 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); |
273 | 273 | ||
274 | return str; | 274 | return str; |
275 | } | 275 | } |
276 | 276 | ||
277 | 277 | ||
278 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) | 278 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) |
279 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} | 279 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} |
280 | EffQuery::~EffQuery() {} | 280 | EffQuery::~EffQuery() {} |
281 | QString EffQuery::query()const { | 281 | QString EffQuery::query()const { |
282 | return m_inc ? with() : out(); | 282 | return m_inc ? with() : out(); |
283 | } | 283 | } |
284 | QString EffQuery::with()const { | 284 | QString EffQuery::with()const { |
285 | QString str; | 285 | QString str; |
286 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") | 286 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") |
287 | .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) | 287 | .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) |
288 | .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); | 288 | .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); |
289 | return str; | 289 | return str; |
290 | } | 290 | } |
291 | QString EffQuery::out()const { | 291 | QString EffQuery::out()const { |
292 | QString str; | 292 | QString str; |
293 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") | 293 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") |
294 | .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) | 294 | .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) |
295 | .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); | 295 | .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); |
296 | 296 | ||
297 | return str; | 297 | return str; |
298 | } | 298 | } |
299 | }; | 299 | }; |
300 | 300 | ||
301 | OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) | 301 | OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) |
302 | : OTodoAccessBackend(), m_dict(15), m_dirty(true) | 302 | : OTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true) |
303 | { | 303 | { |
304 | QString fi = file; | 304 | QString fi = file; |
305 | if ( fi.isEmpty() ) | 305 | if ( fi.isEmpty() ) |
306 | fi = Global::applicationFileName( "todolist", "todolist.db" ); | 306 | fi = Global::applicationFileName( "todolist", "todolist.db" ); |
307 | OSQLManager man; | 307 | OSQLManager man; |
308 | m_driver = man.standard(); | 308 | m_driver = man.standard(); |
309 | m_driver->setUrl(fi); | 309 | m_driver->setUrl(fi); |
310 | // fillDict(); | 310 | // fillDict(); |
311 | } | 311 | } |
312 | 312 | ||
313 | OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ | 313 | OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ |
314 | if( m_driver ) | ||
315 | delete m_driver; | ||
314 | } | 316 | } |
317 | |||
315 | bool OTodoAccessBackendSQL::load(){ | 318 | bool OTodoAccessBackendSQL::load(){ |
316 | if (!m_driver->open() ) | 319 | if (!m_driver->open() ) |
317 | return false; | 320 | return false; |
318 | 321 | ||
319 | CreateQuery creat; | 322 | CreateQuery creat; |
320 | OSQLResult res = m_driver->query(&creat ); | 323 | OSQLResult res = m_driver->query(&creat ); |
321 | 324 | ||
322 | m_dirty = true; | 325 | m_dirty = true; |
323 | return true; | 326 | return true; |
324 | } | 327 | } |
325 | bool OTodoAccessBackendSQL::reload(){ | 328 | bool OTodoAccessBackendSQL::reload(){ |
326 | return load(); | 329 | return load(); |
327 | } | 330 | } |
328 | 331 | ||
329 | bool OTodoAccessBackendSQL::save(){ | 332 | bool OTodoAccessBackendSQL::save(){ |
330 | return m_driver->close(); | 333 | return m_driver->close(); |
331 | } | 334 | } |
332 | QArray<int> OTodoAccessBackendSQL::allRecords()const { | 335 | QArray<int> OTodoAccessBackendSQL::allRecords()const { |
333 | if (m_dirty ) | 336 | if (m_dirty ) |
334 | update(); | 337 | update(); |
335 | 338 | ||
336 | return m_uids; | 339 | return m_uids; |
337 | } | 340 | } |
338 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ | 341 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ |
339 | QArray<int> ints(0); | 342 | QArray<int> ints(0); |
340 | return ints; | 343 | return ints; |
341 | } | 344 | } |
342 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ | 345 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ |
343 | FindQuery query( uid ); | 346 | FindQuery query( uid ); |
344 | return todo( m_driver->query(&query) ); | 347 | return todo( m_driver->query(&query) ); |
345 | 348 | ||
346 | } | 349 | } |
347 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, | 350 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, |
348 | uint cur, Frontend::CacheDirection dir ) const{ | 351 | uint cur, Frontend::CacheDirection dir ) const{ |
349 | uint CACHE = readAhead(); | 352 | uint CACHE = readAhead(); |
350 | qWarning("searching for %d", uid ); | 353 | qWarning("searching for %d", uid ); |
351 | QArray<int> search( CACHE ); | 354 | QArray<int> search( CACHE ); |
352 | uint size =0; | 355 | uint size =0; |
353 | OTodo to; | 356 | OTodo to; |
354 | 357 | ||
355 | // we try to cache CACHE items | 358 | // we try to cache CACHE items |
356 | switch( dir ) { | 359 | switch( dir ) { |
357 | /* forward */ | 360 | /* forward */ |
358 | case 0: // FIXME: Not a good style to use magic numbers here (eilers) | 361 | case 0: // FIXME: Not a good style to use magic numbers here (eilers) |
359 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { | 362 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { |
360 | qWarning("size %d %d", size, ints[i] ); | 363 | qWarning("size %d %d", size, ints[i] ); |
361 | search[size] = ints[i]; | 364 | search[size] = ints[i]; |
362 | size++; | 365 | size++; |
363 | } | 366 | } |
364 | break; | 367 | break; |
365 | /* reverse */ | 368 | /* reverse */ |
366 | case 1: // FIXME: Not a good style to use magic numbers here (eilers) | 369 | case 1: // FIXME: Not a good style to use magic numbers here (eilers) |
367 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { | 370 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { |
368 | search[size] = ints[i]; | 371 | search[size] = ints[i]; |
369 | size++; | 372 | size++; |
370 | } | 373 | } |
371 | break; | 374 | break; |
372 | } | 375 | } |
373 | search.resize( size ); | 376 | search.resize( size ); |
374 | FindQuery query( search ); | 377 | FindQuery query( search ); |
375 | OSQLResult res = m_driver->query( &query ); | 378 | OSQLResult res = m_driver->query( &query ); |
376 | if ( res.state() != OSQLResult::Success ) | 379 | if ( res.state() != OSQLResult::Success ) |
377 | return to; | 380 | return to; |
378 | 381 | ||
379 | return todo( res ); | 382 | return todo( res ); |
380 | } | 383 | } |
381 | void OTodoAccessBackendSQL::clear() { | 384 | void OTodoAccessBackendSQL::clear() { |
382 | ClearQuery cle; | 385 | ClearQuery cle; |
383 | OSQLResult res = m_driver->query( &cle ); | 386 | OSQLResult res = m_driver->query( &cle ); |
384 | CreateQuery qu; | 387 | CreateQuery qu; |
385 | res = m_driver->query(&qu); | 388 | res = m_driver->query(&qu); |
386 | } | 389 | } |
387 | bool OTodoAccessBackendSQL::add( const OTodo& t) { | 390 | bool OTodoAccessBackendSQL::add( const OTodo& t) { |
388 | InsertQuery ins( t ); | 391 | InsertQuery ins( t ); |
389 | OSQLResult res = m_driver->query( &ins ); | 392 | OSQLResult res = m_driver->query( &ins ); |
390 | 393 | ||
391 | if ( res.state() == OSQLResult::Failure ) | 394 | if ( res.state() == OSQLResult::Failure ) |
392 | return false; | 395 | return false; |
393 | int c = m_uids.count(); | 396 | int c = m_uids.count(); |
394 | m_uids.resize( c+1 ); | 397 | m_uids.resize( c+1 ); |
395 | m_uids[c] = t.uid(); | 398 | m_uids[c] = t.uid(); |
396 | 399 | ||
397 | return true; | 400 | return true; |
398 | } | 401 | } |
399 | bool OTodoAccessBackendSQL::remove( int uid ) { | 402 | bool OTodoAccessBackendSQL::remove( int uid ) { |
400 | RemoveQuery rem( uid ); | 403 | RemoveQuery rem( uid ); |
401 | OSQLResult res = m_driver->query(&rem ); | 404 | OSQLResult res = m_driver->query(&rem ); |
402 | 405 | ||
403 | if ( res.state() == OSQLResult::Failure ) | 406 | if ( res.state() == OSQLResult::Failure ) |
404 | return false; | 407 | return false; |
405 | 408 | ||
406 | m_dirty = true; | 409 | m_dirty = true; |
407 | return true; | 410 | return true; |
408 | } | 411 | } |
409 | /* | 412 | /* |
410 | * FIXME better set query | 413 | * FIXME better set query |
411 | * but we need the cache for that | 414 | * but we need the cache for that |
412 | * now we remove | 415 | * now we remove |
413 | */ | 416 | */ |
414 | bool OTodoAccessBackendSQL::replace( const OTodo& t) { | 417 | bool OTodoAccessBackendSQL::replace( const OTodo& t) { |
415 | remove( t.uid() ); | 418 | remove( t.uid() ); |
416 | bool b= add(t); | 419 | bool b= add(t); |
417 | m_dirty = false; // we changed some stuff but the UID stayed the same | 420 | m_dirty = false; // we changed some stuff but the UID stayed the same |
418 | return b; | 421 | return b; |
419 | } | 422 | } |
420 | QArray<int> OTodoAccessBackendSQL::overDue() { | 423 | QArray<int> OTodoAccessBackendSQL::overDue() { |
421 | OverDueQuery qu; | 424 | OverDueQuery qu; |
422 | return uids( m_driver->query(&qu ) ); | 425 | return uids( m_driver->query(&qu ) ); |
423 | } | 426 | } |
424 | QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, | 427 | QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, |
425 | const QDate& t, | 428 | const QDate& t, |
426 | bool u) { | 429 | bool u) { |
427 | EffQuery ef(s, t, u ); | 430 | EffQuery ef(s, t, u ); |
428 | return uids (m_driver->query(&ef) ); | 431 | return uids (m_driver->query(&ef) ); |
429 | } | 432 | } |
430 | /* | 433 | /* |
431 | * | 434 | * |
432 | */ | 435 | */ |
433 | QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, | 436 | QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, |
434 | int sortFilter, int cat ) { | 437 | int sortFilter, int cat ) { |
435 | qWarning("sorted %d, %d", asc, sortOrder ); | 438 | qWarning("sorted %d, %d", asc, sortOrder ); |
436 | QString query; | 439 | QString query; |
437 | query = "select uid from todolist WHERE "; | 440 | query = "select uid from todolist WHERE "; |
438 | 441 | ||
439 | /* | 442 | /* |
440 | * Sort Filter stuff | 443 | * Sort Filter stuff |
441 | * not that straight forward | 444 | * not that straight forward |
442 | * FIXME: Replace magic numbers | 445 | * FIXME: Replace magic numbers |
443 | * | 446 | * |
444 | */ | 447 | */ |
445 | /* Category */ | 448 | /* Category */ |
446 | if ( sortFilter & 1 ) { | 449 | if ( sortFilter & 1 ) { |
447 | QString str; | 450 | QString str; |
448 | if (cat != 0 ) str = QString::number( cat ); | 451 | if (cat != 0 ) str = QString::number( cat ); |
449 | query += " categories like '%" +str+"%' AND"; | 452 | query += " categories like '%" +str+"%' AND"; |
450 | } | 453 | } |
451 | /* Show only overdue */ | 454 | /* Show only overdue */ |
452 | if ( sortFilter & 2 ) { | 455 | if ( sortFilter & 2 ) { |
453 | QDate date = QDate::currentDate(); | 456 | QDate date = QDate::currentDate(); |
454 | QString due; | 457 | QString due; |
455 | QString base; | 458 | QString base; |
456 | base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); | 459 | base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); |
457 | query += " " + base + " AND"; | 460 | query += " " + base + " AND"; |
458 | } | 461 | } |
459 | /* not show completed */ | 462 | /* not show completed */ |
460 | if ( sortFilter & 4 ) { | 463 | if ( sortFilter & 4 ) { |
461 | query += " completed = 0 AND"; | 464 | query += " completed = 0 AND"; |
462 | }else{ | 465 | }else{ |
463 | query += " ( completed = 1 OR completed = 0) AND"; | 466 | query += " ( completed = 1 OR completed = 0) AND"; |
464 | } | 467 | } |
465 | /* srtip the end */ | 468 | /* srtip the end */ |
466 | query = query.remove( query.length()-3, 3 ); | 469 | query = query.remove( query.length()-3, 3 ); |
467 | 470 | ||
468 | 471 | ||
469 | /* | 472 | /* |
470 | * sort order stuff | 473 | * sort order stuff |
471 | * quite straight forward | 474 | * quite straight forward |
472 | */ | 475 | */ |
473 | query += "ORDER BY "; | 476 | query += "ORDER BY "; |
474 | switch( sortOrder ) { | 477 | switch( sortOrder ) { |
475 | /* completed */ | 478 | /* completed */ |
476 | case 0: | 479 | case 0: |
477 | query += "completed"; | 480 | query += "completed"; |
478 | break; | 481 | break; |
479 | case 1: | 482 | case 1: |
480 | query += "priority"; | 483 | query += "priority"; |
481 | break; | 484 | break; |
482 | case 2: | 485 | case 2: |
483 | query += "summary"; | 486 | query += "summary"; |
484 | break; | 487 | break; |
485 | case 3: | 488 | case 3: |
486 | query += "DueDate"; | 489 | query += "DueDate"; |
487 | break; | 490 | break; |
488 | } | 491 | } |
489 | 492 | ||
490 | if ( !asc ) { | 493 | if ( !asc ) { |
491 | qWarning("not ascending!"); | 494 | qWarning("not ascending!"); |
492 | query += " DESC"; | 495 | query += " DESC"; |
493 | } | 496 | } |
494 | 497 | ||
495 | qWarning( query ); | 498 | qWarning( query ); |
496 | OSQLRawQuery raw(query ); | 499 | OSQLRawQuery raw(query ); |
497 | return uids( m_driver->query(&raw) ); | 500 | return uids( m_driver->query(&raw) ); |
498 | } | 501 | } |
499 | bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ | 502 | bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ |
500 | if ( str == "0-0-0" ) | 503 | if ( str == "0-0-0" ) |
501 | return false; | 504 | return false; |
502 | else{ | 505 | else{ |
503 | int day, year, month; | 506 | int day, year, month; |
504 | QStringList list = QStringList::split("-", str ); | 507 | QStringList list = QStringList::split("-", str ); |
505 | year = list[0].toInt(); | 508 | year = list[0].toInt(); |
506 | month = list[1].toInt(); | 509 | month = list[1].toInt(); |
diff --git a/libopie2/opiepim/core/orecur.cpp b/libopie2/opiepim/core/orecur.cpp index 8c9ad46..f46f22e 100644 --- a/libopie2/opiepim/core/orecur.cpp +++ b/libopie2/opiepim/core/orecur.cpp | |||
@@ -1,228 +1,236 @@ | |||
1 | #include <time.h> | 1 | #include <time.h> |
2 | 2 | ||
3 | #include <qshared.h> | 3 | #include <qshared.h> |
4 | 4 | ||
5 | #include <qtopia/timeconversion.h> | 5 | #include <qtopia/timeconversion.h> |
6 | 6 | ||
7 | #include "otimezone.h" | 7 | #include "otimezone.h" |
8 | #include "orecur.h" | 8 | #include "orecur.h" |
9 | 9 | ||
10 | struct ORecur::Data : public QShared { | 10 | struct ORecur::Data : public QShared { |
11 | Data() : QShared() { | 11 | Data() : QShared() { |
12 | type = ORecur::NoRepeat; | 12 | type = ORecur::NoRepeat; |
13 | freq = -1; | 13 | freq = -1; |
14 | days = 0; | 14 | days = 0; |
15 | pos = 0; | 15 | pos = 0; |
16 | create = QDateTime::currentDateTime(); | 16 | create = QDateTime::currentDateTime(); |
17 | hasEnd = FALSE; | 17 | hasEnd = FALSE; |
18 | end = QDate::currentDate(); | 18 | end = QDate::currentDate(); |
19 | } | 19 | } |
20 | char days; // Q_UINT8 for 8 seven days;) | 20 | char days; // Q_UINT8 for 8 seven days;) |
21 | ORecur::RepeatType type; | 21 | ORecur::RepeatType type; |
22 | int freq; | 22 | int freq; |
23 | int pos; | 23 | int pos; |
24 | bool hasEnd : 1; | 24 | bool hasEnd : 1; |
25 | QDate end; | 25 | QDate end; |
26 | QDateTime create; | 26 | QDateTime create; |
27 | int rep; | 27 | int rep; |
28 | QString app; | 28 | QString app; |
29 | ExceptionList list; | 29 | ExceptionList list; |
30 | QDate start; | 30 | QDate start; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | 33 | ||
34 | ORecur::ORecur() { | 34 | ORecur::ORecur() { |
35 | data = new Data; | 35 | data = new Data; |
36 | } | 36 | } |
37 | |||
38 | ORecur::ORecur( const QMap<int, QString>& map ) | ||
39 | { | ||
40 | ORecur(); | ||
41 | fromMap( map ); | ||
42 | } | ||
43 | |||
44 | |||
37 | ORecur::ORecur( const ORecur& rec) | 45 | ORecur::ORecur( const ORecur& rec) |
38 | : data( rec.data ) | 46 | : data( rec.data ) |
39 | { | 47 | { |
40 | data->ref(); | 48 | data->ref(); |
41 | } | 49 | } |
42 | ORecur::~ORecur() { | 50 | ORecur::~ORecur() { |
43 | if ( data->deref() ) { | 51 | if ( data->deref() ) { |
44 | delete data; | 52 | delete data; |
45 | data = 0l; | 53 | data = 0l; |
46 | } | 54 | } |
47 | } | 55 | } |
48 | void ORecur::deref() { | 56 | void ORecur::deref() { |
49 | if ( data->deref() ) { | 57 | if ( data->deref() ) { |
50 | delete data; | 58 | delete data; |
51 | data = 0l; | 59 | data = 0l; |
52 | } | 60 | } |
53 | } | 61 | } |
54 | bool ORecur::operator==( const ORecur& )const { | 62 | bool ORecur::operator==( const ORecur& )const { |
55 | return false; | 63 | return false; |
56 | } | 64 | } |
57 | ORecur &ORecur::operator=( const ORecur& re) { | 65 | ORecur &ORecur::operator=( const ORecur& re) { |
58 | if ( *this == re ) return *this; | 66 | if ( *this == re ) return *this; |
59 | 67 | ||
60 | re.data->ref(); | 68 | re.data->ref(); |
61 | deref(); | 69 | deref(); |
62 | data = re.data; | 70 | data = re.data; |
63 | 71 | ||
64 | return *this; | 72 | return *this; |
65 | } | 73 | } |
66 | bool ORecur::doesRecur()const { | 74 | bool ORecur::doesRecur()const { |
67 | return !( type() == NoRepeat ); | 75 | return !( type() == NoRepeat ); |
68 | } | 76 | } |
69 | /* | 77 | /* |
70 | * we try to be smart here | 78 | * we try to be smart here |
71 | * | 79 | * |
72 | */ | 80 | */ |
73 | bool ORecur::doesRecur( const QDate& date ) { | 81 | bool ORecur::doesRecur( const QDate& date ) { |
74 | /* the day before the recurrance */ | 82 | /* the day before the recurrance */ |
75 | QDate da = date.addDays(-1); | 83 | QDate da = date.addDays(-1); |
76 | 84 | ||
77 | QDate recur; | 85 | QDate recur; |
78 | if (!nextOcurrence( da, recur ) ) | 86 | if (!nextOcurrence( da, recur ) ) |
79 | return false; | 87 | return false; |
80 | 88 | ||
81 | return (recur == date); | 89 | return (recur == date); |
82 | } | 90 | } |
83 | // FIXME unuglify! | 91 | // FIXME unuglify! |
84 | // GPL from Datebookdb.cpp | 92 | // GPL from Datebookdb.cpp |
85 | // FIXME exception list! | 93 | // FIXME exception list! |
86 | bool ORecur::nextOcurrence( const QDate& from, QDate& next ) { | 94 | bool ORecur::nextOcurrence( const QDate& from, QDate& next ) { |
87 | bool stillLooking; | 95 | bool stillLooking; |
88 | stillLooking = p_nextOccurrence( from, next ); | 96 | stillLooking = p_nextOccurrence( from, next ); |
89 | while ( stillLooking && data->list.contains(next) ) | 97 | while ( stillLooking && data->list.contains(next) ) |
90 | stillLooking = p_nextOccurrence( next.addDays(1), next ); | 98 | stillLooking = p_nextOccurrence( next.addDays(1), next ); |
91 | 99 | ||
92 | return stillLooking; | 100 | return stillLooking; |
93 | } | 101 | } |
94 | bool ORecur::p_nextOccurrence( const QDate& from, QDate& next ) { | 102 | bool ORecur::p_nextOccurrence( const QDate& from, QDate& next ) { |
95 | 103 | ||
96 | // easy checks, first are we too far in the future or too far in the past? | 104 | // easy checks, first are we too far in the future or too far in the past? |
97 | QDate tmpDate; | 105 | QDate tmpDate; |
98 | int freq = frequency(); | 106 | int freq = frequency(); |
99 | int diff, diff2, a; | 107 | int diff, diff2, a; |
100 | int iday, imonth, iyear; | 108 | int iday, imonth, iyear; |
101 | int dayOfWeek = 0; | 109 | int dayOfWeek = 0; |
102 | int firstOfWeek = 0; | 110 | int firstOfWeek = 0; |
103 | int weekOfMonth; | 111 | int weekOfMonth; |
104 | 112 | ||
105 | 113 | ||
106 | if (hasEndDate() && endDate() < from) | 114 | if (hasEndDate() && endDate() < from) |
107 | return FALSE; | 115 | return FALSE; |
108 | 116 | ||
109 | if (start() >= from ) { | 117 | if (start() >= from ) { |
110 | next = start(); | 118 | next = start(); |
111 | return TRUE; | 119 | return TRUE; |
112 | } | 120 | } |
113 | 121 | ||
114 | switch ( type() ) { | 122 | switch ( type() ) { |
115 | case Weekly: | 123 | case Weekly: |
116 | /* weekly is just daily by 7 */ | 124 | /* weekly is just daily by 7 */ |
117 | /* first convert the repeatPattern.Days() mask to the next | 125 | /* first convert the repeatPattern.Days() mask to the next |
118 | day of week valid after from */ | 126 | day of week valid after from */ |
119 | dayOfWeek = from.dayOfWeek(); | 127 | dayOfWeek = from.dayOfWeek(); |
120 | dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ | 128 | dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ |
121 | 129 | ||
122 | /* this is done in case freq > 1 and from in week not | 130 | /* this is done in case freq > 1 and from in week not |
123 | for this round */ | 131 | for this round */ |
124 | // firstOfWeek = 0; this is already done at decl. | 132 | // firstOfWeek = 0; this is already done at decl. |
125 | while(!((1 << firstOfWeek) & days() )) | 133 | while(!((1 << firstOfWeek) & days() )) |
126 | firstOfWeek++; | 134 | firstOfWeek++; |
127 | 135 | ||
128 | /* there is at least one 'day', or there would be no event */ | 136 | /* there is at least one 'day', or there would be no event */ |
129 | while(!((1 << (dayOfWeek % 7)) & days() )) | 137 | while(!((1 << (dayOfWeek % 7)) & days() )) |
130 | dayOfWeek++; | 138 | dayOfWeek++; |
131 | 139 | ||
132 | dayOfWeek = dayOfWeek % 7; /* the actual day of week */ | 140 | dayOfWeek = dayOfWeek % 7; /* the actual day of week */ |
133 | dayOfWeek -= start().dayOfWeek() -1; | 141 | dayOfWeek -= start().dayOfWeek() -1; |
134 | 142 | ||
135 | firstOfWeek = firstOfWeek % 7; /* the actual first of week */ | 143 | firstOfWeek = firstOfWeek % 7; /* the actual first of week */ |
136 | firstOfWeek -= start().dayOfWeek() -1; | 144 | firstOfWeek -= start().dayOfWeek() -1; |
137 | 145 | ||
138 | // dayOfWeek may be negitive now | 146 | // dayOfWeek may be negitive now |
139 | // day of week is number of days to add to start day | 147 | // day of week is number of days to add to start day |
140 | 148 | ||
141 | freq *= 7; | 149 | freq *= 7; |
142 | // FALL-THROUGH !!!!! | 150 | // FALL-THROUGH !!!!! |
143 | case Daily: | 151 | case Daily: |
144 | // the add is for the possible fall through from weekly */ | 152 | // the add is for the possible fall through from weekly */ |
145 | if(start().addDays(dayOfWeek) > from) { | 153 | if(start().addDays(dayOfWeek) > from) { |
146 | /* first week exception */ | 154 | /* first week exception */ |
147 | next = QDate(start().addDays(dayOfWeek) ); | 155 | next = QDate(start().addDays(dayOfWeek) ); |
148 | if ((next > endDate()) | 156 | if ((next > endDate()) |
149 | && hasEndDate() ) | 157 | && hasEndDate() ) |
150 | return FALSE; | 158 | return FALSE; |
151 | return TRUE; | 159 | return TRUE; |
152 | } | 160 | } |
153 | /* if from is middle of a non-week */ | 161 | /* if from is middle of a non-week */ |
154 | 162 | ||
155 | diff = start().addDays(dayOfWeek).daysTo(from) % freq; | 163 | diff = start().addDays(dayOfWeek).daysTo(from) % freq; |
156 | diff2 = start().addDays(firstOfWeek).daysTo(from) % freq; | 164 | diff2 = start().addDays(firstOfWeek).daysTo(from) % freq; |
157 | 165 | ||
158 | if(diff != 0) | 166 | if(diff != 0) |
159 | diff = freq - diff; | 167 | diff = freq - diff; |
160 | if(diff2 != 0) | 168 | if(diff2 != 0) |
161 | diff2 = freq - diff2; | 169 | diff2 = freq - diff2; |
162 | diff = QMIN(diff, diff2); | 170 | diff = QMIN(diff, diff2); |
163 | 171 | ||
164 | next = QDate(from.addDays(diff)); | 172 | next = QDate(from.addDays(diff)); |
165 | if ( (next > endDate()) | 173 | if ( (next > endDate()) |
166 | && hasEndDate() ) | 174 | && hasEndDate() ) |
167 | return FALSE; | 175 | return FALSE; |
168 | return TRUE; | 176 | return TRUE; |
169 | case MonthlyDay: | 177 | case MonthlyDay: |
170 | iday = from.day(); | 178 | iday = from.day(); |
171 | iyear = from.year(); | 179 | iyear = from.year(); |
172 | imonth = from.month(); | 180 | imonth = from.month(); |
173 | /* find equivelent day of month for this month */ | 181 | /* find equivelent day of month for this month */ |
174 | dayOfWeek = start().dayOfWeek(); | 182 | dayOfWeek = start().dayOfWeek(); |
175 | weekOfMonth = (start().day() - 1) / 7; | 183 | weekOfMonth = (start().day() - 1) / 7; |
176 | 184 | ||
177 | /* work out when the next valid month is */ | 185 | /* work out when the next valid month is */ |
178 | a = from.year() - start().year(); | 186 | a = from.year() - start().year(); |
179 | a *= 12; | 187 | a *= 12; |
180 | a = a + (imonth - start().month()); | 188 | a = a + (imonth - start().month()); |
181 | /* a is e.start()monthsFrom(from); */ | 189 | /* a is e.start()monthsFrom(from); */ |
182 | if(a % freq) { | 190 | if(a % freq) { |
183 | a = freq - (a % freq); | 191 | a = freq - (a % freq); |
184 | imonth = from.month() + a; | 192 | imonth = from.month() + a; |
185 | if (imonth > 12) { | 193 | if (imonth > 12) { |
186 | imonth--; | 194 | imonth--; |
187 | iyear += imonth / 12; | 195 | iyear += imonth / 12; |
188 | imonth = imonth % 12; | 196 | imonth = imonth % 12; |
189 | imonth++; | 197 | imonth++; |
190 | } | 198 | } |
191 | } | 199 | } |
192 | /* imonth is now the first month after or on | 200 | /* imonth is now the first month after or on |
193 | from that matches the frequency given */ | 201 | from that matches the frequency given */ |
194 | 202 | ||
195 | /* find for this month */ | 203 | /* find for this month */ |
196 | tmpDate = QDate( iyear, imonth, 1 ); | 204 | tmpDate = QDate( iyear, imonth, 1 ); |
197 | 205 | ||
198 | iday = 1; | 206 | iday = 1; |
199 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 207 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
200 | iday += 7 * weekOfMonth; | 208 | iday += 7 * weekOfMonth; |
201 | while (iday > tmpDate.daysInMonth()) { | 209 | while (iday > tmpDate.daysInMonth()) { |
202 | imonth += freq; | 210 | imonth += freq; |
203 | if (imonth > 12) { | 211 | if (imonth > 12) { |
204 | imonth--; | 212 | imonth--; |
205 | iyear += imonth / 12; | 213 | iyear += imonth / 12; |
206 | imonth = imonth % 12; | 214 | imonth = imonth % 12; |
207 | imonth++; | 215 | imonth++; |
208 | } | 216 | } |
209 | tmpDate = QDate( iyear, imonth, 1 ); | 217 | tmpDate = QDate( iyear, imonth, 1 ); |
210 | /* these loops could go for a while, check end case now */ | 218 | /* these loops could go for a while, check end case now */ |
211 | if ((tmpDate > endDate()) && hasEndDate() ) | 219 | if ((tmpDate > endDate()) && hasEndDate() ) |
212 | return FALSE; | 220 | return FALSE; |
213 | iday = 1; | 221 | iday = 1; |
214 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 222 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
215 | iday += 7 * weekOfMonth; | 223 | iday += 7 * weekOfMonth; |
216 | } | 224 | } |
217 | tmpDate = QDate(iyear, imonth, iday); | 225 | tmpDate = QDate(iyear, imonth, iday); |
218 | 226 | ||
219 | if (tmpDate >= from) { | 227 | if (tmpDate >= from) { |
220 | next = tmpDate; | 228 | next = tmpDate; |
221 | if ((next > endDate() ) && hasEndDate() ) | 229 | if ((next > endDate() ) && hasEndDate() ) |
222 | return FALSE; | 230 | return FALSE; |
223 | return TRUE; | 231 | return TRUE; |
224 | } | 232 | } |
225 | 233 | ||
226 | /* need to find the next iteration */ | 234 | /* need to find the next iteration */ |
227 | do { | 235 | do { |
228 | imonth += freq; | 236 | imonth += freq; |
diff --git a/libopie2/opiepim/core/orecur.h b/libopie2/opiepim/core/orecur.h index 47901b0..7750c12 100644 --- a/libopie2/opiepim/core/orecur.h +++ b/libopie2/opiepim/core/orecur.h | |||
@@ -1,101 +1,102 @@ | |||
1 | /* | 1 | /* |
2 | * GPL from TT | 2 | * GPL from TT |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #ifndef OPIE_RECUR_H | 5 | #ifndef OPIE_RECUR_H |
6 | #define OPIE_RECUR_H | 6 | #define OPIE_RECUR_H |
7 | 7 | ||
8 | #include <sys/types.h> | 8 | #include <sys/types.h> |
9 | 9 | ||
10 | #include <qdatetime.h> | 10 | #include <qdatetime.h> |
11 | #include <qvaluelist.h> | 11 | #include <qvaluelist.h> |
12 | #include <qmap.h> | 12 | #include <qmap.h> |
13 | 13 | ||
14 | class ORecur { | 14 | class ORecur { |
15 | public: | 15 | public: |
16 | typedef QValueList<QDate> ExceptionList; | 16 | typedef QValueList<QDate> ExceptionList; |
17 | enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, | 17 | enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, |
18 | MonthlyDate, Yearly }; | 18 | MonthlyDate, Yearly }; |
19 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, | 19 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, |
20 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; | 20 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; |
21 | enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate, | 21 | enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate, |
22 | EndDate, Created, Exceptions }; | 22 | EndDate, Created, Exceptions }; |
23 | 23 | ||
24 | ORecur(); | 24 | ORecur(); |
25 | ORecur( const QMap<int, QString>& map ); | ||
25 | ORecur( const ORecur& ); | 26 | ORecur( const ORecur& ); |
26 | ~ORecur(); | 27 | ~ORecur(); |
27 | 28 | ||
28 | ORecur &operator=( const ORecur& ); | 29 | ORecur &operator=( const ORecur& ); |
29 | bool operator==(const ORecur& )const; | 30 | bool operator==(const ORecur& )const; |
30 | 31 | ||
31 | bool doesRecur()const; | 32 | bool doesRecur()const; |
32 | /* if it recurrs on that day */ | 33 | /* if it recurrs on that day */ |
33 | bool doesRecur( const QDate& ); | 34 | bool doesRecur( const QDate& ); |
34 | RepeatType type()const; | 35 | RepeatType type()const; |
35 | int frequency()const; | 36 | int frequency()const; |
36 | int position()const; | 37 | int position()const; |
37 | char days()const; | 38 | char days()const; |
38 | bool hasEndDate()const; | 39 | bool hasEndDate()const; |
39 | QDate start()const; | 40 | QDate start()const; |
40 | QDate endDate()const; | 41 | QDate endDate()const; |
41 | QDateTime createdDateTime()const; | 42 | QDateTime createdDateTime()const; |
42 | /** | 43 | /** |
43 | * starting on monday=0, sunday=6 | 44 | * starting on monday=0, sunday=6 |
44 | * for convience | 45 | * for convience |
45 | */ | 46 | */ |
46 | bool repeatOnWeekDay( int day )const; | 47 | bool repeatOnWeekDay( int day )const; |
47 | 48 | ||
48 | /** | 49 | /** |
49 | * FromWhereToStart is not included!!! | 50 | * FromWhereToStart is not included!!! |
50 | */ | 51 | */ |
51 | bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); | 52 | bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); |
52 | 53 | ||
53 | /** | 54 | /** |
54 | * The module this ORecur belongs to | 55 | * The module this ORecur belongs to |
55 | */ | 56 | */ |
56 | QString service()const; | 57 | QString service()const; |
57 | 58 | ||
58 | /* | 59 | /* |
59 | * reference to the exception list | 60 | * reference to the exception list |
60 | */ | 61 | */ |
61 | ExceptionList &exceptions(); | 62 | ExceptionList &exceptions(); |
62 | 63 | ||
63 | /** | 64 | /** |
64 | * the current repetition | 65 | * the current repetition |
65 | */ | 66 | */ |
66 | int repetition()const; | 67 | int repetition()const; |
67 | 68 | ||
68 | void setType( const RepeatType& ); | 69 | void setType( const RepeatType& ); |
69 | void setFrequency( int freq ); | 70 | void setFrequency( int freq ); |
70 | void setPosition( int pos ); | 71 | void setPosition( int pos ); |
71 | void setDays( char c); | 72 | void setDays( char c); |
72 | void setEndDate( const QDate& dt ); | 73 | void setEndDate( const QDate& dt ); |
73 | void setStart( const QDate& dt ); | 74 | void setStart( const QDate& dt ); |
74 | void setCreatedDateTime( const QDateTime& ); | 75 | void setCreatedDateTime( const QDateTime& ); |
75 | void setHasEndDate( bool b ); | 76 | void setHasEndDate( bool b ); |
76 | void setRepitition(int ); | 77 | void setRepitition(int ); |
77 | 78 | ||
78 | void setService( const QString& ser ); | 79 | void setService( const QString& ser ); |
79 | 80 | ||
80 | QMap<int, QString> toMap() const; | 81 | QMap<int, QString> toMap() const; |
81 | void fromMap( const QMap<int, QString>& map ); | 82 | void fromMap( const QMap<int, QString>& map ); |
82 | 83 | ||
83 | /* almost internal */ | 84 | /* almost internal */ |
84 | QString toString()const; | 85 | QString toString()const; |
85 | private: | 86 | private: |
86 | bool p_nextOccurrence( const QDate& from, QDate& next ); | 87 | bool p_nextOccurrence( const QDate& from, QDate& next ); |
87 | void deref(); | 88 | void deref(); |
88 | inline void checkOrModify(); | 89 | inline void checkOrModify(); |
89 | 90 | ||
90 | /* Converts rType to String */ | 91 | /* Converts rType to String */ |
91 | QString rTypeString() const; | 92 | QString rTypeString() const; |
92 | /* Returns a map to convert Stringname for RType to RepeatType */ | 93 | /* Returns a map to convert Stringname for RType to RepeatType */ |
93 | QMap<QString, RepeatType> rTypeValueConvertMap() const; | 94 | QMap<QString, RepeatType> rTypeValueConvertMap() const; |
94 | 95 | ||
95 | class Data; | 96 | class Data; |
96 | Data* data; | 97 | Data* data; |
97 | class ORecurPrivate; | 98 | class ORecurPrivate; |
98 | ORecurPrivate *d; | 99 | ORecurPrivate *d; |
99 | }; | 100 | }; |
100 | 101 | ||
101 | #endif | 102 | #endif |
diff --git a/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp index 7bcf944..c916297 100644 --- a/libopie2/opiepim/oevent.cpp +++ b/libopie2/opiepim/oevent.cpp | |||
@@ -1,554 +1,681 @@ | |||
1 | #include <qshared.h> | 1 | #include <qshared.h> |
2 | #include <qarray.h> | ||
2 | 3 | ||
3 | #include <qpe/palmtopuidgen.h> | 4 | #include <qpe/palmtopuidgen.h> |
4 | #include <qpe/categories.h> | 5 | #include <qpe/categories.h> |
5 | #include <qpe/stringutil.h> | 6 | #include <qpe/stringutil.h> |
6 | 7 | ||
7 | #include "orecur.h" | 8 | #include "orecur.h" |
8 | #include "opimresolver.h" | 9 | #include "opimresolver.h" |
9 | #include "opimnotifymanager.h" | 10 | #include "opimnotifymanager.h" |
10 | 11 | ||
11 | #include "oevent.h" | 12 | #include "oevent.h" |
12 | 13 | ||
13 | int OCalendarHelper::week( const QDate& date) { | 14 | int OCalendarHelper::week( const QDate& date) { |
14 | // Calculates the week this date is in within that | 15 | // Calculates the week this date is in within that |
15 | // month. Equals the "row" is is in in the month view | 16 | // month. Equals the "row" is is in in the month view |
16 | int week = 1; | 17 | int week = 1; |
17 | QDate tmp( date.year(), date.month(), 1 ); | 18 | QDate tmp( date.year(), date.month(), 1 ); |
18 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) | 19 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) |
19 | ++week; | 20 | ++week; |
20 | 21 | ||
21 | week += ( date.day() - 1 ) / 7; | 22 | week += ( date.day() - 1 ) / 7; |
22 | 23 | ||
23 | return week; | 24 | return week; |
24 | } | 25 | } |
25 | int OCalendarHelper::ocurrence( const QDate& date) { | 26 | int OCalendarHelper::ocurrence( const QDate& date) { |
26 | // calculates the number of occurrances of this day of the | 27 | // calculates the number of occurrances of this day of the |
27 | // week till the given date (e.g 3rd Wednesday of the month) | 28 | // week till the given date (e.g 3rd Wednesday of the month) |
28 | return ( date.day() - 1 ) / 7 + 1; | 29 | return ( date.day() - 1 ) / 7 + 1; |
29 | } | 30 | } |
30 | int OCalendarHelper::dayOfWeek( char day ) { | 31 | int OCalendarHelper::dayOfWeek( char day ) { |
31 | int dayOfWeek = 1; | 32 | int dayOfWeek = 1; |
32 | char i = ORecur::MON; | 33 | char i = ORecur::MON; |
33 | while ( !( i & day ) && i <= ORecur::SUN ) { | 34 | while ( !( i & day ) && i <= ORecur::SUN ) { |
34 | i <<= 1; | 35 | i <<= 1; |
35 | ++dayOfWeek; | 36 | ++dayOfWeek; |
36 | } | 37 | } |
37 | return dayOfWeek; | 38 | return dayOfWeek; |
38 | } | 39 | } |
39 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { | 40 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { |
40 | return ( second.year() - first.year() ) * 12 + | 41 | return ( second.year() - first.year() ) * 12 + |
41 | second.month() - first.month(); | 42 | second.month() - first.month(); |
42 | } | 43 | } |
43 | 44 | ||
44 | struct OEvent::Data : public QShared { | 45 | struct OEvent::Data : public QShared { |
45 | Data() : QShared() { | 46 | Data() : QShared() { |
46 | child = 0; | 47 | child = 0; |
47 | recur = 0; | 48 | recur = 0; |
48 | manager = 0; | 49 | manager = 0; |
49 | isAllDay = false; | 50 | isAllDay = false; |
50 | parent = 0; | 51 | parent = 0; |
51 | } | 52 | } |
52 | ~Data() { | 53 | ~Data() { |
53 | delete manager; | 54 | delete manager; |
54 | delete recur; | 55 | delete recur; |
55 | } | 56 | } |
56 | QString description; | 57 | QString description; |
57 | QString location; | 58 | QString location; |
58 | OPimNotifyManager* manager; | 59 | OPimNotifyManager* manager; |
59 | ORecur* recur; | 60 | ORecur* recur; |
60 | QString note; | 61 | QString note; |
61 | QDateTime created; | 62 | QDateTime created; |
62 | QDateTime start; | 63 | QDateTime start; |
63 | QDateTime end; | 64 | QDateTime end; |
64 | bool isAllDay : 1; | 65 | bool isAllDay : 1; |
65 | QString timezone; | 66 | QString timezone; |
66 | QArray<int>* child; | 67 | QArray<int>* child; |
67 | int parent; | 68 | int parent; |
68 | }; | 69 | }; |
69 | 70 | ||
70 | OEvent::OEvent( int uid ) | 71 | OEvent::OEvent( int uid ) |
71 | : OPimRecord( uid ) { | 72 | : OPimRecord( uid ) { |
72 | data = new Data; | 73 | data = new Data; |
73 | } | 74 | } |
74 | OEvent::OEvent( const OEvent& ev) | 75 | OEvent::OEvent( const OEvent& ev) |
75 | : OPimRecord( ev ), data( ev.data ) | 76 | : OPimRecord( ev ), data( ev.data ) |
76 | { | 77 | { |
77 | data->ref(); | 78 | data->ref(); |
78 | } | 79 | } |
79 | OEvent::~OEvent() { | 80 | OEvent::~OEvent() { |
80 | if ( data->deref() ) { | 81 | if ( data->deref() ) { |
81 | delete data; | 82 | delete data; |
82 | data = 0; | 83 | data = 0; |
83 | } | 84 | } |
84 | } | 85 | } |
85 | OEvent& OEvent::operator=( const OEvent& ev) { | 86 | OEvent& OEvent::operator=( const OEvent& ev) { |
86 | if ( this == &ev ) return *this; | 87 | if ( this == &ev ) return *this; |
87 | 88 | ||
88 | OPimRecord::operator=( ev ); | 89 | OPimRecord::operator=( ev ); |
89 | ev.data->ref(); | 90 | ev.data->ref(); |
90 | deref(); | 91 | deref(); |
91 | data = ev.data; | 92 | data = ev.data; |
92 | 93 | ||
93 | 94 | ||
94 | return *this; | 95 | return *this; |
95 | } | 96 | } |
96 | QString OEvent::description()const { | 97 | QString OEvent::description()const { |
97 | return data->description; | 98 | return data->description; |
98 | } | 99 | } |
99 | void OEvent::setDescription( const QString& description ) { | 100 | void OEvent::setDescription( const QString& description ) { |
100 | changeOrModify(); | 101 | changeOrModify(); |
101 | data->description = description; | 102 | data->description = description; |
102 | } | 103 | } |
103 | void OEvent::setLocation( const QString& loc ) { | 104 | void OEvent::setLocation( const QString& loc ) { |
104 | changeOrModify(); | 105 | changeOrModify(); |
105 | data->location = loc; | 106 | data->location = loc; |
106 | } | 107 | } |
107 | QString OEvent::location()const { | 108 | QString OEvent::location()const { |
108 | return data->location; | 109 | return data->location; |
109 | } | 110 | } |
110 | OPimNotifyManager &OEvent::notifiers()const { | 111 | OPimNotifyManager &OEvent::notifiers()const { |
111 | // I hope we can skip the changeOrModify here | 112 | // I hope we can skip the changeOrModify here |
112 | // the notifier should take care of it | 113 | // the notifier should take care of it |
113 | // and OPimNotify is shared too | 114 | // and OPimNotify is shared too |
114 | if (!data->manager ) | 115 | if (!data->manager ) |
115 | data->manager = new OPimNotifyManager; | 116 | data->manager = new OPimNotifyManager; |
116 | 117 | ||
117 | return *data->manager; | 118 | return *data->manager; |
118 | } | 119 | } |
119 | bool OEvent::hasNotifiers()const { | 120 | bool OEvent::hasNotifiers()const { |
120 | if (!data->manager ) | 121 | if (!data->manager ) |
121 | return false; | 122 | return false; |
122 | if (data->manager->reminders().isEmpty() && | 123 | if (data->manager->reminders().isEmpty() && |
123 | data->manager->alarms().isEmpty() ) | 124 | data->manager->alarms().isEmpty() ) |
124 | return false; | 125 | return false; |
125 | 126 | ||
126 | return true; | 127 | return true; |
127 | } | 128 | } |
128 | ORecur OEvent::recurrence()const { | 129 | ORecur OEvent::recurrence()const { |
129 | if (!data->recur) | 130 | if (!data->recur) |
130 | data->recur = new ORecur; | 131 | data->recur = new ORecur; |
131 | 132 | ||
132 | return *data->recur; | 133 | return *data->recur; |
133 | } | 134 | } |
134 | void OEvent::setRecurrence( const ORecur& rec) { | 135 | void OEvent::setRecurrence( const ORecur& rec) { |
135 | changeOrModify(); | 136 | changeOrModify(); |
136 | if (data->recur ) | 137 | if (data->recur ) |
137 | (*data->recur) = rec; | 138 | (*data->recur) = rec; |
138 | else | 139 | else |
139 | data->recur = new ORecur( rec ); | 140 | data->recur = new ORecur( rec ); |
140 | } | 141 | } |
141 | bool OEvent::hasRecurrence()const { | 142 | bool OEvent::hasRecurrence()const { |
142 | if (!data->recur ) return false; | 143 | if (!data->recur ) return false; |
143 | return data->recur->doesRecur(); | 144 | return data->recur->doesRecur(); |
144 | } | 145 | } |
145 | QString OEvent::note()const { | 146 | QString OEvent::note()const { |
146 | return data->note; | 147 | return data->note; |
147 | } | 148 | } |
148 | void OEvent::setNote( const QString& note ) { | 149 | void OEvent::setNote( const QString& note ) { |
149 | changeOrModify(); | 150 | changeOrModify(); |
150 | data->note = note; | 151 | data->note = note; |
151 | } | 152 | } |
152 | QDateTime OEvent::createdDateTime()const { | 153 | QDateTime OEvent::createdDateTime()const { |
153 | return data->created; | 154 | return data->created; |
154 | } | 155 | } |
155 | void OEvent::setCreatedDateTime( const QDateTime& time ) { | 156 | void OEvent::setCreatedDateTime( const QDateTime& time ) { |
156 | changeOrModify(); | 157 | changeOrModify(); |
157 | data->created = time; | 158 | data->created = time; |
158 | } | 159 | } |
159 | QDateTime OEvent::startDateTime()const { | 160 | QDateTime OEvent::startDateTime()const { |
160 | if ( data->isAllDay ) | 161 | if ( data->isAllDay ) |
161 | return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); | 162 | return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); |
162 | return data->start; | 163 | return data->start; |
163 | } | 164 | } |
164 | QDateTime OEvent::startDateTimeInZone()const { | 165 | QDateTime OEvent::startDateTimeInZone()const { |
165 | /* if no timezone, or all day event or if the current and this timeZone match... */ | 166 | /* if no timezone, or all day event or if the current and this timeZone match... */ |
166 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); | 167 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); |
167 | 168 | ||
168 | OTimeZone zone(data->timezone ); | 169 | OTimeZone zone(data->timezone ); |
169 | return zone.toDateTime( data->start, OTimeZone::current() ); | 170 | return zone.toDateTime( data->start, OTimeZone::current() ); |
170 | } | 171 | } |
171 | void OEvent::setStartDateTime( const QDateTime& dt ) { | 172 | void OEvent::setStartDateTime( const QDateTime& dt ) { |
172 | changeOrModify(); | 173 | changeOrModify(); |
173 | data->start = dt; | 174 | data->start = dt; |
174 | } | 175 | } |
175 | QDateTime OEvent::endDateTime()const { | 176 | QDateTime OEvent::endDateTime()const { |
176 | /* | 177 | /* |
177 | * if all Day event the end time needs | 178 | * if all Day event the end time needs |
178 | * to be on the same day as the start | 179 | * to be on the same day as the start |
179 | */ | 180 | */ |
180 | if ( data->isAllDay ) | 181 | if ( data->isAllDay ) |
181 | return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); | 182 | return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); |
182 | return data->end; | 183 | return data->end; |
183 | } | 184 | } |
184 | QDateTime OEvent::endDateTimeInZone()const { | 185 | QDateTime OEvent::endDateTimeInZone()const { |
185 | /* if no timezone, or all day event or if the current and this timeZone match... */ | 186 | /* if no timezone, or all day event or if the current and this timeZone match... */ |
186 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); | 187 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); |
187 | 188 | ||
188 | OTimeZone zone(data->timezone ); | 189 | OTimeZone zone(data->timezone ); |
189 | return zone.toDateTime( data->end, OTimeZone::current() ); | 190 | return zone.toDateTime( data->end, OTimeZone::current() ); |
190 | } | 191 | } |
191 | void OEvent::setEndDateTime( const QDateTime& dt ) { | 192 | void OEvent::setEndDateTime( const QDateTime& dt ) { |
192 | changeOrModify(); | 193 | changeOrModify(); |
193 | data->end = dt; | 194 | data->end = dt; |
194 | } | 195 | } |
195 | bool OEvent::isMultipleDay()const { | 196 | bool OEvent::isMultipleDay()const { |
196 | return data->end.date().day() - data->start.date().day(); | 197 | return data->end.date().day() - data->start.date().day(); |
197 | } | 198 | } |
198 | bool OEvent::isAllDay()const { | 199 | bool OEvent::isAllDay()const { |
199 | return data->isAllDay; | 200 | return data->isAllDay; |
200 | } | 201 | } |
201 | void OEvent::setAllDay( bool allDay ) { | 202 | void OEvent::setAllDay( bool allDay ) { |
202 | changeOrModify(); | 203 | changeOrModify(); |
203 | data->isAllDay = allDay; | 204 | data->isAllDay = allDay; |
204 | if (allDay ) data->timezone = "UTC"; | 205 | if (allDay ) data->timezone = "UTC"; |
205 | } | 206 | } |
206 | void OEvent::setTimeZone( const QString& tz ) { | 207 | void OEvent::setTimeZone( const QString& tz ) { |
207 | changeOrModify(); | 208 | changeOrModify(); |
208 | data->timezone = tz; | 209 | data->timezone = tz; |
209 | } | 210 | } |
210 | QString OEvent::timeZone()const { | 211 | QString OEvent::timeZone()const { |
211 | if (data->isAllDay ) return QString::fromLatin1("UTC"); | 212 | if (data->isAllDay ) return QString::fromLatin1("UTC"); |
212 | return data->timezone; | 213 | return data->timezone; |
213 | } | 214 | } |
214 | bool OEvent::match( const QRegExp& re )const { | 215 | bool OEvent::match( const QRegExp& re )const { |
215 | if ( re.match( data->description ) != -1 ){ | 216 | if ( re.match( data->description ) != -1 ){ |
216 | setLastHitField( Qtopia::DatebookDescription ); | 217 | setLastHitField( Qtopia::DatebookDescription ); |
217 | return true; | 218 | return true; |
218 | } | 219 | } |
219 | if ( re.match( data->note ) != -1 ){ | 220 | if ( re.match( data->note ) != -1 ){ |
220 | setLastHitField( Qtopia::Note ); | 221 | setLastHitField( Qtopia::Note ); |
221 | return true; | 222 | return true; |
222 | } | 223 | } |
223 | if ( re.match( data->location ) != -1 ){ | 224 | if ( re.match( data->location ) != -1 ){ |
224 | setLastHitField( Qtopia::Location ); | 225 | setLastHitField( Qtopia::Location ); |
225 | return true; | 226 | return true; |
226 | } | 227 | } |
227 | if ( re.match( data->start.toString() ) != -1 ){ | 228 | if ( re.match( data->start.toString() ) != -1 ){ |
228 | setLastHitField( Qtopia::StartDateTime ); | 229 | setLastHitField( Qtopia::StartDateTime ); |
229 | return true; | 230 | return true; |
230 | } | 231 | } |
231 | if ( re.match( data->end.toString() ) != -1 ){ | 232 | if ( re.match( data->end.toString() ) != -1 ){ |
232 | setLastHitField( Qtopia::EndDateTime ); | 233 | setLastHitField( Qtopia::EndDateTime ); |
233 | return true; | 234 | return true; |
234 | } | 235 | } |
235 | return false; | 236 | return false; |
236 | } | 237 | } |
237 | QString OEvent::toRichText()const { | 238 | QString OEvent::toRichText()const { |
238 | QString text, value; | 239 | QString text, value; |
239 | 240 | ||
240 | // description | 241 | // description |
241 | text += "<b><h3><img src=\"datebook/DateBook\">"; | 242 | text += "<b><h3><img src=\"datebook/DateBook\">"; |
242 | if ( !description().isEmpty() ) { | 243 | if ( !description().isEmpty() ) { |
243 | text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "" ); | 244 | text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "" ); |
244 | } | 245 | } |
245 | text += "</h3></b><br><hr><br>"; | 246 | text += "</h3></b><br><hr><br>"; |
246 | 247 | ||
247 | // location | 248 | // location |
248 | if ( !(value = location()).isEmpty() ) { | 249 | if ( !(value = location()).isEmpty() ) { |
249 | text += "<b>" + QObject::tr( "Location:" ) + "</b> "; | 250 | text += "<b>" + QObject::tr( "Location:" ) + "</b> "; |
250 | text += Qtopia::escapeString(value) + "<br>"; | 251 | text += Qtopia::escapeString(value) + "<br>"; |
251 | } | 252 | } |
252 | 253 | ||
253 | // all day event | 254 | // all day event |
254 | if ( isAllDay() ) { | 255 | if ( isAllDay() ) { |
255 | text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>"; | 256 | text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>"; |
256 | } | 257 | } |
257 | // multiple day event | 258 | // multiple day event |
258 | else if ( isMultipleDay () ) { | 259 | else if ( isMultipleDay () ) { |
259 | text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>"; | 260 | text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>"; |
260 | } | 261 | } |
261 | // start & end times | 262 | // start & end times |
262 | else { | 263 | else { |
263 | // start time | 264 | // start time |
264 | if ( startDateTime().isValid() ) { | 265 | if ( startDateTime().isValid() ) { |
265 | text += "<b>" + QObject::tr( "Start:") + "</b> "; | 266 | text += "<b>" + QObject::tr( "Start:") + "</b> "; |
266 | text += Qtopia::escapeString(startDateTime().toString() ). | 267 | text += Qtopia::escapeString(startDateTime().toString() ). |
267 | replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; | 268 | replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; |
268 | } | 269 | } |
269 | 270 | ||
270 | // end time | 271 | // end time |
271 | if ( endDateTime().isValid() ) { | 272 | if ( endDateTime().isValid() ) { |
272 | text += "<b>" + QObject::tr( "End:") + "</b> "; | 273 | text += "<b>" + QObject::tr( "End:") + "</b> "; |
273 | text += Qtopia::escapeString(endDateTime().toString() ). | 274 | text += Qtopia::escapeString(endDateTime().toString() ). |
274 | replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; | 275 | replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; |
275 | } | 276 | } |
276 | } | 277 | } |
277 | 278 | ||
278 | // categories | 279 | // categories |
279 | if ( categoryNames("Calendar").count() ){ | 280 | if ( categoryNames("Calendar").count() ){ |
280 | text += "<b>" + QObject::tr( "Category:") + "</b> "; | 281 | text += "<b>" + QObject::tr( "Category:") + "</b> "; |
281 | text += categoryNames("Calendar").join(", "); | 282 | text += categoryNames("Calendar").join(", "); |
282 | text += "<br>"; | 283 | text += "<br>"; |
283 | } | 284 | } |
284 | 285 | ||
285 | //notes | 286 | //notes |
286 | if ( !note().isEmpty() ) { | 287 | if ( !note().isEmpty() ) { |
287 | text += "<b>" + QObject::tr( "Note:") + "</b><br>"; | 288 | text += "<b>" + QObject::tr( "Note:") + "</b><br>"; |
288 | text += note(); | 289 | text += note(); |
289 | // text += Qtopia::escapeString(note() ). | 290 | // text += Qtopia::escapeString(note() ). |
290 | // replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; | 291 | // replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; |
291 | } | 292 | } |
292 | return text; | 293 | return text; |
293 | } | 294 | } |
294 | QString OEvent::toShortText()const { | 295 | QString OEvent::toShortText()const { |
295 | QString text; | 296 | QString text; |
296 | text += QString::number( startDateTime().date().day() ); | 297 | text += QString::number( startDateTime().date().day() ); |
297 | text += "."; | 298 | text += "."; |
298 | text += QString::number( startDateTime().date().month() ); | 299 | text += QString::number( startDateTime().date().month() ); |
299 | text += "."; | 300 | text += "."; |
300 | text += QString::number( startDateTime().date().year() ); | 301 | text += QString::number( startDateTime().date().year() ); |
301 | text += " "; | 302 | text += " "; |
302 | text += QString::number( startDateTime().time().hour() ); | 303 | text += QString::number( startDateTime().time().hour() ); |
303 | text += ":"; | 304 | text += ":"; |
304 | text += QString::number( startDateTime().time().minute() ); | 305 | text += QString::number( startDateTime().time().minute() ); |
305 | text += " - "; | 306 | text += " - "; |
306 | text += description(); | 307 | text += description(); |
307 | return text; | 308 | return text; |
308 | } | 309 | } |
309 | QString OEvent::type()const { | 310 | QString OEvent::type()const { |
310 | return QString::fromLatin1("OEvent"); | 311 | return QString::fromLatin1("OEvent"); |
311 | } | 312 | } |
312 | QString OEvent::recordField( int /*id */ )const { | 313 | QString OEvent::recordField( int /*id */ )const { |
313 | return QString::null; | 314 | return QString::null; |
314 | } | 315 | } |
315 | int OEvent::rtti() { | 316 | int OEvent::rtti() { |
316 | return OPimResolver::DateBook; | 317 | return OPimResolver::DateBook; |
317 | } | 318 | } |
318 | bool OEvent::loadFromStream( QDataStream& ) { | 319 | bool OEvent::loadFromStream( QDataStream& ) { |
319 | return true; | 320 | return true; |
320 | } | 321 | } |
321 | bool OEvent::saveToStream( QDataStream& )const { | 322 | bool OEvent::saveToStream( QDataStream& )const { |
322 | return true; | 323 | return true; |
323 | } | 324 | } |
324 | void OEvent::changeOrModify() { | 325 | void OEvent::changeOrModify() { |
325 | if ( data->count != 1 ) { | 326 | if ( data->count != 1 ) { |
326 | data->deref(); | 327 | data->deref(); |
327 | Data* d2 = new Data; | 328 | Data* d2 = new Data; |
328 | d2->description = data->description; | 329 | d2->description = data->description; |
329 | d2->location = data->location; | 330 | d2->location = data->location; |
330 | 331 | ||
331 | if (data->manager ) | 332 | if (data->manager ) |
332 | d2->manager = new OPimNotifyManager( *data->manager ); | 333 | d2->manager = new OPimNotifyManager( *data->manager ); |
333 | 334 | ||
334 | if ( data->recur ) | 335 | if ( data->recur ) |
335 | d2->recur = new ORecur( *data->recur ); | 336 | d2->recur = new ORecur( *data->recur ); |
336 | 337 | ||
337 | d2->note = data->note; | 338 | d2->note = data->note; |
338 | d2->created = data->created; | 339 | d2->created = data->created; |
339 | d2->start = data->start; | 340 | d2->start = data->start; |
340 | d2->end = data->end; | 341 | d2->end = data->end; |
341 | d2->isAllDay = data->isAllDay; | 342 | d2->isAllDay = data->isAllDay; |
342 | d2->timezone = data->timezone; | 343 | d2->timezone = data->timezone; |
343 | d2->parent = data->parent; | 344 | d2->parent = data->parent; |
344 | 345 | ||
345 | if ( data->child ) { | 346 | if ( data->child ) { |
346 | d2->child = new QArray<int>( *data->child ); | 347 | d2->child = new QArray<int>( *data->child ); |
347 | d2->child->detach(); | 348 | d2->child->detach(); |
348 | } | 349 | } |
349 | 350 | ||
350 | data = d2; | 351 | data = d2; |
351 | } | 352 | } |
352 | } | 353 | } |
353 | void OEvent::deref() { | 354 | void OEvent::deref() { |
354 | if ( data->deref() ) { | 355 | if ( data->deref() ) { |
355 | delete data; | 356 | delete data; |
356 | data = 0; | 357 | data = 0; |
357 | } | 358 | } |
358 | } | 359 | } |
359 | // FIXME | 360 | // Exporting Event data to map. Using the same |
361 | // encoding as ODateBookAccessBackend_xml does.. | ||
362 | // Thus, we could remove the stuff there and use this | ||
363 | // for it and for all other places.. | ||
364 | // Encoding should happen at one place, only ! (eilers) | ||
360 | QMap<int, QString> OEvent::toMap()const { | 365 | QMap<int, QString> OEvent::toMap()const { |
361 | return QMap<int, QString>(); | 366 | QMap<int, QString> retMap; |
367 | |||
368 | retMap.insert( OEvent::FUid, QString::number( uid() ) ); | ||
369 | retMap.insert( OEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) )); | ||
370 | retMap.insert( OEvent::FDescription, Qtopia::escapeString( description() ) ); | ||
371 | retMap.insert( OEvent::FLocation, Qtopia::escapeString( location() ) ); | ||
372 | retMap.insert( OEvent::FType, isAllDay() ? "AllDay" : "" ); | ||
373 | OPimAlarm alarm = notifiers().alarms()[0]; | ||
374 | retMap.insert( OEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); | ||
375 | retMap.insert( OEvent::FSound, (alarm.sound() == OPimAlarm::Loud) ? "loud" : "silent" ); | ||
376 | |||
377 | OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); | ||
378 | retMap.insert( OEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OTimeZone::utc() ) ) ) ); | ||
379 | retMap.insert( OEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OTimeZone::utc() ) ) ) ); | ||
380 | retMap.insert( OEvent::FNote, Qtopia::escapeString( note() ) ); | ||
381 | retMap.insert( OEvent::FTimeZone, timeZone().isEmpty() ? "None" : timeZone() ); | ||
382 | if( parent() ) | ||
383 | retMap.insert( OEvent::FRecParent, QString::number( parent() ) ); | ||
384 | if( children().count() ){ | ||
385 | QArray<int> childr = children(); | ||
386 | QString buf; | ||
387 | for ( uint i = 0; i < childr.count(); i++ ) { | ||
388 | if ( i != 0 ) buf += " "; | ||
389 | buf += QString::number( childr[i] ); | ||
390 | } | ||
391 | retMap.insert( OEvent::FRecChildren, buf ); | ||
392 | } | ||
393 | |||
394 | // Add recurrence stuff | ||
395 | if( hasRecurrence() ){ | ||
396 | ORecur recur = recurrence(); | ||
397 | QMap<int, QString> recFields = recur.toMap(); | ||
398 | retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); | ||
399 | retMap.insert( OEvent::FRWeekdays, recFields[ORecur::RWeekdays] ); | ||
400 | retMap.insert( OEvent::FRPosition, recFields[ORecur::RPosition] ); | ||
401 | retMap.insert( OEvent::FRFreq, recFields[ORecur::RFreq] ); | ||
402 | retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] ); | ||
403 | retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] ); | ||
404 | retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] ); | ||
405 | retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] ); | ||
406 | } | ||
407 | |||
408 | return retMap; | ||
409 | } | ||
410 | |||
411 | void OEvent::fromMap( const QMap<int, QString>& map ) | ||
412 | { | ||
413 | |||
414 | // We just want to set the UID if it is really stored. | ||
415 | if ( !map[OEvent::FUid].isEmpty() ) | ||
416 | setUid( map[OEvent::FUid].toInt() ); | ||
417 | |||
418 | setCategories( idsFromString( map[OEvent::FCategories] ) ); | ||
419 | setDescription( map[OEvent::FDescription] ); | ||
420 | setLocation( map[OEvent::FLocation] ); | ||
421 | |||
422 | if ( map[OEvent::FType] == "AllDay" ) | ||
423 | setAllDay( true ); | ||
424 | else | ||
425 | setAllDay( false ); | ||
426 | |||
427 | int alarmTime = -1; | ||
428 | if( !map[OEvent::FAlarm].isEmpty() ) | ||
429 | alarmTime = map[OEvent::FAlarm].toInt(); | ||
430 | |||
431 | int sound = ( ( map[OEvent::FSound] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent ); | ||
432 | if ( ( alarmTime != -1 ) ){ | ||
433 | QDateTime dt = startDateTime().addSecs( -1*alarmTime*60 ); | ||
434 | OPimAlarm al( sound , dt ); | ||
435 | notifiers().add( al ); | ||
436 | } | ||
437 | if ( !map[OEvent::FTimeZone].isEmpty() && ( map[OEvent::FTimeZone] != "None" ) ){ | ||
438 | setTimeZone( map[OEvent::FTimeZone] ); | ||
439 | } | ||
440 | |||
441 | time_t start = (time_t) map[OEvent::FStart].toLong(); | ||
442 | time_t end = (time_t) map[OEvent::FEnd].toLong(); | ||
443 | |||
444 | /* AllDay is always in UTC */ | ||
445 | if ( isAllDay() ) { | ||
446 | OTimeZone utc = OTimeZone::utc(); | ||
447 | setStartDateTime( utc.fromUTCDateTime( start ) ); | ||
448 | setEndDateTime ( utc.fromUTCDateTime( end ) ); | ||
449 | setTimeZone( "UTC"); // make sure it is really utc | ||
450 | }else { | ||
451 | /* to current date time */ | ||
452 | // qWarning(" Start is %d", start ); | ||
453 | OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); | ||
454 | QDateTime date = zone.toDateTime( start ); | ||
455 | qWarning(" Start is %s", date.toString().latin1() ); | ||
456 | setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); | ||
457 | |||
458 | date = zone.toDateTime( end ); | ||
459 | setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); | ||
460 | } | ||
461 | |||
462 | if ( !map[OEvent::FRecParent].isEmpty() ) | ||
463 | setParent( map[OEvent::FRecParent].toInt() ); | ||
464 | |||
465 | if ( !map[OEvent::FRecChildren].isEmpty() ){ | ||
466 | QStringList list = QStringList::split(' ', map[OEvent::FRecChildren] ); | ||
467 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | ||
468 | addChild( (*it).toInt() ); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | // Fill recurrence stuff and put it directly into the ORecur-Object using fromMap.. | ||
473 | if( !map[OEvent::FRType].isEmpty() ){ | ||
474 | QMap<int, QString> recFields; | ||
475 | recFields.insert( ORecur::RType, map[OEvent::FRType] ); | ||
476 | recFields.insert( ORecur::RWeekdays, map[OEvent::FRWeekdays] ); | ||
477 | recFields.insert( ORecur::RPosition, map[OEvent::FRPosition] ); | ||
478 | recFields.insert( ORecur::RFreq, map[OEvent::FRFreq] ); | ||
479 | recFields.insert( ORecur::RHasEndDate, map[OEvent::FRHasEndDate] ); | ||
480 | recFields.insert( ORecur::EndDate, map[OEvent::FREndDate] ); | ||
481 | recFields.insert( ORecur::Created, map[OEvent::FRCreated] ); | ||
482 | recFields.insert( ORecur::Exceptions, map[OEvent::FRExceptions] ); | ||
483 | ORecur recur( recFields ); | ||
484 | setRecurrence( recur ); | ||
485 | } | ||
486 | |||
362 | } | 487 | } |
488 | |||
489 | |||
363 | int OEvent::parent()const { | 490 | int OEvent::parent()const { |
364 | return data->parent; | 491 | return data->parent; |
365 | } | 492 | } |
366 | void OEvent::setParent( int uid ) { | 493 | void OEvent::setParent( int uid ) { |
367 | changeOrModify(); | 494 | changeOrModify(); |
368 | data->parent = uid; | 495 | data->parent = uid; |
369 | } | 496 | } |
370 | QArray<int> OEvent::children() const{ | 497 | QArray<int> OEvent::children() const{ |
371 | if (!data->child) return QArray<int>(); | 498 | if (!data->child) return QArray<int>(); |
372 | else | 499 | else |
373 | return data->child->copy(); | 500 | return data->child->copy(); |
374 | } | 501 | } |
375 | void OEvent::setChildren( const QArray<int>& arr ) { | 502 | void OEvent::setChildren( const QArray<int>& arr ) { |
376 | changeOrModify(); | 503 | changeOrModify(); |
377 | if (data->child) delete data->child; | 504 | if (data->child) delete data->child; |
378 | 505 | ||
379 | data->child = new QArray<int>( arr ); | 506 | data->child = new QArray<int>( arr ); |
380 | data->child->detach(); | 507 | data->child->detach(); |
381 | } | 508 | } |
382 | void OEvent::addChild( int uid ) { | 509 | void OEvent::addChild( int uid ) { |
383 | changeOrModify(); | 510 | changeOrModify(); |
384 | if (!data->child ) { | 511 | if (!data->child ) { |
385 | data->child = new QArray<int>(1); | 512 | data->child = new QArray<int>(1); |
386 | (*data->child)[0] = uid; | 513 | (*data->child)[0] = uid; |
387 | }else{ | 514 | }else{ |
388 | int count = data->child->count(); | 515 | int count = data->child->count(); |
389 | data->child->resize( count + 1 ); | 516 | data->child->resize( count + 1 ); |
390 | (*data->child)[count] = uid; | 517 | (*data->child)[count] = uid; |
391 | } | 518 | } |
392 | } | 519 | } |
393 | void OEvent::removeChild( int uid ) { | 520 | void OEvent::removeChild( int uid ) { |
394 | if (!data->child || !data->child->contains( uid ) ) return; | 521 | if (!data->child || !data->child->contains( uid ) ) return; |
395 | changeOrModify(); | 522 | changeOrModify(); |
396 | QArray<int> newAr( data->child->count() - 1 ); | 523 | QArray<int> newAr( data->child->count() - 1 ); |
397 | int j = 0; | 524 | int j = 0; |
398 | uint count = data->child->count(); | 525 | uint count = data->child->count(); |
399 | for ( uint i = 0; i < count; i++ ) { | 526 | for ( uint i = 0; i < count; i++ ) { |
400 | if ( (*data->child)[i] != uid ) { | 527 | if ( (*data->child)[i] != uid ) { |
401 | newAr[j] = (*data->child)[i]; | 528 | newAr[j] = (*data->child)[i]; |
402 | j++; | 529 | j++; |
403 | } | 530 | } |
404 | } | 531 | } |
405 | (*data->child) = newAr; | 532 | (*data->child) = newAr; |
406 | } | 533 | } |
407 | struct OEffectiveEvent::Data : public QShared { | 534 | struct OEffectiveEvent::Data : public QShared { |
408 | Data() : QShared() { | 535 | Data() : QShared() { |
409 | } | 536 | } |
410 | OEvent event; | 537 | OEvent event; |
411 | QDate date; | 538 | QDate date; |
412 | QTime start, end; | 539 | QTime start, end; |
413 | QDate startDate, endDate; | 540 | QDate startDate, endDate; |
414 | bool dates : 1; | 541 | bool dates : 1; |
415 | }; | 542 | }; |
416 | 543 | ||
417 | OEffectiveEvent::OEffectiveEvent() { | 544 | OEffectiveEvent::OEffectiveEvent() { |
418 | data = new Data; | 545 | data = new Data; |
419 | data->date = QDate::currentDate(); | 546 | data->date = QDate::currentDate(); |
420 | data->start = data->end = QTime::currentTime(); | 547 | data->start = data->end = QTime::currentTime(); |
421 | data->dates = false; | 548 | data->dates = false; |
422 | } | 549 | } |
423 | OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, | 550 | OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, |
424 | Position pos ) { | 551 | Position pos ) { |
425 | data = new Data; | 552 | data = new Data; |
426 | data->event = ev; | 553 | data->event = ev; |
427 | data->date = startDate; | 554 | data->date = startDate; |
428 | if ( pos & Start ) | 555 | if ( pos & Start ) |
429 | data->start = ev.startDateTime().time(); | 556 | data->start = ev.startDateTime().time(); |
430 | else | 557 | else |
431 | data->start = QTime( 0, 0, 0 ); | 558 | data->start = QTime( 0, 0, 0 ); |
432 | 559 | ||
433 | if ( pos & End ) | 560 | if ( pos & End ) |
434 | data->end = ev.endDateTime().time(); | 561 | data->end = ev.endDateTime().time(); |
435 | else | 562 | else |
436 | data->end = QTime( 23, 59, 59 ); | 563 | data->end = QTime( 23, 59, 59 ); |
437 | 564 | ||
438 | data->dates = false; | 565 | data->dates = false; |
439 | } | 566 | } |
440 | OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { | 567 | OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { |
441 | data = ev.data; | 568 | data = ev.data; |
442 | data->ref(); | 569 | data->ref(); |
443 | } | 570 | } |
444 | OEffectiveEvent::~OEffectiveEvent() { | 571 | OEffectiveEvent::~OEffectiveEvent() { |
445 | if ( data->deref() ) { | 572 | if ( data->deref() ) { |
446 | delete data; | 573 | delete data; |
447 | data = 0; | 574 | data = 0; |
448 | } | 575 | } |
449 | } | 576 | } |
450 | OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { | 577 | OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { |
451 | if ( *this == ev ) return *this; | 578 | if ( *this == ev ) return *this; |
452 | 579 | ||
453 | ev.data->ref(); | 580 | ev.data->ref(); |
454 | deref(); | 581 | deref(); |
455 | data = ev.data; | 582 | data = ev.data; |
456 | 583 | ||
457 | return *this; | 584 | return *this; |
458 | } | 585 | } |
459 | 586 | ||
460 | void OEffectiveEvent::setStartTime( const QTime& ti) { | 587 | void OEffectiveEvent::setStartTime( const QTime& ti) { |
461 | changeOrModify(); | 588 | changeOrModify(); |
462 | data->start = ti; | 589 | data->start = ti; |
463 | } | 590 | } |
464 | void OEffectiveEvent::setEndTime( const QTime& en) { | 591 | void OEffectiveEvent::setEndTime( const QTime& en) { |
465 | changeOrModify(); | 592 | changeOrModify(); |
466 | data->end = en; | 593 | data->end = en; |
467 | } | 594 | } |
468 | void OEffectiveEvent::setEvent( const OEvent& ev) { | 595 | void OEffectiveEvent::setEvent( const OEvent& ev) { |
469 | changeOrModify(); | 596 | changeOrModify(); |
470 | data->event = ev; | 597 | data->event = ev; |
471 | } | 598 | } |
472 | void OEffectiveEvent::setDate( const QDate& da) { | 599 | void OEffectiveEvent::setDate( const QDate& da) { |
473 | changeOrModify(); | 600 | changeOrModify(); |
474 | data->date = da; | 601 | data->date = da; |
475 | } | 602 | } |
476 | void OEffectiveEvent::setEffectiveDates( const QDate& from, | 603 | void OEffectiveEvent::setEffectiveDates( const QDate& from, |
477 | const QDate& to ) { | 604 | const QDate& to ) { |
478 | if (!from.isValid() ) { | 605 | if (!from.isValid() ) { |
479 | data->dates = false; | 606 | data->dates = false; |
480 | return; | 607 | return; |
481 | } | 608 | } |
482 | 609 | ||
483 | data->startDate = from; | 610 | data->startDate = from; |
484 | data->endDate = to; | 611 | data->endDate = to; |
485 | } | 612 | } |
486 | QString OEffectiveEvent::description()const { | 613 | QString OEffectiveEvent::description()const { |
487 | return data->event.description(); | 614 | return data->event.description(); |
488 | } | 615 | } |
489 | QString OEffectiveEvent::location()const { | 616 | QString OEffectiveEvent::location()const { |
490 | return data->event.location(); | 617 | return data->event.location(); |
491 | } | 618 | } |
492 | QString OEffectiveEvent::note()const { | 619 | QString OEffectiveEvent::note()const { |
493 | return data->event.note(); | 620 | return data->event.note(); |
494 | } | 621 | } |
495 | OEvent OEffectiveEvent::event()const { | 622 | OEvent OEffectiveEvent::event()const { |
496 | return data->event; | 623 | return data->event; |
497 | } | 624 | } |
498 | QTime OEffectiveEvent::startTime()const { | 625 | QTime OEffectiveEvent::startTime()const { |
499 | return data->start; | 626 | return data->start; |
500 | } | 627 | } |
501 | QTime OEffectiveEvent::endTime()const { | 628 | QTime OEffectiveEvent::endTime()const { |
502 | return data->end; | 629 | return data->end; |
503 | } | 630 | } |
504 | QDate OEffectiveEvent::date()const { | 631 | QDate OEffectiveEvent::date()const { |
505 | return data->date; | 632 | return data->date; |
506 | } | 633 | } |
507 | int OEffectiveEvent::length()const { | 634 | int OEffectiveEvent::length()const { |
508 | return (data->end.hour() * 60 - data->start.hour() * 60) | 635 | return (data->end.hour() * 60 - data->start.hour() * 60) |
509 | + QABS(data->start.minute() - data->end.minute() ); | 636 | + QABS(data->start.minute() - data->end.minute() ); |
510 | } | 637 | } |
511 | int OEffectiveEvent::size()const { | 638 | int OEffectiveEvent::size()const { |
512 | return ( data->end.hour() - data->start.hour() ) * 3600 | 639 | return ( data->end.hour() - data->start.hour() ) * 3600 |
513 | + (data->end.minute() - data->start.minute() * 60 | 640 | + (data->end.minute() - data->start.minute() * 60 |
514 | + data->end.second() - data->start.second() ); | 641 | + data->end.second() - data->start.second() ); |
515 | } | 642 | } |
516 | QDate OEffectiveEvent::startDate()const { | 643 | QDate OEffectiveEvent::startDate()const { |
517 | if ( data->dates ) | 644 | if ( data->dates ) |
518 | return data->startDate; | 645 | return data->startDate; |
519 | else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer | 646 | else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer |
520 | return data->date; | 647 | return data->date; |
521 | else | 648 | else |
522 | return data->event.startDateTime().date(); | 649 | return data->event.startDateTime().date(); |
523 | } | 650 | } |
524 | QDate OEffectiveEvent::endDate()const { | 651 | QDate OEffectiveEvent::endDate()const { |
525 | if ( data->dates ) | 652 | if ( data->dates ) |
526 | return data->endDate; | 653 | return data->endDate; |
527 | else if ( data->event.hasRecurrence() ) | 654 | else if ( data->event.hasRecurrence() ) |
528 | return data->date; | 655 | return data->date; |
529 | else | 656 | else |
530 | return data->event.endDateTime().date(); | 657 | return data->event.endDateTime().date(); |
531 | } | 658 | } |
532 | void OEffectiveEvent::deref() { | 659 | void OEffectiveEvent::deref() { |
533 | if ( data->deref() ) { | 660 | if ( data->deref() ) { |
534 | delete data; | 661 | delete data; |
535 | data = 0; | 662 | data = 0; |
536 | } | 663 | } |
537 | } | 664 | } |
538 | void OEffectiveEvent::changeOrModify() { | 665 | void OEffectiveEvent::changeOrModify() { |
539 | if ( data->count != 1 ) { | 666 | if ( data->count != 1 ) { |
540 | data->deref(); | 667 | data->deref(); |
541 | Data* d2 = new Data; | 668 | Data* d2 = new Data; |
542 | d2->event = data->event; | 669 | d2->event = data->event; |
543 | d2->date = data->date; | 670 | d2->date = data->date; |
544 | d2->start = data->start; | 671 | d2->start = data->start; |
545 | d2->end = data->end; | 672 | d2->end = data->end; |
546 | d2->startDate = data->startDate; | 673 | d2->startDate = data->startDate; |
547 | d2->endDate = data->endDate; | 674 | d2->endDate = data->endDate; |
548 | d2->dates = data->dates; | 675 | d2->dates = data->dates; |
549 | data = d2; | 676 | data = d2; |
550 | } | 677 | } |
551 | } | 678 | } |
552 | bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{ | 679 | bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{ |
553 | if ( data->date < e.date() ) | 680 | if ( data->date < e.date() ) |
554 | return TRUE; | 681 | return TRUE; |
diff --git a/libopie2/opiepim/oevent.h b/libopie2/opiepim/oevent.h index 30f442e..9218c97 100644 --- a/libopie2/opiepim/oevent.h +++ b/libopie2/opiepim/oevent.h | |||
@@ -1,220 +1,230 @@ | |||
1 | // CONTAINS GPLed code of TT | 1 | // CONTAINS GPLed code of TT |
2 | 2 | ||
3 | #ifndef OPIE_PIM_EVENT_H | 3 | #ifndef OPIE_PIM_EVENT_H |
4 | #define OPIE_PIM_EVENT_H | 4 | #define OPIE_PIM_EVENT_H |
5 | 5 | ||
6 | #include <qstring.h> | 6 | #include <qstring.h> |
7 | #include <qdatetime.h> | 7 | #include <qdatetime.h> |
8 | #include <qvaluelist.h> | 8 | #include <qvaluelist.h> |
9 | 9 | ||
10 | #include <qpe/recordfields.h> | 10 | #include <qpe/recordfields.h> |
11 | #include <qpe/palmtopuidgen.h> | 11 | #include <qpe/palmtopuidgen.h> |
12 | 12 | ||
13 | #include "otimezone.h" | 13 | #include "otimezone.h" |
14 | #include "opimrecord.h" | 14 | #include "opimrecord.h" |
15 | 15 | ||
16 | struct OCalendarHelper { | 16 | struct OCalendarHelper { |
17 | /** calculate the week number of the date */ | 17 | /** calculate the week number of the date */ |
18 | static int week( const QDate& ); | 18 | static int week( const QDate& ); |
19 | /** calculate the occurence of week days since the start of the month */ | 19 | /** calculate the occurence of week days since the start of the month */ |
20 | static int ocurrence( const QDate& ); | 20 | static int ocurrence( const QDate& ); |
21 | 21 | ||
22 | // returns the dayOfWeek for the *first* day it finds (ignores | 22 | // returns the dayOfWeek for the *first* day it finds (ignores |
23 | // any further days!). Returns 1 (Monday) if there isn't any day found | 23 | // any further days!). Returns 1 (Monday) if there isn't any day found |
24 | static int dayOfWeek( char day ); | 24 | static int dayOfWeek( char day ); |
25 | 25 | ||
26 | /** returns the diff of month */ | 26 | /** returns the diff of month */ |
27 | static int monthDiff( const QDate& first, const QDate& second ); | 27 | static int monthDiff( const QDate& first, const QDate& second ); |
28 | 28 | ||
29 | }; | 29 | }; |
30 | 30 | ||
31 | class OPimNotifyManager; | 31 | class OPimNotifyManager; |
32 | class ORecur; | 32 | class ORecur; |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * This is the container for all Events. It encapsules all | 35 | * This is the container for all Events. It encapsules all |
36 | * available information for a single Event | 36 | * available information for a single Event |
37 | * @short container for events. | 37 | * @short container for events. |
38 | */ | 38 | */ |
39 | class OEvent : public OPimRecord { | 39 | class OEvent : public OPimRecord { |
40 | public: | 40 | public: |
41 | typedef QValueList<OEvent> ValueList; | 41 | typedef QValueList<OEvent> ValueList; |
42 | /** | 42 | /** |
43 | * RecordFields contain possible attributes | 43 | * RecordFields contain possible attributes |
44 | * used in the Results of toMap().. | ||
44 | */ | 45 | */ |
45 | enum RecordFields { | 46 | enum RecordFields { |
46 | Uid = Qtopia::UID_ID, | 47 | FUid = Qtopia::UID_ID, |
47 | Category = Qtopia::CATEGORY_ID, | 48 | FCategories = Qtopia::CATEGORY_ID, |
48 | Description, | 49 | FDescription = 0, |
49 | Location, | 50 | FLocation, |
50 | Alarm, | 51 | FType, |
51 | Reminder, | 52 | FAlarm, |
52 | Recurrence, | 53 | FSound, |
53 | Note, | 54 | FRType, |
54 | Created, | 55 | FRWeekdays, |
55 | StartDate, | 56 | FRPosition, |
56 | EndDate, | 57 | FRFreq, |
57 | AllDay, | 58 | FRHasEndDate, |
58 | TimeZone | 59 | FREndDate, |
60 | FRCreated, | ||
61 | FRExceptions, | ||
62 | FStart, | ||
63 | FEnd, | ||
64 | FNote, | ||
65 | FTimeZone, | ||
66 | FRecParent, | ||
67 | FRecChildren, | ||
59 | }; | 68 | }; |
60 | 69 | ||
61 | /** | 70 | /** |
62 | * Start with an Empty OEvent. UID == 0 means that it is empty | 71 | * Start with an Empty OEvent. UID == 0 means that it is empty |
63 | */ | 72 | */ |
64 | OEvent(int uid = 0); | 73 | OEvent(int uid = 0); |
65 | 74 | ||
66 | /** | 75 | /** |
67 | * copy c'tor | 76 | * copy c'tor |
68 | */ | 77 | */ |
69 | OEvent( const OEvent& ); | 78 | OEvent( const OEvent& ); |
70 | ~OEvent(); | 79 | ~OEvent(); |
71 | OEvent &operator=( const OEvent& ); | 80 | OEvent &operator=( const OEvent& ); |
72 | 81 | ||
73 | QString description()const; | 82 | QString description()const; |
74 | void setDescription( const QString& description ); | 83 | void setDescription( const QString& description ); |
75 | 84 | ||
76 | QString location()const; | 85 | QString location()const; |
77 | void setLocation( const QString& loc ); | 86 | void setLocation( const QString& loc ); |
78 | 87 | ||
79 | bool hasNotifiers()const; | 88 | bool hasNotifiers()const; |
80 | OPimNotifyManager ¬ifiers()const; | 89 | OPimNotifyManager ¬ifiers()const; |
81 | 90 | ||
82 | ORecur recurrence()const; | 91 | ORecur recurrence()const; |
83 | void setRecurrence( const ORecur& ); | 92 | void setRecurrence( const ORecur& ); |
84 | bool hasRecurrence()const; | 93 | bool hasRecurrence()const; |
85 | 94 | ||
86 | QString note()const; | 95 | QString note()const; |
87 | void setNote( const QString& note ); | 96 | void setNote( const QString& note ); |
88 | 97 | ||
89 | 98 | ||
90 | QDateTime createdDateTime()const; | 99 | QDateTime createdDateTime()const; |
91 | void setCreatedDateTime( const QDateTime& dt); | 100 | void setCreatedDateTime( const QDateTime& dt); |
92 | 101 | ||
93 | /** set the date to dt. dt is the QDateTime in localtime */ | 102 | /** set the date to dt. dt is the QDateTime in localtime */ |
94 | void setStartDateTime( const QDateTime& ); | 103 | void setStartDateTime( const QDateTime& ); |
95 | /** returns the datetime in the local timeZone */ | 104 | /** returns the datetime in the local timeZone */ |
96 | QDateTime startDateTime()const; | 105 | QDateTime startDateTime()const; |
97 | 106 | ||
98 | /** returns the start datetime in the current zone */ | 107 | /** returns the start datetime in the current zone */ |
99 | QDateTime startDateTimeInZone()const; | 108 | QDateTime startDateTimeInZone()const; |
100 | 109 | ||
101 | /** in current timezone */ | 110 | /** in current timezone */ |
102 | void setEndDateTime( const QDateTime& ); | 111 | void setEndDateTime( const QDateTime& ); |
103 | /** in current timezone */ | 112 | /** in current timezone */ |
104 | QDateTime endDateTime()const; | 113 | QDateTime endDateTime()const; |
105 | QDateTime endDateTimeInZone()const; | 114 | QDateTime endDateTimeInZone()const; |
106 | 115 | ||
107 | bool isMultipleDay()const; | 116 | bool isMultipleDay()const; |
108 | bool isAllDay()const; | 117 | bool isAllDay()const; |
109 | void setAllDay( bool isAllDay ); | 118 | void setAllDay( bool isAllDay ); |
110 | 119 | ||
111 | /* pin this event to a timezone! FIXME */ | 120 | /* pin this event to a timezone! FIXME */ |
112 | void setTimeZone( const QString& timeZone ); | 121 | void setTimeZone( const QString& timeZone ); |
113 | QString timeZone()const; | 122 | QString timeZone()const; |
114 | 123 | ||
115 | 124 | ||
116 | virtual bool match( const QRegExp& )const; | 125 | virtual bool match( const QRegExp& )const; |
117 | 126 | ||
118 | /** For exception to recurrence here is a list of children... */ | 127 | /** For exception to recurrence here is a list of children... */ |
119 | QArray<int> children()const; | 128 | QArray<int> children()const; |
120 | void setChildren( const QArray<int>& ); | 129 | void setChildren( const QArray<int>& ); |
121 | void addChild( int uid ); | 130 | void addChild( int uid ); |
122 | void removeChild( int uid ); | 131 | void removeChild( int uid ); |
123 | 132 | ||
124 | /** return the parent OEvent */ | 133 | /** return the parent OEvent */ |
125 | int parent()const; | 134 | int parent()const; |
126 | void setParent( int uid ); | 135 | void setParent( int uid ); |
127 | 136 | ||
128 | 137 | ||
129 | /* needed reimp */ | 138 | /* needed reimp */ |
130 | QString toRichText()const; | 139 | QString toRichText()const; |
131 | QString toShortText()const; | 140 | QString toShortText()const; |
132 | QString type()const; | 141 | QString type()const; |
133 | 142 | ||
134 | QMap<int, QString> toMap()const; | 143 | QMap<int, QString> toMap()const; |
144 | void fromMap( const QMap<int, QString>& map ); | ||
135 | QString recordField(int )const; | 145 | QString recordField(int )const; |
136 | 146 | ||
137 | static int rtti(); | 147 | static int rtti(); |
138 | 148 | ||
139 | bool loadFromStream( QDataStream& ); | 149 | bool loadFromStream( QDataStream& ); |
140 | bool saveToStream( QDataStream& )const; | 150 | bool saveToStream( QDataStream& )const; |
141 | 151 | ||
142 | /* bool operator==( const OEvent& ); | 152 | /* bool operator==( const OEvent& ); |
143 | bool operator!=( const OEvent& ); | 153 | bool operator!=( const OEvent& ); |
144 | bool operator<( const OEvent& ); | 154 | bool operator<( const OEvent& ); |
145 | bool operator<=( const OEvent& ); | 155 | bool operator<=( const OEvent& ); |
146 | bool operator>( const OEvent& ); | 156 | bool operator>( const OEvent& ); |
147 | bool operator>=(const OEvent& ); | 157 | bool operator>=(const OEvent& ); |
148 | */ | 158 | */ |
149 | private: | 159 | private: |
150 | inline void changeOrModify(); | 160 | inline void changeOrModify(); |
151 | void deref(); | 161 | void deref(); |
152 | struct Data; | 162 | struct Data; |
153 | Data* data; | 163 | Data* data; |
154 | class Private; | 164 | class Private; |
155 | Private* priv; | 165 | Private* priv; |
156 | 166 | ||
157 | }; | 167 | }; |
158 | 168 | ||
159 | /** | 169 | /** |
160 | * AN Event can span through multiple days. We split up a multiday eve | 170 | * AN Event can span through multiple days. We split up a multiday eve |
161 | */ | 171 | */ |
162 | class OEffectiveEvent { | 172 | class OEffectiveEvent { |
163 | public: | 173 | public: |
164 | typedef QValueList<OEffectiveEvent> ValueList; | 174 | typedef QValueList<OEffectiveEvent> ValueList; |
165 | enum Position { MidWay, Start, End, StartEnd }; | 175 | enum Position { MidWay, Start, End, StartEnd }; |
166 | // If we calculate the effective event of a multi-day event | 176 | // If we calculate the effective event of a multi-day event |
167 | // we have to figure out whether we are at the first day, | 177 | // we have to figure out whether we are at the first day, |
168 | // at the end, or anywhere else ("middle"). This is important | 178 | // at the end, or anywhere else ("middle"). This is important |
169 | // for the start/end times (00:00/23:59) | 179 | // for the start/end times (00:00/23:59) |
170 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- | 180 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- |
171 | // day event | 181 | // day event |
172 | // Start: start time -> 23:59 | 182 | // Start: start time -> 23:59 |
173 | // End: 00:00 -> end time | 183 | // End: 00:00 -> end time |
174 | // Start | End == StartEnd: for single-day events (default) | 184 | // Start | End == StartEnd: for single-day events (default) |
175 | // here we draw start time -> end time | 185 | // here we draw start time -> end time |
176 | OEffectiveEvent(); | 186 | OEffectiveEvent(); |
177 | OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); | 187 | OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); |
178 | OEffectiveEvent( const OEffectiveEvent& ); | 188 | OEffectiveEvent( const OEffectiveEvent& ); |
179 | OEffectiveEvent &operator=(const OEffectiveEvent& ); | 189 | OEffectiveEvent &operator=(const OEffectiveEvent& ); |
180 | ~OEffectiveEvent(); | 190 | ~OEffectiveEvent(); |
181 | 191 | ||
182 | void setStartTime( const QTime& ); | 192 | void setStartTime( const QTime& ); |
183 | void setEndTime( const QTime& ); | 193 | void setEndTime( const QTime& ); |
184 | void setEvent( const OEvent& ); | 194 | void setEvent( const OEvent& ); |
185 | void setDate( const QDate& ); | 195 | void setDate( const QDate& ); |
186 | 196 | ||
187 | void setEffectiveDates( const QDate& from, const QDate& to ); | 197 | void setEffectiveDates( const QDate& from, const QDate& to ); |
188 | 198 | ||
189 | QString description()const; | 199 | QString description()const; |
190 | QString location()const; | 200 | QString location()const; |
191 | QString note()const; | 201 | QString note()const; |
192 | OEvent event()const; | 202 | OEvent event()const; |
193 | QTime startTime()const; | 203 | QTime startTime()const; |
194 | QTime endTime()const; | 204 | QTime endTime()const; |
195 | QDate date()const; | 205 | QDate date()const; |
196 | 206 | ||
197 | /* return the length in hours */ | 207 | /* return the length in hours */ |
198 | int length()const; | 208 | int length()const; |
199 | int size()const; | 209 | int size()const; |
200 | 210 | ||
201 | QDate startDate()const; | 211 | QDate startDate()const; |
202 | QDate endDate()const; | 212 | QDate endDate()const; |
203 | 213 | ||
204 | bool operator<( const OEffectiveEvent &e ) const; | 214 | bool operator<( const OEffectiveEvent &e ) const; |
205 | bool operator<=( const OEffectiveEvent &e ) const; | 215 | bool operator<=( const OEffectiveEvent &e ) const; |
206 | bool operator==( const OEffectiveEvent &e ) const; | 216 | bool operator==( const OEffectiveEvent &e ) const; |
207 | bool operator!=( const OEffectiveEvent &e ) const; | 217 | bool operator!=( const OEffectiveEvent &e ) const; |
208 | bool operator>( const OEffectiveEvent &e ) const; | 218 | bool operator>( const OEffectiveEvent &e ) const; |
209 | bool operator>= ( const OEffectiveEvent &e ) const; | 219 | bool operator>= ( const OEffectiveEvent &e ) const; |
210 | 220 | ||
211 | private: | 221 | private: |
212 | void deref(); | 222 | void deref(); |
213 | inline void changeOrModify(); | 223 | inline void changeOrModify(); |
214 | class Private; | 224 | class Private; |
215 | Private* priv; | 225 | Private* priv; |
216 | struct Data; | 226 | struct Data; |
217 | Data* data; | 227 | Data* data; |
218 | 228 | ||
219 | }; | 229 | }; |
220 | #endif | 230 | #endif |