-rw-r--r-- | libopie/pim/ocontactaccessbackend_sql.cpp | 11 | ||||
-rw-r--r-- | libopie/pim/ocontactaccessbackend_sql.h | 5 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend_sql.cpp | 221 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend_sql.h | 60 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend_xml.cpp | 12 | ||||
-rw-r--r-- | libopie/pim/oevent.cpp | 131 | ||||
-rw-r--r-- | libopie/pim/oevent.h | 38 | ||||
-rw-r--r-- | libopie/pim/orecur.cpp | 8 | ||||
-rw-r--r-- | libopie/pim/orecur.h | 1 | ||||
-rw-r--r-- | libopie/pim/otodoaccesssql.cpp | 5 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | 11 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.h | 5 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp | 221 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_sql.h | 60 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp | 12 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccesssql.cpp | 5 | ||||
-rw-r--r-- | libopie2/opiepim/core/orecur.cpp | 8 | ||||
-rw-r--r-- | libopie2/opiepim/core/orecur.h | 1 | ||||
-rw-r--r-- | libopie2/opiepim/oevent.cpp | 131 | ||||
-rw-r--r-- | libopie2/opiepim/oevent.h | 38 |
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 @@ -9,16 +9,19 @@ * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * ===================================================================== * ===================================================================== * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.3 2003/12/08 15:18:10 eilers + * Committing unfinished sql implementation before merging to libopie2 starts.. + * * Revision 1.2 2003/09/29 07:44:26 eilers * Improvement of PIM-SQL Databases, but search queries are still limited. * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. * Todo: Started to add new attributes. Some type conversions missing. * * Revision 1.1 2003/09/22 14:31:16 eilers * Added first experimental incarnation of sql-backend for addressbook. * Some modifications to be able to compile the todo sql-backend. @@ -449,17 +452,18 @@ namespace { } }; /* --------------------------------------------------------------------------- */ OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, - const QString& filename ): m_changed(false) + const QString& filename ): + OContactAccessBackend(), m_changed(false), m_driver( NULL ) { qWarning("C'tor OContactAccessBackend_SQL starts"); QTime t; t.start(); /* Expecting to access the default filename if nothing else is set */ if ( filename.isEmpty() ){ m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); @@ -471,16 +475,21 @@ OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname m_driver = man.standard(); m_driver->setUrl( m_fileName ); load(); qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); } +OContactAccessBackend_SQL::~OContactAccessBackend_SQL () +{ + if( m_driver ) + delete m_driver; +} bool OContactAccessBackend_SQL::load () { if (!m_driver->open() ) return false; // Don't expect that the database exists. // It is save here to create the table, even if it 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 @@ -11,16 +11,19 @@ * ===================================================================== * * * ===================================================================== * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.2 2003/12/08 15:18:11 eilers + * Committing unfinished sql implementation before merging to libopie2 starts.. + * * Revision 1.1 2003/09/22 14:31:16 eilers * Added first experimental incarnation of sql-backend for addressbook. * Some modifications to be able to compile the todo sql-backend. * A lot of changes fill follow... * * */ @@ -42,16 +45,18 @@ class OSQLResultItem; * This class is the SQL implementation of a Contact backend * it does implement everything available for OContact. * @see OPimAccessBackend for more information of available methods */ class OContactAccessBackend_SQL : public OContactAccessBackend { public: OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); + ~OContactAccessBackend_SQL (); + bool save(); bool load (); void clear (); bool wasChangedExternally(); 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 @@ +/* + * SQL Backend for the OPIE-Calender Database. + * + * Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de) + * + * ===================================================================== + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * ===================================================================== + * ===================================================================== + * Version: $Id$ + * ===================================================================== + * History: + * $Log$ + * Revision 1.1 2003/12/08 15:18:12 eilers + * Committing unfinished sql implementation before merging to libopie2 starts.. + * + * + */ + +#include <stdio.h> +#include <stdlib.h> + +#include <qarray.h> +#include <qstringlist.h> + +#include "orecur.h" +#include "odatebookaccessbackend_sql.h" + +#include <opie2/osqldriver.h> +#include <opie2/osqlresult.h> +#include <opie2/osqlmanager.h> +#include <opie2/osqlquery.h> + +namespace { + + + +}; + +ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , + const QString& fileName ) + : ODateBookAccessBackend(), m_driver( NULL ) +{ + m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; + + // Get the standart sql-driver from the OSQLManager.. + OSQLManager man; + m_driver = man.standard(); + m_driver->setUrl( m_fileName ); + + initFields(); + + load(); +} + +ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { +} + +void ODateBookAccessBackend_SQL::initFields() +{ + + // This map contains the translation of the fieldtype id's to + // the names of the table columns + m_fieldMap.insert( OEvent::FUid, "uid" ); + m_fieldMap.insert( OEvent::FCategories, "Categories" ); + m_fieldMap.insert( OEvent::FDescription, "Description" ); + m_fieldMap.insert( OEvent::FLocation, "Location" ); + m_fieldMap.insert( OEvent::FType, "Type" ); + m_fieldMap.insert( OEvent::FAlarm, "Alarm" ); + m_fieldMap.insert( OEvent::FSound, "Sound" ); + m_fieldMap.insert( OEvent::FRType, "RType" ); + m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" ); + m_fieldMap.insert( OEvent::FRPosition, "RPosition" ); + m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); + m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); + m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); + m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); + m_fieldMap.insert( OEvent::FRExeptions, "RExceptions" ); + m_fieldMap.insert( OEvent::FStart, "Start" ); + m_fieldMap.insert( OEvent::FEnd, "End" ); + m_fieldMap.insert( OEvent::FNote, "Note" ); + m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); + m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); + m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); +} + +bool ODateBookAccessBackend_SQL::load() +{ + if (!m_driver->open() ) + return false; + + // Don't expect that the database exists. + // It is save here to create the table, even if it + // do exist. ( Is that correct for all databases ?? ) + QString qu = "create table datebook( uid INTEGER PRIMARY KEY "; + + QMap<int, QString>::Iterator it; + for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ + qu += QString( ",\"%1\" VARCHAR(10)" ).arg( it.data() ); + } + qu += " );"; + + qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; + + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ) + return false; + + update(); + + return true; +} + +void ODateBookAccessBackend_SQL::update() +{ + + QString qu = "select uid from datebook"; + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ){ + m_uids.clear(); + return; + } + + m_uids = extractUids( res ); + +} + +QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const +{ + qWarning("extractUids"); + + OSQLResultItem::ValueList list = res.results(); + OSQLResultItem::ValueList::Iterator it; + QArray<int> ints(list.count() ); + qWarning(" count = %d", list.count() ); + + int i = 0; + for (it = list.begin(); it != list.end(); ++it ) { + ints[i] = (*it).data("uid").toInt(); + i++; + } + + return ints; + +} + +bool ODateBookAccessBackend_SQL::reload() +{ + return load(); +} + +bool ODateBookAccessBackend_SQL::save() +{ + return m_driver->close(); +} + +QArray<int> ODateBookAccessBackend_SQL::allRecords()const +{ + return m_uids; +} + +QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) { + return QArray<int>(); +} + +void ODateBookAccessBackend_SQL::clear() +{ + QString qu = "drop table datebook;"; + qu += "drop table custom_data;"; + + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + +} + + +OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ +} + +bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) { + return true; +} +bool ODateBookAccessBackend_SQL::remove( int uid ) { + + return true; +} +bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) { + remove( ev.uid() ); + return add( ev ); +} +QArray<int> ODateBookAccessBackend_SQL::rawEvents()const { + return allRecords(); +} +QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const { + + return ints; +} +QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const { + + return ints; +} +OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() { + + return list; +} +OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() { + + return list; +} + + +QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const +{ + + return m_currentQuery; +} 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 @@ +#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H +#define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H + +#include <qmap.h> + +#include "odatebookaccessbackend.h" + +class OSQLDriver; + +/** + * This is the default SQL implementation for DateBoook SQL storage + * It fully implements the interface + * @see ODateBookAccessBackend + * @see OPimAccessBackend + */ +class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { +public: + ODateBookAccessBackend_SQL( const QString& appName, + const QString& fileName = QString::null); + ~ODateBookAccessBackend_SQL(); + + bool load(); + bool reload(); + bool save(); + + QArray<int> allRecords()const; + QArray<int> matchRegexp(const QRegExp &r) const; + QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() ); + OEvent find( int uid )const; + void clear(); + bool add( const OEvent& ev ); + bool remove( int uid ); + bool replace( const OEvent& ev ); + + QArray<UID> rawEvents()const; + QArray<UID> rawRepeats()const; + QArray<UID> nonRepeats()const; + + OEvent::ValueList directNonRepeats(); + OEvent::ValueList directRawRepeats(); + +private: + bool loadFile(); + QString m_fileName; + QArray<int> m_uids; + + QMap<int, QString> m_fieldMap; + + OSQLDriver* m_driver; + + class Private; + Private *d; + + void initFields(); + void update(); + QArray<int> extractUids( OSQLResult& res ) const; + +}; + +#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 @@ -72,22 +72,24 @@ namespace { FRWeekdays, FRPosition, FRFreq, FRHasEndDate, FREndDate, FRStart, FREnd, FNote, - FCreated, + FCreated, // Should't this be called FRCreated ? FTimeZone, FRecParent, FRecChildren, FExceptions }; + + // FIXME: Use OEvent::toMap() here !! (eilers) inline void save( const OEvent& ev, QString& buf ) { qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; if (!ev.location().isEmpty() ) buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; buf += " uid=\"" + QString::number( ev.uid() ) + "\""; @@ -270,17 +272,17 @@ bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { bool ODateBookAccessBackend_XML::remove( int uid ) { m_changed = true; m_rep.remove( uid ); m_rep.remove( uid ); return true; } bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { - replace( ev.uid() ); + replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers) return add( ev ); } QArray<int> ODateBookAccessBackend_XML::rawEvents()const { return allRecords(); } QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { QArray<int> ints( m_rep.count() ); uint i = 0; @@ -316,16 +318,18 @@ OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { OEvent::ValueList list; QMap<int, OEvent>::ConstIterator it; for (it = m_rep.begin(); it != m_rep.end(); ++it ) list.append( it.data() ); return list; } + +// FIXME: Use OEvent::fromMap() (eilers) bool ODateBookAccessBackend_XML::loadFile() { m_changed = false; int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); if ( fd < 0 ) return false; struct stat attribute; if ( ::fstat(fd, &attribute ) == -1 ) { @@ -354,17 +358,17 @@ bool ODateBookAccessBackend_XML::loadFile() { dict.insert( "rweekdays", new int(FRWeekdays) ); dict.insert( "rposition", new int(FRPosition) ); dict.insert( "rfreq", new int(FRFreq) ); dict.insert( "rhasenddate", new int(FRHasEndDate) ); dict.insert( "enddt", new int(FREndDate) ); dict.insert( "start", new int(FRStart) ); dict.insert( "end", new int(FREnd) ); dict.insert( "note", new int(FNote) ); - dict.insert( "created", new int(FCreated) ); + dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? dict.insert( "recparent", new int(FRecParent) ); dict.insert( "recchildren", new int(FRecChildren) ); dict.insert( "exceptions", new int(FExceptions) ); dict.insert( "timezone", new int(FTimeZone) ); char* dt = (char*)map_addr; int len = attribute.st_size; int i = 0; @@ -439,16 +443,18 @@ bool ODateBookAccessBackend_XML::loadFile() { finalizeRecord( ev ); delete rec; } ::munmap(map_addr, attribute.st_size ); m_changed = false; // changed during add return true; } + +// FIXME: Use OEvent::fromMap() which makes this obsolete.. (eilers) void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { /* AllDay is alway in UTC */ if ( ev.isAllDay() ) { OTimeZone utc = OTimeZone::utc(); ev.setStartDateTime( utc.fromUTCDateTime( start ) ); ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); ev.setTimeZone( "UTC"); // make sure it is really utc }else { 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,9 +1,10 @@ #include <qshared.h> +#include <qarray.h> #include <qpe/palmtopuidgen.h> #include <qpe/categories.h> #include <qpe/stringutil.h> #include "orecur.h" #include "opimresolver.h" #include "opimnotifymanager.h" @@ -351,20 +352,146 @@ void OEvent::changeOrModify() { } } void OEvent::deref() { if ( data->deref() ) { delete data; data = 0; } } -// FIXME +// Exporting Event data to map. Using the same +// encoding as ODateBookAccessBackend_xml does.. +// Thus, we could remove the stuff there and use this +// for it and for all other places.. +// Encoding should happen at one place, only ! (eilers) QMap<int, QString> OEvent::toMap()const { - return QMap<int, QString>(); + QMap<int, QString> retMap; + + retMap.insert( OEvent::FUid, QString::number( uid() ) ); + retMap.insert( OEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) )); + retMap.insert( OEvent::FDescription, Qtopia::escapeString( description() ) ); + retMap.insert( OEvent::FLocation, Qtopia::escapeString( location() ) ); + retMap.insert( OEvent::FType, isAllDay() ? "AllDay" : "" ); + OPimAlarm alarm = notifiers().alarms()[0]; + retMap.insert( OEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); + retMap.insert( OEvent::FSound, (alarm.sound() == OPimAlarm::Loud) ? "loud" : "silent" ); + + OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); + retMap.insert( OEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OTimeZone::utc() ) ) ) ); + retMap.insert( OEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OTimeZone::utc() ) ) ) ); + retMap.insert( OEvent::FNote, Qtopia::escapeString( note() ) ); + retMap.insert( OEvent::FTimeZone, timeZone().isEmpty() ? "None" : timeZone() ); + if( parent() ) + retMap.insert( OEvent::FRecParent, QString::number( parent() ) ); + if( children().count() ){ + QArray<int> childr = children(); + QString buf; + for ( uint i = 0; i < childr.count(); i++ ) { + if ( i != 0 ) buf += " "; + buf += QString::number( childr[i] ); + } + retMap.insert( OEvent::FRecChildren, buf ); + } + + // Add recurrence stuff + if( hasRecurrence() ){ + ORecur recur = recurrence(); + QMap<int, QString> recFields = recur.toMap(); + retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); + retMap.insert( OEvent::FRWeekdays, recFields[ORecur::RWeekdays] ); + retMap.insert( OEvent::FRPosition, recFields[ORecur::RPosition] ); + retMap.insert( OEvent::FRFreq, recFields[ORecur::RFreq] ); + retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] ); + retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] ); + retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] ); + retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] ); + } + + return retMap; +} + +void OEvent::fromMap( const QMap<int, QString>& map ) +{ + + // We just want to set the UID if it is really stored. + if ( !map[OEvent::FUid].isEmpty() ) + setUid( map[OEvent::FUid].toInt() ); + + setCategories( idsFromString( map[OEvent::FCategories] ) ); + setDescription( map[OEvent::FDescription] ); + setLocation( map[OEvent::FLocation] ); + + if ( map[OEvent::FType] == "AllDay" ) + setAllDay( true ); + else + setAllDay( false ); + + int alarmTime = -1; + if( !map[OEvent::FAlarm].isEmpty() ) + alarmTime = map[OEvent::FAlarm].toInt(); + + int sound = ( ( map[OEvent::FSound] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent ); + if ( ( alarmTime != -1 ) ){ + QDateTime dt = startDateTime().addSecs( -1*alarmTime*60 ); + OPimAlarm al( sound , dt ); + notifiers().add( al ); + } + if ( !map[OEvent::FTimeZone].isEmpty() && ( map[OEvent::FTimeZone] != "None" ) ){ + setTimeZone( map[OEvent::FTimeZone] ); + } + + time_t start = (time_t) map[OEvent::FStart].toLong(); + time_t end = (time_t) map[OEvent::FEnd].toLong(); + + /* AllDay is always in UTC */ + if ( isAllDay() ) { + OTimeZone utc = OTimeZone::utc(); + setStartDateTime( utc.fromUTCDateTime( start ) ); + setEndDateTime ( utc.fromUTCDateTime( end ) ); + setTimeZone( "UTC"); // make sure it is really utc + }else { + /* to current date time */ + // qWarning(" Start is %d", start ); + OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); + QDateTime date = zone.toDateTime( start ); + qWarning(" Start is %s", date.toString().latin1() ); + setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); + + date = zone.toDateTime( end ); + setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); + } + + if ( !map[OEvent::FRecParent].isEmpty() ) + setParent( map[OEvent::FRecParent].toInt() ); + + if ( !map[OEvent::FRecChildren].isEmpty() ){ + QStringList list = QStringList::split(' ', map[OEvent::FRecChildren] ); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + addChild( (*it).toInt() ); + } + } + + // Fill recurrence stuff and put it directly into the ORecur-Object using fromMap.. + if( !map[OEvent::FRType].isEmpty() ){ + QMap<int, QString> recFields; + recFields.insert( ORecur::RType, map[OEvent::FRType] ); + recFields.insert( ORecur::RWeekdays, map[OEvent::FRWeekdays] ); + recFields.insert( ORecur::RPosition, map[OEvent::FRPosition] ); + recFields.insert( ORecur::RFreq, map[OEvent::FRFreq] ); + recFields.insert( ORecur::RHasEndDate, map[OEvent::FRHasEndDate] ); + recFields.insert( ORecur::EndDate, map[OEvent::FREndDate] ); + recFields.insert( ORecur::Created, map[OEvent::FRCreated] ); + recFields.insert( ORecur::Exceptions, map[OEvent::FRExceptions] ); + ORecur recur( recFields ); + setRecurrence( recur ); + } + } + + int OEvent::parent()const { return data->parent; } void OEvent::setParent( int uid ) { changeOrModify(); data->parent = uid; } QArray<int> OEvent::children() const{ 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 @@ -36,31 +36,40 @@ class ORecur; * available information for a single Event * @short container for events. */ class OEvent : public OPimRecord { public: typedef QValueList<OEvent> ValueList; /** * RecordFields contain possible attributes + * used in the Results of toMap().. */ enum RecordFields { - Uid = Qtopia::UID_ID, - Category = Qtopia::CATEGORY_ID, - Description, - Location, - Alarm, - Reminder, - Recurrence, - Note, - Created, - StartDate, - EndDate, - AllDay, - TimeZone + FUid = Qtopia::UID_ID, + FCategories = Qtopia::CATEGORY_ID, + FDescription = 0, + FLocation, + FType, + FAlarm, + FSound, + FRType, + FRWeekdays, + FRPosition, + FRFreq, + FRHasEndDate, + FREndDate, + FRCreated, + FRExceptions, + FStart, + FEnd, + FNote, + FTimeZone, + FRecParent, + FRecChildren, }; /** * Start with an Empty OEvent. UID == 0 means that it is empty */ OEvent(int uid = 0); /** @@ -69,17 +78,17 @@ public: OEvent( const OEvent& ); ~OEvent(); OEvent &operator=( const OEvent& ); QString description()const; void setDescription( const QString& description ); QString location()const; - void setLocation( const QString& loc ); + void setLocation( const QString& loc ); bool hasNotifiers()const; OPimNotifyManager ¬ifiers()const; ORecur recurrence()const; void setRecurrence( const ORecur& ); bool hasRecurrence()const; @@ -127,16 +136,17 @@ public: /* needed reimp */ QString toRichText()const; QString toShortText()const; QString type()const; QMap<int, QString> toMap()const; + void fromMap( const QMap<int, QString>& map ); QString recordField(int )const; static int rtti(); bool loadFromStream( QDataStream& ); bool saveToStream( QDataStream& )const; /* bool operator==( const OEvent& ); 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 @@ -29,16 +29,24 @@ struct ORecur::Data : public QShared { ExceptionList list; QDate start; }; ORecur::ORecur() { data = new Data; } + +ORecur::ORecur( const QMap<int, QString>& map ) +{ + ORecur(); + fromMap( map ); +} + + ORecur::ORecur( const ORecur& rec) : data( rec.data ) { data->ref(); } ORecur::~ORecur() { if ( data->deref() ) { delete data; 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 @@ -17,16 +17,17 @@ public: enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, MonthlyDate, Yearly }; enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, FRI = 0x10, SAT = 0x20, SUN = 0x40 }; enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions }; ORecur(); + ORecur( const QMap<int, QString>& map ); ORecur( const ORecur& ); ~ORecur(); ORecur &operator=( const ORecur& ); bool operator==(const ORecur& )const; bool doesRecur()const; /* if it recurrs on that day */ 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 @@ -294,29 +294,32 @@ namespace { .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); return str; } }; OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) - : OTodoAccessBackend(), m_dict(15), m_dirty(true) + : OTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true) { QString fi = file; if ( fi.isEmpty() ) fi = Global::applicationFileName( "todolist", "todolist.db" ); OSQLManager man; m_driver = man.standard(); m_driver->setUrl(fi); // fillDict(); } OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ + if( m_driver ) + delete m_driver; } + bool OTodoAccessBackendSQL::load(){ if (!m_driver->open() ) return false; CreateQuery creat; OSQLResult res = m_driver->query(&creat ); m_dirty = true; 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 @@ -9,16 +9,19 @@ * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * ===================================================================== * ===================================================================== * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.3 2003/12/08 15:18:10 eilers + * Committing unfinished sql implementation before merging to libopie2 starts.. + * * Revision 1.2 2003/09/29 07:44:26 eilers * Improvement of PIM-SQL Databases, but search queries are still limited. * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. * Todo: Started to add new attributes. Some type conversions missing. * * Revision 1.1 2003/09/22 14:31:16 eilers * Added first experimental incarnation of sql-backend for addressbook. * Some modifications to be able to compile the todo sql-backend. @@ -449,17 +452,18 @@ namespace { } }; /* --------------------------------------------------------------------------- */ OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, - const QString& filename ): m_changed(false) + const QString& filename ): + OContactAccessBackend(), m_changed(false), m_driver( NULL ) { qWarning("C'tor OContactAccessBackend_SQL starts"); QTime t; t.start(); /* Expecting to access the default filename if nothing else is set */ if ( filename.isEmpty() ){ m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); @@ -471,16 +475,21 @@ OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname m_driver = man.standard(); m_driver->setUrl( m_fileName ); load(); qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); } +OContactAccessBackend_SQL::~OContactAccessBackend_SQL () +{ + if( m_driver ) + delete m_driver; +} bool OContactAccessBackend_SQL::load () { if (!m_driver->open() ) return false; // Don't expect that the database exists. // It is save here to create the table, even if it 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 @@ -11,16 +11,19 @@ * ===================================================================== * * * ===================================================================== * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.2 2003/12/08 15:18:11 eilers + * Committing unfinished sql implementation before merging to libopie2 starts.. + * * Revision 1.1 2003/09/22 14:31:16 eilers * Added first experimental incarnation of sql-backend for addressbook. * Some modifications to be able to compile the todo sql-backend. * A lot of changes fill follow... * * */ @@ -42,16 +45,18 @@ class OSQLResultItem; * This class is the SQL implementation of a Contact backend * it does implement everything available for OContact. * @see OPimAccessBackend for more information of available methods */ class OContactAccessBackend_SQL : public OContactAccessBackend { public: OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); + ~OContactAccessBackend_SQL (); + bool save(); bool load (); void clear (); bool wasChangedExternally(); 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 @@ +/* + * SQL Backend for the OPIE-Calender Database. + * + * Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de) + * + * ===================================================================== + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * ===================================================================== + * ===================================================================== + * Version: $Id$ + * ===================================================================== + * History: + * $Log$ + * Revision 1.1 2003/12/08 15:18:12 eilers + * Committing unfinished sql implementation before merging to libopie2 starts.. + * + * + */ + +#include <stdio.h> +#include <stdlib.h> + +#include <qarray.h> +#include <qstringlist.h> + +#include "orecur.h" +#include "odatebookaccessbackend_sql.h" + +#include <opie2/osqldriver.h> +#include <opie2/osqlresult.h> +#include <opie2/osqlmanager.h> +#include <opie2/osqlquery.h> + +namespace { + + + +}; + +ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , + const QString& fileName ) + : ODateBookAccessBackend(), m_driver( NULL ) +{ + m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; + + // Get the standart sql-driver from the OSQLManager.. + OSQLManager man; + m_driver = man.standard(); + m_driver->setUrl( m_fileName ); + + initFields(); + + load(); +} + +ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { +} + +void ODateBookAccessBackend_SQL::initFields() +{ + + // This map contains the translation of the fieldtype id's to + // the names of the table columns + m_fieldMap.insert( OEvent::FUid, "uid" ); + m_fieldMap.insert( OEvent::FCategories, "Categories" ); + m_fieldMap.insert( OEvent::FDescription, "Description" ); + m_fieldMap.insert( OEvent::FLocation, "Location" ); + m_fieldMap.insert( OEvent::FType, "Type" ); + m_fieldMap.insert( OEvent::FAlarm, "Alarm" ); + m_fieldMap.insert( OEvent::FSound, "Sound" ); + m_fieldMap.insert( OEvent::FRType, "RType" ); + m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" ); + m_fieldMap.insert( OEvent::FRPosition, "RPosition" ); + m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); + m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); + m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); + m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); + m_fieldMap.insert( OEvent::FRExeptions, "RExceptions" ); + m_fieldMap.insert( OEvent::FStart, "Start" ); + m_fieldMap.insert( OEvent::FEnd, "End" ); + m_fieldMap.insert( OEvent::FNote, "Note" ); + m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); + m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); + m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); +} + +bool ODateBookAccessBackend_SQL::load() +{ + if (!m_driver->open() ) + return false; + + // Don't expect that the database exists. + // It is save here to create the table, even if it + // do exist. ( Is that correct for all databases ?? ) + QString qu = "create table datebook( uid INTEGER PRIMARY KEY "; + + QMap<int, QString>::Iterator it; + for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ + qu += QString( ",\"%1\" VARCHAR(10)" ).arg( it.data() ); + } + qu += " );"; + + qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; + + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ) + return false; + + update(); + + return true; +} + +void ODateBookAccessBackend_SQL::update() +{ + + QString qu = "select uid from datebook"; + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ){ + m_uids.clear(); + return; + } + + m_uids = extractUids( res ); + +} + +QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const +{ + qWarning("extractUids"); + + OSQLResultItem::ValueList list = res.results(); + OSQLResultItem::ValueList::Iterator it; + QArray<int> ints(list.count() ); + qWarning(" count = %d", list.count() ); + + int i = 0; + for (it = list.begin(); it != list.end(); ++it ) { + ints[i] = (*it).data("uid").toInt(); + i++; + } + + return ints; + +} + +bool ODateBookAccessBackend_SQL::reload() +{ + return load(); +} + +bool ODateBookAccessBackend_SQL::save() +{ + return m_driver->close(); +} + +QArray<int> ODateBookAccessBackend_SQL::allRecords()const +{ + return m_uids; +} + +QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) { + return QArray<int>(); +} + +void ODateBookAccessBackend_SQL::clear() +{ + QString qu = "drop table datebook;"; + qu += "drop table custom_data;"; + + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + +} + + +OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ +} + +bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) { + return true; +} +bool ODateBookAccessBackend_SQL::remove( int uid ) { + + return true; +} +bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) { + remove( ev.uid() ); + return add( ev ); +} +QArray<int> ODateBookAccessBackend_SQL::rawEvents()const { + return allRecords(); +} +QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const { + + return ints; +} +QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const { + + return ints; +} +OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() { + + return list; +} +OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() { + + return list; +} + + +QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const +{ + + return m_currentQuery; +} 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 @@ +#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H +#define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H + +#include <qmap.h> + +#include "odatebookaccessbackend.h" + +class OSQLDriver; + +/** + * This is the default SQL implementation for DateBoook SQL storage + * It fully implements the interface + * @see ODateBookAccessBackend + * @see OPimAccessBackend + */ +class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { +public: + ODateBookAccessBackend_SQL( const QString& appName, + const QString& fileName = QString::null); + ~ODateBookAccessBackend_SQL(); + + bool load(); + bool reload(); + bool save(); + + QArray<int> allRecords()const; + QArray<int> matchRegexp(const QRegExp &r) const; + QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() ); + OEvent find( int uid )const; + void clear(); + bool add( const OEvent& ev ); + bool remove( int uid ); + bool replace( const OEvent& ev ); + + QArray<UID> rawEvents()const; + QArray<UID> rawRepeats()const; + QArray<UID> nonRepeats()const; + + OEvent::ValueList directNonRepeats(); + OEvent::ValueList directRawRepeats(); + +private: + bool loadFile(); + QString m_fileName; + QArray<int> m_uids; + + QMap<int, QString> m_fieldMap; + + OSQLDriver* m_driver; + + class Private; + Private *d; + + void initFields(); + void update(); + QArray<int> extractUids( OSQLResult& res ) const; + +}; + +#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 @@ -72,22 +72,24 @@ namespace { FRWeekdays, FRPosition, FRFreq, FRHasEndDate, FREndDate, FRStart, FREnd, FNote, - FCreated, + FCreated, // Should't this be called FRCreated ? FTimeZone, FRecParent, FRecChildren, FExceptions }; + + // FIXME: Use OEvent::toMap() here !! (eilers) inline void save( const OEvent& ev, QString& buf ) { qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; if (!ev.location().isEmpty() ) buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; buf += " uid=\"" + QString::number( ev.uid() ) + "\""; @@ -270,17 +272,17 @@ bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { bool ODateBookAccessBackend_XML::remove( int uid ) { m_changed = true; m_rep.remove( uid ); m_rep.remove( uid ); return true; } bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { - replace( ev.uid() ); + replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers) return add( ev ); } QArray<int> ODateBookAccessBackend_XML::rawEvents()const { return allRecords(); } QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { QArray<int> ints( m_rep.count() ); uint i = 0; @@ -316,16 +318,18 @@ OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { OEvent::ValueList list; QMap<int, OEvent>::ConstIterator it; for (it = m_rep.begin(); it != m_rep.end(); ++it ) list.append( it.data() ); return list; } + +// FIXME: Use OEvent::fromMap() (eilers) bool ODateBookAccessBackend_XML::loadFile() { m_changed = false; int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); if ( fd < 0 ) return false; struct stat attribute; if ( ::fstat(fd, &attribute ) == -1 ) { @@ -354,17 +358,17 @@ bool ODateBookAccessBackend_XML::loadFile() { dict.insert( "rweekdays", new int(FRWeekdays) ); dict.insert( "rposition", new int(FRPosition) ); dict.insert( "rfreq", new int(FRFreq) ); dict.insert( "rhasenddate", new int(FRHasEndDate) ); dict.insert( "enddt", new int(FREndDate) ); dict.insert( "start", new int(FRStart) ); dict.insert( "end", new int(FREnd) ); dict.insert( "note", new int(FNote) ); - dict.insert( "created", new int(FCreated) ); + dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? dict.insert( "recparent", new int(FRecParent) ); dict.insert( "recchildren", new int(FRecChildren) ); dict.insert( "exceptions", new int(FExceptions) ); dict.insert( "timezone", new int(FTimeZone) ); char* dt = (char*)map_addr; int len = attribute.st_size; int i = 0; @@ -439,16 +443,18 @@ bool ODateBookAccessBackend_XML::loadFile() { finalizeRecord( ev ); delete rec; } ::munmap(map_addr, attribute.st_size ); m_changed = false; // changed during add return true; } + +// FIXME: Use OEvent::fromMap() which makes this obsolete.. (eilers) void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { /* AllDay is alway in UTC */ if ( ev.isAllDay() ) { OTimeZone utc = OTimeZone::utc(); ev.setStartDateTime( utc.fromUTCDateTime( start ) ); ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); ev.setTimeZone( "UTC"); // make sure it is really utc }else { 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 @@ -294,29 +294,32 @@ namespace { .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); return str; } }; OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) - : OTodoAccessBackend(), m_dict(15), m_dirty(true) + : OTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true) { QString fi = file; if ( fi.isEmpty() ) fi = Global::applicationFileName( "todolist", "todolist.db" ); OSQLManager man; m_driver = man.standard(); m_driver->setUrl(fi); // fillDict(); } OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ + if( m_driver ) + delete m_driver; } + bool OTodoAccessBackendSQL::load(){ if (!m_driver->open() ) return false; CreateQuery creat; OSQLResult res = m_driver->query(&creat ); m_dirty = true; 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 @@ -29,16 +29,24 @@ struct ORecur::Data : public QShared { ExceptionList list; QDate start; }; ORecur::ORecur() { data = new Data; } + +ORecur::ORecur( const QMap<int, QString>& map ) +{ + ORecur(); + fromMap( map ); +} + + ORecur::ORecur( const ORecur& rec) : data( rec.data ) { data->ref(); } ORecur::~ORecur() { if ( data->deref() ) { delete data; 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 @@ -17,16 +17,17 @@ public: enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, MonthlyDate, Yearly }; enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, FRI = 0x10, SAT = 0x20, SUN = 0x40 }; enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions }; ORecur(); + ORecur( const QMap<int, QString>& map ); ORecur( const ORecur& ); ~ORecur(); ORecur &operator=( const ORecur& ); bool operator==(const ORecur& )const; bool doesRecur()const; /* if it recurrs on that day */ 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,9 +1,10 @@ #include <qshared.h> +#include <qarray.h> #include <qpe/palmtopuidgen.h> #include <qpe/categories.h> #include <qpe/stringutil.h> #include "orecur.h" #include "opimresolver.h" #include "opimnotifymanager.h" @@ -351,20 +352,146 @@ void OEvent::changeOrModify() { } } void OEvent::deref() { if ( data->deref() ) { delete data; data = 0; } } -// FIXME +// Exporting Event data to map. Using the same +// encoding as ODateBookAccessBackend_xml does.. +// Thus, we could remove the stuff there and use this +// for it and for all other places.. +// Encoding should happen at one place, only ! (eilers) QMap<int, QString> OEvent::toMap()const { - return QMap<int, QString>(); + QMap<int, QString> retMap; + + retMap.insert( OEvent::FUid, QString::number( uid() ) ); + retMap.insert( OEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) )); + retMap.insert( OEvent::FDescription, Qtopia::escapeString( description() ) ); + retMap.insert( OEvent::FLocation, Qtopia::escapeString( location() ) ); + retMap.insert( OEvent::FType, isAllDay() ? "AllDay" : "" ); + OPimAlarm alarm = notifiers().alarms()[0]; + retMap.insert( OEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); + retMap.insert( OEvent::FSound, (alarm.sound() == OPimAlarm::Loud) ? "loud" : "silent" ); + + OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); + retMap.insert( OEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OTimeZone::utc() ) ) ) ); + retMap.insert( OEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OTimeZone::utc() ) ) ) ); + retMap.insert( OEvent::FNote, Qtopia::escapeString( note() ) ); + retMap.insert( OEvent::FTimeZone, timeZone().isEmpty() ? "None" : timeZone() ); + if( parent() ) + retMap.insert( OEvent::FRecParent, QString::number( parent() ) ); + if( children().count() ){ + QArray<int> childr = children(); + QString buf; + for ( uint i = 0; i < childr.count(); i++ ) { + if ( i != 0 ) buf += " "; + buf += QString::number( childr[i] ); + } + retMap.insert( OEvent::FRecChildren, buf ); + } + + // Add recurrence stuff + if( hasRecurrence() ){ + ORecur recur = recurrence(); + QMap<int, QString> recFields = recur.toMap(); + retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); + retMap.insert( OEvent::FRWeekdays, recFields[ORecur::RWeekdays] ); + retMap.insert( OEvent::FRPosition, recFields[ORecur::RPosition] ); + retMap.insert( OEvent::FRFreq, recFields[ORecur::RFreq] ); + retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] ); + retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] ); + retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] ); + retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] ); + } + + return retMap; +} + +void OEvent::fromMap( const QMap<int, QString>& map ) +{ + + // We just want to set the UID if it is really stored. + if ( !map[OEvent::FUid].isEmpty() ) + setUid( map[OEvent::FUid].toInt() ); + + setCategories( idsFromString( map[OEvent::FCategories] ) ); + setDescription( map[OEvent::FDescription] ); + setLocation( map[OEvent::FLocation] ); + + if ( map[OEvent::FType] == "AllDay" ) + setAllDay( true ); + else + setAllDay( false ); + + int alarmTime = -1; + if( !map[OEvent::FAlarm].isEmpty() ) + alarmTime = map[OEvent::FAlarm].toInt(); + + int sound = ( ( map[OEvent::FSound] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent ); + if ( ( alarmTime != -1 ) ){ + QDateTime dt = startDateTime().addSecs( -1*alarmTime*60 ); + OPimAlarm al( sound , dt ); + notifiers().add( al ); + } + if ( !map[OEvent::FTimeZone].isEmpty() && ( map[OEvent::FTimeZone] != "None" ) ){ + setTimeZone( map[OEvent::FTimeZone] ); + } + + time_t start = (time_t) map[OEvent::FStart].toLong(); + time_t end = (time_t) map[OEvent::FEnd].toLong(); + + /* AllDay is always in UTC */ + if ( isAllDay() ) { + OTimeZone utc = OTimeZone::utc(); + setStartDateTime( utc.fromUTCDateTime( start ) ); + setEndDateTime ( utc.fromUTCDateTime( end ) ); + setTimeZone( "UTC"); // make sure it is really utc + }else { + /* to current date time */ + // qWarning(" Start is %d", start ); + OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); + QDateTime date = zone.toDateTime( start ); + qWarning(" Start is %s", date.toString().latin1() ); + setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); + + date = zone.toDateTime( end ); + setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); + } + + if ( !map[OEvent::FRecParent].isEmpty() ) + setParent( map[OEvent::FRecParent].toInt() ); + + if ( !map[OEvent::FRecChildren].isEmpty() ){ + QStringList list = QStringList::split(' ', map[OEvent::FRecChildren] ); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + addChild( (*it).toInt() ); + } + } + + // Fill recurrence stuff and put it directly into the ORecur-Object using fromMap.. + if( !map[OEvent::FRType].isEmpty() ){ + QMap<int, QString> recFields; + recFields.insert( ORecur::RType, map[OEvent::FRType] ); + recFields.insert( ORecur::RWeekdays, map[OEvent::FRWeekdays] ); + recFields.insert( ORecur::RPosition, map[OEvent::FRPosition] ); + recFields.insert( ORecur::RFreq, map[OEvent::FRFreq] ); + recFields.insert( ORecur::RHasEndDate, map[OEvent::FRHasEndDate] ); + recFields.insert( ORecur::EndDate, map[OEvent::FREndDate] ); + recFields.insert( ORecur::Created, map[OEvent::FRCreated] ); + recFields.insert( ORecur::Exceptions, map[OEvent::FRExceptions] ); + ORecur recur( recFields ); + setRecurrence( recur ); + } + } + + int OEvent::parent()const { return data->parent; } void OEvent::setParent( int uid ) { changeOrModify(); data->parent = uid; } QArray<int> OEvent::children() const{ 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 @@ -36,31 +36,40 @@ class ORecur; * available information for a single Event * @short container for events. */ class OEvent : public OPimRecord { public: typedef QValueList<OEvent> ValueList; /** * RecordFields contain possible attributes + * used in the Results of toMap().. */ enum RecordFields { - Uid = Qtopia::UID_ID, - Category = Qtopia::CATEGORY_ID, - Description, - Location, - Alarm, - Reminder, - Recurrence, - Note, - Created, - StartDate, - EndDate, - AllDay, - TimeZone + FUid = Qtopia::UID_ID, + FCategories = Qtopia::CATEGORY_ID, + FDescription = 0, + FLocation, + FType, + FAlarm, + FSound, + FRType, + FRWeekdays, + FRPosition, + FRFreq, + FRHasEndDate, + FREndDate, + FRCreated, + FRExceptions, + FStart, + FEnd, + FNote, + FTimeZone, + FRecParent, + FRecChildren, }; /** * Start with an Empty OEvent. UID == 0 means that it is empty */ OEvent(int uid = 0); /** @@ -69,17 +78,17 @@ public: OEvent( const OEvent& ); ~OEvent(); OEvent &operator=( const OEvent& ); QString description()const; void setDescription( const QString& description ); QString location()const; - void setLocation( const QString& loc ); + void setLocation( const QString& loc ); bool hasNotifiers()const; OPimNotifyManager ¬ifiers()const; ORecur recurrence()const; void setRecurrence( const ORecur& ); bool hasRecurrence()const; @@ -127,16 +136,17 @@ public: /* needed reimp */ QString toRichText()const; QString toShortText()const; QString type()const; QMap<int, QString> toMap()const; + void fromMap( const QMap<int, QString>& map ); QString recordField(int )const; static int rtti(); bool loadFromStream( QDataStream& ); bool saveToStream( QDataStream& )const; /* bool operator==( const OEvent& ); |