summaryrefslogtreecommitdiff
authoreilers <eilers>2003-12-08 15:18:10 (UTC)
committer eilers <eilers>2003-12-08 15:18:10 (UTC)
commit6974a4bbdc674a2a5d41d801f80035a183faedb5 (patch) (unidiff)
tree09a719ef263047e92ffb866da13168b7f7d41f23
parent7f2f736597490fd1592d7ed1f40e4abf824673c0 (diff)
downloadopie-6974a4bbdc674a2a5d41d801f80035a183faedb5.zip
opie-6974a4bbdc674a2a5d41d801f80035a183faedb5.tar.gz
opie-6974a4bbdc674a2a5d41d801f80035a183faedb5.tar.bz2
Committing unfinished sql implementation before merging to libopie2 starts..
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontactaccessbackend_sql.cpp11
-rw-r--r--libopie/pim/ocontactaccessbackend_sql.h5
-rw-r--r--libopie/pim/odatebookaccessbackend_sql.cpp221
-rw-r--r--libopie/pim/odatebookaccessbackend_sql.h60
-rw-r--r--libopie/pim/odatebookaccessbackend_xml.cpp12
-rw-r--r--libopie/pim/oevent.cpp131
-rw-r--r--libopie/pim/oevent.h38
-rw-r--r--libopie/pim/orecur.cpp8
-rw-r--r--libopie/pim/orecur.h1
-rw-r--r--libopie/pim/otodoaccesssql.cpp5
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp11
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.h5
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp221
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_sql.h60
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp12
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.cpp5
-rw-r--r--libopie2/opiepim/core/orecur.cpp8
-rw-r--r--libopie2/opiepim/core/orecur.h1
-rw-r--r--libopie2/opiepim/oevent.cpp131
-rw-r--r--libopie2/opiepim/oevent.h38
20 files changed, 942 insertions, 42 deletions
diff --git a/libopie/pim/ocontactaccessbackend_sql.cpp b/libopie/pim/ocontactaccessbackend_sql.cpp
index 132c9fc..dd9dbde 100644
--- a/libopie/pim/ocontactaccessbackend_sql.cpp
+++ b/libopie/pim/ocontactaccessbackend_sql.cpp
@@ -1,32 +1,35 @@
1/* 1/*
2 * SQL Backend for the OPIE-Contact Database. 2 * SQL Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ===================================================================== 12 * =====================================================================
13 * Version: $Id$ 13 * Version: $Id$
14 * ===================================================================== 14 * =====================================================================
15 * History: 15 * History:
16 * $Log$ 16 * $Log$
17 * Revision 1.3 2003/12/08 15:18:10 eilers
18 * Committing unfinished sql implementation before merging to libopie2 starts..
19 *
17 * Revision 1.2 2003/09/29 07:44:26 eilers 20 * Revision 1.2 2003/09/29 07:44:26 eilers
18 * Improvement of PIM-SQL Databases, but search queries are still limited. 21 * Improvement of PIM-SQL Databases, but search queries are still limited.
19 * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. 22 * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space.
20 * Todo: Started to add new attributes. Some type conversions missing. 23 * Todo: Started to add new attributes. Some type conversions missing.
21 * 24 *
22 * Revision 1.1 2003/09/22 14:31:16 eilers 25 * Revision 1.1 2003/09/22 14:31:16 eilers
23 * Added first experimental incarnation of sql-backend for addressbook. 26 * Added first experimental incarnation of sql-backend for addressbook.
24 * Some modifications to be able to compile the todo sql-backend. 27 * Some modifications to be able to compile the todo sql-backend.
25 * A lot of changes fill follow... 28 * A lot of changes fill follow...
26 * 29 *
27 */ 30 */
28 31
29#include "ocontactaccessbackend_sql.h" 32#include "ocontactaccessbackend_sql.h"
30 33
31#include <qarray.h> 34#include <qarray.h>
32#include <qdatetime.h> 35#include <qdatetime.h>
@@ -441,54 +444,60 @@ namespace {
441 QString FindCustomQuery::query()const{ 444 QString FindCustomQuery::query()const{
442 // if ( m_uids.count() == 0 ) 445 // if ( m_uids.count() == 0 )
443 return single(); 446 return single();
444 } 447 }
445 QString FindCustomQuery::single()const{ 448 QString FindCustomQuery::single()const{
446 QString qu = "select uid, type, value from custom_data where uid = "; 449 QString qu = "select uid, type, value from custom_data where uid = ";
447 qu += QString::number(m_uid); 450 qu += QString::number(m_uid);
448 return qu; 451 return qu;
449 } 452 }
450 453
451}; 454};
452 455
453 456
454/* --------------------------------------------------------------------------- */ 457/* --------------------------------------------------------------------------- */
455 458
456OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, 459OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */,
457 const QString& filename ): m_changed(false) 460 const QString& filename ):
461 OContactAccessBackend(), m_changed(false), m_driver( NULL )
458{ 462{
459 qWarning("C'tor OContactAccessBackend_SQL starts"); 463 qWarning("C'tor OContactAccessBackend_SQL starts");
460 QTime t; 464 QTime t;
461 t.start(); 465 t.start();
462 466
463 /* Expecting to access the default filename if nothing else is set */ 467 /* Expecting to access the default filename if nothing else is set */
464 if ( filename.isEmpty() ){ 468 if ( filename.isEmpty() ){
465 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); 469 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
466 } else 470 } else
467 m_fileName = filename; 471 m_fileName = filename;
468 472
469 // Get the standart sql-driver from the OSQLManager.. 473 // Get the standart sql-driver from the OSQLManager..
470 OSQLManager man; 474 OSQLManager man;
471 m_driver = man.standard(); 475 m_driver = man.standard();
472 m_driver->setUrl( m_fileName ); 476 m_driver->setUrl( m_fileName );
473 477
474 load(); 478 load();
475 479
476 qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); 480 qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() );
477} 481}
478 482
483OContactAccessBackend_SQL::~OContactAccessBackend_SQL ()
484{
485 if( m_driver )
486 delete m_driver;
487}
479 488
480bool OContactAccessBackend_SQL::load () 489bool OContactAccessBackend_SQL::load ()
481{ 490{
482 if (!m_driver->open() ) 491 if (!m_driver->open() )
483 return false; 492 return false;
484 493
485 // Don't expect that the database exists. 494 // Don't expect that the database exists.
486 // It is save here to create the table, even if it 495 // It is save here to create the table, even if it
487 // do exist. ( Is that correct for all databases ?? ) 496 // do exist. ( Is that correct for all databases ?? )
488 CreateQuery creat; 497 CreateQuery creat;
489 OSQLResult res = m_driver->query( &creat ); 498 OSQLResult res = m_driver->query( &creat );
490 499
491 update(); 500 update();
492 501
493 return true; 502 return true;
494 503
diff --git a/libopie/pim/ocontactaccessbackend_sql.h b/libopie/pim/ocontactaccessbackend_sql.h
index bb22551..b8f1d8d 100644
--- a/libopie/pim/ocontactaccessbackend_sql.h
+++ b/libopie/pim/ocontactaccessbackend_sql.h
@@ -3,63 +3,68 @@
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * 12 *
13 * 13 *
14 * ===================================================================== 14 * =====================================================================
15 * Version: $Id$ 15 * Version: $Id$
16 * ===================================================================== 16 * =====================================================================
17 * History: 17 * History:
18 * $Log$ 18 * $Log$
19 * Revision 1.2 2003/12/08 15:18:11 eilers
20 * Committing unfinished sql implementation before merging to libopie2 starts..
21 *
19 * Revision 1.1 2003/09/22 14:31:16 eilers 22 * Revision 1.1 2003/09/22 14:31:16 eilers
20 * Added first experimental incarnation of sql-backend for addressbook. 23 * Added first experimental incarnation of sql-backend for addressbook.
21 * Some modifications to be able to compile the todo sql-backend. 24 * Some modifications to be able to compile the todo sql-backend.
22 * A lot of changes fill follow... 25 * A lot of changes fill follow...
23 * 26 *
24 * 27 *
25 */ 28 */
26 29
27#ifndef _OContactAccessBackend_SQL_ 30#ifndef _OContactAccessBackend_SQL_
28#define _OContactAccessBackend_SQL_ 31#define _OContactAccessBackend_SQL_
29 32
30#include "ocontactaccessbackend.h" 33#include "ocontactaccessbackend.h"
31#include "ocontactaccess.h" 34#include "ocontactaccess.h"
32 35
33#include <qlist.h> 36#include <qlist.h>
34#include <qdict.h> 37#include <qdict.h>
35 38
36class OSQLDriver; 39class OSQLDriver;
37class OSQLResult; 40class OSQLResult;
38class OSQLResultItem; 41class OSQLResultItem;
39 42
40/* the default xml implementation */ 43/* the default xml implementation */
41/** 44/**
42 * This class is the SQL implementation of a Contact backend 45 * This class is the SQL implementation of a Contact backend
43 * it does implement everything available for OContact. 46 * it does implement everything available for OContact.
44 * @see OPimAccessBackend for more information of available methods 47 * @see OPimAccessBackend for more information of available methods
45 */ 48 */
46class OContactAccessBackend_SQL : public OContactAccessBackend { 49class OContactAccessBackend_SQL : public OContactAccessBackend {
47 public: 50 public:
48 OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); 51 OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null );
49 52
53 ~OContactAccessBackend_SQL ();
54
50 bool save(); 55 bool save();
51 56
52 bool load (); 57 bool load ();
53 58
54 void clear (); 59 void clear ();
55 60
56 bool wasChangedExternally(); 61 bool wasChangedExternally();
57 62
58 QArray<int> allRecords() const; 63 QArray<int> allRecords() const;
59 64
60 OContact find ( int uid ) const; 65 OContact find ( int uid ) const;
61 // FIXME: Add lookahead-cache support ! 66 // FIXME: Add lookahead-cache support !
62 //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; 67 //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
63 68
64 QArray<int> queryByExample ( const OContact &query, int settings, 69 QArray<int> queryByExample ( const OContact &query, int settings,
65 const QDateTime& d ); 70 const QDateTime& d );
diff --git a/libopie/pim/odatebookaccessbackend_sql.cpp b/libopie/pim/odatebookaccessbackend_sql.cpp
new file mode 100644
index 0000000..9769bf7
--- a/dev/null
+++ b/libopie/pim/odatebookaccessbackend_sql.cpp
@@ -0,0 +1,221 @@
1/*
2 * SQL Backend for the OPIE-Calender Database.
3 *
4 * Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de)
5 *
6 * =====================================================================
7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * =====================================================================
12 * =====================================================================
13 * Version: $Id$
14 * =====================================================================
15 * History:
16 * $Log$
17 * Revision 1.1 2003/12/08 15:18:12 eilers
18 * Committing unfinished sql implementation before merging to libopie2 starts..
19 *
20 *
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25
26#include <qarray.h>
27#include <qstringlist.h>
28
29#include "orecur.h"
30#include "odatebookaccessbackend_sql.h"
31
32#include <opie2/osqldriver.h>
33#include <opie2/osqlresult.h>
34#include <opie2/osqlmanager.h>
35#include <opie2/osqlquery.h>
36
37namespace {
38
39
40
41};
42
43ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& ,
44 const QString& fileName )
45 : ODateBookAccessBackend(), m_driver( NULL )
46{
47 m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName;
48
49 // Get the standart sql-driver from the OSQLManager..
50 OSQLManager man;
51 m_driver = man.standard();
52 m_driver->setUrl( m_fileName );
53
54 initFields();
55
56 load();
57}
58
59ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() {
60}
61
62void ODateBookAccessBackend_SQL::initFields()
63{
64
65 // This map contains the translation of the fieldtype id's to
66 // the names of the table columns
67 m_fieldMap.insert( OEvent::FUid, "uid" );
68 m_fieldMap.insert( OEvent::FCategories, "Categories" );
69 m_fieldMap.insert( OEvent::FDescription, "Description" );
70 m_fieldMap.insert( OEvent::FLocation, "Location" );
71 m_fieldMap.insert( OEvent::FType, "Type" );
72 m_fieldMap.insert( OEvent::FAlarm, "Alarm" );
73 m_fieldMap.insert( OEvent::FSound, "Sound" );
74 m_fieldMap.insert( OEvent::FRType, "RType" );
75 m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" );
76 m_fieldMap.insert( OEvent::FRPosition, "RPosition" );
77 m_fieldMap.insert( OEvent::FRFreq, "RFreq" );
78 m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" );
79 m_fieldMap.insert( OEvent::FREndDate, "REndDate" );
80 m_fieldMap.insert( OEvent::FRCreated, "RCreated" );
81 m_fieldMap.insert( OEvent::FRExeptions, "RExceptions" );
82 m_fieldMap.insert( OEvent::FStart, "Start" );
83 m_fieldMap.insert( OEvent::FEnd, "End" );
84 m_fieldMap.insert( OEvent::FNote, "Note" );
85 m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" );
86 m_fieldMap.insert( OEvent::FRecParent, "RecParent" );
87 m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" );
88}
89
90bool ODateBookAccessBackend_SQL::load()
91{
92 if (!m_driver->open() )
93 return false;
94
95 // Don't expect that the database exists.
96 // It is save here to create the table, even if it
97 // do exist. ( Is that correct for all databases ?? )
98 QStringqu = "create table datebook( uid INTEGER PRIMARY KEY ";
99
100 QMap<int, QString>::Iterator it;
101 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
102 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( it.data() );
103 }
104 qu += " );";
105
106 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
107
108 OSQLRawQuery raw( qu );
109 OSQLResult res = m_driver->query( &raw );
110 if ( res.state() != OSQLResult::Success )
111 return false;
112
113 update();
114
115 return true;
116}
117
118void ODateBookAccessBackend_SQL::update()
119{
120
121 QString qu = "select uid from datebook";
122 OSQLRawQuery raw( qu );
123 OSQLResult res = m_driver->query( &raw );
124 if ( res.state() != OSQLResult::Success ){
125 m_uids.clear();
126 return;
127 }
128
129 m_uids = extractUids( res );
130
131}
132
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()
153{
154 return load();
155}
156
157bool ODateBookAccessBackend_SQL::save()
158{
159 return m_driver->close();
160}
161
162QArray<int> ODateBookAccessBackend_SQL::allRecords()const
163{
164 return m_uids;
165}
166
167QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) {
168 return QArray<int>();
169}
170
171void ODateBookAccessBackend_SQL::clear()
172{
173 QString qu = "drop table datebook;";
174 qu += "drop table custom_data;";
175
176 OSQLRawQuery raw( qu );
177 OSQLResult res = m_driver->query( &raw );
178
179}
180
181
182OEvent ODateBookAccessBackend_SQL::find( int uid ) const{
183}
184
185bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) {
186 return true;
187}
188bool ODateBookAccessBackend_SQL::remove( int uid ) {
189
190 return true;
191}
192bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) {
193 remove( ev.uid() );
194 return add( ev );
195}
196QArray<int> ODateBookAccessBackend_SQL::rawEvents()const {
197 return allRecords();
198}
199QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const {
200
201 return ints;
202}
203QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const {
204
205 return ints;
206}
207OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() {
208
209 return list;
210}
211OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() {
212
213 return list;
214}
215
216
217QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
218{
219
220 return m_currentQuery;
221}
diff --git a/libopie/pim/odatebookaccessbackend_sql.h b/libopie/pim/odatebookaccessbackend_sql.h
new file mode 100644
index 0000000..85e0d4f
--- a/dev/null
+++ b/libopie/pim/odatebookaccessbackend_sql.h
@@ -0,0 +1,60 @@
1#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H
2#define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H
3
4#include <qmap.h>
5
6#include "odatebookaccessbackend.h"
7
8class OSQLDriver;
9
10/**
11 * This is the default SQL implementation for DateBoook SQL storage
12 * It fully implements the interface
13 * @see ODateBookAccessBackend
14 * @see OPimAccessBackend
15 */
16class ODateBookAccessBackend_SQL : public ODateBookAccessBackend {
17public:
18 ODateBookAccessBackend_SQL( const QString& appName,
19 const QString& fileName = QString::null);
20 ~ODateBookAccessBackend_SQL();
21
22 bool load();
23 bool reload();
24 bool save();
25
26 QArray<int> allRecords()const;
27 QArray<int> matchRegexp(const QRegExp &r) const;
28 QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() );
29 OEvent find( int uid )const;
30 void clear();
31 bool add( const OEvent& ev );
32 bool remove( int uid );
33 bool replace( const OEvent& ev );
34
35 QArray<UID> rawEvents()const;
36 QArray<UID> rawRepeats()const;
37 QArray<UID> nonRepeats()const;
38
39 OEvent::ValueList directNonRepeats();
40 OEvent::ValueList directRawRepeats();
41
42private:
43 bool loadFile();
44 QString m_fileName;
45 QArray<int> m_uids;
46
47 QMap<int, QString> m_fieldMap;
48
49 OSQLDriver* m_driver;
50
51 class Private;
52 Private *d;
53
54 void initFields();
55 void update();
56 QArray<int> extractUids( OSQLResult& res ) const;
57
58};
59
60#endif
diff --git a/libopie/pim/odatebookaccessbackend_xml.cpp b/libopie/pim/odatebookaccessbackend_xml.cpp
index 39c43c5..929d004 100644
--- a/libopie/pim/odatebookaccessbackend_xml.cpp
+++ b/libopie/pim/odatebookaccessbackend_xml.cpp
@@ -64,38 +64,40 @@ namespace {
64 FDescription = 0, 64 FDescription = 0,
65 FLocation, 65 FLocation,
66 FCategories, 66 FCategories,
67 FUid, 67 FUid,
68 FType, 68 FType,
69 FAlarm, 69 FAlarm,
70 FSound, 70 FSound,
71 FRType, 71 FRType,
72 FRWeekdays, 72 FRWeekdays,
73 FRPosition, 73 FRPosition,
74 FRFreq, 74 FRFreq,
75 FRHasEndDate, 75 FRHasEndDate,
76 FREndDate, 76 FREndDate,
77 FRStart, 77 FRStart,
78 FREnd, 78 FREnd,
79 FNote, 79 FNote,
80 FCreated, 80 FCreated, // Should't this be called FRCreated ?
81 FTimeZone, 81 FTimeZone,
82 FRecParent, 82 FRecParent,
83 FRecChildren, 83 FRecChildren,
84 FExceptions 84 FExceptions
85 }; 85 };
86
87 // FIXME: Use OEvent::toMap() here !! (eilers)
86 inline void save( const OEvent& ev, QString& buf ) { 88 inline void save( const OEvent& ev, QString& buf ) {
87 qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); 89 qWarning("Saving %d %s", ev.uid(), ev.description().latin1() );
88 buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; 90 buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\"";
89 if (!ev.location().isEmpty() ) 91 if (!ev.location().isEmpty() )
90 buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; 92 buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\"";
91 93
92 buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; 94 buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\"";
93 buf += " uid=\"" + QString::number( ev.uid() ) + "\""; 95 buf += " uid=\"" + QString::number( ev.uid() ) + "\"";
94 96
95 if (ev.isAllDay() ) 97 if (ev.isAllDay() )
96 buf += " type=\"AllDay\""; // is that all ?? (eilers) 98 buf += " type=\"AllDay\""; // is that all ?? (eilers)
97 99
98 if (ev.hasNotifiers() ) { 100 if (ev.hasNotifiers() ) {
99 OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first 101 OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first
100 int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; 102 int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60;
101 buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; 103 buf += " alarm=\"" + QString::number(minutes) + "\" sound=\"";
@@ -262,33 +264,33 @@ bool ODateBookAccessBackend_XML::add( const OEvent& ev ) {
262 m_changed = true; 264 m_changed = true;
263 if (ev.hasRecurrence() ) 265 if (ev.hasRecurrence() )
264 m_rep.insert( ev.uid(), ev ); 266 m_rep.insert( ev.uid(), ev );
265 else 267 else
266 m_raw.insert( ev.uid(), ev ); 268 m_raw.insert( ev.uid(), ev );
267 269
268 return true; 270 return true;
269} 271}
270bool ODateBookAccessBackend_XML::remove( int uid ) { 272bool ODateBookAccessBackend_XML::remove( int uid ) {
271 m_changed = true; 273 m_changed = true;
272 m_rep.remove( uid ); 274 m_rep.remove( uid );
273 m_rep.remove( uid ); 275 m_rep.remove( uid );
274 276
275 return true; 277 return true;
276} 278}
277bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { 279bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) {
278 replace( ev.uid() ); 280 replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers)
279 return add( ev ); 281 return add( ev );
280} 282}
281QArray<int> ODateBookAccessBackend_XML::rawEvents()const { 283QArray<int> ODateBookAccessBackend_XML::rawEvents()const {
282 return allRecords(); 284 return allRecords();
283} 285}
284QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { 286QArray<int> ODateBookAccessBackend_XML::rawRepeats()const {
285 QArray<int> ints( m_rep.count() ); 287 QArray<int> ints( m_rep.count() );
286 uint i = 0; 288 uint i = 0;
287 QMap<int, OEvent>::ConstIterator it; 289 QMap<int, OEvent>::ConstIterator it;
288 290
289 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { 291 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
290 ints[i] = it.key(); 292 ints[i] = it.key();
291 i++; 293 i++;
292 } 294 }
293 295
294 return ints; 296 return ints;
@@ -308,32 +310,34 @@ QArray<int> ODateBookAccessBackend_XML::nonRepeats()const {
308OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { 310OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() {
309 OEvent::ValueList list; 311 OEvent::ValueList list;
310 QMap<int, OEvent>::ConstIterator it; 312 QMap<int, OEvent>::ConstIterator it;
311 for (it = m_raw.begin(); it != m_raw.end(); ++it ) 313 for (it = m_raw.begin(); it != m_raw.end(); ++it )
312 list.append( it.data() ); 314 list.append( it.data() );
313 315
314 return list; 316 return list;
315} 317}
316OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { 318OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() {
317 OEvent::ValueList list; 319 OEvent::ValueList list;
318 QMap<int, OEvent>::ConstIterator it; 320 QMap<int, OEvent>::ConstIterator it;
319 for (it = m_rep.begin(); it != m_rep.end(); ++it ) 321 for (it = m_rep.begin(); it != m_rep.end(); ++it )
320 list.append( it.data() ); 322 list.append( it.data() );
321 323
322 return list; 324 return list;
323} 325}
326
327// FIXME: Use OEvent::fromMap() (eilers)
324bool ODateBookAccessBackend_XML::loadFile() { 328bool ODateBookAccessBackend_XML::loadFile() {
325 m_changed = false; 329 m_changed = false;
326 330
327 int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); 331 int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY );
328 if ( fd < 0 ) return false; 332 if ( fd < 0 ) return false;
329 333
330 struct stat attribute; 334 struct stat attribute;
331 if ( ::fstat(fd, &attribute ) == -1 ) { 335 if ( ::fstat(fd, &attribute ) == -1 ) {
332 ::close( fd ); 336 ::close( fd );
333 return false; 337 return false;
334 } 338 }
335 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 339 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 );
336 if ( map_addr == ( (caddr_t)-1) ) { 340 if ( map_addr == ( (caddr_t)-1) ) {
337 ::close( fd ); 341 ::close( fd );
338 return false; 342 return false;
339 } 343 }
@@ -346,33 +350,33 @@ bool ODateBookAccessBackend_XML::loadFile() {
346 dict.insert( "description", new int(FDescription) ); 350 dict.insert( "description", new int(FDescription) );
347 dict.insert( "location", new int(FLocation) ); 351 dict.insert( "location", new int(FLocation) );
348 dict.insert( "categories", new int(FCategories) ); 352 dict.insert( "categories", new int(FCategories) );
349 dict.insert( "uid", new int(FUid) ); 353 dict.insert( "uid", new int(FUid) );
350 dict.insert( "type", new int(FType) ); 354 dict.insert( "type", new int(FType) );
351 dict.insert( "alarm", new int(FAlarm) ); 355 dict.insert( "alarm", new int(FAlarm) );
352 dict.insert( "sound", new int(FSound) ); 356 dict.insert( "sound", new int(FSound) );
353 dict.insert( "rtype", new int(FRType) ); 357 dict.insert( "rtype", new int(FRType) );
354 dict.insert( "rweekdays", new int(FRWeekdays) ); 358 dict.insert( "rweekdays", new int(FRWeekdays) );
355 dict.insert( "rposition", new int(FRPosition) ); 359 dict.insert( "rposition", new int(FRPosition) );
356 dict.insert( "rfreq", new int(FRFreq) ); 360 dict.insert( "rfreq", new int(FRFreq) );
357 dict.insert( "rhasenddate", new int(FRHasEndDate) ); 361 dict.insert( "rhasenddate", new int(FRHasEndDate) );
358 dict.insert( "enddt", new int(FREndDate) ); 362 dict.insert( "enddt", new int(FREndDate) );
359 dict.insert( "start", new int(FRStart) ); 363 dict.insert( "start", new int(FRStart) );
360 dict.insert( "end", new int(FREnd) ); 364 dict.insert( "end", new int(FREnd) );
361 dict.insert( "note", new int(FNote) ); 365 dict.insert( "note", new int(FNote) );
362 dict.insert( "created", new int(FCreated) ); 366 dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ??
363 dict.insert( "recparent", new int(FRecParent) ); 367 dict.insert( "recparent", new int(FRecParent) );
364 dict.insert( "recchildren", new int(FRecChildren) ); 368 dict.insert( "recchildren", new int(FRecChildren) );
365 dict.insert( "exceptions", new int(FExceptions) ); 369 dict.insert( "exceptions", new int(FExceptions) );
366 dict.insert( "timezone", new int(FTimeZone) ); 370 dict.insert( "timezone", new int(FTimeZone) );
367 371
368 char* dt = (char*)map_addr; 372 char* dt = (char*)map_addr;
369 int len = attribute.st_size; 373 int len = attribute.st_size;
370 int i = 0; 374 int i = 0;
371 char* point; 375 char* point;
372 const char* collectionString = "<event "; 376 const char* collectionString = "<event ";
373 int strLen = ::strlen(collectionString); 377 int strLen = ::strlen(collectionString);
374 int *find; 378 int *find;
375 while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { 379 while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) {
376 i = point -dt; 380 i = point -dt;
377 i+= strLen; 381 i+= strLen;
378 382
@@ -431,32 +435,34 @@ bool ODateBookAccessBackend_XML::loadFile() {
431 find = dict[attr.data()]; 435 find = dict[attr.data()];
432 if (!find) 436 if (!find)
433 ev.setCustomField( attr, str ); 437 ev.setCustomField( attr, str );
434 else { 438 else {
435 setField( ev, *find, str ); 439 setField( ev, *find, str );
436 } 440 }
437 } 441 }
438 /* time to finalize */ 442 /* time to finalize */
439 finalizeRecord( ev ); 443 finalizeRecord( ev );
440 delete rec; 444 delete rec;
441 } 445 }
442 ::munmap(map_addr, attribute.st_size ); 446 ::munmap(map_addr, attribute.st_size );
443 m_changed = false; // changed during add 447 m_changed = false; // changed during add
444 448
445 return true; 449 return true;
446} 450}
451
452// FIXME: Use OEvent::fromMap() which makes this obsolete.. (eilers)
447void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { 453void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) {
448 /* AllDay is alway in UTC */ 454 /* AllDay is alway in UTC */
449 if ( ev.isAllDay() ) { 455 if ( ev.isAllDay() ) {
450 OTimeZone utc = OTimeZone::utc(); 456 OTimeZone utc = OTimeZone::utc();
451 ev.setStartDateTime( utc.fromUTCDateTime( start ) ); 457 ev.setStartDateTime( utc.fromUTCDateTime( start ) );
452 ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); 458 ev.setEndDateTime ( utc.fromUTCDateTime( end ) );
453 ev.setTimeZone( "UTC"); // make sure it is really utc 459 ev.setTimeZone( "UTC"); // make sure it is really utc
454 }else { 460 }else {
455 /* to current date time */ 461 /* to current date time */
456 // qWarning(" Start is %d", start ); 462 // qWarning(" Start is %d", start );
457 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); 463 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() );
458 QDateTime date = zone.toDateTime( start ); 464 QDateTime date = zone.toDateTime( start );
459 qWarning(" Start is %s", date.toString().latin1() ); 465 qWarning(" Start is %s", date.toString().latin1() );
460 ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); 466 ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) );
461 467
462 date = zone.toDateTime( end ); 468 date = zone.toDateTime( end );
diff --git a/libopie/pim/oevent.cpp b/libopie/pim/oevent.cpp
index 7bcf944..c916297 100644
--- a/libopie/pim/oevent.cpp
+++ b/libopie/pim/oevent.cpp
@@ -1,17 +1,18 @@
1#include <qshared.h> 1#include <qshared.h>
2#include <qarray.h>
2 3
3#include <qpe/palmtopuidgen.h> 4#include <qpe/palmtopuidgen.h>
4#include <qpe/categories.h> 5#include <qpe/categories.h>
5#include <qpe/stringutil.h> 6#include <qpe/stringutil.h>
6 7
7#include "orecur.h" 8#include "orecur.h"
8#include "opimresolver.h" 9#include "opimresolver.h"
9#include "opimnotifymanager.h" 10#include "opimnotifymanager.h"
10 11
11#include "oevent.h" 12#include "oevent.h"
12 13
13int OCalendarHelper::week( const QDate& date) { 14int OCalendarHelper::week( const QDate& date) {
14 // Calculates the week this date is in within that 15 // Calculates the week this date is in within that
15 // month. Equals the "row" is is in in the month view 16 // month. Equals the "row" is is in in the month view
16 int week = 1; 17 int week = 1;
17 QDate tmp( date.year(), date.month(), 1 ); 18 QDate tmp( date.year(), date.month(), 1 );
@@ -343,36 +344,162 @@ void OEvent::changeOrModify() {
343 d2->parent = data->parent; 344 d2->parent = data->parent;
344 345
345 if ( data->child ) { 346 if ( data->child ) {
346 d2->child = new QArray<int>( *data->child ); 347 d2->child = new QArray<int>( *data->child );
347 d2->child->detach(); 348 d2->child->detach();
348 } 349 }
349 350
350 data = d2; 351 data = d2;
351 } 352 }
352} 353}
353void OEvent::deref() { 354void OEvent::deref() {
354 if ( data->deref() ) { 355 if ( data->deref() ) {
355 delete data; 356 delete data;
356 data = 0; 357 data = 0;
357 } 358 }
358} 359}
359// FIXME 360// Exporting Event data to map. Using the same
361// encoding as ODateBookAccessBackend_xml does..
362// Thus, we could remove the stuff there and use this
363// for it and for all other places..
364// Encoding should happen at one place, only ! (eilers)
360QMap<int, QString> OEvent::toMap()const { 365QMap<int, QString> OEvent::toMap()const {
361 return QMap<int, QString>(); 366 QMap<int, QString> retMap;
367
368 retMap.insert( OEvent::FUid, QString::number( uid() ) );
369 retMap.insert( OEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) ));
370 retMap.insert( OEvent::FDescription, Qtopia::escapeString( description() ) );
371 retMap.insert( OEvent::FLocation, Qtopia::escapeString( location() ) );
372 retMap.insert( OEvent::FType, isAllDay() ? "AllDay" : "" );
373 OPimAlarm alarm = notifiers().alarms()[0];
374 retMap.insert( OEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) );
375 retMap.insert( OEvent::FSound, (alarm.sound() == OPimAlarm::Loud) ? "loud" : "silent" );
376
377 OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() );
378 retMap.insert( OEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OTimeZone::utc() ) ) ) );
379 retMap.insert( OEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OTimeZone::utc() ) ) ) );
380 retMap.insert( OEvent::FNote, Qtopia::escapeString( note() ) );
381 retMap.insert( OEvent::FTimeZone, timeZone().isEmpty() ? "None" : timeZone() );
382 if( parent() )
383 retMap.insert( OEvent::FRecParent, QString::number( parent() ) );
384 if( children().count() ){
385 QArray<int> childr = children();
386 QString buf;
387 for ( uint i = 0; i < childr.count(); i++ ) {
388 if ( i != 0 ) buf += " ";
389 buf += QString::number( childr[i] );
390 }
391 retMap.insert( OEvent::FRecChildren, buf );
392 }
393
394 // Add recurrence stuff
395 if( hasRecurrence() ){
396 ORecur recur = recurrence();
397 QMap<int, QString> recFields = recur.toMap();
398 retMap.insert( OEvent::FRType, recFields[ORecur::RType] );
399 retMap.insert( OEvent::FRWeekdays, recFields[ORecur::RWeekdays] );
400 retMap.insert( OEvent::FRPosition, recFields[ORecur::RPosition] );
401 retMap.insert( OEvent::FRFreq, recFields[ORecur::RFreq] );
402 retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] );
403 retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] );
404 retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] );
405 retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] );
406 }
407
408 return retMap;
409}
410
411void OEvent::fromMap( const QMap<int, QString>& map )
412{
413
414 // We just want to set the UID if it is really stored.
415 if ( !map[OEvent::FUid].isEmpty() )
416 setUid( map[OEvent::FUid].toInt() );
417
418 setCategories( idsFromString( map[OEvent::FCategories] ) );
419 setDescription( map[OEvent::FDescription] );
420 setLocation( map[OEvent::FLocation] );
421
422 if ( map[OEvent::FType] == "AllDay" )
423 setAllDay( true );
424 else
425 setAllDay( false );
426
427 int alarmTime = -1;
428 if( !map[OEvent::FAlarm].isEmpty() )
429 alarmTime = map[OEvent::FAlarm].toInt();
430
431 int sound = ( ( map[OEvent::FSound] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent );
432 if ( ( alarmTime != -1 ) ){
433 QDateTime dt = startDateTime().addSecs( -1*alarmTime*60 );
434 OPimAlarm al( sound , dt );
435 notifiers().add( al );
436 }
437 if ( !map[OEvent::FTimeZone].isEmpty() && ( map[OEvent::FTimeZone] != "None" ) ){
438 setTimeZone( map[OEvent::FTimeZone] );
439 }
440
441 time_t start = (time_t) map[OEvent::FStart].toLong();
442 time_t end = (time_t) map[OEvent::FEnd].toLong();
443
444 /* AllDay is always in UTC */
445 if ( isAllDay() ) {
446 OTimeZone utc = OTimeZone::utc();
447 setStartDateTime( utc.fromUTCDateTime( start ) );
448 setEndDateTime ( utc.fromUTCDateTime( end ) );
449 setTimeZone( "UTC"); // make sure it is really utc
450 }else {
451 /* to current date time */
452 // qWarning(" Start is %d", start );
453 OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() );
454 QDateTime date = zone.toDateTime( start );
455 qWarning(" Start is %s", date.toString().latin1() );
456 setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) );
457
458 date = zone.toDateTime( end );
459 setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) );
460 }
461
462 if ( !map[OEvent::FRecParent].isEmpty() )
463 setParent( map[OEvent::FRecParent].toInt() );
464
465 if ( !map[OEvent::FRecChildren].isEmpty() ){
466 QStringList list = QStringList::split(' ', map[OEvent::FRecChildren] );
467 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
468 addChild( (*it).toInt() );
469 }
470 }
471
472 // Fill recurrence stuff and put it directly into the ORecur-Object using fromMap..
473 if( !map[OEvent::FRType].isEmpty() ){
474 QMap<int, QString> recFields;
475 recFields.insert( ORecur::RType, map[OEvent::FRType] );
476 recFields.insert( ORecur::RWeekdays, map[OEvent::FRWeekdays] );
477 recFields.insert( ORecur::RPosition, map[OEvent::FRPosition] );
478 recFields.insert( ORecur::RFreq, map[OEvent::FRFreq] );
479 recFields.insert( ORecur::RHasEndDate, map[OEvent::FRHasEndDate] );
480 recFields.insert( ORecur::EndDate, map[OEvent::FREndDate] );
481 recFields.insert( ORecur::Created, map[OEvent::FRCreated] );
482 recFields.insert( ORecur::Exceptions, map[OEvent::FRExceptions] );
483 ORecur recur( recFields );
484 setRecurrence( recur );
485 }
486
362} 487}
488
489
363int OEvent::parent()const { 490int OEvent::parent()const {
364 return data->parent; 491 return data->parent;
365} 492}
366void OEvent::setParent( int uid ) { 493void OEvent::setParent( int uid ) {
367 changeOrModify(); 494 changeOrModify();
368 data->parent = uid; 495 data->parent = uid;
369} 496}
370QArray<int> OEvent::children() const{ 497QArray<int> OEvent::children() const{
371 if (!data->child) return QArray<int>(); 498 if (!data->child) return QArray<int>();
372 else 499 else
373 return data->child->copy(); 500 return data->child->copy();
374} 501}
375void OEvent::setChildren( const QArray<int>& arr ) { 502void OEvent::setChildren( const QArray<int>& arr ) {
376 changeOrModify(); 503 changeOrModify();
377 if (data->child) delete data->child; 504 if (data->child) delete data->child;
378 505
diff --git a/libopie/pim/oevent.h b/libopie/pim/oevent.h
index 30f442e..9218c97 100644
--- a/libopie/pim/oevent.h
+++ b/libopie/pim/oevent.h
@@ -28,66 +28,75 @@ struct OCalendarHelper {
28 28
29}; 29};
30 30
31class OPimNotifyManager; 31class OPimNotifyManager;
32class ORecur; 32class ORecur;
33 33
34/** 34/**
35 * This is the container for all Events. It encapsules all 35 * This is the container for all Events. It encapsules all
36 * available information for a single Event 36 * available information for a single Event
37 * @short container for events. 37 * @short container for events.
38 */ 38 */
39class OEvent : public OPimRecord { 39class OEvent : public OPimRecord {
40public: 40public:
41 typedef QValueList<OEvent> ValueList; 41 typedef QValueList<OEvent> ValueList;
42 /** 42 /**
43 * RecordFields contain possible attributes 43 * RecordFields contain possible attributes
44 * used in the Results of toMap()..
44 */ 45 */
45 enum RecordFields { 46 enum RecordFields {
46 Uid = Qtopia::UID_ID, 47 FUid = Qtopia::UID_ID,
47 Category = Qtopia::CATEGORY_ID, 48 FCategories = Qtopia::CATEGORY_ID,
48 Description, 49 FDescription = 0,
49 Location, 50 FLocation,
50 Alarm, 51 FType,
51 Reminder, 52 FAlarm,
52 Recurrence, 53 FSound,
53 Note, 54 FRType,
54 Created, 55 FRWeekdays,
55 StartDate, 56 FRPosition,
56 EndDate, 57 FRFreq,
57 AllDay, 58 FRHasEndDate,
58 TimeZone 59 FREndDate,
60 FRCreated,
61 FRExceptions,
62 FStart,
63 FEnd,
64 FNote,
65 FTimeZone,
66 FRecParent,
67 FRecChildren,
59 }; 68 };
60 69
61 /** 70 /**
62 * Start with an Empty OEvent. UID == 0 means that it is empty 71 * Start with an Empty OEvent. UID == 0 means that it is empty
63 */ 72 */
64 OEvent(int uid = 0); 73 OEvent(int uid = 0);
65 74
66 /** 75 /**
67 * copy c'tor 76 * copy c'tor
68 */ 77 */
69 OEvent( const OEvent& ); 78 OEvent( const OEvent& );
70 ~OEvent(); 79 ~OEvent();
71 OEvent &operator=( const OEvent& ); 80 OEvent &operator=( const OEvent& );
72 81
73 QString description()const; 82 QString description()const;
74 void setDescription( const QString& description ); 83 void setDescription( const QString& description );
75 84
76 QString location()const; 85 QString location()const;
77 void setLocation( const QString& loc ); 86 void setLocation( const QString& loc );
78 87
79 bool hasNotifiers()const; 88 bool hasNotifiers()const;
80 OPimNotifyManager &notifiers()const; 89 OPimNotifyManager &notifiers()const;
81 90
82 ORecur recurrence()const; 91 ORecur recurrence()const;
83 void setRecurrence( const ORecur& ); 92 void setRecurrence( const ORecur& );
84 bool hasRecurrence()const; 93 bool hasRecurrence()const;
85 94
86 QString note()const; 95 QString note()const;
87 void setNote( const QString& note ); 96 void setNote( const QString& note );
88 97
89 98
90 QDateTime createdDateTime()const; 99 QDateTime createdDateTime()const;
91 void setCreatedDateTime( const QDateTime& dt); 100 void setCreatedDateTime( const QDateTime& dt);
92 101
93 /** set the date to dt. dt is the QDateTime in localtime */ 102 /** set the date to dt. dt is the QDateTime in localtime */
@@ -119,32 +128,33 @@ public:
119 QArray<int> children()const; 128 QArray<int> children()const;
120 void setChildren( const QArray<int>& ); 129 void setChildren( const QArray<int>& );
121 void addChild( int uid ); 130 void addChild( int uid );
122 void removeChild( int uid ); 131 void removeChild( int uid );
123 132
124 /** return the parent OEvent */ 133 /** return the parent OEvent */
125 int parent()const; 134 int parent()const;
126 void setParent( int uid ); 135 void setParent( int uid );
127 136
128 137
129 /* needed reimp */ 138 /* needed reimp */
130 QString toRichText()const; 139 QString toRichText()const;
131 QString toShortText()const; 140 QString toShortText()const;
132 QString type()const; 141 QString type()const;
133 142
134 QMap<int, QString> toMap()const; 143 QMap<int, QString> toMap()const;
144 void fromMap( const QMap<int, QString>& map );
135 QString recordField(int )const; 145 QString recordField(int )const;
136 146
137 static int rtti(); 147 static int rtti();
138 148
139 bool loadFromStream( QDataStream& ); 149 bool loadFromStream( QDataStream& );
140 bool saveToStream( QDataStream& )const; 150 bool saveToStream( QDataStream& )const;
141 151
142/* bool operator==( const OEvent& ); 152/* bool operator==( const OEvent& );
143 bool operator!=( const OEvent& ); 153 bool operator!=( const OEvent& );
144 bool operator<( const OEvent& ); 154 bool operator<( const OEvent& );
145 bool operator<=( const OEvent& ); 155 bool operator<=( const OEvent& );
146 bool operator>( const OEvent& ); 156 bool operator>( const OEvent& );
147 bool operator>=(const OEvent& ); 157 bool operator>=(const OEvent& );
148*/ 158*/
149private: 159private:
150 inline void changeOrModify(); 160 inline void changeOrModify();
diff --git a/libopie/pim/orecur.cpp b/libopie/pim/orecur.cpp
index 8c9ad46..f46f22e 100644
--- a/libopie/pim/orecur.cpp
+++ b/libopie/pim/orecur.cpp
@@ -21,32 +21,40 @@ struct ORecur::Data : public QShared {
21 ORecur::RepeatType type; 21 ORecur::RepeatType type;
22 int freq; 22 int freq;
23 int pos; 23 int pos;
24 bool hasEnd : 1; 24 bool hasEnd : 1;
25 QDate end; 25 QDate end;
26 QDateTime create; 26 QDateTime create;
27 int rep; 27 int rep;
28 QString app; 28 QString app;
29 ExceptionList list; 29 ExceptionList list;
30 QDate start; 30 QDate start;
31}; 31};
32 32
33 33
34ORecur::ORecur() { 34ORecur::ORecur() {
35 data = new Data; 35 data = new Data;
36} 36}
37
38ORecur::ORecur( const QMap<int, QString>& map )
39{
40 ORecur();
41 fromMap( map );
42}
43
44
37ORecur::ORecur( const ORecur& rec) 45ORecur::ORecur( const ORecur& rec)
38 : data( rec.data ) 46 : data( rec.data )
39{ 47{
40 data->ref(); 48 data->ref();
41} 49}
42ORecur::~ORecur() { 50ORecur::~ORecur() {
43 if ( data->deref() ) { 51 if ( data->deref() ) {
44 delete data; 52 delete data;
45 data = 0l; 53 data = 0l;
46 } 54 }
47} 55}
48void ORecur::deref() { 56void ORecur::deref() {
49 if ( data->deref() ) { 57 if ( data->deref() ) {
50 delete data; 58 delete data;
51 data = 0l; 59 data = 0l;
52 } 60 }
diff --git a/libopie/pim/orecur.h b/libopie/pim/orecur.h
index 47901b0..7750c12 100644
--- a/libopie/pim/orecur.h
+++ b/libopie/pim/orecur.h
@@ -9,32 +9,33 @@
9 9
10#include <qdatetime.h> 10#include <qdatetime.h>
11#include <qvaluelist.h> 11#include <qvaluelist.h>
12#include <qmap.h> 12#include <qmap.h>
13 13
14class ORecur { 14class ORecur {
15public: 15public:
16 typedef QValueList<QDate> ExceptionList; 16 typedef QValueList<QDate> ExceptionList;
17 enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, 17 enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay,
18 MonthlyDate, Yearly }; 18 MonthlyDate, Yearly };
19 enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, 19 enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08,
20 FRI = 0x10, SAT = 0x20, SUN = 0x40 }; 20 FRI = 0x10, SAT = 0x20, SUN = 0x40 };
21 enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate, 21 enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate,
22 EndDate, Created, Exceptions }; 22 EndDate, Created, Exceptions };
23 23
24 ORecur(); 24 ORecur();
25 ORecur( const QMap<int, QString>& map );
25 ORecur( const ORecur& ); 26 ORecur( const ORecur& );
26 ~ORecur(); 27 ~ORecur();
27 28
28 ORecur &operator=( const ORecur& ); 29 ORecur &operator=( const ORecur& );
29 bool operator==(const ORecur& )const; 30 bool operator==(const ORecur& )const;
30 31
31 bool doesRecur()const; 32 bool doesRecur()const;
32 /* if it recurrs on that day */ 33 /* if it recurrs on that day */
33 bool doesRecur( const QDate& ); 34 bool doesRecur( const QDate& );
34 RepeatType type()const; 35 RepeatType type()const;
35 int frequency()const; 36 int frequency()const;
36 int position()const; 37 int position()const;
37 char days()const; 38 char days()const;
38 bool hasEndDate()const; 39 bool hasEndDate()const;
39 QDate start()const; 40 QDate start()const;
40 QDate endDate()const; 41 QDate endDate()const;
diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp
index 3913661..75a0860 100644
--- a/libopie/pim/otodoaccesssql.cpp
+++ b/libopie/pim/otodoaccesssql.cpp
@@ -286,45 +286,48 @@ namespace {
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_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 )
315 delete m_driver;
314} 316}
317
315bool OTodoAccessBackendSQL::load(){ 318bool OTodoAccessBackendSQL::load(){
316 if (!m_driver->open() ) 319 if (!m_driver->open() )
317 return false; 320 return false;
318 321
319 CreateQuery creat; 322 CreateQuery creat;
320 OSQLResult res = m_driver->query(&creat ); 323 OSQLResult res = m_driver->query(&creat );
321 324
322 m_dirty = true; 325 m_dirty = true;
323 return true; 326 return true;
324} 327}
325bool OTodoAccessBackendSQL::reload(){ 328bool OTodoAccessBackendSQL::reload(){
326 return load(); 329 return load();
327} 330}
328 331
329bool OTodoAccessBackendSQL::save(){ 332bool OTodoAccessBackendSQL::save(){
330 return m_driver->close(); 333 return m_driver->close();
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
index 132c9fc..dd9dbde 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
@@ -1,32 +1,35 @@
1/* 1/*
2 * SQL Backend for the OPIE-Contact Database. 2 * SQL Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ===================================================================== 12 * =====================================================================
13 * Version: $Id$ 13 * Version: $Id$
14 * ===================================================================== 14 * =====================================================================
15 * History: 15 * History:
16 * $Log$ 16 * $Log$
17 * Revision 1.3 2003/12/08 15:18:10 eilers
18 * Committing unfinished sql implementation before merging to libopie2 starts..
19 *
17 * Revision 1.2 2003/09/29 07:44:26 eilers 20 * Revision 1.2 2003/09/29 07:44:26 eilers
18 * Improvement of PIM-SQL Databases, but search queries are still limited. 21 * Improvement of PIM-SQL Databases, but search queries are still limited.
19 * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. 22 * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space.
20 * Todo: Started to add new attributes. Some type conversions missing. 23 * Todo: Started to add new attributes. Some type conversions missing.
21 * 24 *
22 * Revision 1.1 2003/09/22 14:31:16 eilers 25 * Revision 1.1 2003/09/22 14:31:16 eilers
23 * Added first experimental incarnation of sql-backend for addressbook. 26 * Added first experimental incarnation of sql-backend for addressbook.
24 * Some modifications to be able to compile the todo sql-backend. 27 * Some modifications to be able to compile the todo sql-backend.
25 * A lot of changes fill follow... 28 * A lot of changes fill follow...
26 * 29 *
27 */ 30 */
28 31
29#include "ocontactaccessbackend_sql.h" 32#include "ocontactaccessbackend_sql.h"
30 33
31#include <qarray.h> 34#include <qarray.h>
32#include <qdatetime.h> 35#include <qdatetime.h>
@@ -441,54 +444,60 @@ namespace {
441 QString FindCustomQuery::query()const{ 444 QString FindCustomQuery::query()const{
442 // if ( m_uids.count() == 0 ) 445 // if ( m_uids.count() == 0 )
443 return single(); 446 return single();
444 } 447 }
445 QString FindCustomQuery::single()const{ 448 QString FindCustomQuery::single()const{
446 QString qu = "select uid, type, value from custom_data where uid = "; 449 QString qu = "select uid, type, value from custom_data where uid = ";
447 qu += QString::number(m_uid); 450 qu += QString::number(m_uid);
448 return qu; 451 return qu;
449 } 452 }
450 453
451}; 454};
452 455
453 456
454/* --------------------------------------------------------------------------- */ 457/* --------------------------------------------------------------------------- */
455 458
456OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, 459OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */,
457 const QString& filename ): m_changed(false) 460 const QString& filename ):
461 OContactAccessBackend(), m_changed(false), m_driver( NULL )
458{ 462{
459 qWarning("C'tor OContactAccessBackend_SQL starts"); 463 qWarning("C'tor OContactAccessBackend_SQL starts");
460 QTime t; 464 QTime t;
461 t.start(); 465 t.start();
462 466
463 /* Expecting to access the default filename if nothing else is set */ 467 /* Expecting to access the default filename if nothing else is set */
464 if ( filename.isEmpty() ){ 468 if ( filename.isEmpty() ){
465 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); 469 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
466 } else 470 } else
467 m_fileName = filename; 471 m_fileName = filename;
468 472
469 // Get the standart sql-driver from the OSQLManager.. 473 // Get the standart sql-driver from the OSQLManager..
470 OSQLManager man; 474 OSQLManager man;
471 m_driver = man.standard(); 475 m_driver = man.standard();
472 m_driver->setUrl( m_fileName ); 476 m_driver->setUrl( m_fileName );
473 477
474 load(); 478 load();
475 479
476 qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); 480 qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() );
477} 481}
478 482
483OContactAccessBackend_SQL::~OContactAccessBackend_SQL ()
484{
485 if( m_driver )
486 delete m_driver;
487}
479 488
480bool OContactAccessBackend_SQL::load () 489bool OContactAccessBackend_SQL::load ()
481{ 490{
482 if (!m_driver->open() ) 491 if (!m_driver->open() )
483 return false; 492 return false;
484 493
485 // Don't expect that the database exists. 494 // Don't expect that the database exists.
486 // It is save here to create the table, even if it 495 // It is save here to create the table, even if it
487 // do exist. ( Is that correct for all databases ?? ) 496 // do exist. ( Is that correct for all databases ?? )
488 CreateQuery creat; 497 CreateQuery creat;
489 OSQLResult res = m_driver->query( &creat ); 498 OSQLResult res = m_driver->query( &creat );
490 499
491 update(); 500 update();
492 501
493 return true; 502 return true;
494 503
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
index bb22551..b8f1d8d 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
@@ -3,63 +3,68 @@
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * 12 *
13 * 13 *
14 * ===================================================================== 14 * =====================================================================
15 * Version: $Id$ 15 * Version: $Id$
16 * ===================================================================== 16 * =====================================================================
17 * History: 17 * History:
18 * $Log$ 18 * $Log$
19 * Revision 1.2 2003/12/08 15:18:11 eilers
20 * Committing unfinished sql implementation before merging to libopie2 starts..
21 *
19 * Revision 1.1 2003/09/22 14:31:16 eilers 22 * Revision 1.1 2003/09/22 14:31:16 eilers
20 * Added first experimental incarnation of sql-backend for addressbook. 23 * Added first experimental incarnation of sql-backend for addressbook.
21 * Some modifications to be able to compile the todo sql-backend. 24 * Some modifications to be able to compile the todo sql-backend.
22 * A lot of changes fill follow... 25 * A lot of changes fill follow...
23 * 26 *
24 * 27 *
25 */ 28 */
26 29
27#ifndef _OContactAccessBackend_SQL_ 30#ifndef _OContactAccessBackend_SQL_
28#define _OContactAccessBackend_SQL_ 31#define _OContactAccessBackend_SQL_
29 32
30#include "ocontactaccessbackend.h" 33#include "ocontactaccessbackend.h"
31#include "ocontactaccess.h" 34#include "ocontactaccess.h"
32 35
33#include <qlist.h> 36#include <qlist.h>
34#include <qdict.h> 37#include <qdict.h>
35 38
36class OSQLDriver; 39class OSQLDriver;
37class OSQLResult; 40class OSQLResult;
38class OSQLResultItem; 41class OSQLResultItem;
39 42
40/* the default xml implementation */ 43/* the default xml implementation */
41/** 44/**
42 * This class is the SQL implementation of a Contact backend 45 * This class is the SQL implementation of a Contact backend
43 * it does implement everything available for OContact. 46 * it does implement everything available for OContact.
44 * @see OPimAccessBackend for more information of available methods 47 * @see OPimAccessBackend for more information of available methods
45 */ 48 */
46class OContactAccessBackend_SQL : public OContactAccessBackend { 49class OContactAccessBackend_SQL : public OContactAccessBackend {
47 public: 50 public:
48 OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); 51 OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null );
49 52
53 ~OContactAccessBackend_SQL ();
54
50 bool save(); 55 bool save();
51 56
52 bool load (); 57 bool load ();
53 58
54 void clear (); 59 void clear ();
55 60
56 bool wasChangedExternally(); 61 bool wasChangedExternally();
57 62
58 QArray<int> allRecords() const; 63 QArray<int> allRecords() const;
59 64
60 OContact find ( int uid ) const; 65 OContact find ( int uid ) const;
61 // FIXME: Add lookahead-cache support ! 66 // FIXME: Add lookahead-cache support !
62 //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; 67 //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
63 68
64 QArray<int> queryByExample ( const OContact &query, int settings, 69 QArray<int> queryByExample ( const OContact &query, int settings,
65 const QDateTime& d ); 70 const QDateTime& d );
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp
new file mode 100644
index 0000000..9769bf7
--- a/dev/null
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp
@@ -0,0 +1,221 @@
1/*
2 * SQL Backend for the OPIE-Calender Database.
3 *
4 * Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de)
5 *
6 * =====================================================================
7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * =====================================================================
12 * =====================================================================
13 * Version: $Id$
14 * =====================================================================
15 * History:
16 * $Log$
17 * Revision 1.1 2003/12/08 15:18:12 eilers
18 * Committing unfinished sql implementation before merging to libopie2 starts..
19 *
20 *
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25
26#include <qarray.h>
27#include <qstringlist.h>
28
29#include "orecur.h"
30#include "odatebookaccessbackend_sql.h"
31
32#include <opie2/osqldriver.h>
33#include <opie2/osqlresult.h>
34#include <opie2/osqlmanager.h>
35#include <opie2/osqlquery.h>
36
37namespace {
38
39
40
41};
42
43ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& ,
44 const QString& fileName )
45 : ODateBookAccessBackend(), m_driver( NULL )
46{
47 m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName;
48
49 // Get the standart sql-driver from the OSQLManager..
50 OSQLManager man;
51 m_driver = man.standard();
52 m_driver->setUrl( m_fileName );
53
54 initFields();
55
56 load();
57}
58
59ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() {
60}
61
62void ODateBookAccessBackend_SQL::initFields()
63{
64
65 // This map contains the translation of the fieldtype id's to
66 // the names of the table columns
67 m_fieldMap.insert( OEvent::FUid, "uid" );
68 m_fieldMap.insert( OEvent::FCategories, "Categories" );
69 m_fieldMap.insert( OEvent::FDescription, "Description" );
70 m_fieldMap.insert( OEvent::FLocation, "Location" );
71 m_fieldMap.insert( OEvent::FType, "Type" );
72 m_fieldMap.insert( OEvent::FAlarm, "Alarm" );
73 m_fieldMap.insert( OEvent::FSound, "Sound" );
74 m_fieldMap.insert( OEvent::FRType, "RType" );
75 m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" );
76 m_fieldMap.insert( OEvent::FRPosition, "RPosition" );
77 m_fieldMap.insert( OEvent::FRFreq, "RFreq" );
78 m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" );
79 m_fieldMap.insert( OEvent::FREndDate, "REndDate" );
80 m_fieldMap.insert( OEvent::FRCreated, "RCreated" );
81 m_fieldMap.insert( OEvent::FRExeptions, "RExceptions" );
82 m_fieldMap.insert( OEvent::FStart, "Start" );
83 m_fieldMap.insert( OEvent::FEnd, "End" );
84 m_fieldMap.insert( OEvent::FNote, "Note" );
85 m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" );
86 m_fieldMap.insert( OEvent::FRecParent, "RecParent" );
87 m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" );
88}
89
90bool ODateBookAccessBackend_SQL::load()
91{
92 if (!m_driver->open() )
93 return false;
94
95 // Don't expect that the database exists.
96 // It is save here to create the table, even if it
97 // do exist. ( Is that correct for all databases ?? )
98 QStringqu = "create table datebook( uid INTEGER PRIMARY KEY ";
99
100 QMap<int, QString>::Iterator it;
101 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
102 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( it.data() );
103 }
104 qu += " );";
105
106 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
107
108 OSQLRawQuery raw( qu );
109 OSQLResult res = m_driver->query( &raw );
110 if ( res.state() != OSQLResult::Success )
111 return false;
112
113 update();
114
115 return true;
116}
117
118void ODateBookAccessBackend_SQL::update()
119{
120
121 QString qu = "select uid from datebook";
122 OSQLRawQuery raw( qu );
123 OSQLResult res = m_driver->query( &raw );
124 if ( res.state() != OSQLResult::Success ){
125 m_uids.clear();
126 return;
127 }
128
129 m_uids = extractUids( res );
130
131}
132
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()
153{
154 return load();
155}
156
157bool ODateBookAccessBackend_SQL::save()
158{
159 return m_driver->close();
160}
161
162QArray<int> ODateBookAccessBackend_SQL::allRecords()const
163{
164 return m_uids;
165}
166
167QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) {
168 return QArray<int>();
169}
170
171void ODateBookAccessBackend_SQL::clear()
172{
173 QString qu = "drop table datebook;";
174 qu += "drop table custom_data;";
175
176 OSQLRawQuery raw( qu );
177 OSQLResult res = m_driver->query( &raw );
178
179}
180
181
182OEvent ODateBookAccessBackend_SQL::find( int uid ) const{
183}
184
185bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) {
186 return true;
187}
188bool ODateBookAccessBackend_SQL::remove( int uid ) {
189
190 return true;
191}
192bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) {
193 remove( ev.uid() );
194 return add( ev );
195}
196QArray<int> ODateBookAccessBackend_SQL::rawEvents()const {
197 return allRecords();
198}
199QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const {
200
201 return ints;
202}
203QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const {
204
205 return ints;
206}
207OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() {
208
209 return list;
210}
211OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() {
212
213 return list;
214}
215
216
217QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
218{
219
220 return m_currentQuery;
221}
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h
new file mode 100644
index 0000000..85e0d4f
--- a/dev/null
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h
@@ -0,0 +1,60 @@
1#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H
2#define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H
3
4#include <qmap.h>
5
6#include "odatebookaccessbackend.h"
7
8class OSQLDriver;
9
10/**
11 * This is the default SQL implementation for DateBoook SQL storage
12 * It fully implements the interface
13 * @see ODateBookAccessBackend
14 * @see OPimAccessBackend
15 */
16class ODateBookAccessBackend_SQL : public ODateBookAccessBackend {
17public:
18 ODateBookAccessBackend_SQL( const QString& appName,
19 const QString& fileName = QString::null);
20 ~ODateBookAccessBackend_SQL();
21
22 bool load();
23 bool reload();
24 bool save();
25
26 QArray<int> allRecords()const;
27 QArray<int> matchRegexp(const QRegExp &r) const;
28 QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() );
29 OEvent find( int uid )const;
30 void clear();
31 bool add( const OEvent& ev );
32 bool remove( int uid );
33 bool replace( const OEvent& ev );
34
35 QArray<UID> rawEvents()const;
36 QArray<UID> rawRepeats()const;
37 QArray<UID> nonRepeats()const;
38
39 OEvent::ValueList directNonRepeats();
40 OEvent::ValueList directRawRepeats();
41
42private:
43 bool loadFile();
44 QString m_fileName;
45 QArray<int> m_uids;
46
47 QMap<int, QString> m_fieldMap;
48
49 OSQLDriver* m_driver;
50
51 class Private;
52 Private *d;
53
54 void initFields();
55 void update();
56 QArray<int> extractUids( OSQLResult& res ) const;
57
58};
59
60#endif
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
index 39c43c5..929d004 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
@@ -64,38 +64,40 @@ namespace {
64 FDescription = 0, 64 FDescription = 0,
65 FLocation, 65 FLocation,
66 FCategories, 66 FCategories,
67 FUid, 67 FUid,
68 FType, 68 FType,
69 FAlarm, 69 FAlarm,
70 FSound, 70 FSound,
71 FRType, 71 FRType,
72 FRWeekdays, 72 FRWeekdays,
73 FRPosition, 73 FRPosition,
74 FRFreq, 74 FRFreq,
75 FRHasEndDate, 75 FRHasEndDate,
76 FREndDate, 76 FREndDate,
77 FRStart, 77 FRStart,
78 FREnd, 78 FREnd,
79 FNote, 79 FNote,
80 FCreated, 80 FCreated, // Should't this be called FRCreated ?
81 FTimeZone, 81 FTimeZone,
82 FRecParent, 82 FRecParent,
83 FRecChildren, 83 FRecChildren,
84 FExceptions 84 FExceptions
85 }; 85 };
86
87 // FIXME: Use OEvent::toMap() here !! (eilers)
86 inline void save( const OEvent& ev, QString& buf ) { 88 inline void save( const OEvent& ev, QString& buf ) {
87 qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); 89 qWarning("Saving %d %s", ev.uid(), ev.description().latin1() );
88 buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; 90 buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\"";
89 if (!ev.location().isEmpty() ) 91 if (!ev.location().isEmpty() )
90 buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; 92 buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\"";
91 93
92 buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; 94 buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\"";
93 buf += " uid=\"" + QString::number( ev.uid() ) + "\""; 95 buf += " uid=\"" + QString::number( ev.uid() ) + "\"";
94 96
95 if (ev.isAllDay() ) 97 if (ev.isAllDay() )
96 buf += " type=\"AllDay\""; // is that all ?? (eilers) 98 buf += " type=\"AllDay\""; // is that all ?? (eilers)
97 99
98 if (ev.hasNotifiers() ) { 100 if (ev.hasNotifiers() ) {
99 OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first 101 OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first
100 int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; 102 int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60;
101 buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; 103 buf += " alarm=\"" + QString::number(minutes) + "\" sound=\"";
@@ -262,33 +264,33 @@ bool ODateBookAccessBackend_XML::add( const OEvent& ev ) {
262 m_changed = true; 264 m_changed = true;
263 if (ev.hasRecurrence() ) 265 if (ev.hasRecurrence() )
264 m_rep.insert( ev.uid(), ev ); 266 m_rep.insert( ev.uid(), ev );
265 else 267 else
266 m_raw.insert( ev.uid(), ev ); 268 m_raw.insert( ev.uid(), ev );
267 269
268 return true; 270 return true;
269} 271}
270bool ODateBookAccessBackend_XML::remove( int uid ) { 272bool ODateBookAccessBackend_XML::remove( int uid ) {
271 m_changed = true; 273 m_changed = true;
272 m_rep.remove( uid ); 274 m_rep.remove( uid );
273 m_rep.remove( uid ); 275 m_rep.remove( uid );
274 276
275 return true; 277 return true;
276} 278}
277bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { 279bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) {
278 replace( ev.uid() ); 280 replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers)
279 return add( ev ); 281 return add( ev );
280} 282}
281QArray<int> ODateBookAccessBackend_XML::rawEvents()const { 283QArray<int> ODateBookAccessBackend_XML::rawEvents()const {
282 return allRecords(); 284 return allRecords();
283} 285}
284QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { 286QArray<int> ODateBookAccessBackend_XML::rawRepeats()const {
285 QArray<int> ints( m_rep.count() ); 287 QArray<int> ints( m_rep.count() );
286 uint i = 0; 288 uint i = 0;
287 QMap<int, OEvent>::ConstIterator it; 289 QMap<int, OEvent>::ConstIterator it;
288 290
289 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { 291 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
290 ints[i] = it.key(); 292 ints[i] = it.key();
291 i++; 293 i++;
292 } 294 }
293 295
294 return ints; 296 return ints;
@@ -308,32 +310,34 @@ QArray<int> ODateBookAccessBackend_XML::nonRepeats()const {
308OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { 310OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() {
309 OEvent::ValueList list; 311 OEvent::ValueList list;
310 QMap<int, OEvent>::ConstIterator it; 312 QMap<int, OEvent>::ConstIterator it;
311 for (it = m_raw.begin(); it != m_raw.end(); ++it ) 313 for (it = m_raw.begin(); it != m_raw.end(); ++it )
312 list.append( it.data() ); 314 list.append( it.data() );
313 315
314 return list; 316 return list;
315} 317}
316OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { 318OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() {
317 OEvent::ValueList list; 319 OEvent::ValueList list;
318 QMap<int, OEvent>::ConstIterator it; 320 QMap<int, OEvent>::ConstIterator it;
319 for (it = m_rep.begin(); it != m_rep.end(); ++it ) 321 for (it = m_rep.begin(); it != m_rep.end(); ++it )
320 list.append( it.data() ); 322 list.append( it.data() );
321 323
322 return list; 324 return list;
323} 325}
326
327// FIXME: Use OEvent::fromMap() (eilers)
324bool ODateBookAccessBackend_XML::loadFile() { 328bool ODateBookAccessBackend_XML::loadFile() {
325 m_changed = false; 329 m_changed = false;
326 330
327 int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); 331 int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY );
328 if ( fd < 0 ) return false; 332 if ( fd < 0 ) return false;
329 333
330 struct stat attribute; 334 struct stat attribute;
331 if ( ::fstat(fd, &attribute ) == -1 ) { 335 if ( ::fstat(fd, &attribute ) == -1 ) {
332 ::close( fd ); 336 ::close( fd );
333 return false; 337 return false;
334 } 338 }
335 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 339 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 );
336 if ( map_addr == ( (caddr_t)-1) ) { 340 if ( map_addr == ( (caddr_t)-1) ) {
337 ::close( fd ); 341 ::close( fd );
338 return false; 342 return false;
339 } 343 }
@@ -346,33 +350,33 @@ bool ODateBookAccessBackend_XML::loadFile() {
346 dict.insert( "description", new int(FDescription) ); 350 dict.insert( "description", new int(FDescription) );
347 dict.insert( "location", new int(FLocation) ); 351 dict.insert( "location", new int(FLocation) );
348 dict.insert( "categories", new int(FCategories) ); 352 dict.insert( "categories", new int(FCategories) );
349 dict.insert( "uid", new int(FUid) ); 353 dict.insert( "uid", new int(FUid) );
350 dict.insert( "type", new int(FType) ); 354 dict.insert( "type", new int(FType) );
351 dict.insert( "alarm", new int(FAlarm) ); 355 dict.insert( "alarm", new int(FAlarm) );
352 dict.insert( "sound", new int(FSound) ); 356 dict.insert( "sound", new int(FSound) );
353 dict.insert( "rtype", new int(FRType) ); 357 dict.insert( "rtype", new int(FRType) );
354 dict.insert( "rweekdays", new int(FRWeekdays) ); 358 dict.insert( "rweekdays", new int(FRWeekdays) );
355 dict.insert( "rposition", new int(FRPosition) ); 359 dict.insert( "rposition", new int(FRPosition) );
356 dict.insert( "rfreq", new int(FRFreq) ); 360 dict.insert( "rfreq", new int(FRFreq) );
357 dict.insert( "rhasenddate", new int(FRHasEndDate) ); 361 dict.insert( "rhasenddate", new int(FRHasEndDate) );
358 dict.insert( "enddt", new int(FREndDate) ); 362 dict.insert( "enddt", new int(FREndDate) );
359 dict.insert( "start", new int(FRStart) ); 363 dict.insert( "start", new int(FRStart) );
360 dict.insert( "end", new int(FREnd) ); 364 dict.insert( "end", new int(FREnd) );
361 dict.insert( "note", new int(FNote) ); 365 dict.insert( "note", new int(FNote) );
362 dict.insert( "created", new int(FCreated) ); 366 dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ??
363 dict.insert( "recparent", new int(FRecParent) ); 367 dict.insert( "recparent", new int(FRecParent) );
364 dict.insert( "recchildren", new int(FRecChildren) ); 368 dict.insert( "recchildren", new int(FRecChildren) );
365 dict.insert( "exceptions", new int(FExceptions) ); 369 dict.insert( "exceptions", new int(FExceptions) );
366 dict.insert( "timezone", new int(FTimeZone) ); 370 dict.insert( "timezone", new int(FTimeZone) );
367 371
368 char* dt = (char*)map_addr; 372 char* dt = (char*)map_addr;
369 int len = attribute.st_size; 373 int len = attribute.st_size;
370 int i = 0; 374 int i = 0;
371 char* point; 375 char* point;
372 const char* collectionString = "<event "; 376 const char* collectionString = "<event ";
373 int strLen = ::strlen(collectionString); 377 int strLen = ::strlen(collectionString);
374 int *find; 378 int *find;
375 while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { 379 while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) {
376 i = point -dt; 380 i = point -dt;
377 i+= strLen; 381 i+= strLen;
378 382
@@ -431,32 +435,34 @@ bool ODateBookAccessBackend_XML::loadFile() {
431 find = dict[attr.data()]; 435 find = dict[attr.data()];
432 if (!find) 436 if (!find)
433 ev.setCustomField( attr, str ); 437 ev.setCustomField( attr, str );
434 else { 438 else {
435 setField( ev, *find, str ); 439 setField( ev, *find, str );
436 } 440 }
437 } 441 }
438 /* time to finalize */ 442 /* time to finalize */
439 finalizeRecord( ev ); 443 finalizeRecord( ev );
440 delete rec; 444 delete rec;
441 } 445 }
442 ::munmap(map_addr, attribute.st_size ); 446 ::munmap(map_addr, attribute.st_size );
443 m_changed = false; // changed during add 447 m_changed = false; // changed during add
444 448
445 return true; 449 return true;
446} 450}
451
452// FIXME: Use OEvent::fromMap() which makes this obsolete.. (eilers)
447void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { 453void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) {
448 /* AllDay is alway in UTC */ 454 /* AllDay is alway in UTC */
449 if ( ev.isAllDay() ) { 455 if ( ev.isAllDay() ) {
450 OTimeZone utc = OTimeZone::utc(); 456 OTimeZone utc = OTimeZone::utc();
451 ev.setStartDateTime( utc.fromUTCDateTime( start ) ); 457 ev.setStartDateTime( utc.fromUTCDateTime( start ) );
452 ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); 458 ev.setEndDateTime ( utc.fromUTCDateTime( end ) );
453 ev.setTimeZone( "UTC"); // make sure it is really utc 459 ev.setTimeZone( "UTC"); // make sure it is really utc
454 }else { 460 }else {
455 /* to current date time */ 461 /* to current date time */
456 // qWarning(" Start is %d", start ); 462 // qWarning(" Start is %d", start );
457 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); 463 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() );
458 QDateTime date = zone.toDateTime( start ); 464 QDateTime date = zone.toDateTime( start );
459 qWarning(" Start is %s", date.toString().latin1() ); 465 qWarning(" Start is %s", date.toString().latin1() );
460 ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); 466 ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) );
461 467
462 date = zone.toDateTime( end ); 468 date = zone.toDateTime( end );
diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp
index 3913661..75a0860 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.cpp
+++ b/libopie2/opiepim/backend/otodoaccesssql.cpp
@@ -286,45 +286,48 @@ namespace {
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_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 )
315 delete m_driver;
314} 316}
317
315bool OTodoAccessBackendSQL::load(){ 318bool OTodoAccessBackendSQL::load(){
316 if (!m_driver->open() ) 319 if (!m_driver->open() )
317 return false; 320 return false;
318 321
319 CreateQuery creat; 322 CreateQuery creat;
320 OSQLResult res = m_driver->query(&creat ); 323 OSQLResult res = m_driver->query(&creat );
321 324
322 m_dirty = true; 325 m_dirty = true;
323 return true; 326 return true;
324} 327}
325bool OTodoAccessBackendSQL::reload(){ 328bool OTodoAccessBackendSQL::reload(){
326 return load(); 329 return load();
327} 330}
328 331
329bool OTodoAccessBackendSQL::save(){ 332bool OTodoAccessBackendSQL::save(){
330 return m_driver->close(); 333 return m_driver->close();
diff --git a/libopie2/opiepim/core/orecur.cpp b/libopie2/opiepim/core/orecur.cpp
index 8c9ad46..f46f22e 100644
--- a/libopie2/opiepim/core/orecur.cpp
+++ b/libopie2/opiepim/core/orecur.cpp
@@ -21,32 +21,40 @@ struct ORecur::Data : public QShared {
21 ORecur::RepeatType type; 21 ORecur::RepeatType type;
22 int freq; 22 int freq;
23 int pos; 23 int pos;
24 bool hasEnd : 1; 24 bool hasEnd : 1;
25 QDate end; 25 QDate end;
26 QDateTime create; 26 QDateTime create;
27 int rep; 27 int rep;
28 QString app; 28 QString app;
29 ExceptionList list; 29 ExceptionList list;
30 QDate start; 30 QDate start;
31}; 31};
32 32
33 33
34ORecur::ORecur() { 34ORecur::ORecur() {
35 data = new Data; 35 data = new Data;
36} 36}
37
38ORecur::ORecur( const QMap<int, QString>& map )
39{
40 ORecur();
41 fromMap( map );
42}
43
44
37ORecur::ORecur( const ORecur& rec) 45ORecur::ORecur( const ORecur& rec)
38 : data( rec.data ) 46 : data( rec.data )
39{ 47{
40 data->ref(); 48 data->ref();
41} 49}
42ORecur::~ORecur() { 50ORecur::~ORecur() {
43 if ( data->deref() ) { 51 if ( data->deref() ) {
44 delete data; 52 delete data;
45 data = 0l; 53 data = 0l;
46 } 54 }
47} 55}
48void ORecur::deref() { 56void ORecur::deref() {
49 if ( data->deref() ) { 57 if ( data->deref() ) {
50 delete data; 58 delete data;
51 data = 0l; 59 data = 0l;
52 } 60 }
diff --git a/libopie2/opiepim/core/orecur.h b/libopie2/opiepim/core/orecur.h
index 47901b0..7750c12 100644
--- a/libopie2/opiepim/core/orecur.h
+++ b/libopie2/opiepim/core/orecur.h
@@ -9,32 +9,33 @@
9 9
10#include <qdatetime.h> 10#include <qdatetime.h>
11#include <qvaluelist.h> 11#include <qvaluelist.h>
12#include <qmap.h> 12#include <qmap.h>
13 13
14class ORecur { 14class ORecur {
15public: 15public:
16 typedef QValueList<QDate> ExceptionList; 16 typedef QValueList<QDate> ExceptionList;
17 enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, 17 enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay,
18 MonthlyDate, Yearly }; 18 MonthlyDate, Yearly };
19 enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, 19 enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08,
20 FRI = 0x10, SAT = 0x20, SUN = 0x40 }; 20 FRI = 0x10, SAT = 0x20, SUN = 0x40 };
21 enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate, 21 enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate,
22 EndDate, Created, Exceptions }; 22 EndDate, Created, Exceptions };
23 23
24 ORecur(); 24 ORecur();
25 ORecur( const QMap<int, QString>& map );
25 ORecur( const ORecur& ); 26 ORecur( const ORecur& );
26 ~ORecur(); 27 ~ORecur();
27 28
28 ORecur &operator=( const ORecur& ); 29 ORecur &operator=( const ORecur& );
29 bool operator==(const ORecur& )const; 30 bool operator==(const ORecur& )const;
30 31
31 bool doesRecur()const; 32 bool doesRecur()const;
32 /* if it recurrs on that day */ 33 /* if it recurrs on that day */
33 bool doesRecur( const QDate& ); 34 bool doesRecur( const QDate& );
34 RepeatType type()const; 35 RepeatType type()const;
35 int frequency()const; 36 int frequency()const;
36 int position()const; 37 int position()const;
37 char days()const; 38 char days()const;
38 bool hasEndDate()const; 39 bool hasEndDate()const;
39 QDate start()const; 40 QDate start()const;
40 QDate endDate()const; 41 QDate endDate()const;
diff --git a/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp
index 7bcf944..c916297 100644
--- a/libopie2/opiepim/oevent.cpp
+++ b/libopie2/opiepim/oevent.cpp
@@ -1,17 +1,18 @@
1#include <qshared.h> 1#include <qshared.h>
2#include <qarray.h>
2 3
3#include <qpe/palmtopuidgen.h> 4#include <qpe/palmtopuidgen.h>
4#include <qpe/categories.h> 5#include <qpe/categories.h>
5#include <qpe/stringutil.h> 6#include <qpe/stringutil.h>
6 7
7#include "orecur.h" 8#include "orecur.h"
8#include "opimresolver.h" 9#include "opimresolver.h"
9#include "opimnotifymanager.h" 10#include "opimnotifymanager.h"
10 11
11#include "oevent.h" 12#include "oevent.h"
12 13
13int OCalendarHelper::week( const QDate& date) { 14int OCalendarHelper::week( const QDate& date) {
14 // Calculates the week this date is in within that 15 // Calculates the week this date is in within that
15 // month. Equals the "row" is is in in the month view 16 // month. Equals the "row" is is in in the month view
16 int week = 1; 17 int week = 1;
17 QDate tmp( date.year(), date.month(), 1 ); 18 QDate tmp( date.year(), date.month(), 1 );
@@ -343,36 +344,162 @@ void OEvent::changeOrModify() {
343 d2->parent = data->parent; 344 d2->parent = data->parent;
344 345
345 if ( data->child ) { 346 if ( data->child ) {
346 d2->child = new QArray<int>( *data->child ); 347 d2->child = new QArray<int>( *data->child );
347 d2->child->detach(); 348 d2->child->detach();
348 } 349 }
349 350
350 data = d2; 351 data = d2;
351 } 352 }
352} 353}
353void OEvent::deref() { 354void OEvent::deref() {
354 if ( data->deref() ) { 355 if ( data->deref() ) {
355 delete data; 356 delete data;
356 data = 0; 357 data = 0;
357 } 358 }
358} 359}
359// FIXME 360// Exporting Event data to map. Using the same
361// encoding as ODateBookAccessBackend_xml does..
362// Thus, we could remove the stuff there and use this
363// for it and for all other places..
364// Encoding should happen at one place, only ! (eilers)
360QMap<int, QString> OEvent::toMap()const { 365QMap<int, QString> OEvent::toMap()const {
361 return QMap<int, QString>(); 366 QMap<int, QString> retMap;
367
368 retMap.insert( OEvent::FUid, QString::number( uid() ) );
369 retMap.insert( OEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) ));
370 retMap.insert( OEvent::FDescription, Qtopia::escapeString( description() ) );
371 retMap.insert( OEvent::FLocation, Qtopia::escapeString( location() ) );
372 retMap.insert( OEvent::FType, isAllDay() ? "AllDay" : "" );
373 OPimAlarm alarm = notifiers().alarms()[0];
374 retMap.insert( OEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) );
375 retMap.insert( OEvent::FSound, (alarm.sound() == OPimAlarm::Loud) ? "loud" : "silent" );
376
377 OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() );
378 retMap.insert( OEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OTimeZone::utc() ) ) ) );
379 retMap.insert( OEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OTimeZone::utc() ) ) ) );
380 retMap.insert( OEvent::FNote, Qtopia::escapeString( note() ) );
381 retMap.insert( OEvent::FTimeZone, timeZone().isEmpty() ? "None" : timeZone() );
382 if( parent() )
383 retMap.insert( OEvent::FRecParent, QString::number( parent() ) );
384 if( children().count() ){
385 QArray<int> childr = children();
386 QString buf;
387 for ( uint i = 0; i < childr.count(); i++ ) {
388 if ( i != 0 ) buf += " ";
389 buf += QString::number( childr[i] );
390 }
391 retMap.insert( OEvent::FRecChildren, buf );
392 }
393
394 // Add recurrence stuff
395 if( hasRecurrence() ){
396 ORecur recur = recurrence();
397 QMap<int, QString> recFields = recur.toMap();
398 retMap.insert( OEvent::FRType, recFields[ORecur::RType] );
399 retMap.insert( OEvent::FRWeekdays, recFields[ORecur::RWeekdays] );
400 retMap.insert( OEvent::FRPosition, recFields[ORecur::RPosition] );
401 retMap.insert( OEvent::FRFreq, recFields[ORecur::RFreq] );
402 retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] );
403 retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] );
404 retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] );
405 retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] );
406 }
407
408 return retMap;
409}
410
411void OEvent::fromMap( const QMap<int, QString>& map )
412{
413
414 // We just want to set the UID if it is really stored.
415 if ( !map[OEvent::FUid].isEmpty() )
416 setUid( map[OEvent::FUid].toInt() );
417
418 setCategories( idsFromString( map[OEvent::FCategories] ) );
419 setDescription( map[OEvent::FDescription] );
420 setLocation( map[OEvent::FLocation] );
421
422 if ( map[OEvent::FType] == "AllDay" )
423 setAllDay( true );
424 else
425 setAllDay( false );
426
427 int alarmTime = -1;
428 if( !map[OEvent::FAlarm].isEmpty() )
429 alarmTime = map[OEvent::FAlarm].toInt();
430
431 int sound = ( ( map[OEvent::FSound] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent );
432 if ( ( alarmTime != -1 ) ){
433 QDateTime dt = startDateTime().addSecs( -1*alarmTime*60 );
434 OPimAlarm al( sound , dt );
435 notifiers().add( al );
436 }
437 if ( !map[OEvent::FTimeZone].isEmpty() && ( map[OEvent::FTimeZone] != "None" ) ){
438 setTimeZone( map[OEvent::FTimeZone] );
439 }
440
441 time_t start = (time_t) map[OEvent::FStart].toLong();
442 time_t end = (time_t) map[OEvent::FEnd].toLong();
443
444 /* AllDay is always in UTC */
445 if ( isAllDay() ) {
446 OTimeZone utc = OTimeZone::utc();
447 setStartDateTime( utc.fromUTCDateTime( start ) );
448 setEndDateTime ( utc.fromUTCDateTime( end ) );
449 setTimeZone( "UTC"); // make sure it is really utc
450 }else {
451 /* to current date time */
452 // qWarning(" Start is %d", start );
453 OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() );
454 QDateTime date = zone.toDateTime( start );
455 qWarning(" Start is %s", date.toString().latin1() );
456 setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) );
457
458 date = zone.toDateTime( end );
459 setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) );
460 }
461
462 if ( !map[OEvent::FRecParent].isEmpty() )
463 setParent( map[OEvent::FRecParent].toInt() );
464
465 if ( !map[OEvent::FRecChildren].isEmpty() ){
466 QStringList list = QStringList::split(' ', map[OEvent::FRecChildren] );
467 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
468 addChild( (*it).toInt() );
469 }
470 }
471
472 // Fill recurrence stuff and put it directly into the ORecur-Object using fromMap..
473 if( !map[OEvent::FRType].isEmpty() ){
474 QMap<int, QString> recFields;
475 recFields.insert( ORecur::RType, map[OEvent::FRType] );
476 recFields.insert( ORecur::RWeekdays, map[OEvent::FRWeekdays] );
477 recFields.insert( ORecur::RPosition, map[OEvent::FRPosition] );
478 recFields.insert( ORecur::RFreq, map[OEvent::FRFreq] );
479 recFields.insert( ORecur::RHasEndDate, map[OEvent::FRHasEndDate] );
480 recFields.insert( ORecur::EndDate, map[OEvent::FREndDate] );
481 recFields.insert( ORecur::Created, map[OEvent::FRCreated] );
482 recFields.insert( ORecur::Exceptions, map[OEvent::FRExceptions] );
483 ORecur recur( recFields );
484 setRecurrence( recur );
485 }
486
362} 487}
488
489
363int OEvent::parent()const { 490int OEvent::parent()const {
364 return data->parent; 491 return data->parent;
365} 492}
366void OEvent::setParent( int uid ) { 493void OEvent::setParent( int uid ) {
367 changeOrModify(); 494 changeOrModify();
368 data->parent = uid; 495 data->parent = uid;
369} 496}
370QArray<int> OEvent::children() const{ 497QArray<int> OEvent::children() const{
371 if (!data->child) return QArray<int>(); 498 if (!data->child) return QArray<int>();
372 else 499 else
373 return data->child->copy(); 500 return data->child->copy();
374} 501}
375void OEvent::setChildren( const QArray<int>& arr ) { 502void OEvent::setChildren( const QArray<int>& arr ) {
376 changeOrModify(); 503 changeOrModify();
377 if (data->child) delete data->child; 504 if (data->child) delete data->child;
378 505
diff --git a/libopie2/opiepim/oevent.h b/libopie2/opiepim/oevent.h
index 30f442e..9218c97 100644
--- a/libopie2/opiepim/oevent.h
+++ b/libopie2/opiepim/oevent.h
@@ -28,66 +28,75 @@ struct OCalendarHelper {
28 28
29}; 29};
30 30
31class OPimNotifyManager; 31class OPimNotifyManager;
32class ORecur; 32class ORecur;
33 33
34/** 34/**
35 * This is the container for all Events. It encapsules all 35 * This is the container for all Events. It encapsules all
36 * available information for a single Event 36 * available information for a single Event
37 * @short container for events. 37 * @short container for events.
38 */ 38 */
39class OEvent : public OPimRecord { 39class OEvent : public OPimRecord {
40public: 40public:
41 typedef QValueList<OEvent> ValueList; 41 typedef QValueList<OEvent> ValueList;
42 /** 42 /**
43 * RecordFields contain possible attributes 43 * RecordFields contain possible attributes
44 * used in the Results of toMap()..
44 */ 45 */
45 enum RecordFields { 46 enum RecordFields {
46 Uid = Qtopia::UID_ID, 47 FUid = Qtopia::UID_ID,
47 Category = Qtopia::CATEGORY_ID, 48 FCategories = Qtopia::CATEGORY_ID,
48 Description, 49 FDescription = 0,
49 Location, 50 FLocation,
50 Alarm, 51 FType,
51 Reminder, 52 FAlarm,
52 Recurrence, 53 FSound,
53 Note, 54 FRType,
54 Created, 55 FRWeekdays,
55 StartDate, 56 FRPosition,
56 EndDate, 57 FRFreq,
57 AllDay, 58 FRHasEndDate,
58 TimeZone 59 FREndDate,
60 FRCreated,
61 FRExceptions,
62 FStart,
63 FEnd,
64 FNote,
65 FTimeZone,
66 FRecParent,
67 FRecChildren,
59 }; 68 };
60 69
61 /** 70 /**
62 * Start with an Empty OEvent. UID == 0 means that it is empty 71 * Start with an Empty OEvent. UID == 0 means that it is empty
63 */ 72 */
64 OEvent(int uid = 0); 73 OEvent(int uid = 0);
65 74
66 /** 75 /**
67 * copy c'tor 76 * copy c'tor
68 */ 77 */
69 OEvent( const OEvent& ); 78 OEvent( const OEvent& );
70 ~OEvent(); 79 ~OEvent();
71 OEvent &operator=( const OEvent& ); 80 OEvent &operator=( const OEvent& );
72 81
73 QString description()const; 82 QString description()const;
74 void setDescription( const QString& description ); 83 void setDescription( const QString& description );
75 84
76 QString location()const; 85 QString location()const;
77 void setLocation( const QString& loc ); 86 void setLocation( const QString& loc );
78 87
79 bool hasNotifiers()const; 88 bool hasNotifiers()const;
80 OPimNotifyManager &notifiers()const; 89 OPimNotifyManager &notifiers()const;
81 90
82 ORecur recurrence()const; 91 ORecur recurrence()const;
83 void setRecurrence( const ORecur& ); 92 void setRecurrence( const ORecur& );
84 bool hasRecurrence()const; 93 bool hasRecurrence()const;
85 94
86 QString note()const; 95 QString note()const;
87 void setNote( const QString& note ); 96 void setNote( const QString& note );
88 97
89 98
90 QDateTime createdDateTime()const; 99 QDateTime createdDateTime()const;
91 void setCreatedDateTime( const QDateTime& dt); 100 void setCreatedDateTime( const QDateTime& dt);
92 101
93 /** set the date to dt. dt is the QDateTime in localtime */ 102 /** set the date to dt. dt is the QDateTime in localtime */
@@ -119,32 +128,33 @@ public:
119 QArray<int> children()const; 128 QArray<int> children()const;
120 void setChildren( const QArray<int>& ); 129 void setChildren( const QArray<int>& );
121 void addChild( int uid ); 130 void addChild( int uid );
122 void removeChild( int uid ); 131 void removeChild( int uid );
123 132
124 /** return the parent OEvent */ 133 /** return the parent OEvent */
125 int parent()const; 134 int parent()const;
126 void setParent( int uid ); 135 void setParent( int uid );
127 136
128 137
129 /* needed reimp */ 138 /* needed reimp */
130 QString toRichText()const; 139 QString toRichText()const;
131 QString toShortText()const; 140 QString toShortText()const;
132 QString type()const; 141 QString type()const;
133 142
134 QMap<int, QString> toMap()const; 143 QMap<int, QString> toMap()const;
144 void fromMap( const QMap<int, QString>& map );
135 QString recordField(int )const; 145 QString recordField(int )const;
136 146
137 static int rtti(); 147 static int rtti();
138 148
139 bool loadFromStream( QDataStream& ); 149 bool loadFromStream( QDataStream& );
140 bool saveToStream( QDataStream& )const; 150 bool saveToStream( QDataStream& )const;
141 151
142/* bool operator==( const OEvent& ); 152/* bool operator==( const OEvent& );
143 bool operator!=( const OEvent& ); 153 bool operator!=( const OEvent& );
144 bool operator<( const OEvent& ); 154 bool operator<( const OEvent& );
145 bool operator<=( const OEvent& ); 155 bool operator<=( const OEvent& );
146 bool operator>( const OEvent& ); 156 bool operator>( const OEvent& );
147 bool operator>=(const OEvent& ); 157 bool operator>=(const OEvent& );
148*/ 158*/
149private: 159private:
150 inline void changeOrModify(); 160 inline void changeOrModify();