author | eilers <eilers> | 2003-12-22 10:19:25 (UTC) |
---|---|---|
committer | eilers <eilers> | 2003-12-22 10:19:25 (UTC) |
commit | ae70312b1613e26b4ef89a2c9821d9531b82e987 (patch) (unidiff) | |
tree | 7eb70bc45ee29e94da27a18b0136eb4a14e59fa6 /libopie/pim | |
parent | 9e7aafdb7c76d29fee742d53131a73dd60aded2b (diff) | |
download | opie-ae70312b1613e26b4ef89a2c9821d9531b82e987.zip opie-ae70312b1613e26b4ef89a2c9821d9531b82e987.tar.gz opie-ae70312b1613e26b4ef89a2c9821d9531b82e987.tar.bz2 |
Finishing implementation of sql-backend for datebook. But I have to
port the PIM datebook application to use it, before I could debug the
whole stuff.
Thus, PIM-Database backend is finished, but highly experimental. And some
parts are still generic. For instance, the "queryByExample()" methods are
not (or not fully) implemented. Todo: custom-entries not stored.
The big show stopper: matchRegExp() (needed by OpieSearch) needs regular
expression search in the database, which is not supported by sqlite !
Therefore we need either an extended sqlite or a workaround which would
be very slow and memory consuming..
-rw-r--r-- | libopie/pim/obackendfactory.h | 24 | ||||
-rw-r--r-- | libopie/pim/ocontactaccess.h | 14 | ||||
-rw-r--r-- | libopie/pim/ocontactaccessbackend_sql.cpp | 18 | ||||
-rw-r--r-- | libopie/pim/odatebookaccess.cpp | 19 | ||||
-rw-r--r-- | libopie/pim/odatebookaccess.h | 9 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend.cpp | 34 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend.h | 19 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend_sql.cpp | 231 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend_sql.h | 2 | ||||
-rw-r--r-- | libopie/pim/oevent.cpp | 13 | ||||
-rw-r--r-- | libopie/pim/oevent.h | 6 | ||||
-rw-r--r-- | libopie/pim/otimezone.cpp | 11 | ||||
-rw-r--r-- | libopie/pim/otodoaccesssql.cpp | 2 | ||||
-rw-r--r-- | libopie/pim/test/converter.cpp | 45 | ||||
-rwxr-xr-x | libopie/pim/test/converter.h | 18 | ||||
-rw-r--r-- | libopie/pim/test/converter.pro | 2 |
16 files changed, 394 insertions, 73 deletions
diff --git a/libopie/pim/obackendfactory.h b/libopie/pim/obackendfactory.h index 3567687..761ab9a 100644 --- a/libopie/pim/obackendfactory.h +++ b/libopie/pim/obackendfactory.h | |||
@@ -1,176 +1,194 @@ | |||
1 | /* | 1 | /* |
2 | * Class to manage Backends. | 2 | * Class to manage Backends. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | 4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) |
5 | * | 5 | * |
6 | * ===================================================================== | 6 | * ===================================================================== |
7 | *This program is free software; you can redistribute it and/or | 7 | *This program is free software; you can redistribute it and/or |
8 | *modify it under the terms of the GNU Library General Public | 8 | *modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; | 9 | * License as published by the Free Software Foundation; |
10 | * either version 2 of the License, or (at your option) any later | 10 | * either version 2 of the License, or (at your option) any later |
11 | * version. | 11 | * version. |
12 | * ===================================================================== | 12 | * ===================================================================== |
13 | * ToDo: Use plugins | 13 | * ToDo: Use plugins |
14 | * ===================================================================== | 14 | * ===================================================================== |
15 | * Version: $Id$ | 15 | * Version: $Id$ |
16 | * ===================================================================== | 16 | * ===================================================================== |
17 | * History: | 17 | * History: |
18 | * $Log$ | 18 | * $Log$ |
19 | * Revision 1.9 2003/12/22 10:19:26 eilers | ||
20 | * Finishing implementation of sql-backend for datebook. But I have to | ||
21 | * port the PIM datebook application to use it, before I could debug the | ||
22 | * whole stuff. | ||
23 | * Thus, PIM-Database backend is finished, but highly experimental. And some | ||
24 | * parts are still generic. For instance, the "queryByExample()" methods are | ||
25 | * not (or not fully) implemented. Todo: custom-entries not stored. | ||
26 | * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular | ||
27 | * expression search in the database, which is not supported by sqlite ! | ||
28 | * Therefore we need either an extended sqlite or a workaround which would | ||
29 | * be very slow and memory consuming.. | ||
30 | * | ||
19 | * Revision 1.8 2003/09/22 14:31:16 eilers | 31 | * Revision 1.8 2003/09/22 14:31:16 eilers |
20 | * Added first experimental incarnation of sql-backend for addressbook. | 32 | * Added first experimental incarnation of sql-backend for addressbook. |
21 | * Some modifications to be able to compile the todo sql-backend. | 33 | * Some modifications to be able to compile the todo sql-backend. |
22 | * A lot of changes fill follow... | 34 | * A lot of changes fill follow... |
23 | * | 35 | * |
24 | * Revision 1.7 2003/08/01 12:30:16 eilers | 36 | * Revision 1.7 2003/08/01 12:30:16 eilers |
25 | * Merging changes from BRANCH_1_0 to HEAD | 37 | * Merging changes from BRANCH_1_0 to HEAD |
26 | * | 38 | * |
27 | * Revision 1.6.4.1 2003/06/30 14:34:19 eilers | 39 | * Revision 1.6.4.1 2003/06/30 14:34:19 eilers |
28 | * Patches from Zecke: | 40 | * Patches from Zecke: |
29 | * Fixing and cleaning up extraMap handling | 41 | * Fixing and cleaning up extraMap handling |
30 | * Adding d_ptr for binary compatibility in the future | 42 | * Adding d_ptr for binary compatibility in the future |
31 | * | 43 | * |
32 | * Revision 1.6 2003/04/13 18:07:10 zecke | 44 | * Revision 1.6 2003/04/13 18:07:10 zecke |
33 | * More API doc | 45 | * More API doc |
34 | * QString -> const QString& | 46 | * QString -> const QString& |
35 | * QString = 0l -> QString::null | 47 | * QString = 0l -> QString::null |
36 | * | 48 | * |
37 | * Revision 1.5 2003/02/21 23:31:52 zecke | 49 | * Revision 1.5 2003/02/21 23:31:52 zecke |
38 | * Add XML datebookresource | 50 | * Add XML datebookresource |
39 | * -clean up todoaccessxml header | 51 | * -clean up todoaccessxml header |
40 | * -implement some more stuff in the oeven tester | 52 | * -implement some more stuff in the oeven tester |
41 | * -extend DefaultFactory to not crash and to use datebook | 53 | * -extend DefaultFactory to not crash and to use datebook |
42 | * | 54 | * |
43 | * -reading of OEvents is working nicely.. saving will be added | 55 | * -reading of OEvents is working nicely.. saving will be added |
44 | * tomorrow | 56 | * tomorrow |
45 | * -fix spelling in ODateBookAcces | 57 | * -fix spelling in ODateBookAcces |
46 | * | 58 | * |
47 | * Revision 1.4 2002/10/14 15:55:18 eilers | 59 | * Revision 1.4 2002/10/14 15:55:18 eilers |
48 | * Redeactivate SQL.. ;) | 60 | * Redeactivate SQL.. ;) |
49 | * | 61 | * |
50 | * Revision 1.3 2002/10/10 17:08:58 zecke | 62 | * Revision 1.3 2002/10/10 17:08:58 zecke |
51 | * The Cache is finally in place | 63 | * The Cache is finally in place |
52 | * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;) | 64 | * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;) |
53 | * The read ahead functionality does not make sense for XMLs backends because most of the stuff is already in memory. While using readahead on SQL makes things a lot faster.... | 65 | * The read ahead functionality does not make sense for XMLs backends because most of the stuff is already in memory. While using readahead on SQL makes things a lot faster.... |
54 | * I still have to fully implement read ahead | 66 | * I still have to fully implement read ahead |
55 | * This change is bic but sc | 67 | * This change is bic but sc |
56 | * | 68 | * |
57 | * Revision 1.2 2002/10/08 09:27:36 eilers | 69 | * Revision 1.2 2002/10/08 09:27:36 eilers |
58 | * Fixed libopie.pro to include the new pim-API. | 70 | * Fixed libopie.pro to include the new pim-API. |
59 | * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to | 71 | * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to |
60 | * compile itself would need to install libsqlite, libopiesql... | 72 | * compile itself would need to install libsqlite, libopiesql... |
61 | * Therefore, the backend currently uses XML only.. | 73 | * Therefore, the backend currently uses XML only.. |
62 | * | 74 | * |
63 | * Revision 1.1 2002/10/07 17:35:01 eilers | 75 | * Revision 1.1 2002/10/07 17:35:01 eilers |
64 | * added OBackendFactory for advanced backend access | 76 | * added OBackendFactory for advanced backend access |
65 | * | 77 | * |
66 | * | 78 | * |
67 | * ===================================================================== | 79 | * ===================================================================== |
68 | */ | 80 | */ |
69 | #ifndef OPIE_BACKENDFACTORY_H_ | 81 | #ifndef OPIE_BACKENDFACTORY_H_ |
70 | #define OPIE_BACKENDFACTORY_H_ | 82 | #define OPIE_BACKENDFACTORY_H_ |
71 | 83 | ||
72 | #include <qstring.h> | 84 | #include <qstring.h> |
73 | #include <qasciidict.h> | 85 | #include <qasciidict.h> |
74 | #include <qpe/config.h> | 86 | #include <qpe/config.h> |
75 | 87 | ||
76 | #include "otodoaccessxml.h" | 88 | #include "otodoaccessxml.h" |
77 | #include "ocontactaccessbackend_xml.h" | 89 | #include "ocontactaccessbackend_xml.h" |
78 | #include "odatebookaccessbackend_xml.h" | 90 | #include "odatebookaccessbackend_xml.h" |
79 | 91 | ||
80 | #ifdef __USE_SQL | 92 | #ifdef __USE_SQL |
81 | #include "otodoaccesssql.h" | 93 | #include "otodoaccesssql.h" |
82 | #include "ocontactaccessbackend_sql.h" | 94 | #include "ocontactaccessbackend_sql.h" |
95 | #include "odatebookaccessbackend_sql.h" | ||
83 | #endif | 96 | #endif |
84 | 97 | ||
85 | class OBackendPrivate; | 98 | class OBackendPrivate; |
86 | 99 | ||
87 | /** | 100 | /** |
88 | * This class is our factory. It will give us the default implementations | 101 | * This class is our factory. It will give us the default implementations |
89 | * of at least Todolist, Contacts and Datebook. In the future this class will | 102 | * of at least Todolist, Contacts and Datebook. In the future this class will |
90 | * allow users to switch the backend with ( XML->SQLite ) without the need | 103 | * allow users to switch the backend with ( XML->SQLite ) without the need |
91 | * to recompile.# | 104 | * to recompile.# |
92 | * This class as the whole PIM Api is making use of templates | 105 | * This class as the whole PIM Api is making use of templates |
93 | * | 106 | * |
94 | * <pre> | 107 | * <pre> |
95 | * OTodoAccessBackend* backend = OBackEndFactory<OTodoAccessBackend>::Default("todo", QString::null ); | 108 | * OTodoAccessBackend* backend = OBackEndFactory<OTodoAccessBackend>::Default("todo", QString::null ); |
96 | * backend->load(); | 109 | * backend->load(); |
97 | * </pre> | 110 | * </pre> |
98 | * | 111 | * |
99 | * @author Stefan Eilers | 112 | * @author Stefan Eilers |
100 | * @version 0.1 | 113 | * @version 0.1 |
101 | */ | 114 | */ |
102 | template<class T> | 115 | template<class T> |
103 | class OBackendFactory | 116 | class OBackendFactory |
104 | { | 117 | { |
105 | public: | 118 | public: |
106 | OBackendFactory() {}; | 119 | OBackendFactory() {}; |
107 | 120 | ||
108 | enum BACKENDS { | 121 | enum BACKENDS { |
109 | TODO, | 122 | TODO, |
110 | CONTACT, | 123 | CONTACT, |
111 | DATE | 124 | DATE |
112 | }; | 125 | }; |
113 | 126 | ||
114 | /** | 127 | /** |
115 | * Returns a backend implementation for backendName | 128 | * Returns a backend implementation for backendName |
116 | * @param backendName the type of the backend | 129 | * @param backendName the type of the backend |
117 | * @param appName will be passed on to the backend | 130 | * @param appName will be passed on to the backend |
118 | */ | 131 | */ |
119 | static T* Default( const QString backendName, const QString& appName ){ | 132 | static T* Default( const QString backendName, const QString& appName ){ |
120 | 133 | ||
121 | // __asm__("int3"); | 134 | // __asm__("int3"); |
122 | 135 | ||
123 | Config config( "pimaccess" ); | 136 | Config config( "pimaccess" ); |
124 | config.setGroup ( backendName ); | 137 | config.setGroup ( backendName ); |
125 | QString backend = config.readEntry( "usebackend" ); | 138 | QString backend = config.readEntry( "usebackend" ); |
126 | 139 | ||
127 | qWarning("Selected backend for %s is: %s", backendName.latin1(), backend.latin1() ); | 140 | qWarning("Selected backend for %s is: %s", backendName.latin1(), backend.latin1() ); |
128 | 141 | ||
129 | QAsciiDict<int> dict ( 3 ); | 142 | QAsciiDict<int> dict ( 3 ); |
130 | dict.setAutoDelete ( TRUE ); | 143 | dict.setAutoDelete ( TRUE ); |
131 | 144 | ||
132 | dict.insert( "todo", new int (TODO) ); | 145 | dict.insert( "todo", new int (TODO) ); |
133 | dict.insert( "contact", new int (CONTACT) ); | 146 | dict.insert( "contact", new int (CONTACT) ); |
134 | dict.insert( "datebook", new int(DATE) ); | 147 | dict.insert( "datebook", new int(DATE) ); |
135 | 148 | ||
136 | int *find = dict[ backendName ]; | 149 | int *find = dict[ backendName ]; |
137 | if (!find ) return 0; | 150 | if (!find ) return 0; |
138 | 151 | ||
139 | switch ( *find ){ | 152 | switch ( *find ){ |
140 | case TODO: | 153 | case TODO: |
141 | #ifdef __USE_SQL | 154 | #ifdef __USE_SQL |
142 | if ( backend == "sql" ) | 155 | if ( backend == "sql" ) |
143 | return (T*) new OTodoAccessBackendSQL(""); | 156 | return (T*) new OTodoAccessBackendSQL(""); |
144 | #else | 157 | #else |
145 | if ( backend == "sql" ) | 158 | if ( backend == "sql" ) |
146 | qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); | 159 | qWarning ("OBackendFactory:: sql Backend for TODO not implemented! Using XML instead!"); |
147 | #endif | 160 | #endif |
148 | 161 | ||
149 | return (T*) new OTodoAccessXML( appName ); | 162 | return (T*) new OTodoAccessXML( appName ); |
150 | case CONTACT: | 163 | case CONTACT: |
151 | #ifdef __USE_SQL | 164 | #ifdef __USE_SQL |
152 | if ( backend == "sql" ) | 165 | if ( backend == "sql" ) |
153 | return (T*) new OContactAccessBackend_SQL(""); | 166 | return (T*) new OContactAccessBackend_SQL(""); |
154 | #else | 167 | #else |
155 | if ( backend == "sql" ) | 168 | if ( backend == "sql" ) |
156 | qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); | 169 | qWarning ("OBackendFactory:: sql Backend for CONTACT not implemented! Using XML instead!"); |
157 | #endif | 170 | #endif |
158 | 171 | ||
159 | return (T*) new OContactAccessBackend_XML( appName ); | 172 | return (T*) new OContactAccessBackend_XML( appName ); |
160 | case DATE: | 173 | case DATE: |
174 | #ifdef __USE_SQL | ||
161 | if ( backend == "sql" ) | 175 | if ( backend == "sql" ) |
162 | qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!"); | 176 | return (T*) new ODateBookAccessBackend_SQL(""); |
177 | #else | ||
178 | if ( backend == "sql" ) | ||
179 | qWarning("OBackendFactory:: sql Backend for DATEBOOK not implemented! Using XML instead!"); | ||
180 | #endif | ||
163 | 181 | ||
164 | return (T*) new ODateBookAccessBackend_XML( appName ); | 182 | return (T*) new ODateBookAccessBackend_XML( appName ); |
165 | default: | 183 | default: |
166 | return NULL; | 184 | return NULL; |
167 | } | 185 | } |
168 | 186 | ||
169 | 187 | ||
170 | } | 188 | } |
171 | private: | 189 | private: |
172 | OBackendPrivate* d; | 190 | OBackendPrivate* d; |
173 | }; | 191 | }; |
174 | 192 | ||
175 | 193 | ||
176 | #endif | 194 | #endif |
diff --git a/libopie/pim/ocontactaccess.h b/libopie/pim/ocontactaccess.h index 9b0a719..bd6da40 100644 --- a/libopie/pim/ocontactaccess.h +++ b/libopie/pim/ocontactaccess.h | |||
@@ -1,177 +1,189 @@ | |||
1 | /* | 1 | /* |
2 | * Class to manage the Contacts. | 2 | * Class to manage the Contacts. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | 4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) |
5 | * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) | 5 | * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) |
6 | * | 6 | * |
7 | * ===================================================================== | 7 | * ===================================================================== |
8 | *This program is free software; you can redistribute it and/or | 8 | *This program is free software; you can redistribute it and/or |
9 | *modify it under the terms of the GNU Library General Public | 9 | *modify it under the terms of the GNU Library General Public |
10 | * License as published by the Free Software Foundation; | 10 | * License as published by the Free Software Foundation; |
11 | * either version 2 of the License, or (at your option) any later | 11 | * either version 2 of the License, or (at your option) any later |
12 | * version. | 12 | * version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: Define enum for query settings | 14 | * ToDo: Define enum for query settings |
15 | * ===================================================================== | 15 | * ===================================================================== |
16 | * Version: $Id$ | 16 | * Version: $Id$ |
17 | * ===================================================================== | 17 | * ===================================================================== |
18 | * History: | 18 | * History: |
19 | * $Log$ | 19 | * $Log$ |
20 | * Revision 1.10 2003/12/22 10:19:26 eilers | ||
21 | * Finishing implementation of sql-backend for datebook. But I have to | ||
22 | * port the PIM datebook application to use it, before I could debug the | ||
23 | * whole stuff. | ||
24 | * Thus, PIM-Database backend is finished, but highly experimental. And some | ||
25 | * parts are still generic. For instance, the "queryByExample()" methods are | ||
26 | * not (or not fully) implemented. Todo: custom-entries not stored. | ||
27 | * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular | ||
28 | * expression search in the database, which is not supported by sqlite ! | ||
29 | * Therefore we need either an extended sqlite or a workaround which would | ||
30 | * be very slow and memory consuming.. | ||
31 | * | ||
20 | * Revision 1.9 2003/08/01 12:30:16 eilers | 32 | * Revision 1.9 2003/08/01 12:30:16 eilers |
21 | * Merging changes from BRANCH_1_0 to HEAD | 33 | * Merging changes from BRANCH_1_0 to HEAD |
22 | * | 34 | * |
23 | * Revision 1.8.2.1 2003/06/30 14:34:19 eilers | 35 | * Revision 1.8.2.1 2003/06/30 14:34:19 eilers |
24 | * Patches from Zecke: | 36 | * Patches from Zecke: |
25 | * Fixing and cleaning up extraMap handling | 37 | * Fixing and cleaning up extraMap handling |
26 | * Adding d_ptr for binary compatibility in the future | 38 | * Adding d_ptr for binary compatibility in the future |
27 | * | 39 | * |
28 | * Revision 1.8 2003/05/08 13:55:09 tille | 40 | * Revision 1.8 2003/05/08 13:55:09 tille |
29 | * search stuff | 41 | * search stuff |
30 | * and match, toRichText & toShortText in oevent | 42 | * and match, toRichText & toShortText in oevent |
31 | * | 43 | * |
32 | * Revision 1.7 2003/04/13 18:07:10 zecke | 44 | * Revision 1.7 2003/04/13 18:07:10 zecke |
33 | * More API doc | 45 | * More API doc |
34 | * QString -> const QString& | 46 | * QString -> const QString& |
35 | * QString = 0l -> QString::null | 47 | * QString = 0l -> QString::null |
36 | * | 48 | * |
37 | * Revision 1.6 2003/01/02 14:27:12 eilers | 49 | * Revision 1.6 2003/01/02 14:27:12 eilers |
38 | * Improved query by example: Search by date is possible.. First step | 50 | * Improved query by example: Search by date is possible.. First step |
39 | * for a today plugin for birthdays.. | 51 | * for a today plugin for birthdays.. |
40 | * | 52 | * |
41 | * Revision 1.5 2002/11/13 14:14:51 eilers | 53 | * Revision 1.5 2002/11/13 14:14:51 eilers |
42 | * Added sorted for Contacts.. | 54 | * Added sorted for Contacts.. |
43 | * | 55 | * |
44 | * Revision 1.4 2002/11/01 15:10:42 eilers | 56 | * Revision 1.4 2002/11/01 15:10:42 eilers |
45 | * Added regExp-search in database for all fields in a contact. | 57 | * Added regExp-search in database for all fields in a contact. |
46 | * | 58 | * |
47 | * Revision 1.3 2002/10/16 10:52:40 eilers | 59 | * Revision 1.3 2002/10/16 10:52:40 eilers |
48 | * Added some docu to the interface and now using the cache infrastucture by zecke.. :) | 60 | * Added some docu to the interface and now using the cache infrastucture by zecke.. :) |
49 | * | 61 | * |
50 | * Revision 1.2 2002/10/14 16:21:54 eilers | 62 | * Revision 1.2 2002/10/14 16:21:54 eilers |
51 | * Some minor interface updates | 63 | * Some minor interface updates |
52 | * | 64 | * |
53 | * Revision 1.1 2002/09/27 17:11:44 eilers | 65 | * Revision 1.1 2002/09/27 17:11:44 eilers |
54 | * Added API for accessing the Contact-Database ! It is compiling, but | 66 | * Added API for accessing the Contact-Database ! It is compiling, but |
55 | * please do not expect that anything is working ! | 67 | * please do not expect that anything is working ! |
56 | * I will debug that stuff in the next time .. | 68 | * I will debug that stuff in the next time .. |
57 | * Please read README_COMPILE for compiling ! | 69 | * Please read README_COMPILE for compiling ! |
58 | * | 70 | * |
59 | * ===================================================================== | 71 | * ===================================================================== |
60 | */ | 72 | */ |
61 | #ifndef _OCONTACTACCESS_H | 73 | #ifndef _OCONTACTACCESS_H |
62 | #define _OCONTACTACCESS_H | 74 | #define _OCONTACTACCESS_H |
63 | 75 | ||
64 | #include <qobject.h> | 76 | #include <qobject.h> |
65 | 77 | ||
66 | #include <qpe/qcopenvelope_qws.h> | 78 | #include <qpe/qcopenvelope_qws.h> |
67 | 79 | ||
68 | #include <qvaluelist.h> | 80 | #include <qvaluelist.h> |
69 | #include <qfileinfo.h> | 81 | #include <qfileinfo.h> |
70 | 82 | ||
71 | #include "ocontact.h" | 83 | #include "ocontact.h" |
72 | #include "ocontactaccessbackend.h" | 84 | #include "ocontactaccessbackend.h" |
73 | #include "opimaccesstemplate.h" | 85 | #include "opimaccesstemplate.h" |
74 | 86 | ||
75 | /** | 87 | /** |
76 | * Class to access the contacts database. | 88 | * Class to access the contacts database. |
77 | * This is just a frontend for the real database handling which is | 89 | * This is just a frontend for the real database handling which is |
78 | * done by the backend. | 90 | * done by the backend. |
79 | * This class is used to access the Contacts on a system. This class as any OPIE PIM | 91 | * This class is used to access the Contacts on a system. This class as any OPIE PIM |
80 | * class is backend independent. | 92 | * class is backend independent. |
81 | 93 | * @author Stefan Eilers, Holger Freyther | |
82 | * @see OPimAccessTemplate | 94 | * @see OPimAccessTemplate |
83 | */ | 95 | */ |
84 | class OContactAccess: public QObject, public OPimAccessTemplate<OContact> | 96 | class OContactAccess: public QObject, public OPimAccessTemplate<OContact> |
85 | { | 97 | { |
86 | Q_OBJECT | 98 | Q_OBJECT |
87 | 99 | ||
88 | public: | 100 | public: |
89 | /** | 101 | /** |
90 | * Create Database with contacts (addressbook). | 102 | * Create Database with contacts (addressbook). |
91 | * @param appname Name of application which wants access to the database | 103 | * @param appname Name of application which wants access to the database |
92 | * (i.e. "todolist") | 104 | * (i.e. "todolist") |
93 | * @param filename The name of the database file. If not set, the default one | 105 | * @param filename The name of the database file. If not set, the default one |
94 | * is used. | 106 | * is used. |
95 | * @param backend Pointer to an alternative Backend. If not set, we will use | 107 | * @param backend Pointer to an alternative Backend. If not set, we will use |
96 | * the default backend. | 108 | * the default backend. |
97 | * @param handlesync If <b>true</b> the database stores the current state | 109 | * @param handlesync If <b>true</b> the database stores the current state |
98 | * automatically if it receives the signals <i>flush()</i> and <i>reload()</i> | 110 | * automatically if it receives the signals <i>flush()</i> and <i>reload()</i> |
99 | * which are used before and after synchronisation. If the application wants | 111 | * which are used before and after synchronisation. If the application wants |
100 | * to react itself, it should be disabled by setting it to <b>false</b> | 112 | * to react itself, it should be disabled by setting it to <b>false</b> |
101 | * @see OContactAccessBackend | 113 | * @see OContactAccessBackend |
102 | */ | 114 | */ |
103 | OContactAccess (const QString appname, const QString filename = 0l, | 115 | OContactAccess (const QString appname, const QString filename = 0l, |
104 | OContactAccessBackend* backend = 0l, bool handlesync = true); | 116 | OContactAccessBackend* backend = 0l, bool handlesync = true); |
105 | ~OContactAccess (); | 117 | ~OContactAccess (); |
106 | 118 | ||
107 | /** Constants for query. | 119 | /** Constants for query. |
108 | * Use this constants to set the query parameters. | 120 | * Use this constants to set the query parameters. |
109 | * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes ! | 121 | * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes ! |
110 | * @see queryByExample() | 122 | * @see queryByExample() |
111 | */ | 123 | */ |
112 | enum QuerySettings { | 124 | enum QuerySettings { |
113 | WildCards = 0x0001, | 125 | WildCards = 0x0001, |
114 | IgnoreCase = 0x0002, | 126 | IgnoreCase = 0x0002, |
115 | RegExp = 0x0004, | 127 | RegExp = 0x0004, |
116 | ExactMatch = 0x0008, | 128 | ExactMatch = 0x0008, |
117 | MatchOne = 0x0010, // Only one Entry must match | 129 | MatchOne = 0x0010, // Only one Entry must match |
118 | DateDiff = 0x0020, // Find all entries from today until given date | 130 | DateDiff = 0x0020, // Find all entries from today until given date |
119 | DateYear = 0x0040, // The year matches | 131 | DateYear = 0x0040, // The year matches |
120 | DateMonth = 0x0080, // The month matches | 132 | DateMonth = 0x0080, // The month matches |
121 | DateDay = 0x0100, // The day matches | 133 | DateDay = 0x0100, // The day matches |
122 | }; | 134 | }; |
123 | 135 | ||
124 | 136 | ||
125 | /** Return all Contacts in a sorted manner. | 137 | /** Return all Contacts in a sorted manner. |
126 | * @param ascending true: Sorted in acending order. | 138 | * @param ascending true: Sorted in acending order. |
127 | * @param sortOrder Currently not implemented. Just defined to stay compatible to otodoaccess | 139 | * @param sortOrder Currently not implemented. Just defined to stay compatible to otodoaccess |
128 | * @param sortFilter Currently not implemented. Just defined to stay compatible to otodoaccess | 140 | * @param sortFilter Currently not implemented. Just defined to stay compatible to otodoaccess |
129 | * @param cat Currently not implemented. Just defined to stay compatible to otodoaccess | 141 | * @param cat Currently not implemented. Just defined to stay compatible to otodoaccess |
130 | */ | 142 | */ |
131 | List sorted( bool ascending, int sortOrder, int sortFilter, int cat ) const; | 143 | List sorted( bool ascending, int sortOrder, int sortFilter, int cat ) const; |
132 | 144 | ||
133 | /** Return all possible settings. | 145 | /** Return all possible settings. |
134 | * @return All settings provided by the current backend | 146 | * @return All settings provided by the current backend |
135 | * (i.e.: query_WildCards & query_IgnoreCase) | 147 | * (i.e.: query_WildCards & query_IgnoreCase) |
136 | */ | 148 | */ |
137 | const uint querySettings(); | 149 | const uint querySettings(); |
138 | 150 | ||
139 | /** Check whether settings are correct. | 151 | /** Check whether settings are correct. |
140 | * @return <i>true</i> if the given settings are correct and possible. | 152 | * @return <i>true</i> if the given settings are correct and possible. |
141 | */ | 153 | */ |
142 | bool hasQuerySettings ( int querySettings ) const; | 154 | bool hasQuerySettings ( int querySettings ) const; |
143 | 155 | ||
144 | /** | 156 | /** |
145 | * if the resource was changed externally. | 157 | * if the resource was changed externally. |
146 | * You should use the signal instead of polling possible changes ! | 158 | * You should use the signal instead of polling possible changes ! |
147 | */ | 159 | */ |
148 | bool wasChangedExternally()const; | 160 | bool wasChangedExternally()const; |
149 | 161 | ||
150 | 162 | ||
151 | /** Save contacts database. | 163 | /** Save contacts database. |
152 | * Save is more a "commit". After calling this function, all changes are public available. | 164 | * Save is more a "commit". After calling this function, all changes are public available. |
153 | * @return true if successful | 165 | * @return true if successful |
154 | */ | 166 | */ |
155 | bool save(); | 167 | bool save(); |
156 | 168 | ||
157 | signals: | 169 | signals: |
158 | /* Signal is emitted if the database was changed. Therefore | 170 | /* Signal is emitted if the database was changed. Therefore |
159 | * we may need to reload to stay consistent. | 171 | * we may need to reload to stay consistent. |
160 | * @param which Pointer to the database who created this event. This pointer | 172 | * @param which Pointer to the database who created this event. This pointer |
161 | * is useful if an application has to handle multiple databases at the same time. | 173 | * is useful if an application has to handle multiple databases at the same time. |
162 | * @see reload() | 174 | * @see reload() |
163 | */ | 175 | */ |
164 | void signalChanged ( const OContactAccess *which ); | 176 | void signalChanged ( const OContactAccess *which ); |
165 | 177 | ||
166 | 178 | ||
167 | private: | 179 | private: |
168 | // class OContactAccessPrivate; | 180 | // class OContactAccessPrivate; |
169 | // OContactAccessPrivate* d; | 181 | // OContactAccessPrivate* d; |
170 | OContactAccessBackend *m_backEnd; | 182 | OContactAccessBackend *m_backEnd; |
171 | bool m_loading:1; | 183 | bool m_loading:1; |
172 | 184 | ||
173 | private slots: | 185 | private slots: |
174 | void copMessage( const QCString &msg, const QByteArray &data ); | 186 | void copMessage( const QCString &msg, const QByteArray &data ); |
175 | 187 | ||
176 | private: | 188 | private: |
177 | class Private; | 189 | class Private; |
diff --git a/libopie/pim/ocontactaccessbackend_sql.cpp b/libopie/pim/ocontactaccessbackend_sql.cpp index dd9dbde..a5be4c8 100644 --- a/libopie/pim/ocontactaccessbackend_sql.cpp +++ b/libopie/pim/ocontactaccessbackend_sql.cpp | |||
@@ -1,112 +1,124 @@ | |||
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.4 2003/12/22 10:19:26 eilers | ||
18 | * Finishing implementation of sql-backend for datebook. But I have to | ||
19 | * port the PIM datebook application to use it, before I could debug the | ||
20 | * whole stuff. | ||
21 | * Thus, PIM-Database backend is finished, but highly experimental. And some | ||
22 | * parts are still generic. For instance, the "queryByExample()" methods are | ||
23 | * not (or not fully) implemented. Todo: custom-entries not stored. | ||
24 | * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular | ||
25 | * expression search in the database, which is not supported by sqlite ! | ||
26 | * Therefore we need either an extended sqlite or a workaround which would | ||
27 | * be very slow and memory consuming.. | ||
28 | * | ||
17 | * Revision 1.3 2003/12/08 15:18:10 eilers | 29 | * Revision 1.3 2003/12/08 15:18:10 eilers |
18 | * Committing unfinished sql implementation before merging to libopie2 starts.. | 30 | * Committing unfinished sql implementation before merging to libopie2 starts.. |
19 | * | 31 | * |
20 | * Revision 1.2 2003/09/29 07:44:26 eilers | 32 | * Revision 1.2 2003/09/29 07:44:26 eilers |
21 | * Improvement of PIM-SQL Databases, but search queries are still limited. | 33 | * Improvement of PIM-SQL Databases, but search queries are still limited. |
22 | * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. | 34 | * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. |
23 | * Todo: Started to add new attributes. Some type conversions missing. | 35 | * Todo: Started to add new attributes. Some type conversions missing. |
24 | * | 36 | * |
25 | * Revision 1.1 2003/09/22 14:31:16 eilers | 37 | * Revision 1.1 2003/09/22 14:31:16 eilers |
26 | * Added first experimental incarnation of sql-backend for addressbook. | 38 | * Added first experimental incarnation of sql-backend for addressbook. |
27 | * Some modifications to be able to compile the todo sql-backend. | 39 | * Some modifications to be able to compile the todo sql-backend. |
28 | * A lot of changes fill follow... | 40 | * A lot of changes fill follow... |
29 | * | 41 | * |
30 | */ | 42 | */ |
31 | 43 | ||
32 | #include "ocontactaccessbackend_sql.h" | 44 | #include "ocontactaccessbackend_sql.h" |
33 | 45 | ||
34 | #include <qarray.h> | 46 | #include <qarray.h> |
35 | #include <qdatetime.h> | 47 | #include <qdatetime.h> |
36 | #include <qstringlist.h> | 48 | #include <qstringlist.h> |
37 | 49 | ||
38 | #include <qpe/global.h> | 50 | #include <qpe/global.h> |
39 | #include <qpe/recordfields.h> | 51 | #include <qpe/recordfields.h> |
40 | 52 | ||
41 | #include <opie/ocontactfields.h> | 53 | #include <opie/ocontactfields.h> |
42 | #include <opie/oconversion.h> | 54 | #include <opie/oconversion.h> |
43 | #include <opie2/osqldriver.h> | 55 | #include <opie2/osqldriver.h> |
44 | #include <opie2/osqlresult.h> | 56 | #include <opie2/osqlresult.h> |
45 | #include <opie2/osqlmanager.h> | 57 | #include <opie2/osqlmanager.h> |
46 | #include <opie2/osqlquery.h> | 58 | #include <opie2/osqlquery.h> |
47 | 59 | ||
48 | 60 | ||
49 | 61 | ||
50 | 62 | ||
51 | // If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead | 63 | // If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead |
52 | // vertical like "uid, type, value". | 64 | // vertical like "uid, type, value". |
53 | // DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! | 65 | // DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! |
54 | #define __STORE_HORIZONTAL_ | 66 | #define __STORE_HORIZONTAL_ |
55 | 67 | ||
56 | // Distinct loading is not very fast. If I expect that every person has just | 68 | // Distinct loading is not very fast. If I expect that every person has just |
57 | // one (and always one) 'Last Name', I can request all uid's for existing lastnames, | 69 | // one (and always one) 'Last Name', I can request all uid's for existing lastnames, |
58 | // which is faster.. | 70 | // which is faster.. |
59 | // But this may not be true for all entries, like company contacts.. | 71 | // But this may not be true for all entries, like company contacts.. |
60 | // The current AddressBook application handles this problem, but other may not.. (eilers) | 72 | // The current AddressBook application handles this problem, but other may not.. (eilers) |
61 | #define __USE_SUPERFAST_LOADQUERY | 73 | #define __USE_SUPERFAST_LOADQUERY |
62 | 74 | ||
63 | 75 | ||
64 | /* | 76 | /* |
65 | * Implementation of used query types | 77 | * Implementation of used query types |
66 | * CREATE query | 78 | * CREATE query |
67 | * LOAD query | 79 | * LOAD query |
68 | * INSERT | 80 | * INSERT |
69 | * REMOVE | 81 | * REMOVE |
70 | * CLEAR | 82 | * CLEAR |
71 | */ | 83 | */ |
72 | namespace { | 84 | namespace { |
73 | /** | 85 | /** |
74 | * CreateQuery for the Todolist Table | 86 | * CreateQuery for the Todolist Table |
75 | */ | 87 | */ |
76 | class CreateQuery : public OSQLQuery { | 88 | class CreateQuery : public OSQLQuery { |
77 | public: | 89 | public: |
78 | CreateQuery(); | 90 | CreateQuery(); |
79 | ~CreateQuery(); | 91 | ~CreateQuery(); |
80 | QString query()const; | 92 | QString query()const; |
81 | }; | 93 | }; |
82 | 94 | ||
83 | /** | 95 | /** |
84 | * Clears (delete) a Table | 96 | * Clears (delete) a Table |
85 | */ | 97 | */ |
86 | class ClearQuery : public OSQLQuery { | 98 | class ClearQuery : public OSQLQuery { |
87 | public: | 99 | public: |
88 | ClearQuery(); | 100 | ClearQuery(); |
89 | ~ClearQuery(); | 101 | ~ClearQuery(); |
90 | QString query()const; | 102 | QString query()const; |
91 | 103 | ||
92 | }; | 104 | }; |
93 | 105 | ||
94 | 106 | ||
95 | /** | 107 | /** |
96 | * LoadQuery | 108 | * LoadQuery |
97 | * this one queries for all uids | 109 | * this one queries for all uids |
98 | */ | 110 | */ |
99 | class LoadQuery : public OSQLQuery { | 111 | class LoadQuery : public OSQLQuery { |
100 | public: | 112 | public: |
101 | LoadQuery(); | 113 | LoadQuery(); |
102 | ~LoadQuery(); | 114 | ~LoadQuery(); |
103 | QString query()const; | 115 | QString query()const; |
104 | }; | 116 | }; |
105 | 117 | ||
106 | /** | 118 | /** |
107 | * inserts/adds a OContact to the table | 119 | * inserts/adds a OContact to the table |
108 | */ | 120 | */ |
109 | class InsertQuery : public OSQLQuery { | 121 | class InsertQuery : public OSQLQuery { |
110 | public: | 122 | public: |
111 | InsertQuery(const OContact& ); | 123 | InsertQuery(const OContact& ); |
112 | ~InsertQuery(); | 124 | ~InsertQuery(); |
@@ -417,202 +429,202 @@ namespace { | |||
417 | } | 429 | } |
418 | */ | 430 | */ |
419 | #ifdef __STORE_HORIZONTAL_ | 431 | #ifdef __STORE_HORIZONTAL_ |
420 | QString FindQuery::single()const{ | 432 | QString FindQuery::single()const{ |
421 | QString qu = "select *"; | 433 | QString qu = "select *"; |
422 | qu += " from addressbook where uid = " + QString::number(m_uid); | 434 | qu += " from addressbook where uid = " + QString::number(m_uid); |
423 | 435 | ||
424 | // qWarning("find query: %s", qu.latin1() ); | 436 | // qWarning("find query: %s", qu.latin1() ); |
425 | return qu; | 437 | return qu; |
426 | } | 438 | } |
427 | #else | 439 | #else |
428 | QString FindQuery::single()const{ | 440 | QString FindQuery::single()const{ |
429 | QString qu = "select uid, type, value from addressbook where uid = "; | 441 | QString qu = "select uid, type, value from addressbook where uid = "; |
430 | qu += QString::number(m_uid); | 442 | qu += QString::number(m_uid); |
431 | return qu; | 443 | return qu; |
432 | } | 444 | } |
433 | #endif | 445 | #endif |
434 | 446 | ||
435 | 447 | ||
436 | FindCustomQuery::FindCustomQuery(int uid) | 448 | FindCustomQuery::FindCustomQuery(int uid) |
437 | : OSQLQuery(), m_uid( uid ) { | 449 | : OSQLQuery(), m_uid( uid ) { |
438 | } | 450 | } |
439 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) | 451 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) |
440 | : OSQLQuery(), m_uids( ints ){ | 452 | : OSQLQuery(), m_uids( ints ){ |
441 | } | 453 | } |
442 | FindCustomQuery::~FindCustomQuery() { | 454 | FindCustomQuery::~FindCustomQuery() { |
443 | } | 455 | } |
444 | QString FindCustomQuery::query()const{ | 456 | QString FindCustomQuery::query()const{ |
445 | // if ( m_uids.count() == 0 ) | 457 | // if ( m_uids.count() == 0 ) |
446 | return single(); | 458 | return single(); |
447 | } | 459 | } |
448 | QString FindCustomQuery::single()const{ | 460 | QString FindCustomQuery::single()const{ |
449 | QString qu = "select uid, type, value from custom_data where uid = "; | 461 | QString qu = "select uid, type, value from custom_data where uid = "; |
450 | qu += QString::number(m_uid); | 462 | qu += QString::number(m_uid); |
451 | return qu; | 463 | return qu; |
452 | } | 464 | } |
453 | 465 | ||
454 | }; | 466 | }; |
455 | 467 | ||
456 | 468 | ||
457 | /* --------------------------------------------------------------------------- */ | 469 | /* --------------------------------------------------------------------------- */ |
458 | 470 | ||
459 | OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, | 471 | OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, |
460 | const QString& filename ): | 472 | const QString& filename ): |
461 | OContactAccessBackend(), m_changed(false), m_driver( NULL ) | 473 | OContactAccessBackend(), m_changed(false), m_driver( NULL ) |
462 | { | 474 | { |
463 | qWarning("C'tor OContactAccessBackend_SQL starts"); | 475 | qWarning("C'tor OContactAccessBackend_SQL starts"); |
464 | QTime t; | 476 | QTime t; |
465 | t.start(); | 477 | t.start(); |
466 | 478 | ||
467 | /* Expecting to access the default filename if nothing else is set */ | 479 | /* Expecting to access the default filename if nothing else is set */ |
468 | if ( filename.isEmpty() ){ | 480 | if ( filename.isEmpty() ){ |
469 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); | 481 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); |
470 | } else | 482 | } else |
471 | m_fileName = filename; | 483 | m_fileName = filename; |
472 | 484 | ||
473 | // Get the standart sql-driver from the OSQLManager.. | 485 | // Get the standart sql-driver from the OSQLManager.. |
474 | OSQLManager man; | 486 | OSQLManager man; |
475 | m_driver = man.standard(); | 487 | m_driver = man.standard(); |
476 | m_driver->setUrl( m_fileName ); | 488 | m_driver->setUrl( m_fileName ); |
477 | 489 | ||
478 | load(); | 490 | load(); |
479 | 491 | ||
480 | qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); | 492 | qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); |
481 | } | 493 | } |
482 | 494 | ||
483 | OContactAccessBackend_SQL::~OContactAccessBackend_SQL () | 495 | OContactAccessBackend_SQL::~OContactAccessBackend_SQL () |
484 | { | 496 | { |
485 | if( m_driver ) | 497 | if( m_driver ) |
486 | delete m_driver; | 498 | delete m_driver; |
487 | } | 499 | } |
488 | 500 | ||
489 | bool OContactAccessBackend_SQL::load () | 501 | bool OContactAccessBackend_SQL::load () |
490 | { | 502 | { |
491 | if (!m_driver->open() ) | 503 | if (!m_driver->open() ) |
492 | return false; | 504 | return false; |
493 | 505 | ||
494 | // Don't expect that the database exists. | 506 | // Don't expect that the database exists. |
495 | // It is save here to create the table, even if it | 507 | // It is save here to create the table, even if it |
496 | // do exist. ( Is that correct for all databases ?? ) | 508 | // do exist. ( Is that correct for all databases ?? ) |
497 | CreateQuery creat; | 509 | CreateQuery creat; |
498 | OSQLResult res = m_driver->query( &creat ); | 510 | OSQLResult res = m_driver->query( &creat ); |
499 | 511 | ||
500 | update(); | 512 | update(); |
501 | 513 | ||
502 | return true; | 514 | return true; |
503 | 515 | ||
504 | } | 516 | } |
505 | 517 | ||
506 | bool OContactAccessBackend_SQL::reload() | 518 | bool OContactAccessBackend_SQL::reload() |
507 | { | 519 | { |
508 | return load(); | 520 | return load(); |
509 | } | 521 | } |
510 | 522 | ||
511 | bool OContactAccessBackend_SQL::save() | 523 | bool OContactAccessBackend_SQL::save() |
512 | { | 524 | { |
513 | return m_driver->close(); | 525 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) |
514 | } | 526 | } |
515 | 527 | ||
516 | 528 | ||
517 | void OContactAccessBackend_SQL::clear () | 529 | void OContactAccessBackend_SQL::clear () |
518 | { | 530 | { |
519 | ClearQuery cle; | 531 | ClearQuery cle; |
520 | OSQLResult res = m_driver->query( &cle ); | 532 | OSQLResult res = m_driver->query( &cle ); |
521 | CreateQuery qu; | 533 | |
522 | res = m_driver->query(&qu); | 534 | reload(); |
523 | } | 535 | } |
524 | 536 | ||
525 | bool OContactAccessBackend_SQL::wasChangedExternally() | 537 | bool OContactAccessBackend_SQL::wasChangedExternally() |
526 | { | 538 | { |
527 | return false; | 539 | return false; |
528 | } | 540 | } |
529 | 541 | ||
530 | QArray<int> OContactAccessBackend_SQL::allRecords() const | 542 | QArray<int> OContactAccessBackend_SQL::allRecords() const |
531 | { | 543 | { |
532 | 544 | ||
533 | // FIXME: Think about cute handling of changed tables.. | 545 | // FIXME: Think about cute handling of changed tables.. |
534 | // Thus, we don't have to call update here... | 546 | // Thus, we don't have to call update here... |
535 | if ( m_changed ) | 547 | if ( m_changed ) |
536 | ((OContactAccessBackend_SQL*)this)->update(); | 548 | ((OContactAccessBackend_SQL*)this)->update(); |
537 | 549 | ||
538 | return m_uids; | 550 | return m_uids; |
539 | } | 551 | } |
540 | 552 | ||
541 | bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) | 553 | bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) |
542 | { | 554 | { |
543 | InsertQuery ins( newcontact ); | 555 | InsertQuery ins( newcontact ); |
544 | OSQLResult res = m_driver->query( &ins ); | 556 | OSQLResult res = m_driver->query( &ins ); |
545 | 557 | ||
546 | if ( res.state() == OSQLResult::Failure ) | 558 | if ( res.state() == OSQLResult::Failure ) |
547 | return false; | 559 | return false; |
548 | 560 | ||
549 | int c = m_uids.count(); | 561 | int c = m_uids.count(); |
550 | m_uids.resize( c+1 ); | 562 | m_uids.resize( c+1 ); |
551 | m_uids[c] = newcontact.uid(); | 563 | m_uids[c] = newcontact.uid(); |
552 | 564 | ||
553 | return true; | 565 | return true; |
554 | } | 566 | } |
555 | 567 | ||
556 | 568 | ||
557 | bool OContactAccessBackend_SQL::remove ( int uid ) | 569 | bool OContactAccessBackend_SQL::remove ( int uid ) |
558 | { | 570 | { |
559 | RemoveQuery rem( uid ); | 571 | RemoveQuery rem( uid ); |
560 | OSQLResult res = m_driver->query(&rem ); | 572 | OSQLResult res = m_driver->query(&rem ); |
561 | 573 | ||
562 | if ( res.state() == OSQLResult::Failure ) | 574 | if ( res.state() == OSQLResult::Failure ) |
563 | return false; | 575 | return false; |
564 | 576 | ||
565 | m_changed = true; | 577 | m_changed = true; |
566 | 578 | ||
567 | return true; | 579 | return true; |
568 | } | 580 | } |
569 | 581 | ||
570 | bool OContactAccessBackend_SQL::replace ( const OContact &contact ) | 582 | bool OContactAccessBackend_SQL::replace ( const OContact &contact ) |
571 | { | 583 | { |
572 | if ( !remove( contact.uid() ) ) | 584 | if ( !remove( contact.uid() ) ) |
573 | return false; | 585 | return false; |
574 | 586 | ||
575 | return add( contact ); | 587 | return add( contact ); |
576 | } | 588 | } |
577 | 589 | ||
578 | 590 | ||
579 | OContact OContactAccessBackend_SQL::find ( int uid ) const | 591 | OContact OContactAccessBackend_SQL::find ( int uid ) const |
580 | { | 592 | { |
581 | qWarning("OContactAccessBackend_SQL::find()"); | 593 | qWarning("OContactAccessBackend_SQL::find()"); |
582 | QTime t; | 594 | QTime t; |
583 | t.start(); | 595 | t.start(); |
584 | 596 | ||
585 | OContact retContact( requestNonCustom( uid ) ); | 597 | OContact retContact( requestNonCustom( uid ) ); |
586 | retContact.setExtraMap( requestCustom( uid ) ); | 598 | retContact.setExtraMap( requestCustom( uid ) ); |
587 | 599 | ||
588 | qWarning("OContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() ); | 600 | qWarning("OContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() ); |
589 | return retContact; | 601 | return retContact; |
590 | } | 602 | } |
591 | 603 | ||
592 | 604 | ||
593 | 605 | ||
594 | QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ) | 606 | QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ) |
595 | { | 607 | { |
596 | QString qu = "SELECT uid FROM addressbook WHERE"; | 608 | QString qu = "SELECT uid FROM addressbook WHERE"; |
597 | 609 | ||
598 | QMap<int, QString> queryFields = query.toMap(); | 610 | QMap<int, QString> queryFields = query.toMap(); |
599 | QStringList fieldList = OContactFields::untrfields( false ); | 611 | QStringList fieldList = OContactFields::untrfields( false ); |
600 | QMap<QString, int> translate = OContactFields::untrFieldsToId(); | 612 | QMap<QString, int> translate = OContactFields::untrFieldsToId(); |
601 | 613 | ||
602 | // Convert every filled field to a SQL-Query | 614 | // Convert every filled field to a SQL-Query |
603 | bool isAnyFieldSelected = false; | 615 | bool isAnyFieldSelected = false; |
604 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 616 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
605 | int id = translate[*it]; | 617 | int id = translate[*it]; |
606 | QString queryStr = queryFields[id]; | 618 | QString queryStr = queryFields[id]; |
607 | if ( !queryStr.isEmpty() ){ | 619 | if ( !queryStr.isEmpty() ){ |
608 | isAnyFieldSelected = true; | 620 | isAnyFieldSelected = true; |
609 | switch( id ){ | 621 | switch( id ){ |
610 | default: | 622 | default: |
611 | // Switching between case sensitive and insensitive... | 623 | // Switching between case sensitive and insensitive... |
612 | // LIKE is not case sensitive, GLOB is case sensitive | 624 | // LIKE is not case sensitive, GLOB is case sensitive |
613 | // Do exist a better solution to switch this ? | 625 | // Do exist a better solution to switch this ? |
614 | if ( settings & OContactAccess::IgnoreCase ) | 626 | if ( settings & OContactAccess::IgnoreCase ) |
615 | qu += "(\"" + *it + "\"" + " LIKE " + "'" | 627 | qu += "(\"" + *it + "\"" + " LIKE " + "'" |
616 | + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND "; | 628 | + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND "; |
617 | else | 629 | else |
618 | qu += "(\"" + *it + "\"" + " GLOB " + "'" | 630 | qu += "(\"" + *it + "\"" + " GLOB " + "'" |
diff --git a/libopie/pim/odatebookaccess.cpp b/libopie/pim/odatebookaccess.cpp index a3661a3..82934f9 100644 --- a/libopie/pim/odatebookaccess.cpp +++ b/libopie/pim/odatebookaccess.cpp | |||
@@ -1,66 +1,81 @@ | |||
1 | #include "obackendfactory.h" | 1 | #include "obackendfactory.h" |
2 | #include "odatebookaccess.h" | 2 | #include "odatebookaccess.h" |
3 | 3 | ||
4 | /** | 4 | /** |
5 | * Simple constructor | 5 | * Simple constructor |
6 | * It takes a ODateBookAccessBackend as parent. If it is 0 the default implementation | 6 | * It takes a ODateBookAccessBackend as parent. If it is 0 the default implementation |
7 | * will be used! | 7 | * will be used! |
8 | * @param back The backend to be used or 0 for the default backend | 8 | * @param back The backend to be used or 0 for the default backend |
9 | * @param ac What kind of access is intended | 9 | * @param ac What kind of access is intended |
10 | */ | 10 | */ |
11 | ODateBookAccess::ODateBookAccess( ODateBookAccessBackend* back, enum Access ac ) | 11 | ODateBookAccess::ODateBookAccess( ODateBookAccessBackend* back, enum Access ac ) |
12 | : OPimAccessTemplate<OEvent>( back ) | 12 | : OPimAccessTemplate<OEvent>( back ) |
13 | { | 13 | { |
14 | if (!back ) | 14 | if (!back ) |
15 | back = OBackendFactory<ODateBookAccessBackend>::Default("datebook", QString::null ); | 15 | back = OBackendFactory<ODateBookAccessBackend>::Default("datebook", QString::null ); |
16 | 16 | ||
17 | m_backEnd = back; | 17 | m_backEnd = back; |
18 | setBackEnd( m_backEnd ); | 18 | setBackEnd( m_backEnd ); |
19 | } | 19 | } |
20 | ODateBookAccess::~ODateBookAccess() { | 20 | ODateBookAccess::~ODateBookAccess() { |
21 | } | 21 | } |
22 | 22 | ||
23 | /** | 23 | /** |
24 | * @return all events available | 24 | * @return all events available |
25 | */ | 25 | */ |
26 | ODateBookAccess::List ODateBookAccess::rawEvents()const { | 26 | ODateBookAccess::List ODateBookAccess::rawEvents()const { |
27 | QArray<int> ints = m_backEnd->rawEvents(); | 27 | QArray<int> ints = m_backEnd->rawEvents(); |
28 | 28 | ||
29 | List lis( ints, this ); | 29 | List lis( ints, this ); |
30 | return lis; | 30 | return lis; |
31 | } | 31 | } |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * @return all repeating events | 34 | * @return all repeating events |
35 | */ | 35 | */ |
36 | ODateBookAccess::List ODateBookAccess::rawRepeats()const { | 36 | ODateBookAccess::List ODateBookAccess::rawRepeats()const { |
37 | QArray<int> ints = m_backEnd->rawRepeats(); | 37 | QArray<int> ints = m_backEnd->rawRepeats(); |
38 | 38 | ||
39 | List lis( ints, this ); | 39 | List lis( ints, this ); |
40 | return lis; | 40 | return lis; |
41 | } | 41 | } |
42 | 42 | ||
43 | /** | 43 | /** |
44 | * @return all non repeating events | 44 | * @return all non repeating events |
45 | */ | 45 | */ |
46 | ODateBookAccess::List ODateBookAccess::nonRepeats()const { | 46 | ODateBookAccess::List ODateBookAccess::nonRepeats()const { |
47 | QArray<int> ints = m_backEnd->nonRepeats(); | 47 | QArray<int> ints = m_backEnd->nonRepeats(); |
48 | 48 | ||
49 | List lis( ints, this ); | 49 | List lis( ints, this ); |
50 | return lis; | 50 | return lis; |
51 | } | 51 | } |
52 | 52 | ||
53 | /** | 53 | /** |
54 | * @return dates in the time span between from and to | 54 | * @return dates in the time span between from and to |
55 | * @param from Include all events from... | 55 | * @param from Include all events from... |
56 | * @param to Include all events to... | 56 | * @param to Include all events to... |
57 | */ | 57 | */ |
58 | OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDate& from, const QDate& to ) { | 58 | OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDate& from, const QDate& to ) { |
59 | return m_backEnd->effecticeEvents( from, to ); | 59 | return m_backEnd->effectiveEvents( from, to ); |
60 | } | 60 | } |
61 | /** | 61 | /** |
62 | * @return all events at a given datetime | 62 | * @return all events at a given datetime |
63 | */ | 63 | */ |
64 | OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDateTime& start ) { | 64 | OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDateTime& start ) { |
65 | return m_backEnd->effecticeEvents( start ); | 65 | return m_backEnd->effectiveEvents( start ); |
66 | } | ||
67 | |||
68 | /** | ||
69 | * @return non repeating dates in the time span between from and to | ||
70 | * @param from Include all events from... | ||
71 | * @param to Include all events to... | ||
72 | */ | ||
73 | OEffectiveEvent::ValueList ODateBookAccess::effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) { | ||
74 | return m_backEnd->effectiveNonRepeatingEvents( from, to ); | ||
75 | } | ||
76 | /** | ||
77 | * @return all non repeating events at a given datetime | ||
78 | */ | ||
79 | OEffectiveEvent::ValueList ODateBookAccess::effectiveNonRepeatingEvents( const QDateTime& start ) { | ||
80 | return m_backEnd->effectiveNonRepeatingEvents( start ); | ||
66 | } | 81 | } |
diff --git a/libopie/pim/odatebookaccess.h b/libopie/pim/odatebookaccess.h index 7c7a63f..62196da 100644 --- a/libopie/pim/odatebookaccess.h +++ b/libopie/pim/odatebookaccess.h | |||
@@ -1,41 +1,44 @@ | |||
1 | #ifndef OPIE_DATE_BOOK_ACCESS_H | 1 | #ifndef OPIE_DATE_BOOK_ACCESS_H |
2 | #define OPIE_DATE_BOOK_ACCESS_H | 2 | #define OPIE_DATE_BOOK_ACCESS_H |
3 | 3 | ||
4 | #include "odatebookaccessbackend.h" | 4 | #include "odatebookaccessbackend.h" |
5 | #include "opimaccesstemplate.h" | 5 | #include "opimaccesstemplate.h" |
6 | 6 | ||
7 | #include "oevent.h" | 7 | #include "oevent.h" |
8 | 8 | ||
9 | /** | 9 | /** |
10 | * This is the object orientated datebook database. It'll use OBackendFactory | 10 | * This is the object orientated datebook database. It'll use OBackendFactory |
11 | * to query for a backend. | 11 | * to query for a backend. |
12 | * All access to the datebook should be done via this class. | 12 | * All access to the datebook should be done via this class. |
13 | * Make sure to load and save the datebook this is not part of | 13 | * Make sure to load and save the datebook this is not part of |
14 | * destructing and creating the object | 14 | * destructing and creating the object |
15 | * | 15 | * |
16 | * @author Holger Freyther | 16 | * @author Holger Freyther, Stefan Eilers |
17 | */ | 17 | */ |
18 | class ODateBookAccess : public OPimAccessTemplate<OEvent> { | 18 | class ODateBookAccess : public OPimAccessTemplate<OEvent> { |
19 | public: | 19 | public: |
20 | ODateBookAccess( ODateBookAccessBackend* = 0l, enum Access acc = Random ); | 20 | ODateBookAccess( ODateBookAccessBackend* = 0l, enum Access acc = Random ); |
21 | ~ODateBookAccess(); | 21 | ~ODateBookAccess(); |
22 | 22 | ||
23 | /* return all events */ | 23 | /* return all events */ |
24 | List rawEvents()const; | 24 | List rawEvents()const; |
25 | 25 | ||
26 | /* return repeating events */ | 26 | /* return repeating events */ |
27 | List rawRepeats()const; | 27 | List rawRepeats()const; |
28 | 28 | ||
29 | /* return non repeating events */ | 29 | /* return non repeating events */ |
30 | List nonRepeats()const; | 30 | List nonRepeats()const; |
31 | 31 | ||
32 | OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ); | 32 | /* return non repeating events (from,to) */ |
33 | OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ); | 33 | OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ) const; |
34 | OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ) const; | ||
35 | OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) const; | ||
36 | OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDateTime& start ) const; | ||
34 | 37 | ||
35 | private: | 38 | private: |
36 | ODateBookAccessBackend* m_backEnd; | 39 | ODateBookAccessBackend* m_backEnd; |
37 | class Private; | 40 | class Private; |
38 | Private* d; | 41 | Private* d; |
39 | }; | 42 | }; |
40 | 43 | ||
41 | #endif | 44 | #endif |
diff --git a/libopie/pim/odatebookaccessbackend.cpp b/libopie/pim/odatebookaccessbackend.cpp index 8fa1a68..f0c5d65 100644 --- a/libopie/pim/odatebookaccessbackend.cpp +++ b/libopie/pim/odatebookaccessbackend.cpp | |||
@@ -34,123 +34,149 @@ namespace { | |||
34 | 34 | ||
35 | /* we must also check for end date information... */ | 35 | /* we must also check for end date information... */ |
36 | if ( dtEnd.date() != dtStart.date() && dtEnd.date() >= from ) { | 36 | if ( dtEnd.date() != dtStart.date() && dtEnd.date() >= from ) { |
37 | QDateTime dt = dtStart.addDays( 1 ); | 37 | QDateTime dt = dtStart.addDays( 1 ); |
38 | dt.setTime( QTime(0, 0, 0 ) ); | 38 | dt.setTime( QTime(0, 0, 0 ) ); |
39 | QDateTime dtStop; | 39 | QDateTime dtStop; |
40 | if ( dtEnd > to ) | 40 | if ( dtEnd > to ) |
41 | dtStop = to; | 41 | dtStop = to; |
42 | else | 42 | else |
43 | dtStop = dtEnd; | 43 | dtStop = dtEnd; |
44 | 44 | ||
45 | while ( dt <= dtStop ) { | 45 | while ( dt <= dtStop ) { |
46 | OEffectiveEvent eff; | 46 | OEffectiveEvent eff; |
47 | eff.setEvent( (*it) ); | 47 | eff.setEvent( (*it) ); |
48 | eff.setDate( dt.date() ); | 48 | eff.setDate( dt.date() ); |
49 | 49 | ||
50 | if ( dt >= from ) { | 50 | if ( dt >= from ) { |
51 | eff.setStartTime( QTime(0, 0, 0 ) ); | 51 | eff.setStartTime( QTime(0, 0, 0 ) ); |
52 | if ( dt.date() == dtEnd.date() ) | 52 | if ( dt.date() == dtEnd.date() ) |
53 | eff.setEndTime( dtEnd.time() ); | 53 | eff.setEndTime( dtEnd.time() ); |
54 | else | 54 | else |
55 | eff.setEndTime( QTime(23, 59, 0 ) ); | 55 | eff.setEndTime( QTime(23, 59, 0 ) ); |
56 | tmpList.append( eff ); | 56 | tmpList.append( eff ); |
57 | } | 57 | } |
58 | dt = dt.addDays( 1 ); | 58 | dt = dt.addDays( 1 ); |
59 | } | 59 | } |
60 | } | 60 | } |
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
64 | void repeat( OEffectiveEvent::ValueList& tmpList, const OEvent::ValueList& list, | 64 | void repeat( OEffectiveEvent::ValueList& tmpList, const OEvent::ValueList& list, |
65 | const QDate& from, const QDate& to ) { | 65 | const QDate& from, const QDate& to ) { |
66 | QDate repeat; | 66 | QDate repeat; |
67 | for ( OEvent::ValueList::ConstIterator it = list.begin(); it != list.end(); ++it ) { | 67 | for ( OEvent::ValueList::ConstIterator it = list.begin(); it != list.end(); ++it ) { |
68 | int dur = (*it).startDateTime().date().daysTo( (*it).endDateTime().date() ); | 68 | int dur = (*it).startDateTime().date().daysTo( (*it).endDateTime().date() ); |
69 | QDate itDate = from.addDays(-dur ); | 69 | QDate itDate = from.addDays(-dur ); |
70 | ORecur rec = (*it).recurrence(); | 70 | ORecur rec = (*it).recurrence(); |
71 | if ( !rec.hasEndDate() || rec.endDate() > to ) { | 71 | if ( !rec.hasEndDate() || rec.endDate() > to ) { |
72 | rec.setEndDate( to ); | 72 | rec.setEndDate( to ); |
73 | rec.setHasEndDate( true ); | 73 | rec.setHasEndDate( true ); |
74 | } | 74 | } |
75 | while (rec.nextOcurrence(itDate, repeat ) ) { | 75 | while (rec.nextOcurrence(itDate, repeat ) ) { |
76 | if (repeat > to ) break; | 76 | if (repeat > to ) break; |
77 | OEffectiveEvent eff; | 77 | OEffectiveEvent eff; |
78 | eff.setDate( repeat ); | 78 | eff.setDate( repeat ); |
79 | if ( (*it).isAllDay() ) { | 79 | if ( (*it).isAllDay() ) { |
80 | eff.setStartTime( QTime(0, 0, 0 ) ); | 80 | eff.setStartTime( QTime(0, 0, 0 ) ); |
81 | eff.setEndTime( QTime(23, 59, 59 ) ); | 81 | eff.setEndTime( QTime(23, 59, 59 ) ); |
82 | }else { | 82 | }else { |
83 | /* we only occur by days, not hours/minutes/seconds. Hence | 83 | /* we only occur by days, not hours/minutes/seconds. Hence |
84 | * the actual end and start times will be the same for | 84 | * the actual end and start times will be the same for |
85 | * every repeated event. For multi day events this is | 85 | * every repeated event. For multi day events this is |
86 | * fixed up later if on wronge day span | 86 | * fixed up later if on wronge day span |
87 | */ | 87 | */ |
88 | eff.setStartTime( (*it).startDateTime().time() ); | 88 | eff.setStartTime( (*it).startDateTime().time() ); |
89 | eff.setEndTime( (*it).endDateTime().time() ); | 89 | eff.setEndTime( (*it).endDateTime().time() ); |
90 | } | 90 | } |
91 | if ( dur != 0 ) { | 91 | if ( dur != 0 ) { |
92 | // multi-day repeating events | 92 | // multi-day repeating events |
93 | QDate sub_it = QMAX( repeat, from ); | 93 | QDate sub_it = QMAX( repeat, from ); |
94 | QDate startDate = repeat; | 94 | QDate startDate = repeat; |
95 | QDate endDate = startDate.addDays( dur ); | 95 | QDate endDate = startDate.addDays( dur ); |
96 | 96 | ||
97 | while ( sub_it <= endDate && sub_it <= to ) { | 97 | while ( sub_it <= endDate && sub_it <= to ) { |
98 | OEffectiveEvent tmpEff = eff; | 98 | OEffectiveEvent tmpEff = eff; |
99 | tmpEff.setEvent( (*it) ); | 99 | tmpEff.setEvent( (*it) ); |
100 | if ( sub_it != startDate ) | 100 | if ( sub_it != startDate ) |
101 | tmpEff.setStartTime( QTime(0, 0, 0 ) ); | 101 | tmpEff.setStartTime( QTime(0, 0, 0 ) ); |
102 | if ( sub_it != endDate ) | 102 | if ( sub_it != endDate ) |
103 | tmpEff.setEndTime( QTime( 23, 59, 59 ) ); | 103 | tmpEff.setEndTime( QTime( 23, 59, 59 ) ); |
104 | 104 | ||
105 | tmpEff.setDate( sub_it ); | 105 | tmpEff.setDate( sub_it ); |
106 | tmpEff.setEffectiveDates( startDate, endDate ); | 106 | tmpEff.setEffectiveDates( startDate, endDate ); |
107 | tmpList.append( tmpEff ); | 107 | tmpList.append( tmpEff ); |
108 | 108 | ||
109 | sub_it = sub_it.addDays( 1 ); | 109 | sub_it = sub_it.addDays( 1 ); |
110 | } | 110 | } |
111 | itDate = endDate; | 111 | itDate = endDate; |
112 | }else { | 112 | }else { |
113 | eff.setEvent( (*it) ); | 113 | eff.setEvent( (*it) ); |
114 | tmpList.append( eff ); | 114 | tmpList.append( eff ); |
115 | itDate = repeat.addDays( 1 ); | 115 | itDate = repeat.addDays( 1 ); |
116 | } | 116 | } |
117 | } | 117 | } |
118 | } | 118 | } |
119 | } | 119 | } |
120 | } | 120 | } |
121 | 121 | ||
122 | ODateBookAccessBackend::ODateBookAccessBackend() | 122 | ODateBookAccessBackend::ODateBookAccessBackend() |
123 | : OPimAccessBackend<OEvent>() | 123 | : OPimAccessBackend<OEvent>() |
124 | { | 124 | { |
125 | 125 | ||
126 | } | 126 | } |
127 | ODateBookAccessBackend::~ODateBookAccessBackend() { | 127 | ODateBookAccessBackend::~ODateBookAccessBackend() { |
128 | 128 | ||
129 | } | 129 | } |
130 | OEffectiveEvent::ValueList ODateBookAccessBackend::effecticeEvents( const QDate& from, | 130 | OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDate& from, |
131 | const QDate& to ) { | 131 | const QDate& to ) { |
132 | OEffectiveEvent::ValueList tmpList; | 132 | OEffectiveEvent::ValueList tmpList; |
133 | OEvent::ValueList list = directNonRepeats(); | 133 | OEvent::ValueList list = directNonRepeats(); |
134 | 134 | ||
135 | events( tmpList, list, from, to ); | 135 | events( tmpList, list, from, to ); |
136 | repeat( tmpList, directRawRepeats(),from,to ); | 136 | repeat( tmpList, directRawRepeats(),from,to ); |
137 | 137 | ||
138 | list = directRawRepeats(); | 138 | list = directRawRepeats(); // Useless, isn't it ? (eilers) |
139 | 139 | ||
140 | qHeapSort( tmpList ); | 140 | qHeapSort( tmpList ); |
141 | return tmpList; | 141 | return tmpList; |
142 | } | 142 | } |
143 | OEffectiveEvent::ValueList ODateBookAccessBackend::effecticeEvents( const QDateTime& dt ) { | 143 | OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDateTime& dt ) { |
144 | OEffectiveEvent::ValueList day = effecticeEvents( dt.date(), dt.date() ); | 144 | OEffectiveEvent::ValueList day = effectiveEvents( dt.date(), dt.date() ); |
145 | OEffectiveEvent::ValueList::Iterator it; | ||
146 | |||
147 | OEffectiveEvent::ValueList tmpList; | ||
148 | QDateTime dtTmp; | ||
149 | for ( it = day.begin(); it != day.end(); ++it ) { | ||
150 | dtTmp = QDateTime( (*it).date(), (*it).startTime() ); | ||
151 | if ( QABS(dt.secsTo(dtTmp) ) < 60 ) | ||
152 | tmpList.append( (*it) ); | ||
153 | } | ||
154 | |||
155 | return tmpList; | ||
156 | } | ||
157 | |||
158 | OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDate& from, | ||
159 | const QDate& to ) { | ||
160 | OEffectiveEvent::ValueList tmpList; | ||
161 | OEvent::ValueList list = directNonRepeats(); | ||
162 | |||
163 | events( tmpList, list, from, to ); | ||
164 | |||
165 | qHeapSort( tmpList ); | ||
166 | return tmpList; | ||
167 | } | ||
168 | |||
169 | OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDateTime& dt ) { | ||
170 | OEffectiveEvent::ValueList day = effectiveNonRepeatingEvents( dt.date(), dt.date() ); | ||
145 | OEffectiveEvent::ValueList::Iterator it; | 171 | OEffectiveEvent::ValueList::Iterator it; |
146 | 172 | ||
147 | OEffectiveEvent::ValueList tmpList; | 173 | OEffectiveEvent::ValueList tmpList; |
148 | QDateTime dtTmp; | 174 | QDateTime dtTmp; |
149 | for ( it = day.begin(); it != day.end(); ++it ) { | 175 | for ( it = day.begin(); it != day.end(); ++it ) { |
150 | dtTmp = QDateTime( (*it).date(), (*it).startTime() ); | 176 | dtTmp = QDateTime( (*it).date(), (*it).startTime() ); |
151 | if ( QABS(dt.secsTo(dtTmp) ) < 60 ) | 177 | if ( QABS(dt.secsTo(dtTmp) ) < 60 ) |
152 | tmpList.append( (*it) ); | 178 | tmpList.append( (*it) ); |
153 | } | 179 | } |
154 | 180 | ||
155 | return tmpList; | 181 | return tmpList; |
156 | } | 182 | } |
diff --git a/libopie/pim/odatebookaccessbackend.h b/libopie/pim/odatebookaccessbackend.h index 3c02c42..3472ab3 100644 --- a/libopie/pim/odatebookaccessbackend.h +++ b/libopie/pim/odatebookaccessbackend.h | |||
@@ -1,77 +1,90 @@ | |||
1 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_H | 1 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_H |
2 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_H | 2 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_H |
3 | 3 | ||
4 | #include <qarray.h> | 4 | #include <qarray.h> |
5 | 5 | ||
6 | #include "opimaccessbackend.h" | 6 | #include "opimaccessbackend.h" |
7 | #include "oevent.h" | 7 | #include "oevent.h" |
8 | 8 | ||
9 | /** | 9 | /** |
10 | * This class is the interface to the storage of Events. | 10 | * This class is the interface to the storage of Events. |
11 | * @see OPimAccessBackend | 11 | * @see OPimAccessBackend |
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | class ODateBookAccessBackend : public OPimAccessBackend<OEvent> { | 14 | class ODateBookAccessBackend : public OPimAccessBackend<OEvent> { |
15 | public: | 15 | public: |
16 | typedef int UID; | 16 | typedef int UID; |
17 | 17 | ||
18 | /** | 18 | /** |
19 | * c'tor without parameter | 19 | * c'tor without parameter |
20 | */ | 20 | */ |
21 | ODateBookAccessBackend(); | 21 | ODateBookAccessBackend(); |
22 | ~ODateBookAccessBackend(); | 22 | ~ODateBookAccessBackend(); |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * This method should return a list of UIDs containing | 25 | * This method should return a list of UIDs containing |
26 | * all events. No filter should be applied | 26 | * all events. No filter should be applied |
27 | * @return list of events | 27 | * @return list of events |
28 | */ | 28 | */ |
29 | virtual QArray<UID> rawEvents()const = 0; | 29 | virtual QArray<UID> rawEvents()const = 0; |
30 | 30 | ||
31 | /** | 31 | /** |
32 | * This method should return a list of UIDs containing | 32 | * This method should return a list of UIDs containing |
33 | * all repeating events. No filter should be applied | 33 | * all repeating events. No filter should be applied |
34 | * @return list of repeating events | 34 | * @return list of repeating events |
35 | */ | 35 | */ |
36 | virtual QArray<UID> rawRepeats()const = 0; | 36 | virtual QArray<UID> rawRepeats()const = 0; |
37 | 37 | ||
38 | /** | 38 | /** |
39 | * This mthod should return a list of UIDs containing all non | 39 | * This mthod should return a list of UIDs containing all non |
40 | * repeating events. No filter should be applied | 40 | * repeating events. No filter should be applied |
41 | * @return list of nonrepeating events | 41 | * @return list of nonrepeating events |
42 | */ | 42 | */ |
43 | virtual QArray<UID> nonRepeats() const = 0; | 43 | virtual QArray<UID> nonRepeats() const = 0; |
44 | 44 | ||
45 | /** | 45 | /** |
46 | * If you do not want to implement the effectiveEvents methods below | 46 | * If you do not want to implement the effectiveEvents methods below |
47 | * you need to supply it with directNonRepeats. | 47 | * you need to supply it with directNonRepeats. |
48 | * This method can return empty lists if effectiveEvents is implememted | 48 | * This method can return empty lists if effectiveEvents is implememted |
49 | */ | 49 | */ |
50 | virtual OEvent::ValueList directNonRepeats() = 0; | 50 | virtual OEvent::ValueList directNonRepeats() = 0; |
51 | 51 | ||
52 | /** | 52 | /** |
53 | * Same as above but return raw repeats! | 53 | * Same as above but return raw repeats! |
54 | */ | 54 | */ |
55 | virtual OEvent::ValueList directRawRepeats() = 0; | 55 | virtual OEvent::ValueList directRawRepeats() = 0; |
56 | 56 | ||
57 | /* is implemented by default but you can reimplement it*/ | 57 | /* is implemented by default but you can reimplement it*/ |
58 | /** | 58 | /** |
59 | * Effective Events are special event occuring during a time frame. This method does calcualte | 59 | * Effective Events are special event occuring during a time frame. This method does calcualte |
60 | * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method | 60 | * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method |
61 | * yourself | 61 | * yourself |
62 | */ | 62 | */ |
63 | virtual OEffectiveEvent::ValueList effecticeEvents( const QDate& from, const QDate& to ); | 63 | virtual OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ); |
64 | 64 | ||
65 | /** | 65 | /** |
66 | * this is an overloaded member function | 66 | * this is an overloaded member function |
67 | * @see effecticeEvents | 67 | * @see effectiveEvents( const QDate& from, const QDate& to ) |
68 | */ | 68 | */ |
69 | virtual OEffectiveEvent::ValueList effecticeEvents( const QDateTime& start ); | 69 | virtual OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ); |
70 | |||
71 | /** | ||
72 | * Effective Events are special event occuring during a time frame. This method does calcualte | ||
73 | * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method | ||
74 | * yourself | ||
75 | */ | ||
76 | virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDate& from, const QDate& to ); | ||
77 | |||
78 | /** | ||
79 | * this is an overloaded member function | ||
80 | * @see effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) | ||
81 | */ | ||
82 | virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDateTime& start ); | ||
70 | 83 | ||
71 | private: | 84 | private: |
72 | class Private; | 85 | class Private; |
73 | Private *d; | 86 | Private *d; |
74 | 87 | ||
75 | }; | 88 | }; |
76 | 89 | ||
77 | #endif | 90 | #endif |
diff --git a/libopie/pim/odatebookaccessbackend_sql.cpp b/libopie/pim/odatebookaccessbackend_sql.cpp index 9769bf7..e893b38 100644 --- a/libopie/pim/odatebookaccessbackend_sql.cpp +++ b/libopie/pim/odatebookaccessbackend_sql.cpp | |||
@@ -1,221 +1,356 @@ | |||
1 | /* | 1 | /* |
2 | * SQL Backend for the OPIE-Calender Database. | 2 | * SQL Backend for the OPIE-Calender Database. |
3 | * | 3 | * |
4 | * Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de) | 4 | * Copyright (c) 2003 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.2 2003/12/22 10:19:26 eilers | ||
18 | * Finishing implementation of sql-backend for datebook. But I have to | ||
19 | * port the PIM datebook application to use it, before I could debug the | ||
20 | * whole stuff. | ||
21 | * Thus, PIM-Database backend is finished, but highly experimental. And some | ||
22 | * parts are still generic. For instance, the "queryByExample()" methods are | ||
23 | * not (or not fully) implemented. Todo: custom-entries not stored. | ||
24 | * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular | ||
25 | * expression search in the database, which is not supported by sqlite ! | ||
26 | * Therefore we need either an extended sqlite or a workaround which would | ||
27 | * be very slow and memory consuming.. | ||
28 | * | ||
17 | * Revision 1.1 2003/12/08 15:18:12 eilers | 29 | * Revision 1.1 2003/12/08 15:18:12 eilers |
18 | * Committing unfinished sql implementation before merging to libopie2 starts.. | 30 | * Committing unfinished sql implementation before merging to libopie2 starts.. |
19 | * | 31 | * |
20 | * | 32 | * |
21 | */ | 33 | */ |
22 | 34 | ||
23 | #include <stdio.h> | 35 | #include <stdio.h> |
24 | #include <stdlib.h> | 36 | #include <stdlib.h> |
25 | 37 | ||
26 | #include <qarray.h> | 38 | #include <qarray.h> |
27 | #include <qstringlist.h> | 39 | #include <qstringlist.h> |
28 | 40 | ||
29 | #include "orecur.h" | 41 | #include <qpe/global.h> |
30 | #include "odatebookaccessbackend_sql.h" | ||
31 | 42 | ||
32 | #include <opie2/osqldriver.h> | 43 | #include <opie2/osqldriver.h> |
33 | #include <opie2/osqlresult.h> | ||
34 | #include <opie2/osqlmanager.h> | 44 | #include <opie2/osqlmanager.h> |
35 | #include <opie2/osqlquery.h> | 45 | #include <opie2/osqlquery.h> |
36 | 46 | ||
37 | namespace { | 47 | #include "orecur.h" |
38 | 48 | #include "odatebookaccessbackend_sql.h" | |
39 | 49 | ||
40 | 50 | ||
41 | }; | ||
42 | 51 | ||
43 | ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , | 52 | ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , |
44 | const QString& fileName ) | 53 | const QString& fileName ) |
45 | : ODateBookAccessBackend(), m_driver( NULL ) | 54 | : ODateBookAccessBackend(), m_driver( NULL ) |
46 | { | 55 | { |
47 | m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; | 56 | m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; |
48 | 57 | ||
49 | // Get the standart sql-driver from the OSQLManager.. | 58 | // Get the standart sql-driver from the OSQLManager.. |
50 | OSQLManager man; | 59 | OSQLManager man; |
51 | m_driver = man.standard(); | 60 | m_driver = man.standard(); |
52 | m_driver->setUrl( m_fileName ); | 61 | m_driver->setUrl( m_fileName ); |
53 | 62 | ||
54 | initFields(); | 63 | initFields(); |
55 | 64 | ||
56 | load(); | 65 | load(); |
57 | } | 66 | } |
58 | 67 | ||
59 | ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { | 68 | ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { |
69 | if( m_driver ) | ||
70 | delete m_driver; | ||
60 | } | 71 | } |
61 | 72 | ||
62 | void ODateBookAccessBackend_SQL::initFields() | 73 | void ODateBookAccessBackend_SQL::initFields() |
63 | { | 74 | { |
64 | 75 | ||
65 | // This map contains the translation of the fieldtype id's to | 76 | // This map contains the translation of the fieldtype id's to |
66 | // the names of the table columns | 77 | // the names of the table columns |
67 | m_fieldMap.insert( OEvent::FUid, "uid" ); | 78 | m_fieldMap.insert( OEvent::FUid, "uid" ); |
68 | m_fieldMap.insert( OEvent::FCategories, "Categories" ); | 79 | m_fieldMap.insert( OEvent::FCategories, "Categories" ); |
69 | m_fieldMap.insert( OEvent::FDescription, "Description" ); | 80 | m_fieldMap.insert( OEvent::FDescription, "Description" ); |
70 | m_fieldMap.insert( OEvent::FLocation, "Location" ); | 81 | m_fieldMap.insert( OEvent::FLocation, "Location" ); |
71 | m_fieldMap.insert( OEvent::FType, "Type" ); | 82 | m_fieldMap.insert( OEvent::FType, "Type" ); |
72 | m_fieldMap.insert( OEvent::FAlarm, "Alarm" ); | 83 | m_fieldMap.insert( OEvent::FAlarm, "Alarm" ); |
73 | m_fieldMap.insert( OEvent::FSound, "Sound" ); | 84 | m_fieldMap.insert( OEvent::FSound, "Sound" ); |
74 | m_fieldMap.insert( OEvent::FRType, "RType" ); | 85 | m_fieldMap.insert( OEvent::FRType, "RType" ); |
75 | m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" ); | 86 | m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" ); |
76 | m_fieldMap.insert( OEvent::FRPosition, "RPosition" ); | 87 | m_fieldMap.insert( OEvent::FRPosition, "RPosition" ); |
77 | m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); | 88 | m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); |
78 | m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); | 89 | m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); |
79 | m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); | 90 | m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); |
80 | m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); | 91 | m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); |
81 | m_fieldMap.insert( OEvent::FRExeptions, "RExceptions" ); | 92 | m_fieldMap.insert( OEvent::FRExceptions, "RExceptions" ); |
82 | m_fieldMap.insert( OEvent::FStart, "Start" ); | 93 | m_fieldMap.insert( OEvent::FStart, "Start" ); |
83 | m_fieldMap.insert( OEvent::FEnd, "End" ); | 94 | m_fieldMap.insert( OEvent::FEnd, "End" ); |
84 | m_fieldMap.insert( OEvent::FNote, "Note" ); | 95 | m_fieldMap.insert( OEvent::FNote, "Note" ); |
85 | m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); | 96 | m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); |
86 | m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); | 97 | m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); |
87 | m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); | 98 | m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); |
99 | |||
100 | // Create a map that maps the column name to the id | ||
101 | QMapConstIterator<int, QString> it; | ||
102 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | ||
103 | m_reverseFieldMap.insert( it.data(), it.key() ); | ||
104 | } | ||
105 | |||
88 | } | 106 | } |
89 | 107 | ||
90 | bool ODateBookAccessBackend_SQL::load() | 108 | bool ODateBookAccessBackend_SQL::load() |
91 | { | 109 | { |
92 | if (!m_driver->open() ) | 110 | if (!m_driver->open() ) |
93 | return false; | 111 | return false; |
94 | 112 | ||
95 | // Don't expect that the database exists. | 113 | // Don't expect that the database exists. |
96 | // It is save here to create the table, even if it | 114 | // It is save here to create the table, even if it |
97 | // do exist. ( Is that correct for all databases ?? ) | 115 | // do exist. ( Is that correct for all databases ?? ) |
98 | QStringqu = "create table datebook( uid INTEGER PRIMARY KEY "; | 116 | QStringqu = "create table datebook( uid INTEGER PRIMARY KEY "; |
99 | 117 | ||
100 | QMap<int, QString>::Iterator it; | 118 | QMap<int, QString>::Iterator it; |
101 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | 119 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ |
102 | qu += QString( ",\"%1\" VARCHAR(10)" ).arg( it.data() ); | 120 | qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() ); |
103 | } | 121 | } |
104 | qu += " );"; | 122 | qu += " );"; |
105 | 123 | ||
106 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; | 124 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; |
107 | 125 | ||
126 | qWarning( "command: %s", qu.latin1() ); | ||
127 | |||
108 | OSQLRawQuery raw( qu ); | 128 | OSQLRawQuery raw( qu ); |
109 | OSQLResult res = m_driver->query( &raw ); | 129 | OSQLResult res = m_driver->query( &raw ); |
110 | if ( res.state() != OSQLResult::Success ) | 130 | if ( res.state() != OSQLResult::Success ) |
111 | return false; | 131 | return false; |
112 | 132 | ||
113 | update(); | 133 | update(); |
114 | 134 | ||
115 | return true; | 135 | return true; |
116 | } | 136 | } |
117 | 137 | ||
118 | void ODateBookAccessBackend_SQL::update() | 138 | void ODateBookAccessBackend_SQL::update() |
119 | { | 139 | { |
120 | 140 | ||
121 | QString qu = "select uid from datebook"; | 141 | QString qu = "select uid from datebook"; |
122 | OSQLRawQuery raw( qu ); | 142 | OSQLRawQuery raw( qu ); |
123 | OSQLResult res = m_driver->query( &raw ); | 143 | OSQLResult res = m_driver->query( &raw ); |
124 | if ( res.state() != OSQLResult::Success ){ | 144 | if ( res.state() != OSQLResult::Success ){ |
125 | m_uids.clear(); | 145 | // m_uids.clear(); |
126 | return; | 146 | return; |
127 | } | 147 | } |
128 | 148 | ||
129 | m_uids = extractUids( res ); | 149 | m_uids = extractUids( res ); |
130 | 150 | ||
131 | } | 151 | } |
132 | 152 | ||
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 | bool ODateBookAccessBackend_SQL::reload() |
153 | { | 154 | { |
154 | return load(); | 155 | return load(); |
155 | } | 156 | } |
156 | 157 | ||
157 | bool ODateBookAccessBackend_SQL::save() | 158 | bool ODateBookAccessBackend_SQL::save() |
158 | { | 159 | { |
159 | return m_driver->close(); | 160 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) |
160 | } | 161 | } |
161 | 162 | ||
162 | QArray<int> ODateBookAccessBackend_SQL::allRecords()const | 163 | QArray<int> ODateBookAccessBackend_SQL::allRecords()const |
163 | { | 164 | { |
164 | return m_uids; | 165 | return m_uids; |
165 | } | 166 | } |
166 | 167 | ||
167 | QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) { | 168 | QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) { |
168 | return QArray<int>(); | 169 | return QArray<int>(); |
169 | } | 170 | } |
170 | 171 | ||
171 | void ODateBookAccessBackend_SQL::clear() | 172 | void ODateBookAccessBackend_SQL::clear() |
172 | { | 173 | { |
173 | QString qu = "drop table datebook;"; | 174 | QString qu = "drop table datebook;"; |
174 | qu += "drop table custom_data;"; | 175 | qu += "drop table custom_data;"; |
175 | 176 | ||
176 | OSQLRawQuery raw( qu ); | 177 | OSQLRawQuery raw( qu ); |
177 | OSQLResult res = m_driver->query( &raw ); | 178 | OSQLResult res = m_driver->query( &raw ); |
178 | 179 | ||
180 | reload(); | ||
179 | } | 181 | } |
180 | 182 | ||
181 | 183 | ||
182 | OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ | 184 | OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ |
185 | QString qu = "select *"; | ||
186 | qu += "from datebook where uid = " + QString::number(uid); | ||
187 | |||
188 | OSQLRawQuery raw( qu ); | ||
189 | OSQLResult res = m_driver->query( &raw ); | ||
190 | |||
191 | OSQLResultItem resItem = res.first(); | ||
192 | |||
193 | // Create Map for date event and insert UID | ||
194 | QMap<int,QString> dateEventMap; | ||
195 | dateEventMap.insert( OEvent::FUid, QString::number( uid ) ); | ||
196 | |||
197 | // Now insert the data out of the columns into the map. | ||
198 | QMapConstIterator<int, QString> it; | ||
199 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | ||
200 | dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) ); | ||
201 | } | ||
202 | |||
203 | // Last step: Put map into date event and return it | ||
204 | OEvent retDate( dateEventMap ); | ||
205 | |||
206 | return retDate; | ||
183 | } | 207 | } |
184 | 208 | ||
185 | bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) { | 209 | bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) |
186 | return true; | 210 | { |
211 | QMap<int,QString> eventMap = ev.toMap(); | ||
212 | |||
213 | QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() ); | ||
214 | QMap<int, QString>::Iterator it; | ||
215 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | ||
216 | if ( !eventMap[it.key()].isEmpty() ) | ||
217 | qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] ); | ||
218 | else | ||
219 | qu += QString( ",\"\"" ); | ||
220 | } | ||
221 | qu += " );"; | ||
222 | |||
223 | // Add custom entries | ||
224 | int id = 0; | ||
225 | QMap<QString, QString> customMap = ev.toExtraMap(); | ||
226 | for( QMap<QString, QString>::Iterator it = customMap.begin(); | ||
227 | it != customMap.end(); ++it ){ | ||
228 | qu += "insert into custom_data VALUES(" | ||
229 | + QString::number( ev.uid() ) | ||
230 | + "," | ||
231 | + QString::number( id++ ) | ||
232 | + ",'" | ||
233 | + it.key() //.latin1() | ||
234 | + "'," | ||
235 | + "0" // Priority for future enhancements | ||
236 | + ",'" | ||
237 | + it.data() //.latin1() | ||
238 | + "');"; | ||
239 | } | ||
240 | qWarning("add %s", qu.latin1() ); | ||
241 | |||
242 | OSQLRawQuery raw( qu ); | ||
243 | OSQLResult res = m_driver->query( &raw ); | ||
244 | if ( res.state() != OSQLResult::Success ){ | ||
245 | return false; | ||
246 | } | ||
247 | |||
248 | return true; | ||
187 | } | 249 | } |
188 | bool ODateBookAccessBackend_SQL::remove( int uid ) { | ||
189 | 250 | ||
190 | return true; | 251 | bool ODateBookAccessBackend_SQL::remove( int uid ) |
252 | { | ||
253 | QString qu = "DELETE from datebook where uid = " | ||
254 | + QString::number( uid ) + ";"; | ||
255 | qu += "DELETE from custom_data where uid = " | ||
256 | + QString::number( uid ) + ";"; | ||
257 | |||
258 | OSQLRawQuery raw( qu ); | ||
259 | OSQLResult res = m_driver->query( &raw ); | ||
260 | if ( res.state() != OSQLResult::Success ){ | ||
261 | return false; | ||
262 | } | ||
263 | |||
264 | return true; | ||
191 | } | 265 | } |
192 | bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) { | 266 | |
267 | bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) | ||
268 | { | ||
193 | remove( ev.uid() ); | 269 | remove( ev.uid() ); |
194 | return add( ev ); | 270 | return add( ev ); |
195 | } | 271 | } |
196 | QArray<int> ODateBookAccessBackend_SQL::rawEvents()const { | 272 | |
273 | QArray<int> ODateBookAccessBackend_SQL::rawEvents()const | ||
274 | { | ||
197 | return allRecords(); | 275 | return allRecords(); |
198 | } | 276 | } |
199 | QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const { | ||
200 | 277 | ||
201 | return ints; | 278 | QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const |
279 | { | ||
280 | QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\""; | ||
281 | OSQLRawQuery raw( qu ); | ||
282 | OSQLResult res = m_driver->query( &raw ); | ||
283 | if ( res.state() != OSQLResult::Success ){ | ||
284 | QArray<int> nix; | ||
285 | return nix; | ||
286 | } | ||
287 | |||
288 | return extractUids( res ); | ||
202 | } | 289 | } |
203 | QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const { | ||
204 | 290 | ||
205 | return ints; | 291 | QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const |
292 | { | ||
293 | QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\""; | ||
294 | OSQLRawQuery raw( qu ); | ||
295 | OSQLResult res = m_driver->query( &raw ); | ||
296 | if ( res.state() != OSQLResult::Success ){ | ||
297 | QArray<int> nix; | ||
298 | return nix; | ||
299 | } | ||
300 | |||
301 | return extractUids( res ); | ||
206 | } | 302 | } |
207 | OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() { | ||
208 | 303 | ||
209 | return list; | 304 | OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() |
305 | { | ||
306 | QArray<int> nonRepUids = nonRepeats(); | ||
307 | OEvent::ValueList list; | ||
308 | |||
309 | for (uint i = 0; i < nonRepUids.count(); ++i ){ | ||
310 | list.append( find( nonRepUids[i] ) ); | ||
311 | } | ||
312 | |||
313 | return list; | ||
314 | |||
210 | } | 315 | } |
211 | OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() { | 316 | OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() |
317 | { | ||
318 | QArray<int> rawRepUids = rawRepeats(); | ||
319 | OEvent::ValueList list; | ||
212 | 320 | ||
213 | return list; | 321 | for (uint i = 0; i < rawRepUids.count(); ++i ){ |
322 | list.append( find( rawRepUids[i] ) ); | ||
323 | } | ||
324 | |||
325 | return list; | ||
214 | } | 326 | } |
215 | 327 | ||
216 | 328 | ||
217 | QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | 329 | QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const |
218 | { | 330 | { |
331 | QArray<int> null; | ||
332 | return null; | ||
333 | } | ||
334 | |||
335 | /* ===== Private Functions ========================================== */ | ||
336 | |||
337 | QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const | ||
338 | { | ||
339 | qWarning("extractUids"); | ||
340 | QTime t; | ||
341 | t.start(); | ||
342 | OSQLResultItem::ValueList list = res.results(); | ||
343 | OSQLResultItem::ValueList::Iterator it; | ||
344 | QArray<int> ints(list.count() ); | ||
345 | qWarning(" count = %d", list.count() ); | ||
346 | |||
347 | int i = 0; | ||
348 | for (it = list.begin(); it != list.end(); ++it ) { | ||
349 | ints[i] = (*it).data("uid").toInt(); | ||
350 | i++; | ||
351 | } | ||
352 | qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); | ||
353 | |||
354 | return ints; | ||
219 | 355 | ||
220 | return m_currentQuery; | ||
221 | } | 356 | } |
diff --git a/libopie/pim/odatebookaccessbackend_sql.h b/libopie/pim/odatebookaccessbackend_sql.h index 85e0d4f..f39e154 100644 --- a/libopie/pim/odatebookaccessbackend_sql.h +++ b/libopie/pim/odatebookaccessbackend_sql.h | |||
@@ -1,60 +1,62 @@ | |||
1 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | 1 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H |
2 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | 2 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H |
3 | 3 | ||
4 | #include <qmap.h> | 4 | #include <qmap.h> |
5 | #include <opie2/osqlresult.h> | ||
5 | 6 | ||
6 | #include "odatebookaccessbackend.h" | 7 | #include "odatebookaccessbackend.h" |
7 | 8 | ||
8 | class OSQLDriver; | 9 | class OSQLDriver; |
9 | 10 | ||
10 | /** | 11 | /** |
11 | * This is the default SQL implementation for DateBoook SQL storage | 12 | * This is the default SQL implementation for DateBoook SQL storage |
12 | * It fully implements the interface | 13 | * It fully implements the interface |
13 | * @see ODateBookAccessBackend | 14 | * @see ODateBookAccessBackend |
14 | * @see OPimAccessBackend | 15 | * @see OPimAccessBackend |
15 | */ | 16 | */ |
16 | class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { | 17 | class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { |
17 | public: | 18 | public: |
18 | ODateBookAccessBackend_SQL( const QString& appName, | 19 | ODateBookAccessBackend_SQL( const QString& appName, |
19 | const QString& fileName = QString::null); | 20 | const QString& fileName = QString::null); |
20 | ~ODateBookAccessBackend_SQL(); | 21 | ~ODateBookAccessBackend_SQL(); |
21 | 22 | ||
22 | bool load(); | 23 | bool load(); |
23 | bool reload(); | 24 | bool reload(); |
24 | bool save(); | 25 | bool save(); |
25 | 26 | ||
26 | QArray<int> allRecords()const; | 27 | QArray<int> allRecords()const; |
27 | QArray<int> matchRegexp(const QRegExp &r) const; | 28 | QArray<int> matchRegexp(const QRegExp &r) const; |
28 | QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() ); | 29 | QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() ); |
29 | OEvent find( int uid )const; | 30 | OEvent find( int uid )const; |
30 | void clear(); | 31 | void clear(); |
31 | bool add( const OEvent& ev ); | 32 | bool add( const OEvent& ev ); |
32 | bool remove( int uid ); | 33 | bool remove( int uid ); |
33 | bool replace( const OEvent& ev ); | 34 | bool replace( const OEvent& ev ); |
34 | 35 | ||
35 | QArray<UID> rawEvents()const; | 36 | QArray<UID> rawEvents()const; |
36 | QArray<UID> rawRepeats()const; | 37 | QArray<UID> rawRepeats()const; |
37 | QArray<UID> nonRepeats()const; | 38 | QArray<UID> nonRepeats()const; |
38 | 39 | ||
39 | OEvent::ValueList directNonRepeats(); | 40 | OEvent::ValueList directNonRepeats(); |
40 | OEvent::ValueList directRawRepeats(); | 41 | OEvent::ValueList directRawRepeats(); |
41 | 42 | ||
42 | private: | 43 | private: |
43 | bool loadFile(); | 44 | bool loadFile(); |
44 | QString m_fileName; | 45 | QString m_fileName; |
45 | QArray<int> m_uids; | 46 | QArray<int> m_uids; |
46 | 47 | ||
47 | QMap<int, QString> m_fieldMap; | 48 | QMap<int, QString> m_fieldMap; |
49 | QMap<QString, int> m_reverseFieldMap; | ||
48 | 50 | ||
49 | OSQLDriver* m_driver; | 51 | OSQLDriver* m_driver; |
50 | 52 | ||
51 | class Private; | 53 | class Private; |
52 | Private *d; | 54 | Private *d; |
53 | 55 | ||
54 | void initFields(); | 56 | void initFields(); |
55 | void update(); | 57 | void update(); |
56 | QArray<int> extractUids( OSQLResult& res ) const; | 58 | QArray<int> extractUids( OSQLResult& res ) const; |
57 | 59 | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | #endif | 62 | #endif |
diff --git a/libopie/pim/oevent.cpp b/libopie/pim/oevent.cpp index ec05e77..9b31957 100644 --- a/libopie/pim/oevent.cpp +++ b/libopie/pim/oevent.cpp | |||
@@ -1,175 +1,184 @@ | |||
1 | #include <qshared.h> | 1 | #include <qshared.h> |
2 | #include <qarray.h> | 2 | #include <qarray.h> |
3 | 3 | ||
4 | #include <qpe/palmtopuidgen.h> | 4 | #include <qpe/palmtopuidgen.h> |
5 | #include <qpe/categories.h> | 5 | #include <qpe/categories.h> |
6 | #include <qpe/stringutil.h> | 6 | #include <qpe/stringutil.h> |
7 | 7 | ||
8 | #include "orecur.h" | 8 | #include "orecur.h" |
9 | #include "opimresolver.h" | 9 | #include "opimresolver.h" |
10 | #include "opimnotifymanager.h" | 10 | #include "opimnotifymanager.h" |
11 | 11 | ||
12 | #include "oevent.h" | 12 | #include "oevent.h" |
13 | 13 | ||
14 | int OCalendarHelper::week( const QDate& date) { | 14 | int OCalendarHelper::week( const QDate& date) { |
15 | // Calculates the week this date is in within that | 15 | // Calculates the week this date is in within that |
16 | // month. Equals the "row" is is in in the month view | 16 | // month. Equals the "row" is is in in the month view |
17 | int week = 1; | 17 | int week = 1; |
18 | QDate tmp( date.year(), date.month(), 1 ); | 18 | QDate tmp( date.year(), date.month(), 1 ); |
19 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) | 19 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) |
20 | ++week; | 20 | ++week; |
21 | 21 | ||
22 | week += ( date.day() - 1 ) / 7; | 22 | week += ( date.day() - 1 ) / 7; |
23 | 23 | ||
24 | return week; | 24 | return week; |
25 | } | 25 | } |
26 | int OCalendarHelper::ocurrence( const QDate& date) { | 26 | int OCalendarHelper::ocurrence( const QDate& date) { |
27 | // calculates the number of occurrances of this day of the | 27 | // calculates the number of occurrances of this day of the |
28 | // 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) |
29 | return ( date.day() - 1 ) / 7 + 1; | 29 | return ( date.day() - 1 ) / 7 + 1; |
30 | } | 30 | } |
31 | int OCalendarHelper::dayOfWeek( char day ) { | 31 | int OCalendarHelper::dayOfWeek( char day ) { |
32 | int dayOfWeek = 1; | 32 | int dayOfWeek = 1; |
33 | char i = ORecur::MON; | 33 | char i = ORecur::MON; |
34 | while ( !( i & day ) && i <= ORecur::SUN ) { | 34 | while ( !( i & day ) && i <= ORecur::SUN ) { |
35 | i <<= 1; | 35 | i <<= 1; |
36 | ++dayOfWeek; | 36 | ++dayOfWeek; |
37 | } | 37 | } |
38 | return dayOfWeek; | 38 | return dayOfWeek; |
39 | } | 39 | } |
40 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { | 40 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { |
41 | return ( second.year() - first.year() ) * 12 + | 41 | return ( second.year() - first.year() ) * 12 + |
42 | second.month() - first.month(); | 42 | second.month() - first.month(); |
43 | } | 43 | } |
44 | 44 | ||
45 | struct OEvent::Data : public QShared { | 45 | struct OEvent::Data : public QShared { |
46 | Data() : QShared() { | 46 | Data() : QShared() { |
47 | child = 0; | 47 | child = 0; |
48 | recur = 0; | 48 | recur = 0; |
49 | manager = 0; | 49 | manager = 0; |
50 | isAllDay = false; | 50 | isAllDay = false; |
51 | parent = 0; | 51 | parent = 0; |
52 | } | 52 | } |
53 | ~Data() { | 53 | ~Data() { |
54 | delete manager; | 54 | delete manager; |
55 | delete recur; | 55 | delete recur; |
56 | } | 56 | } |
57 | QString description; | 57 | QString description; |
58 | QString location; | 58 | QString location; |
59 | OPimNotifyManager* manager; | 59 | OPimNotifyManager* manager; |
60 | ORecur* recur; | 60 | ORecur* recur; |
61 | QString note; | 61 | QString note; |
62 | QDateTime created; | 62 | QDateTime created; |
63 | QDateTime start; | 63 | QDateTime start; |
64 | QDateTime end; | 64 | QDateTime end; |
65 | bool isAllDay : 1; | 65 | bool isAllDay : 1; |
66 | QString timezone; | 66 | QString timezone; |
67 | QArray<int>* child; | 67 | QArray<int>* child; |
68 | int parent; | 68 | int parent; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | OEvent::OEvent( int uid ) | 71 | OEvent::OEvent( int uid ) |
72 | : OPimRecord( uid ) { | 72 | : OPimRecord( uid ) { |
73 | data = new Data; | 73 | data = new Data; |
74 | } | 74 | } |
75 | OEvent::OEvent( const OEvent& ev) | 75 | OEvent::OEvent( const OEvent& ev) |
76 | : OPimRecord( ev ), data( ev.data ) | 76 | : OPimRecord( ev ), data( ev.data ) |
77 | { | 77 | { |
78 | data->ref(); | 78 | data->ref(); |
79 | } | 79 | } |
80 | |||
81 | OEvent::OEvent( const QMap<int, QString> map ) | ||
82 | : OPimRecord( 0 ) | ||
83 | { | ||
84 | data = new Data; | ||
85 | |||
86 | fromMap( map ); | ||
87 | } | ||
88 | |||
80 | OEvent::~OEvent() { | 89 | OEvent::~OEvent() { |
81 | if ( data->deref() ) { | 90 | if ( data->deref() ) { |
82 | delete data; | 91 | delete data; |
83 | data = 0; | 92 | data = 0; |
84 | } | 93 | } |
85 | } | 94 | } |
86 | OEvent& OEvent::operator=( const OEvent& ev) { | 95 | OEvent& OEvent::operator=( const OEvent& ev) { |
87 | if ( this == &ev ) return *this; | 96 | if ( this == &ev ) return *this; |
88 | 97 | ||
89 | OPimRecord::operator=( ev ); | 98 | OPimRecord::operator=( ev ); |
90 | ev.data->ref(); | 99 | ev.data->ref(); |
91 | deref(); | 100 | deref(); |
92 | data = ev.data; | 101 | data = ev.data; |
93 | 102 | ||
94 | 103 | ||
95 | return *this; | 104 | return *this; |
96 | } | 105 | } |
97 | QString OEvent::description()const { | 106 | QString OEvent::description()const { |
98 | return data->description; | 107 | return data->description; |
99 | } | 108 | } |
100 | void OEvent::setDescription( const QString& description ) { | 109 | void OEvent::setDescription( const QString& description ) { |
101 | changeOrModify(); | 110 | changeOrModify(); |
102 | data->description = description; | 111 | data->description = description; |
103 | } | 112 | } |
104 | void OEvent::setLocation( const QString& loc ) { | 113 | void OEvent::setLocation( const QString& loc ) { |
105 | changeOrModify(); | 114 | changeOrModify(); |
106 | data->location = loc; | 115 | data->location = loc; |
107 | } | 116 | } |
108 | QString OEvent::location()const { | 117 | QString OEvent::location()const { |
109 | return data->location; | 118 | return data->location; |
110 | } | 119 | } |
111 | OPimNotifyManager &OEvent::notifiers()const { | 120 | OPimNotifyManager &OEvent::notifiers()const { |
112 | // I hope we can skip the changeOrModify here | 121 | // I hope we can skip the changeOrModify here |
113 | // the notifier should take care of it | 122 | // the notifier should take care of it |
114 | // and OPimNotify is shared too | 123 | // and OPimNotify is shared too |
115 | if (!data->manager ) | 124 | if (!data->manager ) |
116 | data->manager = new OPimNotifyManager; | 125 | data->manager = new OPimNotifyManager; |
117 | 126 | ||
118 | return *data->manager; | 127 | return *data->manager; |
119 | } | 128 | } |
120 | bool OEvent::hasNotifiers()const { | 129 | bool OEvent::hasNotifiers()const { |
121 | if (!data->manager ) | 130 | if (!data->manager ) |
122 | return false; | 131 | return false; |
123 | if (data->manager->reminders().isEmpty() && | 132 | if (data->manager->reminders().isEmpty() && |
124 | data->manager->alarms().isEmpty() ) | 133 | data->manager->alarms().isEmpty() ) |
125 | return false; | 134 | return false; |
126 | 135 | ||
127 | return true; | 136 | return true; |
128 | } | 137 | } |
129 | ORecur OEvent::recurrence()const { | 138 | ORecur OEvent::recurrence()const { |
130 | if (!data->recur) | 139 | if (!data->recur) |
131 | data->recur = new ORecur; | 140 | data->recur = new ORecur; |
132 | 141 | ||
133 | return *data->recur; | 142 | return *data->recur; |
134 | } | 143 | } |
135 | void OEvent::setRecurrence( const ORecur& rec) { | 144 | void OEvent::setRecurrence( const ORecur& rec) { |
136 | changeOrModify(); | 145 | changeOrModify(); |
137 | if (data->recur ) | 146 | if (data->recur ) |
138 | (*data->recur) = rec; | 147 | (*data->recur) = rec; |
139 | else | 148 | else |
140 | data->recur = new ORecur( rec ); | 149 | data->recur = new ORecur( rec ); |
141 | } | 150 | } |
142 | bool OEvent::hasRecurrence()const { | 151 | bool OEvent::hasRecurrence()const { |
143 | if (!data->recur ) return false; | 152 | if (!data->recur ) return false; |
144 | return data->recur->doesRecur(); | 153 | return data->recur->doesRecur(); |
145 | } | 154 | } |
146 | QString OEvent::note()const { | 155 | QString OEvent::note()const { |
147 | return data->note; | 156 | return data->note; |
148 | } | 157 | } |
149 | void OEvent::setNote( const QString& note ) { | 158 | void OEvent::setNote( const QString& note ) { |
150 | changeOrModify(); | 159 | changeOrModify(); |
151 | data->note = note; | 160 | data->note = note; |
152 | } | 161 | } |
153 | QDateTime OEvent::createdDateTime()const { | 162 | QDateTime OEvent::createdDateTime()const { |
154 | return data->created; | 163 | return data->created; |
155 | } | 164 | } |
156 | void OEvent::setCreatedDateTime( const QDateTime& time ) { | 165 | void OEvent::setCreatedDateTime( const QDateTime& time ) { |
157 | changeOrModify(); | 166 | changeOrModify(); |
158 | data->created = time; | 167 | data->created = time; |
159 | } | 168 | } |
160 | QDateTime OEvent::startDateTime()const { | 169 | QDateTime OEvent::startDateTime()const { |
161 | if ( data->isAllDay ) | 170 | if ( data->isAllDay ) |
162 | return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); | 171 | return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); |
163 | return data->start; | 172 | return data->start; |
164 | } | 173 | } |
165 | QDateTime OEvent::startDateTimeInZone()const { | 174 | QDateTime OEvent::startDateTimeInZone()const { |
166 | /* if no timezone, or all day event or if the current and this timeZone match... */ | 175 | /* if no timezone, or all day event or if the current and this timeZone match... */ |
167 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); | 176 | if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); |
168 | 177 | ||
169 | OTimeZone zone(data->timezone ); | 178 | OTimeZone zone(data->timezone ); |
170 | return zone.toDateTime( data->start, OTimeZone::current() ); | 179 | return zone.toDateTime( data->start, OTimeZone::current() ); |
171 | } | 180 | } |
172 | void OEvent::setStartDateTime( const QDateTime& dt ) { | 181 | void OEvent::setStartDateTime( const QDateTime& dt ) { |
173 | changeOrModify(); | 182 | changeOrModify(); |
174 | data->start = dt; | 183 | data->start = dt; |
175 | } | 184 | } |
@@ -310,192 +319,196 @@ QString OEvent::toShortText()const { | |||
310 | QString OEvent::type()const { | 319 | QString OEvent::type()const { |
311 | return QString::fromLatin1("OEvent"); | 320 | return QString::fromLatin1("OEvent"); |
312 | } | 321 | } |
313 | QString OEvent::recordField( int /*id */ )const { | 322 | QString OEvent::recordField( int /*id */ )const { |
314 | return QString::null; | 323 | return QString::null; |
315 | } | 324 | } |
316 | int OEvent::rtti() { | 325 | int OEvent::rtti() { |
317 | return OPimResolver::DateBook; | 326 | return OPimResolver::DateBook; |
318 | } | 327 | } |
319 | bool OEvent::loadFromStream( QDataStream& ) { | 328 | bool OEvent::loadFromStream( QDataStream& ) { |
320 | return true; | 329 | return true; |
321 | } | 330 | } |
322 | bool OEvent::saveToStream( QDataStream& )const { | 331 | bool OEvent::saveToStream( QDataStream& )const { |
323 | return true; | 332 | return true; |
324 | } | 333 | } |
325 | void OEvent::changeOrModify() { | 334 | void OEvent::changeOrModify() { |
326 | if ( data->count != 1 ) { | 335 | if ( data->count != 1 ) { |
327 | data->deref(); | 336 | data->deref(); |
328 | Data* d2 = new Data; | 337 | Data* d2 = new Data; |
329 | d2->description = data->description; | 338 | d2->description = data->description; |
330 | d2->location = data->location; | 339 | d2->location = data->location; |
331 | 340 | ||
332 | if (data->manager ) | 341 | if (data->manager ) |
333 | d2->manager = new OPimNotifyManager( *data->manager ); | 342 | d2->manager = new OPimNotifyManager( *data->manager ); |
334 | 343 | ||
335 | if ( data->recur ) | 344 | if ( data->recur ) |
336 | d2->recur = new ORecur( *data->recur ); | 345 | d2->recur = new ORecur( *data->recur ); |
337 | 346 | ||
338 | d2->note = data->note; | 347 | d2->note = data->note; |
339 | d2->created = data->created; | 348 | d2->created = data->created; |
340 | d2->start = data->start; | 349 | d2->start = data->start; |
341 | d2->end = data->end; | 350 | d2->end = data->end; |
342 | d2->isAllDay = data->isAllDay; | 351 | d2->isAllDay = data->isAllDay; |
343 | d2->timezone = data->timezone; | 352 | d2->timezone = data->timezone; |
344 | d2->parent = data->parent; | 353 | d2->parent = data->parent; |
345 | 354 | ||
346 | if ( data->child ) { | 355 | if ( data->child ) { |
347 | d2->child = new QArray<int>( *data->child ); | 356 | d2->child = new QArray<int>( *data->child ); |
348 | d2->child->detach(); | 357 | d2->child->detach(); |
349 | } | 358 | } |
350 | 359 | ||
351 | data = d2; | 360 | data = d2; |
352 | } | 361 | } |
353 | } | 362 | } |
354 | void OEvent::deref() { | 363 | void OEvent::deref() { |
355 | if ( data->deref() ) { | 364 | if ( data->deref() ) { |
356 | delete data; | 365 | delete data; |
357 | data = 0; | 366 | data = 0; |
358 | } | 367 | } |
359 | } | 368 | } |
360 | // Exporting Event data to map. Using the same | 369 | // Exporting Event data to map. Using the same |
361 | // encoding as ODateBookAccessBackend_xml does.. | 370 | // encoding as ODateBookAccessBackend_xml does.. |
362 | // Thus, we could remove the stuff there and use this | 371 | // Thus, we could remove the stuff there and use this |
363 | // for it and for all other places.. | 372 | // for it and for all other places.. |
364 | // Encoding should happen at one place, only ! (eilers) | 373 | // Encoding should happen at one place, only ! (eilers) |
365 | QMap<int, QString> OEvent::toMap()const { | 374 | QMap<int, QString> OEvent::toMap()const { |
366 | QMap<int, QString> retMap; | 375 | QMap<int, QString> retMap; |
367 | 376 | ||
368 | retMap.insert( OEvent::FUid, QString::number( uid() ) ); | 377 | retMap.insert( OEvent::FUid, QString::number( uid() ) ); |
369 | retMap.insert( OEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) )); | 378 | retMap.insert( OEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) )); |
370 | retMap.insert( OEvent::FDescription, Qtopia::escapeString( description() ) ); | 379 | retMap.insert( OEvent::FDescription, Qtopia::escapeString( description() ) ); |
371 | retMap.insert( OEvent::FLocation, Qtopia::escapeString( location() ) ); | 380 | retMap.insert( OEvent::FLocation, Qtopia::escapeString( location() ) ); |
372 | retMap.insert( OEvent::FType, isAllDay() ? "AllDay" : "" ); | 381 | retMap.insert( OEvent::FType, isAllDay() ? "AllDay" : "" ); |
373 | OPimAlarm alarm = notifiers().alarms()[0]; | 382 | OPimAlarm alarm = notifiers().alarms()[0]; |
374 | retMap.insert( OEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); | 383 | retMap.insert( OEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); |
375 | retMap.insert( OEvent::FSound, (alarm.sound() == OPimAlarm::Loud) ? "loud" : "silent" ); | 384 | retMap.insert( OEvent::FSound, (alarm.sound() == OPimAlarm::Loud) ? "loud" : "silent" ); |
376 | 385 | ||
377 | OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); | 386 | OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); |
378 | retMap.insert( OEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OTimeZone::utc() ) ) ) ); | 387 | 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() ) ) ) ); | 388 | retMap.insert( OEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OTimeZone::utc() ) ) ) ); |
380 | retMap.insert( OEvent::FNote, Qtopia::escapeString( note() ) ); | 389 | retMap.insert( OEvent::FNote, Qtopia::escapeString( note() ) ); |
381 | retMap.insert( OEvent::FTimeZone, timeZone().isEmpty() ? QString( "None" ) : timeZone() ); | 390 | retMap.insert( OEvent::FTimeZone, timeZone().isEmpty() ? QString( "None" ) : timeZone() ); |
382 | if( parent() ) | 391 | if( parent() ) |
383 | retMap.insert( OEvent::FRecParent, QString::number( parent() ) ); | 392 | retMap.insert( OEvent::FRecParent, QString::number( parent() ) ); |
384 | if( children().count() ){ | 393 | if( children().count() ){ |
385 | QArray<int> childr = children(); | 394 | QArray<int> childr = children(); |
386 | QString buf; | 395 | QString buf; |
387 | for ( uint i = 0; i < childr.count(); i++ ) { | 396 | for ( uint i = 0; i < childr.count(); i++ ) { |
388 | if ( i != 0 ) buf += " "; | 397 | if ( i != 0 ) buf += " "; |
389 | buf += QString::number( childr[i] ); | 398 | buf += QString::number( childr[i] ); |
390 | } | 399 | } |
391 | retMap.insert( OEvent::FRecChildren, buf ); | 400 | retMap.insert( OEvent::FRecChildren, buf ); |
392 | } | 401 | } |
393 | 402 | ||
394 | // Add recurrence stuff | 403 | // Add recurrence stuff |
395 | if( hasRecurrence() ){ | 404 | if( hasRecurrence() ){ |
396 | ORecur recur = recurrence(); | 405 | ORecur recur = recurrence(); |
397 | QMap<int, QString> recFields = recur.toMap(); | 406 | QMap<int, QString> recFields = recur.toMap(); |
398 | retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); | 407 | retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); |
399 | retMap.insert( OEvent::FRWeekdays, recFields[ORecur::RWeekdays] ); | 408 | retMap.insert( OEvent::FRWeekdays, recFields[ORecur::RWeekdays] ); |
400 | retMap.insert( OEvent::FRPosition, recFields[ORecur::RPosition] ); | 409 | retMap.insert( OEvent::FRPosition, recFields[ORecur::RPosition] ); |
401 | retMap.insert( OEvent::FRFreq, recFields[ORecur::RFreq] ); | 410 | retMap.insert( OEvent::FRFreq, recFields[ORecur::RFreq] ); |
402 | retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] ); | 411 | retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] ); |
403 | retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] ); | 412 | retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] ); |
404 | retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] ); | 413 | retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] ); |
405 | retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] ); | 414 | retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] ); |
415 | } else { | ||
416 | ORecur recur = recurrence(); | ||
417 | QMap<int, QString> recFields = recur.toMap(); | ||
418 | retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); | ||
406 | } | 419 | } |
407 | 420 | ||
408 | return retMap; | 421 | return retMap; |
409 | } | 422 | } |
410 | 423 | ||
411 | void OEvent::fromMap( const QMap<int, QString>& map ) | 424 | void OEvent::fromMap( const QMap<int, QString>& map ) |
412 | { | 425 | { |
413 | 426 | ||
414 | // We just want to set the UID if it is really stored. | 427 | // We just want to set the UID if it is really stored. |
415 | if ( !map[OEvent::FUid].isEmpty() ) | 428 | if ( !map[OEvent::FUid].isEmpty() ) |
416 | setUid( map[OEvent::FUid].toInt() ); | 429 | setUid( map[OEvent::FUid].toInt() ); |
417 | 430 | ||
418 | setCategories( idsFromString( map[OEvent::FCategories] ) ); | 431 | setCategories( idsFromString( map[OEvent::FCategories] ) ); |
419 | setDescription( map[OEvent::FDescription] ); | 432 | setDescription( map[OEvent::FDescription] ); |
420 | setLocation( map[OEvent::FLocation] ); | 433 | setLocation( map[OEvent::FLocation] ); |
421 | 434 | ||
422 | if ( map[OEvent::FType] == "AllDay" ) | 435 | if ( map[OEvent::FType] == "AllDay" ) |
423 | setAllDay( true ); | 436 | setAllDay( true ); |
424 | else | 437 | else |
425 | setAllDay( false ); | 438 | setAllDay( false ); |
426 | 439 | ||
427 | int alarmTime = -1; | 440 | int alarmTime = -1; |
428 | if( !map[OEvent::FAlarm].isEmpty() ) | 441 | if( !map[OEvent::FAlarm].isEmpty() ) |
429 | alarmTime = map[OEvent::FAlarm].toInt(); | 442 | alarmTime = map[OEvent::FAlarm].toInt(); |
430 | 443 | ||
431 | int sound = ( ( map[OEvent::FSound] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent ); | 444 | int sound = ( ( map[OEvent::FSound] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent ); |
432 | if ( ( alarmTime != -1 ) ){ | 445 | if ( ( alarmTime != -1 ) ){ |
433 | QDateTime dt = startDateTime().addSecs( -1*alarmTime*60 ); | 446 | QDateTime dt = startDateTime().addSecs( -1*alarmTime*60 ); |
434 | OPimAlarm al( sound , dt ); | 447 | OPimAlarm al( sound , dt ); |
435 | notifiers().add( al ); | 448 | notifiers().add( al ); |
436 | } | 449 | } |
437 | if ( !map[OEvent::FTimeZone].isEmpty() && ( map[OEvent::FTimeZone] != "None" ) ){ | 450 | if ( !map[OEvent::FTimeZone].isEmpty() && ( map[OEvent::FTimeZone] != "None" ) ){ |
438 | setTimeZone( map[OEvent::FTimeZone] ); | 451 | setTimeZone( map[OEvent::FTimeZone] ); |
439 | } | 452 | } |
440 | 453 | ||
441 | time_t start = (time_t) map[OEvent::FStart].toLong(); | 454 | time_t start = (time_t) map[OEvent::FStart].toLong(); |
442 | time_t end = (time_t) map[OEvent::FEnd].toLong(); | 455 | time_t end = (time_t) map[OEvent::FEnd].toLong(); |
443 | 456 | ||
444 | /* AllDay is always in UTC */ | 457 | /* AllDay is always in UTC */ |
445 | if ( isAllDay() ) { | 458 | if ( isAllDay() ) { |
446 | OTimeZone utc = OTimeZone::utc(); | 459 | OTimeZone utc = OTimeZone::utc(); |
447 | setStartDateTime( utc.fromUTCDateTime( start ) ); | 460 | setStartDateTime( utc.fromUTCDateTime( start ) ); |
448 | setEndDateTime ( utc.fromUTCDateTime( end ) ); | 461 | setEndDateTime ( utc.fromUTCDateTime( end ) ); |
449 | setTimeZone( "UTC"); // make sure it is really utc | 462 | setTimeZone( "UTC"); // make sure it is really utc |
450 | }else { | 463 | }else { |
451 | /* to current date time */ | 464 | /* to current date time */ |
452 | // qWarning(" Start is %d", start ); | 465 | // qWarning(" Start is %d", start ); |
453 | OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); | 466 | OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); |
454 | QDateTime date = zone.toDateTime( start ); | 467 | QDateTime date = zone.toDateTime( start ); |
455 | qWarning(" Start is %s", date.toString().latin1() ); | 468 | qWarning(" Start is %s", date.toString().latin1() ); |
456 | setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); | 469 | setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); |
457 | 470 | ||
458 | date = zone.toDateTime( end ); | 471 | date = zone.toDateTime( end ); |
459 | setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); | 472 | setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); |
460 | } | 473 | } |
461 | 474 | ||
462 | if ( !map[OEvent::FRecParent].isEmpty() ) | 475 | if ( !map[OEvent::FRecParent].isEmpty() ) |
463 | setParent( map[OEvent::FRecParent].toInt() ); | 476 | setParent( map[OEvent::FRecParent].toInt() ); |
464 | 477 | ||
465 | if ( !map[OEvent::FRecChildren].isEmpty() ){ | 478 | if ( !map[OEvent::FRecChildren].isEmpty() ){ |
466 | QStringList list = QStringList::split(' ', map[OEvent::FRecChildren] ); | 479 | QStringList list = QStringList::split(' ', map[OEvent::FRecChildren] ); |
467 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | 480 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { |
468 | addChild( (*it).toInt() ); | 481 | addChild( (*it).toInt() ); |
469 | } | 482 | } |
470 | } | 483 | } |
471 | 484 | ||
472 | // Fill recurrence stuff and put it directly into the ORecur-Object using fromMap.. | 485 | // Fill recurrence stuff and put it directly into the ORecur-Object using fromMap.. |
473 | if( !map[OEvent::FRType].isEmpty() ){ | 486 | if( !map[OEvent::FRType].isEmpty() ){ |
474 | QMap<int, QString> recFields; | 487 | QMap<int, QString> recFields; |
475 | recFields.insert( ORecur::RType, map[OEvent::FRType] ); | 488 | recFields.insert( ORecur::RType, map[OEvent::FRType] ); |
476 | recFields.insert( ORecur::RWeekdays, map[OEvent::FRWeekdays] ); | 489 | recFields.insert( ORecur::RWeekdays, map[OEvent::FRWeekdays] ); |
477 | recFields.insert( ORecur::RPosition, map[OEvent::FRPosition] ); | 490 | recFields.insert( ORecur::RPosition, map[OEvent::FRPosition] ); |
478 | recFields.insert( ORecur::RFreq, map[OEvent::FRFreq] ); | 491 | recFields.insert( ORecur::RFreq, map[OEvent::FRFreq] ); |
479 | recFields.insert( ORecur::RHasEndDate, map[OEvent::FRHasEndDate] ); | 492 | recFields.insert( ORecur::RHasEndDate, map[OEvent::FRHasEndDate] ); |
480 | recFields.insert( ORecur::EndDate, map[OEvent::FREndDate] ); | 493 | recFields.insert( ORecur::EndDate, map[OEvent::FREndDate] ); |
481 | recFields.insert( ORecur::Created, map[OEvent::FRCreated] ); | 494 | recFields.insert( ORecur::Created, map[OEvent::FRCreated] ); |
482 | recFields.insert( ORecur::Exceptions, map[OEvent::FRExceptions] ); | 495 | recFields.insert( ORecur::Exceptions, map[OEvent::FRExceptions] ); |
483 | ORecur recur( recFields ); | 496 | ORecur recur( recFields ); |
484 | setRecurrence( recur ); | 497 | setRecurrence( recur ); |
485 | } | 498 | } |
486 | 499 | ||
487 | } | 500 | } |
488 | 501 | ||
489 | 502 | ||
490 | int OEvent::parent()const { | 503 | int OEvent::parent()const { |
491 | return data->parent; | 504 | return data->parent; |
492 | } | 505 | } |
493 | void OEvent::setParent( int uid ) { | 506 | void OEvent::setParent( int uid ) { |
494 | changeOrModify(); | 507 | changeOrModify(); |
495 | data->parent = uid; | 508 | data->parent = uid; |
496 | } | 509 | } |
497 | QArray<int> OEvent::children() const{ | 510 | QArray<int> OEvent::children() const{ |
498 | if (!data->child) return QArray<int>(); | 511 | if (!data->child) return QArray<int>(); |
499 | else | 512 | else |
500 | return data->child->copy(); | 513 | return data->child->copy(); |
501 | } | 514 | } |
diff --git a/libopie/pim/oevent.h b/libopie/pim/oevent.h index 9218c97..9eb948f 100644 --- a/libopie/pim/oevent.h +++ b/libopie/pim/oevent.h | |||
@@ -1,174 +1,180 @@ | |||
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 | * used in the Results of toMap().. |
45 | */ | 45 | */ |
46 | enum RecordFields { | 46 | enum RecordFields { |
47 | FUid = Qtopia::UID_ID, | 47 | FUid = Qtopia::UID_ID, |
48 | FCategories = Qtopia::CATEGORY_ID, | 48 | FCategories = Qtopia::CATEGORY_ID, |
49 | FDescription = 0, | 49 | FDescription = 0, |
50 | FLocation, | 50 | FLocation, |
51 | FType, | 51 | FType, |
52 | FAlarm, | 52 | FAlarm, |
53 | FSound, | 53 | FSound, |
54 | FRType, | 54 | FRType, |
55 | FRWeekdays, | 55 | FRWeekdays, |
56 | FRPosition, | 56 | FRPosition, |
57 | FRFreq, | 57 | FRFreq, |
58 | FRHasEndDate, | 58 | FRHasEndDate, |
59 | FREndDate, | 59 | FREndDate, |
60 | FRCreated, | 60 | FRCreated, |
61 | FRExceptions, | 61 | FRExceptions, |
62 | FStart, | 62 | FStart, |
63 | FEnd, | 63 | FEnd, |
64 | FNote, | 64 | FNote, |
65 | FTimeZone, | 65 | FTimeZone, |
66 | FRecParent, | 66 | FRecParent, |
67 | FRecChildren, | 67 | FRecChildren, |
68 | }; | 68 | }; |
69 | 69 | ||
70 | /** | 70 | /** |
71 | * 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 |
72 | */ | 72 | */ |
73 | OEvent(int uid = 0); | 73 | OEvent(int uid = 0); |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * copy c'tor | 76 | * copy c'tor |
77 | */ | 77 | */ |
78 | OEvent( const OEvent& ); | 78 | OEvent( const OEvent& ); |
79 | |||
80 | /** | ||
81 | * Create OEvent, initialized by map | ||
82 | * @see enum RecordFields | ||
83 | */ | ||
84 | OEvent( const QMap<int, QString> map ); | ||
79 | ~OEvent(); | 85 | ~OEvent(); |
80 | OEvent &operator=( const OEvent& ); | 86 | OEvent &operator=( const OEvent& ); |
81 | 87 | ||
82 | QString description()const; | 88 | QString description()const; |
83 | void setDescription( const QString& description ); | 89 | void setDescription( const QString& description ); |
84 | 90 | ||
85 | QString location()const; | 91 | QString location()const; |
86 | void setLocation( const QString& loc ); | 92 | void setLocation( const QString& loc ); |
87 | 93 | ||
88 | bool hasNotifiers()const; | 94 | bool hasNotifiers()const; |
89 | OPimNotifyManager ¬ifiers()const; | 95 | OPimNotifyManager ¬ifiers()const; |
90 | 96 | ||
91 | ORecur recurrence()const; | 97 | ORecur recurrence()const; |
92 | void setRecurrence( const ORecur& ); | 98 | void setRecurrence( const ORecur& ); |
93 | bool hasRecurrence()const; | 99 | bool hasRecurrence()const; |
94 | 100 | ||
95 | QString note()const; | 101 | QString note()const; |
96 | void setNote( const QString& note ); | 102 | void setNote( const QString& note ); |
97 | 103 | ||
98 | 104 | ||
99 | QDateTime createdDateTime()const; | 105 | QDateTime createdDateTime()const; |
100 | void setCreatedDateTime( const QDateTime& dt); | 106 | void setCreatedDateTime( const QDateTime& dt); |
101 | 107 | ||
102 | /** set the date to dt. dt is the QDateTime in localtime */ | 108 | /** set the date to dt. dt is the QDateTime in localtime */ |
103 | void setStartDateTime( const QDateTime& ); | 109 | void setStartDateTime( const QDateTime& ); |
104 | /** returns the datetime in the local timeZone */ | 110 | /** returns the datetime in the local timeZone */ |
105 | QDateTime startDateTime()const; | 111 | QDateTime startDateTime()const; |
106 | 112 | ||
107 | /** returns the start datetime in the current zone */ | 113 | /** returns the start datetime in the current zone */ |
108 | QDateTime startDateTimeInZone()const; | 114 | QDateTime startDateTimeInZone()const; |
109 | 115 | ||
110 | /** in current timezone */ | 116 | /** in current timezone */ |
111 | void setEndDateTime( const QDateTime& ); | 117 | void setEndDateTime( const QDateTime& ); |
112 | /** in current timezone */ | 118 | /** in current timezone */ |
113 | QDateTime endDateTime()const; | 119 | QDateTime endDateTime()const; |
114 | QDateTime endDateTimeInZone()const; | 120 | QDateTime endDateTimeInZone()const; |
115 | 121 | ||
116 | bool isMultipleDay()const; | 122 | bool isMultipleDay()const; |
117 | bool isAllDay()const; | 123 | bool isAllDay()const; |
118 | void setAllDay( bool isAllDay ); | 124 | void setAllDay( bool isAllDay ); |
119 | 125 | ||
120 | /* pin this event to a timezone! FIXME */ | 126 | /* pin this event to a timezone! FIXME */ |
121 | void setTimeZone( const QString& timeZone ); | 127 | void setTimeZone( const QString& timeZone ); |
122 | QString timeZone()const; | 128 | QString timeZone()const; |
123 | 129 | ||
124 | 130 | ||
125 | virtual bool match( const QRegExp& )const; | 131 | virtual bool match( const QRegExp& )const; |
126 | 132 | ||
127 | /** For exception to recurrence here is a list of children... */ | 133 | /** For exception to recurrence here is a list of children... */ |
128 | QArray<int> children()const; | 134 | QArray<int> children()const; |
129 | void setChildren( const QArray<int>& ); | 135 | void setChildren( const QArray<int>& ); |
130 | void addChild( int uid ); | 136 | void addChild( int uid ); |
131 | void removeChild( int uid ); | 137 | void removeChild( int uid ); |
132 | 138 | ||
133 | /** return the parent OEvent */ | 139 | /** return the parent OEvent */ |
134 | int parent()const; | 140 | int parent()const; |
135 | void setParent( int uid ); | 141 | void setParent( int uid ); |
136 | 142 | ||
137 | 143 | ||
138 | /* needed reimp */ | 144 | /* needed reimp */ |
139 | QString toRichText()const; | 145 | QString toRichText()const; |
140 | QString toShortText()const; | 146 | QString toShortText()const; |
141 | QString type()const; | 147 | QString type()const; |
142 | 148 | ||
143 | QMap<int, QString> toMap()const; | 149 | QMap<int, QString> toMap()const; |
144 | void fromMap( const QMap<int, QString>& map ); | 150 | void fromMap( const QMap<int, QString>& map ); |
145 | QString recordField(int )const; | 151 | QString recordField(int )const; |
146 | 152 | ||
147 | static int rtti(); | 153 | static int rtti(); |
148 | 154 | ||
149 | bool loadFromStream( QDataStream& ); | 155 | bool loadFromStream( QDataStream& ); |
150 | bool saveToStream( QDataStream& )const; | 156 | bool saveToStream( QDataStream& )const; |
151 | 157 | ||
152 | /* bool operator==( const OEvent& ); | 158 | /* bool operator==( const OEvent& ); |
153 | bool operator!=( const OEvent& ); | 159 | bool operator!=( const OEvent& ); |
154 | bool operator<( const OEvent& ); | 160 | bool operator<( const OEvent& ); |
155 | bool operator<=( const OEvent& ); | 161 | bool operator<=( const OEvent& ); |
156 | bool operator>( const OEvent& ); | 162 | bool operator>( const OEvent& ); |
157 | bool operator>=(const OEvent& ); | 163 | bool operator>=(const OEvent& ); |
158 | */ | 164 | */ |
159 | private: | 165 | private: |
160 | inline void changeOrModify(); | 166 | inline void changeOrModify(); |
161 | void deref(); | 167 | void deref(); |
162 | struct Data; | 168 | struct Data; |
163 | Data* data; | 169 | Data* data; |
164 | class Private; | 170 | class Private; |
165 | Private* priv; | 171 | Private* priv; |
166 | 172 | ||
167 | }; | 173 | }; |
168 | 174 | ||
169 | /** | 175 | /** |
170 | * AN Event can span through multiple days. We split up a multiday eve | 176 | * AN Event can span through multiple days. We split up a multiday eve |
171 | */ | 177 | */ |
172 | class OEffectiveEvent { | 178 | class OEffectiveEvent { |
173 | public: | 179 | public: |
174 | typedef QValueList<OEffectiveEvent> ValueList; | 180 | typedef QValueList<OEffectiveEvent> ValueList; |
diff --git a/libopie/pim/otimezone.cpp b/libopie/pim/otimezone.cpp index b2bd3aa..34659c3 100644 --- a/libopie/pim/otimezone.cpp +++ b/libopie/pim/otimezone.cpp | |||
@@ -1,104 +1,113 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | 3 | ||
4 | #include <sys/types.h> | 4 | #include <sys/types.h> |
5 | 5 | ||
6 | #include "otimezone.h" | 6 | #include "otimezone.h" |
7 | 7 | ||
8 | namespace { | 8 | namespace { |
9 | 9 | ||
10 | QDateTime utcTime( time_t t) { | 10 | QDateTime utcTime( time_t t) { |
11 | tm* broken = ::gmtime( &t ); | 11 | tm* broken = ::gmtime( &t ); |
12 | QDateTime ret; | 12 | QDateTime ret; |
13 | ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) ); | 13 | ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) ); |
14 | ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) ); | 14 | ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) ); |
15 | return ret; | 15 | return ret; |
16 | } | 16 | } |
17 | QDateTime utcTime( time_t t, const QString& zone) { | 17 | QDateTime utcTime( time_t t, const QString& zone) { |
18 | QCString org = ::getenv( "TZ" ); | 18 | QCString org = ::getenv( "TZ" ); |
19 | #ifndef Q_OS_MACX // Following line causes bus errors on Mac | ||
19 | ::setenv( "TZ", zone.latin1(), true ); | 20 | ::setenv( "TZ", zone.latin1(), true ); |
20 | ::tzset(); | 21 | ::tzset(); |
21 | 22 | ||
22 | tm* broken = ::localtime( &t ); | 23 | tm* broken = ::localtime( &t ); |
23 | ::setenv( "TZ", org, true ); | 24 | ::setenv( "TZ", org, true ); |
25 | #else | ||
26 | #warning "Need a replacement for MacOSX!!" | ||
27 | tm* broken = ::localtime( &t ); | ||
28 | #endif | ||
24 | 29 | ||
25 | QDateTime ret; | 30 | QDateTime ret; |
26 | ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) ); | 31 | ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) ); |
27 | ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) ); | 32 | ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) ); |
28 | 33 | ||
29 | return ret; | 34 | return ret; |
30 | } | 35 | } |
31 | time_t to_Time_t( const QDateTime& utc, const QString& str ) { | 36 | time_t to_Time_t( const QDateTime& utc, const QString& str ) { |
32 | QDate d = utc.date(); | 37 | QDate d = utc.date(); |
33 | QTime t = utc.time(); | 38 | QTime t = utc.time(); |
34 | 39 | ||
35 | tm broken; | 40 | tm broken; |
36 | broken.tm_year = d.year() - 1900; | 41 | broken.tm_year = d.year() - 1900; |
37 | broken.tm_mon = d.month() - 1; | 42 | broken.tm_mon = d.month() - 1; |
38 | broken.tm_mday = d.day(); | 43 | broken.tm_mday = d.day(); |
39 | broken.tm_hour = t.hour(); | 44 | broken.tm_hour = t.hour(); |
40 | broken.tm_min = t.minute(); | 45 | broken.tm_min = t.minute(); |
41 | broken.tm_sec = t.second(); | 46 | broken.tm_sec = t.second(); |
42 | 47 | ||
43 | QCString org = ::getenv( "TZ" ); | 48 | QCString org = ::getenv( "TZ" ); |
49 | #ifndef Q_OS_MACX // Following line causes bus errors on Mac | ||
44 | ::setenv( "TZ", str.latin1(), true ); | 50 | ::setenv( "TZ", str.latin1(), true ); |
45 | ::tzset(); | 51 | ::tzset(); |
46 | 52 | ||
47 | time_t ti = ::mktime( &broken ); | 53 | time_t ti = ::mktime( &broken ); |
48 | ::setenv( "TZ", org, true ); | 54 | ::setenv( "TZ", org, true ); |
49 | 55 | #else | |
56 | #warning "Need a replacement for MacOSX!!" | ||
57 | time_t ti = ::mktime( &broken ); | ||
58 | #endif | ||
50 | return ti; | 59 | return ti; |
51 | } | 60 | } |
52 | } | 61 | } |
53 | OTimeZone::OTimeZone( const ZoneName& zone ) | 62 | OTimeZone::OTimeZone( const ZoneName& zone ) |
54 | : m_name(zone) { | 63 | : m_name(zone) { |
55 | } | 64 | } |
56 | OTimeZone::~OTimeZone() { | 65 | OTimeZone::~OTimeZone() { |
57 | } | 66 | } |
58 | 67 | ||
59 | bool OTimeZone::isValid()const { | 68 | bool OTimeZone::isValid()const { |
60 | return !m_name.isEmpty(); | 69 | return !m_name.isEmpty(); |
61 | } | 70 | } |
62 | 71 | ||
63 | /* | 72 | /* |
64 | * we will get the current timezone | 73 | * we will get the current timezone |
65 | * and ask it to convert to the timezone date | 74 | * and ask it to convert to the timezone date |
66 | */ | 75 | */ |
67 | QDateTime OTimeZone::toLocalDateTime( const QDateTime& dt) { | 76 | QDateTime OTimeZone::toLocalDateTime( const QDateTime& dt) { |
68 | return OTimeZone::current().toDateTime( dt, *this ); | 77 | return OTimeZone::current().toDateTime( dt, *this ); |
69 | } | 78 | } |
70 | QDateTime OTimeZone::toUTCDateTime( const QDateTime& dt ) { | 79 | QDateTime OTimeZone::toUTCDateTime( const QDateTime& dt ) { |
71 | return OTimeZone::utc().toDateTime( dt, *this ); | 80 | return OTimeZone::utc().toDateTime( dt, *this ); |
72 | } | 81 | } |
73 | QDateTime OTimeZone::fromUTCDateTime( time_t t) { | 82 | QDateTime OTimeZone::fromUTCDateTime( time_t t) { |
74 | return utcTime( t ); | 83 | return utcTime( t ); |
75 | } | 84 | } |
76 | QDateTime OTimeZone::toDateTime( time_t t) { | 85 | QDateTime OTimeZone::toDateTime( time_t t) { |
77 | return utcTime( t, m_name ); | 86 | return utcTime( t, m_name ); |
78 | } | 87 | } |
79 | /* | 88 | /* |
80 | * convert dt to utc using zone.m_name | 89 | * convert dt to utc using zone.m_name |
81 | * convert utc -> timeZoneDT using this->m_name | 90 | * convert utc -> timeZoneDT using this->m_name |
82 | */ | 91 | */ |
83 | QDateTime OTimeZone::toDateTime( const QDateTime& dt, const OTimeZone& zone ) { | 92 | QDateTime OTimeZone::toDateTime( const QDateTime& dt, const OTimeZone& zone ) { |
84 | time_t utc = to_Time_t( dt, zone.m_name ); | 93 | time_t utc = to_Time_t( dt, zone.m_name ); |
85 | qWarning("%d %s", utc, zone.m_name.latin1() ); | 94 | qWarning("%d %s", utc, zone.m_name.latin1() ); |
86 | return utcTime( utc, m_name ); | 95 | return utcTime( utc, m_name ); |
87 | } | 96 | } |
88 | time_t OTimeZone::fromDateTime( const QDateTime& time ) { | 97 | time_t OTimeZone::fromDateTime( const QDateTime& time ) { |
89 | return to_Time_t( time, m_name ); | 98 | return to_Time_t( time, m_name ); |
90 | } | 99 | } |
91 | time_t OTimeZone::fromUTCDateTime( const QDateTime& time ) { | 100 | time_t OTimeZone::fromUTCDateTime( const QDateTime& time ) { |
92 | return to_Time_t( time, "UTC" ); | 101 | return to_Time_t( time, "UTC" ); |
93 | } | 102 | } |
94 | OTimeZone OTimeZone::current() { | 103 | OTimeZone OTimeZone::current() { |
95 | QCString str = ::getenv("TZ"); | 104 | QCString str = ::getenv("TZ"); |
96 | OTimeZone zone( str ); | 105 | OTimeZone zone( str ); |
97 | return zone; | 106 | return zone; |
98 | } | 107 | } |
99 | OTimeZone OTimeZone::utc() { | 108 | OTimeZone OTimeZone::utc() { |
100 | return OTimeZone("UTC"); | 109 | return OTimeZone("UTC"); |
101 | } | 110 | } |
102 | QString OTimeZone::timeZone()const { | 111 | QString OTimeZone::timeZone()const { |
103 | return m_name; | 112 | return m_name; |
104 | } | 113 | } |
diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp index 75a0860..3764c7e 100644 --- a/libopie/pim/otodoaccesssql.cpp +++ b/libopie/pim/otodoaccesssql.cpp | |||
@@ -237,193 +237,193 @@ namespace { | |||
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_driver(NULL), 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 ) | 314 | if( m_driver ) |
315 | delete m_driver; | 315 | delete m_driver; |
316 | } | 316 | } |
317 | 317 | ||
318 | bool OTodoAccessBackendSQL::load(){ | 318 | bool OTodoAccessBackendSQL::load(){ |
319 | if (!m_driver->open() ) | 319 | if (!m_driver->open() ) |
320 | return false; | 320 | return false; |
321 | 321 | ||
322 | CreateQuery creat; | 322 | CreateQuery creat; |
323 | OSQLResult res = m_driver->query(&creat ); | 323 | OSQLResult res = m_driver->query(&creat ); |
324 | 324 | ||
325 | m_dirty = true; | 325 | m_dirty = true; |
326 | return true; | 326 | return true; |
327 | } | 327 | } |
328 | bool OTodoAccessBackendSQL::reload(){ | 328 | bool OTodoAccessBackendSQL::reload(){ |
329 | return load(); | 329 | return load(); |
330 | } | 330 | } |
331 | 331 | ||
332 | bool OTodoAccessBackendSQL::save(){ | 332 | bool OTodoAccessBackendSQL::save(){ |
333 | return m_driver->close(); | 333 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) |
334 | } | 334 | } |
335 | QArray<int> OTodoAccessBackendSQL::allRecords()const { | 335 | QArray<int> OTodoAccessBackendSQL::allRecords()const { |
336 | if (m_dirty ) | 336 | if (m_dirty ) |
337 | update(); | 337 | update(); |
338 | 338 | ||
339 | return m_uids; | 339 | return m_uids; |
340 | } | 340 | } |
341 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ | 341 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ |
342 | QArray<int> ints(0); | 342 | QArray<int> ints(0); |
343 | return ints; | 343 | return ints; |
344 | } | 344 | } |
345 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ | 345 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ |
346 | FindQuery query( uid ); | 346 | FindQuery query( uid ); |
347 | return todo( m_driver->query(&query) ); | 347 | return todo( m_driver->query(&query) ); |
348 | 348 | ||
349 | } | 349 | } |
350 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, | 350 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, |
351 | uint cur, Frontend::CacheDirection dir ) const{ | 351 | uint cur, Frontend::CacheDirection dir ) const{ |
352 | uint CACHE = readAhead(); | 352 | uint CACHE = readAhead(); |
353 | qWarning("searching for %d", uid ); | 353 | qWarning("searching for %d", uid ); |
354 | QArray<int> search( CACHE ); | 354 | QArray<int> search( CACHE ); |
355 | uint size =0; | 355 | uint size =0; |
356 | OTodo to; | 356 | OTodo to; |
357 | 357 | ||
358 | // we try to cache CACHE items | 358 | // we try to cache CACHE items |
359 | switch( dir ) { | 359 | switch( dir ) { |
360 | /* forward */ | 360 | /* forward */ |
361 | 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) |
362 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { | 362 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { |
363 | qWarning("size %d %d", size, ints[i] ); | 363 | qWarning("size %d %d", size, ints[i] ); |
364 | search[size] = ints[i]; | 364 | search[size] = ints[i]; |
365 | size++; | 365 | size++; |
366 | } | 366 | } |
367 | break; | 367 | break; |
368 | /* reverse */ | 368 | /* reverse */ |
369 | 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) |
370 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { | 370 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { |
371 | search[size] = ints[i]; | 371 | search[size] = ints[i]; |
372 | size++; | 372 | size++; |
373 | } | 373 | } |
374 | break; | 374 | break; |
375 | } | 375 | } |
376 | search.resize( size ); | 376 | search.resize( size ); |
377 | FindQuery query( search ); | 377 | FindQuery query( search ); |
378 | OSQLResult res = m_driver->query( &query ); | 378 | OSQLResult res = m_driver->query( &query ); |
379 | if ( res.state() != OSQLResult::Success ) | 379 | if ( res.state() != OSQLResult::Success ) |
380 | return to; | 380 | return to; |
381 | 381 | ||
382 | return todo( res ); | 382 | return todo( res ); |
383 | } | 383 | } |
384 | void OTodoAccessBackendSQL::clear() { | 384 | void OTodoAccessBackendSQL::clear() { |
385 | ClearQuery cle; | 385 | ClearQuery cle; |
386 | OSQLResult res = m_driver->query( &cle ); | 386 | OSQLResult res = m_driver->query( &cle ); |
387 | CreateQuery qu; | 387 | CreateQuery qu; |
388 | res = m_driver->query(&qu); | 388 | res = m_driver->query(&qu); |
389 | } | 389 | } |
390 | bool OTodoAccessBackendSQL::add( const OTodo& t) { | 390 | bool OTodoAccessBackendSQL::add( const OTodo& t) { |
391 | InsertQuery ins( t ); | 391 | InsertQuery ins( t ); |
392 | OSQLResult res = m_driver->query( &ins ); | 392 | OSQLResult res = m_driver->query( &ins ); |
393 | 393 | ||
394 | if ( res.state() == OSQLResult::Failure ) | 394 | if ( res.state() == OSQLResult::Failure ) |
395 | return false; | 395 | return false; |
396 | int c = m_uids.count(); | 396 | int c = m_uids.count(); |
397 | m_uids.resize( c+1 ); | 397 | m_uids.resize( c+1 ); |
398 | m_uids[c] = t.uid(); | 398 | m_uids[c] = t.uid(); |
399 | 399 | ||
400 | return true; | 400 | return true; |
401 | } | 401 | } |
402 | bool OTodoAccessBackendSQL::remove( int uid ) { | 402 | bool OTodoAccessBackendSQL::remove( int uid ) { |
403 | RemoveQuery rem( uid ); | 403 | RemoveQuery rem( uid ); |
404 | OSQLResult res = m_driver->query(&rem ); | 404 | OSQLResult res = m_driver->query(&rem ); |
405 | 405 | ||
406 | if ( res.state() == OSQLResult::Failure ) | 406 | if ( res.state() == OSQLResult::Failure ) |
407 | return false; | 407 | return false; |
408 | 408 | ||
409 | m_dirty = true; | 409 | m_dirty = true; |
410 | return true; | 410 | return true; |
411 | } | 411 | } |
412 | /* | 412 | /* |
413 | * FIXME better set query | 413 | * FIXME better set query |
414 | * but we need the cache for that | 414 | * but we need the cache for that |
415 | * now we remove | 415 | * now we remove |
416 | */ | 416 | */ |
417 | bool OTodoAccessBackendSQL::replace( const OTodo& t) { | 417 | bool OTodoAccessBackendSQL::replace( const OTodo& t) { |
418 | remove( t.uid() ); | 418 | remove( t.uid() ); |
419 | bool b= add(t); | 419 | bool b= add(t); |
420 | 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 |
421 | return b; | 421 | return b; |
422 | } | 422 | } |
423 | QArray<int> OTodoAccessBackendSQL::overDue() { | 423 | QArray<int> OTodoAccessBackendSQL::overDue() { |
424 | OverDueQuery qu; | 424 | OverDueQuery qu; |
425 | return uids( m_driver->query(&qu ) ); | 425 | return uids( m_driver->query(&qu ) ); |
426 | } | 426 | } |
427 | QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, | 427 | QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, |
428 | const QDate& t, | 428 | const QDate& t, |
429 | bool u) { | 429 | bool u) { |
diff --git a/libopie/pim/test/converter.cpp b/libopie/pim/test/converter.cpp index 650d119..bfdb605 100644 --- a/libopie/pim/test/converter.cpp +++ b/libopie/pim/test/converter.cpp | |||
@@ -1,68 +1,107 @@ | |||
1 | #include "converter.h" | 1 | #include "converter.h" |
2 | 2 | ||
3 | #include <qdatetime.h> | 3 | #include <qdatetime.h> |
4 | #include <qprogressbar.h> | 4 | #include <qprogressbar.h> |
5 | 5 | ||
6 | #include <qpe/qpeapplication.h> | 6 | #include <qpe/qpeapplication.h> |
7 | 7 | ||
8 | #include <opie/ocontactaccess.h> | 8 | #include <opie/ocontactaccess.h> |
9 | #include <opie/ocontactaccessbackend_xml.h> | 9 | #include <opie/ocontactaccessbackend_xml.h> |
10 | #include <opie/ocontactaccessbackend_sql.h> | 10 | #include <opie/ocontactaccessbackend_sql.h> |
11 | 11 | ||
12 | #include <opie/odatebookaccess.h> | ||
13 | #include <opie/odatebookaccessbackend_xml.h> | ||
14 | #include <opie/odatebookaccessbackend_sql.h> | ||
15 | |||
16 | // #define _ADDRESSBOOK_ACCESS | ||
17 | |||
12 | Converter::Converter(){ | 18 | Converter::Converter(){ |
13 | } | 19 | } |
14 | 20 | ||
15 | void Converter::start_conversion(){ | 21 | void Converter::start_conversion(){ |
16 | qWarning("Converting Contacts from XML to SQL.."); | 22 | qWarning("Converting Contacts from XML to SQL.."); |
17 | 23 | ||
18 | // Creating backends to the requested databases.. | 24 | // Creating backends to the requested databases.. |
25 | |||
26 | #ifdef _ADDRESSBOOK_ACCESS | ||
19 | OContactAccessBackend* xmlBackend = new OContactAccessBackend_XML( "Converter", | 27 | OContactAccessBackend* xmlBackend = new OContactAccessBackend_XML( "Converter", |
20 | QString::null ); | 28 | QString::null ); |
21 | 29 | ||
22 | OContactAccessBackend* sqlBackend = new OContactAccessBackend_SQL( QString::null, | 30 | OContactAccessBackend* sqlBackend = new OContactAccessBackend_SQL( QString::null, |
23 | QString::null ); | 31 | QString::null ); |
24 | // Put the created backends into frontends to access them | 32 | // Put the created backends into frontends to access them |
25 | OContactAccess* xmlAccess = new OContactAccess ( "addressbook_xml", | 33 | OContactAccess* xmlAccess = new OContactAccess ( "addressbook_xml", |
26 | QString::null , xmlBackend, true ); | 34 | QString::null , xmlBackend, true ); |
27 | 35 | ||
28 | OContactAccess* sqlAccess = new OContactAccess ( "addressbook_sql", | 36 | OContactAccess* sqlAccess = new OContactAccess ( "addressbook_sql", |
29 | QString::null , sqlBackend, true ); | 37 | QString::null ); |
30 | 38 | ||
39 | #else | ||
40 | ODateBookAccessBackend* xmlBackend = new ODateBookAccessBackend_XML( "Converter", | ||
41 | QString::null ); | ||
42 | |||
43 | ODateBookAccessBackend* sqlBackend = new ODateBookAccessBackend_SQL( QString::null, | ||
44 | QString::null ); | ||
45 | // Put the created backends into frontends to access them | ||
46 | ODateBookAccess* xmlAccess = new ODateBookAccess ( xmlBackend ); | ||
47 | |||
48 | ODateBookAccess* sqlAccess = new ODateBookAccess ( sqlBackend ); | ||
49 | |||
50 | xmlAccess->load(); | ||
51 | |||
52 | #endif | ||
53 | |||
31 | QTime t; | 54 | QTime t; |
32 | t.start(); | 55 | t.start(); |
33 | 56 | ||
34 | // Clean the sql-database.. | 57 | // Clean the sql-database.. |
35 | sqlAccess->clear(); | 58 | sqlAccess->clear(); |
36 | 59 | ||
60 | #ifdef _ADDRESSBOOK_ACCESS | ||
37 | // Now trasmit every contact from the xml database to the sql-database | 61 | // Now trasmit every contact from the xml database to the sql-database |
38 | OContactAccess::List contactList = xmlAccess->allRecords(); | 62 | OContactAccess::List contactList = xmlAccess->allRecords(); |
39 | m_progressBar->setTotalSteps( contactList.count() ); | 63 | m_progressBar->setTotalSteps( contactList.count() ); |
40 | int count = 0; | 64 | int count = 0; |
41 | if ( sqlAccess && xmlAccess ){ | 65 | if ( sqlAccess && xmlAccess ){ |
42 | OContactAccess::List::Iterator it; | 66 | OContactAccess::List::Iterator it; |
43 | for ( it = contactList.begin(); it != contactList.end(); ++it ){ | 67 | for ( it = contactList.begin(); it != contactList.end(); ++it ){ |
44 | sqlAccess->add( *it ); | 68 | sqlAccess->add( *it ); |
45 | m_progressBar->setProgress( ++count ); | 69 | m_progressBar->setProgress( ++count ); |
46 | } | 70 | } |
47 | } | 71 | } |
48 | 72 | #else | |
73 | // Now transmit every contact from the xml database to the sql-database | ||
74 | ODateBookAccess::List dateList = xmlAccess->allRecords(); | ||
75 | m_progressBar->setTotalSteps( dateList.count() ); | ||
76 | qWarning( "Number of elements to copy: %d", dateList.count() ); | ||
77 | |||
78 | int count = 0; | ||
79 | if ( sqlAccess && xmlAccess ){ | ||
80 | ODateBookAccess::List::Iterator it; | ||
81 | for ( it = dateList.begin(); it != dateList.end(); ++it ){ | ||
82 | sqlAccess->add( *it ); | ||
83 | m_progressBar->setProgress( ++count ); | ||
84 | } | ||
85 | } | ||
86 | |||
87 | #endif | ||
49 | // Delete the frontends. Backends will be deleted automatically, too ! | 88 | // Delete the frontends. Backends will be deleted automatically, too ! |
50 | delete sqlAccess; | 89 | delete sqlAccess; |
51 | 90 | ||
52 | qWarning("Conversion is finished and needed %d ms !", t.elapsed()); | 91 | qWarning("Conversion is finished and needed %d ms !", t.elapsed()); |
53 | 92 | ||
54 | delete xmlAccess; | 93 | delete xmlAccess; |
55 | } | 94 | } |
56 | 95 | ||
57 | int main( int argc, char** argv ) { | 96 | int main( int argc, char** argv ) { |
58 | 97 | ||
59 | QPEApplication a( argc, argv ); | 98 | QPEApplication a( argc, argv ); |
60 | 99 | ||
61 | Converter dlg; | 100 | Converter dlg; |
62 | 101 | ||
63 | a.showMainWidget( &dlg ); | 102 | a.showMainWidget( &dlg ); |
64 | // dlg. showMaximized ( ); | 103 | // dlg. showMaximized ( ); |
65 | 104 | ||
66 | return a.exec(); | 105 | return a.exec(); |
67 | 106 | ||
68 | } | 107 | } |
diff --git a/libopie/pim/test/converter.h b/libopie/pim/test/converter.h new file mode 100755 index 0000000..1cc2a7c --- a/dev/null +++ b/libopie/pim/test/converter.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef _CONVERTER_H_ | ||
2 | #define _CONVERTER_H_ | ||
3 | |||
4 | |||
5 | #include "converter_base.h" | ||
6 | |||
7 | |||
8 | class Converter: public converter_base { | ||
9 | public: | ||
10 | Converter(); | ||
11 | |||
12 | void start_conversion(); | ||
13 | private: | ||
14 | |||
15 | }; | ||
16 | |||
17 | |||
18 | #endif | ||
diff --git a/libopie/pim/test/converter.pro b/libopie/pim/test/converter.pro index aa74bff..bd9c7a3 100644 --- a/libopie/pim/test/converter.pro +++ b/libopie/pim/test/converter.pro | |||
@@ -1,12 +1,12 @@ | |||
1 | TEMPLATE= app | 1 | # TEMPLATE= app |
2 | CONFIG = qt warn_on debug | 2 | CONFIG = qt warn_on debug |
3 | # CONFIG = qt warn_on release | 3 | # CONFIG = qt warn_on release |
4 | #HEADERS = | 4 | #HEADERS = |
5 | SOURCES = converter.cpp | 5 | SOURCES = converter.cpp |
6 | INTERFACES = converter_base.ui | 6 | INTERFACES = converter_base.ui |
7 | INCLUDEPATH+= $(OPIEDIR)/include | 7 | INCLUDEPATH+= $(OPIEDIR)/include |
8 | DEPENDPATH+= $(OPIEDIR)/include | 8 | DEPENDPATH+= $(OPIEDIR)/include |
9 | LIBS += -lqpe -lopie | 9 | LIBS += -lqpe -lopie |
10 | TARGET = converter | 10 | TARGET = converter |
11 | 11 | ||
12 | include ( $(OPIEDIR)/include.pro ) | 12 | include ( $(OPIEDIR)/include.pro ) |