summaryrefslogtreecommitdiff
path: root/libopie/pim
authoreilers <eilers>2003-12-22 10:19:25 (UTC)
committer eilers <eilers>2003-12-22 10:19:25 (UTC)
commitae70312b1613e26b4ef89a2c9821d9531b82e987 (patch) (unidiff)
tree7eb70bc45ee29e94da27a18b0136eb4a14e59fa6 /libopie/pim
parent9e7aafdb7c76d29fee742d53131a73dd60aded2b (diff)
downloadopie-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..
Diffstat (limited to 'libopie/pim') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/obackendfactory.h24
-rw-r--r--libopie/pim/ocontactaccess.h14
-rw-r--r--libopie/pim/ocontactaccessbackend_sql.cpp18
-rw-r--r--libopie/pim/odatebookaccess.cpp19
-rw-r--r--libopie/pim/odatebookaccess.h9
-rw-r--r--libopie/pim/odatebookaccessbackend.cpp34
-rw-r--r--libopie/pim/odatebookaccessbackend.h19
-rw-r--r--libopie/pim/odatebookaccessbackend_sql.cpp231
-rw-r--r--libopie/pim/odatebookaccessbackend_sql.h2
-rw-r--r--libopie/pim/oevent.cpp13
-rw-r--r--libopie/pim/oevent.h6
-rw-r--r--libopie/pim/otimezone.cpp11
-rw-r--r--libopie/pim/otodoaccesssql.cpp2
-rw-r--r--libopie/pim/test/converter.cpp45
-rwxr-xr-xlibopie/pim/test/converter.h18
-rw-r--r--libopie/pim/test/converter.pro2
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
85class OBackendPrivate; 98class 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 */
102template<class T> 115template<class T>
103class OBackendFactory 116class 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,181 +1,193 @@
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 */
84class OContactAccess: public QObject, public OPimAccessTemplate<OContact> 96class 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;
178 Private *d; 190 Private *d;
179 191
180}; 192};
181#endif 193#endif
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,208 +1,220 @@
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 */
72namespace { 84namespace {
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();
113 QString query()const; 125 QString query()const;
114 private: 126 private:
115 OContact m_contact; 127 OContact m_contact;
116 }; 128 };
117 129
118 130
119 /** 131 /**
120 * removes one from the table 132 * removes one from the table
121 */ 133 */
122 class RemoveQuery : public OSQLQuery { 134 class RemoveQuery : public OSQLQuery {
123 public: 135 public:
124 RemoveQuery(int uid ); 136 RemoveQuery(int uid );
125 ~RemoveQuery(); 137 ~RemoveQuery();
126 QString query()const; 138 QString query()const;
127 private: 139 private:
128 int m_uid; 140 int m_uid;
129 }; 141 };
130 142
131 /** 143 /**
132 * a find query for noncustom elements 144 * a find query for noncustom elements
133 */ 145 */
134 class FindQuery : public OSQLQuery { 146 class FindQuery : public OSQLQuery {
135 public: 147 public:
136 FindQuery(int uid); 148 FindQuery(int uid);
137 FindQuery(const QArray<int>& ); 149 FindQuery(const QArray<int>& );
138 ~FindQuery(); 150 ~FindQuery();
139 QString query()const; 151 QString query()const;
140 private: 152 private:
141 QString single()const; 153 QString single()const;
142 QString multi()const; 154 QString multi()const;
143 QArray<int> m_uids; 155 QArray<int> m_uids;
144 int m_uid; 156 int m_uid;
145 }; 157 };
146 158
147 /** 159 /**
148 * a find query for custom elements 160 * a find query for custom elements
149 */ 161 */
150 class FindCustomQuery : public OSQLQuery { 162 class FindCustomQuery : public OSQLQuery {
151 public: 163 public:
152 FindCustomQuery(int uid); 164 FindCustomQuery(int uid);
153 FindCustomQuery(const QArray<int>& ); 165 FindCustomQuery(const QArray<int>& );
154 ~FindCustomQuery(); 166 ~FindCustomQuery();
155 QString query()const; 167 QString query()const;
156 private: 168 private:
157 QString single()const; 169 QString single()const;
158 QString multi()const; 170 QString multi()const;
159 QArray<int> m_uids; 171 QArray<int> m_uids;
160 int m_uid; 172 int m_uid;
161 }; 173 };
162 174
163 175
164 176
165 // We using three tables to store the information: 177 // We using three tables to store the information:
166 // 1. addressbook : It contains General information about the contact (non custom) 178 // 1. addressbook : It contains General information about the contact (non custom)
167 // 2. custom_data : Not official supported entries 179 // 2. custom_data : Not official supported entries
168 // All tables are connected by the uid of the contact. 180 // All tables are connected by the uid of the contact.
169 // Maybe I should add a table for meta-information ? 181 // Maybe I should add a table for meta-information ?
170 CreateQuery::CreateQuery() : OSQLQuery() {} 182 CreateQuery::CreateQuery() : OSQLQuery() {}
171 CreateQuery::~CreateQuery() {} 183 CreateQuery::~CreateQuery() {}
172 QString CreateQuery::query()const { 184 QString CreateQuery::query()const {
173 QString qu; 185 QString qu;
174#ifdef __STORE_HORIZONTAL_ 186#ifdef __STORE_HORIZONTAL_
175 187
176 qu += "create table addressbook( uid PRIMARY KEY "; 188 qu += "create table addressbook( uid PRIMARY KEY ";
177 189
178 QStringList fieldList = OContactFields::untrfields( false ); 190 QStringList fieldList = OContactFields::untrfields( false );
179 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 191 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
180 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); 192 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it );
181 } 193 }
182 qu += " );"; 194 qu += " );";
183 195
184 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; 196 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
185 197
186#else 198#else
187 199
188 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));"; 200 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));";
189 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; 201 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
190 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );"; 202 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );";
191 203
192#endif // __STORE_HORIZONTAL_ 204#endif // __STORE_HORIZONTAL_
193 return qu; 205 return qu;
194 } 206 }
195 207
196 ClearQuery::ClearQuery() 208 ClearQuery::ClearQuery()
197 : OSQLQuery() {} 209 : OSQLQuery() {}
198 ClearQuery::~ClearQuery() {} 210 ClearQuery::~ClearQuery() {}
199 QString ClearQuery::query()const { 211 QString ClearQuery::query()const {
200 QString qu = "drop table addressbook;"; 212 QString qu = "drop table addressbook;";
201 qu += "drop table custom_data;"; 213 qu += "drop table custom_data;";
202 // qu += "drop table dates;"; 214 // qu += "drop table dates;";
203 return qu; 215 return qu;
204 } 216 }
205 217
206 218
207 LoadQuery::LoadQuery() : OSQLQuery() {} 219 LoadQuery::LoadQuery() : OSQLQuery() {}
208 LoadQuery::~LoadQuery() {} 220 LoadQuery::~LoadQuery() {}
@@ -321,394 +333,394 @@ namespace {
321 .arg( day.day() ) ); 333 .arg( day.day() ) );
322 } 334 }
323 break; 335 break;
324 case Qtopia::AddressUid: // Ignore UID 336 case Qtopia::AddressUid: // Ignore UID
325 break; 337 break;
326 default: // Translate id to String 338 default: // Translate id to String
327 addressbook_db.insert( transMap[it.key()], it.data() ); 339 addressbook_db.insert( transMap[it.key()], it.data() );
328 break; 340 break;
329 } 341 }
330 342
331 } 343 }
332 344
333 // Now convert this whole stuff into a SQL String, beginning with 345 // Now convert this whole stuff into a SQL String, beginning with
334 // the addressbook table.. 346 // the addressbook table..
335 QString qu; 347 QString qu;
336 // qu += "begin transaction;"; 348 // qu += "begin transaction;";
337 int id = 0; 349 int id = 0;
338 for( QMap<QString, QString>::Iterator it = addressbook_db.begin(); 350 for( QMap<QString, QString>::Iterator it = addressbook_db.begin();
339 it != addressbook_db.end(); ++it ){ 351 it != addressbook_db.end(); ++it ){
340 qu += "insert into addressbook VALUES(" 352 qu += "insert into addressbook VALUES("
341 + QString::number( m_contact.uid() ) 353 + QString::number( m_contact.uid() )
342 + "," 354 + ","
343 + QString::number( id++ ) 355 + QString::number( id++ )
344 + ",'" 356 + ",'"
345 + it.key() //.latin1() 357 + it.key() //.latin1()
346 + "'," 358 + "',"
347 + "0" // Priority for future enhancements 359 + "0" // Priority for future enhancements
348 + ",'" 360 + ",'"
349 + it.data() //.latin1() 361 + it.data() //.latin1()
350 + "');"; 362 + "');";
351 } 363 }
352 364
353 #endif //__STORE_HORIZONTAL_ 365 #endif //__STORE_HORIZONTAL_
354 // Now add custom data.. 366 // Now add custom data..
355#ifdef __STORE_HORIZONTAL_ 367#ifdef __STORE_HORIZONTAL_
356 int id = 0; 368 int id = 0;
357#endif 369#endif
358 id = 0; 370 id = 0;
359 QMap<QString, QString> customMap = m_contact.toExtraMap(); 371 QMap<QString, QString> customMap = m_contact.toExtraMap();
360 for( QMap<QString, QString>::Iterator it = customMap.begin(); 372 for( QMap<QString, QString>::Iterator it = customMap.begin();
361 it != customMap.end(); ++it ){ 373 it != customMap.end(); ++it ){
362 qu += "insert into custom_data VALUES(" 374 qu += "insert into custom_data VALUES("
363 + QString::number( m_contact.uid() ) 375 + QString::number( m_contact.uid() )
364 + "," 376 + ","
365 + QString::number( id++ ) 377 + QString::number( id++ )
366 + ",'" 378 + ",'"
367 + it.key() //.latin1() 379 + it.key() //.latin1()
368 + "'," 380 + "',"
369 + "0" // Priority for future enhancements 381 + "0" // Priority for future enhancements
370 + ",'" 382 + ",'"
371 + it.data() //.latin1() 383 + it.data() //.latin1()
372 + "');"; 384 + "');";
373 } 385 }
374 // qu += "commit;"; 386 // qu += "commit;";
375 qWarning("add %s", qu.latin1() ); 387 qWarning("add %s", qu.latin1() );
376 return qu; 388 return qu;
377 } 389 }
378 390
379 391
380 RemoveQuery::RemoveQuery(int uid ) 392 RemoveQuery::RemoveQuery(int uid )
381 : OSQLQuery(), m_uid( uid ) {} 393 : OSQLQuery(), m_uid( uid ) {}
382 RemoveQuery::~RemoveQuery() {} 394 RemoveQuery::~RemoveQuery() {}
383 QString RemoveQuery::query()const { 395 QString RemoveQuery::query()const {
384 QString qu = "DELETE from addressbook where uid = " 396 QString qu = "DELETE from addressbook where uid = "
385 + QString::number(m_uid) + ";"; 397 + QString::number(m_uid) + ";";
386 qu += "DELETE from custom_data where uid = " 398 qu += "DELETE from custom_data where uid = "
387 + QString::number(m_uid) + ";"; 399 + QString::number(m_uid) + ";";
388 return qu; 400 return qu;
389 } 401 }
390 402
391 403
392 404
393 405
394 FindQuery::FindQuery(int uid) 406 FindQuery::FindQuery(int uid)
395 : OSQLQuery(), m_uid( uid ) { 407 : OSQLQuery(), m_uid( uid ) {
396 } 408 }
397 FindQuery::FindQuery(const QArray<int>& ints) 409 FindQuery::FindQuery(const QArray<int>& ints)
398 : OSQLQuery(), m_uids( ints ){ 410 : OSQLQuery(), m_uids( ints ){
399 } 411 }
400 FindQuery::~FindQuery() { 412 FindQuery::~FindQuery() {
401 } 413 }
402 QString FindQuery::query()const{ 414 QString FindQuery::query()const{
403 // if ( m_uids.count() == 0 ) 415 // if ( m_uids.count() == 0 )
404 return single(); 416 return single();
405 } 417 }
406 /* 418 /*
407 else 419 else
408 return multi(); 420 return multi();
409 } 421 }
410 QString FindQuery::multi()const { 422 QString FindQuery::multi()const {
411 QString qu = "select uid, type, value from addressbook where"; 423 QString qu = "select uid, type, value from addressbook where";
412 for (uint i = 0; i < m_uids.count(); i++ ) { 424 for (uint i = 0; i < m_uids.count(); i++ ) {
413 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 425 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
414 } 426 }
415 qu.remove( qu.length()-2, 2 ); // Hmmmm.. 427 qu.remove( qu.length()-2, 2 ); // Hmmmm..
416 return qu; 428 return qu;
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
459OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, 471OContactAccessBackend_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
483OContactAccessBackend_SQL::~OContactAccessBackend_SQL () 495OContactAccessBackend_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
489bool OContactAccessBackend_SQL::load () 501bool 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
506bool OContactAccessBackend_SQL::reload() 518bool OContactAccessBackend_SQL::reload()
507{ 519{
508 return load(); 520 return load();
509} 521}
510 522
511bool OContactAccessBackend_SQL::save() 523bool 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
517void OContactAccessBackend_SQL::clear () 529void 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
525bool OContactAccessBackend_SQL::wasChangedExternally() 537bool OContactAccessBackend_SQL::wasChangedExternally()
526{ 538{
527 return false; 539 return false;
528} 540}
529 541
530QArray<int> OContactAccessBackend_SQL::allRecords() const 542QArray<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
541bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) 553bool 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
557bool OContactAccessBackend_SQL::remove ( int uid ) 569bool 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
570bool OContactAccessBackend_SQL::replace ( const OContact &contact ) 582bool 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
579OContact OContactAccessBackend_SQL::find ( int uid ) const 591OContact 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
594QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ) 606QArray<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 " + "'"
619 + queryStr + "'" + ") AND "; 631 + queryStr + "'" + ") AND ";
620 632
621 } 633 }
622 } 634 }
623 } 635 }
624 // Skip trailing "AND" 636 // Skip trailing "AND"
625 if ( isAnyFieldSelected ) 637 if ( isAnyFieldSelected )
626 qu = qu.left( qu.length() - 4 ); 638 qu = qu.left( qu.length() - 4 );
627 639
628 qWarning( "queryByExample query: %s", qu.latin1() ); 640 qWarning( "queryByExample query: %s", qu.latin1() );
629 641
630 // Execute query and return the received uid's 642 // Execute query and return the received uid's
631 OSQLRawQuery raw( qu ); 643 OSQLRawQuery raw( qu );
632 OSQLResult res = m_driver->query( &raw ); 644 OSQLResult res = m_driver->query( &raw );
633 if ( res.state() != OSQLResult::Success ){ 645 if ( res.state() != OSQLResult::Success ){
634 QArray<int> empty; 646 QArray<int> empty;
635 return empty; 647 return empty;
636 } 648 }
637 649
638 QArray<int> list = extractUids( res ); 650 QArray<int> list = extractUids( res );
639 651
640 return list; 652 return list;
641} 653}
642 654
643QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 655QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
644{ 656{
645 QArray<int> nix(0); 657 QArray<int> nix(0);
646 return nix; 658 return nix;
647} 659}
648 660
649const uint OContactAccessBackend_SQL::querySettings() 661const uint OContactAccessBackend_SQL::querySettings()
650{ 662{
651 return OContactAccess::IgnoreCase 663 return OContactAccess::IgnoreCase
652 || OContactAccess::WildCards; 664 || OContactAccess::WildCards;
653} 665}
654 666
655bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const 667bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
656{ 668{
657 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 669 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
658 * may be added with any of the other settings. IgnoreCase should never used alone. 670 * may be added with any of the other settings. IgnoreCase should never used alone.
659 * Wildcards, RegExp, ExactMatch should never used at the same time... 671 * Wildcards, RegExp, ExactMatch should never used at the same time...
660 */ 672 */
661 673
662 // Step 1: Check whether the given settings are supported by this backend 674 // Step 1: Check whether the given settings are supported by this backend
663 if ( ( querySettings & ( 675 if ( ( querySettings & (
664 OContactAccess::IgnoreCase 676 OContactAccess::IgnoreCase
665 | OContactAccess::WildCards 677 | OContactAccess::WildCards
666 // | OContactAccess::DateDiff 678 // | OContactAccess::DateDiff
667 // | OContactAccess::DateYear 679 // | OContactAccess::DateYear
668 // | OContactAccess::DateMonth 680 // | OContactAccess::DateMonth
669 // | OContactAccess::DateDay 681 // | OContactAccess::DateDay
670 // | OContactAccess::RegExp 682 // | OContactAccess::RegExp
671 // | OContactAccess::ExactMatch 683 // | OContactAccess::ExactMatch
672 ) ) != querySettings ) 684 ) ) != querySettings )
673 return false; 685 return false;
674 686
675 // Step 2: Check whether the given combinations are ok.. 687 // Step 2: Check whether the given combinations are ok..
676 688
677 // IngoreCase alone is invalid 689 // IngoreCase alone is invalid
678 if ( querySettings == OContactAccess::IgnoreCase ) 690 if ( querySettings == OContactAccess::IgnoreCase )
679 return false; 691 return false;
680 692
681 // WildCards, RegExp and ExactMatch should never used at the same time 693 // WildCards, RegExp and ExactMatch should never used at the same time
682 switch ( querySettings & ~( OContactAccess::IgnoreCase 694 switch ( querySettings & ~( OContactAccess::IgnoreCase
683 | OContactAccess::DateDiff 695 | OContactAccess::DateDiff
684 | OContactAccess::DateYear 696 | OContactAccess::DateYear
685 | OContactAccess::DateMonth 697 | OContactAccess::DateMonth
686 | OContactAccess::DateDay 698 | OContactAccess::DateDay
687 ) 699 )
688 ){ 700 ){
689 case OContactAccess::RegExp: 701 case OContactAccess::RegExp:
690 return ( true ); 702 return ( true );
691 case OContactAccess::WildCards: 703 case OContactAccess::WildCards:
692 return ( true ); 704 return ( true );
693 case OContactAccess::ExactMatch: 705 case OContactAccess::ExactMatch:
694 return ( true ); 706 return ( true );
695 case 0: // one of the upper removed bits were set.. 707 case 0: // one of the upper removed bits were set..
696 return ( true ); 708 return ( true );
697 default: 709 default:
698 return ( false ); 710 return ( false );
699 } 711 }
700 712
701} 713}
702 714
703QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int ) 715QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int )
704{ 716{
705 QTime t; 717 QTime t;
706 t.start(); 718 t.start();
707 719
708#ifdef __STORE_HORIZONTAL_ 720#ifdef __STORE_HORIZONTAL_
709 QString query = "SELECT uid FROM addressbook "; 721 QString query = "SELECT uid FROM addressbook ";
710 query += "ORDER BY \"Last Name\" "; 722 query += "ORDER BY \"Last Name\" ";
711#else 723#else
712 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' "; 724 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' ";
713 query += "ORDER BY upper( value )"; 725 query += "ORDER BY upper( value )";
714#endif 726#endif
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 */
11ODateBookAccess::ODateBookAccess( ODateBookAccessBackend* back, enum Access ac ) 11ODateBookAccess::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}
20ODateBookAccess::~ODateBookAccess() { 20ODateBookAccess::~ODateBookAccess() {
21} 21}
22 22
23/** 23/**
24 * @return all events available 24 * @return all events available
25 */ 25 */
26ODateBookAccess::List ODateBookAccess::rawEvents()const { 26ODateBookAccess::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 */
36ODateBookAccess::List ODateBookAccess::rawRepeats()const { 36ODateBookAccess::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 */
46ODateBookAccess::List ODateBookAccess::nonRepeats()const { 46ODateBookAccess::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 */
58OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDate& from, const QDate& to ) { 58OEffectiveEvent::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 */
64OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDateTime& start ) { 64OEffectiveEvent::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 */
73OEffectiveEvent::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 */
79OEffectiveEvent::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 */
18class ODateBookAccess : public OPimAccessTemplate<OEvent> { 18class ODateBookAccess : public OPimAccessTemplate<OEvent> {
19public: 19public:
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
35private: 38private:
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
@@ -1,156 +1,182 @@
1#include <qtl.h> 1#include <qtl.h>
2 2
3#include "orecur.h" 3#include "orecur.h"
4 4
5#include "odatebookaccessbackend.h" 5#include "odatebookaccessbackend.h"
6 6
7namespace { 7namespace {
8/* a small helper to get all NonRepeating events for a range of time */ 8/* a small helper to get all NonRepeating events for a range of time */
9 void events( OEffectiveEvent::ValueList& tmpList, const OEvent::ValueList& events, 9 void events( OEffectiveEvent::ValueList& tmpList, const OEvent::ValueList& events,
10 const QDate& from, const QDate& to ) { 10 const QDate& from, const QDate& to ) {
11 QDateTime dtStart, dtEnd; 11 QDateTime dtStart, dtEnd;
12 12
13 for ( OEvent::ValueList::ConstIterator it = events.begin(); it != events.end(); ++it ) { 13 for ( OEvent::ValueList::ConstIterator it = events.begin(); it != events.end(); ++it ) {
14 dtStart = (*it).startDateTime(); 14 dtStart = (*it).startDateTime();
15 dtEnd = (*it).endDateTime(); 15 dtEnd = (*it).endDateTime();
16 16
17 /* 17 /*
18 * If in range 18 * If in range
19 */ 19 */
20 if (dtStart.date() >= from && dtEnd.date() <= to ) { 20 if (dtStart.date() >= from && dtEnd.date() <= to ) {
21 OEffectiveEvent eff; 21 OEffectiveEvent eff;
22 eff.setEvent( (*it) ); 22 eff.setEvent( (*it) );
23 eff.setDate( dtStart.date() ); 23 eff.setDate( dtStart.date() );
24 eff.setStartTime( dtStart.time() ); 24 eff.setStartTime( dtStart.time() );
25 25
26 /* if not on the same day */ 26 /* if not on the same day */
27 if ( dtStart.date() != dtEnd.date() ) 27 if ( dtStart.date() != dtEnd.date() )
28 eff.setEndTime( QTime(23, 59, 0 ) ); 28 eff.setEndTime( QTime(23, 59, 0 ) );
29 else 29 else
30 eff.setEndTime( dtEnd.time() ); 30 eff.setEndTime( dtEnd.time() );
31 31
32 tmpList.append( eff ); 32 tmpList.append( eff );
33 } 33 }
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
122ODateBookAccessBackend::ODateBookAccessBackend() 122ODateBookAccessBackend::ODateBookAccessBackend()
123 : OPimAccessBackend<OEvent>() 123 : OPimAccessBackend<OEvent>()
124{ 124{
125 125
126} 126}
127ODateBookAccessBackend::~ODateBookAccessBackend() { 127ODateBookAccessBackend::~ODateBookAccessBackend() {
128 128
129} 129}
130OEffectiveEvent::ValueList ODateBookAccessBackend::effecticeEvents( const QDate& from, 130OEffectiveEvent::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}
143OEffectiveEvent::ValueList ODateBookAccessBackend::effecticeEvents( const QDateTime& dt ) { 143OEffectiveEvent::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
158OEffectiveEvent::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
169OEffectiveEvent::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 */
14class ODateBookAccessBackend : public OPimAccessBackend<OEvent> { 14class ODateBookAccessBackend : public OPimAccessBackend<OEvent> {
15public: 15public:
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
71private: 84private:
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
37namespace { 47#include "orecur.h"
38 48#include "odatebookaccessbackend_sql.h"
39 49
40 50
41};
42 51
43ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , 52ODateBookAccessBackend_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
59ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { 68ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() {
69 if( m_driver )
70 delete m_driver;
60} 71}
61 72
62void ODateBookAccessBackend_SQL::initFields() 73void 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
90bool ODateBookAccessBackend_SQL::load() 108bool 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
118void ODateBookAccessBackend_SQL::update() 138void 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
133QArray<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
152bool ODateBookAccessBackend_SQL::reload() 153bool ODateBookAccessBackend_SQL::reload()
153{ 154{
154 return load(); 155 return load();
155} 156}
156 157
157bool ODateBookAccessBackend_SQL::save() 158bool 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
162QArray<int> ODateBookAccessBackend_SQL::allRecords()const 163QArray<int> ODateBookAccessBackend_SQL::allRecords()const
163{ 164{
164 return m_uids; 165 return m_uids;
165} 166}
166 167
167QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) { 168QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) {
168 return QArray<int>(); 169 return QArray<int>();
169} 170}
170 171
171void ODateBookAccessBackend_SQL::clear() 172void 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
182OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ 184OEvent 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
185bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) { 209bool 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}
188bool ODateBookAccessBackend_SQL::remove( int uid ) {
189 250
190 return true; 251bool 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}
192bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) { 266
267bool 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}
196QArray<int> ODateBookAccessBackend_SQL::rawEvents()const { 272
273QArray<int> ODateBookAccessBackend_SQL::rawEvents()const
274{
197 return allRecords(); 275 return allRecords();
198} 276}
199QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const {
200 277
201 return ints; 278QArray<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}
203QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const {
204 290
205 return ints; 291QArray<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}
207OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() {
208 303
209 return list; 304OEvent::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}
211OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() { 316OEvent::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
217QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 329QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
218{ 330{
331 QArray<int> null;
332 return null;
333}
334
335/* ===== Private Functions ========================================== */
336
337QArray<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
8class OSQLDriver; 9class 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 */
16class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { 17class ODateBookAccessBackend_SQL : public ODateBookAccessBackend {
17public: 18public:
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
42private: 43private:
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,597 +1,610 @@
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
14int OCalendarHelper::week( const QDate& date) { 14int 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}
26int OCalendarHelper::ocurrence( const QDate& date) { 26int 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}
31int OCalendarHelper::dayOfWeek( char day ) { 31int 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}
40int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { 40int 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
45struct OEvent::Data : public QShared { 45struct 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
71OEvent::OEvent( int uid ) 71OEvent::OEvent( int uid )
72 : OPimRecord( uid ) { 72 : OPimRecord( uid ) {
73 data = new Data; 73 data = new Data;
74} 74}
75OEvent::OEvent( const OEvent& ev) 75OEvent::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
81OEvent::OEvent( const QMap<int, QString> map )
82 : OPimRecord( 0 )
83{
84 data = new Data;
85
86 fromMap( map );
87}
88
80OEvent::~OEvent() { 89OEvent::~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}
86OEvent& OEvent::operator=( const OEvent& ev) { 95OEvent& 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}
97QString OEvent::description()const { 106QString OEvent::description()const {
98 return data->description; 107 return data->description;
99} 108}
100void OEvent::setDescription( const QString& description ) { 109void OEvent::setDescription( const QString& description ) {
101 changeOrModify(); 110 changeOrModify();
102 data->description = description; 111 data->description = description;
103} 112}
104void OEvent::setLocation( const QString& loc ) { 113void OEvent::setLocation( const QString& loc ) {
105 changeOrModify(); 114 changeOrModify();
106 data->location = loc; 115 data->location = loc;
107} 116}
108QString OEvent::location()const { 117QString OEvent::location()const {
109 return data->location; 118 return data->location;
110} 119}
111OPimNotifyManager &OEvent::notifiers()const { 120OPimNotifyManager &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}
120bool OEvent::hasNotifiers()const { 129bool 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}
129ORecur OEvent::recurrence()const { 138ORecur 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}
135void OEvent::setRecurrence( const ORecur& rec) { 144void 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}
142bool OEvent::hasRecurrence()const { 151bool 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}
146QString OEvent::note()const { 155QString OEvent::note()const {
147 return data->note; 156 return data->note;
148} 157}
149void OEvent::setNote( const QString& note ) { 158void OEvent::setNote( const QString& note ) {
150 changeOrModify(); 159 changeOrModify();
151 data->note = note; 160 data->note = note;
152} 161}
153QDateTime OEvent::createdDateTime()const { 162QDateTime OEvent::createdDateTime()const {
154 return data->created; 163 return data->created;
155} 164}
156void OEvent::setCreatedDateTime( const QDateTime& time ) { 165void OEvent::setCreatedDateTime( const QDateTime& time ) {
157 changeOrModify(); 166 changeOrModify();
158 data->created = time; 167 data->created = time;
159} 168}
160QDateTime OEvent::startDateTime()const { 169QDateTime 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}
165QDateTime OEvent::startDateTimeInZone()const { 174QDateTime 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}
172void OEvent::setStartDateTime( const QDateTime& dt ) { 181void OEvent::setStartDateTime( const QDateTime& dt ) {
173 changeOrModify(); 182 changeOrModify();
174 data->start = dt; 183 data->start = dt;
175} 184}
176QDateTime OEvent::endDateTime()const { 185QDateTime OEvent::endDateTime()const {
177 /* 186 /*
178 * if all Day event the end time needs 187 * if all Day event the end time needs
179 * to be on the same day as the start 188 * to be on the same day as the start
180 */ 189 */
181 if ( data->isAllDay ) 190 if ( data->isAllDay )
182 return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); 191 return QDateTime( data->start.date(), QTime(23, 59, 59 ) );
183 return data->end; 192 return data->end;
184} 193}
185QDateTime OEvent::endDateTimeInZone()const { 194QDateTime OEvent::endDateTimeInZone()const {
186 /* if no timezone, or all day event or if the current and this timeZone match... */ 195 /* if no timezone, or all day event or if the current and this timeZone match... */
187 if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); 196 if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime();
188 197
189 OTimeZone zone(data->timezone ); 198 OTimeZone zone(data->timezone );
190 return zone.toDateTime( data->end, OTimeZone::current() ); 199 return zone.toDateTime( data->end, OTimeZone::current() );
191} 200}
192void OEvent::setEndDateTime( const QDateTime& dt ) { 201void OEvent::setEndDateTime( const QDateTime& dt ) {
193 changeOrModify(); 202 changeOrModify();
194 data->end = dt; 203 data->end = dt;
195} 204}
196bool OEvent::isMultipleDay()const { 205bool OEvent::isMultipleDay()const {
197 return data->end.date().day() - data->start.date().day(); 206 return data->end.date().day() - data->start.date().day();
198} 207}
199bool OEvent::isAllDay()const { 208bool OEvent::isAllDay()const {
200 return data->isAllDay; 209 return data->isAllDay;
201} 210}
202void OEvent::setAllDay( bool allDay ) { 211void OEvent::setAllDay( bool allDay ) {
203 changeOrModify(); 212 changeOrModify();
204 data->isAllDay = allDay; 213 data->isAllDay = allDay;
205 if (allDay ) data->timezone = "UTC"; 214 if (allDay ) data->timezone = "UTC";
206} 215}
207void OEvent::setTimeZone( const QString& tz ) { 216void OEvent::setTimeZone( const QString& tz ) {
208 changeOrModify(); 217 changeOrModify();
209 data->timezone = tz; 218 data->timezone = tz;
210} 219}
211QString OEvent::timeZone()const { 220QString OEvent::timeZone()const {
212 if (data->isAllDay ) return QString::fromLatin1("UTC"); 221 if (data->isAllDay ) return QString::fromLatin1("UTC");
213 return data->timezone; 222 return data->timezone;
214} 223}
215bool OEvent::match( const QRegExp& re )const { 224bool OEvent::match( const QRegExp& re )const {
216 if ( re.match( data->description ) != -1 ){ 225 if ( re.match( data->description ) != -1 ){
217 setLastHitField( Qtopia::DatebookDescription ); 226 setLastHitField( Qtopia::DatebookDescription );
218 return true; 227 return true;
219 } 228 }
220 if ( re.match( data->note ) != -1 ){ 229 if ( re.match( data->note ) != -1 ){
221 setLastHitField( Qtopia::Note ); 230 setLastHitField( Qtopia::Note );
222 return true; 231 return true;
223 } 232 }
224 if ( re.match( data->location ) != -1 ){ 233 if ( re.match( data->location ) != -1 ){
225 setLastHitField( Qtopia::Location ); 234 setLastHitField( Qtopia::Location );
226 return true; 235 return true;
227 } 236 }
228 if ( re.match( data->start.toString() ) != -1 ){ 237 if ( re.match( data->start.toString() ) != -1 ){
229 setLastHitField( Qtopia::StartDateTime ); 238 setLastHitField( Qtopia::StartDateTime );
230 return true; 239 return true;
231 } 240 }
232 if ( re.match( data->end.toString() ) != -1 ){ 241 if ( re.match( data->end.toString() ) != -1 ){
233 setLastHitField( Qtopia::EndDateTime ); 242 setLastHitField( Qtopia::EndDateTime );
234 return true; 243 return true;
235 } 244 }
236 return false; 245 return false;
237} 246}
238QString OEvent::toRichText()const { 247QString OEvent::toRichText()const {
239 QString text, value; 248 QString text, value;
240 249
241 // description 250 // description
242 text += "<b><h3><img src=\"datebook/DateBook\">"; 251 text += "<b><h3><img src=\"datebook/DateBook\">";
243 if ( !description().isEmpty() ) { 252 if ( !description().isEmpty() ) {
244 text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "" ); 253 text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "" );
245 } 254 }
246 text += "</h3></b><br><hr><br>"; 255 text += "</h3></b><br><hr><br>";
247 256
248 // location 257 // location
249 if ( !(value = location()).isEmpty() ) { 258 if ( !(value = location()).isEmpty() ) {
250 text += "<b>" + QObject::tr( "Location:" ) + "</b> "; 259 text += "<b>" + QObject::tr( "Location:" ) + "</b> ";
251 text += Qtopia::escapeString(value) + "<br>"; 260 text += Qtopia::escapeString(value) + "<br>";
252 } 261 }
253 262
254 // all day event 263 // all day event
255 if ( isAllDay() ) { 264 if ( isAllDay() ) {
256 text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>"; 265 text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>";
257 } 266 }
258 // multiple day event 267 // multiple day event
259 else if ( isMultipleDay () ) { 268 else if ( isMultipleDay () ) {
260 text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>"; 269 text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>";
261 } 270 }
262 // start & end times 271 // start & end times
263 else { 272 else {
264 // start time 273 // start time
265 if ( startDateTime().isValid() ) { 274 if ( startDateTime().isValid() ) {
266 text += "<b>" + QObject::tr( "Start:") + "</b> "; 275 text += "<b>" + QObject::tr( "Start:") + "</b> ";
267 text += Qtopia::escapeString(startDateTime().toString() ). 276 text += Qtopia::escapeString(startDateTime().toString() ).
268 replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; 277 replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
269 } 278 }
270 279
271 // end time 280 // end time
272 if ( endDateTime().isValid() ) { 281 if ( endDateTime().isValid() ) {
273 text += "<b>" + QObject::tr( "End:") + "</b> "; 282 text += "<b>" + QObject::tr( "End:") + "</b> ";
274 text += Qtopia::escapeString(endDateTime().toString() ). 283 text += Qtopia::escapeString(endDateTime().toString() ).
275 replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; 284 replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
276 } 285 }
277 } 286 }
278 287
279 // categories 288 // categories
280 if ( categoryNames("Calendar").count() ){ 289 if ( categoryNames("Calendar").count() ){
281 text += "<b>" + QObject::tr( "Category:") + "</b> "; 290 text += "<b>" + QObject::tr( "Category:") + "</b> ";
282 text += categoryNames("Calendar").join(", "); 291 text += categoryNames("Calendar").join(", ");
283 text += "<br>"; 292 text += "<br>";
284 } 293 }
285 294
286 //notes 295 //notes
287 if ( !note().isEmpty() ) { 296 if ( !note().isEmpty() ) {
288 text += "<b>" + QObject::tr( "Note:") + "</b><br>"; 297 text += "<b>" + QObject::tr( "Note:") + "</b><br>";
289 text += note(); 298 text += note();
290// text += Qtopia::escapeString(note() ). 299// text += Qtopia::escapeString(note() ).
291// replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; 300// replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
292 } 301 }
293 return text; 302 return text;
294} 303}
295QString OEvent::toShortText()const { 304QString OEvent::toShortText()const {
296 QString text; 305 QString text;
297 text += QString::number( startDateTime().date().day() ); 306 text += QString::number( startDateTime().date().day() );
298 text += "."; 307 text += ".";
299 text += QString::number( startDateTime().date().month() ); 308 text += QString::number( startDateTime().date().month() );
300 text += "."; 309 text += ".";
301 text += QString::number( startDateTime().date().year() ); 310 text += QString::number( startDateTime().date().year() );
302 text += " "; 311 text += " ";
303 text += QString::number( startDateTime().time().hour() ); 312 text += QString::number( startDateTime().time().hour() );
304 text += ":"; 313 text += ":";
305 text += QString::number( startDateTime().time().minute() ); 314 text += QString::number( startDateTime().time().minute() );
306 text += " - "; 315 text += " - ";
307 text += description(); 316 text += description();
308 return text; 317 return text;
309} 318}
310QString OEvent::type()const { 319QString OEvent::type()const {
311 return QString::fromLatin1("OEvent"); 320 return QString::fromLatin1("OEvent");
312} 321}
313QString OEvent::recordField( int /*id */ )const { 322QString OEvent::recordField( int /*id */ )const {
314 return QString::null; 323 return QString::null;
315} 324}
316int OEvent::rtti() { 325int OEvent::rtti() {
317 return OPimResolver::DateBook; 326 return OPimResolver::DateBook;
318} 327}
319bool OEvent::loadFromStream( QDataStream& ) { 328bool OEvent::loadFromStream( QDataStream& ) {
320 return true; 329 return true;
321} 330}
322bool OEvent::saveToStream( QDataStream& )const { 331bool OEvent::saveToStream( QDataStream& )const {
323 return true; 332 return true;
324} 333}
325void OEvent::changeOrModify() { 334void 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}
354void OEvent::deref() { 363void 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)
365QMap<int, QString> OEvent::toMap()const { 374QMap<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
411void OEvent::fromMap( const QMap<int, QString>& map ) 424void 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
490int OEvent::parent()const { 503int OEvent::parent()const {
491 return data->parent; 504 return data->parent;
492} 505}
493void OEvent::setParent( int uid ) { 506void OEvent::setParent( int uid ) {
494 changeOrModify(); 507 changeOrModify();
495 data->parent = uid; 508 data->parent = uid;
496} 509}
497QArray<int> OEvent::children() const{ 510QArray<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}
502void OEvent::setChildren( const QArray<int>& arr ) { 515void OEvent::setChildren( const QArray<int>& arr ) {
503 changeOrModify(); 516 changeOrModify();
504 if (data->child) delete data->child; 517 if (data->child) delete data->child;
505 518
506 data->child = new QArray<int>( arr ); 519 data->child = new QArray<int>( arr );
507 data->child->detach(); 520 data->child->detach();
508} 521}
509void OEvent::addChild( int uid ) { 522void OEvent::addChild( int uid ) {
510 changeOrModify(); 523 changeOrModify();
511 if (!data->child ) { 524 if (!data->child ) {
512 data->child = new QArray<int>(1); 525 data->child = new QArray<int>(1);
513 (*data->child)[0] = uid; 526 (*data->child)[0] = uid;
514 }else{ 527 }else{
515 int count = data->child->count(); 528 int count = data->child->count();
516 data->child->resize( count + 1 ); 529 data->child->resize( count + 1 );
517 (*data->child)[count] = uid; 530 (*data->child)[count] = uid;
518 } 531 }
519} 532}
520void OEvent::removeChild( int uid ) { 533void OEvent::removeChild( int uid ) {
521 if (!data->child || !data->child->contains( uid ) ) return; 534 if (!data->child || !data->child->contains( uid ) ) return;
522 changeOrModify(); 535 changeOrModify();
523 QArray<int> newAr( data->child->count() - 1 ); 536 QArray<int> newAr( data->child->count() - 1 );
524 int j = 0; 537 int j = 0;
525 uint count = data->child->count(); 538 uint count = data->child->count();
526 for ( uint i = 0; i < count; i++ ) { 539 for ( uint i = 0; i < count; i++ ) {
527 if ( (*data->child)[i] != uid ) { 540 if ( (*data->child)[i] != uid ) {
528 newAr[j] = (*data->child)[i]; 541 newAr[j] = (*data->child)[i];
529 j++; 542 j++;
530 } 543 }
531 } 544 }
532 (*data->child) = newAr; 545 (*data->child) = newAr;
533} 546}
534struct OEffectiveEvent::Data : public QShared { 547struct OEffectiveEvent::Data : public QShared {
535 Data() : QShared() { 548 Data() : QShared() {
536 } 549 }
537 OEvent event; 550 OEvent event;
538 QDate date; 551 QDate date;
539 QTime start, end; 552 QTime start, end;
540 QDate startDate, endDate; 553 QDate startDate, endDate;
541 bool dates : 1; 554 bool dates : 1;
542}; 555};
543 556
544OEffectiveEvent::OEffectiveEvent() { 557OEffectiveEvent::OEffectiveEvent() {
545 data = new Data; 558 data = new Data;
546 data->date = QDate::currentDate(); 559 data->date = QDate::currentDate();
547 data->start = data->end = QTime::currentTime(); 560 data->start = data->end = QTime::currentTime();
548 data->dates = false; 561 data->dates = false;
549} 562}
550OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, 563OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate,
551 Position pos ) { 564 Position pos ) {
552 data = new Data; 565 data = new Data;
553 data->event = ev; 566 data->event = ev;
554 data->date = startDate; 567 data->date = startDate;
555 if ( pos & Start ) 568 if ( pos & Start )
556 data->start = ev.startDateTime().time(); 569 data->start = ev.startDateTime().time();
557 else 570 else
558 data->start = QTime( 0, 0, 0 ); 571 data->start = QTime( 0, 0, 0 );
559 572
560 if ( pos & End ) 573 if ( pos & End )
561 data->end = ev.endDateTime().time(); 574 data->end = ev.endDateTime().time();
562 else 575 else
563 data->end = QTime( 23, 59, 59 ); 576 data->end = QTime( 23, 59, 59 );
564 577
565 data->dates = false; 578 data->dates = false;
566} 579}
567OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { 580OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) {
568 data = ev.data; 581 data = ev.data;
569 data->ref(); 582 data->ref();
570} 583}
571OEffectiveEvent::~OEffectiveEvent() { 584OEffectiveEvent::~OEffectiveEvent() {
572 if ( data->deref() ) { 585 if ( data->deref() ) {
573 delete data; 586 delete data;
574 data = 0; 587 data = 0;
575 } 588 }
576} 589}
577OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { 590OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) {
578 if ( *this == ev ) return *this; 591 if ( *this == ev ) return *this;
579 592
580 ev.data->ref(); 593 ev.data->ref();
581 deref(); 594 deref();
582 data = ev.data; 595 data = ev.data;
583 596
584 return *this; 597 return *this;
585} 598}
586 599
587void OEffectiveEvent::setStartTime( const QTime& ti) { 600void OEffectiveEvent::setStartTime( const QTime& ti) {
588 changeOrModify(); 601 changeOrModify();
589 data->start = ti; 602 data->start = ti;
590} 603}
591void OEffectiveEvent::setEndTime( const QTime& en) { 604void OEffectiveEvent::setEndTime( const QTime& en) {
592 changeOrModify(); 605 changeOrModify();
593 data->end = en; 606 data->end = en;
594} 607}
595void OEffectiveEvent::setEvent( const OEvent& ev) { 608void OEffectiveEvent::setEvent( const OEvent& ev) {
596 changeOrModify(); 609 changeOrModify();
597 data->event = ev; 610 data->event = ev;
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,230 +1,236 @@
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
16struct OCalendarHelper { 16struct 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
31class OPimNotifyManager; 31class OPimNotifyManager;
32class ORecur; 32class 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 */
39class OEvent : public OPimRecord { 39class OEvent : public OPimRecord {
40public: 40public:
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 &notifiers()const; 95 OPimNotifyManager &notifiers()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*/
159private: 165private:
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 */
172class OEffectiveEvent { 178class OEffectiveEvent {
173public: 179public:
174 typedef QValueList<OEffectiveEvent> ValueList; 180 typedef QValueList<OEffectiveEvent> ValueList;
175 enum Position { MidWay, Start, End, StartEnd }; 181 enum Position { MidWay, Start, End, StartEnd };
176 // If we calculate the effective event of a multi-day event 182 // If we calculate the effective event of a multi-day event
177 // we have to figure out whether we are at the first day, 183 // we have to figure out whether we are at the first day,
178 // at the end, or anywhere else ("middle"). This is important 184 // at the end, or anywhere else ("middle"). This is important
179 // for the start/end times (00:00/23:59) 185 // for the start/end times (00:00/23:59)
180 // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- 186 // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi-
181 // day event 187 // day event
182 // Start: start time -> 23:59 188 // Start: start time -> 23:59
183 // End: 00:00 -> end time 189 // End: 00:00 -> end time
184 // Start | End == StartEnd: for single-day events (default) 190 // Start | End == StartEnd: for single-day events (default)
185 // here we draw start time -> end time 191 // here we draw start time -> end time
186 OEffectiveEvent(); 192 OEffectiveEvent();
187 OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); 193 OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd );
188 OEffectiveEvent( const OEffectiveEvent& ); 194 OEffectiveEvent( const OEffectiveEvent& );
189 OEffectiveEvent &operator=(const OEffectiveEvent& ); 195 OEffectiveEvent &operator=(const OEffectiveEvent& );
190 ~OEffectiveEvent(); 196 ~OEffectiveEvent();
191 197
192 void setStartTime( const QTime& ); 198 void setStartTime( const QTime& );
193 void setEndTime( const QTime& ); 199 void setEndTime( const QTime& );
194 void setEvent( const OEvent& ); 200 void setEvent( const OEvent& );
195 void setDate( const QDate& ); 201 void setDate( const QDate& );
196 202
197 void setEffectiveDates( const QDate& from, const QDate& to ); 203 void setEffectiveDates( const QDate& from, const QDate& to );
198 204
199 QString description()const; 205 QString description()const;
200 QString location()const; 206 QString location()const;
201 QString note()const; 207 QString note()const;
202 OEvent event()const; 208 OEvent event()const;
203 QTime startTime()const; 209 QTime startTime()const;
204 QTime endTime()const; 210 QTime endTime()const;
205 QDate date()const; 211 QDate date()const;
206 212
207 /* return the length in hours */ 213 /* return the length in hours */
208 int length()const; 214 int length()const;
209 int size()const; 215 int size()const;
210 216
211 QDate startDate()const; 217 QDate startDate()const;
212 QDate endDate()const; 218 QDate endDate()const;
213 219
214 bool operator<( const OEffectiveEvent &e ) const; 220 bool operator<( const OEffectiveEvent &e ) const;
215 bool operator<=( const OEffectiveEvent &e ) const; 221 bool operator<=( const OEffectiveEvent &e ) const;
216 bool operator==( const OEffectiveEvent &e ) const; 222 bool operator==( const OEffectiveEvent &e ) const;
217 bool operator!=( const OEffectiveEvent &e ) const; 223 bool operator!=( const OEffectiveEvent &e ) const;
218 bool operator>( const OEffectiveEvent &e ) const; 224 bool operator>( const OEffectiveEvent &e ) const;
219 bool operator>= ( const OEffectiveEvent &e ) const; 225 bool operator>= ( const OEffectiveEvent &e ) const;
220 226
221private: 227private:
222 void deref(); 228 void deref();
223 inline void changeOrModify(); 229 inline void changeOrModify();
224 class Private; 230 class Private;
225 Private* priv; 231 Private* priv;
226 struct Data; 232 struct Data;
227 Data* data; 233 Data* data;
228 234
229}; 235};
230#endif 236#endif
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
8namespace { 8namespace {
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}
53OTimeZone::OTimeZone( const ZoneName& zone ) 62OTimeZone::OTimeZone( const ZoneName& zone )
54 : m_name(zone) { 63 : m_name(zone) {
55} 64}
56OTimeZone::~OTimeZone() { 65OTimeZone::~OTimeZone() {
57} 66}
58 67
59bool OTimeZone::isValid()const { 68bool 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 */
67QDateTime OTimeZone::toLocalDateTime( const QDateTime& dt) { 76QDateTime OTimeZone::toLocalDateTime( const QDateTime& dt) {
68 return OTimeZone::current().toDateTime( dt, *this ); 77 return OTimeZone::current().toDateTime( dt, *this );
69} 78}
70QDateTime OTimeZone::toUTCDateTime( const QDateTime& dt ) { 79QDateTime OTimeZone::toUTCDateTime( const QDateTime& dt ) {
71 return OTimeZone::utc().toDateTime( dt, *this ); 80 return OTimeZone::utc().toDateTime( dt, *this );
72} 81}
73QDateTime OTimeZone::fromUTCDateTime( time_t t) { 82QDateTime OTimeZone::fromUTCDateTime( time_t t) {
74 return utcTime( t ); 83 return utcTime( t );
75} 84}
76QDateTime OTimeZone::toDateTime( time_t t) { 85QDateTime 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 */
83QDateTime OTimeZone::toDateTime( const QDateTime& dt, const OTimeZone& zone ) { 92QDateTime 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}
88time_t OTimeZone::fromDateTime( const QDateTime& time ) { 97time_t OTimeZone::fromDateTime( const QDateTime& time ) {
89 return to_Time_t( time, m_name ); 98 return to_Time_t( time, m_name );
90} 99}
91time_t OTimeZone::fromUTCDateTime( const QDateTime& time ) { 100time_t OTimeZone::fromUTCDateTime( const QDateTime& time ) {
92 return to_Time_t( time, "UTC" ); 101 return to_Time_t( time, "UTC" );
93} 102}
94OTimeZone OTimeZone::current() { 103OTimeZone 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}
99OTimeZone OTimeZone::utc() { 108OTimeZone OTimeZone::utc() {
100 return OTimeZone("UTC"); 109 return OTimeZone("UTC");
101} 110}
102QString OTimeZone::timeZone()const { 111QString 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
@@ -141,385 +141,385 @@ namespace {
141 return qu; 141 return qu;
142 } 142 }
143 143
144 InsertQuery::InsertQuery( const OTodo& todo ) 144 InsertQuery::InsertQuery( const OTodo& todo )
145 : OSQLQuery(), m_todo( todo ) { 145 : OSQLQuery(), m_todo( todo ) {
146 } 146 }
147 InsertQuery::~InsertQuery() { 147 InsertQuery::~InsertQuery() {
148 } 148 }
149 /* 149 /*
150 * converts from a OTodo to a query 150 * converts from a OTodo to a query
151 * we leave out X-Ref + Alarms 151 * we leave out X-Ref + Alarms
152 */ 152 */
153 QString InsertQuery::query()const{ 153 QString InsertQuery::query()const{
154 154
155 int year, month, day; 155 int year, month, day;
156 year = month = day = 0; 156 year = month = day = 0;
157 if (m_todo.hasDueDate() ) { 157 if (m_todo.hasDueDate() ) {
158 QDate date = m_todo.dueDate(); 158 QDate date = m_todo.dueDate();
159 year = date.year(); 159 year = date.year();
160 month = date.month(); 160 month = date.month();
161 day = date.day(); 161 day = date.day();
162 } 162 }
163 int sYear = 0, sMonth = 0, sDay = 0; 163 int sYear = 0, sMonth = 0, sDay = 0;
164 if( m_todo.hasStartDate() ){ 164 if( m_todo.hasStartDate() ){
165 QDate sDate = m_todo.startDate(); 165 QDate sDate = m_todo.startDate();
166 sYear = sDate.year(); 166 sYear = sDate.year();
167 sMonth= sDate.month(); 167 sMonth= sDate.month();
168 sDay = sDate.day(); 168 sDay = sDate.day();
169 } 169 }
170 170
171 int eYear = 0, eMonth = 0, eDay = 0; 171 int eYear = 0, eMonth = 0, eDay = 0;
172 if( m_todo.hasCompletedDate() ){ 172 if( m_todo.hasCompletedDate() ){
173 QDate eDate = m_todo.completedDate(); 173 QDate eDate = m_todo.completedDate();
174 eYear = eDate.year(); 174 eYear = eDate.year();
175 eMonth= eDate.month(); 175 eMonth= eDate.month();
176 eDay = eDate.day(); 176 eDay = eDate.day();
177 } 177 }
178 QString qu; 178 QString qu;
179 QMap<int, QString> recMap = m_todo.recurrence().toMap(); 179 QMap<int, QString> recMap = m_todo.recurrence().toMap();
180 qu = "insert into todolist VALUES(" 180 qu = "insert into todolist VALUES("
181 + QString::number( m_todo.uid() ) + "," 181 + QString::number( m_todo.uid() ) + ","
182 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," 182 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + ","
183 + QString::number( m_todo.isCompleted() ) + "," 183 + QString::number( m_todo.isCompleted() ) + ","
184 + "'" + m_todo.description() + "'" + "," 184 + "'" + m_todo.description() + "'" + ","
185 + "'" + m_todo.summary() + "'" + "," 185 + "'" + m_todo.summary() + "'" + ","
186 + QString::number(m_todo.priority() ) + "," 186 + QString::number(m_todo.priority() ) + ","
187 + "'" + QString::number(year) + "-" 187 + "'" + QString::number(year) + "-"
188 + QString::number(month) 188 + QString::number(month)
189 + "-" + QString::number( day ) + "'" + "," 189 + "-" + QString::number( day ) + "'" + ","
190 + QString::number( m_todo.progress() ) + "," 190 + QString::number( m_todo.progress() ) + ","
191 + QString::number( m_todo.state().state() ) + "," 191 + QString::number( m_todo.state().state() ) + ","
192 + "'" + recMap[ ORecur::RType ] + "'" + "," 192 + "'" + recMap[ ORecur::RType ] + "'" + ","
193 + "'" + recMap[ ORecur::RWeekdays ] + "'" + "," 193 + "'" + recMap[ ORecur::RWeekdays ] + "'" + ","
194 + "'" + recMap[ ORecur::RPosition ] + "'" + "," 194 + "'" + recMap[ ORecur::RPosition ] + "'" + ","
195 + "'" + recMap[ ORecur::RFreq ] + "'" + "," 195 + "'" + recMap[ ORecur::RFreq ] + "'" + ","
196 + "'" + recMap[ ORecur::RHasEndDate ] + "'" + "," 196 + "'" + recMap[ ORecur::RHasEndDate ] + "'" + ","
197 + "'" + recMap[ ORecur::EndDate ] + "'" + "," 197 + "'" + recMap[ ORecur::EndDate ] + "'" + ","
198 + "'" + recMap[ ORecur::Created ] + "'" + "," 198 + "'" + recMap[ ORecur::Created ] + "'" + ","
199 + "'" + recMap[ ORecur::Exceptions ] + "'" + ","; 199 + "'" + recMap[ ORecur::Exceptions ] + "'" + ",";
200 200
201 if ( m_todo.hasNotifiers() ) { 201 if ( m_todo.hasNotifiers() ) {
202 OPimNotifyManager manager = m_todo.notifiers(); 202 OPimNotifyManager manager = m_todo.notifiers();
203 qu += "'" + manager.remindersToString() + "'" + "," 203 qu += "'" + manager.remindersToString() + "'" + ","
204 + "'" + manager.alarmsToString() + "'" + ","; 204 + "'" + manager.alarmsToString() + "'" + ",";
205 } 205 }
206 else{ 206 else{
207 qu += QString( "''" ) + "," 207 qu += QString( "''" ) + ","
208 + "''" + ","; 208 + "''" + ",";
209 } 209 }
210 210
211 qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) 211 qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !)
212 + "'" + QString::number(sYear) + "-" 212 + "'" + QString::number(sYear) + "-"
213 + QString::number(sMonth) 213 + QString::number(sMonth)
214 + "-" + QString::number(sDay) + "'" + "," 214 + "-" + QString::number(sDay) + "'" + ","
215 + "'" + QString::number(eYear) + "-" 215 + "'" + QString::number(eYear) + "-"
216 + QString::number(eMonth) 216 + QString::number(eMonth)
217 + "-"+QString::number(eDay) + "'" 217 + "-"+QString::number(eDay) + "'"
218 + ")"; 218 + ")";
219 219
220 qWarning("add %s", qu.latin1() ); 220 qWarning("add %s", qu.latin1() );
221 return qu; 221 return qu;
222 } 222 }
223 223
224 RemoveQuery::RemoveQuery(int uid ) 224 RemoveQuery::RemoveQuery(int uid )
225 : OSQLQuery(), m_uid( uid ) {} 225 : OSQLQuery(), m_uid( uid ) {}
226 RemoveQuery::~RemoveQuery() {} 226 RemoveQuery::~RemoveQuery() {}
227 QString RemoveQuery::query()const { 227 QString RemoveQuery::query()const {
228 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); 228 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid);
229 return qu; 229 return qu;
230 } 230 }
231 231
232 232
233 ClearQuery::ClearQuery() 233 ClearQuery::ClearQuery()
234 : OSQLQuery() {} 234 : OSQLQuery() {}
235 ClearQuery::~ClearQuery() {} 235 ClearQuery::~ClearQuery() {}
236 QString ClearQuery::query()const { 236 QString ClearQuery::query()const {
237 QString qu = "drop table todolist"; 237 QString qu = "drop table todolist";
238 return qu; 238 return qu;
239 } 239 }
240 FindQuery::FindQuery(int uid) 240 FindQuery::FindQuery(int uid)
241 : OSQLQuery(), m_uid(uid ) { 241 : OSQLQuery(), m_uid(uid ) {
242 } 242 }
243 FindQuery::FindQuery(const QArray<int>& ints) 243 FindQuery::FindQuery(const QArray<int>& ints)
244 : OSQLQuery(), m_uids(ints){ 244 : OSQLQuery(), m_uids(ints){
245 } 245 }
246 FindQuery::~FindQuery() { 246 FindQuery::~FindQuery() {
247 } 247 }
248 QString FindQuery::query()const{ 248 QString FindQuery::query()const{
249 if (m_uids.count() == 0 ) 249 if (m_uids.count() == 0 )
250 return single(); 250 return single();
251 else 251 else
252 return multi(); 252 return multi();
253 } 253 }
254 QString FindQuery::single()const{ 254 QString FindQuery::single()const{
255 QString qu = "select * from todolist where uid = " + QString::number(m_uid); 255 QString qu = "select * from todolist where uid = " + QString::number(m_uid);
256 return qu; 256 return qu;
257 } 257 }
258 QString FindQuery::multi()const { 258 QString FindQuery::multi()const {
259 QString qu = "select * from todolist where "; 259 QString qu = "select * from todolist where ";
260 for (uint i = 0; i < m_uids.count(); i++ ) { 260 for (uint i = 0; i < m_uids.count(); i++ ) {
261 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 261 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
262 } 262 }
263 qu.remove( qu.length()-2, 2 ); 263 qu.remove( qu.length()-2, 2 );
264 return qu; 264 return qu;
265 } 265 }
266 266
267 OverDueQuery::OverDueQuery(): OSQLQuery() {} 267 OverDueQuery::OverDueQuery(): OSQLQuery() {}
268 OverDueQuery::~OverDueQuery() {} 268 OverDueQuery::~OverDueQuery() {}
269 QString OverDueQuery::query()const { 269 QString OverDueQuery::query()const {
270 QDate date = QDate::currentDate(); 270 QDate date = QDate::currentDate();
271 QString str; 271 QString str;
272 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); 272 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() );
273 273
274 return str; 274 return str;
275 } 275 }
276 276
277 277
278 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) 278 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc )
279 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} 279 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {}
280 EffQuery::~EffQuery() {} 280 EffQuery::~EffQuery() {}
281 QString EffQuery::query()const { 281 QString EffQuery::query()const {
282 return m_inc ? with() : out(); 282 return m_inc ? with() : out();
283 } 283 }
284 QString EffQuery::with()const { 284 QString EffQuery::with()const {
285 QString str; 285 QString str;
286 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") 286 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ")
287 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) 287 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() )
288 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); 288 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() );
289 return str; 289 return str;
290 } 290 }
291 QString EffQuery::out()const { 291 QString EffQuery::out()const {
292 QString str; 292 QString str;
293 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") 293 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'")
294 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) 294 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() )
295 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); 295 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() );
296 296
297 return str; 297 return str;
298 } 298 }
299}; 299};
300 300
301OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) 301OTodoAccessBackendSQL::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
313OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ 313OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){
314 if( m_driver ) 314 if( m_driver )
315 delete m_driver; 315 delete m_driver;
316} 316}
317 317
318bool OTodoAccessBackendSQL::load(){ 318bool 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}
328bool OTodoAccessBackendSQL::reload(){ 328bool OTodoAccessBackendSQL::reload(){
329 return load(); 329 return load();
330} 330}
331 331
332bool OTodoAccessBackendSQL::save(){ 332bool OTodoAccessBackendSQL::save(){
333 return m_driver->close(); 333 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
334} 334}
335QArray<int> OTodoAccessBackendSQL::allRecords()const { 335QArray<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}
341QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ 341QArray<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}
345OTodo OTodoAccessBackendSQL::find(int uid ) const{ 345OTodo 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}
350OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, 350OTodo 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}
384void OTodoAccessBackendSQL::clear() { 384void 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}
390bool OTodoAccessBackendSQL::add( const OTodo& t) { 390bool 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}
402bool OTodoAccessBackendSQL::remove( int uid ) { 402bool 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 */
417bool OTodoAccessBackendSQL::replace( const OTodo& t) { 417bool 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}
423QArray<int> OTodoAccessBackendSQL::overDue() { 423QArray<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}
427QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, 427QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s,
428 const QDate& t, 428 const QDate& t,
429 bool u) { 429 bool u) {
430 EffQuery ef(s, t, u ); 430 EffQuery ef(s, t, u );
431 return uids (m_driver->query(&ef) ); 431 return uids (m_driver->query(&ef) );
432} 432}
433/* 433/*
434 * 434 *
435 */ 435 */
436QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, 436QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
437 int sortFilter, int cat ) { 437 int sortFilter, int cat ) {
438 qWarning("sorted %d, %d", asc, sortOrder ); 438 qWarning("sorted %d, %d", asc, sortOrder );
439 QString query; 439 QString query;
440 query = "select uid from todolist WHERE "; 440 query = "select uid from todolist WHERE ";
441 441
442 /* 442 /*
443 * Sort Filter stuff 443 * Sort Filter stuff
444 * not that straight forward 444 * not that straight forward
445 * FIXME: Replace magic numbers 445 * FIXME: Replace magic numbers
446 * 446 *
447 */ 447 */
448 /* Category */ 448 /* Category */
449 if ( sortFilter & 1 ) { 449 if ( sortFilter & 1 ) {
450 QString str; 450 QString str;
451 if (cat != 0 ) str = QString::number( cat ); 451 if (cat != 0 ) str = QString::number( cat );
452 query += " categories like '%" +str+"%' AND"; 452 query += " categories like '%" +str+"%' AND";
453 } 453 }
454 /* Show only overdue */ 454 /* Show only overdue */
455 if ( sortFilter & 2 ) { 455 if ( sortFilter & 2 ) {
456 QDate date = QDate::currentDate(); 456 QDate date = QDate::currentDate();
457 QString due; 457 QString due;
458 QString base; 458 QString base;
459 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); 459 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() );
460 query += " " + base + " AND"; 460 query += " " + base + " AND";
461 } 461 }
462 /* not show completed */ 462 /* not show completed */
463 if ( sortFilter & 4 ) { 463 if ( sortFilter & 4 ) {
464 query += " completed = 0 AND"; 464 query += " completed = 0 AND";
465 }else{ 465 }else{
466 query += " ( completed = 1 OR completed = 0) AND"; 466 query += " ( completed = 1 OR completed = 0) AND";
467 } 467 }
468 /* srtip the end */ 468 /* srtip the end */
469 query = query.remove( query.length()-3, 3 ); 469 query = query.remove( query.length()-3, 3 );
470 470
471 471
472 /* 472 /*
473 * sort order stuff 473 * sort order stuff
474 * quite straight forward 474 * quite straight forward
475 */ 475 */
476 query += "ORDER BY "; 476 query += "ORDER BY ";
477 switch( sortOrder ) { 477 switch( sortOrder ) {
478 /* completed */ 478 /* completed */
479 case 0: 479 case 0:
480 query += "completed"; 480 query += "completed";
481 break; 481 break;
482 case 1: 482 case 1:
483 query += "priority"; 483 query += "priority";
484 break; 484 break;
485 case 2: 485 case 2:
486 query += "summary"; 486 query += "summary";
487 break; 487 break;
488 case 3: 488 case 3:
489 query += "DueDate"; 489 query += "DueDate";
490 break; 490 break;
491 } 491 }
492 492
493 if ( !asc ) { 493 if ( !asc ) {
494 qWarning("not ascending!"); 494 qWarning("not ascending!");
495 query += " DESC"; 495 query += " DESC";
496 } 496 }
497 497
498 qWarning( query ); 498 qWarning( query );
499 OSQLRawQuery raw(query ); 499 OSQLRawQuery raw(query );
500 return uids( m_driver->query(&raw) ); 500 return uids( m_driver->query(&raw) );
501} 501}
502bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ 502bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{
503 if ( str == "0-0-0" ) 503 if ( str == "0-0-0" )
504 return false; 504 return false;
505 else{ 505 else{
506 int day, year, month; 506 int day, year, month;
507 QStringList list = QStringList::split("-", str ); 507 QStringList list = QStringList::split("-", str );
508 year = list[0].toInt(); 508 year = list[0].toInt();
509 month = list[1].toInt(); 509 month = list[1].toInt();
510 day = list[2].toInt(); 510 day = list[2].toInt();
511 da.setYMD( year, month, day ); 511 da.setYMD( year, month, day );
512 return true; 512 return true;
513 } 513 }
514} 514}
515OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ 515OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{
516 if ( res.state() == OSQLResult::Failure ) { 516 if ( res.state() == OSQLResult::Failure ) {
517 OTodo to; 517 OTodo to;
518 return to; 518 return to;
519 } 519 }
520 520
521 OSQLResultItem::ValueList list = res.results(); 521 OSQLResultItem::ValueList list = res.results();
522 OSQLResultItem::ValueList::Iterator it = list.begin(); 522 OSQLResultItem::ValueList::Iterator it = list.begin();
523 qWarning("todo1"); 523 qWarning("todo1");
524 OTodo to = todo( (*it) ); 524 OTodo to = todo( (*it) );
525 cache( to ); 525 cache( to );
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
12Converter::Converter(){ 18Converter::Converter(){
13} 19}
14 20
15void Converter::start_conversion(){ 21void 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
57int main( int argc, char** argv ) { 96int 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
8class Converter: public converter_base {
9public:
10 Converter();
11
12 void start_conversion();
13private:
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
6INTERFACES = converter_base.ui 6INTERFACES = converter_base.ui
7 INCLUDEPATH+= $(OPIEDIR)/include 7 INCLUDEPATH+= $(OPIEDIR)/include
8 DEPENDPATH+= $(OPIEDIR)/include 8 DEPENDPATH+= $(OPIEDIR)/include
9LIBS += -lqpe -lopie 9LIBS += -lqpe -lopie
10 TARGET = converter 10 TARGET = converter
11 11
12include ( $(OPIEDIR)/include.pro ) 12include ( $(OPIEDIR)/include.pro )