summaryrefslogtreecommitdiff
path: root/libopie2
Unidiff
Diffstat (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/backends.pro5
-rw-r--r--libopie2/opiepim/backend/obackendfactory.h42
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend.cpp121
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend.h80
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp26
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_vcard.h3
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp29
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.h5
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend.cpp228
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend.h47
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp15
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_sql.h5
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp12
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.h4
-rw-r--r--libopie2/opiepim/backend/opimaccessbackend.h361
-rw-r--r--libopie2/opiepim/backend/opimbackendoccurrence.cpp241
-rw-r--r--libopie2/opiepim/backend/opimbackendoccurrence.h108
-rw-r--r--libopie2/opiepim/backend/otodoaccessbackend.cpp114
-rw-r--r--libopie2/opiepim/backend/otodoaccessbackend.h40
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.cpp135
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.h37
-rw-r--r--libopie2/opiepim/backend/otodoaccessvcal.cpp40
-rw-r--r--libopie2/opiepim/backend/otodoaccessvcal.h10
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp316
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.h13
25 files changed, 1218 insertions, 819 deletions
diff --git a/libopie2/opiepim/backend/backends.pro b/libopie2/opiepim/backend/backends.pro
index 42d807c..739f74e 100644
--- a/libopie2/opiepim/backend/backends.pro
+++ b/libopie2/opiepim/backend/backends.pro
@@ -1,37 +1,40 @@
1SOURCES += \ 1SOURCES += \
2 backend/ocontactaccessbackend.cpp \
2 backend/ocontactaccessbackend_vcard.cpp \ 3 backend/ocontactaccessbackend_vcard.cpp \
3 backend/ocontactaccessbackend_xml.cpp \ 4 backend/ocontactaccessbackend_xml.cpp \
4 backend/odatebookaccessbackend.cpp \ 5 backend/odatebookaccessbackend.cpp \
5 backend/odatebookaccessbackend_xml.cpp \ 6 backend/odatebookaccessbackend_xml.cpp \
7 backend/opimbackendoccurrence.cpp \
6 backend/otodoaccessbackend.cpp \ 8 backend/otodoaccessbackend.cpp \
7 backend/otodoaccessvcal.cpp \ 9 backend/otodoaccessvcal.cpp \
8 backend/otodoaccessxml.cpp 10 backend/otodoaccessxml.cpp
9 11
10HEADERS += \ 12HEADERS += \
11 backend/obackendfactory.h \ 13 backend/obackendfactory.h \
12 backend/ocontactaccessbackend.h \ 14 backend/ocontactaccessbackend.h \
13 backend/ocontactaccessbackend_vcard.h \ 15 backend/ocontactaccessbackend_vcard.h \
14 backend/ocontactaccessbackend_xml.h \ 16 backend/ocontactaccessbackend_xml.h \
15 backend/odatebookaccessbackend.h \ 17 backend/odatebookaccessbackend.h \
16 backend/odatebookaccessbackend_xml.h \ 18 backend/odatebookaccessbackend_xml.h \
17 backend/opimaccessbackend.h \ 19 backend/opimaccessbackend.h \
20 backend/opimbackendoccurrence.h \
18 backend/otodoaccessbackend.h \ 21 backend/otodoaccessbackend.h \
19 backend/otodoaccessvcal.h \ 22 backend/otodoaccessvcal.h \
20 backend/otodoaccessxml.h 23 backend/otodoaccessxml.h
21 24
22contains( ENABLE_SQL_PIM_BACKEND, y ) { 25contains( ENABLE_SQL_PIM_BACKEND, y ) {
23 message ( Enabling the SQL Backend for libopiepim2 ) 26 message ( Enabling the SQL Backend for libopiepim2 )
24 DEFINES += __USE_SQL 27 DEFINES += __USE_SQL
25 LIBS += -lopiedb2 28 LIBS += -lopiedb2
26 HEADERS += backend/otodoaccesssql.h \ 29 HEADERS += backend/otodoaccesssql.h \
27 backend/ocontactaccessbackend_sql.h \ 30 backend/ocontactaccessbackend_sql.h \
28 backend/odatebookaccessbackend_sql.h 31 backend/odatebookaccessbackend_sql.h
29 SOURCES += backend/otodoaccesssql.cpp \ 32 SOURCES += backend/otodoaccesssql.cpp \
30 backend/ocontactaccessbackend_sql.cpp \ 33 backend/ocontactaccessbackend_sql.cpp \
31 backend/odatebookaccessbackend_sql.cpp 34 backend/odatebookaccessbackend_sql.cpp
32} 35}
33 36
34!contains( ENABLE_SQL_PIM_BACKEND, y ) { 37!contains( ENABLE_SQL_PIM_BACKEND, y ) {
35 message ( No SQL Backend in libopiepim2 ) 38 message ( No SQL Backend in libopiepim2 )
36} 39}
37 40
diff --git a/libopie2/opiepim/backend/obackendfactory.h b/libopie2/opiepim/backend/obackendfactory.h
index 9f3a823..25e247b 100644
--- a/libopie2/opiepim/backend/obackendfactory.h
+++ b/libopie2/opiepim/backend/obackendfactory.h
@@ -1,230 +1,232 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers <eilers.stefan@epost.de> 3 Copyright (C) Stefan Eilers <eilers.stefan@epost.de>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * ===================================================================== 30 * =====================================================================
31 * ToDo: Use plugins 31 * ToDo: Use plugins
32 * ===================================================================== 32 * =====================================================================
33 */ 33 */
34#ifndef OPIE_BACKENDFACTORY_H_ 34#ifndef OPIE_BACKENDFACTORY_H_
35#define OPIE_BACKENDFACTORY_H_ 35#define OPIE_BACKENDFACTORY_H_
36 36
37/* OPIE */ 37/* OPIE */
38#include <opie2/opimaccessbackend.h> 38#include <opie2/opimaccessbackend.h>
39#include <opie2/opimglobal.h> 39#include <opie2/opimglobal.h>
40#include <opie2/otodoaccessxml.h> 40#include <opie2/otodoaccessxml.h>
41#include <opie2/otodoaccessvcal.h> 41#include <opie2/otodoaccessvcal.h>
42#include <opie2/ocontactaccessbackend_xml.h> 42#include <opie2/ocontactaccessbackend_xml.h>
43#include <opie2/ocontactaccessbackend_vcard.h> 43#include <opie2/ocontactaccessbackend_vcard.h>
44#include <opie2/odatebookaccessbackend_xml.h> 44#include <opie2/odatebookaccessbackend_xml.h>
45#include <opie2/odebug.h> 45#include <opie2/odebug.h>
46 46
47#ifdef __USE_SQL 47#ifdef __USE_SQL
48#include <opie2/otodoaccesssql.h> 48#include <opie2/otodoaccesssql.h>
49#include <opie2/ocontactaccessbackend_sql.h> 49#include <opie2/ocontactaccessbackend_sql.h>
50#include <opie2/odatebookaccessbackend_sql.h> 50#include <opie2/odatebookaccessbackend_sql.h>
51#endif 51#endif
52 52
53#include <qpe/config.h> 53#include <qpe/config.h>
54 54
55/* QT */ 55/* QT */
56#include <qstring.h> 56#include <qstring.h>
57#include <qasciidict.h> 57#include <qasciidict.h>
58 58
59 59
60 60
61using namespace Opie; 61using namespace Opie;
62using namespace Opie::Pim; 62using namespace Opie::Pim;
63 63
64namespace Opie { 64namespace Opie {
65 65
66class OBackendPrivate; 66class OBackendPrivate;
67 67
68/** 68/**
69 * This class is our factory. It will give us the default implementations 69 * This class is our factory. It will give us the default implementations
70 * of at least Todolist, Contacts and Datebook. In the future this class will 70 * of at least Todolist, Contacts and Datebook. In the future this class will
71 * allow users to switch the backend with ( XML->SQLite ) without the need 71 * allow users to switch the backend with ( XML->SQLite ) without the need
72 * to recompile.# 72 * to recompile.#
73 * This class - as the whole PIM Api - is making use of templates 73 * This class - as the whole PIM Api - is making use of templates
74 * 74 *
75 * <pre> 75 * <pre>
76 * OPimTodoAccessBackend* backend = OBackEndFactory<OPimTodoAccessBackend>::Default( OPimGlobal::TODOLIST, QString::null ); 76 * OPimTodoAccessBackend* backend = OBackEndFactory<OPimTodoAccessBackend>::Default( OPimGlobal::TODOLIST, QString::null );
77 * backend->load(); 77 * backend->load();
78 * </pre> 78 * </pre>
79 * 79 *
80 * @author Stefan Eilers 80 * @author Stefan Eilers
81 * @version 0.1 81 * @version 0.1
82 */ 82 */
83 template<class T> 83 template<class T>
84 class OBackendFactory 84 class OBackendFactory
85 { 85 {
86 public: 86 public:
87 OBackendFactory() {}; 87 OBackendFactory() {};
88 88
89 /** 89 /**
90 * Returns a selected backend implementation 90 * Returns a selected backend implementation
91 * @param type the type of the backend 91 * @param type the type of the backend
92 * @param database the type of the used database 92 * @param database the type of the used database
93 * @param appName The name of your application. It will be passed on to the backend. 93 * @param appName The name of your application. It will be passed on to the backend.
94 * @param filename Filename of the database file if you don't want to access the default 94 * @param filename Filename of the database file if you don't want to access the default
95 * @see OPimGlobal() 95 * @see OPimGlobal()
96 */ 96 */
97 static T* create( OPimGlobal::PimType type, OPimGlobal::DatabaseStyle database, 97 static T* create( OPimGlobal::PimType type, OPimGlobal::DatabaseStyle database,
98 const QString& appName, const QString& filename = QString::null ){ 98 const QString& appName, const QString& filename = QString::null ){
99 owarn << "Selected backend for " << type << " is: " << database << oendl; 99 owarn << "Selected backend for " << type << " is: " <<
100 // If we should use the dafult database style, we have to request it 100database << oendl;
101
102 // If we should use the dafult database style, we have to request it
101 OPimGlobal::DatabaseStyle use_database = database; 103 OPimGlobal::DatabaseStyle use_database = database;
102 if ( use_database == OPimGlobal::DEFAULT ){ 104 if ( use_database == OPimGlobal::DEFAULT ){
103 use_database = defaultDB( type ); 105 use_database = defaultDB( type );
104 } 106 }
105 107
106 switch ( type ){ 108 switch ( type ){
107 case OPimGlobal::TODOLIST: 109 case OPimGlobal::TODOLIST:
108 110
109 switch ( use_database ){ 111 switch ( use_database ){
110 default: // Use SQL if something weird is given. 112 default: // Use SQL if something weird is given.
111 // Fall through !! 113 // Fall through !!
112 case OPimGlobal::SQL: 114 case OPimGlobal::SQL:
113#ifdef __USE_SQL 115#ifdef __USE_SQL
114 return (T*) new OPimTodoAccessBackendSQL( filename ); 116 return (T*) new OPimTodoAccessBackendSQL( filename );
115 break; 117 break;
116#else 118#else
117 owarn << "OBackendFactory:: sql Backend for TODO not implemented! Using XML instead!" << oendl; 119 owarn << "OBackendFactory:: sql Backend for TODO not implemented! Using XML instead!" << oendl;
118 // Fall through !! 120 // Fall through !!
119#endif 121#endif
120 case OPimGlobal::XML: 122 case OPimGlobal::XML:
121 return (T*) new OPimTodoAccessXML( appName, filename ); 123 return (T*) new OPimTodoAccessXML( appName, filename );
122 break; 124 break;
123 case OPimGlobal::VCARD: 125 case OPimGlobal::VCARD:
124 return (T*) new OPimTodoAccessVCal( filename ); 126 return (T*) new OPimTodoAccessVCal( filename );
125 break; 127 break;
126 } 128 }
127 case OPimGlobal::CONTACTLIST: 129 case OPimGlobal::CONTACTLIST:
128 switch ( use_database ){ 130 switch ( use_database ){
129 default: // Use SQL if something weird is given. 131 default: // Use SQL if something weird is given.
130 // Fall through !! 132 // Fall through !!
131 case OPimGlobal::SQL: 133 case OPimGlobal::SQL:
132#ifdef __USE_SQL 134#ifdef __USE_SQL
133 return (T*) new OPimContactAccessBackend_SQL( appName, filename ); 135 return (T*) new OPimContactAccessBackend_SQL( appName, filename );
134 break; 136 break;
135#else 137#else
136 owarn << "OBackendFactory:: sql Backend for CONTACT not implemented! Using XML instead!" << oendl; 138 owarn << "OBackendFactory:: sql Backend for CONTACT not implemented! Using XML instead!" << oendl;
137 // Fall through !! 139 // Fall through !!
138#endif 140#endif
139 case OPimGlobal::XML: 141 case OPimGlobal::XML:
140 return (T*) new OPimContactAccessBackend_XML( appName, filename ); 142 return (T*) new OPimContactAccessBackend_XML( appName, filename );
141 break; 143 break;
142 case OPimGlobal::VCARD: 144 case OPimGlobal::VCARD:
143 return (T*) new OPimContactAccessBackend_VCard( appName, filename ); 145 return (T*) new OPimContactAccessBackend_VCard( appName, filename );
144 break; 146 break;
145 } 147 }
146 case OPimGlobal::DATEBOOK: 148 case OPimGlobal::DATEBOOK:
147 switch ( use_database ){ 149 switch ( use_database ){
148 default: // Use SQL if something weird is given. 150 default: // Use SQL if something weird is given.
149 // Fall through !! 151 // Fall through !!
150 case OPimGlobal::SQL: 152 case OPimGlobal::SQL:
151#ifdef __USE_SQL 153#ifdef __USE_SQL
152 return (T*) new ODateBookAccessBackend_SQL( appName, filename ); 154 return (T*) new ODateBookAccessBackend_SQL( appName, filename );
153 break; 155 break;
154#else 156#else
155 owarn << "OBackendFactory:: sql Backend for DATEBOOK not implemented! Using XML instead!" << oendl; 157 owarn << "OBackendFactory:: sql Backend for DATEBOOK not implemented! Using XML instead!" << oendl;
156 // Fall through !! 158 // Fall through !!
157#endif 159#endif
158 case OPimGlobal::XML: 160 case OPimGlobal::XML:
159 return (T*) new ODateBookAccessBackend_XML( appName, filename ); 161 return (T*) new ODateBookAccessBackend_XML( appName, filename );
160 break; 162 break;
161 case OPimGlobal::VCARD: 163 case OPimGlobal::VCARD:
162 owarn << "OBackendFactory:: VCal Backend for DATEBOOK not implemented!" << oendl; 164 owarn << "OBackendFactory:: VCal Backend for DATEBOOK not implemented!" << oendl;
163 return (T*) NULL; 165 return (T*) NULL;
164 break; 166 break;
165 } 167 }
166 default: 168 default:
167 return (T*) NULL; 169 return (T*) NULL;
168 } 170 }
169 171
170 } 172 }
171 173
172 /** 174 /**
173 * Returns the style of the default database which is used to contact PIM data. 175 * Returns the style of the default database which is used to contact PIM data.
174 * @param type the type of the backend 176 * @param type the type of the backend
175 * @see OPimGlobal() 177 * @see OPimGlobal()
176 */ 178 */
177 static OPimGlobal::DatabaseStyle defaultDB( OPimGlobal::PimType type ){ 179 static OPimGlobal::DatabaseStyle defaultDB( OPimGlobal::PimType type ){
178 QString group_name; 180 QString group_name;
179 switch ( type ){ 181 switch ( type ){
180 case OPimGlobal::TODOLIST: 182 case OPimGlobal::TODOLIST:
181 group_name = "todo"; 183 group_name = "todo";
182 break; 184 break;
183 case OPimGlobal::CONTACTLIST: 185 case OPimGlobal::CONTACTLIST:
184 group_name = "contact"; 186 group_name = "contact";
185 break; 187 break;
186 case OPimGlobal::DATEBOOK: 188 case OPimGlobal::DATEBOOK:
187 group_name = "datebook"; 189 group_name = "datebook";
188 break; 190 break;
189 default: 191 default:
190 group_name = "unknown"; 192 group_name = "unknown";
191 } 193 }
192 194
193 Config config( "pimaccess" ); 195 Config config( "pimaccess" );
194 config.setGroup ( group_name ); 196 config.setGroup ( group_name );
195 QString db_String = config.readEntry( "usebackend", "xml" ); 197 QString db_String = config.readEntry( "usebackend", "xml" );
196 198
197 QAsciiDict<int> dictDbTypes( OPimGlobal::_END_DatabaseStyle ); 199 QAsciiDict<int> dictDbTypes( OPimGlobal::_END_DatabaseStyle );
198 dictDbTypes.setAutoDelete( TRUE ); 200 dictDbTypes.setAutoDelete( TRUE );
199 201
200 dictDbTypes.insert( "xml", new int (OPimGlobal::XML) ); 202 dictDbTypes.insert( "xml", new int (OPimGlobal::XML) );
201 dictDbTypes.insert( "sql", new int (OPimGlobal::SQL) ); 203 dictDbTypes.insert( "sql", new int (OPimGlobal::SQL) );
202 dictDbTypes.insert( "vcard", new int (OPimGlobal::VCARD) ); 204 dictDbTypes.insert( "vcard", new int (OPimGlobal::VCARD) );
203 205
204 int* db_find = dictDbTypes[ db_String ]; 206 int* db_find = dictDbTypes[ db_String ];
205 207
206 if ( !db_find ) 208 if ( !db_find )
207 return OPimGlobal::UNKNOWN; 209 return OPimGlobal::UNKNOWN;
208 210
209 return (OPimGlobal::DatabaseStyle) *db_find; 211 return (OPimGlobal::DatabaseStyle) *db_find;
210 } 212 }
211 213
212 214
213 /** 215 /**
214 * Returns the default backend implementation for backendName. Which one is used, is defined 216 * Returns the default backend implementation for backendName. Which one is used, is defined
215 * by the configfile "pimaccess.conf". 217 * by the configfile "pimaccess.conf".
216 * @param type The type of the backend (@see OPimGlobal()) 218 * @param type The type of the backend (@see OPimGlobal())
217 * @param appName The name of your application. It will be passed on to the backend 219 * @param appName The name of your application. It will be passed on to the backend
218 * @see OPimGlobal() 220 * @see OPimGlobal()
219 */ 221 */
220 static T* defaultBackend( OPimGlobal::PimType type, const QString& appName ){ 222 static T* defaultBackend( OPimGlobal::PimType type, const QString& appName ){
221 return create( type, OPimGlobal::DEFAULT, appName ); 223 return create( type, OPimGlobal::DEFAULT, appName );
222 } 224 }
223 private: 225 private:
224 OBackendPrivate* d; 226 OBackendPrivate* d;
225 227
226 }; 228 };
227 229
228} 230}
229 231
230#endif 232#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.cpp b/libopie2/opiepim/backend/ocontactaccessbackend.cpp
new file mode 100644
index 0000000..6ef60eb
--- a/dev/null
+++ b/libopie2/opiepim/backend/ocontactaccessbackend.cpp
@@ -0,0 +1,121 @@
1/*
2 This file is part of the Opie Project
3 Copyright (C) 2004 Holger Freyther <freyther@handhelds.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l.
6 .>+-=
7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more
20++= -. .` .: details.
21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA.
28*/
29
30#include "ocontactaccessbackend.h"
31#include <opie2/private/opimcontactsortvector.h>
32#include <opie2/ocontactaccess.h>
33
34#include <opie2/odebug.h>
35
36namespace Opie {
37OPimContactAccessBackend::OPimContactAccessBackend() {}
38
39UIDArray
40OPimContactAccessBackend::queryByExample( const OPimContact&, int,
41 const QDateTime& )const {
42 return UIDArray();
43}
44
45UIDArray
46OPimContactAccessBackend::sorted( const UIDArray& ar, bool asc, int sortOrder,
47 int filter, const QArray<int>& categories)const {
48 odebug << "Using Unaccelerated OPimContactAccessBackend sorted Implementation" << oendl;
49
50 Internal::OPimContactSortVector vector(ar.count(), asc, sortOrder );
51
52 int item = 0;
53 uint cat_count = categories.count();
54 uint eve_count = ar.count();
55 bool bCat = filter & OPimContactAccess::FilterCategory ? true : false;
56 bool catPassed = false;
57 int cat;
58
59 for ( uint i = 0; i < eve_count; ++i ) {
60 OPimContact contact = find( ar[i], ar, i, Frontend::Forward );
61 if ( contact.isEmpty() )
62 continue;
63
64 /* show category */
65 /* -1 == unfiled */
66 catPassed = false;
67 for ( uint cat_nu = 0; cat_nu < cat_count; ++cat_nu ) {
68 cat = categories[cat_nu];
69 if ( bCat && cat == -1 ) {
70 if(!contact.categories().isEmpty() )
71 continue;
72 } else if ( bCat && cat != 0)
73 if (!contact.categories().contains( cat ) )
74 continue;
75 catPassed = true;
76 break;
77 }
78
79 /*
80 * If none of the Categories matched
81 * continue
82 */
83 if ( !catPassed )
84 continue;
85
86 vector.insert(item++, contact );
87 }
88
89 vector.resize( item );
90 /* sort it now */
91 vector.sort();
92 /* now get the uids */
93 UIDArray array( vector.count() );
94 for (uint i= 0; i < vector.count(); i++ )
95 array[i] = vector.uidAt( i );
96
97 return array;
98}
99
100OPimBackendOccurrence::List OPimContactAccessBackend::occurrences( const QDate& start,
101 const QDate& end)const {
102 OPimBackendOccurrence::List lst;
103
104 UIDArray records = allRecords();
105 const uint count = records.count();
106 int uid;
107
108 for ( uint i = 0; i < count; ++i ) {
109 uid = records[i];
110 OPimContact contact = find(uid, records, i, Frontend::Forward );
111
112 QDate date = contact.anniversary();
113 date = QDate( start.year(), date.month(),date.day() );
114
115// if ( date.isValid() && date.) {
116// }
117 }
118
119 return lst;
120}
121}
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.h b/libopie2/opiepim/backend/ocontactaccessbackend.h
index 8436adc..efb04c7 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend.h
@@ -1,114 +1,108 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) The Main Author <main-author@whereever.org> 3 Copyright (C) The Main Author <main-author@whereever.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/** 29/**
30 * The class responsible for managing a backend. 30 * The class responsible for managing a backend.
31 * The implementation of this abstract class contains 31 * The implementation of this abstract class contains
32 * the complete database handling. 32 * the complete database handling.
33 * 33 *
34 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 34 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
35 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) 35 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org)
36 * 36 *
37 */ 37 */
38 38
39#ifndef _OCONTACTACCESSBACKEND_H_ 39#ifndef _OCONTACTACCESSBACKEND_H_
40#define _OCONTACTACCESSBACKEND_H_ 40#define _OCONTACTACCESSBACKEND_H_
41 41
42#include <opie2/opimcontact.h> 42#include <opie2/opimcontact.h>
43#include <opie2/opimaccessbackend.h> 43#include <opie2/opimaccessbackend.h>
44 44
45#include <qregexp.h> 45#include <qregexp.h>
46 46
47namespace Opie { 47namespace Opie {
48/** 48/**
49 * This class represents the interface of all Contact Backends. 49 * This class represents the interface of all Contact Backends.
50 * Derivates of this class will be used to access the contacts. 50 * Derivates of this class will be used to access the contacts.
51 * As implementation currently XML and vCard exist. This class needs to be implemented 51 * As implementation currently XML and vCard exist. This class needs to be implemented
52 * if you want to provide your own storage. 52 * if you want to provide your own storage.
53 * In all queries a list of uids is passed on instead of loading the actual record! 53 * In all queries a list of uids is passed on instead of loading the actual record!
54 * 54 *
55 * @see OPimContactAccessBackend_VCard 55 * @see OPimContactAccessBackend_VCard
56 * @see OPimContactAccessBackend_XML 56 * @see OPimContactAccessBackend_XML
57 */ 57 */
58class OPimContactAccessBackend: public OPimAccessBackend<OPimContact> { 58class OPimContactAccessBackend: public OPimAccessBackend<OPimContact> {
59 public: 59 public:
60 /** 60 OPimContactAccessBackend();
61 * @todo make non line in regard to BC guide of KDE
62 */
63 OPimContactAccessBackend() {}
64 /**
65 * @todo make non inline in regard to the BC guide of KDE
66 */
67 virtual ~OPimContactAccessBackend() {}
68 61
69 62
70 /** 63 /**
71 * Return if database was changed externally. 64 * Return if database was changed externally.
72 * This may just make sense on file based databases like a XML-File. 65 * This may just make sense on file based databases like a XML-File.
73 * It is used to prevent to overwrite the current database content 66 * It is used to prevent to overwrite the current database content
74 * if the file was already changed by something else ! 67 * if the file was already changed by something else !
75 * If this happens, we have to reload before save our data. 68 * If this happens, we have to reload before save our data.
76 * If we use real databases, this should be handled by the database 69 * If we use real databases, this should be handled by the database
77 * management system themselve, therefore this function should always return false in 70 * management system themselve, therefore this function should always return false in
78 * this case. It is not our problem to handle this conflict ... 71 * this case. It is not our problem to handle this conflict ...
79 * @return <i>true</i> if the database was changed and if save without reload will 72 * @return <i>true</i> if the database was changed and if save without reload will
80 * be dangerous. <i>false</i> if the database was not changed or it is save to write 73 * be dangerous. <i>false</i> if the database was not changed or it is save to write
81 * in this situation. 74 * in this situation.
82 */ 75 */
83 virtual bool wasChangedExternally() = 0; 76 virtual bool wasChangedExternally() = 0;
84 77
85 virtual QArray<int> matchRegexp( const QRegExp &r ) const = 0; 78 /**
79 * Return all possible settings.
80 * @return All settings provided by the current backend
81 * (i.e.: query_WildCards & query_IgnoreCase)
82 */
83 virtual const uint querySettings() = 0;
86 84
87 /** 85 /**
88 * Return all possible settings. 86 * Check whether settings are correct.
89 * @return All settings provided by the current backend 87 * @return <i>true</i> if the given settings are correct and possible.
90 * (i.e.: query_WildCards & query_IgnoreCase) 88 */
91 */ 89 virtual bool hasQuerySettings (uint querySettings) const = 0;
92 virtual const uint querySettings() = 0; 90
91 /**
92 * Slow and inefficent default implementation
93 */
94//@{
95 UIDArray queryByExample( const OPimContact&, int settings, const QDateTime& d = QDateTime() )const;
96 UIDArray sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const;
97 OPimBackendOccurrence::List occurrences( const QDate&, const QDate& )const;
98//@}
93 99
94 /**
95 * Check whether settings are correct.
96 * @return <i>true</i> if the given settings are correct and possible.
97 */
98 virtual bool hasQuerySettings (uint querySettings) const = 0;
99 100
100 /**
101 * FIXME!!!
102 * Returns a sorted list of records either ascendinf or descending for a giving criteria and category
103 */
104 virtual QArray<int> sorted( bool ascending, int sortOrder, int sortFilter, int cat ) = 0;
105
106
107private: 101private:
108 class Private; 102 class Private;
109 Private *d; 103 Private *d;
110}; 104};
111 105
112} 106}
113 107
114#endif 108#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
index af77a05..43e530a 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
@@ -1,611 +1,585 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) The Main Author <main-author@whereever.org> 3 Copyright (C) The Main Author <main-author@whereever.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * VCard Backend for the OPIE-Contact Database. 30 * VCard Backend for the OPIE-Contact Database.
31 */ 31 */
32 32
33 33
34#include <opie2/private/vobject_p.h> 34#include <opie2/private/vobject_p.h>
35 35
36/* OPIE */ 36/* OPIE */
37#include <opie2/ocontactaccessbackend_vcard.h> 37#include <opie2/ocontactaccessbackend_vcard.h>
38#include <opie2/odebug.h> 38#include <opie2/odebug.h>
39 39
40#include <qpe/timeconversion.h> 40#include <qpe/timeconversion.h>
41 41
42//FIXME: Hack to allow direct access to FILE* fh. Rewrite this! 42//FIXME: Hack to allow direct access to FILE* fh. Rewrite this!
43#define protected public 43#define protected public
44#include <qfile.h> 44#include <qfile.h>
45#undef protected 45#undef protected
46 46
47namespace Opie { 47namespace Opie {
48 48
49OPimContactAccessBackend_VCard::OPimContactAccessBackend_VCard ( const QString& , const QString& filename ): 49OPimContactAccessBackend_VCard::OPimContactAccessBackend_VCard ( const QString& , const QString& filename ):
50 m_dirty( false ), 50 m_dirty( false ),
51 m_file( filename ) 51 m_file( filename )
52{ 52{
53 load(); 53 load();
54} 54}
55 55
56 56
57bool OPimContactAccessBackend_VCard::load () 57bool OPimContactAccessBackend_VCard::load ()
58{ 58{
59 m_map.clear(); 59 m_map.clear();
60 m_dirty = false; 60 m_dirty = false;
61 61
62 VObject* obj = 0l; 62 VObject* obj = 0l;
63 63
64 if ( QFile::exists(m_file) ){ 64 if ( QFile::exists(m_file) ){
65 obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); 65 obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() );
66 if ( !obj ) 66 if ( !obj )
67 return false; 67 return false;
68 }else{ 68 }else{
69 odebug << "File \"" << m_file << "\" not found !" << oendl; 69 odebug << "File \"" << m_file << "\" not found !" << oendl;
70 return false; 70 return false;
71 } 71 }
72 72
73 while ( obj ) { 73 while ( obj ) {
74 OPimContact con = parseVObject( obj ); 74 OPimContact con = parseVObject( obj );
75 /* 75 /*
76 * if uid is 0 assign a new one 76 * if uid is 0 assign a new one
77 * this at least happens on 77 * this at least happens on
78 * Nokia6210 78 * Nokia6210
79 */ 79 */
80 if ( con.uid() == 0 ){ 80 if ( con.uid() == 0 ){
81 con.setUid( 1 ); 81 con.setUid( 1 );
82 owarn << "assigned new uid " << con.uid() << "" << oendl; 82 owarn << "assigned new uid " << con.uid() << "" << oendl;
83 } 83 }
84 84
85 m_map.insert( con.uid(), con ); 85 m_map.insert( con.uid(), con );
86 86
87 VObject *t = obj; 87 VObject *t = obj;
88 obj = nextVObjectInList(obj); 88 obj = nextVObjectInList(obj);
89 cleanVObject( t ); 89 cleanVObject( t );
90 } 90 }
91 91
92 return true; 92 return true;
93 93
94} 94}
95bool OPimContactAccessBackend_VCard::reload() 95bool OPimContactAccessBackend_VCard::reload()
96{ 96{
97 return load(); 97 return load();
98} 98}
99bool OPimContactAccessBackend_VCard::save() 99bool OPimContactAccessBackend_VCard::save()
100{ 100{
101 if (!m_dirty ) 101 if (!m_dirty )
102 return true; 102 return true;
103 103
104 QFile file( m_file ); 104 QFile file( m_file );
105 if (!file.open(IO_WriteOnly ) ) 105 if (!file.open(IO_WriteOnly ) )
106 return false; 106 return false;
107 107
108 VObject *obj; 108 VObject *obj;
109 obj = newVObject( VCCalProp ); 109 obj = newVObject( VCCalProp );
110 addPropValue( obj, VCVersionProp, "1.0" ); 110 addPropValue( obj, VCVersionProp, "1.0" );
111 111
112 VObject *vo; 112 VObject *vo;
113 for(QMap<int, OPimContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ 113 for(QMap<int, OPimContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){
114 vo = createVObject( *it ); 114 vo = createVObject( *it );
115 writeVObject( file.fh, vo ); //FIXME: HACK!!! 115 writeVObject( file.fh, vo ); //FIXME: HACK!!!
116 cleanVObject( vo ); 116 cleanVObject( vo );
117 } 117 }
118 cleanStrTbl(); 118 cleanStrTbl();
119 deleteVObject( obj ); 119 deleteVObject( obj );
120 120
121 m_dirty = false; 121 m_dirty = false;
122 return true; 122 return true;
123 123
124 124
125} 125}
126void OPimContactAccessBackend_VCard::clear () 126void OPimContactAccessBackend_VCard::clear ()
127{ 127{
128 m_map.clear(); 128 m_map.clear();
129 m_dirty = true; // ??? sure ? (se) 129 m_dirty = true; // ??? sure ? (se)
130} 130}
131 131
132bool OPimContactAccessBackend_VCard::add ( const OPimContact& newcontact ) 132bool OPimContactAccessBackend_VCard::add ( const OPimContact& newcontact )
133{ 133{
134 m_map.insert( newcontact.uid(), newcontact ); 134 m_map.insert( newcontact.uid(), newcontact );
135 m_dirty = true; 135 m_dirty = true;
136 return true; 136 return true;
137} 137}
138 138
139bool OPimContactAccessBackend_VCard::remove ( int uid ) 139bool OPimContactAccessBackend_VCard::remove ( int uid )
140{ 140{
141 m_map.remove( uid ); 141 m_map.remove( uid );
142 m_dirty = true; 142 m_dirty = true;
143 return true; 143 return true;
144} 144}
145 145
146bool OPimContactAccessBackend_VCard::replace ( const OPimContact &contact ) 146bool OPimContactAccessBackend_VCard::replace ( const OPimContact &contact )
147{ 147{
148 m_map.replace( contact.uid(), contact ); 148 m_map.replace( contact.uid(), contact );
149 m_dirty = true; 149 m_dirty = true;
150 return true; 150 return true;
151} 151}
152 152
153OPimContact OPimContactAccessBackend_VCard::find ( int uid ) const 153OPimContact OPimContactAccessBackend_VCard::find ( int uid ) const
154{ 154{
155 return m_map[uid]; 155 return m_map[uid];
156} 156}
157 157
158QArray<int> OPimContactAccessBackend_VCard::allRecords() const 158QArray<int> OPimContactAccessBackend_VCard::allRecords() const
159{ 159{
160 QArray<int> ar( m_map.count() ); 160 QArray<int> ar( m_map.count() );
161 QMap<int, OPimContact>::ConstIterator it; 161 QMap<int, OPimContact>::ConstIterator it;
162 int i = 0; 162 int i = 0;
163 for ( it = m_map.begin(); it != m_map.end(); ++it ) { 163 for ( it = m_map.begin(); it != m_map.end(); ++it ) {
164 ar[i] = it.key(); 164 ar[i] = it.key();
165 i++; 165 i++;
166 } 166 }
167 return ar; 167 return ar;
168} 168}
169 169
170// Not implemented
171QArray<int> OPimContactAccessBackend_VCard::queryByExample ( const OPimContact&, int, const QDateTime& )
172{
173 QArray<int> ar(0);
174 return ar;
175}
176
177// Not implemented
178QArray<int> OPimContactAccessBackend_VCard::matchRegexp( const QRegExp& ) const
179{
180 QArray<int> ar(0);
181 return ar;
182}
183
184const uint OPimContactAccessBackend_VCard::querySettings() 170const uint OPimContactAccessBackend_VCard::querySettings()
185{ 171{
186 return 0; // No search possible 172 return 0; // No search possible
187} 173}
188 174
189bool OPimContactAccessBackend_VCard::hasQuerySettings (uint ) const 175bool OPimContactAccessBackend_VCard::hasQuerySettings (uint ) const
190{ 176{
191 return false; // No search possible, therefore all settings invalid ;) 177 return false; // No search possible, therefore all settings invalid ;)
192} 178}
193 179
194bool OPimContactAccessBackend_VCard::wasChangedExternally() 180bool OPimContactAccessBackend_VCard::wasChangedExternally()
195{ 181{
196 return false; // Don't expect concurrent access 182 return false; // Don't expect concurrent access
197} 183}
198 184
199// Not implemented
200QArray<int> OPimContactAccessBackend_VCard::sorted( bool , int, int, int )
201{
202 QArray<int> ar(0);
203 return ar;
204}
205
206// *** Private stuff *** 185// *** Private stuff ***
207
208
209OPimContact OPimContactAccessBackend_VCard::parseVObject( VObject *obj ) 186OPimContact OPimContactAccessBackend_VCard::parseVObject( VObject *obj )
210{ 187{
211 OPimContact c; 188 OPimContact c;
212 189
213 VObjectIterator it; 190 VObjectIterator it;
214 initPropIterator( &it, obj ); 191 initPropIterator( &it, obj );
215 while( moreIteration( &it ) ) { 192 while( moreIteration( &it ) ) {
216 VObject *o = nextVObject( &it ); 193 VObject *o = nextVObject( &it );
217 QCString name = vObjectName( o ); 194 QCString name = vObjectName( o );
218 QString value = QString::fromUtf8( vObjectStringZValue( o ) ); 195 QString value = QString::fromUtf8( vObjectStringZValue( o ) );
219 odebug << "(1)Read: %s" << QString( value ).latin1() << oendl; 196 odebug << "(1)Read: %s" << QString( value ).latin1() << oendl;
220 if ( name == VCNameProp ) { 197 if ( name == VCNameProp ) {
221 VObjectIterator nit; 198 VObjectIterator nit;
222 initPropIterator( &nit, o ); 199 initPropIterator( &nit, o );
223 while( moreIteration( &nit ) ) { 200 while( moreIteration( &nit ) ) {
224 VObject *o = nextVObject( &nit ); 201 VObject *o = nextVObject( &nit );
225 QCString name = vObjectTypeInfo( o ); 202 QCString name = vObjectTypeInfo( o );
226 QString value = QString::fromUtf8( vObjectStringZValue( o ) ); 203 QString value = QString::fromUtf8( vObjectStringZValue( o ) );
227 odebug << "(2)Read: %s" << value.latin1() << oendl; 204 odebug << "(2)Read: %s" << value.latin1() << oendl;
228 if ( name == VCNamePrefixesProp ) 205 if ( name == VCNamePrefixesProp )
229 c.setTitle( value ); 206 c.setTitle( value );
230 else if ( name == VCNameSuffixesProp ) 207 else if ( name == VCNameSuffixesProp )
231 c.setSuffix( value ); 208 c.setSuffix( value );
232 else if ( name == VCFamilyNameProp ) 209 else if ( name == VCFamilyNameProp )
233 c.setLastName( value ); 210 c.setLastName( value );
234 else if ( name == VCGivenNameProp ) 211 else if ( name == VCGivenNameProp )
235 c.setFirstName( value ); 212 c.setFirstName( value );
236 else if ( name == VCAdditionalNamesProp ) 213 else if ( name == VCAdditionalNamesProp )
237 c.setMiddleName( value ); 214 c.setMiddleName( value );
238 } 215 }
239 } 216 }
240 else if ( name == VCAdrProp ) { 217 else if ( name == VCAdrProp ) {
241 bool work = TRUE; // default address is work address 218 bool work = TRUE; // default address is work address
242 QString street; 219 QString street;
243 QString city; 220 QString city;
244 QString region; 221 QString region;
245 QString postal; 222 QString postal;
246 QString country; 223 QString country;
247 224
248 VObjectIterator nit; 225 VObjectIterator nit;
249 initPropIterator( &nit, o ); 226 initPropIterator( &nit, o );
250 while( moreIteration( &nit ) ) { 227 while( moreIteration( &nit ) ) {
251 VObject *o = nextVObject( &nit ); 228 VObject *o = nextVObject( &nit );
252 QCString name = vObjectName( o ); 229 QCString name = vObjectName( o );
253 QString value = QString::fromUtf8( vObjectStringZValue( o ) ); 230 QString value = QString::fromUtf8( vObjectStringZValue( o ) );
254 if ( name == VCHomeProp ) 231 if ( name == VCHomeProp )
255 work = FALSE; 232 work = FALSE;
256 else if ( name == VCWorkProp ) 233 else if ( name == VCWorkProp )
257 work = TRUE; 234 work = TRUE;
258 else if ( name == VCStreetAddressProp ) 235 else if ( name == VCStreetAddressProp )
259 street = value; 236 street = value;
260 else if ( name == VCCityProp ) 237 else if ( name == VCCityProp )
261 city = value; 238 city = value;
262 else if ( name == VCRegionProp ) 239 else if ( name == VCRegionProp )
263 region = value; 240 region = value;
264 else if ( name == VCPostalCodeProp ) 241 else if ( name == VCPostalCodeProp )
265 postal = value; 242 postal = value;
266 else if ( name == VCCountryNameProp ) 243 else if ( name == VCCountryNameProp )
267 country = value; 244 country = value;
268 } 245 }
269 if ( work ) { 246 if ( work ) {
270 c.setBusinessStreet( street ); 247 c.setBusinessStreet( street );
271 c.setBusinessCity( city ); 248 c.setBusinessCity( city );
272 c.setBusinessCountry( country ); 249 c.setBusinessCountry( country );
273 c.setBusinessZip( postal ); 250 c.setBusinessZip( postal );
274 c.setBusinessState( region ); 251 c.setBusinessState( region );
275 } else { 252 } else {
276 c.setHomeStreet( street ); 253 c.setHomeStreet( street );
277 c.setHomeCity( city ); 254 c.setHomeCity( city );
278 c.setHomeCountry( country ); 255 c.setHomeCountry( country );
279 c.setHomeZip( postal ); 256 c.setHomeZip( postal );
280 c.setHomeState( region ); 257 c.setHomeState( region );
281 } 258 }
282 } 259 }
283 else if ( name == VCTelephoneProp ) { 260 else if ( name == VCTelephoneProp ) {
284 enum { 261 enum {
285 HOME = 0x01, 262 HOME = 0x01,
286 WORK = 0x02, 263 WORK = 0x02,
287 VOICE = 0x04, 264 VOICE = 0x04,
288 CELL = 0x08, 265 CELL = 0x08,
289 FAX = 0x10, 266 FAX = 0x10,
290 PAGER = 0x20, 267 PAGER = 0x20,
291 UNKNOWN = 0x80 268 UNKNOWN = 0x80
292 }; 269 };
293 int type = 0; 270 int type = 0;
294 271
295 VObjectIterator nit; 272 VObjectIterator nit;
296 initPropIterator( &nit, o ); 273 initPropIterator( &nit, o );
297 while( moreIteration( &nit ) ) { 274 while( moreIteration( &nit ) ) {
298 VObject *o = nextVObject( &nit ); 275 VObject *o = nextVObject( &nit );
299 QCString name = vObjectTypeInfo( o ); 276 QCString name = vObjectTypeInfo( o );
300 if ( name == VCHomeProp ) 277 if ( name == VCHomeProp )
301 type |= HOME; 278 type |= HOME;
302 else if ( name == VCWorkProp ) 279 else if ( name == VCWorkProp )
303 type |= WORK; 280 type |= WORK;
304 else if ( name == VCVoiceProp ) 281 else if ( name == VCVoiceProp )
305 type |= VOICE; 282 type |= VOICE;
306 else if ( name == VCCellularProp ) 283 else if ( name == VCCellularProp )
307 type |= CELL; 284 type |= CELL;
308 else if ( name == VCFaxProp ) 285 else if ( name == VCFaxProp )
309 type |= FAX; 286 type |= FAX;
310 else if ( name == VCPagerProp ) 287 else if ( name == VCPagerProp )
311 type |= PAGER; 288 type |= PAGER;
312 else if ( name == VCPreferredProp ) 289 else if ( name == VCPreferredProp )
313 ; 290 ;
314 else 291 else
315 type |= UNKNOWN; 292 type |= UNKNOWN;
316 } 293 }
317 if ( (type & UNKNOWN) != UNKNOWN ) { 294 if ( (type & UNKNOWN) != UNKNOWN ) {
318 if ( ( type & (HOME|WORK) ) == 0 ) // default 295 if ( ( type & (HOME|WORK) ) == 0 ) // default
319 type |= HOME; 296 type |= HOME;
320 if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default 297 if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default
321 type |= VOICE; 298 type |= VOICE;
322 299
323 owarn << "value %s %d" << value.data() << type << oendl;
324 if ( (type & (VOICE|HOME) ) == (VOICE|HOME) && (type & (CELL|HOME) ) != (CELL|HOME) ) 300 if ( (type & (VOICE|HOME) ) == (VOICE|HOME) && (type & (CELL|HOME) ) != (CELL|HOME) )
325 c.setHomePhone( value ); 301 c.setHomePhone( value );
326 if ( ( type & (FAX|HOME) ) == (FAX|HOME) ) 302 if ( ( type & (FAX|HOME) ) == (FAX|HOME) )
327 c.setHomeFax( value ); 303 c.setHomeFax( value );
328 if ( ( type & (CELL|HOME) ) == (CELL|HOME) ) 304 if ( ( type & (CELL|HOME) ) == (CELL|HOME) )
329 c.setHomeMobile( value ); 305 c.setHomeMobile( value );
330 if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) && (type & (CELL|WORK) ) != (CELL|WORK) ) 306 if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) && (type & (CELL|WORK) ) != (CELL|WORK) )
331 c.setBusinessPhone( value ); 307 c.setBusinessPhone( value );
332 if ( ( type & (FAX|WORK) ) == (FAX|WORK) ) 308 if ( ( type & (FAX|WORK) ) == (FAX|WORK) )
333 c.setBusinessFax( value ); 309 c.setBusinessFax( value );
334 if ( ( type & (CELL|WORK) ) == (CELL|WORK) ) 310 if ( ( type & (CELL|WORK) ) == (CELL|WORK) )
335 c.setBusinessMobile( value ); 311 c.setBusinessMobile( value );
336 if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) ) 312 if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) )
337 c.setBusinessPager( value ); 313 c.setBusinessPager( value );
338 } 314 }
339 } 315 }
340 else if ( name == VCEmailAddressProp ) { 316 else if ( name == VCEmailAddressProp ) {
341 QString email = QString::fromUtf8( vObjectStringZValue( o ) ); 317 QString email = QString::fromUtf8( vObjectStringZValue( o ) );
342 bool valid = TRUE; 318 bool valid = TRUE;
343 VObjectIterator nit; 319 VObjectIterator nit;
344 initPropIterator( &nit, o ); 320 initPropIterator( &nit, o );
345 while( moreIteration( &nit ) ) { 321 while( moreIteration( &nit ) ) {
346 VObject *o = nextVObject( &nit ); 322 VObject *o = nextVObject( &nit );
347 QCString name = vObjectTypeInfo( o ); 323 QCString name = vObjectTypeInfo( o );
348 if ( name != VCInternetProp && name != VCHomeProp && 324 if ( name != VCInternetProp && name != VCHomeProp &&
349 name != VCWorkProp && 325 name != VCWorkProp &&
350 name != VCPreferredProp ) 326 name != VCPreferredProp )
351 // ### preffered should map to default email 327 // ### preffered should map to default email
352 valid = FALSE; 328 valid = FALSE;
353 } 329 }
354 if ( valid ) { 330 if ( valid ) {
355 c.insertEmail( email ); 331 c.insertEmail( email );
356 } 332 }
357 } 333 }
358 else if ( name == VCURLProp ) { 334 else if ( name == VCURLProp ) {
359 VObjectIterator nit; 335 VObjectIterator nit;
360 initPropIterator( &nit, o ); 336 initPropIterator( &nit, o );
361 while( moreIteration( &nit ) ) { 337 while( moreIteration( &nit ) ) {
362 VObject *o = nextVObject( &nit ); 338 VObject *o = nextVObject( &nit );
363 QCString name = vObjectTypeInfo( o ); 339 QCString name = vObjectTypeInfo( o );
364 if ( name == VCHomeProp ) 340 if ( name == VCHomeProp )
365 c.setHomeWebpage( value ); 341 c.setHomeWebpage( value );
366 else if ( name == VCWorkProp ) 342 else if ( name == VCWorkProp )
367 c.setBusinessWebpage( value ); 343 c.setBusinessWebpage( value );
368 } 344 }
369 } 345 }
370 else if ( name == VCOrgProp ) { 346 else if ( name == VCOrgProp ) {
371 VObjectIterator nit; 347 VObjectIterator nit;
372 initPropIterator( &nit, o ); 348 initPropIterator( &nit, o );
373 while( moreIteration( &nit ) ) { 349 while( moreIteration( &nit ) ) {
374 VObject *o = nextVObject( &nit ); 350 VObject *o = nextVObject( &nit );
375 QCString name = vObjectName( o ); 351 QCString name = vObjectName( o );
376 QString value = QString::fromUtf8( vObjectStringZValue( o ) ); 352 QString value = QString::fromUtf8( vObjectStringZValue( o ) );
377 if ( name == VCOrgNameProp ) 353 if ( name == VCOrgNameProp )
378 c.setCompany( value ); 354 c.setCompany( value );
379 else if ( name == VCOrgUnitProp ) 355 else if ( name == VCOrgUnitProp )
380 c.setDepartment( value ); 356 c.setDepartment( value );
381 else if ( name == VCOrgUnit2Prop ) 357 else if ( name == VCOrgUnit2Prop )
382 c.setOffice( value ); 358 c.setOffice( value );
383 } 359 }
384 } 360 }
385 else if ( name == VCTitleProp ) { 361 else if ( name == VCTitleProp ) {
386 c.setJobTitle( value ); 362 c.setJobTitle( value );
387 } 363 }
388 else if ( name == "X-Qtopia-Profession" ) { 364 else if ( name == "X-Qtopia-Profession" ) {
389 c.setProfession( value ); 365 c.setProfession( value );
390 } 366 }
391 else if ( name == "X-Qtopia-Manager" ) { 367 else if ( name == "X-Qtopia-Manager" ) {
392 c.setManager( value ); 368 c.setManager( value );
393 } 369 }
394 else if ( name == "X-Qtopia-Assistant" ) { 370 else if ( name == "X-Qtopia-Assistant" ) {
395 c.setAssistant( value ); 371 c.setAssistant( value );
396 } 372 }
397 else if ( name == "X-Qtopia-Spouse" ) { 373 else if ( name == "X-Qtopia-Spouse" ) {
398 c.setSpouse( value ); 374 c.setSpouse( value );
399 } 375 }
400 else if ( name == "X-Qtopia-Gender" ) { 376 else if ( name == "X-Qtopia-Gender" ) {
401 c.setGender( value ); 377 c.setGender( value );
402 } 378 }
403 else if ( name == "X-Qtopia-Anniversary" ) { 379 else if ( name == "X-Qtopia-Anniversary" ) {
404 c.setAnniversary( convVCardDateToDate( value ) ); 380 c.setAnniversary( convVCardDateToDate( value ) );
405 } 381 }
406 else if ( name == "X-Qtopia-Nickname" ) { 382 else if ( name == "X-Qtopia-Nickname" ) {
407 c.setNickname( value ); 383 c.setNickname( value );
408 } 384 }
409 else if ( name == "X-Qtopia-Children" ) { 385 else if ( name == "X-Qtopia-Children" ) {
410 c.setChildren( value ); 386 c.setChildren( value );
411 } 387 }
412 else if ( name == VCBirthDateProp ) { 388 else if ( name == VCBirthDateProp ) {
413 // Reading Birthdate regarding RFC 2425 (5.8.4) 389 // Reading Birthdate regarding RFC 2425 (5.8.4)
414 c.setBirthday( convVCardDateToDate( value ) ); 390 c.setBirthday( convVCardDateToDate( value ) );
415 391
416 } 392 }
417 else if ( name == VCCommentProp ) { 393 else if ( name == VCCommentProp ) {
418 c.setNotes( value ); 394 c.setNotes( value );
419 } 395 }
420#if 0 396#if 0
421 else { 397 else {
422 printf("Name: %s, value=%s\n", name.data(), QString::fromUtf8( vObjectStringZValue( o ) ) ); 398 printf("Name: %s, value=%s\n", name.data(), QString::fromUtf8( vObjectStringZValue( o ) ) );
423 VObjectIterator nit; 399 VObjectIterator nit;
424 initPropIterator( &nit, o ); 400 initPropIterator( &nit, o );
425 while( moreIteration( &nit ) ) { 401 while( moreIteration( &nit ) ) {
426 VObject *o = nextVObject( &nit ); 402 VObject *o = nextVObject( &nit );
427 QCString name = vObjectName( o ); 403 QCString name = vObjectName( o );
428 QString value = QString::fromUtf8( vObjectStringZValue( o ) ); 404 QString value = QString::fromUtf8( vObjectStringZValue( o ) );
429 printf(" subprop: %s = %s\n", name.data(), value.latin1() ); 405 printf(" subprop: %s = %s\n", name.data(), value.latin1() );
430 } 406 }
431 } 407 }
432 else { 408 else {
433 printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); 409 printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) );
434 VObjectIterator nit; 410 VObjectIterator nit;
435 initPropIterator( &nit, o ); 411 initPropIterator( &nit, o );
436 while( moreIteration( &nit ) ) { 412 while( moreIteration( &nit ) ) {
437 VObject *o = nextVObject( &nit ); 413 VObject *o = nextVObject( &nit );
438 QCString name = vObjectName( o ); 414 QCString name = vObjectName( o );
439 QString value = vObjectStringZValue( o ); 415 QString value = vObjectStringZValue( o );
440 printf(" subprop: %s = %s\n", name.data(), value.latin1() ); 416 printf(" subprop: %s = %s\n", name.data(), value.latin1() );
441 } 417 }
442 } 418 }
443#endif 419#endif
444 } 420 }
445 c.setFileAs(); 421 c.setFileAs();
446 return c; 422 return c;
447} 423}
448 424
449 425
450VObject* OPimContactAccessBackend_VCard::createVObject( const OPimContact &c ) 426VObject* OPimContactAccessBackend_VCard::createVObject( const OPimContact &c )
451{ 427{
452 VObject *vcard = newVObject( VCCardProp ); 428 VObject *vcard = newVObject( VCCardProp );
453 safeAddPropValue( vcard, VCVersionProp, "2.1" ); 429 safeAddPropValue( vcard, VCVersionProp, "2.1" );
454 safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) ); 430 safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) );
455 safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) ); 431 safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) );
456 432
457 // full name 433 // full name
458 safeAddPropValue( vcard, VCFullNameProp, c.fullName() ); 434 safeAddPropValue( vcard, VCFullNameProp, c.fullName() );
459 435
460 // name properties 436 // name properties
461 VObject *name = safeAddProp( vcard, VCNameProp ); 437 VObject *name = safeAddProp( vcard, VCNameProp );
462 safeAddPropValue( name, VCFamilyNameProp, c.lastName() ); 438 safeAddPropValue( name, VCFamilyNameProp, c.lastName() );
463 safeAddPropValue( name, VCGivenNameProp, c.firstName() ); 439 safeAddPropValue( name, VCGivenNameProp, c.firstName() );
464 safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() ); 440 safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() );
465 safeAddPropValue( name, VCNamePrefixesProp, c.title() ); 441 safeAddPropValue( name, VCNamePrefixesProp, c.title() );
466 safeAddPropValue( name, VCNameSuffixesProp, c.suffix() ); 442 safeAddPropValue( name, VCNameSuffixesProp, c.suffix() );
467 443
468 // home properties 444 // home properties
469 VObject *home_adr= safeAddProp( vcard, VCAdrProp ); 445 VObject *home_adr= safeAddProp( vcard, VCAdrProp );
470 safeAddProp( home_adr, VCHomeProp ); 446 safeAddProp( home_adr, VCHomeProp );
471 safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() ); 447 safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() );
472 safeAddPropValue( home_adr, VCCityProp, c.homeCity() ); 448 safeAddPropValue( home_adr, VCCityProp, c.homeCity() );
473 safeAddPropValue( home_adr, VCRegionProp, c.homeState() ); 449 safeAddPropValue( home_adr, VCRegionProp, c.homeState() );
474 safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() ); 450 safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() );
475 safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() ); 451 safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() );
476 452
477 VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() ); 453 VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() );
478 safeAddProp( home_phone, VCHomeProp ); 454 safeAddProp( home_phone, VCHomeProp );
479 home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() ); 455 home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() );
480 safeAddProp( home_phone, VCHomeProp ); 456 safeAddProp( home_phone, VCHomeProp );
481 safeAddProp( home_phone, VCCellularProp ); 457 safeAddProp( home_phone, VCCellularProp );
482 home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() ); 458 home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() );
483 safeAddProp( home_phone, VCHomeProp ); 459 safeAddProp( home_phone, VCHomeProp );
484 safeAddProp( home_phone, VCFaxProp ); 460 safeAddProp( home_phone, VCFaxProp );
485 461
486 VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() ); 462 VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() );
487 safeAddProp( url, VCHomeProp ); 463 safeAddProp( url, VCHomeProp );
488 464
489 // work properties 465 // work properties
490 VObject *work_adr= safeAddProp( vcard, VCAdrProp ); 466 VObject *work_adr= safeAddProp( vcard, VCAdrProp );
491 safeAddProp( work_adr, VCWorkProp ); 467 safeAddProp( work_adr, VCWorkProp );
492 safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() ); 468 safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() );
493 safeAddPropValue( work_adr, VCCityProp, c.businessCity() ); 469 safeAddPropValue( work_adr, VCCityProp, c.businessCity() );
494 safeAddPropValue( work_adr, VCRegionProp, c.businessState() ); 470 safeAddPropValue( work_adr, VCRegionProp, c.businessState() );
495 safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() ); 471 safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() );
496 safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() ); 472 safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() );
497 473
498 VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() ); 474 VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() );
499 safeAddProp( work_phone, VCWorkProp ); 475 safeAddProp( work_phone, VCWorkProp );
500 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() ); 476 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() );
501 safeAddProp( work_phone, VCWorkProp ); 477 safeAddProp( work_phone, VCWorkProp );
502 safeAddProp( work_phone, VCCellularProp ); 478 safeAddProp( work_phone, VCCellularProp );
503 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() ); 479 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() );
504 safeAddProp( work_phone, VCWorkProp ); 480 safeAddProp( work_phone, VCWorkProp );
505 safeAddProp( work_phone, VCFaxProp ); 481 safeAddProp( work_phone, VCFaxProp );
506 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() ); 482 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() );
507 safeAddProp( work_phone, VCWorkProp ); 483 safeAddProp( work_phone, VCWorkProp );
508 safeAddProp( work_phone, VCPagerProp ); 484 safeAddProp( work_phone, VCPagerProp );
509 485
510 url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() ); 486 url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() );
511 safeAddProp( url, VCWorkProp ); 487 safeAddProp( url, VCWorkProp );
512 488
513 VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() ); 489 VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() );
514 safeAddProp( title, VCWorkProp ); 490 safeAddProp( title, VCWorkProp );
515 491
516 492
517 QStringList emails = c.emailList(); 493 QStringList emails = c.emailList();
518 // emails.prepend( c.defaultEmail() ); Fix for bugreport #1045 494 // emails.prepend( c.defaultEmail() ); Fix for bugreport #1045
519 for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { 495 for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) {
520 VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it ); 496 VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it );
521 safeAddProp( email, VCInternetProp ); 497 safeAddProp( email, VCInternetProp );
522 } 498 }
523 499
524 safeAddPropValue( vcard, VCNoteProp, c.notes() ); 500 safeAddPropValue( vcard, VCNoteProp, c.notes() );
525 501
526 // Exporting Birthday regarding RFC 2425 (5.8.4) 502 // Exporting Birthday regarding RFC 2425 (5.8.4)
527 if ( c.birthday().isValid() ){ 503 if ( c.birthday().isValid() ){
528 owarn << "Exporting birthday as: " << convDateToVCardDate( c.birthday() ) << "" << oendl;
529 safeAddPropValue( vcard, VCBirthDateProp, convDateToVCardDate( c.birthday() ) ); 504 safeAddPropValue( vcard, VCBirthDateProp, convDateToVCardDate( c.birthday() ) );
530 } 505 }
531 506
532 if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) { 507 if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) {
533 VObject *org = safeAddProp( vcard, VCOrgProp ); 508 VObject *org = safeAddProp( vcard, VCOrgProp );
534 safeAddPropValue( org, VCOrgNameProp, c.company() ); 509 safeAddPropValue( org, VCOrgNameProp, c.company() );
535 safeAddPropValue( org, VCOrgUnitProp, c.department() ); 510 safeAddPropValue( org, VCOrgUnitProp, c.department() );
536 safeAddPropValue( org, VCOrgUnit2Prop, c.office() ); 511 safeAddPropValue( org, VCOrgUnit2Prop, c.office() );
537 } 512 }
538 513
539 // some values we have to export as custom fields 514 // some values we have to export as custom fields
540 safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() ); 515 safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() );
541 safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() ); 516 safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() );
542 safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() ); 517 safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() );
543 518
544 safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() ); 519 safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() );
545 safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() ); 520 safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() );
546 if ( c.anniversary().isValid() ){ 521 if ( c.anniversary().isValid() ){
547 owarn << "Exporting anniversary as: " << convDateToVCardDate( c.anniversary() ) << "" << oendl;
548 safeAddPropValue( vcard, "X-Qtopia-Anniversary", convDateToVCardDate( c.anniversary() ) ); 522 safeAddPropValue( vcard, "X-Qtopia-Anniversary", convDateToVCardDate( c.anniversary() ) );
549 } 523 }
550 safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() ); 524 safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() );
551 safeAddPropValue( vcard, "X-Qtopia-Children", c.children() ); 525 safeAddPropValue( vcard, "X-Qtopia-Children", c.children() );
552 526
553 return vcard; 527 return vcard;
554} 528}
555 529
556QString OPimContactAccessBackend_VCard::convDateToVCardDate( const QDate& d ) const 530QString OPimContactAccessBackend_VCard::convDateToVCardDate( const QDate& d ) const
557{ 531{
558 QString str_rfc2425 = QString("%1-%2-%3") 532 QString str_rfc2425 = QString("%1-%2-%3")
559 .arg( d.year() ) 533 .arg( d.year() )
560 .arg( d.month(), 2 ) 534 .arg( d.month(), 2 )
561 .arg( d.day(), 2 ); 535 .arg( d.day(), 2 );
562 // Now replace spaces with "0"... 536 // Now replace spaces with "0"...
563 int pos = 0; 537 int pos = 0;
564 while ( ( pos = str_rfc2425.find (' ') ) > 0 ) 538 while ( ( pos = str_rfc2425.find (' ') ) > 0 )
565 str_rfc2425.replace( pos, 1, "0" ); 539 str_rfc2425.replace( pos, 1, "0" );
566 540
567 return str_rfc2425; 541 return str_rfc2425;
568} 542}
569 543
570QDate OPimContactAccessBackend_VCard::convVCardDateToDate( const QString& datestr ) 544QDate OPimContactAccessBackend_VCard::convVCardDateToDate( const QString& datestr )
571{ 545{
572 int monthPos = datestr.find('-'); 546 int monthPos = datestr.find('-');
573 int dayPos = datestr.find('-', monthPos+1 ); 547 int dayPos = datestr.find('-', monthPos+1 );
574 int sep_ignore = 1; 548 int sep_ignore = 1;
575 if ( monthPos == -1 || dayPos == -1 ) { 549 if ( monthPos == -1 || dayPos == -1 ) {
576 odebug << "fromString didn't find - in str = " << datestr << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl; 550 odebug << "fromString didn't find - in str = " << datestr << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl;
577 // Ok.. No "-" found, therefore we will try to read other format ( YYYYMMDD ) 551 // Ok.. No "-" found, therefore we will try to read other format ( YYYYMMDD )
578 if ( datestr.length() == 8 ){ 552 if ( datestr.length() == 8 ){
579 monthPos = 4; 553 monthPos = 4;
580 dayPos = 6; 554 dayPos = 6;
581 sep_ignore = 0; 555 sep_ignore = 0;
582 odebug << "Try with follwing positions str = " << datestr << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl; 556 odebug << "Try with follwing positions str = " << datestr << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl;
583 } else { 557 } else {
584 return QDate(); 558 return QDate();
585 } 559 }
586 } 560 }
587 int y = datestr.left( monthPos ).toInt(); 561 int y = datestr.left( monthPos ).toInt();
588 int m = datestr.mid( monthPos + sep_ignore, dayPos - monthPos - sep_ignore ).toInt(); 562 int m = datestr.mid( monthPos + sep_ignore, dayPos - monthPos - sep_ignore ).toInt();
589 int d = datestr.mid( dayPos + sep_ignore ).toInt(); 563 int d = datestr.mid( dayPos + sep_ignore ).toInt();
590 odebug << "TimeConversion::fromString ymd = " << datestr << " => " << y << " " << m << " " << d << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl; 564 odebug << "TimeConversion::fromString ymd = " << datestr << " => " << y << " " << m << " " << d << "; mpos = " << monthPos << " ypos = " << dayPos << "" << oendl;
591 QDate date ( y,m,d ); 565 QDate date ( y,m,d );
592 return date; 566 return date;
593} 567}
594 568
595VObject* OPimContactAccessBackend_VCard::safeAddPropValue( VObject *o, const char *prop, const QString &value ) 569VObject* OPimContactAccessBackend_VCard::safeAddPropValue( VObject *o, const char *prop, const QString &value )
596{ 570{
597 VObject *ret = 0; 571 VObject *ret = 0;
598 if ( o && !value.isEmpty() ) 572 if ( o && !value.isEmpty() )
599 ret = addPropValue( o, prop, value.utf8() ); 573 ret = addPropValue( o, prop, value.utf8() );
600 return ret; 574 return ret;
601} 575}
602 576
603VObject* OPimContactAccessBackend_VCard::safeAddProp( VObject *o, const char *prop) 577VObject* OPimContactAccessBackend_VCard::safeAddProp( VObject *o, const char *prop)
604{ 578{
605 VObject *ret = 0; 579 VObject *ret = 0;
606 if ( o ) 580 if ( o )
607 ret = addProp( o, prop ); 581 ret = addProp( o, prop );
608 return ret; 582 return ret;
609} 583}
610 584
611} 585}
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h
index 2a786af..1faf747 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h
@@ -1,85 +1,82 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) The Main Author <main-author@whereever.org> 3 Copyright (C) The Main Author <main-author@whereever.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * VCard Backend for the OPIE-Contact Database. 30 * VCard Backend for the OPIE-Contact Database.
31 */ 31 */
32#ifndef __OCONTACTACCESSBACKEND_VCARD_H_ 32#ifndef __OCONTACTACCESSBACKEND_VCARD_H_
33#define __OCONTACTACCESSBACKEND_VCARD_H_ 33#define __OCONTACTACCESSBACKEND_VCARD_H_
34 34
35#include <opie2/opimcontact.h> 35#include <opie2/opimcontact.h>
36 36
37#include <opie2/ocontactaccessbackend.h> 37#include <opie2/ocontactaccessbackend.h>
38 38
39class VObject; 39class VObject;
40 40
41namespace Opie { 41namespace Opie {
42/** 42/**
43 * This is the vCard 2.1 implementation of the Contact Storage 43 * This is the vCard 2.1 implementation of the Contact Storage
44 * @see OPimContactAccessBackend_XML 44 * @see OPimContactAccessBackend_XML
45 * @see OPimAccessBackend 45 * @see OPimAccessBackend
46 */ 46 */
47class OPimContactAccessBackend_VCard : public OPimContactAccessBackend { 47class OPimContactAccessBackend_VCard : public OPimContactAccessBackend {
48 public: 48 public:
49 OPimContactAccessBackend_VCard ( const QString& appname, const QString& filename = QString::null ); 49 OPimContactAccessBackend_VCard ( const QString& appname, const QString& filename = QString::null );
50 50
51 bool load (); 51 bool load ();
52 bool reload(); 52 bool reload();
53 bool save(); 53 bool save();
54 void clear (); 54 void clear ();
55 55
56 bool add ( const OPimContact& newcontact ); 56 bool add ( const OPimContact& newcontact );
57 bool remove ( int uid ); 57 bool remove ( int uid );
58 bool replace ( const OPimContact& contact ); 58 bool replace ( const OPimContact& contact );
59 59
60 OPimContact find ( int uid ) const; 60 OPimContact find ( int uid ) const;
61 QArray<int> allRecords() const; 61 QArray<int> allRecords() const;
62 QArray<int> queryByExample ( const OPimContact &query, int settings, const QDateTime& d = QDateTime() );
63 QArray<int> matchRegexp( const QRegExp &r ) const;
64 62
65 const uint querySettings(); 63 const uint querySettings();
66 bool hasQuerySettings (uint querySettings) const; 64 bool hasQuerySettings (uint querySettings) const;
67 QArray<int> sorted( bool ascending, int sortOrder, int sortFilter, int cat );
68 bool wasChangedExternally(); 65 bool wasChangedExternally();
69 66
70private: 67private:
71 OPimContact parseVObject( VObject* obj ); 68 OPimContact parseVObject( VObject* obj );
72 VObject* createVObject( const OPimContact& c ); 69 VObject* createVObject( const OPimContact& c );
73 QString convDateToVCardDate( const QDate& c ) const; 70 QString convDateToVCardDate( const QDate& c ) const;
74 QDate convVCardDateToDate( const QString& datestr ); 71 QDate convVCardDateToDate( const QString& datestr );
75 VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value ); 72 VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value );
76 VObject *safeAddProp( VObject* o, const char* prop); 73 VObject *safeAddProp( VObject* o, const char* prop);
77 74
78 bool m_dirty : 1; 75 bool m_dirty : 1;
79 QString m_file; 76 QString m_file;
80 QMap<int, OPimContact> m_map; 77 QMap<int, OPimContact> m_map;
81}; 78};
82 79
83} 80}
84 81
85#endif 82#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
index 18113c2..5df7253 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
@@ -1,750 +1,729 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * XML Backend for the OPIE-Contact Database. 30 * XML Backend for the OPIE-Contact Database.
31 */ 31 */
32 32
33 33
34/* OPIE */ 34/* OPIE */
35#include <opie2/ocontactaccessbackend_xml.h> 35#include <opie2/ocontactaccessbackend_xml.h>
36#include <opie2/xmltree.h> 36#include <opie2/xmltree.h>
37#include <opie2/ocontactaccessbackend.h> 37#include <opie2/ocontactaccessbackend.h>
38#include <opie2/ocontactaccess.h> 38#include <opie2/ocontactaccess.h>
39#include <opie2/odebug.h> 39#include <opie2/odebug.h>
40 40
41#include <qpe/global.h> 41#include <qpe/global.h>
42 42
43/* QT */ 43/* QT */
44#include <qasciidict.h> 44#include <qasciidict.h>
45#include <qfile.h> 45#include <qfile.h>
46#include <qfileinfo.h> 46#include <qfileinfo.h>
47#include <qregexp.h> 47#include <qregexp.h>
48#include <qarray.h> 48#include <qarray.h>
49#include <qmap.h> 49#include <qmap.h>
50 50
51/* STD */ 51/* STD */
52#include <stdlib.h> 52#include <stdlib.h>
53#include <errno.h> 53#include <errno.h>
54 54
55using namespace Opie::Core; 55using namespace Opie::Core;
56 56
57 57
58namespace Opie { 58namespace Opie {
59OPimContactAccessBackend_XML::OPimContactAccessBackend_XML ( const QString& appname, const QString& filename ): 59OPimContactAccessBackend_XML::OPimContactAccessBackend_XML ( const QString& appname, const QString& filename ):
60 m_changed( false ) 60 m_changed( false )
61{ 61{
62 // Just m_contactlist should call delete if an entry 62 // Just m_contactlist should call delete if an entry
63 // is removed. 63 // is removed.
64 m_contactList.setAutoDelete( true ); 64 m_contactList.setAutoDelete( true );
65 m_uidToContact.setAutoDelete( false ); 65 m_uidToContact.setAutoDelete( false );
66 66
67 m_appName = appname; 67 m_appName = appname;
68 68
69 /* Set journalfile name ... */ 69 /* Set journalfile name ... */
70 m_journalName = getenv("HOME"); 70 m_journalName = getenv("HOME");
71 m_journalName +="/.abjournal" + appname; 71 m_journalName +="/.abjournal" + appname;
72 72
73 /* Expecting to access the default filename if nothing else is set */ 73 /* Expecting to access the default filename if nothing else is set */
74 if ( filename.isEmpty() ){ 74 if ( filename.isEmpty() ){
75 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 75 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
76 } else 76 } else
77 m_fileName = filename; 77 m_fileName = filename;
78 78
79 /* Load Database now */ 79 /* Load Database now */
80 load (); 80 load ();
81} 81}
82 82
83bool OPimContactAccessBackend_XML::save() 83bool OPimContactAccessBackend_XML::save()
84{ 84{
85 85
86 if ( !m_changed ) 86 if ( !m_changed )
87 return true; 87 return true;
88 88
89 QString strNewFile = m_fileName + ".new"; 89 QString strNewFile = m_fileName + ".new";
90 QFile f( strNewFile ); 90 QFile f( strNewFile );
91 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 91 if ( !f.open( IO_WriteOnly|IO_Raw ) )
92 return false; 92 return false;
93 93
94 int total_written; 94 int total_written;
95 int idx_offset = 0; 95 int idx_offset = 0;
96 QString out; 96 QString out;
97 97
98 // Write Header 98 // Write Header
99 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 99 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
100 " <Groups>\n" 100 " <Groups>\n"
101 " </Groups>\n" 101 " </Groups>\n"
102 " <Contacts>\n"; 102 " <Contacts>\n";
103 QCString cstr = out.utf8(); 103 QCString cstr = out.utf8();
104 f.writeBlock( cstr.data(), cstr.length() ); 104 f.writeBlock( cstr.data(), cstr.length() );
105 idx_offset += cstr.length(); 105 idx_offset += cstr.length();
106 out = ""; 106 out = "";
107 107
108 // Write all contacts 108 // Write all contacts
109 QListIterator<OPimContact> it( m_contactList ); 109 QListIterator<OPimContact> it( m_contactList );
110 for ( ; it.current(); ++it ) { 110 for ( ; it.current(); ++it ) {
111 // owarn << " Uid " << (*it)->uid() << " at Offset: " << idx_offset << "" << oendl;
112 out += "<Contact "; 111 out += "<Contact ";
113 (*it)->save( out ); 112 (*it)->save( out );
114 out += "/>\n"; 113 out += "/>\n";
115 cstr = out.utf8(); 114 cstr = out.utf8();
116 total_written = f.writeBlock( cstr.data(), cstr.length() ); 115 total_written = f.writeBlock( cstr.data(), cstr.length() );
117 idx_offset += cstr.length(); 116 idx_offset += cstr.length();
118 if ( total_written != int(cstr.length()) ) { 117 if ( total_written != int(cstr.length()) ) {
119 f.close(); 118 f.close();
120 QFile::remove( strNewFile ); 119 QFile::remove( strNewFile );
121 return false; 120 return false;
122 } 121 }
123 out = ""; 122 out = "";
124 } 123 }
125 out += " </Contacts>\n</AddressBook>\n"; 124 out += " </Contacts>\n</AddressBook>\n";
126 125
127 // Write Footer 126 // Write Footer
128 cstr = out.utf8(); 127 cstr = out.utf8();
129 total_written = f.writeBlock( cstr.data(), cstr.length() ); 128 total_written = f.writeBlock( cstr.data(), cstr.length() );
130 if ( total_written != int( cstr.length() ) ) { 129 if ( total_written != int( cstr.length() ) ) {
131 f.close(); 130 f.close();
132 QFile::remove( strNewFile ); 131 QFile::remove( strNewFile );
133 return false; 132 return false;
134 } 133 }
135 f.close(); 134 f.close();
136 135
137 // move the file over, I'm just going to use the system call 136 // move the file over, I'm just going to use the system call
138 // because, I don't feel like using QDir. 137 // because, I don't feel like using QDir.
139 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 138 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
140 owarn << "problem renaming file " << strNewFile << " to " << m_journalName
141 << ", errno: " << errno << oendl;
142 // remove the tmp file... 139 // remove the tmp file...
143 QFile::remove( strNewFile ); 140 QFile::remove( strNewFile );
144 } 141 }
145 142
146 /* The journalfile should be removed now... */ 143 /* The journalfile should be removed now... */
147 removeJournal(); 144 removeJournal();
148 145
149 m_changed = false; 146 m_changed = false;
150 return true; 147 return true;
151} 148}
152 149
153bool OPimContactAccessBackend_XML::load () 150bool OPimContactAccessBackend_XML::load ()
154{ 151{
155 m_contactList.clear(); 152 m_contactList.clear();
156 m_uidToContact.clear(); 153 m_uidToContact.clear();
157 154
158 /* Load XML-File and journal if it exists */ 155 /* Load XML-File and journal if it exists */
159 if ( !load ( m_fileName, false ) ) 156 if ( !load ( m_fileName, false ) )
160 return false; 157 return false;
161 /* The returncode of the journalfile is ignored due to the 158 /* The returncode of the journalfile is ignored due to the
162 * fact that it does not exist when this class is instantiated ! 159 * fact that it does not exist when this class is instantiated !
163 * But there may such a file exist, if the application crashed. 160 * But there may such a file exist, if the application crashed.
164 * Therefore we try to load it to get the changes before the # 161 * Therefore we try to load it to get the changes before the #
165 * crash happened... 162 * crash happened...
166 */ 163 */
167 load (m_journalName, true); 164 load (m_journalName, true);
168 165
169 return true; 166 return true;
170} 167}
171 168
172void OPimContactAccessBackend_XML::clear () 169void OPimContactAccessBackend_XML::clear ()
173{ 170{
174 m_contactList.clear(); 171 m_contactList.clear();
175 m_uidToContact.clear(); 172 m_uidToContact.clear();
176 173
177 m_changed = false; 174 m_changed = false;
178} 175}
179 176
180bool OPimContactAccessBackend_XML::wasChangedExternally() 177bool OPimContactAccessBackend_XML::wasChangedExternally()
181{ 178{
182 QFileInfo fi( m_fileName ); 179 QFileInfo fi( m_fileName );
183 180
184 QDateTime lastmod = fi.lastModified (); 181 QDateTime lastmod = fi.lastModified ();
185 182
186 return (lastmod != m_readtime); 183 return (lastmod != m_readtime);
187} 184}
188 185
189QArray<int> OPimContactAccessBackend_XML::allRecords() const 186QArray<int> OPimContactAccessBackend_XML::allRecords() const
190{ 187{
191 QArray<int> uid_list( m_contactList.count() ); 188 QArray<int> uid_list( m_contactList.count() );
192 189
193 uint counter = 0; 190 uint counter = 0;
194 QListIterator<OPimContact> it( m_contactList ); 191 QListIterator<OPimContact> it( m_contactList );
195 for( ; it.current(); ++it ){ 192 for( ; it.current(); ++it ){
196 uid_list[counter++] = (*it)->uid(); 193 uid_list[counter++] = (*it)->uid();
197 } 194 }
198 195
199 return ( uid_list ); 196 return ( uid_list );
200} 197}
201 198
202OPimContact OPimContactAccessBackend_XML::find ( int uid ) const 199OPimContact OPimContactAccessBackend_XML::find ( int uid ) const
203{ 200{
204 OPimContact foundContact; //Create empty contact 201 OPimContact foundContact; //Create empty contact
205 202
206 OPimContact* found = m_uidToContact.find( QString().setNum( uid ) ); 203 OPimContact* found = m_uidToContact.find( QString().setNum( uid ) );
207 204
208 if ( found ){ 205 if ( found ){
209 foundContact = *found; 206 foundContact = *found;
210 } 207 }
211 208
212 return ( foundContact ); 209 return ( foundContact );
213} 210}
214 211
215QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings, 212QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings,
216 const QDateTime& d ) 213 const QDateTime& d )const
217{ 214{
218
219 QArray<int> m_currentQuery( m_contactList.count() ); 215 QArray<int> m_currentQuery( m_contactList.count() );
220 QListIterator<OPimContact> it( m_contactList ); 216 QListIterator<OPimContact> it( m_contactList );
221 uint arraycounter = 0; 217 uint arraycounter = 0;
222 218
223 for( ; it.current(); ++it ){ 219 for( ; it.current(); ++it ){
224 /* Search all fields and compare them with query object. Store them into list 220 /* Search all fields and compare them with query object. Store them into list
225 * if all fields matches. 221 * if all fields matches.
226 */ 222 */
227 QDate* queryDate = 0l; 223 QDate* queryDate = 0l;
228 QDate* checkDate = 0l; 224 QDate* checkDate = 0l;
229 bool allcorrect = true; 225 bool allcorrect = true;
230 for ( int i = 0; i < Qtopia::Groups; i++ ) { 226 for ( int i = 0; i < Qtopia::Groups; i++ ) {
231 // Birthday and anniversary are special nonstring fields and should 227 // Birthday and anniversary are special nonstring fields and should
232 // be handled specially 228 // be handled specially
233 switch ( i ){ 229 switch ( i ){
234 case Qtopia::Birthday: 230 case Qtopia::Birthday:
235 queryDate = new QDate( query.birthday() ); 231 queryDate = new QDate( query.birthday() );
236 checkDate = new QDate( (*it)->birthday() ); 232 checkDate = new QDate( (*it)->birthday() );
237 // fall through 233 // fall through
238 case Qtopia::Anniversary: 234 case Qtopia::Anniversary:
239 if ( queryDate == 0l ){ 235 if ( queryDate == 0l ){
240 queryDate = new QDate( query.anniversary() ); 236 queryDate = new QDate( query.anniversary() );
241 checkDate = new QDate( (*it)->anniversary() ); 237 checkDate = new QDate( (*it)->anniversary() );
242 } 238 }
243 239
244 if ( queryDate->isValid() ){ 240 if ( queryDate->isValid() ){
245 if( checkDate->isValid() ){ 241 if( checkDate->isValid() ){
246 if ( settings & OPimContactAccess::DateYear ){ 242 if ( settings & OPimContactAccess::DateYear ){
247 if ( queryDate->year() != checkDate->year() ) 243 if ( queryDate->year() != checkDate->year() )
248 allcorrect = false; 244 allcorrect = false;
249 } 245 }
250 if ( settings & OPimContactAccess::DateMonth ){ 246 if ( settings & OPimContactAccess::DateMonth ){
251 if ( queryDate->month() != checkDate->month() ) 247 if ( queryDate->month() != checkDate->month() )
252 allcorrect = false; 248 allcorrect = false;
253 } 249 }
254 if ( settings & OPimContactAccess::DateDay ){ 250 if ( settings & OPimContactAccess::DateDay ){
255 if ( queryDate->day() != checkDate->day() ) 251 if ( queryDate->day() != checkDate->day() )
256 allcorrect = false; 252 allcorrect = false;
257 } 253 }
258 if ( settings & OPimContactAccess::DateDiff ) { 254 if ( settings & OPimContactAccess::DateDiff ) {
259 QDate current; 255 QDate current;
260 // If we get an additional date, we 256 // If we get an additional date, we
261 // will take this date instead of 257 // will take this date instead of
262 // the current one.. 258 // the current one..
263 if ( !d.date().isValid() ) 259 if ( !d.date().isValid() )
264 current = QDate::currentDate(); 260 current = QDate::currentDate();
265 else 261 else
266 current = d.date(); 262 current = d.date();
267 263
268 // We have to equalize the year, otherwise 264 // We have to equalize the year, otherwise
269 // the search will fail.. 265 // the search will fail..
270 checkDate->setYMD( current.year(), 266 checkDate->setYMD( current.year(),
271 checkDate->month(), 267 checkDate->month(),
272 checkDate->day() ); 268 checkDate->day() );
273 if ( *checkDate < current ) 269 if ( *checkDate < current )
274 checkDate->setYMD( current.year()+1, 270 checkDate->setYMD( current.year()+1,
275 checkDate->month(), 271 checkDate->month(),
276 checkDate->day() ); 272 checkDate->day() );
277 273
278 // Check whether the birthday/anniversary date is between 274 // Check whether the birthday/anniversary date is between
279 // the current/given date and the maximum date 275 // the current/given date and the maximum date
280 // ( maximum time range ) ! 276 // ( maximum time range ) !
281 owarn << "Checking if " << checkDate->toString() << " is between " << current.toString()
282 << " and " << queryDate->toString() << " ! " << oendl;
283 if ( current.daysTo( *queryDate ) >= 0 ){ 277 if ( current.daysTo( *queryDate ) >= 0 ){
284 if ( !( ( *checkDate >= current ) && 278 if ( !( ( *checkDate >= current ) &&
285 ( *checkDate <= *queryDate ) ) ){ 279 ( *checkDate <= *queryDate ) ) ){
286 allcorrect = false; 280 allcorrect = false;
287 owarn << " Nope!.." << oendl;
288 } 281 }
289 } 282 }
290 } 283 }
291 } else{ 284 } else{
292 // checkDate is invalid. Therefore this entry is always rejected 285 // checkDate is invalid. Therefore this entry is always rejected
293 allcorrect = false; 286 allcorrect = false;
294 } 287 }
295 } 288 }
296 289
297 delete queryDate; 290 delete queryDate;
298 queryDate = 0l; 291 queryDate = 0l;
299 delete checkDate; 292 delete checkDate;
300 checkDate = 0l; 293 checkDate = 0l;
301 break; 294 break;
302 default: 295 default:
303 /* Just compare fields which are not empty in the query object */ 296 /* Just compare fields which are not empty in the query object */
304 if ( !query.field(i).isEmpty() ){ 297 if ( !query.field(i).isEmpty() ){
305 switch ( settings & ~( OPimContactAccess::IgnoreCase 298 switch ( settings & ~( OPimContactAccess::IgnoreCase
306 | OPimContactAccess::DateDiff 299 | OPimContactAccess::DateDiff
307 | OPimContactAccess::DateYear 300 | OPimContactAccess::DateYear
308 | OPimContactAccess::DateMonth 301 | OPimContactAccess::DateMonth
309 | OPimContactAccess::DateDay 302 | OPimContactAccess::DateDay
310 | OPimContactAccess::MatchOne 303 | OPimContactAccess::MatchOne
311 ) ){ 304 ) ){
312 305
313 case OPimContactAccess::RegExp:{ 306 case OPimContactAccess::RegExp:{
314 QRegExp expr ( query.field(i), 307 QRegExp expr ( query.field(i),
315 !(settings & OPimContactAccess::IgnoreCase), 308 !(settings & OPimContactAccess::IgnoreCase),
316 false ); 309 false );
317 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 310 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
318 allcorrect = false; 311 allcorrect = false;
319 } 312 }
320 break; 313 break;
321 case OPimContactAccess::WildCards:{ 314 case OPimContactAccess::WildCards:{
322 QRegExp expr ( query.field(i), 315 QRegExp expr ( query.field(i),
323 !(settings & OPimContactAccess::IgnoreCase), 316 !(settings & OPimContactAccess::IgnoreCase),
324 true ); 317 true );
325 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 318 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
326 allcorrect = false; 319 allcorrect = false;
327 } 320 }
328 break; 321 break;
329 case OPimContactAccess::ExactMatch:{ 322 case OPimContactAccess::ExactMatch:{
330 if (settings & OPimContactAccess::IgnoreCase){ 323 if (settings & OPimContactAccess::IgnoreCase){
331 if ( query.field(i).upper() != 324 if ( query.field(i).upper() !=
332 (*it)->field(i).upper() ) 325 (*it)->field(i).upper() )
333 allcorrect = false; 326 allcorrect = false;
334 }else{ 327 }else{
335 if ( query.field(i) != (*it)->field(i) ) 328 if ( query.field(i) != (*it)->field(i) )
336 allcorrect = false; 329 allcorrect = false;
337 } 330 }
338 } 331 }
339 break; 332 break;
340 } 333 }
341 } 334 }
342 } 335 }
343 } 336 }
344 if ( allcorrect ){ 337 if ( allcorrect ){
345 m_currentQuery[arraycounter++] = (*it)->uid(); 338 m_currentQuery[arraycounter++] = (*it)->uid();
346 } 339 }
347 } 340 }
348 341
349 // Shrink to fit.. 342 // Shrink to fit..
350 m_currentQuery.resize(arraycounter); 343 m_currentQuery.resize(arraycounter);
351 344
352 return m_currentQuery; 345 return m_currentQuery;
353} 346}
354 347
355QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const 348QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
356{ 349{
357 QArray<int> m_currentQuery( m_contactList.count() ); 350 QArray<int> m_currentQuery( m_contactList.count() );
358 QListIterator<OPimContact> it( m_contactList ); 351 QListIterator<OPimContact> it( m_contactList );
359 uint arraycounter = 0; 352 uint arraycounter = 0;
360 353
361 for( ; it.current(); ++it ){ 354 for( ; it.current(); ++it ){
362 if ( (*it)->match( r ) ){ 355 if ( (*it)->match( r ) ){
363 m_currentQuery[arraycounter++] = (*it)->uid(); 356 m_currentQuery[arraycounter++] = (*it)->uid();
364 } 357 }
365 358
366 } 359 }
367 // Shrink to fit.. 360 // Shrink to fit..
368 m_currentQuery.resize(arraycounter); 361 m_currentQuery.resize(arraycounter);
369 362
370 return m_currentQuery; 363 return m_currentQuery;
371} 364}
372 365
373const uint OPimContactAccessBackend_XML::querySettings() 366const uint OPimContactAccessBackend_XML::querySettings()
374{ 367{
375 return ( OPimContactAccess::WildCards 368 return ( OPimContactAccess::WildCards
376 | OPimContactAccess::IgnoreCase 369 | OPimContactAccess::IgnoreCase
377 | OPimContactAccess::RegExp 370 | OPimContactAccess::RegExp
378 | OPimContactAccess::ExactMatch 371 | OPimContactAccess::ExactMatch
379 | OPimContactAccess::DateDiff 372 | OPimContactAccess::DateDiff
380 | OPimContactAccess::DateYear 373 | OPimContactAccess::DateYear
381 | OPimContactAccess::DateMonth 374 | OPimContactAccess::DateMonth
382 | OPimContactAccess::DateDay 375 | OPimContactAccess::DateDay
383 ); 376 );
384} 377}
385 378
386bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const 379bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const
387{ 380{
388 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 381 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
389 * may be added with any of the other settings. IgnoreCase should never used alone. 382 * may be added with any of the other settings. IgnoreCase should never used alone.
390 * Wildcards, RegExp, ExactMatch should never used at the same time... 383 * Wildcards, RegExp, ExactMatch should never used at the same time...
391 */ 384 */
392 385
393 // Step 1: Check whether the given settings are supported by this backend 386 // Step 1: Check whether the given settings are supported by this backend
394 if ( ( querySettings & ( 387 if ( ( querySettings & (
395 OPimContactAccess::IgnoreCase 388 OPimContactAccess::IgnoreCase
396 | OPimContactAccess::WildCards 389 | OPimContactAccess::WildCards
397 | OPimContactAccess::DateDiff 390 | OPimContactAccess::DateDiff
398 | OPimContactAccess::DateYear 391 | OPimContactAccess::DateYear
399 | OPimContactAccess::DateMonth 392 | OPimContactAccess::DateMonth
400 | OPimContactAccess::DateDay 393 | OPimContactAccess::DateDay
401 | OPimContactAccess::RegExp 394 | OPimContactAccess::RegExp
402 | OPimContactAccess::ExactMatch 395 | OPimContactAccess::ExactMatch
403 ) ) != querySettings ) 396 ) ) != querySettings )
404 return false; 397 return false;
405 398
406 // Step 2: Check whether the given combinations are ok.. 399 // Step 2: Check whether the given combinations are ok..
407 400
408 // IngoreCase alone is invalid 401 // IngoreCase alone is invalid
409 if ( querySettings == OPimContactAccess::IgnoreCase ) 402 if ( querySettings == OPimContactAccess::IgnoreCase )
410 return false; 403 return false;
411 404
412 // WildCards, RegExp and ExactMatch should never used at the same time 405 // WildCards, RegExp and ExactMatch should never used at the same time
413 switch ( querySettings & ~( OPimContactAccess::IgnoreCase 406 switch ( querySettings & ~( OPimContactAccess::IgnoreCase
414 | OPimContactAccess::DateDiff 407 | OPimContactAccess::DateDiff
415 | OPimContactAccess::DateYear 408 | OPimContactAccess::DateYear
416 | OPimContactAccess::DateMonth 409 | OPimContactAccess::DateMonth
417 | OPimContactAccess::DateDay 410 | OPimContactAccess::DateDay
418 ) 411 )
419 ){ 412 ){
420 case OPimContactAccess::RegExp: 413 case OPimContactAccess::RegExp:
421 return ( true ); 414 return ( true );
422 case OPimContactAccess::WildCards: 415 case OPimContactAccess::WildCards:
423 return ( true ); 416 return ( true );
424 case OPimContactAccess::ExactMatch: 417 case OPimContactAccess::ExactMatch:
425 return ( true ); 418 return ( true );
426 case 0: // one of the upper removed bits were set.. 419 case 0: // one of the upper removed bits were set..
427 return ( true ); 420 return ( true );
428 default: 421 default:
429 return ( false ); 422 return ( false );
430 } 423 }
431} 424}
432 425
426#if 0
433// Currently only asc implemented.. 427// Currently only asc implemented..
434QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) 428QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int )
435{ 429{
436 QMap<QString, int> nameToUid; 430 QMap<QString, int> nameToUid;
437 QStringList names; 431 QStringList names;
438 QArray<int> m_currentQuery( m_contactList.count() ); 432 QArray<int> m_currentQuery( m_contactList.count() );
439 433
440 // First fill map and StringList with all Names 434 // First fill map and StringList with all Names
441 // Afterwards sort namelist and use map to fill array to return.. 435 // Afterwards sort namelist and use map to fill array to return..
442 QListIterator<OPimContact> it( m_contactList ); 436 QListIterator<OPimContact> it( m_contactList );
443 for( ; it.current(); ++it ){ 437 for( ; it.current(); ++it ){
444 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); 438 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) );
445 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); 439 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() );
446 } 440 }
447 names.sort(); 441 names.sort();
448 442
449 int i = 0; 443 int i = 0;
450 if ( asc ){ 444 if ( asc ){
451 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 445 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
452 m_currentQuery[i++] = nameToUid[ (*it) ]; 446 m_currentQuery[i++] = nameToUid[ (*it) ];
453 }else{ 447 }else{
454 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 448 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
455 m_currentQuery[i++] = nameToUid[ (*it) ]; 449 m_currentQuery[i++] = nameToUid[ (*it) ];
456 } 450 }
457 451
458 return m_currentQuery; 452 return m_currentQuery;
459 453
460} 454}
455#endif
456
461 457
462bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact ) 458bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact )
463{ 459{
464 //owarn << "odefaultbackend: ACTION::ADD" << oendl;
465 updateJournal (newcontact, ACTION_ADD); 460 updateJournal (newcontact, ACTION_ADD);
466 addContact_p( newcontact ); 461 addContact_p( newcontact );
467 462
468 m_changed = true; 463 m_changed = true;
469 464
470 return true; 465 return true;
471} 466}
472 467
473bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact ) 468bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact )
474{ 469{
475 m_changed = true; 470 m_changed = true;
476 471
477 OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); 472 OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) );
478 473
479 if ( found ) { 474 if ( found ) {
480 OPimContact* newCont = new OPimContact( contact ); 475 OPimContact* newCont = new OPimContact( contact );
481 476
482 updateJournal ( *newCont, ACTION_REPLACE); 477 updateJournal ( *newCont, ACTION_REPLACE);
483 m_contactList.removeRef ( found ); 478 m_contactList.removeRef ( found );
484 m_contactList.append ( newCont ); 479 m_contactList.append ( newCont );
485 m_uidToContact.remove( QString().setNum( contact.uid() ) ); 480 m_uidToContact.remove( QString().setNum( contact.uid() ) );
486 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); 481 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont );
487 482
488 owarn << "Nur zur Sicherheit: " << contact.uid() << " == " << newCont->uid() << " ?" << oendl;
489
490 return true; 483 return true;
491 } else 484 } else
492 return false; 485 return false;
493} 486}
494 487
495bool OPimContactAccessBackend_XML::remove ( int uid ) 488bool OPimContactAccessBackend_XML::remove ( int uid )
496{ 489{
497 m_changed = true; 490 m_changed = true;
498 491
499 OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) ); 492 OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) );
500 493
501 if ( found ) { 494 if ( found ) {
502 updateJournal ( *found, ACTION_REMOVE); 495 updateJournal ( *found, ACTION_REMOVE);
503 m_contactList.removeRef ( found ); 496 m_contactList.removeRef ( found );
504 m_uidToContact.remove( QString().setNum( uid ) ); 497 m_uidToContact.remove( QString().setNum( uid ) );
505 498
506 return true; 499 return true;
507 } else 500 } else
508 return false; 501 return false;
509} 502}
510 503
511bool OPimContactAccessBackend_XML::reload(){ 504bool OPimContactAccessBackend_XML::reload(){
512 /* Reload is the same as load in this implementation */ 505 /* Reload is the same as load in this implementation */
513 return ( load() ); 506 return ( load() );
514} 507}
515 508
516void OPimContactAccessBackend_XML::addContact_p( const OPimContact &newcontact ) 509void OPimContactAccessBackend_XML::addContact_p( const OPimContact &newcontact )
517{ 510{
518 OPimContact* contRef = new OPimContact( newcontact ); 511 OPimContact* contRef = new OPimContact( newcontact );
519 512
520 m_contactList.append ( contRef ); 513 m_contactList.append ( contRef );
521 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); 514 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef );
522} 515}
523 516
524/* This function loads the xml-database and the journalfile */ 517/* This function loads the xml-database and the journalfile */
525bool OPimContactAccessBackend_XML::load( const QString filename, bool isJournal ) 518bool OPimContactAccessBackend_XML::load( const QString filename, bool isJournal )
526{ 519{
527 520
528 /* We use the time of the last read to check if the file was 521 /* We use the time of the last read to check if the file was
529 * changed externally. 522 * changed externally.
530 */ 523 */
531 if ( !isJournal ){ 524 if ( !isJournal ){
532 QFileInfo fi( filename ); 525 QFileInfo fi( filename );
533 m_readtime = fi.lastModified (); 526 m_readtime = fi.lastModified ();
534 } 527 }
535 528
536 const int JOURNALACTION = Qtopia::Notes + 1; 529 const int JOURNALACTION = Qtopia::Notes + 1;
537 const int JOURNALROW = JOURNALACTION + 1; 530 const int JOURNALROW = JOURNALACTION + 1;
538 531
539 bool foundAction = false; 532 bool foundAction = false;
540 journal_action action = ACTION_ADD; 533 journal_action action = ACTION_ADD;
541 int journalKey = 0; 534 int journalKey = 0;
542 QMap<int, QString> contactMap; 535 QMap<int, QString> contactMap;
543 QMap<QString, QString> customMap; 536 QMap<QString, QString> customMap;
544 QMap<QString, QString>::Iterator customIt; 537 QMap<QString, QString>::Iterator customIt;
545 QAsciiDict<int> dict( 47 ); 538 QAsciiDict<int> dict( 47 );
546 539
547 dict.setAutoDelete( TRUE ); 540 dict.setAutoDelete( TRUE );
548 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 541 dict.insert( "Uid", new int(Qtopia::AddressUid) );
549 dict.insert( "Title", new int(Qtopia::Title) ); 542 dict.insert( "Title", new int(Qtopia::Title) );
550 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 543 dict.insert( "FirstName", new int(Qtopia::FirstName) );
551 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 544 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
552 dict.insert( "LastName", new int(Qtopia::LastName) ); 545 dict.insert( "LastName", new int(Qtopia::LastName) );
553 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 546 dict.insert( "Suffix", new int(Qtopia::Suffix) );
554 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 547 dict.insert( "FileAs", new int(Qtopia::FileAs) );
555 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 548 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
556 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 549 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
557 dict.insert( "Emails", new int(Qtopia::Emails) ); 550 dict.insert( "Emails", new int(Qtopia::Emails) );
558 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 551 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
559 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 552 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
560 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 553 dict.insert( "HomeState", new int(Qtopia::HomeState) );
561 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 554 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
562 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 555 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
563 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 556 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
564 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 557 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
565 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 558 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
566 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 559 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
567 dict.insert( "Company", new int(Qtopia::Company) ); 560 dict.insert( "Company", new int(Qtopia::Company) );
568 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 561 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
569 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 562 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
570 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 563 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
571 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 564 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
572 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 565 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
573 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 566 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
574 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 567 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
575 dict.insert( "Department", new int(Qtopia::Department) ); 568 dict.insert( "Department", new int(Qtopia::Department) );
576 dict.insert( "Office", new int(Qtopia::Office) ); 569 dict.insert( "Office", new int(Qtopia::Office) );
577 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); 570 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
578 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); 571 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
579 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); 572 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
580 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); 573 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
581 dict.insert( "Profession", new int(Qtopia::Profession) ); 574 dict.insert( "Profession", new int(Qtopia::Profession) );
582 dict.insert( "Assistant", new int(Qtopia::Assistant) ); 575 dict.insert( "Assistant", new int(Qtopia::Assistant) );
583 dict.insert( "Manager", new int(Qtopia::Manager) ); 576 dict.insert( "Manager", new int(Qtopia::Manager) );
584 dict.insert( "Spouse", new int(Qtopia::Spouse) ); 577 dict.insert( "Spouse", new int(Qtopia::Spouse) );
585 dict.insert( "Children", new int(Qtopia::Children) ); 578 dict.insert( "Children", new int(Qtopia::Children) );
586 dict.insert( "Gender", new int(Qtopia::Gender) ); 579 dict.insert( "Gender", new int(Qtopia::Gender) );
587 dict.insert( "Birthday", new int(Qtopia::Birthday) ); 580 dict.insert( "Birthday", new int(Qtopia::Birthday) );
588 dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); 581 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
589 dict.insert( "Nickname", new int(Qtopia::Nickname) ); 582 dict.insert( "Nickname", new int(Qtopia::Nickname) );
590 dict.insert( "Notes", new int(Qtopia::Notes) ); 583 dict.insert( "Notes", new int(Qtopia::Notes) );
591 dict.insert( "action", new int(JOURNALACTION) ); 584 dict.insert( "action", new int(JOURNALACTION) );
592 dict.insert( "actionrow", new int(JOURNALROW) ); 585 dict.insert( "actionrow", new int(JOURNALROW) );
593 586
594 //owarn << "OPimContactDefaultBackEnd::loading " << filename << "" << oendl;
595
596 XMLElement *root = XMLElement::load( filename ); 587 XMLElement *root = XMLElement::load( filename );
597 if(root != 0l ){ // start parsing 588 if(root != 0l ){ // start parsing
598 /* Parse all XML-Elements and put the data into the 589 /* Parse all XML-Elements and put the data into the
599 * Contact-Class 590 * Contact-Class
600 */ 591 */
601 XMLElement *element = root->firstChild(); 592 XMLElement *element = root->firstChild();
602 //owarn << "OPimContactAccess::load tagName(): " << root->tagName() << "" << oendl;
603 element = element ? element->firstChild() : 0; 593 element = element ? element->firstChild() : 0;
604 594
605 /* Search Tag "Contacts" which is the parent of all Contacts */ 595 /* Search Tag "Contacts" which is the parent of all Contacts */
606 while( element && !isJournal ){ 596 while( element && !isJournal ){
607 if( element->tagName() != QString::fromLatin1("Contacts") ){ 597 if( element->tagName() != QString::fromLatin1("Contacts") ){
608 //owarn << "OPimContactDefBack::Searching for Tag \"Contacts\"! Found: "
609 // << element->tagName() << oendl;
610 element = element->nextChild(); 598 element = element->nextChild();
611 } else { 599 } else {
612 element = element->firstChild(); 600 element = element->firstChild();
613 break; 601 break;
614 } 602 }
615 } 603 }
616 /* Parse all Contacts and ignore unknown tags */ 604 /* Parse all Contacts and ignore unknown tags */
617 while( element ){ 605 while( element ){
618 if( element->tagName() != QString::fromLatin1("Contact") ){ 606 if( element->tagName() != QString::fromLatin1("Contact") ){
619 //owarn << "OPimContactDefBack::Searching for Tag \"Contact\"! Found: "
620 // << element->tagName() << oendl;
621 element = element->nextChild(); 607 element = element->nextChild();
622 continue; 608 continue;
623 } 609 }
624 /* Found alement with tagname "contact", now parse and store all 610 /* Found alement with tagname "contact", now parse and store all
625 * attributes contained 611 * attributes contained
626 */ 612 */
627 //owarn << "OPimContactDefBack::load element tagName() : "
628 // << element->tagName() << oendl;
629 QString dummy; 613 QString dummy;
630 foundAction = false; 614 foundAction = false;
631 615
632 XMLElement::AttributeMap aMap = element->attributes(); 616 XMLElement::AttributeMap aMap = element->attributes();
633 XMLElement::AttributeMap::Iterator it; 617 XMLElement::AttributeMap::Iterator it;
634 contactMap.clear(); 618 contactMap.clear();
635 customMap.clear(); 619 customMap.clear();
636 for( it = aMap.begin(); it != aMap.end(); ++it ){ 620 for( it = aMap.begin(); it != aMap.end(); ++it ){
637 // owarn << "Read Attribute: " << it.key() << "=" << it.data() << oendl;
638
639 int *find = dict[ it.key() ]; 621 int *find = dict[ it.key() ];
640 /* Unknown attributes will be stored as "Custom" elements */ 622 /* Unknown attributes will be stored as "Custom" elements */
641 if ( !find ) { 623 if ( !find ) {
642 // owarn << "Attribute " << it.key() << " not known." << oendl;
643 //contact.setCustomField(it.key(), it.data()); 624 //contact.setCustomField(it.key(), it.data());
644 customMap.insert( it.key(), it.data() ); 625 customMap.insert( it.key(), it.data() );
645 continue; 626 continue;
646 } 627 }
647 628
648 /* Check if special conversion is needed and add attribute 629 /* Check if special conversion is needed and add attribute
649 * into Contact class 630 * into Contact class
650 */ 631 */
651 switch( *find ) { 632 switch( *find ) {
652 /* 633 /*
653 case Qtopia::AddressUid: 634 case Qtopia::AddressUid:
654 contact.setUid( it.data().toInt() ); 635 contact.setUid( it.data().toInt() );
655 break; 636 break;
656 case Qtopia::AddressCategory: 637 case Qtopia::AddressCategory:
657 contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); 638 contact.setCategories( Qtopia::Record::idsFromString( it.data( )));
658 break; 639 break;
659 */ 640 */
660 case JOURNALACTION: 641 case JOURNALACTION:
661 action = journal_action(it.data().toInt()); 642 action = journal_action(it.data().toInt());
662 foundAction = true; 643 foundAction = true;
663 owarn << "ODefBack(journal)::ACTION found: " << action << oendl; 644 owarn << "ODefBack(journal)::ACTION found: " << action << oendl;
664 break; 645 break;
665 case JOURNALROW: 646 case JOURNALROW:
666 journalKey = it.data().toInt(); 647 journalKey = it.data().toInt();
667 break; 648 break;
668 default: // no conversion needed add them to the map 649 default: // no conversion needed add them to the map
669 contactMap.insert( *find, it.data() ); 650 contactMap.insert( *find, it.data() );
670 break; 651 break;
671 } 652 }
672 } 653 }
673 /* now generate the Contact contact */ 654 /* now generate the Contact contact */
674 OPimContact contact( contactMap ); 655 OPimContact contact( contactMap );
675 656
676 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { 657 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) {
677 contact.setCustomField( customIt.key(), customIt.data() ); 658 contact.setCustomField( customIt.key(), customIt.data() );
678 } 659 }
679 660
680 if (foundAction){ 661 if (foundAction){
681 foundAction = false; 662 foundAction = false;
682 switch ( action ) { 663 switch ( action ) {
683 case ACTION_ADD: 664 case ACTION_ADD:
684 addContact_p (contact); 665 addContact_p (contact);
685 break; 666 break;
686 case ACTION_REMOVE: 667 case ACTION_REMOVE:
687 if ( !remove (contact.uid()) ) 668 if ( !remove (contact.uid()) )
688 owarn << "ODefBack(journal)::Unable to remove uid: " << contact.uid() << oendl; 669 owarn << "ODefBack(journal)::Unable to remove uid: " << contact.uid() << oendl;
689 break; 670 break;
690 case ACTION_REPLACE: 671 case ACTION_REPLACE:
691 if ( !replace ( contact ) ) 672 if ( !replace ( contact ) )
692 owarn << "ODefBack(journal)::Unable to replace uid: " << contact.uid() << oendl; 673 owarn << "ODefBack(journal)::Unable to replace uid: " << contact.uid() << oendl;
693 break; 674 break;
694 default: 675 default:
695 owarn << "Unknown action: ignored !" << oendl; 676 owarn << "Unknown action: ignored !" << oendl;
696 break; 677 break;
697 } 678 }
698 }else{ 679 }else{
699 /* Add contact to list */ 680 /* Add contact to list */
700 addContact_p (contact); 681 addContact_p (contact);
701 } 682 }
702 683
703 /* Move to next element */ 684 /* Move to next element */
704 element = element->nextChild(); 685 element = element->nextChild();
705 } 686 }
706 }else { 687 }else {
707 owarn << "ODefBack::could not load" << oendl;
708 } 688 }
709 delete root; 689 delete root;
710 owarn << "returning from loading" << oendl;
711 return true; 690 return true;
712} 691}
713 692
714 693
715void OPimContactAccessBackend_XML::updateJournal( const OPimContact& cnt, 694void OPimContactAccessBackend_XML::updateJournal( const OPimContact& cnt,
716 journal_action action ) 695 journal_action action )
717{ 696{
718 QFile f( m_journalName ); 697 QFile f( m_journalName );
719 bool created = !f.exists(); 698 bool created = !f.exists();
720 if ( !f.open(IO_WriteOnly|IO_Append) ) 699 if ( !f.open(IO_WriteOnly|IO_Append) )
721 return; 700 return;
722 701
723 QString buf; 702 QString buf;
724 QCString str; 703 QCString str;
725 704
726 // if the file was created, we have to set the Tag "<CONTACTS>" to 705 // if the file was created, we have to set the Tag "<CONTACTS>" to
727 // get a XML-File which is readable by our parser. 706 // get a XML-File which is readable by our parser.
728 // This is just a cheat, but better than rewrite the parser. 707 // This is just a cheat, but better than rewrite the parser.
729 if ( created ){ 708 if ( created ){
730 buf = "<Contacts>"; 709 buf = "<Contacts>";
731 QCString cstr = buf.utf8(); 710 QCString cstr = buf.utf8();
732 f.writeBlock( cstr.data(), cstr.length() ); 711 f.writeBlock( cstr.data(), cstr.length() );
733 } 712 }
734 713
735 buf = "<Contact "; 714 buf = "<Contact ";
736 cnt.save( buf ); 715 cnt.save( buf );
737 buf += " action=\"" + QString::number( (int)action ) + "\" "; 716 buf += " action=\"" + QString::number( (int)action ) + "\" ";
738 buf += "/>\n"; 717 buf += "/>\n";
739 QCString cstr = buf.utf8(); 718 QCString cstr = buf.utf8();
740 f.writeBlock( cstr.data(), cstr.length() ); 719 f.writeBlock( cstr.data(), cstr.length() );
741} 720}
742 721
743void OPimContactAccessBackend_XML::removeJournal() 722void OPimContactAccessBackend_XML::removeJournal()
744{ 723{
745 QFile f ( m_journalName ); 724 QFile f ( m_journalName );
746 if ( f.exists() ) 725 if ( f.exists() )
747 f.remove(); 726 f.remove();
748} 727}
749 728
750} 729}
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
index eaea352..3e4f1e1 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
@@ -1,108 +1,105 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * XML Backend for the OPIE-Contact Database. 30 * XML Backend for the OPIE-Contact Database.
31 */ 31 */
32 32
33#ifndef _OPimContactAccessBackend_XML_ 33#ifndef _OPimContactAccessBackend_XML_
34#define _OPimContactAccessBackend_XML_ 34#define _OPimContactAccessBackend_XML_
35 35
36#include <opie2/ocontactaccessbackend.h> 36#include <opie2/ocontactaccessbackend.h>
37#include <opie2/ocontactaccess.h> 37#include <opie2/ocontactaccess.h>
38 38
39#include <qlist.h> 39#include <qlist.h>
40#include <qdict.h> 40#include <qdict.h>
41 41
42namespace Opie { 42namespace Opie {
43/* the default xml implementation */ 43/* the default xml implementation */
44/** 44/**
45 * This class is the XML implementation of a Contact backend 45 * This class is the XML implementation of a Contact backend
46 * it does implement everything available for OPimContact. 46 * it does implement everything available for OPimContact.
47 * @see OPimAccessBackend for more information of available methods 47 * @see OPimAccessBackend for more information of available methods
48 */ 48 */
49class OPimContactAccessBackend_XML : public OPimContactAccessBackend { 49class OPimContactAccessBackend_XML : public OPimContactAccessBackend {
50 public: 50 public:
51 OPimContactAccessBackend_XML ( const QString& appname, const QString& filename = QString::null ); 51 OPimContactAccessBackend_XML ( const QString& appname, const QString& filename = QString::null );
52 52
53 bool save(); 53 bool save();
54 54
55 bool load (); 55 bool load ();
56 56
57 void clear (); 57 void clear ();
58 58
59 bool wasChangedExternally(); 59 bool wasChangedExternally();
60 60
61 QArray<int> allRecords() const; 61 QArray<int> allRecords() const;
62 62
63 OPimContact find ( int uid ) const; 63 OPimContact find ( int uid ) const;
64 64
65 QArray<int> queryByExample ( const OPimContact &query, int settings, const QDateTime& d = QDateTime() ); 65 QArray<int> queryByExample ( const OPimContact &query, int settings, const QDateTime& d )const;
66
67 QArray<int> matchRegexp( const QRegExp &r ) const; 66 QArray<int> matchRegexp( const QRegExp &r ) const;
68 67
69 const uint querySettings(); 68 const uint querySettings();
70 69
71 bool hasQuerySettings (uint querySettings) const; 70 bool hasQuerySettings (uint querySettings) const;
72 71
73 // Currently only asc implemented..
74 QArray<int> sorted( bool asc, int , int , int );
75 bool add ( const OPimContact &newcontact ); 72 bool add ( const OPimContact &newcontact );
76 73
77 bool replace ( const OPimContact &contact ); 74 bool replace ( const OPimContact &contact );
78 75
79 bool remove ( int uid ); 76 bool remove ( int uid );
80 bool reload(); 77 bool reload();
81 78
82 private: 79 private:
83 80
84 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; 81 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
85 82
86 void addContact_p( const OPimContact &newcontact ); 83 void addContact_p( const OPimContact &newcontact );
87 84
88 /* This function loads the xml-database and the journalfile */ 85 /* This function loads the xml-database and the journalfile */
89 bool load( const QString filename, bool isJournal ); 86 bool load( const QString filename, bool isJournal );
90 87
91 88
92 void updateJournal( const OPimContact& cnt, journal_action action ); 89 void updateJournal( const OPimContact& cnt, journal_action action );
93 void removeJournal(); 90 void removeJournal();
94 91
95 protected: 92 protected:
96 bool m_changed; 93 bool m_changed;
97 QString m_journalName; 94 QString m_journalName;
98 QString m_fileName; 95 QString m_fileName;
99 QString m_appName; 96 QString m_appName;
100 QList<OPimContact> m_contactList; 97 QList<OPimContact> m_contactList;
101 QDateTime m_readtime; 98 QDateTime m_readtime;
102 99
103 QDict<OPimContact> m_uidToContact; 100 QDict<OPimContact> m_uidToContact;
104}; 101};
105 102
106} 103}
107 104
108#endif 105#endif
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend.cpp b/libopie2/opiepim/backend/odatebookaccessbackend.cpp
index f3b7b5f..73c7059 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend.cpp
+++ b/libopie2/opiepim/backend/odatebookaccessbackend.cpp
@@ -1,216 +1,164 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#include <qtl.h> 29#include <qtl.h>
30 30
31#include <opie2/opimrecurrence.h> 31#include <opie2/opimrecurrence.h>
32 32
33#include <opie2/odatebookaccessbackend.h> 33#include <opie2/odatebookaccessbackend.h>
34 34
35using namespace Opie; 35using namespace Opie;
36 36
37namespace { 37namespace {
38/* a small helper to get all NonRepeating events for a range of time */ 38/* a small helper to get all NonRepeating events for a range of time */
39 void events( OEffectiveEvent::ValueList& tmpList, const OPimEvent::ValueList& events, 39void events( OPimBackendOccurrence::List& tmpList,
40 const QDate& from, const QDate& to ) { 40 const OPimEvent::ValueList& events,
41 QDateTime dtStart, dtEnd; 41 const QDate& from, const QDate& to ) {
42 42 QDateTime dtStart, dtEnd;
43 for ( OPimEvent::ValueList::ConstIterator it = events.begin(); it != events.end(); ++it ) { 43
44 dtStart = (*it).startDateTime(); 44 for ( OPimEvent::ValueList::ConstIterator it = events.begin(); it != events.end(); ++it ) {
45 dtEnd = (*it).endDateTime(); 45 dtStart = (*it).startDateTime();
46 46 dtEnd = (*it).endDateTime();
47 /* 47
48 * If in range 48 /*
49 */ 49 * If in range
50 if (dtStart.date() >= from && dtEnd.date() <= to ) { 50 */
51 OEffectiveEvent eff; 51 if (dtStart.date() >= from && dtEnd.date() <= to ) {
52 eff.setEvent( (*it) ); 52 OPimBackendOccurrence eff( dtStart, dtEnd, (*it).uid() );;
53 eff.setDate( dtStart.date() ); 53 tmpList.append( eff );
54 eff.setStartTime( dtStart.time() );
55
56 /* if not on the same day */
57 if ( dtStart.date() != dtEnd.date() )
58 eff.setEndTime( QTime(23, 59, 0 ) );
59 else
60 eff.setEndTime( dtEnd.time() );
61
62 tmpList.append( eff );
63 }
64
65 /* we must also check for end date information... */
66 if ( dtEnd.date() != dtStart.date() && dtEnd.date() >= from ) {
67 QDateTime dt = dtStart.addDays( 1 );
68 dt.setTime( QTime(0, 0, 0 ) );
69 QDateTime dtStop;
70 if ( dtEnd > to )
71 dtStop = to;
72 else
73 dtStop = dtEnd;
74
75 while ( dt <= dtStop ) {
76 OEffectiveEvent eff;
77 eff.setEvent( (*it) );
78 eff.setDate( dt.date() );
79
80 if ( dt >= from ) {
81 eff.setStartTime( QTime(0, 0, 0 ) );
82 if ( dt.date() == dtEnd.date() )
83 eff.setEndTime( dtEnd.time() );
84 else
85 eff.setEndTime( QTime(23, 59, 0 ) );
86 tmpList.append( eff );
87 }
88 dt = dt.addDays( 1 );
89 }
90 }
91 } 54 }
92 } 55 }
56}
93 57
94 void repeat( OEffectiveEvent::ValueList& tmpList, const OPimEvent::ValueList& list, 58void repeat( OPimBackendOccurrence::List& tmpList, const OPimEvent::ValueList& list,
95 const QDate& from, const QDate& to ) { 59 const QDate& from, const QDate& to ) {
96 QDate repeat; 60 QDate repeat;
97 for ( OPimEvent::ValueList::ConstIterator it = list.begin(); it != list.end(); ++it ) { 61 for ( OPimEvent::ValueList::ConstIterator it = list.begin(); it != list.end(); ++it ) {
98 int dur = (*it).startDateTime().date().daysTo( (*it).endDateTime().date() ); 62 int dur = (*it).startDateTime().date().daysTo( (*it).endDateTime().date() );
99 QDate itDate = from.addDays(-dur ); 63 QDate itDate = from.addDays(-dur );
100 OPimRecurrence rec = (*it).recurrence(); 64 OPimRecurrence rec = (*it).recurrence();
101 if ( !rec.hasEndDate() || rec.endDate() > to ) { 65 if ( !rec.hasEndDate() || rec.endDate() > to ) {
102 rec.setEndDate( to ); 66 rec.setEndDate( to );
103 rec.setHasEndDate( true ); 67 rec.setHasEndDate( true );
104 } 68 }
105 while (rec.nextOcurrence(itDate, repeat ) ) { 69
106 if (repeat > to ) break; 70 QDateTime start, end;
107 OEffectiveEvent eff; 71 while (rec.nextOcurrence(itDate, repeat ) ) {
108 eff.setDate( repeat ); 72 if (repeat > to ) break;
109 if ( (*it).isAllDay() ) { 73
110 eff.setStartTime( QTime(0, 0, 0 ) ); 74 OPimEvent event = *it;
111 eff.setEndTime( QTime(23, 59, 59 ) ); 75 start = QDateTime( repeat, event.startDateTime().time() );
112 }else { 76 end = QDateTime( repeat.addDays(dur), event.endDateTime().time() );
113 /* we only occur by days, not hours/minutes/seconds. Hence 77 OPimBackendOccurrence eff(start, end, event.uid() );
114 * the actual end and start times will be the same for 78 tmpList.append( eff );
115 * every repeated event. For multi day events this is
116 * fixed up later if on wronge day span
117 */
118 eff.setStartTime( (*it).startDateTime().time() );
119 eff.setEndTime( (*it).endDateTime().time() );
120 }
121 if ( dur != 0 ) {
122 // multi-day repeating events
123 QDate sub_it = QMAX( repeat, from );
124 QDate startDate = repeat;
125 QDate endDate = startDate.addDays( dur );
126
127 while ( sub_it <= endDate && sub_it <= to ) {
128 OEffectiveEvent tmpEff = eff;
129 tmpEff.setEvent( (*it) );
130 if ( sub_it != startDate )
131 tmpEff.setStartTime( QTime(0, 0, 0 ) );
132 if ( sub_it != endDate )
133 tmpEff.setEndTime( QTime( 23, 59, 59 ) );
134
135 tmpEff.setDate( sub_it );
136 tmpEff.setEffectiveDates( startDate, endDate );
137 tmpList.append( tmpEff );
138
139 sub_it = sub_it.addDays( 1 );
140 }
141 itDate = endDate;
142 }else {
143 eff.setEvent( (*it) );
144 tmpList.append( eff );
145 itDate = repeat.addDays( 1 );
146 }
147 }
148 } 79 }
149 } 80 }
150} 81}
82}
151 83
152namespace Opie { 84namespace Opie {
153 85
154ODateBookAccessBackend::ODateBookAccessBackend() 86ODateBookAccessBackend::ODateBookAccessBackend()
155 : OPimAccessBackend<OPimEvent>() 87 : OPimAccessBackend<OPimEvent>()
156{ 88{
157 89
158} 90}
159ODateBookAccessBackend::~ODateBookAccessBackend() { 91ODateBookAccessBackend::~ODateBookAccessBackend() {
160 92
161} 93}
162OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDate& from, 94OPimBackendOccurrence::List ODateBookAccessBackend::occurrences( const QDate& from,
163 const QDate& to ) { 95 const QDate& to )const {
164 OEffectiveEvent::ValueList tmpList; 96 OPimBackendOccurrence::List tmpList;
165 OPimEvent::ValueList list = directNonRepeats();
166 97
167 events( tmpList, list, from, to ); 98 events( tmpList, directNonRepeats(), from, to );
168 repeat( tmpList, directRawRepeats(),from,to ); 99 repeat( tmpList, directRawRepeats(),from,to );
169 100
170 list = directRawRepeats(); // Useless, isn't it ? (eilers)
171
172 qHeapSort( tmpList );
173 return tmpList; 101 return tmpList;
174} 102}
175OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDateTime& dt ) { 103OPimBackendOccurrence::List ODateBookAccessBackend::occurrences( const QDateTime& dt )const {
176 OEffectiveEvent::ValueList day = effectiveEvents( dt.date(), dt.date() ); 104 OPimBackendOccurrence::List day = occurrences( dt.date(), dt.date() );
177 OEffectiveEvent::ValueList::Iterator it;
178
179 OEffectiveEvent::ValueList tmpList;
180 QDateTime dtTmp;
181 for ( it = day.begin(); it != day.end(); ++it ) {
182 dtTmp = QDateTime( (*it).date(), (*it).startTime() );
183 if ( QABS(dt.secsTo(dtTmp) ) < 60 )
184 tmpList.append( (*it) );
185 }
186 105
187 return tmpList; 106 return filterOccurrences( day, dt );
188} 107}
189 108
190OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDate& from, 109OPimBackendOccurrence::List ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDate& from,
191 const QDate& to ) { 110 const QDate& to )const {
192 OEffectiveEvent::ValueList tmpList; 111 OPimBackendOccurrence::List tmpList;
193 OPimEvent::ValueList list = directNonRepeats(); 112 OPimEvent::ValueList list = directNonRepeats();
194 113
195 events( tmpList, list, from, to ); 114 events( tmpList, list, from, to );
196 115
197 qHeapSort( tmpList );
198 return tmpList; 116 return tmpList;
199} 117}
200 118
201OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDateTime& dt ) { 119OPimBackendOccurrence::List ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDateTime& dt )const {
202 OEffectiveEvent::ValueList day = effectiveNonRepeatingEvents( dt.date(), dt.date() ); 120 OPimBackendOccurrence::List day = effectiveNonRepeatingEvents( dt.date(), dt.date() );
203 OEffectiveEvent::ValueList::Iterator it; 121 return filterOccurrences( day,dt );
122}
123
124
125UIDArray ODateBookAccessBackend::queryByExample( const OPimEvent&, int settings,
126 const QDateTime& d )const {
127 return UIDArray();
128}
129
130UIDArray ODateBookAccessBackend::sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const {
131 return UIDArray();
132}
204 133
205 OEffectiveEvent::ValueList tmpList; 134OPimBackendOccurrence::List ODateBookAccessBackend::filterOccurrences( const OPimBackendOccurrence::List dayList,
206 QDateTime dtTmp; 135 const QDateTime& dt ) {
207 for ( it = day.begin(); it != day.end(); ++it ) { 136 OPimBackendOccurrence::List tmpList;
208 dtTmp = QDateTime( (*it).date(), (*it).startTime() ); 137 OPimBackendOccurrence::List::ConstIterator it;
209 if ( QABS(dt.secsTo(dtTmp) ) < 60 ) 138
210 tmpList.append( (*it) ); 139 for ( it = dayList.begin(); it != dayList.end(); ++it ) {
140 OPimBackendOccurrence occ = *it;
141
142 /*
143 * Let us find occurrences that are 'now'!
144 * If the dt.date() is on the same day as start or end of the Occurrence
145 * check how near start/end are.
146 * If it is in the middle of a multiday occurrence list it.
147 *
148 * We might want to 'lose' the sixty second offset and list
149 * all Events which are active at that time.
150 */
151 if ( dt.date() == occ.startDateTime().date() ) {
152 if ( QABS( dt.time().secsTo( occ.startDateTime().time() ) ) < 60 )
153 tmpList.append( occ );
154 }else if ( dt.date() == occ.endDateTime().date() ) {
155 if ( QABS( dt.time().secsTo( occ.endDateTime().time() ) ) < 60 )
156 tmpList.append( occ );
157 }else if ( dt.date() >= occ.startDateTime().date() &&
158 dt.date() >= occ.endDateTime().date() )
159 tmpList.append( occ );
211 } 160 }
212 161
213 return tmpList; 162 return tmpList;
214} 163}
215
216} 164}
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend.h b/libopie2/opiepim/backend/odatebookaccessbackend.h
index a9cce6a..8927ca1 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend.h
+++ b/libopie2/opiepim/backend/odatebookaccessbackend.h
@@ -1,121 +1,114 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_H 29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_H
30#define OPIE_DATE_BOOK_ACCESS_BACKEND_H 30#define OPIE_DATE_BOOK_ACCESS_BACKEND_H
31 31
32#include <qarray.h> 32#include <qarray.h>
33 33
34#include <opie2/opimaccessbackend.h> 34#include <opie2/opimaccessbackend.h>
35#include <opie2/opimevent.h> 35#include <opie2/opimevent.h>
36 36
37namespace Opie { 37namespace Opie {
38/** 38/**
39 * This class is the interface to the storage of Events. 39 * This class is the interface to the storage of Events.
40 * @see OPimAccessBackend 40 * @see OPimAccessBackend
41 * 41 *
42 */ 42 */
43class ODateBookAccessBackend : public OPimAccessBackend<OPimEvent> { 43class ODateBookAccessBackend : public OPimAccessBackend<OPimEvent> {
44public: 44public:
45 typedef int UID;
46
47 /** 45 /**
48 * c'tor without parameter 46 * c'tor without parameter
49 */ 47 */
50 ODateBookAccessBackend(); 48 ODateBookAccessBackend();
51 ~ODateBookAccessBackend(); 49 ~ODateBookAccessBackend();
52 50
53 /** 51 /**
54 * This method should return a list of UIDs containing 52 * This method should return a list of UIDs containing
55 * all events. No filter should be applied
56 * @return list of events
57 */
58 virtual QArray<UID> rawEvents()const = 0;
59
60 /**
61 * This method should return a list of UIDs containing
62 * all repeating events. No filter should be applied 53 * all repeating events. No filter should be applied
63 * @return list of repeating events 54 * @return list of repeating events
64 */ 55 */
65 virtual QArray<UID> rawRepeats()const = 0; 56 virtual UIDArray rawRepeats()const = 0;
66 57
67 /** 58 /**
68 * This mthod should return a list of UIDs containing all non 59 * This mthod should return a list of UIDs containing all non
69 * repeating events. No filter should be applied 60 * repeating events. No filter should be applied
70 * @return list of nonrepeating events 61 * @return list of nonrepeating events
71 */ 62 */
72 virtual QArray<UID> nonRepeats() const = 0; 63 virtual UIDArray nonRepeats() const = 0;
73 64
74 /** 65 /**
75 * If you do not want to implement the effectiveEvents methods below 66 * If you do not want to implement the effectiveEvents methods below
76 * you need to supply it with directNonRepeats. 67 * you need to supply it with directNonRepeats.
77 * This method can return empty lists if effectiveEvents is implememted 68 * This method can return empty lists if effectiveEvents is implememted
78 */ 69 */
79 virtual OPimEvent::ValueList directNonRepeats() = 0; 70 virtual OPimEvent::ValueList directNonRepeats()const = 0;
80 71
81 /** 72 /**
82 * Same as above but return raw repeats! 73 * Same as above but return raw repeats!
83 */ 74 */
84 virtual OPimEvent::ValueList directRawRepeats() = 0; 75 virtual OPimEvent::ValueList directRawRepeats()const = 0;
85 76
86 /* is implemented by default but you can reimplement it*/ 77 /* is implemented by default but you can reimplement it*/
87 /** 78 /**
88 * Effective Events are special event occuring during a time frame. This method does calcualte 79 * Effective Events are special event occuring during a time frame. This method does calcualte
89 * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method 80 * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method
90 * yourself 81 * yourself
91 */ 82 */
92 virtual OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ); 83 virtual OPimBackendOccurrence::List effectiveNonRepeatingEvents( const QDate& from, const QDate& to )const;
93 84
94 /** 85 /**
95 * this is an overloaded member function 86 * this is an overloaded member function
96 * @see effectiveEvents( const QDate& from, const QDate& to ) 87 * @see effectiveNonRepeatingEvents( const QDate& from, const QDate& to )
97 */
98 virtual OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start );
99
100 /**
101 * Effective Events are special event occuring during a time frame. This method does calcualte
102 * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method
103 * yourself
104 */ 88 */
105 virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDate& from, const QDate& to ); 89 virtual OPimBackendOccurrence::List effectiveNonRepeatingEvents( const QDateTime& start )const;
106 90
107 /** 91 /**
108 * this is an overloaded member function 92 * Common and probably inefficent implementation
109 * @see effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) 93 * for queryByExample, sorted
94 * and occurrences
110 */ 95 */
111 virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDateTime& start ); 96//@{
112 97 UIDArray queryByExample( const OPimEvent&, int settings, const QDateTime& d = QDateTime() )const;
98 UIDArray sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const;
99 OPimBackendOccurrence::List occurrences( const QDate&, const QDate& end )const;
100 OPimBackendOccurrence::List occurrences( const QDateTime& )const;
101//@}
102
103protected:
104 static OPimBackendOccurrence::List filterOccurrences(const OPimBackendOccurrence::List,
105 const QDateTime& time );
113private: 106private:
114 class Private; 107 class Private;
115 Private *d; 108 Private *d;
116 109
117}; 110};
118 111
119} 112}
120 113
121#endif 114#endif
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp
index 105c106..41b714e 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp
@@ -1,459 +1,448 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * SQL Backend for the OPIE-Calender Database. 30 * SQL Backend for the OPIE-Calender Database.
31 * 31 *
32 */ 32 */
33 33
34/* OPIE */ 34/* OPIE */
35#include <opie2/osqldriver.h> 35#include <opie2/osqldriver.h>
36#include <opie2/osqlmanager.h> 36#include <opie2/osqlmanager.h>
37#include <opie2/osqlquery.h> 37#include <opie2/osqlquery.h>
38 38
39#include <opie2/opimrecurrence.h> 39#include <opie2/opimrecurrence.h>
40#include <opie2/odatebookaccessbackend_sql.h> 40#include <opie2/odatebookaccessbackend_sql.h>
41#include <opie2/odebug.h> 41#include <opie2/odebug.h>
42 42
43#include <qpe/global.h> 43#include <qpe/global.h>
44 44
45/* QT */ 45/* QT */
46#include <qarray.h> 46#include <qarray.h>
47#include <qstringlist.h> 47#include <qstringlist.h>
48 48
49/* STD */ 49/* STD */
50#include <stdio.h> 50#include <stdio.h>
51#include <stdlib.h> 51#include <stdlib.h>
52 52
53 53
54using namespace Opie::DB; 54using namespace Opie::DB;
55 55
56namespace { 56namespace {
57 /** 57 /**
58 * a find query for custom elements 58 * a find query for custom elements
59 */ 59 */
60 class FindCustomQuery : public OSQLQuery { 60 class FindCustomQuery : public OSQLQuery {
61 public: 61 public:
62 FindCustomQuery(int uid); 62 FindCustomQuery(int uid);
63 FindCustomQuery(const QArray<int>& ); 63 FindCustomQuery(const QArray<int>& );
64 ~FindCustomQuery(); 64 ~FindCustomQuery();
65 QString query()const; 65 QString query()const;
66 private: 66 private:
67 QString single()const; 67 QString single()const;
68 QString multi()const; 68 QString multi()const;
69 QArray<int> m_uids; 69 QArray<int> m_uids;
70 int m_uid; 70 int m_uid;
71 }; 71 };
72 72
73 FindCustomQuery::FindCustomQuery(int uid) 73 FindCustomQuery::FindCustomQuery(int uid)
74 : OSQLQuery(), m_uid( uid ) { 74 : OSQLQuery(), m_uid( uid ) {
75 } 75 }
76 FindCustomQuery::FindCustomQuery(const QArray<int>& ints) 76 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
77 : OSQLQuery(), m_uids( ints ){ 77 : OSQLQuery(), m_uids( ints ){
78 } 78 }
79 FindCustomQuery::~FindCustomQuery() { 79 FindCustomQuery::~FindCustomQuery() {
80 } 80 }
81 QString FindCustomQuery::query()const{ 81 QString FindCustomQuery::query()const{
82// if ( m_uids.count() == 0 ) 82// if ( m_uids.count() == 0 )
83 return single(); 83 return single();
84 } 84 }
85 QString FindCustomQuery::single()const{ 85 QString FindCustomQuery::single()const{
86 QString qu = "select uid, type, value from custom_data where uid = "; 86 QString qu = "select uid, type, value from custom_data where uid = ";
87 qu += QString::number(m_uid); 87 qu += QString::number(m_uid);
88 return qu; 88 return qu;
89 } 89 }
90} 90}
91 91
92 92
93namespace Opie { 93namespace Opie {
94 94
95 95
96ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , 96ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& ,
97 const QString& fileName ) 97 const QString& fileName )
98 : ODateBookAccessBackend(), m_driver( NULL ) 98 : ODateBookAccessBackend(), m_driver( NULL )
99{ 99{
100 m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; 100 m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName;
101 101
102 // Get the standart sql-driver from the OSQLManager.. 102 // Get the standart sql-driver from the OSQLManager..
103 OSQLManager man; 103 OSQLManager man;
104 m_driver = man.standard(); 104 m_driver = man.standard();
105 m_driver->setUrl( m_fileName ); 105 m_driver->setUrl( m_fileName );
106 106
107 initFields(); 107 initFields();
108 108
109 load(); 109 load();
110} 110}
111 111
112ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { 112ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() {
113 if( m_driver ) 113 if( m_driver )
114 delete m_driver; 114 delete m_driver;
115} 115}
116 116
117void ODateBookAccessBackend_SQL::initFields() 117void ODateBookAccessBackend_SQL::initFields()
118{ 118{
119 119
120 // This map contains the translation of the fieldtype id's to 120 // This map contains the translation of the fieldtype id's to
121 // the names of the table columns 121 // the names of the table columns
122 m_fieldMap.insert( OPimEvent::FUid, "uid" ); 122 m_fieldMap.insert( OPimEvent::FUid, "uid" );
123 m_fieldMap.insert( OPimEvent::FCategories, "Categories" ); 123 m_fieldMap.insert( OPimEvent::FCategories, "Categories" );
124 m_fieldMap.insert( OPimEvent::FDescription, "Description" ); 124 m_fieldMap.insert( OPimEvent::FDescription, "Description" );
125 m_fieldMap.insert( OPimEvent::FLocation, "Location" ); 125 m_fieldMap.insert( OPimEvent::FLocation, "Location" );
126 m_fieldMap.insert( OPimEvent::FType, "Type" ); 126 m_fieldMap.insert( OPimEvent::FType, "Type" );
127 m_fieldMap.insert( OPimEvent::FAlarm, "Alarm" ); 127 m_fieldMap.insert( OPimEvent::FAlarm, "Alarm" );
128 m_fieldMap.insert( OPimEvent::FSound, "Sound" ); 128 m_fieldMap.insert( OPimEvent::FSound, "Sound" );
129 m_fieldMap.insert( OPimEvent::FRType, "RType" ); 129 m_fieldMap.insert( OPimEvent::FRType, "RType" );
130 m_fieldMap.insert( OPimEvent::FRWeekdays, "RWeekdays" ); 130 m_fieldMap.insert( OPimEvent::FRWeekdays, "RWeekdays" );
131 m_fieldMap.insert( OPimEvent::FRPosition, "RPosition" ); 131 m_fieldMap.insert( OPimEvent::FRPosition, "RPosition" );
132 m_fieldMap.insert( OPimEvent::FRFreq, "RFreq" ); 132 m_fieldMap.insert( OPimEvent::FRFreq, "RFreq" );
133 m_fieldMap.insert( OPimEvent::FRHasEndDate, "RHasEndDate" ); 133 m_fieldMap.insert( OPimEvent::FRHasEndDate, "RHasEndDate" );
134 m_fieldMap.insert( OPimEvent::FREndDate, "REndDate" ); 134 m_fieldMap.insert( OPimEvent::FREndDate, "REndDate" );
135 m_fieldMap.insert( OPimEvent::FRCreated, "RCreated" ); 135 m_fieldMap.insert( OPimEvent::FRCreated, "RCreated" );
136 m_fieldMap.insert( OPimEvent::FRExceptions, "RExceptions" ); 136 m_fieldMap.insert( OPimEvent::FRExceptions, "RExceptions" );
137 m_fieldMap.insert( OPimEvent::FStart, "Start" ); 137 m_fieldMap.insert( OPimEvent::FStart, "Start" );
138 m_fieldMap.insert( OPimEvent::FEnd, "End" ); 138 m_fieldMap.insert( OPimEvent::FEnd, "End" );
139 m_fieldMap.insert( OPimEvent::FNote, "Note" ); 139 m_fieldMap.insert( OPimEvent::FNote, "Note" );
140 m_fieldMap.insert( OPimEvent::FTimeZone, "TimeZone" ); 140 m_fieldMap.insert( OPimEvent::FTimeZone, "TimeZone" );
141 m_fieldMap.insert( OPimEvent::FRecParent, "RecParent" ); 141 m_fieldMap.insert( OPimEvent::FRecParent, "RecParent" );
142 m_fieldMap.insert( OPimEvent::FRecChildren, "Recchildren" ); 142 m_fieldMap.insert( OPimEvent::FRecChildren, "Recchildren" );
143 143
144 // Create a map that maps the column name to the id 144 // Create a map that maps the column name to the id
145 QMapConstIterator<int, QString> it; 145 QMapConstIterator<int, QString> it;
146 for ( it = m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 146 for ( it = m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
147 m_reverseFieldMap.insert( it.data(), it.key() ); 147 m_reverseFieldMap.insert( it.data(), it.key() );
148 } 148 }
149 149
150} 150}
151 151
152bool ODateBookAccessBackend_SQL::load() 152bool ODateBookAccessBackend_SQL::load()
153{ 153{
154 if (!m_driver->open() ) 154 if (!m_driver->open() )
155 return false; 155 return false;
156 156
157 // Don't expect that the database exists. 157 // Don't expect that the database exists.
158 // It is save here to create the table, even if it 158 // It is save here to create the table, even if it
159 // do exist. ( Is that correct for all databases ?? ) 159 // do exist. ( Is that correct for all databases ?? )
160 QString qu = "create table datebook( uid INTEGER PRIMARY KEY "; 160 QString qu = "create table datebook( uid INTEGER PRIMARY KEY ";
161 161
162 QMap<int, QString>::Iterator it; 162 QMap<int, QString>::Iterator it;
163 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 163 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
164 qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() ); 164 qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() );
165 } 165 }
166 qu += " );"; 166 qu += " );";
167 167
168 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; 168 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );";
169 169
170 owarn << "command: " << qu << "" << oendl;
171
172 OSQLRawQuery raw( qu ); 170 OSQLRawQuery raw( qu );
173 OSQLResult res = m_driver->query( &raw ); 171 OSQLResult res = m_driver->query( &raw );
174 if ( res.state() != OSQLResult::Success ) 172 if ( res.state() != OSQLResult::Success )
175 return false; 173 return false;
176 174
177 update(); 175 update();
178 176
179 return true; 177 return true;
180} 178}
181 179
182void ODateBookAccessBackend_SQL::update() 180void ODateBookAccessBackend_SQL::update()
183{ 181{
184 182
185 QString qu = "select uid from datebook"; 183 QString qu = "select uid from datebook";
186 OSQLRawQuery raw( qu ); 184 OSQLRawQuery raw( qu );
187 OSQLResult res = m_driver->query( &raw ); 185 OSQLResult res = m_driver->query( &raw );
188 if ( res.state() != OSQLResult::Success ){ 186 if ( res.state() != OSQLResult::Success ){
189 // m_uids.clear(); 187 // m_uids.clear();
190 return; 188 return;
191 } 189 }
192 190
193 m_uids = extractUids( res ); 191 m_uids = extractUids( res );
194 192
195} 193}
196 194
197bool ODateBookAccessBackend_SQL::reload() 195bool ODateBookAccessBackend_SQL::reload()
198{ 196{
199 return load(); 197 return load();
200} 198}
201 199
202bool ODateBookAccessBackend_SQL::save() 200bool ODateBookAccessBackend_SQL::save()
203{ 201{
204 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) 202 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
205} 203}
206 204
207QArray<int> ODateBookAccessBackend_SQL::allRecords()const 205QArray<int> ODateBookAccessBackend_SQL::allRecords()const
208{ 206{
209 return m_uids; 207 return m_uids;
210} 208}
211 209
212QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OPimEvent&, int, const QDateTime& ) { 210QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OPimEvent&, int, const QDateTime& ) {
213 return QArray<int>(); 211 return QArray<int>();
214} 212}
215 213
216void ODateBookAccessBackend_SQL::clear() 214void ODateBookAccessBackend_SQL::clear()
217{ 215{
218 QString qu = "drop table datebook;"; 216 QString qu = "drop table datebook;";
219 qu += "drop table custom_data;"; 217 qu += "drop table custom_data;";
220 218
221 OSQLRawQuery raw( qu ); 219 OSQLRawQuery raw( qu );
222 OSQLResult res = m_driver->query( &raw ); 220 OSQLResult res = m_driver->query( &raw );
223 221
224 reload(); 222 reload();
225} 223}
226 224
227 225
228OPimEvent ODateBookAccessBackend_SQL::find( int uid ) const{ 226OPimEvent ODateBookAccessBackend_SQL::find( int uid ) const{
229 odebug << "ODateBookAccessBackend_SQL::find( " << uid << " )" << oendl; 227 odebug << "ODateBookAccessBackend_SQL::find( " << uid << " )" << oendl;
230 228
231 QString qu = "select *"; 229 QString qu = "select *";
232 qu += "from datebook where uid = " + QString::number(uid); 230 qu += "from datebook where uid = " + QString::number(uid);
233 231
234 odebug << "Query: " << qu << "" << oendl; 232 odebug << "Query: " << qu << "" << oendl;
235 233
236 OSQLRawQuery raw( qu ); 234 OSQLRawQuery raw( qu );
237 OSQLResult res = m_driver->query( &raw ); 235 OSQLResult res = m_driver->query( &raw );
238 236
239 OSQLResultItem resItem = res.first(); 237 OSQLResultItem resItem = res.first();
240 238
241 // Create Map for date event and insert UID 239 // Create Map for date event and insert UID
242 QMap<int,QString> dateEventMap; 240 QMap<int,QString> dateEventMap;
243 dateEventMap.insert( OPimEvent::FUid, QString::number( uid ) ); 241 dateEventMap.insert( OPimEvent::FUid, QString::number( uid ) );
244 242
245 // Now insert the data out of the columns into the map. 243 // Now insert the data out of the columns into the map.
246 QMapConstIterator<int, QString> it; 244 QMapConstIterator<int, QString> it;
247 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 245 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
248 dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) ); 246 dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) );
249 } 247 }
250 248
251 // Last step: Put map into date event, add custom map and return it 249 // Last step: Put map into date event, add custom map and return it
252 OPimEvent retDate( dateEventMap ); 250 OPimEvent retDate( dateEventMap );
253 retDate.setExtraMap( requestCustom( uid ) ); 251 retDate.setExtraMap( requestCustom( uid ) );
254 252
255 odebug << "ODateBookAccessBackend_SQL::find( " << uid << " ) end" << oendl; 253 odebug << "ODateBookAccessBackend_SQL::find( " << uid << " ) end" << oendl;
256 return retDate; 254 return retDate;
257} 255}
258 256
259// FIXME: Speed up update of uid's.. 257// FIXME: Speed up update of uid's..
260bool ODateBookAccessBackend_SQL::add( const OPimEvent& ev ) 258bool ODateBookAccessBackend_SQL::add( const OPimEvent& ev )
261{ 259{
262 QMap<int,QString> eventMap = ev.toMap(); 260 QMap<int,QString> eventMap = ev.toMap();
263 261
264 QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() ); 262 QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() );
265 QMap<int, QString>::Iterator it; 263 QMap<int, QString>::Iterator it;
266 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 264 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
267 if ( !eventMap[it.key()].isEmpty() ) 265 if ( !eventMap[it.key()].isEmpty() )
268 qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] ); 266 qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] );
269 else 267 else
270 qu += QString( ",\"\"" ); 268 qu += QString( ",\"\"" );
271 } 269 }
272 qu += " );"; 270 qu += " );";
273 271
274 // Add custom entries 272 // Add custom entries
275 int id = 0; 273 int id = 0;
276 QMap<QString, QString> customMap = ev.toExtraMap(); 274 QMap<QString, QString> customMap = ev.toExtraMap();
277 for( QMap<QString, QString>::Iterator it = customMap.begin(); 275 for( QMap<QString, QString>::Iterator it = customMap.begin();
278 it != customMap.end(); ++it ){ 276 it != customMap.end(); ++it ){
279 qu += "insert into custom_data VALUES(" 277 qu += "insert into custom_data VALUES("
280 + QString::number( ev.uid() ) 278 + QString::number( ev.uid() )
281 + "," 279 + ","
282 + QString::number( id++ ) 280 + QString::number( id++ )
283 + ",'" 281 + ",'"
284 + it.key() //.latin1() 282 + it.key() //.latin1()
285 + "'," 283 + "',"
286 + "0" // Priority for future enhancements 284 + "0" // Priority for future enhancements
287 + ",'" 285 + ",'"
288 + it.data() //.latin1() 286 + it.data() //.latin1()
289 + "');"; 287 + "');";
290 } 288 }
291 owarn << "add " << qu << "" << oendl;
292 289
293 OSQLRawQuery raw( qu ); 290 OSQLRawQuery raw( qu );
294 OSQLResult res = m_driver->query( &raw ); 291 OSQLResult res = m_driver->query( &raw );
295 if ( res.state() != OSQLResult::Success ){ 292 if ( res.state() != OSQLResult::Success ){
296 return false; 293 return false;
297 } 294 }
298 295
299 // Update list of uid's 296 // Update list of uid's
300 update(); 297 update();
301 298
302 return true; 299 return true;
303} 300}
304 301
305// FIXME: Speed up update of uid's.. 302// FIXME: Speed up update of uid's..
306bool ODateBookAccessBackend_SQL::remove( int uid ) 303bool ODateBookAccessBackend_SQL::remove( int uid )
307{ 304{
308 QString qu = "DELETE from datebook where uid = " 305 QString qu = "DELETE from datebook where uid = "
309 + QString::number( uid ) + ";"; 306 + QString::number( uid ) + ";";
310 qu += "DELETE from custom_data where uid = " 307 qu += "DELETE from custom_data where uid = "
311 + QString::number( uid ) + ";"; 308 + QString::number( uid ) + ";";
312 309
313 OSQLRawQuery raw( qu ); 310 OSQLRawQuery raw( qu );
314 OSQLResult res = m_driver->query( &raw ); 311 OSQLResult res = m_driver->query( &raw );
315 if ( res.state() != OSQLResult::Success ){ 312 if ( res.state() != OSQLResult::Success ){
316 return false; 313 return false;
317 } 314 }
318 315
319 // Update list of uid's 316 // Update list of uid's
320 update(); 317 update();
321 318
322 return true; 319 return true;
323} 320}
324 321
325bool ODateBookAccessBackend_SQL::replace( const OPimEvent& ev ) 322bool ODateBookAccessBackend_SQL::replace( const OPimEvent& ev )
326{ 323{
327 remove( ev.uid() ); 324 remove( ev.uid() );
328 return add( ev ); 325 return add( ev );
329} 326}
330 327
331QArray<int> ODateBookAccessBackend_SQL::rawEvents()const
332{
333 return allRecords();
334}
335 328
336QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const 329QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const
337{ 330{
338 QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\""; 331 QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\"";
339 OSQLRawQuery raw( qu ); 332 OSQLRawQuery raw( qu );
340 OSQLResult res = m_driver->query( &raw ); 333 OSQLResult res = m_driver->query( &raw );
341 if ( res.state() != OSQLResult::Success ){ 334 if ( res.state() != OSQLResult::Success ){
342 QArray<int> nix; 335 QArray<int> nix;
343 return nix; 336 return nix;
344 } 337 }
345 338
346 return extractUids( res ); 339 return extractUids( res );
347} 340}
348 341
349QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const 342QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const
350{ 343{
351 QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\""; 344 QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\"";
352 OSQLRawQuery raw( qu ); 345 OSQLRawQuery raw( qu );
353 OSQLResult res = m_driver->query( &raw ); 346 OSQLResult res = m_driver->query( &raw );
354 if ( res.state() != OSQLResult::Success ){ 347 if ( res.state() != OSQLResult::Success ){
355 QArray<int> nix; 348 QArray<int> nix;
356 return nix; 349 return nix;
357 } 350 }
358 351
359 return extractUids( res ); 352 return extractUids( res );
360} 353}
361 354
362OPimEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() 355OPimEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats()const
363{ 356{
364 QArray<int> nonRepUids = nonRepeats(); 357 QArray<int> nonRepUids = nonRepeats();
365 OPimEvent::ValueList list; 358 OPimEvent::ValueList list;
366 359
367 for (uint i = 0; i < nonRepUids.count(); ++i ){ 360 for (uint i = 0; i < nonRepUids.count(); ++i ){
368 list.append( find( nonRepUids[i] ) ); 361 list.append( find( nonRepUids[i] ) );
369 } 362 }
370 363
371 return list; 364 return list;
372 365
373} 366}
374OPimEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() 367OPimEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats()const
375{ 368{
376 QArray<int> rawRepUids = rawRepeats(); 369 QArray<int> rawRepUids = rawRepeats();
377 OPimEvent::ValueList list; 370 OPimEvent::ValueList list;
378 371
379 for (uint i = 0; i < rawRepUids.count(); ++i ){ 372 for (uint i = 0; i < rawRepUids.count(); ++i ){
380 list.append( find( rawRepUids[i] ) ); 373 list.append( find( rawRepUids[i] ) );
381 } 374 }
382 375
383 return list; 376 return list;
384} 377}
385 378
386 379
387QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 380QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
388{ 381{
389 382
390 QString qu = "SELECT uid FROM datebook WHERE ("; 383 QString qu = "SELECT uid FROM datebook WHERE (";
391 384
392 // Do it make sense to search other fields, too ? 385 // Do it make sense to search other fields, too ?
393 qu += " rlike(\""+ r.pattern() + "\", Location ) OR"; 386 qu += " rlike(\""+ r.pattern() + "\", Location ) OR";
394 qu += " rlike(\""+ r.pattern() + "\", Note )"; 387 qu += " rlike(\""+ r.pattern() + "\", Note )";
395 388
396 qu += " )"; 389 qu += " )";
397 390
398 odebug << "query: " << qu << "" << oendl; 391 odebug << "query: " << qu << "" << oendl;
399 392
400 OSQLRawQuery raw( qu ); 393 OSQLRawQuery raw( qu );
401 OSQLResult res = m_driver->query( &raw ); 394 OSQLResult res = m_driver->query( &raw );
402 395
403 return extractUids( res ); 396 return extractUids( res );
404 397
405 398
406 399
407} 400}
408 401
409/* ===== Private Functions ========================================== */ 402/* ===== Private Functions ========================================== */
410 403
411QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const 404QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const
412{ 405{
413 owarn << "extractUids" << oendl;
414 QTime t; 406 QTime t;
415 t.start(); 407 t.start();
416 OSQLResultItem::ValueList list = res.results(); 408 OSQLResultItem::ValueList list = res.results();
417 OSQLResultItem::ValueList::Iterator it; 409 OSQLResultItem::ValueList::Iterator it;
418 QArray<int> ints(list.count() ); 410 QArray<int> ints(list.count() );
419 owarn << " count = " << list.count() << "" << oendl;
420 411
421 int i = 0; 412 int i = 0;
422 for (it = list.begin(); it != list.end(); ++it ) { 413 for (it = list.begin(); it != list.end(); ++it ) {
423 ints[i] = (*it).data("uid").toInt(); 414 ints[i] = (*it).data("uid").toInt();
424 i++; 415 i++;
425 } 416 }
426 owarn << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl;
427 417
428 return ints; 418 return ints;
429 419
430} 420}
431 421
432QMap<QString, QString> ODateBookAccessBackend_SQL::requestCustom( int uid ) const 422QMap<QString, QString> ODateBookAccessBackend_SQL::requestCustom( int uid ) const
433{ 423{
434 QTime t; 424 QTime t;
435 t.start(); 425 t.start();
436 426
437 QMap<QString, QString> customMap; 427 QMap<QString, QString> customMap;
438 428
439 FindCustomQuery query( uid ); 429 FindCustomQuery query( uid );
440 OSQLResult res_custom = m_driver->query( &query ); 430 OSQLResult res_custom = m_driver->query( &query );
441 431
442 if ( res_custom.state() == OSQLResult::Failure ) { 432 if ( res_custom.state() == OSQLResult::Failure ) {
443 owarn << "OSQLResult::Failure in find query !!" << oendl;
444 QMap<QString, QString> empty; 433 QMap<QString, QString> empty;
445 return empty; 434 return empty;
446 } 435 }
447 436
448 OSQLResultItem::ValueList list = res_custom.results(); 437 OSQLResultItem::ValueList list = res_custom.results();
449 OSQLResultItem::ValueList::Iterator it = list.begin(); 438 OSQLResultItem::ValueList::Iterator it = list.begin();
450 for ( ; it != list.end(); ++it ) { 439 for ( ; it != list.end(); ++it ) {
451 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); 440 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
452 } 441 }
453 442
454 odebug << "RequestCustom needed: " << t.elapsed() << " ms" << oendl; 443 odebug << "RequestCustom needed: " << t.elapsed() << " ms" << oendl;
455 return customMap; 444 return customMap;
456} 445}
457 446
458 447
459} 448}
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h
index b624159..a649d25 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h
@@ -1,99 +1,98 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H 29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H
30#define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H 30#define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H
31 31
32#include <qmap.h> 32#include <qmap.h>
33#include <opie2/osqlresult.h> 33#include <opie2/osqlresult.h>
34 34
35#include <opie2/odatebookaccessbackend.h> 35#include <opie2/odatebookaccessbackend.h>
36 36
37namespace Opie { 37namespace Opie {
38namespace DB { 38namespace DB {
39class OSQLDriver; 39class OSQLDriver;
40} 40}
41} 41}
42 42
43namespace Opie { 43namespace Opie {
44/** 44/**
45 * This is the default SQL implementation for DateBoook SQL storage 45 * This is the default SQL implementation for DateBoook SQL storage
46 * It fully implements the interface 46 * It fully implements the interface
47 * @see ODateBookAccessBackend 47 * @see ODateBookAccessBackend
48 * @see OPimAccessBackend 48 * @see OPimAccessBackend
49 */ 49 */
50class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { 50class ODateBookAccessBackend_SQL : public ODateBookAccessBackend {
51public: 51public:
52 ODateBookAccessBackend_SQL( const QString& appName, 52 ODateBookAccessBackend_SQL( const QString& appName,
53 const QString& fileName = QString::null); 53 const QString& fileName = QString::null);
54 ~ODateBookAccessBackend_SQL(); 54 ~ODateBookAccessBackend_SQL();
55 55
56 bool load(); 56 bool load();
57 bool reload(); 57 bool reload();
58 bool save(); 58 bool save();
59 59
60 QArray<int> allRecords()const; 60 QArray<int> allRecords()const;
61 QArray<int> matchRegexp(const QRegExp &r) const; 61 QArray<int> matchRegexp(const QRegExp &r) const;
62 QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() ); 62 QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() );
63 OPimEvent find( int uid )const; 63 OPimEvent find( int uid )const;
64 void clear(); 64 void clear();
65 bool add( const OPimEvent& ev ); 65 bool add( const OPimEvent& ev );
66 bool remove( int uid ); 66 bool remove( int uid );
67 bool replace( const OPimEvent& ev ); 67 bool replace( const OPimEvent& ev );
68 68
69 QArray<UID> rawEvents()const;
70 QArray<UID> rawRepeats()const; 69 QArray<UID> rawRepeats()const;
71 QArray<UID> nonRepeats()const; 70 QArray<UID> nonRepeats()const;
72 71
73 OPimEvent::ValueList directNonRepeats(); 72 OPimEvent::ValueList directNonRepeats()const;
74 OPimEvent::ValueList directRawRepeats(); 73 OPimEvent::ValueList directRawRepeats()const;
75 74
76private: 75private:
77 bool loadFile(); 76 bool loadFile();
78 QString m_fileName; 77 QString m_fileName;
79 QArray<int> m_uids; 78 QArray<int> m_uids;
80 79
81 QMap<int, QString> m_fieldMap; 80 QMap<int, QString> m_fieldMap;
82 QMap<QString, int> m_reverseFieldMap; 81 QMap<QString, int> m_reverseFieldMap;
83 82
84 Opie::DB::OSQLDriver* m_driver; 83 Opie::DB::OSQLDriver* m_driver;
85 84
86 class Private; 85 class Private;
87 Private *d; 86 Private *d;
88 87
89 void initFields(); 88 void initFields();
90 void update(); 89 void update();
91 90
92 QArray<int> extractUids( Opie::DB::OSQLResult& res ) const; 91 QArray<int> extractUids( Opie::DB::OSQLResult& res ) const;
93 QMap<QString, QString> requestCustom( int uid ) const; 92 QMap<QString, QString> requestCustom( int uid ) const;
94 93
95}; 94};
96 95
97} 96}
98 97
99#endif 98#endif
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
index 0f99d50..55e47e2 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
@@ -1,670 +1,664 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29 29
30/* OPIE */ 30/* OPIE */
31#include <opie2/opimnotifymanager.h> 31#include <opie2/opimnotifymanager.h>
32#include <opie2/opimrecurrence.h> 32#include <opie2/opimrecurrence.h>
33#include <opie2/opimtimezone.h> 33#include <opie2/opimtimezone.h>
34#include <opie2/odatebookaccessbackend_xml.h> 34#include <opie2/odatebookaccessbackend_xml.h>
35#include <opie2/odebug.h> 35#include <opie2/odebug.h>
36 36
37#include <qtopia/global.h> 37#include <qtopia/global.h>
38#include <qtopia/stringutil.h> 38#include <qtopia/stringutil.h>
39#include <qtopia/timeconversion.h> 39#include <qtopia/timeconversion.h>
40 40
41/* QT */ 41/* QT */
42#include <qasciidict.h> 42#include <qasciidict.h>
43#include <qfile.h> 43#include <qfile.h>
44 44
45/* STD */ 45/* STD */
46#include <errno.h> 46#include <errno.h>
47#include <fcntl.h> 47#include <fcntl.h>
48 48
49#include <stdio.h> 49#include <stdio.h>
50#include <stdlib.h> 50#include <stdlib.h>
51 51
52#include <sys/types.h> 52#include <sys/types.h>
53#include <sys/mman.h> 53#include <sys/mman.h>
54#include <sys/stat.h> 54#include <sys/stat.h>
55 55
56#include <unistd.h> 56#include <unistd.h>
57 57
58 58
59using namespace Opie; 59using namespace Opie;
60 60
61namespace { 61namespace {
62 // FROM TT again 62 // FROM TT again
63char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) 63char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
64{ 64{
65 char needleChar; 65 char needleChar;
66 char haystackChar; 66 char haystackChar;
67 if (!needle || !haystack || !hLen || !nLen) 67 if (!needle || !haystack || !hLen || !nLen)
68 return 0; 68 return 0;
69 69
70 const char* hsearch = haystack; 70 const char* hsearch = haystack;
71 71
72 if ((needleChar = *needle++) != 0) { 72 if ((needleChar = *needle++) != 0) {
73 nLen--; //(to make up for needle++) 73 nLen--; //(to make up for needle++)
74 do { 74 do {
75 do { 75 do {
76 if ((haystackChar = *hsearch++) == 0) 76 if ((haystackChar = *hsearch++) == 0)
77 return (0); 77 return (0);
78 if (hsearch >= haystack + hLen) 78 if (hsearch >= haystack + hLen)
79 return (0); 79 return (0);
80 } while (haystackChar != needleChar); 80 } while (haystackChar != needleChar);
81 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); 81 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
82 hsearch--; 82 hsearch--;
83 } 83 }
84 return ((char *)hsearch); 84 return ((char *)hsearch);
85} 85}
86} 86}
87 87
88namespace { 88namespace {
89 time_t start, end, created, rp_end; 89 time_t start, end, created, rp_end;
90 OPimRecurrence* rec; 90 OPimRecurrence* rec;
91 static OPimRecurrence* recur() { 91 static OPimRecurrence* recur() {
92 if (!rec) 92 if (!rec)
93 rec = new OPimRecurrence; 93 rec = new OPimRecurrence;
94 94
95 return rec; 95 return rec;
96 } 96 }
97 int alarmTime; 97 int alarmTime;
98 int snd; 98 int snd;
99 enum Attribute{ 99 enum Attribute{
100 FDescription = 0, 100 FDescription = 0,
101 FLocation, 101 FLocation,
102 FCategories, 102 FCategories,
103 FUid, 103 FUid,
104 FType, 104 FType,
105 FAlarm, 105 FAlarm,
106 FSound, 106 FSound,
107 FRType, 107 FRType,
108 FRWeekdays, 108 FRWeekdays,
109 FRPosition, 109 FRPosition,
110 FRFreq, 110 FRFreq,
111 FRHasEndDate, 111 FRHasEndDate,
112 FREndDate, 112 FREndDate,
113 FRStart, 113 FRStart,
114 FREnd, 114 FREnd,
115 FNote, 115 FNote,
116 FCreated, // Should't this be called FRCreated ? 116 FCreated, // Should't this be called FRCreated ?
117 FTimeZone, 117 FTimeZone,
118 FRecParent, 118 FRecParent,
119 FRecChildren, 119 FRecChildren,
120 FExceptions 120 FExceptions
121 }; 121 };
122 122
123 // FIXME: Use OPimEvent::toMap() here !! (eilers) 123 // FIXME: Use OPimEvent::toMap() here !! (eilers)
124 static void save( const OPimEvent& ev, QString& buf ) { 124 static void save( const OPimEvent& ev, QString& buf ) {
125 owarn << "Saving " << ev.uid() << " " << ev.description() << "" << oendl;
126 buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; 125 buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\"";
127 if (!ev.location().isEmpty() ) 126 if (!ev.location().isEmpty() )
128 buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; 127 buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\"";
129 128
130 if (!ev.categories().isEmpty() ) 129 if (!ev.categories().isEmpty() )
131 buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; 130 buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\"";
132 131
133 buf += " uid=\"" + QString::number( ev.uid() ) + "\""; 132 buf += " uid=\"" + QString::number( ev.uid() ) + "\"";
134 133
135 if (ev.isAllDay() ) 134 if (ev.isAllDay() )
136 buf += " type=\"AllDay\""; // is that all ?? (eilers) 135 buf += " type=\"AllDay\""; // is that all ?? (eilers)
137 136
138 if (ev.hasNotifiers() ) { 137 if (ev.hasNotifiers() ) {
139 OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first 138 OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first
140 int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; 139 int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60;
141 buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; 140 buf += " alarm=\"" + QString::number(minutes) + "\" sound=\"";
142 if ( alarm.sound() == OPimAlarm::Loud ) 141 if ( alarm.sound() == OPimAlarm::Loud )
143 buf += "loud"; 142 buf += "loud";
144 else 143 else
145 buf += "silent"; 144 buf += "silent";
146 buf += "\""; 145 buf += "\"";
147 } 146 }
148 if ( ev.hasRecurrence() ) { 147 if ( ev.hasRecurrence() ) {
149 buf += ev.recurrence().toString(); 148 buf += ev.recurrence().toString();
150 } 149 }
151 150
152 /* 151 /*
153 * fscking timezones :) well, we'll first convert 152 * fscking timezones :) well, we'll first convert
154 * the QDateTime to a QDateTime in UTC time 153 * the QDateTime to a QDateTime in UTC time
155 * and then we'll create a nice time_t 154 * and then we'll create a nice time_t
156 */ 155 */
157 OPimTimeZone zone( (ev.timeZone().isEmpty()||ev.isAllDay()) ? OPimTimeZone::utc() : OPimTimeZone::current() ); 156 OPimTimeZone zone( (ev.timeZone().isEmpty()||ev.isAllDay()) ? OPimTimeZone::utc() : OPimTimeZone::current() );
158 buf += " start=\"" + QString::number( zone.fromDateTime( ev.startDateTime())) + "\""; 157 buf += " start=\"" + QString::number( zone.fromDateTime( ev.startDateTime())) + "\"";
159 buf += " end=\"" + QString::number( zone.fromDateTime( ev.endDateTime() )) + "\""; 158 buf += " end=\"" + QString::number( zone.fromDateTime( ev.endDateTime() )) + "\"";
160 if (!ev.note().isEmpty() ) { 159 if (!ev.note().isEmpty() ) {
161 buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; 160 buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\"";
162 } 161 }
163 162
164 /* 163 /*
165 * Don't save a timezone if AllDay Events 164 * Don't save a timezone if AllDay Events
166 * as they're UTC only anyway 165 * as they're UTC only anyway
167 */ 166 */
168 if (!ev.isAllDay() ) { 167 if (!ev.isAllDay() ) {
169 168
170 buf += " timezone=\""; 169 buf += " timezone=\"";
171 if ( ev.timeZone().isEmpty() ) 170 if ( ev.timeZone().isEmpty() )
172 buf += "None"; 171 buf += "None";
173 else 172 else
174 buf += ev.timeZone(); 173 buf += ev.timeZone();
175 buf += "\""; 174 buf += "\"";
176 } 175 }
177 176
178 if (ev.parent() != 0 ) { 177 if (ev.parent() != 0 ) {
179 buf += " recparent=\""+QString::number(ev.parent() )+"\""; 178 buf += " recparent=\""+QString::number(ev.parent() )+"\"";
180 } 179 }
181 180
182 if (ev.children().count() != 0 ) { 181 if (ev.children().count() != 0 ) {
183 QArray<int> children = ev.children(); 182 QArray<int> children = ev.children();
184 buf += " recchildren=\""; 183 buf += " recchildren=\"";
185 for ( uint i = 0; i < children.count(); i++ ) { 184 for ( uint i = 0; i < children.count(); i++ ) {
186 if ( i != 0 ) buf += " "; 185 if ( i != 0 ) buf += " ";
187 buf += QString::number( children[i] ); 186 buf += QString::number( children[i] );
188 } 187 }
189 buf+= "\""; 188 buf+= "\"";
190 } 189 }
191 190
192 // skip custom writing 191 // skip custom writing
193 } 192 }
194 193
195 static bool saveEachEvent( const QMap<int, OPimEvent>& list, QFile& file ) { 194 static bool saveEachEvent( const QMap<int, OPimEvent>& list, QFile& file ) {
196 QMap<int, OPimEvent>::ConstIterator it; 195 QMap<int, OPimEvent>::ConstIterator it;
197 QString buf; 196 QString buf;
198 QCString str; 197 QCString str;
199 int total_written; 198 int total_written;
200 for ( it = list.begin(); it != list.end(); ++it ) { 199 for ( it = list.begin(); it != list.end(); ++it ) {
201 buf = "<event"; 200 buf = "<event";
202 save( it.data(), buf ); 201 save( it.data(), buf );
203 buf += " />\n"; 202 buf += " />\n";
204 str = buf.utf8(); 203 str = buf.utf8();
205 204
206 total_written = file.writeBlock(str.data(), str.length() ); 205 total_written = file.writeBlock(str.data(), str.length() );
207 if ( total_written != int(str.length() ) ) 206 if ( total_written != int(str.length() ) )
208 return false; 207 return false;
209 } 208 }
210 return true; 209 return true;
211 } 210 }
212} 211}
213 212
214namespace Opie { 213namespace Opie {
215ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , 214ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& ,
216 const QString& fileName ) 215 const QString& fileName )
217 : ODateBookAccessBackend() { 216 : ODateBookAccessBackend() {
218 m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; 217 m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName;
219 m_changed = false; 218 m_changed = false;
220} 219}
221ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { 220ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() {
222} 221}
223bool ODateBookAccessBackend_XML::load() { 222bool ODateBookAccessBackend_XML::load() {
224 return loadFile(); 223 return loadFile();
225} 224}
226bool ODateBookAccessBackend_XML::reload() { 225bool ODateBookAccessBackend_XML::reload() {
227 clear(); 226 clear();
228 return load(); 227 return load();
229} 228}
230bool ODateBookAccessBackend_XML::save() { 229bool ODateBookAccessBackend_XML::save() {
231 if (!m_changed) return true; 230 if (!m_changed) return true;
232 231
233 int total_written; 232 int total_written;
234 QString strFileNew = m_name + ".new"; 233 QString strFileNew = m_name + ".new";
235 234
236 QFile f( strFileNew ); 235 QFile f( strFileNew );
237 if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; 236 if (!f.open( IO_WriteOnly | IO_Raw ) ) return false;
238 237
239 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); 238 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
240 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; 239 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n";
241 buf += "<events>\n"; 240 buf += "<events>\n";
242 QCString str = buf.utf8(); 241 QCString str = buf.utf8();
243 total_written = f.writeBlock( str.data(), str.length() ); 242 total_written = f.writeBlock( str.data(), str.length() );
244 if ( total_written != int(str.length() ) ) { 243 if ( total_written != int(str.length() ) ) {
245 f.close(); 244 f.close();
246 QFile::remove( strFileNew ); 245 QFile::remove( strFileNew );
247 return false; 246 return false;
248 } 247 }
249 248
250 if (!saveEachEvent( m_raw, f ) ) { 249 if (!saveEachEvent( m_raw, f ) ) {
251 f.close(); 250 f.close();
252 QFile::remove( strFileNew ); 251 QFile::remove( strFileNew );
253 return false; 252 return false;
254 } 253 }
255 if (!saveEachEvent( m_rep, f ) ) { 254 if (!saveEachEvent( m_rep, f ) ) {
256 f.close(); 255 f.close();
257 QFile::remove( strFileNew ); 256 QFile::remove( strFileNew );
258 return false; 257 return false;
259 } 258 }
260 259
261 buf = "</events>\n</DATEBOOK>\n"; 260 buf = "</events>\n</DATEBOOK>\n";
262 str = buf.utf8(); 261 str = buf.utf8();
263 total_written = f.writeBlock( str.data(), str.length() ); 262 total_written = f.writeBlock( str.data(), str.length() );
264 if ( total_written != int(str.length() ) ) { 263 if ( total_written != int(str.length() ) ) {
265 f.close(); 264 f.close();
266 QFile::remove( strFileNew ); 265 QFile::remove( strFileNew );
267 return false; 266 return false;
268 } 267 }
269 f.close(); 268 f.close();
270 269
271 if ( ::rename( strFileNew, m_name ) < 0 ) { 270 if ( ::rename( strFileNew, m_name ) < 0 ) {
272 QFile::remove( strFileNew ); 271 QFile::remove( strFileNew );
273 return false; 272 return false;
274 } 273 }
275 274
276 m_changed = false; 275 m_changed = false;
277 return true; 276 return true;
278} 277}
279QArray<int> ODateBookAccessBackend_XML::allRecords()const { 278QArray<int> ODateBookAccessBackend_XML::allRecords()const {
280 QArray<int> ints( m_raw.count()+ m_rep.count() ); 279 QArray<int> ints( m_raw.count()+ m_rep.count() );
281 uint i = 0; 280 uint i = 0;
282 QMap<int, OPimEvent>::ConstIterator it; 281 QMap<int, OPimEvent>::ConstIterator it;
283 282
284 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { 283 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
285 ints[i] = it.key(); 284 ints[i] = it.key();
286 i++; 285 i++;
287 } 286 }
288 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { 287 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
289 ints[i] = it.key(); 288 ints[i] = it.key();
290 i++; 289 i++;
291 } 290 }
292 291
293 return ints; 292 return ints;
294} 293}
295QArray<int> ODateBookAccessBackend_XML::queryByExample(const OPimEvent&, int, const QDateTime& ) { 294QArray<int> ODateBookAccessBackend_XML::queryByExample(const OPimEvent&, int, const QDateTime& ) {
296 return QArray<int>(); 295 return QArray<int>();
297} 296}
298void ODateBookAccessBackend_XML::clear() { 297void ODateBookAccessBackend_XML::clear() {
299 m_changed = true; 298 m_changed = true;
300 m_raw.clear(); 299 m_raw.clear();
301 m_rep.clear(); 300 m_rep.clear();
302} 301}
303OPimEvent ODateBookAccessBackend_XML::find( int uid ) const{ 302OPimEvent ODateBookAccessBackend_XML::find( int uid ) const{
304 if ( m_raw.contains( uid ) ) 303 if ( m_raw.contains( uid ) )
305 return m_raw[uid]; 304 return m_raw[uid];
306 else 305 else
307 return m_rep[uid]; 306 return m_rep[uid];
308} 307}
309bool ODateBookAccessBackend_XML::add( const OPimEvent& ev ) { 308bool ODateBookAccessBackend_XML::add( const OPimEvent& ev ) {
310 m_changed = true; 309 m_changed = true;
311 if (ev.hasRecurrence() ) 310 if (ev.hasRecurrence() )
312 m_rep.insert( ev.uid(), ev ); 311 m_rep.insert( ev.uid(), ev );
313 else 312 else
314 m_raw.insert( ev.uid(), ev ); 313 m_raw.insert( ev.uid(), ev );
315 314
316 return true; 315 return true;
317} 316}
318bool ODateBookAccessBackend_XML::remove( int uid ) { 317bool ODateBookAccessBackend_XML::remove( int uid ) {
319 m_changed = true; 318 m_changed = true;
320 m_raw.remove( uid ); 319 m_raw.remove( uid );
321 m_rep.remove( uid ); 320 m_rep.remove( uid );
322 321
323 return true; 322 return true;
324} 323}
325bool ODateBookAccessBackend_XML::replace( const OPimEvent& ev ) { 324bool ODateBookAccessBackend_XML::replace( const OPimEvent& ev ) {
326 replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers) 325 replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers)
327 return add( ev ); 326 return add( ev );
328} 327}
329QArray<int> ODateBookAccessBackend_XML::rawEvents()const { 328
330 return allRecords();
331}
332QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { 329QArray<int> ODateBookAccessBackend_XML::rawRepeats()const {
333 QArray<int> ints( m_rep.count() ); 330 QArray<int> ints( m_rep.count() );
334 uint i = 0; 331 uint i = 0;
335 QMap<int, OPimEvent>::ConstIterator it; 332 QMap<int, OPimEvent>::ConstIterator it;
336 333
337 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { 334 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
338 ints[i] = it.key(); 335 ints[i] = it.key();
339 i++; 336 i++;
340 } 337 }
341 338
342 return ints; 339 return ints;
343} 340}
344QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { 341QArray<int> ODateBookAccessBackend_XML::nonRepeats()const {
345 QArray<int> ints( m_raw.count() ); 342 QArray<int> ints( m_raw.count() );
346 uint i = 0; 343 uint i = 0;
347 QMap<int, OPimEvent>::ConstIterator it; 344 QMap<int, OPimEvent>::ConstIterator it;
348 345
349 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { 346 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
350 ints[i] = it.key(); 347 ints[i] = it.key();
351 i++; 348 i++;
352 } 349 }
353 350
354 return ints; 351 return ints;
355} 352}
356OPimEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { 353OPimEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats()const {
357 OPimEvent::ValueList list; 354 OPimEvent::ValueList list;
358 QMap<int, OPimEvent>::ConstIterator it; 355 QMap<int, OPimEvent>::ConstIterator it;
359 for (it = m_raw.begin(); it != m_raw.end(); ++it ) 356 for (it = m_raw.begin(); it != m_raw.end(); ++it )
360 list.append( it.data() ); 357 list.append( it.data() );
361 358
362 return list; 359 return list;
363} 360}
364OPimEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { 361OPimEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats()const {
365 OPimEvent::ValueList list; 362 OPimEvent::ValueList list;
366 QMap<int, OPimEvent>::ConstIterator it; 363 QMap<int, OPimEvent>::ConstIterator it;
367 for (it = m_rep.begin(); it != m_rep.end(); ++it ) 364 for (it = m_rep.begin(); it != m_rep.end(); ++it )
368 list.append( it.data() ); 365 list.append( it.data() );
369 366
370 return list; 367 return list;
371} 368}
372 369
373// FIXME: Use OPimEvent::fromMap() (eilers) 370// FIXME: Use OPimEvent::fromMap() (eilers)
374bool ODateBookAccessBackend_XML::loadFile() { 371bool ODateBookAccessBackend_XML::loadFile() {
375 m_changed = false; 372 m_changed = false;
376 373
377 int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); 374 int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY );
378 if ( fd < 0 ) return false; 375 if ( fd < 0 ) return false;
379 376
380 struct stat attribute; 377 struct stat attribute;
381 if ( ::fstat(fd, &attribute ) == -1 ) { 378 if ( ::fstat(fd, &attribute ) == -1 ) {
382 ::close( fd ); 379 ::close( fd );
383 return false; 380 return false;
384 } 381 }
385 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 382 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 );
386 if ( map_addr == ( (caddr_t)-1) ) { 383 if ( map_addr == ( (caddr_t)-1) ) {
387 ::close( fd ); 384 ::close( fd );
388 return false; 385 return false;
389 } 386 }
390 387
391 ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); 388 ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL );
392 ::close( fd ); 389 ::close( fd );
393 390
394 QAsciiDict<int> dict(FExceptions+1); 391 QAsciiDict<int> dict(FExceptions+1);
395 dict.setAutoDelete( true ); 392 dict.setAutoDelete( true );
396 dict.insert( "description", new int(FDescription) ); 393 dict.insert( "description", new int(FDescription) );
397 dict.insert( "location", new int(FLocation) ); 394 dict.insert( "location", new int(FLocation) );
398 dict.insert( "categories", new int(FCategories) ); 395 dict.insert( "categories", new int(FCategories) );
399 dict.insert( "uid", new int(FUid) ); 396 dict.insert( "uid", new int(FUid) );
400 dict.insert( "type", new int(FType) ); 397 dict.insert( "type", new int(FType) );
401 dict.insert( "alarm", new int(FAlarm) ); 398 dict.insert( "alarm", new int(FAlarm) );
402 dict.insert( "sound", new int(FSound) ); 399 dict.insert( "sound", new int(FSound) );
403 dict.insert( "rtype", new int(FRType) ); 400 dict.insert( "rtype", new int(FRType) );
404 dict.insert( "rweekdays", new int(FRWeekdays) ); 401 dict.insert( "rweekdays", new int(FRWeekdays) );
405 dict.insert( "rposition", new int(FRPosition) ); 402 dict.insert( "rposition", new int(FRPosition) );
406 dict.insert( "rfreq", new int(FRFreq) ); 403 dict.insert( "rfreq", new int(FRFreq) );
407 dict.insert( "rhasenddate", new int(FRHasEndDate) ); 404 dict.insert( "rhasenddate", new int(FRHasEndDate) );
408 dict.insert( "enddt", new int(FREndDate) ); 405 dict.insert( "enddt", new int(FREndDate) );
409 dict.insert( "start", new int(FRStart) ); 406 dict.insert( "start", new int(FRStart) );
410 dict.insert( "end", new int(FREnd) ); 407 dict.insert( "end", new int(FREnd) );
411 dict.insert( "note", new int(FNote) ); 408 dict.insert( "note", new int(FNote) );
412 dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? 409 dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ??
413 dict.insert( "recparent", new int(FRecParent) ); 410 dict.insert( "recparent", new int(FRecParent) );
414 dict.insert( "recchildren", new int(FRecChildren) ); 411 dict.insert( "recchildren", new int(FRecChildren) );
415 dict.insert( "exceptions", new int(FExceptions) ); 412 dict.insert( "exceptions", new int(FExceptions) );
416 dict.insert( "timezone", new int(FTimeZone) ); 413 dict.insert( "timezone", new int(FTimeZone) );
417 414
418 415
419 // initialiaze db hack 416 // initialiaze db hack
420 m_noTimeZone = true; 417 m_noTimeZone = true;
421 418
422 char* dt = (char*)map_addr; 419 char* dt = (char*)map_addr;
423 int len = attribute.st_size; 420 int len = attribute.st_size;
424 int i = 0; 421 int i = 0;
425 char* point; 422 char* point;
426 const char* collectionString = "<event "; 423 const char* collectionString = "<event ";
427 int strLen = ::strlen(collectionString); 424 int strLen = ::strlen(collectionString);
428 int *find; 425 int *find;
429 while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { 426 while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) {
430 i = point -dt; 427 i = point -dt;
431 i+= strLen; 428 i+= strLen;
432 429
433 alarmTime = -1; 430 alarmTime = -1;
434 snd = 0; // silent 431 snd = 0; // silent
435 432
436 OPimEvent ev; 433 OPimEvent ev;
437 rec = 0; 434 rec = 0;
438 435
439 while ( TRUE ) { 436 while ( TRUE ) {
440 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 437 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
441 ++i; 438 ++i;
442 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 439 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
443 break; 440 break;
444 441
445 442
446 // we have another attribute, read it. 443 // we have another attribute, read it.
447 int j = i; 444 int j = i;
448 while ( j < len && dt[j] != '=' ) 445 while ( j < len && dt[j] != '=' )
449 ++j; 446 ++j;
450 QCString attr( dt+i, j-i+1); 447 QCString attr( dt+i, j-i+1);
451 448
452 i = ++j; // skip = 449 i = ++j; // skip =
453 450
454 // find the start of quotes 451 // find the start of quotes
455 while ( i < len && dt[i] != '"' ) 452 while ( i < len && dt[i] != '"' )
456 ++i; 453 ++i;
457 j = ++i; 454 j = ++i;
458 455
459 bool haveUtf = FALSE; 456 bool haveUtf = FALSE;
460 bool haveEnt = FALSE; 457 bool haveEnt = FALSE;
461 while ( j < len && dt[j] != '"' ) { 458 while ( j < len && dt[j] != '"' ) {
462 if ( ((unsigned char)dt[j]) > 0x7f ) 459 if ( ((unsigned char)dt[j]) > 0x7f )
463 haveUtf = TRUE; 460 haveUtf = TRUE;
464 if ( dt[j] == '&' ) 461 if ( dt[j] == '&' )
465 haveEnt = TRUE; 462 haveEnt = TRUE;
466 ++j; 463 ++j;
467 } 464 }
468 if ( i == j ) { 465 if ( i == j ) {
469 // empty value 466 // empty value
470 i = j + 1; 467 i = j + 1;
471 continue; 468 continue;
472 } 469 }
473 470
474 QCString value( dt+i, j-i+1 ); 471 QCString value( dt+i, j-i+1 );
475 i = j + 1; 472 i = j + 1;
476 473
477 QString str = (haveUtf ? QString::fromUtf8( value ) 474 QString str = (haveUtf ? QString::fromUtf8( value )
478 : QString::fromLatin1( value ) ); 475 : QString::fromLatin1( value ) );
479 if ( haveEnt ) 476 if ( haveEnt )
480 str = Qtopia::plainString( str ); 477 str = Qtopia::plainString( str );
481 478
482 /* 479 /*
483 * add key + value 480 * add key + value
484 */ 481 */
485 find = dict[attr.data()]; 482 find = dict[attr.data()];
486 if (!find) 483 if (!find)
487 ev.setCustomField( attr, str ); 484 ev.setCustomField( attr, str );
488 else { 485 else {
489 setField( ev, *find, str ); 486 setField( ev, *find, str );
490 } 487 }
491 } 488 }
492 /* time to finalize */ 489 /* time to finalize */
493 finalizeRecord( ev ); 490 finalizeRecord( ev );
494 delete rec; 491 delete rec;
495 m_noTimeZone = true; 492 m_noTimeZone = true;
496 } 493 }
497 ::munmap(map_addr, attribute.st_size ); 494 ::munmap(map_addr, attribute.st_size );
498 m_changed = false; // changed during add 495 m_changed = false; // changed during add
499 496
500 return true; 497 return true;
501} 498}
502 499
503// FIXME: Use OPimEvent::fromMap() which makes this obsolete.. (eilers) 500// FIXME: Use OPimEvent::fromMap() which makes this obsolete.. (eilers)
504void ODateBookAccessBackend_XML::finalizeRecord( OPimEvent& ev ) { 501void ODateBookAccessBackend_XML::finalizeRecord( OPimEvent& ev ) {
505 502
506 /* 503 /*
507 * quirk to import datebook files. They normally don't have a 504 * quirk to import datebook files. They normally don't have a
508 * timeZone attribute and we treat this as to use OPimTimeZone::current() 505 * timeZone attribute and we treat this as to use OPimTimeZone::current()
509 */ 506 */
510 if (m_noTimeZone ) 507 if (m_noTimeZone )
511 ev.setTimeZone( OPimTimeZone::current().timeZone() ); 508 ev.setTimeZone( OPimTimeZone::current().timeZone() );
512 509
513 510
514 511
515 /* AllDay is alway in UTC */ 512 /* AllDay is alway in UTC */
516 if ( ev.isAllDay() ) { 513 if ( ev.isAllDay() ) {
517 OPimTimeZone utc = OPimTimeZone::utc(); 514 OPimTimeZone utc = OPimTimeZone::utc();
518 ev.setStartDateTime( utc.toDateTime( start ) ); 515 ev.setStartDateTime( utc.toDateTime( start ) );
519 ev.setEndDateTime ( utc.toDateTime( end ) ); 516 ev.setEndDateTime ( utc.toDateTime( end ) );
520 }else { 517 }else {
521 /* to current date time */ 518 /* to current date time */
522 OPimTimeZone to_zone( ev.timeZone().isEmpty() ? OPimTimeZone::utc() : OPimTimeZone::current() ); 519 OPimTimeZone to_zone( ev.timeZone().isEmpty() ? OPimTimeZone::utc() : OPimTimeZone::current() );
523 520
524 ev.setStartDateTime(to_zone.toDateTime( start)); 521 ev.setStartDateTime(to_zone.toDateTime( start));
525 ev.setEndDateTime (to_zone.toDateTime( end)); 522 ev.setEndDateTime (to_zone.toDateTime( end));
526 } 523 }
527 if ( rec && rec->doesRecur() ) { 524 if ( rec && rec->doesRecur() ) {
528 OPimTimeZone utc = OPimTimeZone::utc(); 525 OPimTimeZone utc = OPimTimeZone::utc();
529 OPimRecurrence recu( *rec ); // call copy c'tor; 526 OPimRecurrence recu( *rec ); // call copy c'tor;
530 recu.setEndDate ( utc.toDateTime( rp_end ).date() ); 527 recu.setEndDate ( utc.toDateTime( rp_end ).date() );
531 recu.setCreatedDateTime( utc.toDateTime( created ) ); 528 recu.setCreatedDateTime( utc.toDateTime( created ) );
532 recu.setStart( ev.startDateTime().date() ); 529 recu.setStart( ev.startDateTime().date() );
533 ev.setRecurrence( recu ); 530 ev.setRecurrence( recu );
534 } 531 }
535 532
536 if (alarmTime != -1 ) { 533 if (alarmTime != -1 ) {
537 QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); 534 QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 );
538 OPimAlarm al( snd , dt ); 535 OPimAlarm al( snd , dt );
539 ev.notifiers().add( al ); 536 ev.notifiers().add( al );
540 } 537 }
541 if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { 538 if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) {
542 owarn << "already contains assign uid" << oendl;
543 ev.setUid( 1 ); 539 ev.setUid( 1 );
544 } 540 }
545 541
546 if ( ev.hasRecurrence() ) 542 if ( ev.hasRecurrence() )
547 m_rep.insert( ev.uid(), ev ); 543 m_rep.insert( ev.uid(), ev );
548 else 544 else
549 m_raw.insert( ev.uid(), ev ); 545 m_raw.insert( ev.uid(), ev );
550 546
551} 547}
552void ODateBookAccessBackend_XML::setField( OPimEvent& e, int id, const QString& value) { 548void ODateBookAccessBackend_XML::setField( OPimEvent& e, int id, const QString& value) {
553// owarn << " setting " << value << "" << oendl;
554 switch( id ) { 549 switch( id ) {
555 case FDescription: 550 case FDescription:
556 e.setDescription( value ); 551 e.setDescription( value );
557 break; 552 break;
558 case FLocation: 553 case FLocation:
559 e.setLocation( value ); 554 e.setLocation( value );
560 break; 555 break;
561 case FCategories: 556 case FCategories:
562 e.setCategories( e.idsFromString( value ) ); 557 e.setCategories( e.idsFromString( value ) );
563 break; 558 break;
564 case FUid: 559 case FUid:
565 e.setUid( value.toInt() ); 560 e.setUid( value.toInt() );
566 break; 561 break;
567 case FType: 562 case FType:
568 if ( value == "AllDay" ) { 563 if ( value == "AllDay" ) {
569 e.setAllDay( true ); 564 e.setAllDay( true );
570 } 565 }
571 break; 566 break;
572 case FAlarm: 567 case FAlarm:
573 alarmTime = value.toInt(); 568 alarmTime = value.toInt();
574 break; 569 break;
575 case FSound: 570 case FSound:
576 snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; 571 snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent;
577 break; 572 break;
578 // recurrence stuff 573 // recurrence stuff
579 case FRType: 574 case FRType:
580 if ( value == "Daily" ) 575 if ( value == "Daily" )
581 recur()->setType( OPimRecurrence::Daily ); 576 recur()->setType( OPimRecurrence::Daily );
582 else if ( value == "Weekly" ) 577 else if ( value == "Weekly" )
583 recur()->setType( OPimRecurrence::Weekly); 578 recur()->setType( OPimRecurrence::Weekly);
584 else if ( value == "MonthlyDay" ) 579 else if ( value == "MonthlyDay" )
585 recur()->setType( OPimRecurrence::MonthlyDay ); 580 recur()->setType( OPimRecurrence::MonthlyDay );
586 else if ( value == "MonthlyDate" ) 581 else if ( value == "MonthlyDate" )
587 recur()->setType( OPimRecurrence::MonthlyDate ); 582 recur()->setType( OPimRecurrence::MonthlyDate );
588 else if ( value == "Yearly" ) 583 else if ( value == "Yearly" )
589 recur()->setType( OPimRecurrence::Yearly ); 584 recur()->setType( OPimRecurrence::Yearly );
590 else 585 else
591 recur()->setType( OPimRecurrence::NoRepeat ); 586 recur()->setType( OPimRecurrence::NoRepeat );
592 break; 587 break;
593 case FRWeekdays: 588 case FRWeekdays:
594 recur()->setDays( value.toInt() ); 589 recur()->setDays( value.toInt() );
595 break; 590 break;
596 case FRPosition: 591 case FRPosition:
597 recur()->setPosition( value.toInt() ); 592 recur()->setPosition( value.toInt() );
598 break; 593 break;
599 case FRFreq: 594 case FRFreq:
600 recur()->setFrequency( value.toInt() ); 595 recur()->setFrequency( value.toInt() );
601 break; 596 break;
602 case FRHasEndDate: 597 case FRHasEndDate:
603 recur()->setHasEndDate( value.toInt() ); 598 recur()->setHasEndDate( value.toInt() );
604 break; 599 break;
605 case FREndDate: { 600 case FREndDate: {
606 rp_end = (time_t) value.toLong(); 601 rp_end = (time_t) value.toLong();
607 break; 602 break;
608 } 603 }
609 case FRStart: { 604 case FRStart: {
610 start = (time_t) value.toLong(); 605 start = (time_t) value.toLong();
611 break; 606 break;
612 } 607 }
613 case FREnd: { 608 case FREnd: {
614 end = ( (time_t) value.toLong() ); 609 end = ( (time_t) value.toLong() );
615 break; 610 break;
616 } 611 }
617 case FNote: 612 case FNote:
618 e.setNote( value ); 613 e.setNote( value );
619 break; 614 break;
620 case FCreated: 615 case FCreated:
621 created = value.toInt(); 616 created = value.toInt();
622 break; 617 break;
623 case FRecParent: 618 case FRecParent:
624 e.setParent( value.toInt() ); 619 e.setParent( value.toInt() );
625 break; 620 break;
626 case FRecChildren:{ 621 case FRecChildren:{
627 QStringList list = QStringList::split(' ', value ); 622 QStringList list = QStringList::split(' ', value );
628 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { 623 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
629 e.addChild( (*it).toInt() ); 624 e.addChild( (*it).toInt() );
630 } 625 }
631 } 626 }
632 break; 627 break;
633 case FExceptions:{ 628 case FExceptions:{
634 QStringList list = QStringList::split(' ', value ); 629 QStringList list = QStringList::split(' ', value );
635 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { 630 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
636 QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); 631 QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() );
637 owarn << "adding exception " << date.toString() << "" << oendl;
638 recur()->exceptions().append( date ); 632 recur()->exceptions().append( date );
639 } 633 }
640 } 634 }
641 break; 635 break;
642 case FTimeZone: 636 case FTimeZone:
643 m_noTimeZone = false; 637 m_noTimeZone = false;
644 if ( value != "None" ) 638 if ( value != "None" )
645 e.setTimeZone( value ); 639 e.setTimeZone( value );
646 break; 640 break;
647 default: 641 default:
648 break; 642 break;
649 } 643 }
650} 644}
651QArray<int> ODateBookAccessBackend_XML::matchRegexp( const QRegExp &r ) const 645QArray<int> ODateBookAccessBackend_XML::matchRegexp( const QRegExp &r ) const
652{ 646{
653 QArray<int> m_currentQuery( m_raw.count()+ m_rep.count() ); 647 QArray<int> m_currentQuery( m_raw.count()+ m_rep.count() );
654 uint arraycounter = 0; 648 uint arraycounter = 0;
655 QMap<int, OPimEvent>::ConstIterator it; 649 QMap<int, OPimEvent>::ConstIterator it;
656 650
657 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) 651 for ( it = m_raw.begin(); it != m_raw.end(); ++it )
658 if ( it.data().match( r ) ) 652 if ( it.data().match( r ) )
659 m_currentQuery[arraycounter++] = it.data().uid(); 653 m_currentQuery[arraycounter++] = it.data().uid();
660 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) 654 for ( it = m_rep.begin(); it != m_rep.end(); ++it )
661 if ( it.data().match( r ) ) 655 if ( it.data().match( r ) )
662 m_currentQuery[arraycounter++] = it.data().uid(); 656 m_currentQuery[arraycounter++] = it.data().uid();
663 657
664 // Shrink to fit.. 658 // Shrink to fit..
665 m_currentQuery.resize(arraycounter); 659 m_currentQuery.resize(arraycounter);
666 660
667 return m_currentQuery; 661 return m_currentQuery;
668} 662}
669 663
670} 664}
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.h b/libopie2/opiepim/backend/odatebookaccessbackend_xml.h
index af5b114..cb19f76 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.h
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.h
@@ -1,88 +1,88 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H 29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H
30#define OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H 30#define OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H
31 31
32#include <qmap.h> 32#include <qmap.h>
33 33
34#include <opie2/odatebookaccessbackend.h> 34#include <opie2/odatebookaccessbackend.h>
35 35
36namespace Opie { 36namespace Opie {
37/** 37/**
38 * This is the default XML implementation for DateBoook XML storage 38 * This is the default XML implementation for DateBoook XML storage
39 * It fully implements the interface 39 * It fully implements the interface
40 * @see ODateBookAccessBackend 40 * @see ODateBookAccessBackend
41 * @see OPimAccessBackend 41 * @see OPimAccessBackend
42 */ 42 */
43class ODateBookAccessBackend_XML : public ODateBookAccessBackend { 43class ODateBookAccessBackend_XML : public ODateBookAccessBackend {
44public: 44public:
45 ODateBookAccessBackend_XML( const QString& appName, 45 ODateBookAccessBackend_XML( const QString& appName,
46 const QString& fileName = QString::null); 46 const QString& fileName = QString::null);
47 ~ODateBookAccessBackend_XML(); 47 ~ODateBookAccessBackend_XML();
48 48
49 bool load(); 49 bool load();
50 bool reload(); 50 bool reload();
51 bool save(); 51 bool save();
52 52
53 QArray<int> allRecords()const; 53 QArray<int> allRecords()const;
54 QArray<int> matchRegexp(const QRegExp &r) const; 54 QArray<int> matchRegexp(const QRegExp &r) const;
55 QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() ); 55 QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() );
56 OPimEvent find( int uid )const; 56 OPimEvent find( int uid )const;
57 void clear(); 57 void clear();
58 bool add( const OPimEvent& ev ); 58 bool add( const OPimEvent& ev );
59 bool remove( int uid ); 59 bool remove( int uid );
60 bool replace( const OPimEvent& ev ); 60 bool replace( const OPimEvent& ev );
61 61
62 QArray<UID> rawEvents()const; 62 QArray<UID> rawEvents()const;
63 QArray<UID> rawRepeats()const; 63 QArray<UID> rawRepeats()const;
64 QArray<UID> nonRepeats()const; 64 QArray<UID> nonRepeats()const;
65 65
66 OPimEvent::ValueList directNonRepeats(); 66 OPimEvent::ValueList directNonRepeats()const;
67 OPimEvent::ValueList directRawRepeats(); 67 OPimEvent::ValueList directRawRepeats()const;
68 68
69private: 69private:
70 bool m_changed :1 ; 70 bool m_changed :1 ;
71 bool m_noTimeZone : 1; 71 bool m_noTimeZone : 1;
72 72
73 bool loadFile(); 73 bool loadFile();
74 inline void finalizeRecord( OPimEvent& ev ); 74 inline void finalizeRecord( OPimEvent& ev );
75 inline void setField( OPimEvent&, int field, const QString& val ); 75 inline void setField( OPimEvent&, int field, const QString& val );
76 QString m_name; 76 QString m_name;
77 QMap<int, OPimEvent> m_raw; 77 QMap<int, OPimEvent> m_raw;
78 QMap<int, OPimEvent> m_rep; 78 QMap<int, OPimEvent> m_rep;
79 79
80 struct Data; 80 struct Data;
81 Data* data; 81 Data* data;
82 class Private; 82 class Private;
83 Private *d; 83 Private *d;
84}; 84};
85 85
86} 86}
87 87
88#endif 88#endif
diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h
index 26af762..0d112c9 100644
--- a/libopie2/opiepim/backend/opimaccessbackend.h
+++ b/libopie2/opiepim/backend/opimaccessbackend.h
@@ -1,196 +1,423 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) The Main Author <main-author@whereever.org> 3 Copyright (C) The Main Author <main-author@whereever.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_PIM_ACCESS_BACKEND 29#ifndef OPIE_PIM_ACCESS_BACKEND
30#define OPIE_PIM_ACCESS_BACKEND 30#define OPIE_PIM_ACCESS_BACKEND
31 31
32#include <qarray.h> 32#include <qarray.h>
33#include <qdatetime.h> 33#include <qdatetime.h>
34 34
35#include <opie2/opimtemplatebase.h> 35#include <opie2/opimtemplatebase.h>
36#include <opie2/opimrecord.h> 36#include <opie2/opimrecord.h>
37 37#include <opie2/opimbackendoccurrence.h>
38 38
39namespace Opie { 39namespace Opie {
40class OPimAccessBackendPrivate; 40class OPimAccessBackendPrivate;
41
41/** 42/**
42 * OPimAccessBackend is the base class 43 * OPimAccessBackend is the Backend Interface to be used
43 * for all private backends 44 * by OTemplateBase based Frontends.
44 * it operates on OPimRecord as the base class 45 * For efficency reasons and to support delayed loading
45 * and it's responsible for fast manipulating 46 * most of the Frontend functions can be implemented
46 * the resource the implementation takes care 47 * by this backend.
47 * of 48 * This allows to utilise the best method on each backend.
49 * For example we can use SQL queries instead of self made
50 * query which is first more efficent and also uses less memory.
48 */ 51 */
49template <class T = OPimRecord> 52template <class T = OPimRecord>
50class OPimAccessBackend { 53class OPimAccessBackend {
51public: 54public:
52 typedef OTemplateBase<T> Frontend; 55 typedef OTemplateBase<T> Frontend;
53 56
54 /** The access hint from the frontend */ 57 //@{
55 OPimAccessBackend(int access = 0); 58 OPimAccessBackend(int access = 0);
56 virtual ~OPimAccessBackend(); 59 virtual ~OPimAccessBackend();
60 //@}
57 61
58 /** 62 //@{
59 * load the resource
60 */
61 virtual bool load() = 0; 63 virtual bool load() = 0;
62
63 /**
64 * reload the resource
65 */
66 virtual bool reload() = 0; 64 virtual bool reload() = 0;
67
68 /**
69 * save the resource and
70 * all it's changes
71 */
72 virtual bool save() = 0; 65 virtual bool save() = 0;
66 virtual void clear() = 0;
67 //@}
73 68
74 /**
75 * return an array of
76 * all available uids
77 */
78 virtual QArray<int> allRecords()const = 0;
79 69
80 /** 70 //@{
81 * return a List of records 71 virtual UIDArray allRecords()const = 0;
82 * that match the regex 72 virtual UIDArray matchRegexp(const QRegExp &r) const;
83 */ 73 virtual UIDArray queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() )const = 0;
84 virtual QArray<int> matchRegexp(const QRegExp &r) const = 0; 74 virtual UIDArray queryByExample( const OPimRecord* rec, int, const QDateTime& d = QDateTime() )const;
75 virtual UIDArray sorted( const UIDArray&, bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const;
76 virtual UIDArray sorted( bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const;
77 virtual OPimBackendOccurrence::List occurrences( const QDate& start, const QDate& end)const;
78 virtual OPimBackendOccurrence::List occurrences( const QDateTime& dt )const;
79 //@}
85 80
86 /**
87 * queryByExample for T with the given Settings
88 *
89 */
90 virtual QArray<int> queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() ) = 0;
91 81
92 /** 82 //@{
93 * find the OPimRecord with uid @param uid 83 virtual T find(UID uid )const = 0;
94 * returns T and T.isEmpty() if nothing was found 84 virtual T find(UID uid, const QArray<UID>& items,
95 */ 85 uint current, typename Frontend::CacheDirection )const ;
96 virtual T find( int uid )const = 0; 86 //@}
97 87
98 virtual T find( int uid, const QArray<int>& items,
99 uint current, typename Frontend::CacheDirection ) const;
100 /**
101 * clear the back end
102 */
103 virtual void clear() = 0;
104 88
105 /** 89 //@{
106 * add T
107 */
108 virtual bool add( const T& t ) = 0; 90 virtual bool add( const T& t ) = 0;
91 virtual bool remove( UID uid ) = 0;
92 virtual bool replace( const T& t ) = 0;
93 //@}
109 94
110 /**
111 * remove
112 */
113 virtual bool remove( int uid ) = 0;
114 95
115 /**
116 * replace a record with T.uid()
117 */
118 virtual bool replace( const T& t ) = 0;
119 96
120 /*
121 * setTheFrontEnd!!!
122 */
123 void setFrontend( Frontend* front ); 97 void setFrontend( Frontend* front );
124 98
125 /** 99 /**
126 * set the read ahead count 100 * set the read ahead count
127 */ 101 */
128 void setReadAhead( uint count ); 102 void setReadAhead( uint count );
129protected: 103protected:
104 //@{
130 int access()const; 105 int access()const;
131
132 void cache( const T& t )const; 106 void cache( const T& t )const;
133
134 /**
135 * use a prime number here!
136 */
137 void setSaneCacheSize( int ); 107 void setSaneCacheSize( int );
138
139 uint readAhead()const; 108 uint readAhead()const;
109 //@}
140 110
141private: 111private:
142 OPimAccessBackendPrivate *d; 112 OPimAccessBackendPrivate *d;
143 Frontend* m_front; 113 Frontend* m_front;
144 uint m_read; 114 uint m_read;
145 int m_acc; 115 int m_acc;
146 116
147}; 117};
148 118
149template <class T> 119template <class T>
150OPimAccessBackend<T>::OPimAccessBackend(int acc) 120OPimAccessBackend<T>::OPimAccessBackend(int acc)
151 : m_acc( acc ) 121 : m_acc( acc )
152{ 122{
153 m_front = 0l; 123 m_front = 0l;
154} 124}
155template <class T> 125template <class T>
156OPimAccessBackend<T>::~OPimAccessBackend() { 126OPimAccessBackend<T>::~OPimAccessBackend() {
157 127
158} 128}
129
130/*
131 * Slow but default matchRegexp Implementation
132 * Create a Big Enough QArray and then iterate
133 * over all Records and matchRegexp them.
134 * At the end we will resize the array to the actual
135 * number of items
136 */
137template <class T>
138UIDArray OPimAccessBackend<T>::matchRegexp( const QRegExp& reg )const {
139 UIDArray all_rec = allRecords();
140 UIDArray result( all_rec.count() );
141 uint used_records = 0, all_rec_count = all_rec.count();
142
143 for ( uint i = 0; i < all_rec_count; ++i )
144 if (find( all_rec[i], all_rec, i, Frontend::Forward ).match( reg ) )
145 result[used_records++] = all_rec[i];
146
147 /* shrink to fit */
148 result.resize( used_records );
149 return result;
150}
151
152template <class T>
153UIDArray OPimAccessBackend<T>::queryByExample( const OPimRecord* rec, int settings,
154 const QDateTime& datetime )const {
155 T* tmp_rec = T::safeCast( rec );
156 UIDArray ar;
157 if ( tmp_rec )
158 ar = queryByExample( *tmp_rec, settings, datetime );
159
160 return ar;
161}
162
163template <class T>
164UIDArray OPimAccessBackend<T>::sorted( const UIDArray& ids, bool,
165 int, int, const QArray<int>& ) const {
166 return ids;
167}
168
169template <class T>
170UIDArray OPimAccessBackend<T>::sorted( bool asc, int order, int filter,
171 const QArray<int>& cats )const {
172 return sorted( allRecords(), asc, order, filter, cats );
173}
174
175template<class T>
176OPimBackendOccurrence::List OPimAccessBackend<T>::occurrences( const QDate&,
177 const QDate& )const {
178 return OPimBackendOccurrence::List();
179}
180
181template<class T>
182OPimBackendOccurrence::List OPimAccessBackend<T>::occurrences( const QDateTime& dt )const {
183 QDate date = dt.date();
184 return occurrences( date, date );
185}
186
159template <class T> 187template <class T>
160void OPimAccessBackend<T>::setFrontend( Frontend* fr ) { 188void OPimAccessBackend<T>::setFrontend( Frontend* fr ) {
161 m_front = fr; 189 m_front = fr;
162} 190}
163template <class T> 191template <class T>
164void OPimAccessBackend<T>::cache( const T& t )const { 192void OPimAccessBackend<T>::cache( const T& t )const {
165 if ( m_front ) 193 if ( m_front )
166 m_front->cache( t ); 194 m_front->cache( t );
167} 195}
168 196
169
170template <class T> 197template <class T>
171void OPimAccessBackend<T>::setSaneCacheSize( int size) { 198void OPimAccessBackend<T>::setSaneCacheSize( int size) {
172 if ( m_front ) 199 if ( m_front )
173 m_front->setSaneCacheSize( size ); 200 m_front->setSaneCacheSize( size );
174} 201}
175template <class T> 202template <class T>
176T OPimAccessBackend<T>::find( int uid, const QArray<int>&, 203T OPimAccessBackend<T>::find( int uid, const QArray<int>&,
177 uint, typename Frontend::CacheDirection ) const{ 204 uint, typename Frontend::CacheDirection ) const{
178 qDebug( "*** Lookahead feature not supported. Fallback to default find!!" ); 205 qDebug( "*** Lookahead feature not supported. Fallback to default find!!" );
179 return find( uid ); 206 return find( uid );
180} 207}
181template <class T> 208template <class T>
182void OPimAccessBackend<T>::setReadAhead( uint count ) { 209void OPimAccessBackend<T>::setReadAhead( uint count ) {
183 m_read = count; 210 m_read = count;
184} 211}
185template <class T> 212template <class T>
186uint OPimAccessBackend<T>::readAhead()const { 213uint OPimAccessBackend<T>::readAhead()const {
187 return m_read; 214 return m_read;
188} 215}
189template <class T> 216template <class T>
190int OPimAccessBackend<T>::access()const { 217int OPimAccessBackend<T>::access()const {
191 return m_acc; 218 return m_acc;
192} 219}
193 220
194} 221}
195 222
223/**
224 * \fn template <class T> OPimAccessBackend<T>::OPimAccessBackend(int hint )
225 * @param hint The access hint from the frontend
226 */
227
228/**
229 * \fn template <class T> bool OPimAccessBackend<T>::load()
230 * Opens the DataBase and does necessary
231 * initialisation of internal structures.
232 *
233 * @return true If the DataBase could be opened and
234 * Information was successfully loaded
235 */
236
237/**
238 * \fn template <class T> bool OPimAccessBackend<T>::reload()
239 * Reinitialise the DataBase and merges the external changes
240 * with your local changes.
241 *
242 * @return True if the DataBase was reloaded.
243 *
244 */
245
246/**
247 * \fn template <class T> bool OPimAccessBackend<T>::save()
248 *
249 * Save the changes to storage. In case of memory or
250 * disk shortage, return false.
251 *
252 *
253 * @return True if the DataBase could be saved to storage.
254 */
255
256/**
257 * \fn template <class T> bool OPimAccessBackend<T>::clear()
258 * Until a \sa save() changes shouldn't be comitted
259 *
260 *
261 * @return True if the DataBase could be cleared
262 * @todo Introduce a 'Commit'
263 */
264
265/**
266 * \fn template <class T> QArray<UID> OPimAccessBackend<T>::allRecords()const
267 * Return an array of all available uids in the loaded
268 * DataBase.
269 * @see load
270 */
271
272/**
273 * \fn template <class T> QArray<UID> OPimAccessBackend<T>::matchRegexp(const QRegExp& r)const
274 * Return a List of records that match the regex \par r.
275 *
276 * @param r The QRegExp to match.
277 */
278
279/**
280 * \fn template <class T> QArray<UID> OPimAccessBackend<T>::queryByExample(const T& t, int settings, const QDateTime& d = QDateTime() )
281 *
282 * Implement QueryByExample. An Example record is filled and with the
283 * settings and QDateTime it is determined how the query should be executed.
284 * Return a list of UIDs that match the Example
285 *
286 * @param t The Example record
287 * @param settings Gives
288 *
289 */
290
291/**
292 * \fn template<class T> QArray<UID> OPimAccessBackend<T>::sorted(const QArray<UID>& ids, bool asc, int sortOrder, int sortFilter, int cat)
293 * \brief Sort the List of records according to the preference
294 *
295 * Implement sorting in your backend. The default implementation is
296 * to return the list as it was passed.
297 * The default Backend Implementation should do unaccelerated filtering
298 *
299 *
300 * @param ids The Records to sort
301 * @param asc Sort ascending or descending
302 * @param sortOrder
303 * @param sortFilter Sort filter
304 * @param cat The Category to include
305 */
306
307/**
308 * \fn template <class T> T OPimAccessBackend<T>::find(UID uid)const
309 * \brief Find the Record with the UID
310 *
311 * Find the UID in the database and return the record.
312 * @param uid The uid to be searched for
313 * @return The record or an empty record (T.isEmpty())
314 *
315 */
316
317/**
318 * \fn template <class T> T OPimAccessBackend<T>::find( UID uid, const QArray<UID>& items, uint current, typename Frontend::CacheDirection d)const
319 * \brief find a Record and do a read ahead or read behind
320 *
321 * @param uid The UID to search for
322 * @param items The list of items from where your search
323 * @param current The index of \param uid
324 * @param d The direction to search for
325 *
326 * @see find
327 */
328
329
330/**
331 * \fn template<class T> bool OPimAccessBackend<T>::add(const T& t)
332 *
333 * \brief Add the record to the internal database
334 *
335 * If an record with the same t.uid() is already present internally
336 * the behaviour is undefined but the state of the database
337 * needs to be stable.
338 * For modifying a record use \sa replace.
339 *
340 *
341 * @return true if the record could be added or false if not
342 * @todo Eilers your opinion on readd/replace
343 */
344
345/**
346 * \fn template<class T> bool OPimAccessBackend<T>::remove(UID uid)
347 * \brief Remove a record by its UID
348 *
349 * Remove the records with UID from the internal Database.
350 *
351 * @return True if the record could be removed.
352 *
353 */
354
355/**
356 * \fn template<class T> bool OPimAccessBackend<T>::replace(const T& t)
357 * \brief Take this Record and replace the old version.
358 *
359 * Take \param t as the new record for t.uid(). It is not described
360 * what happens if the record is not present in the database.
361 * Normally the record is determined by the UID.
362 *
363 * @param t The record to use internally.
364 */
365
366/**
367 * \fn template<class T> void OPimAccessBackend<T>::setFrontend( Frontend* fron)
368 * \@aram fron The Frontend that uses this backend
369 *
370 * This function is called by the frontend and is used
371 */
372
373/**
374 * \fn template<class T> void OPimAccessBackend<T>::setReadAhead(uint count)
375 * \brief Set the number of items to Read-Ahead/Read-Behind
376 *
377 * @param count The number of records to read ahead
378 */
379
380/**
381 * \fn template<class T> void OPimAccessBackend<T>::cache( const T& t)const
382 * \brief Add the Record to the PIM Cache
383 *
384 * This will add the Record to the PIM cache, which is owned
385 * by the FrontEnd. If no FrontEnd is available the item will
386 * not be cached.
387 *
388 *
389 * @param t The Item to be added to the Cache
390 */
391
392/**
393 * \fn template<class T> void OPimAccessBackend<T>::setSaneCacheSize(int items)
394 * \brief Give a hint on the number of too cached items
395 *
396 * Give the Frontend a hint on the number of items to be cached. Use
397 * a prime number for best performance.
398 *
399 * @param items The number of items to be cached
400 */
401
402/**
403 * \fn template<class T> uint OPimAccessBackend<T>::readAhead()const
404 * \brief Return the number of Items to be ReadAhead
405 *
406 * @return The number of Items to read ahead/read behind
407 */
408
409/**
410 * \fn template<class T> QArray<OPimBackendOccurence> OPimAccessBackend<T>::occurrences(const QDateTime& start,const QDateTime& end)
411 * \brief Get a List of Occurrences for a period of time
412 *
413 * Return an Array of OPimBackendOccurence for a period of time. If start == end date
414 * return only occurrences for the start date. If end is smaller the start date
415 * the result is not defined. You could switch dates or return an empty list.
416 *
417 * @return Return an array of OPimBackendOccurence for the period specified by the parameters
418 * @param start The start of the period.
419 * @param end The end of the period.
420 *
421 */
422
196#endif 423#endif
diff --git a/libopie2/opiepim/backend/opimbackendoccurrence.cpp b/libopie2/opiepim/backend/opimbackendoccurrence.cpp
new file mode 100644
index 0000000..8af930d
--- a/dev/null
+++ b/libopie2/opiepim/backend/opimbackendoccurrence.cpp
@@ -0,0 +1,241 @@
1/*
2 This file is part of the Opie Project
3 Copyright (C) 2004 Holger Hans Peter Freyther <zecke@handhelds.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l.
6 .>+-=
7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more
20++= -. .` .: details.
21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA.
28*/
29
30#include "opimbackendoccurrence.h"
31
32namespace Opie {
33
34OPimBackendOccurrence::OPimBackendOccurrence() {}
35/**
36 * \brief The occurence is only on the specefic Day
37 *
38 * If an occurrence is only a day without any time associated
39 * use this Constructor.
40 * \sa timeAssociated() will return false.
41 *
42 * @param date The Date this Occurence takes place
43 * @param uid The \sa UID of the associated OPimRecord
44 * @param sum The optional summary
45 *
46 */
47OPimBackendOccurrence::OPimBackendOccurrence( const QDate& date,
48 const UID& uid,
49 const QString& sum )
50 : m_start( date ), m_end( date ), m_uid( uid ),
51 m_haveTime(false ), m_summary( sum )
52{}
53
54/**
55 * \brief An Occurrence with a start day and end day without time
56 *
57 * Overloaded Constructor. Use this if you've a start date and
58 * end date but no time. If you need to overwrite the summary
59 * use setSummary.
60 * \sa timeAssociated() will return false.
61 *
62 * @param date The Start Date
63 * @param end Tne End Date
64 * @param uid The UID of the associated record
65 *
66 * @see setSummary
67 */
68OPimBackendOccurrence::OPimBackendOccurrence( const QDate& date,
69 const QDate& end,
70 const UID& uid)
71 : m_start( date ), m_end( end ), m_uid( uid ), m_haveTime( false )
72{}
73
74
75/**
76 * \brief Use Start and End Date with Time
77 *
78 * Overloaded Constructor to use Dates with Time time associated
79 * to it. \sa timeAssociated() will return true.
80 *
81 * @param date The Start Date and Time of the occurrence
82 * @param end The End Date and Time of the occurrence
83 * @param uid The UID of the \sa OPimRecord.
84 */
85OPimBackendOccurrence::OPimBackendOccurrence( const QDateTime& date,
86 const QDateTime& end,
87 const UID& uid )
88 : m_start( date ), m_end( end ), m_uid( uid ), m_haveTime( true )
89{}
90
91/**
92 * \brief Return the Start Date and Time
93 *
94 * @return This method will return the start
95 * Date and Time. Time is only valid if
96 * \sa timeAssociated() is true.
97 *
98 */
99QDateTime OPimBackendOccurrence::startDateTime()const {
100 return m_start;
101}
102
103/**
104 * \brief Return the Start Date and Time
105 *
106 * @return This will return the end Date and Time. The
107 * limitation for Time is the same as in startDateTime
108 *
109 * @see startDateTime()
110 */
111QDateTime OPimBackendOccurrence::endDateTime()const {
112 return m_end;
113}
114
115/**
116 * \brief Return the UID of the Associated OPimRecord
117 *
118 * @return the associated OPimRecord
119 */
120UID OPimBackendOccurrence::uid()const {
121 return m_uid;
122}
123
124/**
125 * \brief Return if there is a time associated or not
126 *
127 * If a time is present with start and end date this method
128 * will return true. There is no direct way to manipulate
129 * that attribute. But \sa setStartDate and \sa setStartDateTime
130 * will change it.
131 *
132 * @return Return true if a time is available with the date
133 *
134 */
135bool OPimBackendOccurrence::isAllDay()const {
136 return m_haveTime;
137}
138
139/**
140 * @return The special summary that will overwrite OPimRecord::summary
141 */
142QString OPimBackendOccurrence::summary()const {
143 return m_summary;
144}
145
146QString OPimBackendOccurrence::location()const {
147 return m_location;
148}
149
150QString OPimBackendOccurrence::note()const {
151 return m_note;
152}
153
154/**
155 * \brief Set the Start Date
156 *
157 * This method will set the start date and internally will mark
158 * this occurrence to have no time associated to both start
159 * and end date.
160 * A call to timeAssociated will return false after using this
161 * method.
162 *
163 * @param start The Start Date
164 *
165 */
166void OPimBackendOccurrence::setStartDate( const QDate& start) {
167 m_start = start;
168 m_haveTime = false;
169}
170
171/**
172 * \brief Set the Start Date and Time
173 *
174 * Set the Start Date and Time. After this call
175 * \sa timeAssociated will return true.
176 *
177 * @param dt The Start Date and Time to be set
178 */
179void OPimBackendOccurrence::setStartDateTime( const QDateTime& dt ) {
180 m_start = dt;
181 m_haveTime = true;
182}
183
184/**
185 * \brief This will set the End Date.
186 *
187 * This method will set the End Date. The timeAssociated attribute
188 * will not be changed.
189 *
190 * @param end The End Date to be set
191 */
192void OPimBackendOccurrence::setEndDate( const QDate& end ) {
193 m_end = end;
194}
195
196/**
197 * \brief Set the End Date and Time of the occurrence
198 *
199 * This will set the End Date and Time but will not change
200 * the timeAssociated attribute.
201 *
202 * @param dt The End Date and Time to be set.
203 */
204void OPimBackendOccurrence::setEndDateTime( const QDateTime& dt ) {
205 m_end = dt;
206}
207
208/**
209 * \brief This method will set the UID of the Record
210 *
211 * Set the UID of the OPimRecord to be associated with
212 * this OPimRecurrence.
213 *
214 * @param uid The UID of the associated OPimRecord to be set
215 */
216void OPimBackendOccurrence::setUid( const UID& uid ) {
217 m_uid = uid;
218}
219
220
221/**
222 * \brief Set a special summary instead of \sa OPimRecord::summary()
223 *
224 * If \sa OPimRecord::summary() doesn't describe the occurrence
225 * reason you can set a custom summary for the Occurrence.
226 *
227 * @param str The to be set Summary
228 */
229void OPimBackendOccurrence::setSummary( const QString& str ) {
230 m_summary = str;
231}
232
233void OPimBackendOccurrence::setLocation( const QString& str ) {
234 m_location = str;
235}
236
237void OPimBackendOccurrence::setNote( const QString& str ) {
238 m_note = str;
239}
240
241}
diff --git a/libopie2/opiepim/backend/opimbackendoccurrence.h b/libopie2/opiepim/backend/opimbackendoccurrence.h
new file mode 100644
index 0000000..08c3cdf
--- a/dev/null
+++ b/libopie2/opiepim/backend/opimbackendoccurrence.h
@@ -0,0 +1,108 @@
1/*
2 This file is part of the Opie Project
3 Copyright (C) 2004 Holger Hans Peter Freyther <zecke@handhelds.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l.
6 .>+-=
7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more
20++= -. .` .: details.
21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA.
28*/
29
30#ifndef OPIE_PIM_BACKEND_OCCURRENCE_H
31#define OPIE_PIM_BACKEND_OCCURRENCE_H
32
33#include <opie2/opimglobal.h>
34
35#include <qarray.h>
36#include <qdatetime.h>
37#include <qvaluelist.h>
38
39namespace Opie {
40
41/**
42 * \brief Internal representation of an Occurence
43 *
44 * This class is used by the Backends to express
45 * Occurences for the Period Based Query to
46 * the by the Backend represanted Database.
47 * In the Frontend this single representation is splitted
48 * into per day \sa OPimOccurrence 's.
49 * OPimBackendOccurrence can be understand as a hint to
50 * the Frontend and must contain the \sa UID, the Start Date
51 * and End Date of the Occurence. If you have no time associated
52 * to the datetime use the QDate constructors.
53 * If OPimRecord::summary() does not describe the Occurrence
54 * right you can call setSummary() and then the supplied
55 * summary will be used.
56 * All Dates and Times are in the local time.
57 *
58 * @version 1.0
59 * @author Holger Hans Peter Freyther zecke@handhelds.org
60 */
61class OPimBackendOccurrence {
62public:
63 typedef QValueList<OPimBackendOccurrence> List;
64
65 //@{
66 OPimBackendOccurrence();
67 OPimBackendOccurrence( const QDate& date,
68 const UID& , const QString& = QString::null );
69 OPimBackendOccurrence( const QDate& date, const QDate& end,
70 const UID& );
71 OPimBackendOccurrence( const QDateTime& start,
72 const QDateTime& end,
73 const UID& uid );
74 //@}
75
76 //@{
77 QDateTime startDateTime()const;
78 QDateTime endDateTime()const;
79 UID uid()const;
80 bool isAllDay()const;
81 QString summary()const;
82 QString location()const;
83 QString note()const;
84 //@}
85
86 //@{
87 void setStartDate( const QDate& );
88 void setStartDateTime( const QDateTime& dt );
89 void setEndDate( const QDate& );
90 void setEndDateTime( const QDateTime& dt );
91 void setUid( const UID& );
92 void setSummary( const QString& );
93 void setLocation( const QString& );
94 void setNote( const QString& );
95 //@}
96
97private:
98 QDateTime m_start, m_end;
99 UID m_uid;
100 bool m_haveTime : 1;
101 QString m_summary, m_note, m_location;
102
103 struct Private;
104 Private *d;
105};
106}
107
108#endif
diff --git a/libopie2/opiepim/backend/otodoaccessbackend.cpp b/libopie2/opiepim/backend/otodoaccessbackend.cpp
index 790a764..5f86be9 100644
--- a/libopie2/opiepim/backend/otodoaccessbackend.cpp
+++ b/libopie2/opiepim/backend/otodoaccessbackend.cpp
@@ -1,41 +1,155 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) The Main Author <main-author@whereever.org> 3 Copyright (C) The Main Author <main-author@whereever.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29 29
30#include <opie2/otodoaccessbackend.h> 30#include <opie2/otodoaccessbackend.h>
31#include <opie2/private/opimtodosortvector.h>
32#include <opie2/otodoaccess.h>
33
34#include <qintdict.h>
31 35
32namespace Opie { 36namespace Opie {
33OPimTodoAccessBackend::OPimTodoAccessBackend() 37OPimTodoAccessBackend::OPimTodoAccessBackend()
34 : OPimAccessBackend<OPimTodo>() 38 : OPimAccessBackend<OPimTodo>()
35{ 39{
36} 40}
37OPimTodoAccessBackend::~OPimTodoAccessBackend() { 41OPimTodoAccessBackend::~OPimTodoAccessBackend() {
38 42
39} 43}
40 44
45UIDArray OPimTodoAccessBackend::queryByExample( const OPimTodo&, int settings,
46 const QDateTime& d)const {
47 return UIDArray();
48}
49
50UIDArray OPimTodoAccessBackend::sorted( const UIDArray& events, bool asc,
51 int sortOrder, int sortFilter,
52 const QArray<int>& categories )const {
53 odebug << "Using Unaccelerated TodoList sorted Implementation" << oendl;
54 Internal::OPimTodoSortVector vector(events.count(), asc,sortOrder );
55 int item = 0;
56
57 bool bCat = sortFilter & OPimTodoAccess::FilterCategory ? true : false;
58 bool bOnly = sortFilter & OPimTodoAccess::OnlyOverDue ? true : false;
59 bool comp = sortFilter & OPimTodoAccess::DoNotShowCompleted ? true : false;
60 bool catPassed = false;
61 int cat;
62
63 for ( uint i = 0; i < events.count(); ++i ) {
64 OPimTodo todo = find( events[i], events, i, Frontend::Forward );
65 if ( todo.isEmpty() )
66 continue;
67
68 /* show category */
69 /* -1 == unfiled */
70 catPassed = false;
71 for ( uint cat_nu = 0; cat_nu < categories.count(); ++cat_nu ) {
72 cat = categories[cat_nu];
73 if ( bCat && cat == -1 ) {
74 if(!todo.categories().isEmpty() )
75 continue;
76 } else if ( bCat && cat != 0)
77 if (!todo.categories().contains( cat ) )
78 continue;
79 catPassed = true;
80 break;
81 }
82
83 /*
84 * If none of the Categories matched
85 * continue
86 */
87 if ( !catPassed )
88 continue;
89 if ( !todo.isOverdue() && bOnly )
90 continue;
91 if (todo.isCompleted() && comp )
92 continue;
93
94 vector.insert(item++, todo );
95 }
96
97 vector.resize( item );
98 /* sort it now */
99 vector.sort();
100 /* now get the uids */
101 UIDArray array( vector.count() );
102 for (uint i= 0; i < vector.count(); i++ )
103 array[i] = vector.uidAt( i );
104
105 return array;
106}
107
108OPimBackendOccurrence::List OPimTodoAccessBackend::occurrences( const QDate& start,
109 const QDate& end )const {
110 OPimBackendOccurrence::List lst;
111 UIDArray effective = effectiveToDos( start, end, false );
112 UIDArray overdue = overDue();
113 uint count = effective.count();
114 int uid;
115 QIntDict<int> hash;
116 hash.setAutoDelete( true );
117 OPimTodo todo;
118
119 for ( uint i = 0; i < count; ++i ) {
120 uid = effective[i];
121 todo = find( uid, effective, i, Frontend::Forward );
122 /*
123 * If isOverdue but in the 'normal' range we will fill
124 * the hash so we won't have duplicates in OPimBackendOccurrence
125 */
126 if ( todo.isOverdue() )
127 hash.insert( uid, new int(6) );
128 OPimBackendOccurrence oc = todo.hasStartDate() ?
129 OPimBackendOccurrence( todo.startDate(),
130 todo.dueDate(), uid ) :
131 OPimBackendOccurrence( todo.dueDate(), uid, QString::null );
132 oc.setSummary( todo.summary() );
133 lst.append( oc );
134 }
135
136 /*
137 * Create the OverDue items but skip
138 * the already handled Records
139 */
140 if ( !overdue.isEmpty() ) {
141 QDate today = QDate::currentDate();
142 QDate dueDate = (start >= today && today <= end ) ? today : start;
143 count = overdue.count();
144 for ( uint i = 0; i < count; ++i ) {
145 uid = overdue[i];
146 if (!hash.find( uid ) )
147 continue;
148 todo = find( uid, overdue, i, Frontend::Forward );
149 lst.append( OPimBackendOccurrence(dueDate, uid, todo.summary() ) );
150 }
151 }
152
153 return lst;
154}
41} 155}
diff --git a/libopie2/opiepim/backend/otodoaccessbackend.h b/libopie2/opiepim/backend/otodoaccessbackend.h
index 9dfda45..66297bb 100644
--- a/libopie2/opiepim/backend/otodoaccessbackend.h
+++ b/libopie2/opiepim/backend/otodoaccessbackend.h
@@ -1,59 +1,79 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) The Main Author <main-author@whereever.org> 3 Copyright (C) The Main Author <main-author@whereever.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_TODO_ACCESS_BACKEND_H 29#ifndef OPIE_TODO_ACCESS_BACKEND_H
30#define OPIE_TODO_ACCESS_BACKEND_H 30#define OPIE_TODO_ACCESS_BACKEND_H
31 31
32#include <qbitarray.h> 32#include <qbitarray.h>
33 33
34#include <opie2/opimtodo.h> 34#include <opie2/opimtodo.h>
35#include <opie2/opimaccessbackend.h> 35#include <opie2/opimaccessbackend.h>
36 36
37namespace Opie { 37namespace Opie {
38class OPimTodoAccessBackend : public OPimAccessBackend<OPimTodo> { 38class OPimTodoAccessBackend : public OPimAccessBackend<OPimTodo> {
39public: 39public:
40 OPimTodoAccessBackend(); 40 OPimTodoAccessBackend();
41 ~OPimTodoAccessBackend(); 41 ~OPimTodoAccessBackend();
42 virtual QArray<int> effectiveToDos( const QDate& start, 42 virtual UIDArray effectiveToDos( const QDate& start,
43 const QDate& end, 43 const QDate& end,
44 bool includeNoDates ) = 0; 44 bool includeNoDates )const = 0;
45 virtual QArray<int> overDue() = 0; 45 virtual UIDArray overDue()const = 0;
46 virtual QArray<int> sorted( bool asc, int sortOrder, int sortFilter, 46 virtual void removeAllCompleted() = 0;
47 int cat ) = 0; 47
48 virtual void removeAllCompleted() = 0; 48 /**
49 virtual QBitArray supports()const = 0; 49 * Common and probably inefficent implementation
50 50 * for queryByExample, matchRegexp, sorted
51 * and occurrences
52 */
53 //@{
54 UIDArray queryByExample( const OPimTodo&, int settings, const QDateTime& d = QDateTime() )const;
55 UIDArray sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const;
56 OPimBackendOccurrence::List occurrences( const QDate&, const QDate& )const;
57 //@}
58
51private: 59private:
52 class Private; 60 class Private;
53 Private *d; 61 Private *d;
54 62
55}; 63};
56
57} 64}
58 65
66
67/**
68 * \fn Opie::OPimBackendOccurrence::List Opie::OPimTodoAccessBackend::occurrences(const QDate& start,const QDate& end)const
69 * \brief Return occurrences for a period of time
70 *
71 * This method will return the 'effective' Todos and also
72 * 'Overdue' Todos. Overdues will be shown on the 'current'
73 * day if it is in the range or on \par start. If the overdue
74 * is inside the 'Effective Todos' we will skip the
75 * special overdue handling.
76 *
77 *
78 */
59#endif 79#endif
diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp
index 4e3e47b..2bcab29 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.cpp
+++ b/libopie2/opiepim/backend/otodoaccesssql.cpp
@@ -74,822 +74,757 @@ namespace {
74 * LoadQuery 74 * LoadQuery
75 * this one queries for all uids 75 * this one queries for all uids
76 */ 76 */
77 class LoadQuery : public OSQLQuery { 77 class LoadQuery : public OSQLQuery {
78 public: 78 public:
79 LoadQuery(); 79 LoadQuery();
80 ~LoadQuery(); 80 ~LoadQuery();
81 QString query()const; 81 QString query()const;
82 }; 82 };
83 83
84 /** 84 /**
85 * inserts/adds a OPimTodo to the table 85 * inserts/adds a OPimTodo to the table
86 */ 86 */
87 class InsertQuery : public OSQLQuery { 87 class InsertQuery : public OSQLQuery {
88 public: 88 public:
89 InsertQuery(const OPimTodo& ); 89 InsertQuery(const OPimTodo& );
90 ~InsertQuery(); 90 ~InsertQuery();
91 QString query()const; 91 QString query()const;
92 private: 92 private:
93 OPimTodo m_todo; 93 OPimTodo m_todo;
94 }; 94 };
95 95
96 /** 96 /**
97 * removes one from the table 97 * removes one from the table
98 */ 98 */
99 class RemoveQuery : public OSQLQuery { 99 class RemoveQuery : public OSQLQuery {
100 public: 100 public:
101 RemoveQuery(int uid ); 101 RemoveQuery(int uid );
102 ~RemoveQuery(); 102 ~RemoveQuery();
103 QString query()const; 103 QString query()const;
104 private: 104 private:
105 int m_uid; 105 int m_uid;
106 }; 106 };
107 107
108 /** 108 /**
109 * Clears (delete) a Table 109 * Clears (delete) a Table
110 */ 110 */
111 class ClearQuery : public OSQLQuery { 111 class ClearQuery : public OSQLQuery {
112 public: 112 public:
113 ClearQuery(); 113 ClearQuery();
114 ~ClearQuery(); 114 ~ClearQuery();
115 QString query()const; 115 QString query()const;
116 116
117 }; 117 };
118 118
119 /** 119 /**
120 * a find query 120 * a find query
121 */ 121 */
122 class FindQuery : public OSQLQuery { 122 class FindQuery : public OSQLQuery {
123 public: 123 public:
124 FindQuery(int uid); 124 FindQuery(int uid);
125 FindQuery(const QArray<int>& ); 125 FindQuery(const QArray<int>& );
126 ~FindQuery(); 126 ~FindQuery();
127 QString query()const; 127 QString query()const;
128 private: 128 private:
129 QString single()const; 129 QString single()const;
130 QString multi()const; 130 QString multi()const;
131 QArray<int> m_uids; 131 QArray<int> m_uids;
132 int m_uid; 132 int m_uid;
133 }; 133 };
134 134
135 /** 135 /**
136 * overdue query 136 * overdue query
137 */ 137 */
138 class OverDueQuery : public OSQLQuery { 138 class OverDueQuery : public OSQLQuery {
139 public: 139 public:
140 OverDueQuery(); 140 OverDueQuery();
141 ~OverDueQuery(); 141 ~OverDueQuery();
142 QString query()const; 142 QString query()const;
143 }; 143 };
144 class EffQuery : public OSQLQuery { 144 class EffQuery : public OSQLQuery {
145 public: 145 public:
146 EffQuery( const QDate&, const QDate&, bool inc ); 146 EffQuery( const QDate&, const QDate&, bool inc );
147 ~EffQuery(); 147 ~EffQuery();
148 QString query()const; 148 QString query()const;
149 private: 149 private:
150 QString with()const; 150 QString with()const;
151 QString out()const; 151 QString out()const;
152 QDate m_start; 152 QDate m_start;
153 QDate m_end; 153 QDate m_end;
154 bool m_inc :1; 154 bool m_inc :1;
155 }; 155 };
156 156
157 157
158 /** 158 /**
159 * a find query for custom elements 159 * a find query for custom elements
160 */ 160 */
161 class FindCustomQuery : public OSQLQuery { 161 class FindCustomQuery : public OSQLQuery {
162 public: 162 public:
163 FindCustomQuery(int uid); 163 FindCustomQuery(int uid);
164 FindCustomQuery(const QArray<int>& ); 164 FindCustomQuery(const QArray<int>& );
165 ~FindCustomQuery(); 165 ~FindCustomQuery();
166 QString query()const; 166 QString query()const;
167 private: 167 private:
168 QString single()const; 168 QString single()const;
169 QString multi()const; 169 QString multi()const;
170 QArray<int> m_uids; 170 QArray<int> m_uids;
171 int m_uid; 171 int m_uid;
172 }; 172 };
173 173
174 174
175 175
176 CreateQuery::CreateQuery() : OSQLQuery() {} 176 CreateQuery::CreateQuery() : OSQLQuery() {}
177 CreateQuery::~CreateQuery() {} 177 CreateQuery::~CreateQuery() {}
178 QString CreateQuery::query()const { 178 QString CreateQuery::query()const {
179 QString qu; 179 QString qu;
180 qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; 180 qu += "create table todolist( uid PRIMARY KEY, categories, completed, ";
181 qu += "description, summary, priority, DueDate, progress , state, "; 181 qu += "description, summary, priority, DueDate, progress , state, ";
182 // This is the recurrance-stuff .. Exceptions are currently not supported (see OPimRecurrence.cpp) ! (eilers) 182 // This is the recurrance-stuff .. Exceptions are currently not supported (see OPimRecurrence.cpp) ! (eilers)
183 qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, "; 183 qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, ";
184 qu += "reminders, alarms, maintainer, startdate, completeddate);"; 184 qu += "reminders, alarms, maintainer, startdate, completeddate);";
185 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; 185 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );";
186 return qu; 186 return qu;
187 } 187 }
188 188
189 LoadQuery::LoadQuery() : OSQLQuery() {} 189 LoadQuery::LoadQuery() : OSQLQuery() {}
190 LoadQuery::~LoadQuery() {} 190 LoadQuery::~LoadQuery() {}
191 QString LoadQuery::query()const { 191 QString LoadQuery::query()const {
192 QString qu; 192 QString qu;
193 // We do not need "distinct" here. The primary key is always unique.. 193 // We do not need "distinct" here. The primary key is always unique..
194 //qu += "select distinct uid from todolist"; 194 //qu += "select distinct uid from todolist";
195 qu += "select uid from todolist"; 195 qu += "select uid from todolist";
196 196
197 return qu; 197 return qu;
198 } 198 }
199 199
200 InsertQuery::InsertQuery( const OPimTodo& todo ) 200 InsertQuery::InsertQuery( const OPimTodo& todo )
201 : OSQLQuery(), m_todo( todo ) { 201 : OSQLQuery(), m_todo( todo ) {
202 } 202 }
203 InsertQuery::~InsertQuery() { 203 InsertQuery::~InsertQuery() {
204 } 204 }
205 /* 205 /*
206 * converts from a OPimTodo to a query 206 * converts from a OPimTodo to a query
207 * we leave out X-Ref + Maintainer 207 * we leave out X-Ref + Maintainer
208 * FIXME: Implement/Finish toMap()/fromMap() into OpimTodo to move the encoding 208 * FIXME: Implement/Finish toMap()/fromMap() into OpimTodo to move the encoding
209 * decoding stuff there.. (eilers) 209 * decoding stuff there.. (eilers)
210 */ 210 */
211 QString InsertQuery::query()const{ 211 QString InsertQuery::query()const{
212 212
213 int year, month, day; 213 int year, month, day;
214 year = month = day = 0; 214 year = month = day = 0;
215 if (m_todo.hasDueDate() ) { 215 if (m_todo.hasDueDate() ) {
216 QDate date = m_todo.dueDate(); 216 QDate date = m_todo.dueDate();
217 year = date.year(); 217 year = date.year();
218 month = date.month(); 218 month = date.month();
219 day = date.day(); 219 day = date.day();
220 } 220 }
221 int sYear = 0, sMonth = 0, sDay = 0; 221 int sYear = 0, sMonth = 0, sDay = 0;
222 if( m_todo.hasStartDate() ){ 222 if( m_todo.hasStartDate() ){
223 QDate sDate = m_todo.startDate(); 223 QDate sDate = m_todo.startDate();
224 sYear = sDate.year(); 224 sYear = sDate.year();
225 sMonth= sDate.month(); 225 sMonth= sDate.month();
226 sDay = sDate.day(); 226 sDay = sDate.day();
227 } 227 }
228 228
229 int eYear = 0, eMonth = 0, eDay = 0; 229 int eYear = 0, eMonth = 0, eDay = 0;
230 if( m_todo.hasCompletedDate() ){ 230 if( m_todo.hasCompletedDate() ){
231 QDate eDate = m_todo.completedDate(); 231 QDate eDate = m_todo.completedDate();
232 eYear = eDate.year(); 232 eYear = eDate.year();
233 eMonth= eDate.month(); 233 eMonth= eDate.month();
234 eDay = eDate.day(); 234 eDay = eDate.day();
235 } 235 }
236 QString qu; 236 QString qu;
237 QMap<int, QString> recMap = m_todo.recurrence().toMap(); 237 QMap<int, QString> recMap = m_todo.recurrence().toMap();
238 qu = "insert into todolist VALUES(" 238 qu = "insert into todolist VALUES("
239 + QString::number( m_todo.uid() ) + "," 239 + QString::number( m_todo.uid() ) + ","
240 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," 240 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + ","
241 + QString::number( m_todo.isCompleted() ) + "," 241 + QString::number( m_todo.isCompleted() ) + ","
242 + "'" + m_todo.description() + "'" + "," 242 + "'" + m_todo.description() + "'" + ","
243 + "'" + m_todo.summary() + "'" + "," 243 + "'" + m_todo.summary() + "'" + ","
244 + QString::number(m_todo.priority() ) + "," 244 + QString::number(m_todo.priority() ) + ","
245 + "'" + QString::number(year).rightJustify( 4, '0' ) + "-" 245 + "'" + QString::number(year).rightJustify( 4, '0' ) + "-"
246 + QString::number(month).rightJustify( 2, '0' ) 246 + QString::number(month).rightJustify( 2, '0' )
247 + "-" + QString::number( day ).rightJustify( 2, '0' )+ "'" + "," 247 + "-" + QString::number( day ).rightJustify( 2, '0' )+ "'" + ","
248 + QString::number( m_todo.progress() ) + "," 248 + QString::number( m_todo.progress() ) + ","
249 + QString::number( m_todo.state().state() ) + "," 249 + QString::number( m_todo.state().state() ) + ","
250 + "'" + recMap[ OPimRecurrence::RType ] + "'" + "," 250 + "'" + recMap[ OPimRecurrence::RType ] + "'" + ","
251 + "'" + recMap[ OPimRecurrence::RWeekdays ] + "'" + "," 251 + "'" + recMap[ OPimRecurrence::RWeekdays ] + "'" + ","
252 + "'" + recMap[ OPimRecurrence::RPosition ] + "'" + "," 252 + "'" + recMap[ OPimRecurrence::RPosition ] + "'" + ","
253 + "'" + recMap[ OPimRecurrence::RFreq ] + "'" + "," 253 + "'" + recMap[ OPimRecurrence::RFreq ] + "'" + ","
254 + "'" + recMap[ OPimRecurrence::RHasEndDate ] + "'" + "," 254 + "'" + recMap[ OPimRecurrence::RHasEndDate ] + "'" + ","
255 + "'" + recMap[ OPimRecurrence::EndDate ] + "'" + "," 255 + "'" + recMap[ OPimRecurrence::EndDate ] + "'" + ","
256 + "'" + recMap[ OPimRecurrence::Created ] + "'" + "," 256 + "'" + recMap[ OPimRecurrence::Created ] + "'" + ","
257 + "'" + recMap[ OPimRecurrence::Exceptions ] + "'" + ","; 257 + "'" + recMap[ OPimRecurrence::Exceptions ] + "'" + ",";
258 258
259 if ( m_todo.hasNotifiers() ) { 259 if ( m_todo.hasNotifiers() ) {
260 OPimNotifyManager manager = m_todo.notifiers(); 260 OPimNotifyManager manager = m_todo.notifiers();
261 qu += "'" + manager.remindersToString() + "'" + "," 261 qu += "'" + manager.remindersToString() + "'" + ","
262 + "'" + manager.alarmsToString() + "'" + ","; 262 + "'" + manager.alarmsToString() + "'" + ",";
263 } 263 }
264 else{ 264 else{
265 qu += QString( "''" ) + "," 265 qu += QString( "''" ) + ","
266 + "''" + ","; 266 + "''" + ",";
267 } 267 }
268 268
269 qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) 269 qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !)
270 + "'" + QString::number(sYear).rightJustify( 4, '0' ) + "-" 270 + "'" + QString::number(sYear).rightJustify( 4, '0' ) + "-"
271 + QString::number(sMonth).rightJustify( 2, '0' ) 271 + QString::number(sMonth).rightJustify( 2, '0' )
272 + "-" + QString::number(sDay).rightJustify( 2, '0' )+ "'" + "," 272 + "-" + QString::number(sDay).rightJustify( 2, '0' )+ "'" + ","
273 + "'" + QString::number(eYear).rightJustify( 4, '0' ) + "-" 273 + "'" + QString::number(eYear).rightJustify( 4, '0' ) + "-"
274 + QString::number(eMonth).rightJustify( 2, '0' ) 274 + QString::number(eMonth).rightJustify( 2, '0' )
275 + "-"+QString::number(eDay).rightJustify( 2, '0' ) + "'" 275 + "-"+QString::number(eDay).rightJustify( 2, '0' ) + "'"
276 + "); "; 276 + "); ";
277 277
278 // Save custom Entries: 278 // Save custom Entries:
279 int id = 0; 279 int id = 0;
280 id = 0; 280 id = 0;
281 QMap<QString, QString> customMap = m_todo.toExtraMap(); 281 QMap<QString, QString> customMap = m_todo.toExtraMap();
282 for( QMap<QString, QString>::Iterator it = customMap.begin(); 282 for( QMap<QString, QString>::Iterator it = customMap.begin();
283 it != customMap.end(); ++it ){ 283 it != customMap.end(); ++it ){
284 qu += "insert into custom_data VALUES(" 284 qu += "insert into custom_data VALUES("
285 + QString::number( m_todo.uid() ) 285 + QString::number( m_todo.uid() )
286 + "," 286 + ","
287 + QString::number( id++ ) 287 + QString::number( id++ )
288 + ",'" 288 + ",'"
289 + it.key() 289 + it.key()
290 + "'," 290 + "',"
291 + "0" // Priority for future enhancements 291 + "0" // Priority for future enhancements
292 + ",'" 292 + ",'"
293 + it.data() 293 + it.data()
294 + "');"; 294 + "');";
295 } 295 }
296 296
297 297
298 odebug << "add " << qu << "" << oendl; 298 odebug << "add " << qu << "" << oendl;
299 return qu; 299 return qu;
300 } 300 }
301 301
302 RemoveQuery::RemoveQuery(int uid ) 302 RemoveQuery::RemoveQuery(int uid )
303 : OSQLQuery(), m_uid( uid ) {} 303 : OSQLQuery(), m_uid( uid ) {}
304 RemoveQuery::~RemoveQuery() {} 304 RemoveQuery::~RemoveQuery() {}
305 QString RemoveQuery::query()const { 305 QString RemoveQuery::query()const {
306 QString qu = "DELETE FROM todolist WHERE uid = " + QString::number(m_uid) + " ;"; 306 QString qu = "DELETE FROM todolist WHERE uid = " + QString::number(m_uid) + " ;";
307 qu += "DELETE FROM custom_data WHERE uid = " + QString::number(m_uid); 307 qu += "DELETE FROM custom_data WHERE uid = " + QString::number(m_uid);
308 return qu; 308 return qu;
309 } 309 }
310 310
311 311
312 ClearQuery::ClearQuery() 312 ClearQuery::ClearQuery()
313 : OSQLQuery() {} 313 : OSQLQuery() {}
314 ClearQuery::~ClearQuery() {} 314 ClearQuery::~ClearQuery() {}
315 QString ClearQuery::query()const { 315 QString ClearQuery::query()const {
316 QString qu = "drop table todolist"; 316 QString qu = "drop table todolist";
317 return qu; 317 return qu;
318 } 318 }
319 FindQuery::FindQuery(int uid) 319 FindQuery::FindQuery(int uid)
320 : OSQLQuery(), m_uid(uid ) { 320 : OSQLQuery(), m_uid(uid ) {
321 } 321 }
322 FindQuery::FindQuery(const QArray<int>& ints) 322 FindQuery::FindQuery(const QArray<int>& ints)
323 : OSQLQuery(), m_uids(ints){ 323 : OSQLQuery(), m_uids(ints){
324 } 324 }
325 FindQuery::~FindQuery() { 325 FindQuery::~FindQuery() {
326 } 326 }
327 QString FindQuery::query()const{ 327 QString FindQuery::query()const{
328 if (m_uids.count() == 0 ) 328 if (m_uids.count() == 0 )
329 return single(); 329 return single();
330 else 330 else
331 return multi(); 331 return multi();
332 } 332 }
333 QString FindQuery::single()const{ 333 QString FindQuery::single()const{
334 QString qu = "select * from todolist where uid = " + QString::number(m_uid); 334 QString qu = "select * from todolist where uid = " + QString::number(m_uid);
335 return qu; 335 return qu;
336 } 336 }
337 QString FindQuery::multi()const { 337 QString FindQuery::multi()const {
338 QString qu = "select * from todolist where "; 338 QString qu = "select * from todolist where ";
339 for (uint i = 0; i < m_uids.count(); i++ ) { 339 for (uint i = 0; i < m_uids.count(); i++ ) {
340 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 340 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
341 } 341 }
342 qu.remove( qu.length()-2, 2 ); 342 qu.remove( qu.length()-2, 2 );
343 return qu; 343 return qu;
344 } 344 }
345 345
346 OverDueQuery::OverDueQuery(): OSQLQuery() {} 346 OverDueQuery::OverDueQuery(): OSQLQuery() {}
347 OverDueQuery::~OverDueQuery() {} 347 OverDueQuery::~OverDueQuery() {}
348 QString OverDueQuery::query()const { 348 QString OverDueQuery::query()const {
349 QDate date = QDate::currentDate(); 349 QDate date = QDate::currentDate();
350 QString str; 350 QString str;
351 str = QString("select uid from todolist where DueDate ='%1-%2-%3'") 351 str = QString("select uid from todolist where DueDate ='%1-%2-%3'")
352 .arg( QString::number( date.year() ).rightJustify( 4, '0' ) ) 352 .arg( QString::number( date.year() ).rightJustify( 4, '0' ) )
353 .arg( QString::number( date.month() ).rightJustify( 2, '0' ) ) 353 .arg( QString::number( date.month() ).rightJustify( 2, '0' ) )
354 .arg( QString::number( date.day() ) .rightJustify( 2, '0' ) ); 354 .arg( QString::number( date.day() ) .rightJustify( 2, '0' ) );
355 355
356 return str; 356 return str;
357 } 357 }
358 358
359 359
360 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) 360 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc )
361 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} 361 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {}
362 EffQuery::~EffQuery() {} 362 EffQuery::~EffQuery() {}
363 QString EffQuery::query()const { 363 QString EffQuery::query()const {
364 return m_inc ? with() : out(); 364 return m_inc ? with() : out();
365 } 365 }
366 QString EffQuery::with()const { 366 QString EffQuery::with()const {
367 QString str; 367 QString str;
368 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") 368 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ")
369 .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) ) 369 .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) )
370 .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) ) 370 .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) )
371 .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) ) 371 .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) )
372 .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) ) 372 .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) )
373 .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) ) 373 .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) )
374 .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) ); 374 .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) );
375 return str; 375 return str;
376 } 376 }
377 QString EffQuery::out()const { 377 QString EffQuery::out()const {
378 QString str; 378 QString str;
379 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") 379 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'")
380 .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) ) 380 .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) )
381 .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) ) 381 .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) )
382 .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) ) 382 .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) )
383 .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) ) 383 .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) )
384 .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) ) 384 .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) )
385 .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) ); 385 .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) );
386 386
387 return str; 387 return str;
388 } 388 }
389 389
390 FindCustomQuery::FindCustomQuery(int uid) 390 FindCustomQuery::FindCustomQuery(int uid)
391 : OSQLQuery(), m_uid( uid ) { 391 : OSQLQuery(), m_uid( uid ) {
392 } 392 }
393 FindCustomQuery::FindCustomQuery(const QArray<int>& ints) 393 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
394 : OSQLQuery(), m_uids( ints ){ 394 : OSQLQuery(), m_uids( ints ){
395 } 395 }
396 FindCustomQuery::~FindCustomQuery() { 396 FindCustomQuery::~FindCustomQuery() {
397 } 397 }
398 QString FindCustomQuery::query()const{ 398 QString FindCustomQuery::query()const{
399 return single(); // Multiple requests not supported ! 399 return single(); // Multiple requests not supported !
400 } 400 }
401 QString FindCustomQuery::single()const{ 401 QString FindCustomQuery::single()const{
402 QString qu = "select uid, type, value from custom_data where uid = "; 402 QString qu = "select uid, type, value from custom_data where uid = ";
403 qu += QString::number(m_uid); 403 qu += QString::number(m_uid);
404 return qu; 404 return qu;
405 } 405 }
406 406
407}; 407};
408 408
409 409
410namespace Opie { 410namespace Opie {
411OPimTodoAccessBackendSQL::OPimTodoAccessBackendSQL( const QString& file ) 411OPimTodoAccessBackendSQL::OPimTodoAccessBackendSQL( const QString& file )
412 : OPimTodoAccessBackend(),/* m_dict(15),*/ m_driver(NULL), m_dirty(true) 412 : OPimTodoAccessBackend(),/* m_dict(15),*/ m_driver(NULL), m_dirty(true)
413{ 413{
414 QString fi = file; 414 QString fi = file;
415 if ( fi.isEmpty() ) 415 if ( fi.isEmpty() )
416 fi = Global::applicationFileName( "todolist", "todolist.db" ); 416 fi = Global::applicationFileName( "todolist", "todolist.db" );
417 OSQLManager man; 417 OSQLManager man;
418 m_driver = man.standard(); 418 m_driver = man.standard();
419 m_driver->setUrl(fi); 419 m_driver->setUrl(fi);
420 // fillDict(); 420 // fillDict();
421} 421}
422 422
423OPimTodoAccessBackendSQL::~OPimTodoAccessBackendSQL(){ 423OPimTodoAccessBackendSQL::~OPimTodoAccessBackendSQL(){
424 if( m_driver ) 424 if( m_driver )
425 delete m_driver; 425 delete m_driver;
426} 426}
427 427
428bool OPimTodoAccessBackendSQL::load(){ 428bool OPimTodoAccessBackendSQL::load(){
429 if (!m_driver->open() ) 429 if (!m_driver->open() )
430 return false; 430 return false;
431 431
432 CreateQuery creat; 432 CreateQuery creat;
433 OSQLResult res = m_driver->query(&creat ); 433 OSQLResult res = m_driver->query(&creat );
434 434
435 m_dirty = true; 435 m_dirty = true;
436 return true; 436 return true;
437} 437}
438bool OPimTodoAccessBackendSQL::reload(){ 438bool OPimTodoAccessBackendSQL::reload(){
439 return load(); 439 return load();
440} 440}
441 441
442bool OPimTodoAccessBackendSQL::save(){ 442bool OPimTodoAccessBackendSQL::save(){
443 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) 443 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
444} 444}
445QArray<int> OPimTodoAccessBackendSQL::allRecords()const { 445QArray<int> OPimTodoAccessBackendSQL::allRecords()const {
446 if (m_dirty ) 446 if (m_dirty )
447 update(); 447 update();
448 448
449 return m_uids; 449 return m_uids;
450} 450}
451QArray<int> OPimTodoAccessBackendSQL::queryByExample( const OPimTodo& , int, const QDateTime& ){ 451QArray<int> OPimTodoAccessBackendSQL::queryByExample( const OPimTodo& , int, const QDateTime& ){
452 QArray<int> ints(0); 452 QArray<int> ints(0);
453 return ints; 453 return ints;
454} 454}
455OPimTodo OPimTodoAccessBackendSQL::find(int uid ) const{ 455OPimTodo OPimTodoAccessBackendSQL::find(int uid ) const{
456 FindQuery query( uid ); 456 FindQuery query( uid );
457 return parseResultAndCache( uid, m_driver->query(&query) ); 457 return parseResultAndCache( uid, m_driver->query(&query) );
458
459} 458}
460 459
461// Remember: uid is already in the list of uids, called ints ! 460// Remember: uid is already in the list of uids, called ints !
462OPimTodo OPimTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, 461OPimTodo OPimTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
463 uint cur, Frontend::CacheDirection dir ) const{ 462 uint cur, Frontend::CacheDirection dir ) const{
464 uint CACHE = readAhead(); 463 uint CACHE = readAhead();
465 odebug << "searching for " << uid << "" << oendl; 464 odebug << "searching for " << uid << "" << oendl;
466 QArray<int> search( CACHE ); 465 QArray<int> search( CACHE );
467 uint size =0; 466 uint size =0;
468 OPimTodo to;
469 467
470 // we try to cache CACHE items 468 // we try to cache CACHE items
471 switch( dir ) { 469 switch( dir ) {
472 /* forward */ 470 /* forward */
473 case Frontend::Forward: 471 case Frontend::Forward:
474 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { 472 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
475 odebug << "size " << size << " " << ints[i] << "" << oendl;
476 search[size] = ints[i]; 473 search[size] = ints[i];
477 size++; 474 size++;
478 } 475 }
479 break; 476 break;
480 /* reverse */ 477 /* reverse */
481 case Frontend::Reverse: 478 case Frontend::Reverse:
482 for (uint i = cur; i != 0 && size < CACHE; i-- ) { 479 for (uint i = cur; i != 0 && size < CACHE; i-- ) {
483 search[size] = ints[i]; 480 search[size] = ints[i];
484 size++; 481 size++;
485 } 482 }
486 break; 483 break;
487 } 484 }
488 485
489 search.resize( size ); 486 search.resize( size );
490 FindQuery query( search ); 487 FindQuery query( search );
491 OSQLResult res = m_driver->query( &query ); 488 OSQLResult res = m_driver->query( &query );
492 if ( res.state() != OSQLResult::Success ) 489 if ( res.state() != OSQLResult::Success )
493 return to; 490 return OPimTodo();
494 491
495 return parseResultAndCache( uid, res ); 492 return parseResultAndCache( uid, res );
496} 493}
497 494
498void OPimTodoAccessBackendSQL::clear() { 495void OPimTodoAccessBackendSQL::clear() {
499 ClearQuery cle; 496 ClearQuery cle;
500 OSQLResult res = m_driver->query( &cle ); 497 OSQLResult res = m_driver->query( &cle );
501 CreateQuery qu; 498 CreateQuery qu;
502 res = m_driver->query(&qu); 499 res = m_driver->query(&qu);
503} 500}
504bool OPimTodoAccessBackendSQL::add( const OPimTodo& t) { 501bool OPimTodoAccessBackendSQL::add( const OPimTodo& t) {
505 InsertQuery ins( t ); 502 InsertQuery ins( t );
506 OSQLResult res = m_driver->query( &ins ); 503 OSQLResult res = m_driver->query( &ins );
507 504
508 if ( res.state() == OSQLResult::Failure ) 505 if ( res.state() == OSQLResult::Failure )
509 return false; 506 return false;
507
510 int c = m_uids.count(); 508 int c = m_uids.count();
511 m_uids.resize( c+1 ); 509 m_uids.resize( c+1 );
512 m_uids[c] = t.uid(); 510 m_uids[c] = t.uid();
513 511
514 return true; 512 return true;
515} 513}
516bool OPimTodoAccessBackendSQL::remove( int uid ) { 514bool OPimTodoAccessBackendSQL::remove( int uid ) {
517 RemoveQuery rem( uid ); 515 RemoveQuery rem( uid );
518 OSQLResult res = m_driver->query(&rem ); 516 OSQLResult res = m_driver->query(&rem );
519 517
520 if ( res.state() == OSQLResult::Failure ) 518 if ( res.state() == OSQLResult::Failure )
521 return false; 519 return false;
522 520
523 m_dirty = true; 521 m_dirty = true;
524 return true; 522 return true;
525} 523}
526/* 524/*
527 * FIXME better set query 525 * FIXME better set query
528 * but we need the cache for that 526 * but we need the cache for that
529 * now we remove 527 * now we remove
530 */ 528 */
531bool OPimTodoAccessBackendSQL::replace( const OPimTodo& t) { 529bool OPimTodoAccessBackendSQL::replace( const OPimTodo& t) {
532 remove( t.uid() ); 530 remove( t.uid() );
533 bool b= add(t); 531 bool b= add(t);
534 m_dirty = false; // we changed some stuff but the UID stayed the same 532 m_dirty = false; // we changed some stuff but the UID stayed the same
535 return b; 533 return b;
536} 534}
537QArray<int> OPimTodoAccessBackendSQL::overDue() { 535QArray<int> OPimTodoAccessBackendSQL::overDue()const {
538 OverDueQuery qu; 536 OverDueQuery qu;
539 return uids( m_driver->query(&qu ) ); 537 return uids( m_driver->query(&qu ) );
540} 538}
541QArray<int> OPimTodoAccessBackendSQL::effectiveToDos( const QDate& s, 539QArray<int> OPimTodoAccessBackendSQL::effectiveToDos( const QDate& s,
542 const QDate& t, 540 const QDate& t,
543 bool u) { 541 bool u)const {
544 EffQuery ef(s, t, u ); 542 EffQuery ef(s, t, u );
545 return uids (m_driver->query(&ef) ); 543 return uids (m_driver->query(&ef) );
546} 544}
545
546#if 0
547/* 547/*
548 * 548 *
549 */ 549 */
550QArray<int> OPimTodoAccessBackendSQL::sorted( bool asc, int sortOrder, 550QArray<int> OPimTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
551 int sortFilter, int cat ) { 551 int sortFilter, int cat ) {
552 odebug << "sorted " << asc << ", " << sortOrder << "" << oendl; 552 odebug << "sorted " << asc << ", " << sortOrder << "" << oendl;
553 QString query; 553 QString query;
554 query = "select uid from todolist WHERE "; 554 query = "select uid from todolist WHERE ";
555 555
556 /* 556 /*
557 * Sort Filter stuff 557 * Sort Filter stuff
558 * not that straight forward 558 * not that straight forward
559 * FIXME: Replace magic numbers 559 * FIXME: Replace magic numbers
560 * 560 *
561 */ 561 */
562 /* Category */ 562 /* Category */
563 if ( sortFilter & 1 ) { 563 if ( sortFilter & OPimTodoAccess::FilterCategory ) {
564 QString str; 564 QString str;
565 if (cat != 0 ) str = QString::number( cat ); 565 if (cat != 0 ) str = QString::number( cat );
566 query += " categories like '%" +str+"%' AND"; 566 query += " categories like '%" +str+"%' AND";
567 } 567 }
568 /* Show only overdue */ 568 /* Show only overdue */
569 if ( sortFilter & 2 ) { 569 if ( sortFilter & OPimTodoAccess::OnlyOverDue ) {
570 QDate date = QDate::currentDate(); 570 QDate date = QDate::currentDate();
571 QString due; 571 QString due;
572 QString base; 572 QString base;
573 base = QString("DueDate <= '%1-%2-%3' AND completed = 0") 573 base = QString("DueDate <= '%1-%2-%3' AND completed = 0")
574 .arg( QString::number( date.year() ).rightJustify( 4, '0' ) ) 574 .arg( QString::number( date.year() ).rightJustify( 4, '0' ) )
575 .arg( QString::number( date.month() ).rightJustify( 2, '0' ) ) 575 .arg( QString::number( date.month() ).rightJustify( 2, '0' ) )
576 .arg( QString::number( date.day() ).rightJustify( 2, '0' ) ); 576 .arg( QString::number( date.day() ).rightJustify( 2, '0' ) );
577 query += " " + base + " AND"; 577 query += " " + base + " AND";
578 } 578 }
579 /* not show completed */ 579 /* not show completed */
580 if ( sortFilter & 4 ) { 580 if ( sortFilter & OPimTodoAccess::DoNotShowCompleted ) {
581 query += " completed = 0 AND"; 581 query += " completed = 0 AND";
582 }else{ 582 }else{
583 query += " ( completed = 1 OR completed = 0) AND"; 583 query += " ( completed = 1 OR completed = 0) AND";
584 } 584 }
585 /* strip the end */ 585 /* strip the end */
586 query = query.remove( query.length()-3, 3 ); 586 query = query.remove( query.length()-3, 3 );
587 587
588 588
589 /* 589 /*
590 * sort order stuff 590 * sort order stuff
591 * quite straight forward 591 * quite straight forward
592 */ 592 */
593 query += "ORDER BY "; 593 query += "ORDER BY ";
594 switch( sortOrder ) { 594 switch( sortOrder ) {
595 /* completed */ 595 /* completed */
596 case 0: 596 case OPimTodoAccess::Completed:
597 query += "completed"; 597 query += "completed";
598 break; 598 break;
599 case 1: 599 case OPimTodoAccess::Priority:
600 query += "priority"; 600 query += "priority";
601 break; 601 break;
602 case 2: 602 case OPimTodoAccess::SortSummary:
603 query += "summary"; 603 query += "summary";
604 break; 604 break;
605 case 3: 605 case OPimTodoAccess::Deadline:
606 query += "DueDate"; 606 query += "DueDate";
607 break; 607 break;
608 } 608 }
609 609
610 if ( !asc ) { 610 if ( !asc )
611 odebug << "not ascending!" << oendl;
612 query += " DESC"; 611 query += " DESC";
613 } 612
614 613
615 odebug << query << oendl; 614 odebug << query << oendl;
616 OSQLRawQuery raw(query ); 615 OSQLRawQuery raw(query );
617 return uids( m_driver->query(&raw) ); 616 return uids( m_driver->query(&raw) );
618} 617}
618#endif
619
620
619bool OPimTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ 621bool OPimTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{
620 if ( str == "0-0-0" ) 622 if ( str == "0-0-0" )
621 return false; 623 return false;
622 else{ 624 else{
623 int day, year, month; 625 int day, year, month;
624 QStringList list = QStringList::split("-", str ); 626 QStringList list = QStringList::split("-", str );
625 year = list[0].toInt(); 627 year = list[0].toInt();
626 month = list[1].toInt(); 628 month = list[1].toInt();
627 day = list[2].toInt(); 629 day = list[2].toInt();
628 da.setYMD( year, month, day ); 630 da.setYMD( year, month, day );
629 return true; 631 return true;
630 } 632 }
631} 633}
634
635
632OPimTodo OPimTodoAccessBackendSQL::parseResultAndCache( int uid, const OSQLResult& res ) const{ 636OPimTodo OPimTodoAccessBackendSQL::parseResultAndCache( int uid, const OSQLResult& res ) const{
633 if ( res.state() == OSQLResult::Failure ) { 637 if ( res.state() == OSQLResult::Failure ) {
634 OPimTodo to; 638 OPimTodo to;
635 return to; 639 return to;
636 } 640 }
637 641
638 OPimTodo retTodo; 642 OPimTodo retTodo;
639 643
640 OSQLResultItem::ValueList list = res.results(); 644 OSQLResultItem::ValueList list = res.results();
641 OSQLResultItem::ValueList::Iterator it = list.begin(); 645 OSQLResultItem::ValueList::Iterator it = list.begin();
642 odebug << "todo1" << oendl; 646 OPimTodo to, tmp;
643 OPimTodo to = todo( (*it) );
644 cache( to );
645 ++it;
646 647
647 for ( ; it != list.end(); ++it ) { 648 for ( ; it != list.end(); ++it ) {
648 odebug << "caching" << oendl; 649 OPimTodo newTodo = parse( (*it) );
649 OPimTodo newTodo = todo( (*it) );
650 cache( newTodo ); 650 cache( newTodo );
651 if ( newTodo.uid() == uid ) 651 if ( newTodo.uid() == uid )
652 retTodo = newTodo; 652 retTodo = newTodo;
653 } 653 }
654 return retTodo; 654 return retTodo;
655} 655}
656OPimTodo OPimTodoAccessBackendSQL::todo( OSQLResultItem& item )const { 656OPimTodo OPimTodoAccessBackendSQL::parse( OSQLResultItem& item )const {
657 odebug << "todo(ResultItem)" << oendl;
658 657
659 // Request information from addressbook table and create the OPimTodo-object. 658 // Request information from addressbook table and create the OPimTodo-object.
660 659
661 bool hasDueDate = false; QDate dueDate = QDate::currentDate(); 660 bool hasDueDate = false; QDate dueDate = QDate::currentDate();
662 hasDueDate = date( dueDate, item.data("DueDate") ); 661 hasDueDate = date( dueDate, item.data("DueDate") );
663 QStringList cats = QStringList::split(";", item.data("categories") ); 662 QStringList cats = QStringList::split(";", item.data("categories") );
664 663
665 odebug << "Item is completed: " << item.data("completed").toInt() << "" << oendl;
666
667 OPimTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), 664 OPimTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(),
668 cats, item.data("summary"), item.data("description"), 665 cats, item.data("summary"), item.data("description"),
669 item.data("progress").toUShort(), hasDueDate, dueDate, 666 item.data("progress").toUShort(), hasDueDate, dueDate,
670 item.data("uid").toInt() ); 667 item.data("uid").toInt() );
671 668
672 bool isOk; 669 bool isOk;
673 int prioInt = QString( item.data("priority") ).toInt( &isOk ); 670 int prioInt = QString( item.data("priority") ).toInt( &isOk );
674 if ( isOk ) 671 if ( isOk )
675 to.setPriority( prioInt ); 672 to.setPriority( prioInt );
676 673
677 bool hasStartDate = false; QDate startDate = QDate::currentDate(); 674 bool hasStartDate = false; QDate startDate = QDate::currentDate();
678 hasStartDate = date( startDate, item.data("startdate") ); 675 hasStartDate = date( startDate, item.data("startdate") );
679 bool hasCompletedDate = false; QDate completedDate = QDate::currentDate(); 676 bool hasCompletedDate = false; QDate completedDate = QDate::currentDate();
680 hasCompletedDate = date( completedDate, item.data("completeddate") ); 677 hasCompletedDate = date( completedDate, item.data("completeddate") );
681 678
682 if ( hasStartDate ) 679 if ( hasStartDate )
683 to.setStartDate( startDate ); 680 to.setStartDate( startDate );
684 if ( hasCompletedDate ) 681 if ( hasCompletedDate )
685 to.setCompletedDate( completedDate ); 682 to.setCompletedDate( completedDate );
686 683
687 OPimNotifyManager& manager = to.notifiers(); 684 OPimNotifyManager& manager = to.notifiers();
688 manager.alarmsFromString( item.data("alarms") ); 685 manager.alarmsFromString( item.data("alarms") );
689 manager.remindersFromString( item.data("reminders") ); 686 manager.remindersFromString( item.data("reminders") );
690 687
691 OPimState pimState; 688 OPimState pimState;
692 pimState.setState( QString( item.data("state") ).toInt() ); 689 pimState.setState( QString( item.data("state") ).toInt() );
693 to.setState( pimState ); 690 to.setState( pimState );
694 691
695 QMap<int, QString> recMap; 692 QMap<int, QString> recMap;
696 recMap.insert( OPimRecurrence::RType , item.data("RType") ); 693 recMap.insert( OPimRecurrence::RType , item.data("RType") );
697 recMap.insert( OPimRecurrence::RWeekdays , item.data("RWeekdays") ); 694 recMap.insert( OPimRecurrence::RWeekdays , item.data("RWeekdays") );
698 recMap.insert( OPimRecurrence::RPosition , item.data("RPosition") ); 695 recMap.insert( OPimRecurrence::RPosition , item.data("RPosition") );
699 recMap.insert( OPimRecurrence::RFreq , item.data("RFreq") ); 696 recMap.insert( OPimRecurrence::RFreq , item.data("RFreq") );
700 recMap.insert( OPimRecurrence::RHasEndDate, item.data("RHasEndDate") ); 697 recMap.insert( OPimRecurrence::RHasEndDate, item.data("RHasEndDate") );
701 recMap.insert( OPimRecurrence::EndDate , item.data("EndDate") ); 698 recMap.insert( OPimRecurrence::EndDate , item.data("EndDate") );
702 recMap.insert( OPimRecurrence::Created , item.data("Created") ); 699 recMap.insert( OPimRecurrence::Created , item.data("Created") );
703 recMap.insert( OPimRecurrence::Exceptions , item.data("Exceptions") ); 700 recMap.insert( OPimRecurrence::Exceptions , item.data("Exceptions") );
704 701
705 OPimRecurrence recur; 702 OPimRecurrence recur;
706 recur.fromMap( recMap ); 703 recur.fromMap( recMap );
707 to.setRecurrence( recur ); 704 to.setRecurrence( recur );
708 705
709 // Finally load the custom-entries for this UID and put it into the created object 706 // Finally load the custom-entries for this UID and put it into the created object
710 to.setExtraMap( requestCustom( to.uid() ) ); 707 to.setExtraMap( requestCustom( to.uid() ) );
711 708
712 return to; 709 return to;
713} 710}
714 711
715// FIXME: Where is the difference to "find" ? (eilers) 712// FIXME: Where is the difference to "find" ? (eilers)
716OPimTodo OPimTodoAccessBackendSQL::todo( int uid )const { 713OPimTodo OPimTodoAccessBackendSQL::todo( int uid )const {
717 FindQuery find( uid ); 714 FindQuery find( uid );
718 return parseResultAndCache( uid, m_driver->query(&find) ); 715 return parseResultAndCache( uid, m_driver->query(&find) );
719} 716}
720/*
721 * update the dict
722 */
723void OPimTodoAccessBackendSQL::fillDict() {
724 717
725#if 0
726 /* initialize dict */
727 /*
728 * UPDATE dict if you change anything!!!
729 * FIXME: Isn't this dict obsolete ? (eilers)
730 */
731 m_dict.setAutoDelete( TRUE );
732 m_dict.insert("Categories" , new int(OPimTodo::Category) );
733 m_dict.insert("Uid" , new int(OPimTodo::Uid) );
734 m_dict.insert("HasDate" , new int(OPimTodo::HasDate) );
735 m_dict.insert("Completed" , new int(OPimTodo::Completed) );
736 m_dict.insert("Description" , new int(OPimTodo::Description) );
737 m_dict.insert("Summary" , new int(OPimTodo::Summary) );
738 m_dict.insert("Priority" , new int(OPimTodo::Priority) );
739 m_dict.insert("DateDay" , new int(OPimTodo::DateDay) );
740 m_dict.insert("DateMonth" , new int(OPimTodo::DateMonth) );
741 m_dict.insert("DateYear" , new int(OPimTodo::DateYear) );
742 m_dict.insert("Progress" , new int(OPimTodo::Progress) );
743 m_dict.insert("Completed", new int(OPimTodo::Completed) ); // Why twice ? (eilers)
744 m_dict.insert("CrossReference", new int(OPimTodo::CrossReference) );
745// m_dict.insert("HasAlarmDateTime",new int(OPimTodo::HasAlarmDateTime) ); // old stuff (eilers)
746// m_dict.insert("AlarmDateTime", new int(OPimTodo::AlarmDateTime) ); // old stuff (eilers)
747 718
748#endif
749}
750/* 719/*
751 * need to be const so let's fool the 720 * need to be const so let's fool the
752 * compiler :( 721 * compiler :(
753 */ 722 */
754void OPimTodoAccessBackendSQL::update()const { 723void OPimTodoAccessBackendSQL::update()const {
755 ((OPimTodoAccessBackendSQL*)this)->m_dirty = false; 724 ((OPimTodoAccessBackendSQL*)this)->m_dirty = false;
756 LoadQuery lo; 725 LoadQuery lo;
757 OSQLResult res = m_driver->query(&lo); 726 OSQLResult res = m_driver->query(&lo);
758 if ( res.state() != OSQLResult::Success ) 727 if ( res.state() != OSQLResult::Success )
759 return; 728 return;
760 729
761 ((OPimTodoAccessBackendSQL*)this)->m_uids = uids( res ); 730 ((OPimTodoAccessBackendSQL*)this)->m_uids = uids( res );
762} 731}
763QArray<int> OPimTodoAccessBackendSQL::uids( const OSQLResult& res) const{ 732QArray<int> OPimTodoAccessBackendSQL::uids( const OSQLResult& res) const{
764 733
765 OSQLResultItem::ValueList list = res.results(); 734 OSQLResultItem::ValueList list = res.results();
766 OSQLResultItem::ValueList::Iterator it; 735 OSQLResultItem::ValueList::Iterator it;
767 QArray<int> ints(list.count() ); 736 QArray<int> ints(list.count() );
768 odebug << " count = " << list.count() << "" << oendl;
769 737
770 int i = 0; 738 int i = 0;
771 for (it = list.begin(); it != list.end(); ++it ) { 739 for (it = list.begin(); it != list.end(); ++it ) {
772 ints[i] = (*it).data("uid").toInt(); 740 ints[i] = (*it).data("uid").toInt();
773 i++; 741 i++;
774 } 742 }
775 return ints; 743 return ints;
776} 744}
777 745
778QArray<int> OPimTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const 746QArray<int> OPimTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
779{ 747{
780
781#if 0
782 QArray<int> empty;
783 return empty;
784
785#else
786 QString qu = "SELECT uid FROM todolist WHERE ("; 748 QString qu = "SELECT uid FROM todolist WHERE (";
787 749
788 // Do it make sense to search other fields, too ? 750 // Does it make sense to search other fields, too ?
789 qu += " rlike(\""+ r.pattern() + "\",\"description\") OR"; 751 qu += " rlike(\""+ r.pattern() + "\",\"description\") OR";
790 qu += " rlike(\""+ r.pattern() + "\",\"summary\")"; 752 qu += " rlike(\""+ r.pattern() + "\",\"summary\")";
791 753
792 qu += ")"; 754 qu += ")";
793 755
794 odebug << "query: " << qu << "" << oendl;
795
796 OSQLRawQuery raw( qu ); 756 OSQLRawQuery raw( qu );
797 OSQLResult res = m_driver->query( &raw ); 757 OSQLResult res = m_driver->query( &raw );
798 758
799 return uids( res ); 759 return uids( res );
800
801
802#endif
803
804}
805QBitArray OPimTodoAccessBackendSQL::supports()const {
806
807 return sup();
808}
809
810QBitArray OPimTodoAccessBackendSQL::sup() const{
811
812 QBitArray ar( OPimTodo::CompletedDate + 1 );
813 ar.fill( true );
814 ar[OPimTodo::CrossReference] = false;
815 ar[OPimTodo::State ] = false;
816 ar[OPimTodo::Reminders] = false;
817 ar[OPimTodo::Notifiers] = false;
818 ar[OPimTodo::Maintainer] = false;
819
820 return ar;
821} 760}
822 761
823void OPimTodoAccessBackendSQL::removeAllCompleted(){ 762void OPimTodoAccessBackendSQL::removeAllCompleted(){
824 // First we need the uids from all entries which are 763 // First we need the uids from all entries which are
825 // completed. Then, we just have to remove them... 764 // completed. Then, we just have to remove them...
826 765
827 QString qu = "SELECT uid FROM todolist WHERE completed = 1"; 766 QString qu = "SELECT uid FROM todolist WHERE completed = 1";
828 767
829 OSQLRawQuery raw( qu ); 768 OSQLRawQuery raw( qu );
830 OSQLResult res = m_driver->query( &raw ); 769 OSQLResult res = m_driver->query( &raw );
831 770
832 QArray<int> completed_uids = uids( res ); 771 QArray<int> completed_uids = uids( res );
833 772
834 odebug << "Number of completed: " << completed_uids.size() << "" << oendl;
835
836 if ( completed_uids.size() == 0 ) 773 if ( completed_uids.size() == 0 )
837 return; 774 return;
838 775
839 qu = "DELETE FROM todolist WHERE ("; 776 qu = "DELETE FROM todolist WHERE (";
840 QString query; 777 QString query;
841 778
842 for ( int i = 0; i < completed_uids.size(); i++ ){ 779 for ( uint i = 0; i < completed_uids.size(); i++ ){
843 if ( !query.isEmpty() ) 780 if ( !query.isEmpty() )
844 query += " OR "; 781 query += " OR ";
845 query += QString( "uid = %1" ).arg( completed_uids[i] ); 782 query += QString( "uid = %1" ).arg( completed_uids[i] );
846 } 783 }
847 qu += query + " );"; 784 qu += query + " );";
848 785
849 // Put remove of custom entries in this query to speed up.. 786 // Put remove of custom entries in this query to speed up..
850 qu += "DELETE FORM custom_data WHERE ("; 787 qu += "DELETE FORM custom_data WHERE (";
851 query = ""; 788 query = "";
852 789
853 for ( int i = 0; i < completed_uids.size(); i++ ){ 790 for ( uint i = 0; i < completed_uids.size(); i++ ){
854 if ( !query.isEmpty() ) 791 if ( !query.isEmpty() )
855 query += " OR "; 792 query += " OR ";
856 query += QString( "uid = %1" ).arg( completed_uids[i] ); 793 query += QString( "uid = %1" ).arg( completed_uids[i] );
857 } 794 }
858 qu += query + " );"; 795 qu += query + " );";
859 796
860 odebug << "query: " << qu << "" << oendl;
861
862 OSQLRawQuery raw2( qu ); 797 OSQLRawQuery raw2( qu );
863 res = m_driver->query( &raw2 ); 798 res = m_driver->query( &raw2 );
864 if ( res.state() == OSQLResult::Failure ) { 799
800 if ( res.state() == OSQLResult::Failure )
865 owarn << "OPimTodoAccessBackendSQL::removeAllCompleted():Failure in query: " << qu << "" << oendl; 801 owarn << "OPimTodoAccessBackendSQL::removeAllCompleted():Failure in query: " << qu << "" << oendl;
866 } 802
867} 803}
868 804
869 805
870QMap<QString, QString> OPimTodoAccessBackendSQL::requestCustom( int uid ) const 806QMap<QString, QString> OPimTodoAccessBackendSQL::requestCustom( int uid ) const
871{ 807{
872 QMap<QString, QString> customMap; 808 QMap<QString, QString> customMap;
873 809
874 FindCustomQuery query( uid ); 810 FindCustomQuery query( uid );
875 OSQLResult res_custom = m_driver->query( &query ); 811 OSQLResult res_custom = m_driver->query( &query );
876 812
877 if ( res_custom.state() == OSQLResult::Failure ) { 813 if ( res_custom.state() == OSQLResult::Failure ) {
878 owarn << "OSQLResult::Failure in find query !!" << oendl; 814 owarn << "OSQLResult::Failure in find query !!" << oendl;
879 QMap<QString, QString> empty; 815 return QMap<QString, QString>();
880 return empty;
881 } 816 }
882 817
883 OSQLResultItem::ValueList list = res_custom.results(); 818 OSQLResultItem::ValueList list = res_custom.results();
884 OSQLResultItem::ValueList::Iterator it = list.begin(); 819 OSQLResultItem::ValueList::Iterator it = list.begin();
885 for ( ; it != list.end(); ++it ) { 820 for ( ; it != list.end(); ++it )
886 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); 821 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
887 } 822
888 823
889 return customMap; 824 return customMap;
890} 825}
891 826
892 827
893 828
894 829
895} 830}
diff --git a/libopie2/opiepim/backend/otodoaccesssql.h b/libopie2/opiepim/backend/otodoaccesssql.h
index 415f791..0ba8f3a 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.h
+++ b/libopie2/opiepim/backend/otodoaccesssql.h
@@ -1,93 +1,88 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_PIM_ACCESS_SQL_H 29#ifndef OPIE_PIM_ACCESS_SQL_H
30#define OPIE_PIM_ACCESS_SQL_H 30#define OPIE_PIM_ACCESS_SQL_H
31 31
32/* #include <qasciidict.h> */ 32/* #include <qasciidict.h> */
33 33
34#include <opie2/otodoaccessbackend.h> 34#include <opie2/otodoaccessbackend.h>
35 35
36namespace Opie { 36namespace Opie {
37namespace DB { 37namespace DB {
38class OSQLDriver; 38class OSQLDriver;
39class OSQLResult; 39class OSQLResult;
40class OSQLResultItem; 40class OSQLResultItem;
41} 41}
42} 42}
43 43
44namespace Opie { 44namespace Opie {
45 45
46class OPimTodoAccessBackendSQL : public OPimTodoAccessBackend { 46class OPimTodoAccessBackendSQL : public OPimTodoAccessBackend {
47public: 47public:
48 OPimTodoAccessBackendSQL( const QString& file ); 48 OPimTodoAccessBackendSQL( const QString& file );
49 ~OPimTodoAccessBackendSQL(); 49 ~OPimTodoAccessBackendSQL();
50 50
51 bool load(); 51 bool load();
52 bool reload(); 52 bool reload();
53 bool save(); 53 bool save();
54 QArray<int> allRecords()const; 54 QArray<UID> allRecords()const;
55 55
56 QArray<int> queryByExample( const OPimTodo& t, int settings, const QDateTime& d = QDateTime() ); 56 QArray<UID> queryByExample( const OPimTodo& t, int settings, const QDateTime& d = QDateTime() );
57 OPimTodo find(int uid)const; 57 OPimTodo find(UID uid)const;
58 OPimTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; 58 OPimTodo find(UID uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
59 void clear(); 59 void clear();
60 bool add( const OPimTodo& t ); 60 bool add( const OPimTodo& t );
61 bool remove( int uid ); 61 bool remove( UID uid );
62 bool replace( const OPimTodo& t ); 62 bool replace( const OPimTodo& t );
63 63
64 QArray<int> overDue(); 64 QArray<UID> overDue()const;
65 QArray<int> effectiveToDos( const QDate& start, 65 QArray<UID> effectiveToDos( const QDate& start,
66 const QDate& end, bool includeNoDates ); 66 const QDate& end, bool includeNoDates )const;
67 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat ); 67 QArray<UID> matchRegexp( const QRegExp &r ) const;
68
69 QBitArray supports()const;
70 QArray<int> matchRegexp( const QRegExp &r ) const;
71 void removeAllCompleted(); 68 void removeAllCompleted();
72 69
73 70
74private: 71private:
75 void update()const; 72 void update()const;
76 void fillDict();
77 inline bool date( QDate& date, const QString& )const; 73 inline bool date( QDate& date, const QString& )const;
78 inline OPimTodo parseResultAndCache( int uid, const Opie::DB::OSQLResult& )const; 74 inline OPimTodo parseResultAndCache( UID uid, const Opie::DB::OSQLResult& )const;
79 inline OPimTodo todo( Opie::DB::OSQLResultItem& )const; 75 inline OPimTodo parse( Opie::DB::OSQLResultItem& )const;
80 inline QArray<int> uids( const Opie::DB::OSQLResult& )const; 76 inline QArray<UID> uids( const Opie::DB::OSQLResult& )const;
81 OPimTodo todo( int uid )const; 77 OPimTodo todo( UID uid )const;
82 QBitArray sup() const; 78 QMap<QString, QString> requestCustom( UID uid ) const;
83 QMap<QString, QString> requestCustom( int uid ) const;
84 79
85 // QAsciiDict<int> m_dict; 80 // QAsciiDict<int> m_dict;
86 Opie::DB::OSQLDriver* m_driver; 81 Opie::DB::OSQLDriver* m_driver;
87 QArray<int> m_uids; 82 QArray<UID> m_uids;
88 bool m_dirty : 1; 83 bool m_dirty : 1;
89}; 84};
90 85
91} 86}
92 87
93#endif 88#endif
diff --git a/libopie2/opiepim/backend/otodoaccessvcal.cpp b/libopie2/opiepim/backend/otodoaccessvcal.cpp
index 7d58a40..aa8a7eb 100644
--- a/libopie2/opiepim/backend/otodoaccessvcal.cpp
+++ b/libopie2/opiepim/backend/otodoaccessvcal.cpp
@@ -1,289 +1,259 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29 29
30#include <opie2/private/vobject_p.h> 30#include <opie2/private/vobject_p.h>
31 31
32/* OPIE */ 32/* OPIE */
33#include <opie2/otodoaccessvcal.h> 33#include <opie2/otodoaccessvcal.h>
34#include <opie2/odebug.h> 34#include <opie2/odebug.h>
35 35
36#include <qpe/timeconversion.h> 36#include <qpe/timeconversion.h>
37 37
38/* QT */ 38/* QT */
39//FIXME: Hack to allow direct access to FILE* fh. Rewrite this! 39//FIXME: Hack to allow direct access to FILE* fh. Rewrite this!
40#define protected public 40#define protected public
41#include <qfile.h> 41#include <qfile.h>
42#undef protected 42#undef protected
43 43
44using namespace Opie; 44using namespace Opie;
45 45
46namespace { 46namespace {
47 static OPimTodo eventByVObj( VObject *obj ){ 47 static OPimTodo eventByVObj( VObject *obj ){
48 OPimTodo event; 48 OPimTodo event;
49 VObject *ob; 49 VObject *ob;
50 QCString name; 50 QCString name;
51 // no uid, attendees, ... and no fun 51 // no uid, attendees, ... and no fun
52 // description 52 // description
53 if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){ 53 if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){
54 name = vObjectStringZValue( ob ); 54 name = vObjectStringZValue( ob );
55#if 0 55#if 0
56 event.setDescription( name ); 56 event.setDescription( name );
57#else 57#else
58 event.setSummary( name ); 58 event.setSummary( name );
59#endif 59#endif
60 } 60 }
61 // summary 61 // summary
62 if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) { 62 if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) {
63 name = vObjectStringZValue( ob ); 63 name = vObjectStringZValue( ob );
64#if 0 64#if 0
65 event.setSummary( name ); 65 event.setSummary( name );
66#else 66#else
67 event.setDescription( name ); 67 event.setDescription( name );
68#endif 68#endif
69 } 69 }
70 // completed 70 // completed
71 if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){ 71 if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){
72 name = vObjectStringZValue( ob ); 72 name = vObjectStringZValue( ob );
73 if( name == "COMPLETED" ){ 73 if( name == "COMPLETED" ){
74 event.setCompleted( true ); 74 event.setCompleted( true );
75 }else{ 75 }else{
76 event.setCompleted( false ); 76 event.setCompleted( false );
77 } 77 }
78 }else 78 }else
79 event.setCompleted( false ); 79 event.setCompleted( false );
80 // priority 80 // priority
81 if ((ob = isAPropertyOf(obj, VCPriorityProp))) { 81 if ((ob = isAPropertyOf(obj, VCPriorityProp))) {
82 name = vObjectStringZValue( ob ); 82 name = vObjectStringZValue( ob );
83 bool ok; 83 bool ok;
84 event.setPriority(name.toInt(&ok) ); 84 event.setPriority(name.toInt(&ok) );
85 } 85 }
86 //due date 86 //due date
87 if((ob = isAPropertyOf(obj, VCDueProp)) ){ 87 if((ob = isAPropertyOf(obj, VCDueProp)) ){
88 event.setHasDueDate( true ); 88 event.setHasDueDate( true );
89 name = vObjectStringZValue( ob ); 89 name = vObjectStringZValue( ob );
90 event.setDueDate( TimeConversion::fromISO8601( name).date() ); 90 event.setDueDate( TimeConversion::fromISO8601( name).date() );
91 } 91 }
92 // categories 92 // categories
93 if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){ 93 if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){
94 name = vObjectStringZValue( ob ); 94 name = vObjectStringZValue( ob );
95 owarn << "Categories:" << name.data() << "" << oendl;
96 } 95 }
97 96
98 event.setUid( 1 ); 97 event.setUid( 1 );
99 return event; 98 return event;
100 }; 99 };
101 static VObject *vobjByEvent( const OPimTodo &event ) { 100 static VObject *vobjByEvent( const OPimTodo &event ) {
102 VObject *task = newVObject( VCTodoProp ); 101 VObject *task = newVObject( VCTodoProp );
103 if( task == 0 ) 102 if( task == 0 )
104 return 0l; 103 return 0l;
105 104
106 if( event.hasDueDate() ) { 105 if( event.hasDueDate() ) {
107 QTime time(0, 0, 0); 106 QTime time(0, 0, 0);
108 QDateTime date(event.dueDate(), time ); 107 QDateTime date(event.dueDate(), time );
109 addPropValue( task, VCDueProp, 108 addPropValue( task, VCDueProp,
110 TimeConversion::toISO8601( date ) ); 109 TimeConversion::toISO8601( date ) );
111 } 110 }
112 111
113 if( event.isCompleted() ) 112 if( event.isCompleted() )
114 addPropValue( task, VCStatusProp, "COMPLETED"); 113 addPropValue( task, VCStatusProp, "COMPLETED");
115 114
116 QString string = QString::number(event.priority() ); 115 QString string = QString::number(event.priority() );
117 addPropValue( task, VCPriorityProp, string.local8Bit() ); 116 addPropValue( task, VCPriorityProp, string.local8Bit() );
118 117
119 addPropValue( task, VCCategoriesProp, 118 addPropValue( task, VCCategoriesProp,
120 event.idsToString( event.categories() ).local8Bit() ); 119 event.idsToString( event.categories() ).local8Bit() );
121 120
122#if 0 121#if 0
123 122
124 // There seems a misrepresentation between summary in otodoevent 123 // There seems a misrepresentation between summary in otodoevent
125 // and summary in vcard. 124 // and summary in vcard.
126 // The same with description.. 125 // The same with description..
127 // Description is summary and vice versa.. Argh.. (eilers) 126 // Description is summary and vice versa.. Argh.. (eilers)
128 127
129 128
130 addPropValue( task, VCDescriptionProp, 129 addPropValue( task, VCDescriptionProp,
131 event.description().local8Bit() ); 130 event.description().local8Bit() );
132 131
133 addPropValue( task, VCSummaryProp, 132 addPropValue( task, VCSummaryProp,
134 event.summary().local8Bit() ); 133 event.summary().local8Bit() );
135 134
136#else 135#else
137 addPropValue( task, VCDescriptionProp, 136 addPropValue( task, VCDescriptionProp,
138 event.summary().local8Bit() ); 137 event.summary().local8Bit() );
139 138
140 addPropValue( task, VCSummaryProp, 139 addPropValue( task, VCSummaryProp,
141 event.description().local8Bit() ); 140 event.description().local8Bit() );
142#endif 141#endif
143 return task; 142 return task;
144}; 143};
145} 144}
146 145
147namespace Opie { 146namespace Opie {
148OPimTodoAccessVCal::OPimTodoAccessVCal( const QString& path ) 147OPimTodoAccessVCal::OPimTodoAccessVCal( const QString& path )
149 : m_dirty(false), m_file( path ) 148 : m_dirty(false), m_file( path )
150{ 149{
151} 150}
152OPimTodoAccessVCal::~OPimTodoAccessVCal() { 151OPimTodoAccessVCal::~OPimTodoAccessVCal() {
153} 152}
154bool OPimTodoAccessVCal::load() { 153bool OPimTodoAccessVCal::load() {
155 m_map.clear(); 154 m_map.clear();
156 m_dirty = false; 155 m_dirty = false;
157 156
158 VObject* vcal = 0l; 157 VObject* vcal = 0l;
159 vcal = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); 158 vcal = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() );
160 if (!vcal ) 159 if (!vcal )
161 return false; 160 return false;
162 161
163 // Iterate over the list 162 // Iterate over the list
164 VObjectIterator it; 163 VObjectIterator it;
165 VObject* vobj; 164 VObject* vobj;
166 165
167 initPropIterator(&it, vcal); 166 initPropIterator(&it, vcal);
168 167
169 while( moreIteration( &it ) ) { 168 while( moreIteration( &it ) ) {
170 vobj = ::nextVObject( &it ); 169 vobj = ::nextVObject( &it );
171 QCString name = ::vObjectName( vobj ); 170 QCString name = ::vObjectName( vobj );
172 if( name == VCTodoProp ){ 171 if( name == VCTodoProp ){
173 OPimTodo to = eventByVObj( vobj ); 172 OPimTodo to = eventByVObj( vobj );
174 m_map.insert( to.uid(), to ); 173 m_map.insert( to.uid(), to );
175 } 174 }
176 } 175 }
177 176
178 // Should I do a delete vcal? 177 // Should I do a delete vcal?
179 178
180 return true; 179 return true;
181} 180}
182bool OPimTodoAccessVCal::reload() { 181bool OPimTodoAccessVCal::reload() {
183 return load(); 182 return load();
184} 183}
185bool OPimTodoAccessVCal::save() { 184bool OPimTodoAccessVCal::save() {
186 if (!m_dirty ) 185 if (!m_dirty )
187 return true; 186 return true;
188 187
189 QFile file( m_file ); 188 QFile file( m_file );
190 if (!file.open(IO_WriteOnly ) ) 189 if (!file.open(IO_WriteOnly ) )
191 return false; 190 return false;
192 191
193 VObject *obj; 192 VObject *obj;
194 obj = newVObject( VCCalProp ); 193 obj = newVObject( VCCalProp );
195 addPropValue( obj, VCVersionProp, "1.0" ); 194 addPropValue( obj, VCVersionProp, "1.0" );
196 VObject *vo; 195 VObject *vo;
197 for(QMap<int, OPimTodo>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ 196 for(QMap<int, OPimTodo>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){
198 vo = vobjByEvent( it.data() ); 197 vo = vobjByEvent( it.data() );
199 addVObjectProp(obj, vo ); 198 addVObjectProp(obj, vo );
200 } 199 }
201 writeVObject( file.fh, obj ); //FIXME: HACK!!! 200 writeVObject( file.fh, obj ); //FIXME: HACK!!!
202 cleanVObject( obj ); 201 cleanVObject( obj );
203 cleanStrTbl(); 202 cleanStrTbl();
204 203
205 m_dirty = false; 204 m_dirty = false;
206 return true; 205 return true;
207} 206}
208void OPimTodoAccessVCal::clear() { 207void OPimTodoAccessVCal::clear() {
209 m_map.clear(); 208 m_map.clear();
210 m_dirty = true; 209 m_dirty = true;
211} 210}
212bool OPimTodoAccessVCal::add( const OPimTodo& to ) { 211bool OPimTodoAccessVCal::add( const OPimTodo& to ) {
213 m_map.insert( to.uid(), to ); 212 m_map.insert( to.uid(), to );
214 m_dirty = true; 213 m_dirty = true;
215 return true; 214 return true;
216} 215}
217bool OPimTodoAccessVCal::remove( int uid ) { 216bool OPimTodoAccessVCal::remove( int uid ) {
218 m_map.remove( uid ); 217 m_map.remove( uid );
219 m_dirty = true; 218 m_dirty = true;
220 return true; 219 return true;
221} 220}
222void OPimTodoAccessVCal::removeAllCompleted() { 221void OPimTodoAccessVCal::removeAllCompleted() {
223 for ( QMap<int, OPimTodo>::Iterator it = m_map.begin(); it != m_map.end(); ++it ) { 222 for ( QMap<int, OPimTodo>::Iterator it = m_map.begin(); it != m_map.end(); ++it ) {
224 if ( (*it).isCompleted() ) 223 if ( (*it).isCompleted() )
225 m_map.remove( it ); 224 m_map.remove( it );
226 } 225 }
227} 226}
228bool OPimTodoAccessVCal::replace( const OPimTodo& to ) { 227bool OPimTodoAccessVCal::replace( const OPimTodo& to ) {
229 m_map.replace( to.uid(), to ); 228 m_map.replace( to.uid(), to );
230 m_dirty = true; 229 m_dirty = true;
231 return true; 230 return true;
232} 231}
233OPimTodo OPimTodoAccessVCal::find(int uid )const { 232OPimTodo OPimTodoAccessVCal::find(int uid )const {
234 return m_map[uid]; 233 return m_map[uid];
235} 234}
236QArray<int> OPimTodoAccessVCal::sorted( bool, int, int, int ) { 235
237 QArray<int> ar(0);
238 return ar;
239}
240QArray<int> OPimTodoAccessVCal::allRecords()const { 236QArray<int> OPimTodoAccessVCal::allRecords()const {
241 QArray<int> ar( m_map.count() ); 237 QArray<int> ar( m_map.count() );
242 QMap<int, OPimTodo>::ConstIterator it; 238 QMap<int, OPimTodo>::ConstIterator it;
243 int i = 0; 239 int i = 0;
244 for ( it = m_map.begin(); it != m_map.end(); ++it ) { 240 for ( it = m_map.begin(); it != m_map.end(); ++it ) {
245 ar[i] = it.key(); 241 ar[i] = it.key();
246 i++; 242 i++;
247 } 243 }
248 return ar; 244 return ar;
249} 245}
250QArray<int> OPimTodoAccessVCal::matchRegexp(const QRegExp& /* r */)const { 246
251 QArray<int> ar(0);
252 return ar;
253}
254QArray<int> OPimTodoAccessVCal::queryByExample( const OPimTodo&, int, const QDateTime& ) {
255 QArray<int> ar(0);
256 return ar;
257}
258QArray<int> OPimTodoAccessVCal::effectiveToDos( const QDate& , 247QArray<int> OPimTodoAccessVCal::effectiveToDos( const QDate& ,
259 const QDate& , 248 const QDate& ,
260 bool ) { 249 bool )const {
261 QArray<int> ar(0);
262 return ar;
263}
264QArray<int> OPimTodoAccessVCal::overDue() {
265 QArray<int> ar(0); 250 QArray<int> ar(0);
266 return ar; 251 return ar;
267} 252}
268QBitArray OPimTodoAccessVCal::supports()const {
269 static QBitArray ar = sup();
270
271 return ar;
272}
273QBitArray OPimTodoAccessVCal::sup() {
274 QBitArray ar ( OPimTodo::CompletedDate +1 );
275 ar.fill( true );
276
277 ar[OPimTodo::CrossReference] = false;
278 ar[OPimTodo::State ] = false;
279 ar[OPimTodo::Reminders] = false;
280 ar[OPimTodo::Notifiers] = false;
281 ar[OPimTodo::Maintainer] = false;
282 ar[OPimTodo::Progress] = false;
283 ar[OPimTodo::Alarms ] = false;
284 ar[OPimTodo::Recurrence] = false;
285 253
254QArray<int> OPimTodoAccessVCal::overDue()const {
255 QArray<int> ar(0);
286 return ar; 256 return ar;
287} 257}
288 258
289} 259}
diff --git a/libopie2/opiepim/backend/otodoaccessvcal.h b/libopie2/opiepim/backend/otodoaccessvcal.h
index 1e106d3..05dd76b 100644
--- a/libopie2/opiepim/backend/otodoaccessvcal.h
+++ b/libopie2/opiepim/backend/otodoaccessvcal.h
@@ -1,72 +1,66 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_OTODO_ACCESS_VCAL_H 29#ifndef OPIE_OTODO_ACCESS_VCAL_H
30#define OPIE_OTODO_ACCESS_VCAL_H 30#define OPIE_OTODO_ACCESS_VCAL_H
31 31
32#include <opie2/otodoaccessbackend.h> 32#include <opie2/otodoaccessbackend.h>
33 33
34namespace Opie { 34namespace Opie {
35 35
36class OPimTodoAccessVCal : public OPimTodoAccessBackend { 36class OPimTodoAccessVCal : public OPimTodoAccessBackend {
37public: 37public:
38 OPimTodoAccessVCal(const QString& ); 38 OPimTodoAccessVCal(const QString& );
39 ~OPimTodoAccessVCal(); 39 ~OPimTodoAccessVCal();
40 40
41 bool load(); 41 bool load();
42 bool reload(); 42 bool reload();
43 bool save(); 43 bool save();
44 44
45 QArray<int> allRecords()const; 45 QArray<int> allRecords()const;
46 QArray<int> matchRegexp(const QRegExp &r) const;
47 QArray<int> queryByExample( const OPimTodo& t, int sort, const QDateTime& d = QDateTime() );
48 QArray<int> effectiveToDos( const QDate& start, 46 QArray<int> effectiveToDos( const QDate& start,
49 const QDate& end, 47 const QDate& end,
50 bool includeNoDates ); 48 bool includeNoDates )const;
51 QArray<int> overDue(); 49 QArray<int> overDue()const;
52 QArray<int> sorted( bool asc, int sortOrder, int sortFilter,
53 int cat );
54 OPimTodo find(int uid)const; 50 OPimTodo find(int uid)const;
55 void clear(); 51 void clear();
56 bool add( const OPimTodo& ); 52 bool add( const OPimTodo& );
57 bool remove( int uid ); 53 bool remove( int uid );
58 bool replace( const OPimTodo& ); 54 bool replace( const OPimTodo& );
59 55
60 void removeAllCompleted(); 56 void removeAllCompleted();
61 virtual QBitArray supports()const;
62 57
63private: 58private:
64 static QBitArray sup();
65 bool m_dirty : 1; 59 bool m_dirty : 1;
66 QString m_file; 60 QString m_file;
67 QMap<int, OPimTodo> m_map; 61 QMap<int, OPimTodo> m_map;
68}; 62};
69 63
70} 64}
71 65
72#endif 66#endif
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp
index 3e06d88..273f91a 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.cpp
+++ b/libopie2/opiepim/backend/otodoaccessxml.cpp
@@ -1,914 +1,720 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29 29
30/* OPIE */ 30/* OPIE */
31#include <opie2/opimdateconversion.h> 31#include <opie2/opimdateconversion.h>
32#include <opie2/opimstate.h> 32#include <opie2/opimstate.h>
33#include <opie2/opimtimezone.h> 33#include <opie2/opimtimezone.h>
34#include <opie2/opimnotifymanager.h> 34#include <opie2/opimnotifymanager.h>
35#include <opie2/opimrecurrence.h> 35#include <opie2/opimrecurrence.h>
36#include <opie2/otodoaccessxml.h> 36#include <opie2/otodoaccessxml.h>
37#include <opie2/otodoaccess.h>
37#include <opie2/odebug.h> 38#include <opie2/odebug.h>
38 39
40#include <opie2/private/opimtodosortvector.h>
41
39#include <qpe/global.h> 42#include <qpe/global.h>
40#include <qpe/stringutil.h> 43#include <qpe/stringutil.h>
41#include <qpe/timeconversion.h> 44#include <qpe/timeconversion.h>
42 45
43/* QT */ 46/* QT */
44#include <qfile.h> 47#include <qfile.h>
45#include <qvector.h> 48#include <qvector.h>
46 49
47/* STD */ 50/* STD */
48#include <errno.h> 51#include <errno.h>
49#include <fcntl.h> 52#include <fcntl.h>
50 53
51#include <sys/mman.h> 54#include <sys/mman.h>
52#include <sys/stat.h> 55#include <sys/stat.h>
53#include <sys/types.h> 56#include <sys/types.h>
54 57
55#include <unistd.h> 58#include <unistd.h>
56 59
57 60
58using namespace Opie; 61using namespace Opie;
59 62
60namespace { 63namespace {
61 time_t rp_end; 64 time_t rp_end;
62 OPimRecurrence* rec; 65 OPimRecurrence* rec;
63 OPimRecurrence *recur() { 66 OPimRecurrence *recur() {
64 if (!rec ) rec = new OPimRecurrence; 67 if (!rec ) rec = new OPimRecurrence;
65 return rec; 68 return rec;
66 } 69 }
67 int snd; 70 int snd;
68 enum MoreAttributes { 71 enum MoreAttributes {
69 FRType = OPimTodo::CompletedDate + 2, 72 FRType = OPimTodo::CompletedDate + 2,
70 FRWeekdays, 73 FRWeekdays,
71 FRPosition, 74 FRPosition,
72 FRFreq, 75 FRFreq,
73 FRHasEndDate, 76 FRHasEndDate,
74 FREndDate, 77 FREndDate,
75 FRStart, 78 FRStart,
76 FREnd 79 FREnd
77 }; 80 };
78 // FROM TT again 81 // FROM TT again
79char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) 82char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
80{ 83{
81 char needleChar; 84 char needleChar;
82 char haystackChar; 85 char haystackChar;
83 if (!needle || !haystack || !hLen || !nLen) 86 if (!needle || !haystack || !hLen || !nLen)
84 return 0; 87 return 0;
85 88
86 const char* hsearch = haystack; 89 const char* hsearch = haystack;
87 90
88 if ((needleChar = *needle++) != 0) { 91 if ((needleChar = *needle++) != 0) {
89 nLen--; //(to make up for needle++) 92 nLen--; //(to make up for needle++)
90 do { 93 do {
91 do { 94 do {
92 if ((haystackChar = *hsearch++) == 0) 95 if ((haystackChar = *hsearch++) == 0)
93 return (0); 96 return (0);
94 if (hsearch >= haystack + hLen) 97 if (hsearch >= haystack + hLen)
95 return (0); 98 return (0);
96 } while (haystackChar != needleChar); 99 } while (haystackChar != needleChar);
97 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); 100 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
98 hsearch--; 101 hsearch--;
99 } 102 }
100 return ((char *)hsearch); 103 return ((char *)hsearch);
101} 104}
102} 105}
103 106
104namespace Opie { 107namespace Opie {
105 108
106OPimTodoAccessXML::OPimTodoAccessXML( const QString& appName, 109OPimTodoAccessXML::OPimTodoAccessXML( const QString& appName,
107 const QString& fileName ) 110 const QString& fileName )
108 : OPimTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) 111 : OPimTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
109{ 112{
110 if (!fileName.isEmpty() ) 113 if (!fileName.isEmpty() )
111 m_file = fileName; 114 m_file = fileName;
112 else 115 else
113 m_file = Global::applicationFileName( "todolist", "todolist.xml" ); 116 m_file = Global::applicationFileName( "todolist", "todolist.xml" );
114} 117}
115OPimTodoAccessXML::~OPimTodoAccessXML() { 118OPimTodoAccessXML::~OPimTodoAccessXML() {
116 119
117} 120}
118bool OPimTodoAccessXML::load() { 121bool OPimTodoAccessXML::load() {
119 rec = 0; 122 rec = 0;
120 m_opened = true; 123 m_opened = true;
121 m_changed = false; 124 m_changed = false;
122 /* initialize dict */ 125 /* initialize dict */
123 /* 126 /*
124 * UPDATE dict if you change anything!!! 127 * UPDATE dict if you change anything!!!
125 */ 128 */
126 QAsciiDict<int> dict(26); 129 QAsciiDict<int> dict(26);
127 dict.setAutoDelete( TRUE ); 130 dict.setAutoDelete( TRUE );
128 dict.insert("Categories" , new int(OPimTodo::Category) ); 131 dict.insert("Categories" , new int(OPimTodo::Category) );
129 dict.insert("Uid" , new int(OPimTodo::Uid) ); 132 dict.insert("Uid" , new int(OPimTodo::Uid) );
130 dict.insert("HasDate" , new int(OPimTodo::HasDate) ); 133 dict.insert("HasDate" , new int(OPimTodo::HasDate) );
131 dict.insert("Completed" , new int(OPimTodo::Completed) ); 134 dict.insert("Completed" , new int(OPimTodo::Completed) );
132 dict.insert("Description" , new int(OPimTodo::Description) ); 135 dict.insert("Description" , new int(OPimTodo::Description) );
133 dict.insert("Summary" , new int(OPimTodo::Summary) ); 136 dict.insert("Summary" , new int(OPimTodo::Summary) );
134 dict.insert("Priority" , new int(OPimTodo::Priority) ); 137 dict.insert("Priority" , new int(OPimTodo::Priority) );
135 dict.insert("DateDay" , new int(OPimTodo::DateDay) ); 138 dict.insert("DateDay" , new int(OPimTodo::DateDay) );
136 dict.insert("DateMonth" , new int(OPimTodo::DateMonth) ); 139 dict.insert("DateMonth" , new int(OPimTodo::DateMonth) );
137 dict.insert("DateYear" , new int(OPimTodo::DateYear) ); 140 dict.insert("DateYear" , new int(OPimTodo::DateYear) );
138 dict.insert("Progress" , new int(OPimTodo::Progress) ); 141 dict.insert("Progress" , new int(OPimTodo::Progress) );
139 dict.insert("CompletedDate", new int(OPimTodo::CompletedDate) ); 142 dict.insert("CompletedDate", new int(OPimTodo::CompletedDate) );
140 dict.insert("StartDate", new int(OPimTodo::StartDate) ); 143 dict.insert("StartDate", new int(OPimTodo::StartDate) );
141 dict.insert("CrossReference", new int(OPimTodo::CrossReference) ); 144 dict.insert("CrossReference", new int(OPimTodo::CrossReference) );
142 dict.insert("State", new int(OPimTodo::State) ); 145 dict.insert("State", new int(OPimTodo::State) );
143 dict.insert("Alarms", new int(OPimTodo::Alarms) ); 146 dict.insert("Alarms", new int(OPimTodo::Alarms) );
144 dict.insert("Reminders", new int(OPimTodo::Reminders) ); 147 dict.insert("Reminders", new int(OPimTodo::Reminders) );
145 dict.insert("Notifiers", new int(OPimTodo::Notifiers) );
146 dict.insert("Maintainer", new int(OPimTodo::Maintainer) ); 148 dict.insert("Maintainer", new int(OPimTodo::Maintainer) );
147 dict.insert("rtype", new int(FRType) ); 149 dict.insert("rtype", new int(FRType) );
148 dict.insert("rweekdays", new int(FRWeekdays) ); 150 dict.insert("rweekdays", new int(FRWeekdays) );
149 dict.insert("rposition", new int(FRPosition) ); 151 dict.insert("rposition", new int(FRPosition) );
150 dict.insert("rfreq", new int(FRFreq) ); 152 dict.insert("rfreq", new int(FRFreq) );
151 dict.insert("start", new int(FRStart) ); 153 dict.insert("start", new int(FRStart) );
152 dict.insert("rhasenddate", new int(FRHasEndDate) ); 154 dict.insert("rhasenddate", new int(FRHasEndDate) );
153 dict.insert("enddt", new int(FREndDate) ); 155 dict.insert("enddt", new int(FREndDate) );
154 156
155 // here the custom XML parser from TT it's GPL 157 // here the custom XML parser from TT it's GPL
156 // but we want to push OpiePIM... to TT..... 158 // but we want to push OpiePIM... to TT.....
157 // mmap part from zecke :) 159 // mmap part from zecke :)
158 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); 160 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
159 struct stat attribut; 161 struct stat attribut;
160 if ( fd < 0 ) return false; 162 if ( fd < 0 ) return false;
161 163
162 if ( fstat(fd, &attribut ) == -1 ) { 164 if ( fstat(fd, &attribut ) == -1 ) {
163 ::close( fd ); 165 ::close( fd );
164 return false; 166 return false;
165 } 167 }
166 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 168 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
167 if ( map_addr == ( (caddr_t)-1) ) { 169 if ( map_addr == ( (caddr_t)-1) ) {
168 ::close(fd ); 170 ::close(fd );
169 return false; 171 return false;
170 } 172 }
171 /* advise the kernel who we want to read it */ 173 /* advise the kernel who we want to read it */
172 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); 174 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
173 /* we do not the file any more */ 175 /* we do not the file any more */
174 ::close( fd ); 176 ::close( fd );
175 177
176 char* dt = (char*)map_addr; 178 char* dt = (char*)map_addr;
177 int len = attribut.st_size; 179 int len = attribut.st_size;
178 int i = 0; 180 int i = 0;
179 char *point; 181 char *point;
180 const char* collectionString = "<Task "; 182 const char* collectionString = "<Task ";
181 int strLen = strlen(collectionString); 183 int strLen = strlen(collectionString);
182 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { 184 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) {
183 i = point -dt; 185 i = point -dt;
184 i+= strLen; 186 i+= strLen;
185 owarn << "Found a start at " << i << " " << (point-dt) << "" << oendl;
186 187
187 OPimTodo ev; 188 OPimTodo ev;
188 m_year = m_month = m_day = 0; 189 m_year = m_month = m_day = 0;
189 190
190 while ( TRUE ) { 191 while ( TRUE ) {
191 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 192 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
192 ++i; 193 ++i;
193 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 194 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
194 break; 195 break;
195 196
196 // we have another attribute, read it. 197 // we have another attribute, read it.
197 int j = i; 198 int j = i;
198 while ( j < len && dt[j] != '=' ) 199 while ( j < len && dt[j] != '=' )
199 ++j; 200 ++j;
200 QCString attr( dt+i, j-i+1); 201 QCString attr( dt+i, j-i+1);
201 202
202 i = ++j; // skip = 203 i = ++j; // skip =
203 204
204 // find the start of quotes 205 // find the start of quotes
205 while ( i < len && dt[i] != '"' ) 206 while ( i < len && dt[i] != '"' )
206 ++i; 207 ++i;
207 j = ++i; 208 j = ++i;
208 209
209 bool haveUtf = FALSE; 210 bool haveUtf = FALSE;
210 bool haveEnt = FALSE; 211 bool haveEnt = FALSE;
211 while ( j < len && dt[j] != '"' ) { 212 while ( j < len && dt[j] != '"' ) {
212 if ( ((unsigned char)dt[j]) > 0x7f ) 213 if ( ((unsigned char)dt[j]) > 0x7f )
213 haveUtf = TRUE; 214 haveUtf = TRUE;
214 if ( dt[j] == '&' ) 215 if ( dt[j] == '&' )
215 haveEnt = TRUE; 216 haveEnt = TRUE;
216 ++j; 217 ++j;
217 } 218 }
218 if ( i == j ) { 219 if ( i == j ) {
219 // empty value 220 // empty value
220 i = j + 1; 221 i = j + 1;
221 continue; 222 continue;
222 } 223 }
223 224
224 QCString value( dt+i, j-i+1 ); 225 QCString value( dt+i, j-i+1 );
225 i = j + 1; 226 i = j + 1;
226 227
227 QString str = (haveUtf ? QString::fromUtf8( value ) 228 QString str = (haveUtf ? QString::fromUtf8( value )
228 : QString::fromLatin1( value ) ); 229 : QString::fromLatin1( value ) );
229 if ( haveEnt ) 230 if ( haveEnt )
230 str = Qtopia::plainString( str ); 231 str = Qtopia::plainString( str );
231 232
232 /* 233 /*
233 * add key + value 234 * add key + value
234 */ 235 */
235 todo( &dict, ev, attr, str ); 236 todo( &dict, ev, attr, str );
236 237
237 } 238 }
238 /* 239 /*
239 * now add it 240 * now add it
240 */ 241 */
241 owarn << "End at " << i << "" << oendl;
242 if (m_events.contains( ev.uid() ) || ev.uid() == 0) { 242 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
243 ev.setUid( 1 ); 243 ev.setUid( 1 );
244 m_changed = true; 244 m_changed = true;
245 } 245 }
246 if ( ev.hasDueDate() ) { 246 if ( ev.hasDueDate() ) {
247 ev.setDueDate( QDate(m_year, m_month, m_day) ); 247 ev.setDueDate( QDate(m_year, m_month, m_day) );
248 } 248 }
249 if ( rec && rec->doesRecur() ) { 249 if ( rec && rec->doesRecur() ) {
250 OPimTimeZone utc = OPimTimeZone::utc(); 250 OPimTimeZone utc = OPimTimeZone::utc();
251 OPimRecurrence recu( *rec ); // call copy c'tor 251 OPimRecurrence recu( *rec ); // call copy c'tor
252 recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() ); 252 recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() );
253 recu.setStart( ev.dueDate() ); 253 recu.setStart( ev.dueDate() );
254 ev.setRecurrence( recu ); 254 ev.setRecurrence( recu );
255 } 255 }
256 m_events.insert(ev.uid(), ev ); 256 m_events.insert(ev.uid(), ev );
257 m_year = m_month = m_day = -1; 257 m_year = m_month = m_day = -1;
258 delete rec; 258 delete rec;
259 rec = 0; 259 rec = 0;
260 } 260 }
261 261
262 munmap(map_addr, attribut.st_size ); 262 munmap(map_addr, attribut.st_size );
263 263
264 owarn << "counts " << m_events.count() << " records loaded!" << oendl;
265 return true; 264 return true;
266} 265}
267bool OPimTodoAccessXML::reload() { 266bool OPimTodoAccessXML::reload() {
268 m_events.clear(); 267 m_events.clear();
269 return load(); 268 return load();
270} 269}
271bool OPimTodoAccessXML::save() { 270bool OPimTodoAccessXML::save() {
272// owarn << "saving" << oendl;
273 if (!m_opened || !m_changed ) { 271 if (!m_opened || !m_changed ) {
274// owarn << "not saving" << oendl;
275 return true; 272 return true;
276 } 273 }
277 QString strNewFile = m_file + ".new"; 274 QString strNewFile = m_file + ".new";
278 QFile f( strNewFile ); 275 QFile f( strNewFile );
279 if (!f.open( IO_WriteOnly|IO_Raw ) ) 276 if (!f.open( IO_WriteOnly|IO_Raw ) )
280 return false; 277 return false;
281 278
282 int written; 279 int written;
283 QString out; 280 QString out;
284 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 281 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
285 282
286 // for all todos 283 // for all todos
287 QMap<int, OPimTodo>::Iterator it; 284 QMap<int, OPimTodo>::Iterator it;
288 for (it = m_events.begin(); it != m_events.end(); ++it ) { 285 for (it = m_events.begin(); it != m_events.end(); ++it ) {
289 out+= "<Task " + toString( (*it) ) + " />\n"; 286 out+= "<Task " + toString( (*it) ) + " />\n";
290 QCString cstr = out.utf8(); 287 QCString cstr = out.utf8();
291 written = f.writeBlock( cstr.data(), cstr.length() ); 288 written = f.writeBlock( cstr.data(), cstr.length() );
292 289
293 /* less written then we wanted */ 290 /* less written then we wanted */
294 if ( written != (int)cstr.length() ) { 291 if ( written != (int)cstr.length() ) {
295 f.close(); 292 f.close();
296 QFile::remove( strNewFile ); 293 QFile::remove( strNewFile );
297 return false; 294 return false;
298 } 295 }
299 out = QString::null; 296 out = QString::null;
300 } 297 }
301 298
302 out += "</Tasks>"; 299 out += "</Tasks>";
303 QCString cstr = out.utf8(); 300 QCString cstr = out.utf8();
304 written = f.writeBlock( cstr.data(), cstr.length() ); 301 written = f.writeBlock( cstr.data(), cstr.length() );
305 302
306 if ( written != (int)cstr.length() ) { 303 if ( written != (int)cstr.length() ) {
307 f.close(); 304 f.close();
308 QFile::remove( strNewFile ); 305 QFile::remove( strNewFile );
309 return false; 306 return false;
310 } 307 }
311 /* flush before renaming */ 308 /* flush before renaming */
312 f.close(); 309 f.close();
313 310
314 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 311 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
315// owarn << "error renaming" << oendl;
316 QFile::remove( strNewFile ); 312 QFile::remove( strNewFile );
317 } 313 }
318 314
319 m_changed = false; 315 m_changed = false;
320 return true; 316 return true;
321} 317}
322QArray<int> OPimTodoAccessXML::allRecords()const { 318QArray<int> OPimTodoAccessXML::allRecords()const {
323 QArray<int> ids( m_events.count() ); 319 QArray<int> ids( m_events.count() );
324 QMap<int, OPimTodo>::ConstIterator it; 320 QMap<int, OPimTodo>::ConstIterator it;
325 int i = 0; 321 int i = 0;
326 322
327 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 323 for ( it = m_events.begin(); it != m_events.end(); ++it )
328 ids[i] = it.key(); 324 ids[i++] = it.key();
329 i++; 325
330 } 326
331 return ids; 327 return ids;
332} 328}
333QArray<int> OPimTodoAccessXML::queryByExample( const OPimTodo&, int, const QDateTime& ) { 329QArray<int> OPimTodoAccessXML::queryByExample( const OPimTodo&, int, const QDateTime& ) {
334 QArray<int> ids(0); 330 QArray<int> ids(0);
335 return ids; 331 return ids;
336} 332}
337OPimTodo OPimTodoAccessXML::find( int uid )const { 333OPimTodo OPimTodoAccessXML::find( int uid )const {
338 OPimTodo todo; 334 OPimTodo todo;
339 todo.setUid( 0 ); // isEmpty() 335 todo.setUid( 0 ); // isEmpty()
340 QMap<int, OPimTodo>::ConstIterator it = m_events.find( uid ); 336 QMap<int, OPimTodo>::ConstIterator it = m_events.find( uid );
341 if ( it != m_events.end() ) 337 if ( it != m_events.end() )
342 todo = it.data(); 338 todo = it.data();
343 339
344 return todo; 340 return todo;
345} 341}
346void OPimTodoAccessXML::clear() { 342void OPimTodoAccessXML::clear() {
347 if (m_opened ) 343 if (m_opened )
348 m_changed = true; 344 m_changed = true;
349 345
350 m_events.clear(); 346 m_events.clear();
351} 347}
352bool OPimTodoAccessXML::add( const OPimTodo& todo ) { 348bool OPimTodoAccessXML::add( const OPimTodo& todo ) {
353// owarn << "add" << oendl;
354 m_changed = true; 349 m_changed = true;
355 m_events.insert( todo.uid(), todo ); 350 m_events.insert( todo.uid(), todo );
356 351
357 return true; 352 return true;
358} 353}
359bool OPimTodoAccessXML::remove( int uid ) { 354bool OPimTodoAccessXML::remove( int uid ) {
360 m_changed = true; 355 m_changed = true;
361 m_events.remove( uid ); 356 m_events.remove( uid );
362 357
363 return true; 358 return true;
364} 359}
365bool OPimTodoAccessXML::replace( const OPimTodo& todo) { 360bool OPimTodoAccessXML::replace( const OPimTodo& todo) {
366 m_changed = true; 361 m_changed = true;
367 m_events.replace( todo.uid(), todo ); 362 m_events.replace( todo.uid(), todo );
368 363
369 return true; 364 return true;
370} 365}
371QArray<int> OPimTodoAccessXML::effectiveToDos( const QDate& start, 366QArray<int> OPimTodoAccessXML::effectiveToDos( const QDate& start,
372 const QDate& end, 367 const QDate& end,
373 bool includeNoDates ) { 368 bool includeNoDates )const {
374 QArray<int> ids( m_events.count() ); 369 QArray<int> ids( m_events.count() );
375 QMap<int, OPimTodo>::Iterator it; 370 QMap<int, OPimTodo>::ConstIterator it;
376 371
377 int i = 0; 372 int i = 0;
378 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 373 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
379 if ( !it.data().hasDueDate() ) { 374 if ( !it.data().hasDueDate() && includeNoDates) {
380 if ( includeNoDates ) { 375 ids[i++] = it.key();
381 ids[i] = it.key();
382 i++;
383 }
384 }else if ( it.data().dueDate() >= start && 376 }else if ( it.data().dueDate() >= start &&
385 it.data().dueDate() <= end ) { 377 it.data().dueDate() <= end ) {
386 ids[i] = it.key(); 378 ids[i++] = it.key();
387 i++;
388 } 379 }
389 } 380 }
390 ids.resize( i ); 381 ids.resize( i );
391 return ids; 382 return ids;
392} 383}
393QArray<int> OPimTodoAccessXML::overDue() { 384QArray<int> OPimTodoAccessXML::overDue()const {
394 QArray<int> ids( m_events.count() ); 385 QArray<int> ids( m_events.count() );
395 int i = 0; 386 int i = 0;
396 387
397 QMap<int, OPimTodo>::Iterator it; 388 QMap<int, OPimTodo>::ConstIterator it;
398 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 389 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
399 if ( it.data().isOverdue() ) { 390 if ( it.data().isOverdue() ) {
400 ids[i] = it.key(); 391 ids[i] = it.key();
401 i++; 392 i++;
402 } 393 }
403 } 394 }
404 ids.resize( i ); 395 ids.resize( i );
405 return ids; 396 return ids;
406} 397}
407 398
408 399
409/* private */ 400/* private */
410void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev, 401void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev,
411 const QCString& attr, const QString& val) { 402 const QCString& attr, const QString& val) {
412// owarn << "parse to do from XMLElement" << oendl;
413 403
414 int *find=0; 404 int *find=0;
415 405
416 find = (*dict)[ attr.data() ]; 406 find = (*dict)[ attr.data() ];
417 if (!find ) { 407 if (!find ) {
418// owarn << "Unknown option" + it.key() << oendl;
419 ev.setCustomField( attr, val ); 408 ev.setCustomField( attr, val );
420 return; 409 return;
421 } 410 }
422 411
423 switch( *find ) { 412 switch( *find ) {
424 case OPimTodo::Uid: 413 case OPimTodo::Uid:
425 ev.setUid( val.toInt() ); 414 ev.setUid( val.toInt() );
426 break; 415 break;
427 case OPimTodo::Category: 416 case OPimTodo::Category:
428 ev.setCategories( ev.idsFromString( val ) ); 417 ev.setCategories( ev.idsFromString( val ) );
429 break; 418 break;
430 case OPimTodo::HasDate: 419 case OPimTodo::HasDate:
431 ev.setHasDueDate( val.toInt() ); 420 ev.setHasDueDate( val.toInt() );
432 break; 421 break;
433 case OPimTodo::Completed: 422 case OPimTodo::Completed:
434 ev.setCompleted( val.toInt() ); 423 ev.setCompleted( val.toInt() );
435 break; 424 break;
436 case OPimTodo::Description: 425 case OPimTodo::Description:
437 ev.setDescription( val ); 426 ev.setDescription( val );
438 break; 427 break;
439 case OPimTodo::Summary: 428 case OPimTodo::Summary:
440 ev.setSummary( val ); 429 ev.setSummary( val );
441 break; 430 break;
442 case OPimTodo::Priority: 431 case OPimTodo::Priority:
443 ev.setPriority( val.toInt() ); 432 ev.setPriority( val.toInt() );
444 break; 433 break;
445 case OPimTodo::DateDay: 434 case OPimTodo::DateDay:
446 m_day = val.toInt(); 435 m_day = val.toInt();
447 break; 436 break;
448 case OPimTodo::DateMonth: 437 case OPimTodo::DateMonth:
449 m_month = val.toInt(); 438 m_month = val.toInt();
450 break; 439 break;
451 case OPimTodo::DateYear: 440 case OPimTodo::DateYear:
452 m_year = val.toInt(); 441 m_year = val.toInt();
453 break; 442 break;
454 case OPimTodo::Progress: 443 case OPimTodo::Progress:
455 ev.setProgress( val.toInt() ); 444 ev.setProgress( val.toInt() );
456 break; 445 break;
457 case OPimTodo::CompletedDate: 446 case OPimTodo::CompletedDate:
458 ev.setCompletedDate( OPimDateConversion::dateFromString( val ) ); 447 ev.setCompletedDate( OPimDateConversion::dateFromString( val ) );
459 break; 448 break;
460 case OPimTodo::StartDate: 449 case OPimTodo::StartDate:
461 ev.setStartDate( OPimDateConversion::dateFromString( val ) ); 450 ev.setStartDate( OPimDateConversion::dateFromString( val ) );
462 break; 451 break;
463 case OPimTodo::State: 452 case OPimTodo::State:
464 ev.setState( val.toInt() ); 453 ev.setState( val.toInt() );
465 break; 454 break;
466 case OPimTodo::Alarms:{ 455 case OPimTodo::Alarms:{
467 OPimNotifyManager &manager = ev.notifiers(); 456 OPimNotifyManager &manager = ev.notifiers();
468 QStringList als = QStringList::split(";", val ); 457 QStringList als = QStringList::split(";", val );
469 for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) { 458 for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) {
470 QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty 459 QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty
471 owarn << "alarm: " << alarm.join("___") << "" << oendl;
472 owarn << "alarm[0]: " << alarm[0] << " " << OPimDateConversion::dateTimeFromString( alarm[0] ).toString() << "" << oendl;
473 OPimAlarm al( alarm[2].toInt(), OPimDateConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() ); 460 OPimAlarm al( alarm[2].toInt(), OPimDateConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() );
474 manager.add( al ); 461 manager.add( al );
475 } 462 }
476 } 463 }
477 break; 464 break;
478 case OPimTodo::Reminders:{ 465 case OPimTodo::Reminders:{
479 OPimNotifyManager &manager = ev.notifiers(); 466 OPimNotifyManager &manager = ev.notifiers();
480 QStringList rems = QStringList::split(";", val ); 467 QStringList rems = QStringList::split(";", val );
481 for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) { 468 for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) {
482 OPimReminder rem( (*it).toInt() ); 469 OPimReminder rem( (*it).toInt() );
483 manager.add( rem ); 470 manager.add( rem );
484 } 471 }
485 } 472 }
486 break; 473 break;
487 case OPimTodo::CrossReference: 474 case OPimTodo::CrossReference:
488 { 475 {
489 /* 476 /*
490 * A cross refernce looks like 477 * A cross refernce looks like
491 * appname,id;appname,id 478 * appname,id;appname,id
492 * we need to split it up 479 * we need to split it up
493 */ 480 */
494 QStringList refs = QStringList::split(';', val ); 481 QStringList refs = QStringList::split(';', val );
495 QStringList::Iterator strIt; 482 QStringList::Iterator strIt;
496 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 483 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
497 int pos = (*strIt).find(','); 484 int pos = (*strIt).find(',');
498 if ( pos > -1 ) 485 if ( pos > -1 )
499 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 486 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
500 487
501 } 488 }
502 break; 489 break;
503 } 490 }
504 /* Recurrence stuff below + post processing later */ 491 /* Recurrence stuff below + post processing later */
505 case FRType: 492 case FRType:
506 if ( val == "Daily" ) 493 if ( val == "Daily" )
507 recur()->setType( OPimRecurrence::Daily ); 494 recur()->setType( OPimRecurrence::Daily );
508 else if ( val == "Weekly" ) 495 else if ( val == "Weekly" )
509 recur()->setType( OPimRecurrence::Weekly); 496 recur()->setType( OPimRecurrence::Weekly);
510 else if ( val == "MonthlyDay" ) 497 else if ( val == "MonthlyDay" )
511 recur()->setType( OPimRecurrence::MonthlyDay ); 498 recur()->setType( OPimRecurrence::MonthlyDay );
512 else if ( val == "MonthlyDate" ) 499 else if ( val == "MonthlyDate" )
513 recur()->setType( OPimRecurrence::MonthlyDate ); 500 recur()->setType( OPimRecurrence::MonthlyDate );
514 else if ( val == "Yearly" ) 501 else if ( val == "Yearly" )
515 recur()->setType( OPimRecurrence::Yearly ); 502 recur()->setType( OPimRecurrence::Yearly );
516 else 503 else
517 recur()->setType( OPimRecurrence::NoRepeat ); 504 recur()->setType( OPimRecurrence::NoRepeat );
518 break; 505 break;
519 case FRWeekdays: 506 case FRWeekdays:
520 recur()->setDays( val.toInt() ); 507 recur()->setDays( val.toInt() );
521 break; 508 break;
522 case FRPosition: 509 case FRPosition:
523 recur()->setPosition( val.toInt() ); 510 recur()->setPosition( val.toInt() );
524 break; 511 break;
525 case FRFreq: 512 case FRFreq:
526 recur()->setFrequency( val.toInt() ); 513 recur()->setFrequency( val.toInt() );
527 break; 514 break;
528 case FRHasEndDate: 515 case FRHasEndDate:
529 recur()->setHasEndDate( val.toInt() ); 516 recur()->setHasEndDate( val.toInt() );
530 break; 517 break;
531 case FREndDate: { 518 case FREndDate: {
532 rp_end = (time_t) val.toLong(); 519 rp_end = (time_t) val.toLong();
533 break; 520 break;
534 } 521 }
535 default: 522 default:
536 ev.setCustomField( attr, val ); 523 ev.setCustomField( attr, val );
537 break; 524 break;
538 } 525 }
539} 526}
540 527
541// from PalmtopRecord... GPL ### FIXME 528// from PalmtopRecord... GPL ### FIXME
542namespace { 529namespace {
543QString customToXml(const QMap<QString, QString>& customMap ) 530QString customToXml(const QMap<QString, QString>& customMap )
544{ 531{
545 //owarn << QString("writing custom %1").arg(customMap.count()) << oendl;
546 QString buf(" "); 532 QString buf(" ");
547 for ( QMap<QString, QString>::ConstIterator cit = customMap.begin(); 533 for ( QMap<QString, QString>::ConstIterator cit = customMap.begin();
548 cit != customMap.end(); ++cit) { 534 cit != customMap.end(); ++cit) {
549// owarn << ".ITEM." << oendl;
550 buf += cit.key(); 535 buf += cit.key();
551 buf += "=\""; 536 buf += "=\"";
552 buf += Qtopia::escapeString(cit.data()); 537 buf += Qtopia::escapeString(cit.data());
553 buf += "\" "; 538 buf += "\" ";
554 } 539 }
555 return buf; 540 return buf;
556} 541}
557 542
558 543
559} 544}
560 545
561QString OPimTodoAccessXML::toString( const OPimTodo& ev )const { 546QString OPimTodoAccessXML::toString( const OPimTodo& ev )const {
562 QString str; 547 QString str;
563 548
564 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 549 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
565 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 550 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
566 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 551 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
567 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 552 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
568 553
569 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 554 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
570 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 555 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
571 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 556 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
572 557
573 if ( ev.hasDueDate() ) { 558 if ( ev.hasDueDate() ) {
574 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 559 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
575 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 560 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
576 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 561 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
577 } 562 }
578// owarn << "Uid " << ev.uid() << "" << oendl;
579 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 563 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
580 564
581// append the extra options 565// append the extra options
582 /* FIXME Qtopia::Record this is currently not 566 /* FIXME Qtopia::Record this is currently not
583 * possible you can set custom fields 567 * possible you can set custom fields
584 * but don' iterate over the list 568 * but don' iterate over the list
585 * I may do #define private protected 569 * I may do #define private protected
586 * for this case - cough --zecke 570 * for this case - cough --zecke
587 */ 571 */
588 /* 572 /*
589 QMap<QString, QString> extras = ev.extras(); 573 QMap<QString, QString> extras = ev.extras();
590 QMap<QString, QString>::Iterator extIt; 574 QMap<QString, QString>::Iterator extIt;
591 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 575 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
592 str += extIt.key() + "=\"" + extIt.data() + "\" "; 576 str += extIt.key() + "=\"" + extIt.data() + "\" ";
593 */ 577 */
594 // cross refernce 578 // cross refernce
595 if ( ev.hasRecurrence() ) { 579 if ( ev.hasRecurrence() ) {
596 str += ev.recurrence().toString(); 580 str += ev.recurrence().toString();
597 } 581 }
598 if ( ev.hasStartDate() ) 582 if ( ev.hasStartDate() )
599 str += "StartDate=\""+ OPimDateConversion::dateToString( ev.startDate() ) +"\" "; 583 str += "StartDate=\""+ OPimDateConversion::dateToString( ev.startDate() ) +"\" ";
600 if ( ev.hasCompletedDate() ) 584 if ( ev.hasCompletedDate() )
601 str += "CompletedDate=\""+ OPimDateConversion::dateToString( ev.completedDate() ) +"\" "; 585 str += "CompletedDate=\""+ OPimDateConversion::dateToString( ev.completedDate() ) +"\" ";
602 if ( ev.hasState() ) 586 if ( ev.hasState() )
603 str += "State=\""+QString::number( ev.state().state() )+"\" "; 587 str += "State=\""+QString::number( ev.state().state() )+"\" ";
604 588
605 /* 589 /*
606 * save reminders and notifiers! 590 * save reminders and notifiers!
607 * DATE_TIME:DURATION:SOUND:NOT_USED_YET;OTHER_DATE_TIME:OTHER_DURATION:SOUND:.... 591 * DATE_TIME:DURATION:SOUND:NOT_USED_YET;OTHER_DATE_TIME:OTHER_DURATION:SOUND:....
608 */ 592 */
609 if ( ev.hasNotifiers() ) { 593 if ( ev.hasNotifiers() ) {
610 OPimNotifyManager manager = ev.notifiers(); 594 OPimNotifyManager manager = ev.notifiers();
611 OPimNotifyManager::Alarms alarms = manager.alarms(); 595 OPimNotifyManager::Alarms alarms = manager.alarms();
612 if (!alarms.isEmpty() ) { 596 if (!alarms.isEmpty() ) {
613 QStringList als; 597 QStringList als;
614 OPimNotifyManager::Alarms::Iterator it = alarms.begin(); 598 OPimNotifyManager::Alarms::Iterator it = alarms.begin();
615 for ( ; it != alarms.end(); ++it ) { 599 for ( ; it != alarms.end(); ++it ) {
616 /* only if time is valid */ 600 /* only if time is valid */
617 if ( (*it).dateTime().isValid() ) { 601 if ( (*it).dateTime().isValid() ) {
618 als << OPimDateConversion::dateTimeToString( (*it).dateTime() ) 602 als << OPimDateConversion::dateTimeToString( (*it).dateTime() )
619 + ":" + QString::number( (*it).duration() ) 603 + ":" + QString::number( (*it).duration() )
620 + ":" + QString::number( (*it).sound() ) 604 + ":" + QString::number( (*it).sound() )
621 + ":"; 605 + ":";
622 } 606 }
623 } 607 }
624 // now write the list 608 // now write the list
625 owarn << "als: " << als.join("____________") << "" << oendl;
626 str += "Alarms=\""+als.join(";") +"\" "; 609 str += "Alarms=\""+als.join(";") +"\" ";
627 } 610 }
628 611
629 /* 612 /*
630 * now the same for reminders but more easy. We just save the uid of the OPimEvent. 613 * now the same for reminders but more easy. We just save the uid of the OPimEvent.
631 */ 614 */
632 OPimNotifyManager::Reminders reminders = manager.reminders(); 615 OPimNotifyManager::Reminders reminders = manager.reminders();
633 if (!reminders.isEmpty() ) { 616 if (!reminders.isEmpty() ) {
634 OPimNotifyManager::Reminders::Iterator it = reminders.begin(); 617 OPimNotifyManager::Reminders::Iterator it = reminders.begin();
635 QStringList records; 618 QStringList records;
636 for ( ; it != reminders.end(); ++it ) { 619 for ( ; it != reminders.end(); ++it ) {
637 records << QString::number( (*it).recordUid() ); 620 records << QString::number( (*it).recordUid() );
638 } 621 }
639 str += "Reminders=\""+ records.join(";") +"\" "; 622 str += "Reminders=\""+ records.join(";") +"\" ";
640 } 623 }
641 } 624 }
642 str += customToXml( ev.toExtraMap() ); 625 str += customToXml( ev.toExtraMap() );
643 626
644 627
645 return str; 628 return str;
646} 629}
647QString OPimTodoAccessXML::toString( const QArray<int>& ints ) const { 630QString OPimTodoAccessXML::toString( const QArray<int>& ints ) const {
648 return Qtopia::Record::idsToString( ints ); 631 return Qtopia::Record::idsToString( ints );
649} 632}
650 633
651/* internal class for sorting
652 *
653 * Inspired by todoxmlio.cpp from TT
654 */
655 634
656struct OPimTodoXMLContainer { 635QArray<int> OPimTodoAccessXML::sorted( const UIDArray& events, bool asc,
657 OPimTodo todo; 636 int sortOrder,int sortFilter,
658}; 637 const QArray<int>& categories )const {
638 Internal::OPimTodoSortVector vector(events.count(), asc,sortOrder );
639 int item = 0;
659 640
660namespace { 641 bool bCat = sortFilter & OPimTodoAccess::FilterCategory ? true : false;
661 inline QString string( const OPimTodo& todo) { 642 bool bOnly = sortFilter & OPimTodoAccess::OnlyOverDue ? true : false;
662 return todo.summary().isEmpty() ? 643 bool comp = sortFilter & OPimTodoAccess::DoNotShowCompleted ? true : false;
663 todo.description().left(20 ) : 644 bool catPassed = false;
664 todo.summary(); 645 int cat;
665 }
666 inline int completed( const OPimTodo& todo1, const OPimTodo& todo2) {
667 int ret = 0;
668 if ( todo1.isCompleted() ) ret++;
669 if ( todo2.isCompleted() ) ret--;
670 return ret;
671 }
672 inline int priority( const OPimTodo& t1, const OPimTodo& t2) {
673 return ( t1.priority() - t2.priority() );
674 }
675 inline int description( const OPimTodo& t1, const OPimTodo& t2) {
676 return QString::compare( string(t1), string(t2) );
677 }
678 inline int deadline( const OPimTodo& t1, const OPimTodo& t2) {
679 int ret = 0;
680 if ( t1.hasDueDate() &&
681 t2.hasDueDate() )
682 ret = t2.dueDate().daysTo( t1.dueDate() );
683 else if ( t1.hasDueDate() )
684 ret = -1;
685 else if ( t2.hasDueDate() )
686 ret = 1;
687 else
688 ret = 0;
689 646
690 return ret; 647 for ( uint i = 0; i < events.count(); ++i ) {
691 } 648 /* Guard against creating a new item... */
649 if ( !m_events.contains( events[i] ) )
650 continue;
692 651
693}; 652 OPimTodo todo = m_events[events[i]];
694 653
695/* 654 /* show category */
696 * Returns: 655 /* -1 == unfiled */
697 * 0 if item1 == item2 656 catPassed = false;
698 * 657 for ( uint cat_nu = 0; cat_nu < categories.count(); ++cat_nu ) {
699 * non-zero if item1 != item2 658 cat = categories[cat_nu];
700 * 659 if ( bCat && cat == -1 ) {
701 * This function returns int rather than bool so that reimplementations 660 if(!todo.categories().isEmpty() )
702 * can return one of three values and use it to sort by: 661 continue;
703 * 662 } else if ( bCat && cat != 0)
704 * 0 if item1 == item2 663 if (!todo.categories().contains( cat ) )
705 * 664 continue;
706 * > 0 (positive integer) if item1 > item2 665 catPassed = true;
707 *
708 * < 0 (negative integer) if item1 < item2
709 *
710 */
711class OPimTodoXMLVector : public QVector<OPimTodoXMLContainer> {
712public:
713 OPimTodoXMLVector(int size, bool asc, int sort)
714 : QVector<OPimTodoXMLContainer>( size )
715 {
716 setAutoDelete( true );
717 m_asc = asc;
718 m_sort = sort;
719 }
720 /* return the summary/description */
721 QString string( const OPimTodo& todo) {
722 return todo.summary().isEmpty() ?
723 todo.description().left(20 ) :
724 todo.summary();
725 }
726 /**
727 * we take the sortorder( switch on it )
728 *
729 */
730 int compareItems( Item d1, Item d2 ) {
731 bool seComp, sePrio, seDesc, seDeadline;
732 seComp = sePrio = seDeadline = seDesc = false;
733 int ret =0;
734 OPimTodoXMLContainer* con1 = (OPimTodoXMLContainer*)d1;
735 OPimTodoXMLContainer* con2 = (OPimTodoXMLContainer*)d2;
736
737 /* same item */
738 if ( con1->todo.uid() == con2->todo.uid() )
739 return 0;
740
741 switch ( m_sort ) {
742 /* completed */
743 case 0: {
744 ret = completed( con1->todo, con2->todo );
745 seComp = TRUE;
746 break;
747 }
748 /* priority */
749 case 1: {
750 ret = priority( con1->todo, con2->todo );
751 sePrio = TRUE;
752 break;
753 }
754 /* description */
755 case 2: {
756 ret = description( con1->todo, con2->todo );
757 seDesc = TRUE;
758 break;
759 }
760 /* deadline */
761 case 3: {
762 ret = deadline( con1->todo, con2->todo );
763 seDeadline = TRUE;
764 break; 666 break;
765 } 667 }
766 default:
767 ret = 0;
768 break;
769 };
770 /*
771 * FIXME do better sorting if the first sort criteria
772 * ret equals 0 start with complete and so on...
773 */
774
775 /* twist it we're not ascending*/
776 if (!m_asc)
777 ret = ret * -1;
778 668
779 if ( ret )
780 return ret;
781
782 // default did not gave difference let's try it other way around
783 /* 669 /*
784 * General try if already checked if not test 670 * If none of the Categories matched
785 * and return 671 * continue
786 * 1.Completed
787 * 2.Priority
788 * 3.Description
789 * 4.DueDate
790 */ 672 */
791 if (!seComp ) { 673 if ( !catPassed )
792 if ( (ret = completed( con1->todo, con2->todo ) ) ) {
793 if (!m_asc ) ret *= -1;
794 return ret;
795 }
796 }
797 if (!sePrio ) {
798 if ( (ret = priority( con1->todo, con2->todo ) ) ) {
799 if (!m_asc ) ret *= -1;
800 return ret;
801 }
802 }
803 if (!seDesc ) {
804 if ( (ret = description(con1->todo, con2->todo ) ) ) {
805 if (!m_asc) ret *= -1;
806 return ret;
807 }
808 }
809 if (!seDeadline) {
810 if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
811 if (!m_asc) ret *= -1;
812 return ret;
813 }
814 }
815
816 return 0;
817 }
818 private:
819 bool m_asc;
820 int m_sort;
821
822};
823
824QArray<int> OPimTodoAccessXML::sorted( bool asc, int sortOrder,
825 int sortFilter, int cat ) {
826 OPimTodoXMLVector vector(m_events.count(), asc,sortOrder );
827 QMap<int, OPimTodo>::Iterator it;
828 int item = 0;
829
830 bool bCat = sortFilter & 1 ? true : false;
831 bool bOnly = sortFilter & 2 ? true : false;
832 bool comp = sortFilter & 4 ? true : false;
833 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
834
835 /* show category */
836 /* -1 == unfiled */
837 if ( bCat && cat == -1 ) {
838 if(!(*it).categories().isEmpty() )
839 continue;
840 }else if ( bCat && cat != 0)
841 if (!(*it).categories().contains( cat ) ) {
842 continue;
843 }
844 /* isOverdue but we should not show overdue - why?*/
845/* if ( (*it).isOverdue() && !bOnly ) {
846 owarn << "item is overdue but !bOnly" << oendl;
847 continue; 674 continue;
848 } 675 if ( !todo.isOverdue() && bOnly )
849*/
850 if ( !(*it).isOverdue() && bOnly ) {
851 continue; 676 continue;
852 } 677 if (todo.isCompleted() && comp )
853
854 if ((*it).isCompleted() && comp ) {
855 continue; 678 continue;
856 }
857 679
858 680 vector.insert(item++, todo );
859 OPimTodoXMLContainer* con = new OPimTodoXMLContainer();
860 con->todo = (*it);
861 vector.insert(item, con );
862 item++;
863 } 681 }
682
864 vector.resize( item ); 683 vector.resize( item );
865 /* sort it now */ 684 /* sort it now */
866 vector.sort(); 685 vector.sort();
867 /* now get the uids */ 686 /* now get the uids */
868 QArray<int> array( vector.count() ); 687 UIDArray array( vector.count() );
869 for (uint i= 0; i < vector.count(); i++ ) { 688 for (uint i= 0; i < vector.count(); i++ )
870 array[i] = ( vector.at(i) )->todo.uid(); 689 array[i] = vector.uidAt( i );
871 } 690
872 return array; 691 return array;
873}; 692}
693
874void OPimTodoAccessXML::removeAllCompleted() { 694void OPimTodoAccessXML::removeAllCompleted() {
875 QMap<int, OPimTodo> events = m_events; 695 QMap<int, OPimTodo> events = m_events;
876 for ( QMap<int, OPimTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { 696 for ( QMap<int, OPimTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
877 if ( (*it).isCompleted() ) 697 if ( (*it).isCompleted() )
878 events.remove( it.key() ); 698 events.remove( it.key() );
879 } 699 }
880 m_events = events; 700 m_events = events;
881} 701}
882QBitArray OPimTodoAccessXML::supports()const { 702
883 static QBitArray ar = sup();
884 return ar;
885}
886QBitArray OPimTodoAccessXML::sup() {
887 QBitArray ar( OPimTodo::CompletedDate +1 );
888 ar.fill( true );
889 ar[OPimTodo::CrossReference] = false;
890 ar[OPimTodo::State ] = false;
891 ar[OPimTodo::Reminders] = false;
892 ar[OPimTodo::Notifiers] = false;
893 ar[OPimTodo::Maintainer] = false;
894
895 return ar;
896}
897QArray<int> OPimTodoAccessXML::matchRegexp( const QRegExp &r ) const 703QArray<int> OPimTodoAccessXML::matchRegexp( const QRegExp &r ) const
898{ 704{
899 QArray<int> m_currentQuery( m_events.count() ); 705 QArray<int> currentQuery( m_events.count() );
900 uint arraycounter = 0; 706 uint arraycounter = 0;
901 707
902 QMap<int, OPimTodo>::ConstIterator it; 708 QMap<int, OPimTodo>::ConstIterator it;
903 for (it = m_events.begin(); it != m_events.end(); ++it ) { 709 for (it = m_events.begin(); it != m_events.end(); ++it ) {
904 if ( it.data().match( r ) ) 710 if ( it.data().match( r ) )
905 m_currentQuery[arraycounter++] = it.data().uid(); 711 currentQuery[arraycounter++] = it.data().uid();
906 712
907 } 713 }
908 // Shrink to fit.. 714 // Shrink to fit..
909 m_currentQuery.resize(arraycounter); 715 currentQuery.resize(arraycounter);
910 716
911 return m_currentQuery; 717 return currentQuery;
912} 718}
913 719
914} 720}
diff --git a/libopie2/opiepim/backend/otodoaccessxml.h b/libopie2/opiepim/backend/otodoaccessxml.h
index 3a51543..134a21a 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.h
+++ b/libopie2/opiepim/backend/otodoaccessxml.h
@@ -1,89 +1,88 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_TODO_ACCESS_XML_H 29#ifndef OPIE_TODO_ACCESS_XML_H
30#define OPIE_TODO_ACCESS_XML_H 30#define OPIE_TODO_ACCESS_XML_H
31 31
32#include <qasciidict.h> 32#include <qasciidict.h>
33#include <qmap.h> 33#include <qmap.h>
34 34
35#include <opie2/otodoaccessbackend.h> 35#include <opie2/otodoaccessbackend.h>
36 36
37namespace Opie { 37namespace Opie {
38 class XMLElement; 38 class XMLElement;
39 39
40class OPimTodoAccessXML : public OPimTodoAccessBackend { 40class OPimTodoAccessXML : public OPimTodoAccessBackend {
41public: 41public:
42 /** 42 /**
43 * fileName if Empty we will use the default path 43 * fileName if Empty we will use the default path
44 */ 44 */
45 OPimTodoAccessXML( const QString& appName, 45 OPimTodoAccessXML( const QString& appName,
46 const QString& fileName = QString::null ); 46 const QString& fileName = QString::null );
47 ~OPimTodoAccessXML(); 47 ~OPimTodoAccessXML();
48 48
49 bool load(); 49 bool load();
50 bool reload(); 50 bool reload();
51 bool save(); 51 bool save();
52 52
53 QArray<int> allRecords()const; 53 QArray<int> allRecords()const;
54 QArray<int> matchRegexp(const QRegExp &r) const; 54 QArray<int> matchRegexp(const QRegExp &r) const;
55 QArray<int> queryByExample( const OPimTodo&, int querysettings, const QDateTime& d = QDateTime() ); 55 QArray<int> queryByExample( const OPimTodo&, int querysettings, const QDateTime& d = QDateTime() );
56 OPimTodo find( int uid )const; 56 OPimTodo find( int uid )const;
57 void clear(); 57 void clear();
58 bool add( const OPimTodo& ); 58 bool add( const OPimTodo& );
59 bool remove( int uid ); 59 bool remove( int uid );
60 void removeAllCompleted(); 60 void removeAllCompleted();
61 bool replace( const OPimTodo& ); 61 bool replace( const OPimTodo& );
62 62
63 /* our functions */ 63 /* our functions */
64 QArray<int> effectiveToDos( const QDate& start, 64 QArray<int> effectiveToDos( const QDate& start,
65 const QDate& end, 65 const QDate& end,
66 bool includeNoDates ); 66 bool includeNoDates )const;
67 QArray<int> overDue(); 67 QArray<int> overDue()const;
68 QArray<int> sorted( bool asc, int sortOrder, 68
69 int sortFilter, int cat ); 69//@{
70 QBitArray supports()const; 70 UIDArray sorted( const UIDArray&, bool, int, int, const QArray<int>& )const;
71//@}
71private: 72private:
72 static QBitArray sup();
73 void todo( QAsciiDict<int>*, OPimTodo&,const QCString&,const QString& ); 73 void todo( QAsciiDict<int>*, OPimTodo&,const QCString&,const QString& );
74 QString toString( const OPimTodo& )const; 74 QString toString( const OPimTodo& )const;
75 QString toString( const QArray<int>& ints ) const; 75 QString toString( const QArray<int>& ints ) const;
76 QMap<int, OPimTodo> m_events; 76 QMap<int, OPimTodo> m_events;
77 QString m_file; 77 QString m_file;
78 QString m_app; 78 QString m_app;
79 bool m_opened : 1; 79 bool m_opened : 1;
80 bool m_changed : 1; 80 bool m_changed : 1;
81 class OPimTodoAccessXMLPrivate; 81 class OPimTodoAccessXMLPrivate;
82 OPimTodoAccessXMLPrivate* d; 82 OPimTodoAccessXMLPrivate* d;
83 int m_year, m_month, m_day; 83 int m_year, m_month, m_day;
84
85}; 84};
86 85
87}; 86};
88 87
89#endif 88#endif