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