summaryrefslogtreecommitdiff
authorzecke <zecke>2003-02-21 23:31:52 (UTC)
committer zecke <zecke>2003-02-21 23:31:52 (UTC)
commit46f47c0a1e542a8b4222f3ced8f3304534c7509d (patch) (side-by-side diff)
tree82dc97a07bae77387987711c0c21697691955937
parenta7448ec87d97a0128618e83ad7526bd884ef8853 (diff)
downloadopie-46f47c0a1e542a8b4222f3ced8f3304534c7509d.zip
opie-46f47c0a1e542a8b4222f3ced8f3304534c7509d.tar.gz
opie-46f47c0a1e542a8b4222f3ced8f3304534c7509d.tar.bz2
Add XML datebookresource
-clean up todoaccessxml header -implement some more stuff in the oeven tester -extend DefaultFactory to not crash and to use datebook -reading of OEvents is working nicely.. saving will be added tomorrow -fix spelling in ODateBookAcces
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/libopie.pro2
-rw-r--r--libopie/pim/obackendfactory.h41
-rw-r--r--libopie/pim/odatebookaccess.cpp5
-rw-r--r--libopie/pim/odatebookaccess.h4
-rw-r--r--libopie/pim/odatebookaccessbackend_xml.cpp395
-rw-r--r--libopie/pim/odatebookaccessbackend_xml.h48
-rw-r--r--libopie/pim/oevent.cpp5
-rw-r--r--libopie/pim/opimnotify.h2
-rw-r--r--libopie/pim/otodoaccessxml.cpp2
-rw-r--r--libopie/pim/test/oevent_test.cpp27
-rw-r--r--libopie2/opiepim/backend/obackendfactory.h41
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp395
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.h48
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp2
-rw-r--r--libopie2/opiepim/core/odatebookaccess.cpp5
-rw-r--r--libopie2/opiepim/core/odatebookaccess.h4
-rw-r--r--libopie2/opiepim/core/opimnotify.h2
-rw-r--r--libopie2/opiepim/oevent.cpp5
18 files changed, 995 insertions, 38 deletions
diff --git a/libopie/libopie.pro b/libopie/libopie.pro
index 70399ea..391f30e 100644
--- a/libopie/libopie.pro
+++ b/libopie/libopie.pro
@@ -1,116 +1,118 @@
TEMPLATE = lib
CONFIG += qte warn_on release
HEADERS = ofontmenu.h \
ocolorbutton.h \
ofiledialog.h ofileselector.h \
ocheckitem.h \
xmltree.h \
colordialog.h colorpopupmenu.h \
oclickablelabel.h oprocctrl.h \
oprocess.h odevice.h odevicebutton.h \
otimepicker.h otabwidget.h \
otabbar.h otabinfo.h \
ofontselector.h \
pim/opimrecord.h \
pim/otodo.h \
pim/orecordlist.h \
pim/opimaccesstemplate.h \
pim/opimaccessbackend.h \
pim/otodoaccess.h \
pim/otodoaccessbackend.h \
pim/ocontact.h \
pim/ocontactaccess.h \
pim/ocontactaccessbackend.h \
pim/ocontactaccessbackend_xml.h \
pim/ocontactaccessbackend_vcard.h \
pim/obackendfactory.h \
pim/opimcache.h \
pim/otodoaccessvcal.h \
pim/orecur.h \
pim/opimstate.h \
pim/opimxrefpartner.h \
pim/opimxref.h \
pim/opimxrefmanager.h \
pim/opimmaintainer.h \
pim/opimnotify.h \
pim/opimnotifymanager.h \
pim/opimmainwindow.h \
pim/opimresolver.h \
pim/oevent.h \
pim/otimezone.h \
pim/odatebookaccess.h \
pim/odatebookaccessbackend.h \
+ pim/odatebookaccessbackend_xml.h \
orecurrancewidget.h \
oticker.h
# pim/otodoaccesssql.h \
SOURCES = ofontmenu.cc \
ocolorbutton.cpp \
sharp_compat.cpp \
xmltree.cc \
ofiledialog.cc ofileselector.cc \
ocheckitem.cpp \
colordialog.cpp \
colorpopupmenu.cpp oclickablelabel.cpp \
oprocctrl.cpp oprocess.cpp \
odevice.cpp odevicebutton.cpp otimepicker.cpp \
otabwidget.cpp otabbar.cpp \
ofontselector.cpp \
pim/otodo.cpp \
pim/opimrecord.cpp \
pim/otodoaccess.cpp \
pim/otodoaccessbackend.cpp \
pim/otodoaccessxml.cpp \
pim/ocontact.cpp \
pim/ocontactaccess.cpp \
pim/ocontactaccessbackend_vcard.cpp \
pim/otodoaccessvcal.cpp \
pim/orecur.cpp \
pim/opimstate.cpp \
pim/opimxrefpartner.cpp \
pim/opimxref.cpp \
pim/opimxrefmanager.cpp \
pim/opimmaintainer.cpp \
pim/opimnotify.cpp \
pim/opimnotifymanager.cpp \
pim/opimmainwindow.cpp \
pim/opimresolver.cpp \
pim/oevent.cpp \
pim/otimezone.cpp \
pim/odatebookaccess.cpp \
pim/odatebookaccessbackend.cpp \
+ pim/odatebookaccessbackend_xml.cpp \
orecurrancewidget.cpp \
oticker.cpp
# pim/otodoaccesssql.cpp \
TARGET = opie
INCLUDEPATH += $(OPIEDIR)/include
DESTDIR = $(OPIEDIR)/lib$(PROJMAK)
#VERSION = 1.0.0
LIBS += -lqpe
# LIBS += -lopiesql
INTERFACES = otimepickerbase.ui orecurrancebase.ui
TRANSLATIONS = ../i18n/de/libopie.ts \
../i18n/xx/libopie.ts \
../i18n/en/libopie.ts \
../i18n/es/libopie.ts \
../i18n/fr/libopie.ts \
../i18n/hu/libopie.ts \
../i18n/ja/libopie.ts \
../i18n/ko/libopie.ts \
../i18n/no/libopie.ts \
../i18n/pl/libopie.ts \
../i18n/pt/libopie.ts \
../i18n/pt_BR/libopie.ts \
../i18n/sl/libopie.ts \
../i18n/zh_CN/libopie.ts \
../i18n/zh_TW/libopie.ts \
../i18n/da/libopie.ts
include ( $(OPIEDIR)/include.pro )
diff --git a/libopie/pim/obackendfactory.h b/libopie/pim/obackendfactory.h
index b796fb8..3a73210 100644
--- a/libopie/pim/obackendfactory.h
+++ b/libopie/pim/obackendfactory.h
@@ -1,113 +1,130 @@
/*
* Class to manage Backends.
*
* Copyright (c) 2002 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.
* =====================================================================
- * ToDo: Use plugins
+ * ToDo: Use plugins
* =====================================================================
* Version: $Id$
* =====================================================================
* History:
* $Log$
+ * Revision 1.5 2003/02/21 23:31:52 zecke
+ * Add XML datebookresource
+ * -clean up todoaccessxml header
+ * -implement some more stuff in the oeven tester
+ * -extend DefaultFactory to not crash and to use datebook
+ *
+ * -reading of OEvents is working nicely.. saving will be added
+ * tomorrow
+ * -fix spelling in ODateBookAcces
+ *
* Revision 1.4 2002/10/14 15:55:18 eilers
* Redeactivate SQL.. ;)
*
* Revision 1.3 2002/10/10 17:08:58 zecke
* The Cache is finally in place
* I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;)
* The read ahead functionality does not make sense for XMLs backends because most of the stuff is already in memory. While using readahead on SQL makes things a lot faster....
* I still have to fully implement read ahead
* This change is bic but sc
*
* Revision 1.2 2002/10/08 09:27:36 eilers
* Fixed libopie.pro to include the new pim-API.
* The SQL-Stuff is currently deactivated. Otherwise everyone who wants to
* compile itself would need to install libsqlite, libopiesql...
* Therefore, the backend currently uses XML only..
*
* Revision 1.1 2002/10/07 17:35:01 eilers
* added OBackendFactory for advanced backend access
*
*
* =====================================================================
*/
#ifndef OPIE_BACKENDFACTORY_H_
#define OPIE_BACKENDFACTORY_H_
#include <qstring.h>
#include <qasciidict.h>
#include <qpe/config.h>
#include "otodoaccessxml.h"
#include "ocontactaccessbackend_xml.h"
+#include "odatebookaccessbackend_xml.h"
#ifdef __USE_SQL
#include "otodoaccesssql.h"
#endif
template<class T>
class OBackendFactory
{
public:
OBackendFactory() {};
enum BACKENDS {
TODO,
CONTACT,
DATE
};
-
+
static T* Default( const QString backendName, const QString& appName ){
-
+
// __asm__("int3");
Config config( "pimaccess" );
config.setGroup ( backendName );
QString backend = config.readEntry( "usebackend" );
QAsciiDict<int> dict ( 3 );
dict.setAutoDelete ( TRUE );
dict.insert( "todo", new int (TODO) );
dict.insert( "contact", new int (CONTACT) );
+ dict.insert( "datebook", new int(DATE) );
qWarning ("TODO is: %d", TODO);
qWarning ("CONTACT is: %d", CONTACT);
-
- switch ( *dict.take( backendName ) ){
+
+ int *find = dict[ backendName ];
+ if (!find ) return 0;
+
+ switch ( *find ){
case TODO:
#ifdef __USE_SQL
- if ( backend == "sql" )
+ if ( backend == "sql" )
return (T*) new OTodoAccessBackendSQL("");
#else
- if ( backend == "sql" )
+ if ( backend == "sql" )
qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
#endif
return (T*) new OTodoAccessXML( appName );
case CONTACT:
- if ( backend == "sql" )
+ if ( backend == "sql" )
qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
return (T*) new OContactAccessBackend_XML( appName );
case DATE:
- qWarning ("OBackendFactory:: DATE-Backend not implemented!");
- return NULL;
+ if ( backend == "sql" )
+ qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!");
+
+ return (T*) new ODateBookAccessBackend_XML( appName );
default:
return NULL;
}
-
-
+
+
}
};
#endif
diff --git a/libopie/pim/odatebookaccess.cpp b/libopie/pim/odatebookaccess.cpp
index 5f97e7c..08e61ff 100644
--- a/libopie/pim/odatebookaccess.cpp
+++ b/libopie/pim/odatebookaccess.cpp
@@ -1,37 +1,38 @@
#include "obackendfactory.h"
#include "odatebookaccess.h"
ODateBookAccess::ODateBookAccess( ODateBookAccessBackend* back, enum Access ac )
: OPimAccessTemplate<OEvent>( back )
{
if (!back )
back = OBackendFactory<ODateBookAccessBackend>::Default("datebook", QString::null );
m_backEnd = back;
+ setBackEnd( m_backEnd );
}
ODateBookAccess::~ODateBookAccess() {
}
ODateBookAccess::List ODateBookAccess::rawEvents()const {
QArray<int> ints = m_backEnd->rawEvents();
List lis( ints, this );
return lis;
}
ODateBookAccess::List ODateBookAccess::rawRepeats()const {
QArray<int> ints = m_backEnd->rawRepeats();
List lis( ints, this );
return lis;
}
ODateBookAccess::List ODateBookAccess::nonRepeats()const {
QArray<int> ints = m_backEnd->nonRepeats();
List lis( ints, this );
return lis;
}
-OEffectiveEvent::ValueList ODateBookAccess::effecticeEvents( const QDate& from, const QDate& to ) {
+OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDate& from, const QDate& to ) {
return m_backEnd->effecticeEvents( from, to );
}
-OEffectiveEvent::ValueList ODateBookAccess::effecticeEvents( const QDateTime& start ) {
+OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDateTime& start ) {
return m_backEnd->effecticeEvents( start );
}
diff --git a/libopie/pim/odatebookaccess.h b/libopie/pim/odatebookaccess.h
index 3f2c728..7047039 100644
--- a/libopie/pim/odatebookaccess.h
+++ b/libopie/pim/odatebookaccess.h
@@ -1,32 +1,32 @@
#ifndef OPIE_DATE_BOOK_ACCESS_H
#define OPIE_DATE_BOOK_ACCESS_H
#include "odatebookaccessbackend.h"
#include "opimaccesstemplate.h"
#include "oevent.h"
class ODateBookAccess : public OPimAccessTemplate<OEvent> {
public:
ODateBookAccess( ODateBookAccessBackend* = 0l, enum Access acc = Random );
~ODateBookAccess();
/** return all events */
List rawEvents()const;
/** return repeating events */
List rawRepeats()const;
/** return non repeating events */
List nonRepeats()const;
- OEffectiveEvent::ValueList effecticeEvents( const QDate& from, const QDate& to );
- OEffectiveEvent::ValueList effecticeEvents( const QDateTime& start );
+ OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to );
+ OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start );
private:
ODateBookAccessBackend* m_backEnd;
class Private;
Private* d;
};
#endif
diff --git a/libopie/pim/odatebookaccessbackend_xml.cpp b/libopie/pim/odatebookaccessbackend_xml.cpp
new file mode 100644
index 0000000..a4c514b
--- a/dev/null
+++ b/libopie/pim/odatebookaccessbackend_xml.cpp
@@ -0,0 +1,395 @@
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <unistd.h>
+
+#include <qasciidict.h>
+#include <qfile.h>
+
+#include <qtopia/global.h>
+#include <qtopia/stringutil.h>
+
+#include "opimnotifymanager.h"
+#include "orecur.h"
+#include "otimezone.h"
+#include "odatebookaccessbackend_xml.h"
+
+namespace {
+ time_t start, end, created, rp_end;
+ ORecur* rec;
+ ORecur* recur() {
+ if (!rec)
+ rec = new ORecur;
+
+ return rec;
+ }
+ int alarmTime;
+ int snd;
+ enum Attribute{
+ FDescription = 0,
+ FLocation,
+ FCategories,
+ FUid,
+ FType,
+ FAlarm,
+ FSound,
+ FRType,
+ FRWeekdays,
+ FRPosition,
+ FRFreq,
+ FRHasEndDate,
+ FREndDate,
+ FRStart,
+ FREnd,
+ FNote,
+ FCreated
+ };
+}
+
+ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& ,
+ const QString& fileName )
+ : ODateBookAccessBackend() {
+ m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName;
+ m_changed = false;
+}
+ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() {
+}
+bool ODateBookAccessBackend_XML::load() {
+ return loadFile();
+}
+bool ODateBookAccessBackend_XML::reload() {
+ clear();
+ return load();
+}
+bool ODateBookAccessBackend_XML::save() {
+ if (!m_changed) return true;
+ m_changed = false;
+
+ return true;
+}
+QArray<int> ODateBookAccessBackend_XML::allRecords()const {
+ QArray<int> ints( m_raw.count()+ m_rep.count() );
+ uint i = 0;
+ QMap<int, OEvent>::ConstIterator it;
+
+ for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
+ ints[i] = it.key();
+ i++;
+ }
+ for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
+ ints[i] = it.key();
+ i++;
+ }
+
+ return ints;
+}
+QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int ) {
+ return QArray<int>();
+}
+void ODateBookAccessBackend_XML::clear() {
+ m_raw.clear();
+ m_rep.clear();
+}
+OEvent ODateBookAccessBackend_XML::find( int uid ) const{
+ if ( m_raw.contains( uid ) )
+ return m_raw[uid];
+ else
+ return m_rep[uid];
+}
+bool ODateBookAccessBackend_XML::add( const OEvent& ev ) {
+ m_changed = true;
+ if (ev.hasRecurrence() )
+ m_rep.insert( ev.uid(), ev );
+ else
+ m_raw.insert( ev.uid(), ev );
+
+ return true;
+}
+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() );
+ 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;
+ QMap<int, OEvent>::ConstIterator it;
+
+ for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
+ ints[i] = it.key();
+ i++;
+ }
+
+ return ints;
+}
+QArray<int> ODateBookAccessBackend_XML::nonRepeats()const {
+ QArray<int> ints( m_raw.count() );
+ uint i = 0;
+ QMap<int, OEvent>::ConstIterator it;
+
+ for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
+ ints[i] = it.key();
+ i++;
+ }
+
+ return ints;
+}
+OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() {
+ OEvent::ValueList list;
+ QMap<int, OEvent>::ConstIterator it;
+ for (it = m_raw.begin(); it != m_raw.end(); ++it )
+ list.append( it.data() );
+
+ return list;
+}
+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;
+}
+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 ) {
+ ::close( fd );
+ return false;
+ }
+ void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 );
+ if ( map_addr == ( (caddr_t)-1) ) {
+ ::close( fd );
+ return false;
+ }
+
+ ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL );
+ ::close( fd );
+
+ QAsciiDict<int> dict(FCreated+1);
+ dict.setAutoDelete( true );
+ dict.insert( "description", new int(FDescription) );
+ dict.insert( "location", new int(FLocation) );
+ dict.insert( "categories", new int(FCategories) );
+ dict.insert( "uid", new int(FUid) );
+ dict.insert( "type", new int(FType) );
+ dict.insert( "alarm", new int(FAlarm) );
+ dict.insert( "sound", new int(FSound) );
+ dict.insert( "rtype", new int(FRType) );
+ 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) );
+
+ char* dt = (char*)map_addr;
+ int len = attribute.st_size;
+ int i = 0;
+ char* point;
+ const char* collectionString = "<event ";
+ int strLen = ::strlen(collectionString);
+ int *find;
+ while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) {
+ i = point -dt;
+ i+= strLen;
+
+ alarmTime = -1;
+ snd = 0; // silent
+
+ OEvent ev;
+ rec = 0;
+
+ while ( TRUE ) {
+ while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
+ ++i;
+ if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
+ break;
+
+
+ // we have another attribute, read it.
+ int j = i;
+ while ( j < len && dt[j] != '=' )
+ ++j;
+ QCString attr( dt+i, j-i+1);
+
+ i = ++j; // skip =
+
+ // find the start of quotes
+ while ( i < len && dt[i] != '"' )
+ ++i;
+ j = ++i;
+
+ bool haveUtf = FALSE;
+ bool haveEnt = FALSE;
+ while ( j < len && dt[j] != '"' ) {
+ if ( ((unsigned char)dt[j]) > 0x7f )
+ haveUtf = TRUE;
+ if ( dt[j] == '&' )
+ haveEnt = TRUE;
+ ++j;
+ }
+ if ( i == j ) {
+ // empty value
+ i = j + 1;
+ continue;
+ }
+
+ QCString value( dt+i, j-i+1 );
+ i = j + 1;
+
+ QString str = (haveUtf ? QString::fromUtf8( value )
+ : QString::fromLatin1( value ) );
+ if ( haveEnt )
+ str = Qtopia::plainString( str );
+
+ /*
+ * add key + value
+ */
+ find = dict[attr.data()];
+ if (!find)
+ ev.setCustomField( attr, value );
+ else {
+ setField( ev, *find, value );
+ }
+ }
+ /* time to finalize */
+ finalizeRecord( ev );
+ add( ev );
+ delete rec;
+ }
+ ::munmap(map_addr, attribute.st_size );
+ m_changed = false; // changed during add
+
+ return true;
+}
+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 ) );
+ }else {
+ OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() );
+ ev.setStartDateTime( zone.toDateTime( start ) );
+ ev.setEndDateTime ( zone.toDateTime( end ) );
+ }
+ if ( rec && rec->doesRecur() ) {
+ OTimeZone utc = OTimeZone::utc();
+ ORecur recu( *rec ); // call copy c'tor;
+ recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() );
+ recu.setCreatedDateTime( utc.fromUTCDateTime( created ) );
+ recu.setStart( ev.startDateTime().date() );
+ ev.setRecurrence( recu );
+ }
+
+ if (alarmTime != -1 ) {
+ QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 );
+ OPimAlarm al( snd , dt );
+ ev.notifiers().add( al );
+ }
+ if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) {
+ ev.setUid( 1 );
+ }
+ if ( ev.hasRecurrence() )
+ m_rep.insert( ev.uid(), ev );
+ else
+ m_raw.insert( ev.uid(), ev );
+
+}
+void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) {
+// qWarning(" setting %s", value.latin1() );
+ switch( id ) {
+ case FDescription:
+ e.setDescription( value );
+ break;
+ case FLocation:
+ e.setLocation( value );
+ break;
+ case FCategories:
+ e.setCategories( e.idsFromString( value ) );
+ break;
+ case FUid:
+ e.setUid( value.toInt() );
+ break;
+ case FType:
+ if ( value == "AllDay" ) {
+ e.setAllDay( true );
+ e.setTimeZone( "UTC" );
+ }
+ break;
+ case FAlarm:
+ alarmTime = value.toInt();
+ break;
+ case FSound:
+ snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent;
+ break;
+ // recurrence stuff
+ case FRType:
+ if ( value == "Daily" )
+ recur()->setType( ORecur::Daily );
+ else if ( value == "Weekly" )
+ recur()->setType( ORecur::Weekly);
+ else if ( value == "MonthlyDay" )
+ recur()->setType( ORecur::MonthlyDay );
+ else if ( value == "MonthlyDate" )
+ recur()->setType( ORecur::MonthlyDate );
+ else if ( value == "Yearly" )
+ recur()->setType( ORecur::Yearly );
+ else
+ recur()->setType( ORecur::NoRepeat );
+ break;
+ case FRWeekdays:
+ recur()->setDays( value.toInt() );
+ break;
+ case FRPosition:
+ recur()->setPosition( value.toInt() );
+ break;
+ case FRFreq:
+ recur()->setFrequency( value.toInt() );
+ break;
+ case FRHasEndDate:
+ recur()->setHasEndDate( value.toInt() );
+ break;
+ case FREndDate: {
+ rp_end = (time_t) value.toLong();
+ break;
+ }
+ case FRStart: {
+ start = (time_t) value.toLong();
+ break;
+ }
+ case FREnd: {
+ end = ( (time_t) value.toLong() );
+ break;
+ }
+ case FNote:
+ e.setNote( value );
+ break;
+ case FCreated:
+ created = value.toInt();
+ break;
+ default:
+ break;
+ }
+}
diff --git a/libopie/pim/odatebookaccessbackend_xml.h b/libopie/pim/odatebookaccessbackend_xml.h
new file mode 100644
index 0000000..40f69d8
--- a/dev/null
+++ b/libopie/pim/odatebookaccessbackend_xml.h
@@ -0,0 +1,48 @@
+#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H
+#define OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H
+
+#include <qmap.h>
+
+#include "odatebookaccessbackend.h"
+
+class ODateBookAccessBackend_XML : public ODateBookAccessBackend {
+public:
+ ODateBookAccessBackend_XML( const QString& appName,
+ const QString& fileName = QString::null);
+ ~ODateBookAccessBackend_XML();
+
+ bool load();
+ bool reload();
+ bool save();
+
+ QArray<int> allRecords()const;
+ QArray<int> queryByExample( const OEvent&, int );
+ 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 m_changed :1 ;
+ bool loadFile();
+ inline void finalizeRecord( OEvent& ev );
+ inline void setField( OEvent&, int field, const QString& val );
+ QString m_name;
+ QMap<int, OEvent> m_raw;
+ QMap<int, OEvent> m_rep;
+
+ struct Data;
+ Data* data;
+ class Private;
+ Private *d;
+};
+
+#endif
diff --git a/libopie/pim/oevent.cpp b/libopie/pim/oevent.cpp
index aaae3b2..ada596c 100644
--- a/libopie/pim/oevent.cpp
+++ b/libopie/pim/oevent.cpp
@@ -1,381 +1,386 @@
#include <qshared.h>
#include <qpe/palmtopuidgen.h>
#include <qpe/categories.h>
#include "orecur.h"
#include "opimresolver.h"
#include "opimnotifymanager.h"
#include "oevent.h"
int OCalendarHelper::week( const QDate& date) {
// Calculates the week this date is in within that
// month. Equals the "row" is is in in the month view
int week = 1;
QDate tmp( date.year(), date.month(), 1 );
if ( date.dayOfWeek() < tmp.dayOfWeek() )
++week;
week += ( date.day() - 1 ) / 7;
return week;
}
int OCalendarHelper::ocurrence( const QDate& date) {
// calculates the number of occurrances of this day of the
// week till the given date (e.g 3rd Wednesday of the month)
return ( date.day() - 1 ) / 7 + 1;
}
int OCalendarHelper::dayOfWeek( char day ) {
int dayOfWeek = 1;
char i = ORecur::MON;
while ( !( i & day ) && i <= ORecur::SUN ) {
i <<= 1;
++dayOfWeek;
}
return dayOfWeek;
}
int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) {
return ( second.year() - first.year() ) * 12 +
second.month() - first.month();
}
struct OEvent::Data : public QShared {
Data() : QShared() {
recur = 0;
manager = 0;
isAllDay = false;
}
~Data() {
delete manager;
delete recur;
}
QString description;
QString location;
OPimNotifyManager* manager;
ORecur* recur;
QString note;
QDateTime created;
QDateTime start;
QDateTime end;
bool isAllDay : 1;
QString timezone;
};
OEvent::OEvent( int uid )
: OPimRecord( uid ) {
data = new Data;
}
OEvent::OEvent( const OEvent& ev)
: OPimRecord( ev ), data( ev.data )
{
data->ref();
}
OEvent::~OEvent() {
if ( data->deref() ) {
delete data;
data = 0;
}
}
OEvent& OEvent::operator=( const OEvent& ev) {
if ( *this == ev ) return *this;
OPimRecord::operator=( ev );
ev.data->ref();
deref();
data = ev.data;
return *this;
}
QString OEvent::description()const {
return data->description;
}
void OEvent::setDescription( const QString& description ) {
changeOrModify();
data->description = description;
}
void OEvent::setLocation( const QString& loc ) {
changeOrModify();
data->location = loc;
}
QString OEvent::location()const {
return data->location;
}
OPimNotifyManager &OEvent::notifiers() {
// I hope we can skip the changeOrModify here
// the notifier should take care of it
// and OPimNotify is shared too
if (!data->manager )
data->manager = new OPimNotifyManager;
return *data->manager;
}
bool OEvent::hasNotifiers()const {
return ( data->manager);
}
ORecur OEvent::recurrence()const {
if (!data->recur)
data->recur = new ORecur;
return *data->recur;
}
void OEvent::setRecurrence( const ORecur& rec) {
changeOrModify();
if (data->recur )
(*data->recur) = rec;
else
data->recur = new ORecur( rec );
}
bool OEvent::hasRecurrence()const {
if (!data->recur ) return false;
return data->recur->doesRecur();
}
QString OEvent::note()const {
return data->note;
}
void OEvent::setNote( const QString& note ) {
changeOrModify();
data->note = note;
}
QDateTime OEvent::createdDateTime()const {
return data->created;
}
void OEvent::setCreatedDateTime( const QDateTime& time ) {
changeOrModify();
data->created = time;
}
QDateTime OEvent::startDateTime()const {
if ( data->isAllDay )
return QDateTime( data->start.date(), QTime(0, 0, 0 ) );
return data->start;
}
QDateTime OEvent::startDateTimeInZone()const {
/* if no timezone, or all day event or if the current and this timeZone match... */
if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime();
OTimeZone zone(data->timezone );
return zone.toDateTime( data->start, OTimeZone::current() );
}
void OEvent::setStartDateTime( const QDateTime& dt ) {
changeOrModify();
data->start = dt;
}
QDateTime OEvent::endDateTime()const {
/*
* if all Day event the end time needs
* to be on the same day as the start
*/
if ( data->isAllDay )
return QDateTime( data->start.date(), QTime(23, 59, 59 ) );
return data->end;
}
QDateTime OEvent::endDateTimeInZone()const {
/* if no timezone, or all day event or if the current and this timeZone match... */
if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime();
OTimeZone zone(data->timezone );
return zone.toDateTime( data->end, OTimeZone::current() );
}
void OEvent::setEndDateTime( const QDateTime& dt ) {
changeOrModify();
data->end = dt;
}
bool OEvent::isMultipleDay()const {
return data->end.date().day() - data->start.date().day();
}
bool OEvent::isAllDay()const {
return data->isAllDay;
}
+void OEvent::setAllDay( bool allDay ) {
+ changeOrModify();
+ data->isAllDay = allDay;
+ if (allDay ) data->timezone = "UTC";
+}
void OEvent::setTimeZone( const QString& tz ) {
changeOrModify();
data->timezone = tz;
}
QString OEvent::timeZone()const {
return data->timezone;
}
bool OEvent::match( const QRegExp& )const {
// FIXME
return false;
}
QString OEvent::toRichText()const {
// FIXME
return "OEvent test";
}
QString OEvent::toShortText()const {
return "OEvent shotText";
}
QString OEvent::type()const {
return QString::fromLatin1("OEvent");
}
QString OEvent::recordField( int /*id */ )const {
return QString::null;
}
int OEvent::rtti() {
return OPimResolver::DateBook;
}
bool OEvent::loadFromStream( QDataStream& ) {
return true;
}
bool OEvent::saveToStream( QDataStream& )const {
return true;
}
void OEvent::changeOrModify() {
if ( data->count != 1 ) {
data->deref();
Data* d2 = new Data;
d2->description = data->description;
d2->location = data->location;
d2->manager = data->manager;
d2->recur = data->recur;
d2->note = data->note;
d2->created = data->created;
d2->start = data->start;
d2->end = data->end;
d2->isAllDay = data->isAllDay;
d2->timezone = data->timezone;
data = d2;
}
}
void OEvent::deref() {
if ( data->deref() ) {
delete data;
data = 0;
}
}
// FIXME
QMap<int, QString> OEvent::toMap()const {
return QMap<int, QString>();
}
QMap<QString, QString> OEvent::toExtraMap()const {
return QMap<QString, QString>();
}
struct OEffectiveEvent::Data : public QShared {
Data() : QShared() {
}
OEvent event;
QDate date;
QTime start, end;
QDate startDate, endDate;
bool dates : 1;
};
OEffectiveEvent::OEffectiveEvent() {
data = new Data;
data->date = QDate::currentDate();
data->start = data->end = QTime::currentTime();
data->dates = false;
}
OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate,
Position pos ) {
data = new Data;
data->event = ev;
data->date = startDate;
if ( pos & Start )
data->start = ev.startDateTime().time();
else
data->start = QTime( 0, 0, 0 );
if ( pos & End )
data->end = ev.endDateTime().time();
else
data->end = QTime( 23, 59, 59 );
data->dates = false;
}
OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) {
data = ev.data;
data->ref();
}
OEffectiveEvent::~OEffectiveEvent() {
if ( data->deref() ) {
delete data;
data = 0;
}
}
OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) {
if ( *this == ev ) return *this;
ev.data->ref();
deref();
data = ev.data;
return *this;
}
void OEffectiveEvent::setStartTime( const QTime& ti) {
changeOrModify();
data->start = ti;
}
void OEffectiveEvent::setEndTime( const QTime& en) {
changeOrModify();
data->end = en;
}
void OEffectiveEvent::setEvent( const OEvent& ev) {
changeOrModify();
data->event = ev;
}
void OEffectiveEvent::setDate( const QDate& da) {
changeOrModify();
data->date = da;
}
void OEffectiveEvent::setEffectiveDates( const QDate& from,
const QDate& to ) {
if (!from.isValid() ) {
data->dates = false;
return;
}
data->startDate = from;
data->endDate = to;
}
QString OEffectiveEvent::description()const {
return data->event.description();
}
QString OEffectiveEvent::location()const {
return data->event.location();
}
QString OEffectiveEvent::note()const {
return data->event.note();
}
OEvent OEffectiveEvent::event()const {
return data->event;
}
QTime OEffectiveEvent::startTime()const {
return data->start;
}
QTime OEffectiveEvent::endTime()const {
return data->end;
}
QDate OEffectiveEvent::date()const {
return data->date;
}
int OEffectiveEvent::length()const {
return (data->end.hour() * 60 - data->start.hour() * 60)
+ QABS(data->start.minute() - data->end.minute() );
}
int OEffectiveEvent::size()const {
return ( data->end.hour() - data->start.hour() ) * 3600
+ (data->end.minute() - data->start.minute() * 60
+ data->end.second() - data->start.second() );
}
QDate OEffectiveEvent::startDate()const {
if ( data->dates )
return data->startDate;
else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer
return data->date;
else
return data->event.startDateTime().date();
}
QDate OEffectiveEvent::endDate()const {
if ( data->dates )
return data->endDate;
else if ( data->event.hasRecurrence() )
return data->date;
else
return data->event.endDateTime().date();
}
void OEffectiveEvent::deref() {
diff --git a/libopie/pim/opimnotify.h b/libopie/pim/opimnotify.h
index 3501948..b0de000 100644
--- a/libopie/pim/opimnotify.h
+++ b/libopie/pim/opimnotify.h
@@ -1,142 +1,142 @@
#ifndef OPIE_PIM_NOTIFY_H
#define OPIE_PIM_NOTIFY_H
#include <qdatetime.h>
#include <qvaluelist.h>
/**
* This is the base class of Notifiers. Possible
* notifiers would be Alarms, Reminders
* What they share is that they have
* A DateTime, Type, Duration
* This is what this base class takes care of
* on top of that it's shared
*/
/*
* TALK to eilers: have a class OPimDuration which sets the Duration
* given on the Due/Start Date? -zecke
* discuss: do we need a uid for the notify? -zecke
*/
class OPimNotify {
public:
typedef QValueList<OPimNotify> ValueList;
OPimNotify( const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 );
OPimNotify( const OPimNotify& );
virtual ~OPimNotify();
OPimNotify &operator=(const OPimNotify& );
bool operator==( const OPimNotify& );
virtual QString type()const = 0;
/** start date */
QDateTime dateTime()const;
QString service()const;
/**
* RETURN the parent uid
*/
int parent()const;
/**
* in Seconds
*/
int duration()const;
/**
* Start Time + Duration
*/
QDateTime endTime()const;
void setDateTime( const QDateTime& );
void setDuration( int dur );
void setParent(int uid );
void setService( const QString& );
private:
inline void copyIntern();
void deref();
struct Data;
Data* data;
/* d-pointer */
class NotifyPrivate;
NotifyPrivate* d;
};
/**
* An alarm is a sound/mail/buzzer played/send
* at a given time to inform about
* an Event
*/
class OPimAlarm : public OPimNotify {
public:
- enum Sound{Loud=0, Silent, Custom };
+ enum Sound{Loud=1, Silent=0, Custom=2 };
OPimAlarm( int sound = Silent, const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 );
OPimAlarm( const OPimAlarm& );
~OPimAlarm();
OPimAlarm &operator=( const OPimAlarm& );
bool operator==( const OPimAlarm& );
QString type()const;
int sound()const;
QString file()const;
void setSound( int );
/* only when sound is custom... */
void setFile( const QString& sound );
private:
void deref();
void copyIntern();
struct Data;
Data * data;
class Private;
Private* d;
};
/**
* A Reminder will be put into the
* datebook
*/
class OPimReminder : public OPimNotify {
public:
/**
* c'tor of a reminder
* @param uid The uid of the Record inside the Datebook
* @param start the StartDate invalid for all day...
* @param duration The duration of the event ( -1 for all day )
* @param parent The 'parent' record of this reminder
*/
OPimReminder( int uid = 0, const QDateTime& start = QDateTime(),
int duration = 0, int parent = 0 );
OPimReminder( const OPimReminder& );
OPimReminder &operator=(const OPimReminder& );
QString type()const;
bool operator==( const OPimReminder& );
/**
* the uid of the alarm
* inside the 'datebook' application
*/
int recordUid()const;
void setRecordUid( int uid );
private:
void deref();
void copyIntern();
struct Data;
Data* data;
class Private;
Private *d;
};
#endif
diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp
index c3416cb..22b2469 100644
--- a/libopie/pim/otodoaccessxml.cpp
+++ b/libopie/pim/otodoaccessxml.cpp
@@ -1,211 +1,209 @@
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <qfile.h>
#include <qvector.h>
#include <qpe/global.h>
#include <qpe/stringutil.h>
#include <qpe/timeconversion.h>
-#include <opie/xmltree.h>
-
#include "otodoaccessxml.h"
OTodoAccessXML::OTodoAccessXML( const QString& appName,
const QString& fileName )
: OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
{
if (!fileName.isEmpty() )
m_file = fileName;
else
m_file = Global::applicationFileName( "todolist", "todolist.xml" );
}
OTodoAccessXML::~OTodoAccessXML() {
}
bool OTodoAccessXML::load() {
m_opened = true;
m_changed = false;
/* initialize dict */
/*
* UPDATE dict if you change anything!!!
*/
QAsciiDict<int> dict(21);
dict.setAutoDelete( TRUE );
dict.insert("Categories" , new int(OTodo::Category) );
dict.insert("Uid" , new int(OTodo::Uid) );
dict.insert("HasDate" , new int(OTodo::HasDate) );
dict.insert("Completed" , new int(OTodo::Completed) );
dict.insert("Description" , new int(OTodo::Description) );
dict.insert("Summary" , new int(OTodo::Summary) );
dict.insert("Priority" , new int(OTodo::Priority) );
dict.insert("DateDay" , new int(OTodo::DateDay) );
dict.insert("DateMonth" , new int(OTodo::DateMonth) );
dict.insert("DateYear" , new int(OTodo::DateYear) );
dict.insert("Progress" , new int(OTodo::Progress) );
dict.insert("Completed", new int(OTodo::Completed) );
dict.insert("CrossReference", new int(OTodo::CrossReference) );
dict.insert("State", new int(OTodo::State) );
dict.insert("Recurrence", new int(OTodo::Recurrence) );
dict.insert("Alarms", new int(OTodo::Alarms) );
dict.insert("Reminders", new int(OTodo::Reminders) );
dict.insert("Notifiers", new int(OTodo::Notifiers) );
dict.insert("Maintainer", new int(OTodo::Maintainer) );
// here the custom XML parser from TT it's GPL
// but we want to push OpiePIM... to TT.....
// mmap part from zecke :)
int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
struct stat attribut;
if ( fd < 0 ) return false;
if ( fstat(fd, &attribut ) == -1 ) {
::close( fd );
return false;
}
void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
if ( map_addr == ( (caddr_t)-1) ) {
::close(fd );
return false;
}
/* advise the kernel who we want to read it */
::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
/* we do not the file any more */
::close( fd );
char* dt = (char*)map_addr;
int len = attribut.st_size;
int i = 0;
char *point;
const char* collectionString = "<Task ";
int strLen = strlen(collectionString);
while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) {
i = point -dt;
i+= strLen;
qWarning("Found a start at %d %d", i, (point-dt) );
OTodo ev;
m_year = m_month = m_day = 0;
while ( TRUE ) {
while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
++i;
if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
break;
// we have another attribute, read it.
int j = i;
while ( j < len && dt[j] != '=' )
++j;
QCString attr( dt+i, j-i+1);
i = ++j; // skip =
// find the start of quotes
while ( i < len && dt[i] != '"' )
++i;
j = ++i;
bool haveUtf = FALSE;
bool haveEnt = FALSE;
while ( j < len && dt[j] != '"' ) {
if ( ((unsigned char)dt[j]) > 0x7f )
haveUtf = TRUE;
if ( dt[j] == '&' )
haveEnt = TRUE;
++j;
}
if ( i == j ) {
// empty value
i = j + 1;
continue;
}
QCString value( dt+i, j-i+1 );
i = j + 1;
QString str = (haveUtf ? QString::fromUtf8( value )
: QString::fromLatin1( value ) );
if ( haveEnt )
str = Qtopia::plainString( str );
/*
* add key + value
*/
todo( &dict, ev, attr, str );
}
/*
* now add it
*/
qWarning("End at %d", i );
if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
ev.setUid( 1 );
m_changed = true;
}
if ( ev.hasDueDate() ) {
ev.setDueDate( QDate(m_year, m_month, m_day) );
}
m_events.insert(ev.uid(), ev );
m_year = m_month = m_day = -1;
}
munmap(map_addr, attribut.st_size );
qWarning("counts %d records loaded!", m_events.count() );
return true;
}
bool OTodoAccessXML::reload() {
m_events.clear();
return load();
}
bool OTodoAccessXML::save() {
// qWarning("saving");
if (!m_opened || !m_changed ) {
// qWarning("not saving");
return true;
}
QString strNewFile = m_file + ".new";
QFile f( strNewFile );
if (!f.open( IO_WriteOnly|IO_Raw ) )
return false;
int written;
QString out;
out = "<!DOCTYPE Tasks>\n<Tasks>\n";
// for all todos
QMap<int, OTodo>::Iterator it;
for (it = m_events.begin(); it != m_events.end(); ++it ) {
out+= "<Task " + toString( (*it) ) + " />\n";
QCString cstr = out.utf8();
written = f.writeBlock( cstr.data(), cstr.length() );
/* less written then we wanted */
if ( written != (int)cstr.length() ) {
f.close();
QFile::remove( strNewFile );
return false;
}
out = QString::null;
}
out += "</Tasks>";
QCString cstr = out.utf8();
written = f.writeBlock( cstr.data(), cstr.length() );
if ( written != (int)cstr.length() ) {
f.close();
QFile::remove( strNewFile );
return false;
}
/* flush before renaming */
f.close();
diff --git a/libopie/pim/test/oevent_test.cpp b/libopie/pim/test/oevent_test.cpp
index 50cc032..6f04995 100644
--- a/libopie/pim/test/oevent_test.cpp
+++ b/libopie/pim/test/oevent_test.cpp
@@ -1,23 +1,50 @@
#include <qdatetime.h>
#include "../oevent.h"
+#include "../odatebookaccess.h"
int main(int argc, char* argv ) {
OEvent ev;
ev.setUid( 20 );
ev.setDescription( "Foo" );
OEvent ev2 = ev;
ev2.setDescription("Foo2");
qWarning("%s", ev2.description().latin1() );
qWarning("%s", ev.description().latin1() );
QDateTime time = QDateTime::currentDateTime();
ev2.setStartDateTime( time );
ev2.setTimeZone( "Europe/London" );
qWarning("%s", ev2.startDateTime().toString().latin1() );
qWarning("%s", ev2.startDateTimeInZone().toString().latin1() );
+
+ ODateBookAccess acc;
+ if(!acc.load() ) qWarning("could not load");
+
+ ODateBookAccess::List::Iterator it;
+ ODateBookAccess::List list = acc.allRecords();
+
+ for( it = list.begin(); it != list.end(); ++it ){
+ OEvent ev = (*it);
+ qWarning("Summary: %s",ev.description().latin1() );
+ qWarning("Start: %s End: %s",ev.startDateTime().toString().latin1(), ev.endDateTime().toString().latin1() );
+ qWarning("All Day: %d",ev.isAllDay() );
+
+ }
+ QDate date1(2003,02,01 );
+ QDate date2(2003,03,01 );
+
+ OEffectiveEvent::ValueList effList = acc.effectiveEvents( date1,date2 );
+ OEffectiveEvent::ValueList::Iterator effIt;
+
+ for( effIt = effList.begin(); effIt != effList.end(); ++effIt ){
+ OEffectiveEvent ef = (*effIt);
+ qWarning("Summary: %s", ef.description().latin1() );
+ qWarning("Date: %s", ef.date().toString().latin1() );
+ }
+
return 0;
}
diff --git a/libopie2/opiepim/backend/obackendfactory.h b/libopie2/opiepim/backend/obackendfactory.h
index b796fb8..3a73210 100644
--- a/libopie2/opiepim/backend/obackendfactory.h
+++ b/libopie2/opiepim/backend/obackendfactory.h
@@ -1,113 +1,130 @@
/*
* Class to manage Backends.
*
* Copyright (c) 2002 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.
* =====================================================================
- * ToDo: Use plugins
+ * ToDo: Use plugins
* =====================================================================
* Version: $Id$
* =====================================================================
* History:
* $Log$
+ * Revision 1.5 2003/02/21 23:31:52 zecke
+ * Add XML datebookresource
+ * -clean up todoaccessxml header
+ * -implement some more stuff in the oeven tester
+ * -extend DefaultFactory to not crash and to use datebook
+ *
+ * -reading of OEvents is working nicely.. saving will be added
+ * tomorrow
+ * -fix spelling in ODateBookAcces
+ *
* Revision 1.4 2002/10/14 15:55:18 eilers
* Redeactivate SQL.. ;)
*
* Revision 1.3 2002/10/10 17:08:58 zecke
* The Cache is finally in place
* I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;)
* The read ahead functionality does not make sense for XMLs backends because most of the stuff is already in memory. While using readahead on SQL makes things a lot faster....
* I still have to fully implement read ahead
* This change is bic but sc
*
* Revision 1.2 2002/10/08 09:27:36 eilers
* Fixed libopie.pro to include the new pim-API.
* The SQL-Stuff is currently deactivated. Otherwise everyone who wants to
* compile itself would need to install libsqlite, libopiesql...
* Therefore, the backend currently uses XML only..
*
* Revision 1.1 2002/10/07 17:35:01 eilers
* added OBackendFactory for advanced backend access
*
*
* =====================================================================
*/
#ifndef OPIE_BACKENDFACTORY_H_
#define OPIE_BACKENDFACTORY_H_
#include <qstring.h>
#include <qasciidict.h>
#include <qpe/config.h>
#include "otodoaccessxml.h"
#include "ocontactaccessbackend_xml.h"
+#include "odatebookaccessbackend_xml.h"
#ifdef __USE_SQL
#include "otodoaccesssql.h"
#endif
template<class T>
class OBackendFactory
{
public:
OBackendFactory() {};
enum BACKENDS {
TODO,
CONTACT,
DATE
};
-
+
static T* Default( const QString backendName, const QString& appName ){
-
+
// __asm__("int3");
Config config( "pimaccess" );
config.setGroup ( backendName );
QString backend = config.readEntry( "usebackend" );
QAsciiDict<int> dict ( 3 );
dict.setAutoDelete ( TRUE );
dict.insert( "todo", new int (TODO) );
dict.insert( "contact", new int (CONTACT) );
+ dict.insert( "datebook", new int(DATE) );
qWarning ("TODO is: %d", TODO);
qWarning ("CONTACT is: %d", CONTACT);
-
- switch ( *dict.take( backendName ) ){
+
+ int *find = dict[ backendName ];
+ if (!find ) return 0;
+
+ switch ( *find ){
case TODO:
#ifdef __USE_SQL
- if ( backend == "sql" )
+ if ( backend == "sql" )
return (T*) new OTodoAccessBackendSQL("");
#else
- if ( backend == "sql" )
+ if ( backend == "sql" )
qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
#endif
return (T*) new OTodoAccessXML( appName );
case CONTACT:
- if ( backend == "sql" )
+ if ( backend == "sql" )
qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
return (T*) new OContactAccessBackend_XML( appName );
case DATE:
- qWarning ("OBackendFactory:: DATE-Backend not implemented!");
- return NULL;
+ if ( backend == "sql" )
+ qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!");
+
+ return (T*) new ODateBookAccessBackend_XML( appName );
default:
return NULL;
}
-
-
+
+
}
};
#endif
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
new file mode 100644
index 0000000..a4c514b
--- a/dev/null
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
@@ -0,0 +1,395 @@
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <unistd.h>
+
+#include <qasciidict.h>
+#include <qfile.h>
+
+#include <qtopia/global.h>
+#include <qtopia/stringutil.h>
+
+#include "opimnotifymanager.h"
+#include "orecur.h"
+#include "otimezone.h"
+#include "odatebookaccessbackend_xml.h"
+
+namespace {
+ time_t start, end, created, rp_end;
+ ORecur* rec;
+ ORecur* recur() {
+ if (!rec)
+ rec = new ORecur;
+
+ return rec;
+ }
+ int alarmTime;
+ int snd;
+ enum Attribute{
+ FDescription = 0,
+ FLocation,
+ FCategories,
+ FUid,
+ FType,
+ FAlarm,
+ FSound,
+ FRType,
+ FRWeekdays,
+ FRPosition,
+ FRFreq,
+ FRHasEndDate,
+ FREndDate,
+ FRStart,
+ FREnd,
+ FNote,
+ FCreated
+ };
+}
+
+ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& ,
+ const QString& fileName )
+ : ODateBookAccessBackend() {
+ m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName;
+ m_changed = false;
+}
+ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() {
+}
+bool ODateBookAccessBackend_XML::load() {
+ return loadFile();
+}
+bool ODateBookAccessBackend_XML::reload() {
+ clear();
+ return load();
+}
+bool ODateBookAccessBackend_XML::save() {
+ if (!m_changed) return true;
+ m_changed = false;
+
+ return true;
+}
+QArray<int> ODateBookAccessBackend_XML::allRecords()const {
+ QArray<int> ints( m_raw.count()+ m_rep.count() );
+ uint i = 0;
+ QMap<int, OEvent>::ConstIterator it;
+
+ for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
+ ints[i] = it.key();
+ i++;
+ }
+ for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
+ ints[i] = it.key();
+ i++;
+ }
+
+ return ints;
+}
+QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int ) {
+ return QArray<int>();
+}
+void ODateBookAccessBackend_XML::clear() {
+ m_raw.clear();
+ m_rep.clear();
+}
+OEvent ODateBookAccessBackend_XML::find( int uid ) const{
+ if ( m_raw.contains( uid ) )
+ return m_raw[uid];
+ else
+ return m_rep[uid];
+}
+bool ODateBookAccessBackend_XML::add( const OEvent& ev ) {
+ m_changed = true;
+ if (ev.hasRecurrence() )
+ m_rep.insert( ev.uid(), ev );
+ else
+ m_raw.insert( ev.uid(), ev );
+
+ return true;
+}
+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() );
+ 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;
+ QMap<int, OEvent>::ConstIterator it;
+
+ for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
+ ints[i] = it.key();
+ i++;
+ }
+
+ return ints;
+}
+QArray<int> ODateBookAccessBackend_XML::nonRepeats()const {
+ QArray<int> ints( m_raw.count() );
+ uint i = 0;
+ QMap<int, OEvent>::ConstIterator it;
+
+ for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
+ ints[i] = it.key();
+ i++;
+ }
+
+ return ints;
+}
+OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() {
+ OEvent::ValueList list;
+ QMap<int, OEvent>::ConstIterator it;
+ for (it = m_raw.begin(); it != m_raw.end(); ++it )
+ list.append( it.data() );
+
+ return list;
+}
+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;
+}
+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 ) {
+ ::close( fd );
+ return false;
+ }
+ void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 );
+ if ( map_addr == ( (caddr_t)-1) ) {
+ ::close( fd );
+ return false;
+ }
+
+ ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL );
+ ::close( fd );
+
+ QAsciiDict<int> dict(FCreated+1);
+ dict.setAutoDelete( true );
+ dict.insert( "description", new int(FDescription) );
+ dict.insert( "location", new int(FLocation) );
+ dict.insert( "categories", new int(FCategories) );
+ dict.insert( "uid", new int(FUid) );
+ dict.insert( "type", new int(FType) );
+ dict.insert( "alarm", new int(FAlarm) );
+ dict.insert( "sound", new int(FSound) );
+ dict.insert( "rtype", new int(FRType) );
+ 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) );
+
+ char* dt = (char*)map_addr;
+ int len = attribute.st_size;
+ int i = 0;
+ char* point;
+ const char* collectionString = "<event ";
+ int strLen = ::strlen(collectionString);
+ int *find;
+ while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) {
+ i = point -dt;
+ i+= strLen;
+
+ alarmTime = -1;
+ snd = 0; // silent
+
+ OEvent ev;
+ rec = 0;
+
+ while ( TRUE ) {
+ while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
+ ++i;
+ if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
+ break;
+
+
+ // we have another attribute, read it.
+ int j = i;
+ while ( j < len && dt[j] != '=' )
+ ++j;
+ QCString attr( dt+i, j-i+1);
+
+ i = ++j; // skip =
+
+ // find the start of quotes
+ while ( i < len && dt[i] != '"' )
+ ++i;
+ j = ++i;
+
+ bool haveUtf = FALSE;
+ bool haveEnt = FALSE;
+ while ( j < len && dt[j] != '"' ) {
+ if ( ((unsigned char)dt[j]) > 0x7f )
+ haveUtf = TRUE;
+ if ( dt[j] == '&' )
+ haveEnt = TRUE;
+ ++j;
+ }
+ if ( i == j ) {
+ // empty value
+ i = j + 1;
+ continue;
+ }
+
+ QCString value( dt+i, j-i+1 );
+ i = j + 1;
+
+ QString str = (haveUtf ? QString::fromUtf8( value )
+ : QString::fromLatin1( value ) );
+ if ( haveEnt )
+ str = Qtopia::plainString( str );
+
+ /*
+ * add key + value
+ */
+ find = dict[attr.data()];
+ if (!find)
+ ev.setCustomField( attr, value );
+ else {
+ setField( ev, *find, value );
+ }
+ }
+ /* time to finalize */
+ finalizeRecord( ev );
+ add( ev );
+ delete rec;
+ }
+ ::munmap(map_addr, attribute.st_size );
+ m_changed = false; // changed during add
+
+ return true;
+}
+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 ) );
+ }else {
+ OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() );
+ ev.setStartDateTime( zone.toDateTime( start ) );
+ ev.setEndDateTime ( zone.toDateTime( end ) );
+ }
+ if ( rec && rec->doesRecur() ) {
+ OTimeZone utc = OTimeZone::utc();
+ ORecur recu( *rec ); // call copy c'tor;
+ recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() );
+ recu.setCreatedDateTime( utc.fromUTCDateTime( created ) );
+ recu.setStart( ev.startDateTime().date() );
+ ev.setRecurrence( recu );
+ }
+
+ if (alarmTime != -1 ) {
+ QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 );
+ OPimAlarm al( snd , dt );
+ ev.notifiers().add( al );
+ }
+ if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) {
+ ev.setUid( 1 );
+ }
+ if ( ev.hasRecurrence() )
+ m_rep.insert( ev.uid(), ev );
+ else
+ m_raw.insert( ev.uid(), ev );
+
+}
+void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) {
+// qWarning(" setting %s", value.latin1() );
+ switch( id ) {
+ case FDescription:
+ e.setDescription( value );
+ break;
+ case FLocation:
+ e.setLocation( value );
+ break;
+ case FCategories:
+ e.setCategories( e.idsFromString( value ) );
+ break;
+ case FUid:
+ e.setUid( value.toInt() );
+ break;
+ case FType:
+ if ( value == "AllDay" ) {
+ e.setAllDay( true );
+ e.setTimeZone( "UTC" );
+ }
+ break;
+ case FAlarm:
+ alarmTime = value.toInt();
+ break;
+ case FSound:
+ snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent;
+ break;
+ // recurrence stuff
+ case FRType:
+ if ( value == "Daily" )
+ recur()->setType( ORecur::Daily );
+ else if ( value == "Weekly" )
+ recur()->setType( ORecur::Weekly);
+ else if ( value == "MonthlyDay" )
+ recur()->setType( ORecur::MonthlyDay );
+ else if ( value == "MonthlyDate" )
+ recur()->setType( ORecur::MonthlyDate );
+ else if ( value == "Yearly" )
+ recur()->setType( ORecur::Yearly );
+ else
+ recur()->setType( ORecur::NoRepeat );
+ break;
+ case FRWeekdays:
+ recur()->setDays( value.toInt() );
+ break;
+ case FRPosition:
+ recur()->setPosition( value.toInt() );
+ break;
+ case FRFreq:
+ recur()->setFrequency( value.toInt() );
+ break;
+ case FRHasEndDate:
+ recur()->setHasEndDate( value.toInt() );
+ break;
+ case FREndDate: {
+ rp_end = (time_t) value.toLong();
+ break;
+ }
+ case FRStart: {
+ start = (time_t) value.toLong();
+ break;
+ }
+ case FREnd: {
+ end = ( (time_t) value.toLong() );
+ break;
+ }
+ case FNote:
+ e.setNote( value );
+ break;
+ case FCreated:
+ created = value.toInt();
+ break;
+ default:
+ break;
+ }
+}
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.h b/libopie2/opiepim/backend/odatebookaccessbackend_xml.h
new file mode 100644
index 0000000..40f69d8
--- a/dev/null
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.h
@@ -0,0 +1,48 @@
+#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H
+#define OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H
+
+#include <qmap.h>
+
+#include "odatebookaccessbackend.h"
+
+class ODateBookAccessBackend_XML : public ODateBookAccessBackend {
+public:
+ ODateBookAccessBackend_XML( const QString& appName,
+ const QString& fileName = QString::null);
+ ~ODateBookAccessBackend_XML();
+
+ bool load();
+ bool reload();
+ bool save();
+
+ QArray<int> allRecords()const;
+ QArray<int> queryByExample( const OEvent&, int );
+ 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 m_changed :1 ;
+ bool loadFile();
+ inline void finalizeRecord( OEvent& ev );
+ inline void setField( OEvent&, int field, const QString& val );
+ QString m_name;
+ QMap<int, OEvent> m_raw;
+ QMap<int, OEvent> m_rep;
+
+ struct Data;
+ Data* data;
+ class Private;
+ Private *d;
+};
+
+#endif
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp
index c3416cb..22b2469 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.cpp
+++ b/libopie2/opiepim/backend/otodoaccessxml.cpp
@@ -1,211 +1,209 @@
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <qfile.h>
#include <qvector.h>
#include <qpe/global.h>
#include <qpe/stringutil.h>
#include <qpe/timeconversion.h>
-#include <opie/xmltree.h>
-
#include "otodoaccessxml.h"
OTodoAccessXML::OTodoAccessXML( const QString& appName,
const QString& fileName )
: OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
{
if (!fileName.isEmpty() )
m_file = fileName;
else
m_file = Global::applicationFileName( "todolist", "todolist.xml" );
}
OTodoAccessXML::~OTodoAccessXML() {
}
bool OTodoAccessXML::load() {
m_opened = true;
m_changed = false;
/* initialize dict */
/*
* UPDATE dict if you change anything!!!
*/
QAsciiDict<int> dict(21);
dict.setAutoDelete( TRUE );
dict.insert("Categories" , new int(OTodo::Category) );
dict.insert("Uid" , new int(OTodo::Uid) );
dict.insert("HasDate" , new int(OTodo::HasDate) );
dict.insert("Completed" , new int(OTodo::Completed) );
dict.insert("Description" , new int(OTodo::Description) );
dict.insert("Summary" , new int(OTodo::Summary) );
dict.insert("Priority" , new int(OTodo::Priority) );
dict.insert("DateDay" , new int(OTodo::DateDay) );
dict.insert("DateMonth" , new int(OTodo::DateMonth) );
dict.insert("DateYear" , new int(OTodo::DateYear) );
dict.insert("Progress" , new int(OTodo::Progress) );
dict.insert("Completed", new int(OTodo::Completed) );
dict.insert("CrossReference", new int(OTodo::CrossReference) );
dict.insert("State", new int(OTodo::State) );
dict.insert("Recurrence", new int(OTodo::Recurrence) );
dict.insert("Alarms", new int(OTodo::Alarms) );
dict.insert("Reminders", new int(OTodo::Reminders) );
dict.insert("Notifiers", new int(OTodo::Notifiers) );
dict.insert("Maintainer", new int(OTodo::Maintainer) );
// here the custom XML parser from TT it's GPL
// but we want to push OpiePIM... to TT.....
// mmap part from zecke :)
int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
struct stat attribut;
if ( fd < 0 ) return false;
if ( fstat(fd, &attribut ) == -1 ) {
::close( fd );
return false;
}
void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
if ( map_addr == ( (caddr_t)-1) ) {
::close(fd );
return false;
}
/* advise the kernel who we want to read it */
::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
/* we do not the file any more */
::close( fd );
char* dt = (char*)map_addr;
int len = attribut.st_size;
int i = 0;
char *point;
const char* collectionString = "<Task ";
int strLen = strlen(collectionString);
while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) {
i = point -dt;
i+= strLen;
qWarning("Found a start at %d %d", i, (point-dt) );
OTodo ev;
m_year = m_month = m_day = 0;
while ( TRUE ) {
while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
++i;
if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
break;
// we have another attribute, read it.
int j = i;
while ( j < len && dt[j] != '=' )
++j;
QCString attr( dt+i, j-i+1);
i = ++j; // skip =
// find the start of quotes
while ( i < len && dt[i] != '"' )
++i;
j = ++i;
bool haveUtf = FALSE;
bool haveEnt = FALSE;
while ( j < len && dt[j] != '"' ) {
if ( ((unsigned char)dt[j]) > 0x7f )
haveUtf = TRUE;
if ( dt[j] == '&' )
haveEnt = TRUE;
++j;
}
if ( i == j ) {
// empty value
i = j + 1;
continue;
}
QCString value( dt+i, j-i+1 );
i = j + 1;
QString str = (haveUtf ? QString::fromUtf8( value )
: QString::fromLatin1( value ) );
if ( haveEnt )
str = Qtopia::plainString( str );
/*
* add key + value
*/
todo( &dict, ev, attr, str );
}
/*
* now add it
*/
qWarning("End at %d", i );
if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
ev.setUid( 1 );
m_changed = true;
}
if ( ev.hasDueDate() ) {
ev.setDueDate( QDate(m_year, m_month, m_day) );
}
m_events.insert(ev.uid(), ev );
m_year = m_month = m_day = -1;
}
munmap(map_addr, attribut.st_size );
qWarning("counts %d records loaded!", m_events.count() );
return true;
}
bool OTodoAccessXML::reload() {
m_events.clear();
return load();
}
bool OTodoAccessXML::save() {
// qWarning("saving");
if (!m_opened || !m_changed ) {
// qWarning("not saving");
return true;
}
QString strNewFile = m_file + ".new";
QFile f( strNewFile );
if (!f.open( IO_WriteOnly|IO_Raw ) )
return false;
int written;
QString out;
out = "<!DOCTYPE Tasks>\n<Tasks>\n";
// for all todos
QMap<int, OTodo>::Iterator it;
for (it = m_events.begin(); it != m_events.end(); ++it ) {
out+= "<Task " + toString( (*it) ) + " />\n";
QCString cstr = out.utf8();
written = f.writeBlock( cstr.data(), cstr.length() );
/* less written then we wanted */
if ( written != (int)cstr.length() ) {
f.close();
QFile::remove( strNewFile );
return false;
}
out = QString::null;
}
out += "</Tasks>";
QCString cstr = out.utf8();
written = f.writeBlock( cstr.data(), cstr.length() );
if ( written != (int)cstr.length() ) {
f.close();
QFile::remove( strNewFile );
return false;
}
/* flush before renaming */
f.close();
diff --git a/libopie2/opiepim/core/odatebookaccess.cpp b/libopie2/opiepim/core/odatebookaccess.cpp
index 5f97e7c..08e61ff 100644
--- a/libopie2/opiepim/core/odatebookaccess.cpp
+++ b/libopie2/opiepim/core/odatebookaccess.cpp
@@ -1,37 +1,38 @@
#include "obackendfactory.h"
#include "odatebookaccess.h"
ODateBookAccess::ODateBookAccess( ODateBookAccessBackend* back, enum Access ac )
: OPimAccessTemplate<OEvent>( back )
{
if (!back )
back = OBackendFactory<ODateBookAccessBackend>::Default("datebook", QString::null );
m_backEnd = back;
+ setBackEnd( m_backEnd );
}
ODateBookAccess::~ODateBookAccess() {
}
ODateBookAccess::List ODateBookAccess::rawEvents()const {
QArray<int> ints = m_backEnd->rawEvents();
List lis( ints, this );
return lis;
}
ODateBookAccess::List ODateBookAccess::rawRepeats()const {
QArray<int> ints = m_backEnd->rawRepeats();
List lis( ints, this );
return lis;
}
ODateBookAccess::List ODateBookAccess::nonRepeats()const {
QArray<int> ints = m_backEnd->nonRepeats();
List lis( ints, this );
return lis;
}
-OEffectiveEvent::ValueList ODateBookAccess::effecticeEvents( const QDate& from, const QDate& to ) {
+OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDate& from, const QDate& to ) {
return m_backEnd->effecticeEvents( from, to );
}
-OEffectiveEvent::ValueList ODateBookAccess::effecticeEvents( const QDateTime& start ) {
+OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDateTime& start ) {
return m_backEnd->effecticeEvents( start );
}
diff --git a/libopie2/opiepim/core/odatebookaccess.h b/libopie2/opiepim/core/odatebookaccess.h
index 3f2c728..7047039 100644
--- a/libopie2/opiepim/core/odatebookaccess.h
+++ b/libopie2/opiepim/core/odatebookaccess.h
@@ -1,32 +1,32 @@
#ifndef OPIE_DATE_BOOK_ACCESS_H
#define OPIE_DATE_BOOK_ACCESS_H
#include "odatebookaccessbackend.h"
#include "opimaccesstemplate.h"
#include "oevent.h"
class ODateBookAccess : public OPimAccessTemplate<OEvent> {
public:
ODateBookAccess( ODateBookAccessBackend* = 0l, enum Access acc = Random );
~ODateBookAccess();
/** return all events */
List rawEvents()const;
/** return repeating events */
List rawRepeats()const;
/** return non repeating events */
List nonRepeats()const;
- OEffectiveEvent::ValueList effecticeEvents( const QDate& from, const QDate& to );
- OEffectiveEvent::ValueList effecticeEvents( const QDateTime& start );
+ OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to );
+ OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start );
private:
ODateBookAccessBackend* m_backEnd;
class Private;
Private* d;
};
#endif
diff --git a/libopie2/opiepim/core/opimnotify.h b/libopie2/opiepim/core/opimnotify.h
index 3501948..b0de000 100644
--- a/libopie2/opiepim/core/opimnotify.h
+++ b/libopie2/opiepim/core/opimnotify.h
@@ -1,142 +1,142 @@
#ifndef OPIE_PIM_NOTIFY_H
#define OPIE_PIM_NOTIFY_H
#include <qdatetime.h>
#include <qvaluelist.h>
/**
* This is the base class of Notifiers. Possible
* notifiers would be Alarms, Reminders
* What they share is that they have
* A DateTime, Type, Duration
* This is what this base class takes care of
* on top of that it's shared
*/
/*
* TALK to eilers: have a class OPimDuration which sets the Duration
* given on the Due/Start Date? -zecke
* discuss: do we need a uid for the notify? -zecke
*/
class OPimNotify {
public:
typedef QValueList<OPimNotify> ValueList;
OPimNotify( const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 );
OPimNotify( const OPimNotify& );
virtual ~OPimNotify();
OPimNotify &operator=(const OPimNotify& );
bool operator==( const OPimNotify& );
virtual QString type()const = 0;
/** start date */
QDateTime dateTime()const;
QString service()const;
/**
* RETURN the parent uid
*/
int parent()const;
/**
* in Seconds
*/
int duration()const;
/**
* Start Time + Duration
*/
QDateTime endTime()const;
void setDateTime( const QDateTime& );
void setDuration( int dur );
void setParent(int uid );
void setService( const QString& );
private:
inline void copyIntern();
void deref();
struct Data;
Data* data;
/* d-pointer */
class NotifyPrivate;
NotifyPrivate* d;
};
/**
* An alarm is a sound/mail/buzzer played/send
* at a given time to inform about
* an Event
*/
class OPimAlarm : public OPimNotify {
public:
- enum Sound{Loud=0, Silent, Custom };
+ enum Sound{Loud=1, Silent=0, Custom=2 };
OPimAlarm( int sound = Silent, const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 );
OPimAlarm( const OPimAlarm& );
~OPimAlarm();
OPimAlarm &operator=( const OPimAlarm& );
bool operator==( const OPimAlarm& );
QString type()const;
int sound()const;
QString file()const;
void setSound( int );
/* only when sound is custom... */
void setFile( const QString& sound );
private:
void deref();
void copyIntern();
struct Data;
Data * data;
class Private;
Private* d;
};
/**
* A Reminder will be put into the
* datebook
*/
class OPimReminder : public OPimNotify {
public:
/**
* c'tor of a reminder
* @param uid The uid of the Record inside the Datebook
* @param start the StartDate invalid for all day...
* @param duration The duration of the event ( -1 for all day )
* @param parent The 'parent' record of this reminder
*/
OPimReminder( int uid = 0, const QDateTime& start = QDateTime(),
int duration = 0, int parent = 0 );
OPimReminder( const OPimReminder& );
OPimReminder &operator=(const OPimReminder& );
QString type()const;
bool operator==( const OPimReminder& );
/**
* the uid of the alarm
* inside the 'datebook' application
*/
int recordUid()const;
void setRecordUid( int uid );
private:
void deref();
void copyIntern();
struct Data;
Data* data;
class Private;
Private *d;
};
#endif
diff --git a/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp
index aaae3b2..ada596c 100644
--- a/libopie2/opiepim/oevent.cpp
+++ b/libopie2/opiepim/oevent.cpp
@@ -1,381 +1,386 @@
#include <qshared.h>
#include <qpe/palmtopuidgen.h>
#include <qpe/categories.h>
#include "orecur.h"
#include "opimresolver.h"
#include "opimnotifymanager.h"
#include "oevent.h"
int OCalendarHelper::week( const QDate& date) {
// Calculates the week this date is in within that
// month. Equals the "row" is is in in the month view
int week = 1;
QDate tmp( date.year(), date.month(), 1 );
if ( date.dayOfWeek() < tmp.dayOfWeek() )
++week;
week += ( date.day() - 1 ) / 7;
return week;
}
int OCalendarHelper::ocurrence( const QDate& date) {
// calculates the number of occurrances of this day of the
// week till the given date (e.g 3rd Wednesday of the month)
return ( date.day() - 1 ) / 7 + 1;
}
int OCalendarHelper::dayOfWeek( char day ) {
int dayOfWeek = 1;
char i = ORecur::MON;
while ( !( i & day ) && i <= ORecur::SUN ) {
i <<= 1;
++dayOfWeek;
}
return dayOfWeek;
}
int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) {
return ( second.year() - first.year() ) * 12 +
second.month() - first.month();
}
struct OEvent::Data : public QShared {
Data() : QShared() {
recur = 0;
manager = 0;
isAllDay = false;
}
~Data() {
delete manager;
delete recur;
}
QString description;
QString location;
OPimNotifyManager* manager;
ORecur* recur;
QString note;
QDateTime created;
QDateTime start;
QDateTime end;
bool isAllDay : 1;
QString timezone;
};
OEvent::OEvent( int uid )
: OPimRecord( uid ) {
data = new Data;
}
OEvent::OEvent( const OEvent& ev)
: OPimRecord( ev ), data( ev.data )
{
data->ref();
}
OEvent::~OEvent() {
if ( data->deref() ) {
delete data;
data = 0;
}
}
OEvent& OEvent::operator=( const OEvent& ev) {
if ( *this == ev ) return *this;
OPimRecord::operator=( ev );
ev.data->ref();
deref();
data = ev.data;
return *this;
}
QString OEvent::description()const {
return data->description;
}
void OEvent::setDescription( const QString& description ) {
changeOrModify();
data->description = description;
}
void OEvent::setLocation( const QString& loc ) {
changeOrModify();
data->location = loc;
}
QString OEvent::location()const {
return data->location;
}
OPimNotifyManager &OEvent::notifiers() {
// I hope we can skip the changeOrModify here
// the notifier should take care of it
// and OPimNotify is shared too
if (!data->manager )
data->manager = new OPimNotifyManager;
return *data->manager;
}
bool OEvent::hasNotifiers()const {
return ( data->manager);
}
ORecur OEvent::recurrence()const {
if (!data->recur)
data->recur = new ORecur;
return *data->recur;
}
void OEvent::setRecurrence( const ORecur& rec) {
changeOrModify();
if (data->recur )
(*data->recur) = rec;
else
data->recur = new ORecur( rec );
}
bool OEvent::hasRecurrence()const {
if (!data->recur ) return false;
return data->recur->doesRecur();
}
QString OEvent::note()const {
return data->note;
}
void OEvent::setNote( const QString& note ) {
changeOrModify();
data->note = note;
}
QDateTime OEvent::createdDateTime()const {
return data->created;
}
void OEvent::setCreatedDateTime( const QDateTime& time ) {
changeOrModify();
data->created = time;
}
QDateTime OEvent::startDateTime()const {
if ( data->isAllDay )
return QDateTime( data->start.date(), QTime(0, 0, 0 ) );
return data->start;
}
QDateTime OEvent::startDateTimeInZone()const {
/* if no timezone, or all day event or if the current and this timeZone match... */
if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime();
OTimeZone zone(data->timezone );
return zone.toDateTime( data->start, OTimeZone::current() );
}
void OEvent::setStartDateTime( const QDateTime& dt ) {
changeOrModify();
data->start = dt;
}
QDateTime OEvent::endDateTime()const {
/*
* if all Day event the end time needs
* to be on the same day as the start
*/
if ( data->isAllDay )
return QDateTime( data->start.date(), QTime(23, 59, 59 ) );
return data->end;
}
QDateTime OEvent::endDateTimeInZone()const {
/* if no timezone, or all day event or if the current and this timeZone match... */
if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime();
OTimeZone zone(data->timezone );
return zone.toDateTime( data->end, OTimeZone::current() );
}
void OEvent::setEndDateTime( const QDateTime& dt ) {
changeOrModify();
data->end = dt;
}
bool OEvent::isMultipleDay()const {
return data->end.date().day() - data->start.date().day();
}
bool OEvent::isAllDay()const {
return data->isAllDay;
}
+void OEvent::setAllDay( bool allDay ) {
+ changeOrModify();
+ data->isAllDay = allDay;
+ if (allDay ) data->timezone = "UTC";
+}
void OEvent::setTimeZone( const QString& tz ) {
changeOrModify();
data->timezone = tz;
}
QString OEvent::timeZone()const {
return data->timezone;
}
bool OEvent::match( const QRegExp& )const {
// FIXME
return false;
}
QString OEvent::toRichText()const {
// FIXME
return "OEvent test";
}
QString OEvent::toShortText()const {
return "OEvent shotText";
}
QString OEvent::type()const {
return QString::fromLatin1("OEvent");
}
QString OEvent::recordField( int /*id */ )const {
return QString::null;
}
int OEvent::rtti() {
return OPimResolver::DateBook;
}
bool OEvent::loadFromStream( QDataStream& ) {
return true;
}
bool OEvent::saveToStream( QDataStream& )const {
return true;
}
void OEvent::changeOrModify() {
if ( data->count != 1 ) {
data->deref();
Data* d2 = new Data;
d2->description = data->description;
d2->location = data->location;
d2->manager = data->manager;
d2->recur = data->recur;
d2->note = data->note;
d2->created = data->created;
d2->start = data->start;
d2->end = data->end;
d2->isAllDay = data->isAllDay;
d2->timezone = data->timezone;
data = d2;
}
}
void OEvent::deref() {
if ( data->deref() ) {
delete data;
data = 0;
}
}
// FIXME
QMap<int, QString> OEvent::toMap()const {
return QMap<int, QString>();
}
QMap<QString, QString> OEvent::toExtraMap()const {
return QMap<QString, QString>();
}
struct OEffectiveEvent::Data : public QShared {
Data() : QShared() {
}
OEvent event;
QDate date;
QTime start, end;
QDate startDate, endDate;
bool dates : 1;
};
OEffectiveEvent::OEffectiveEvent() {
data = new Data;
data->date = QDate::currentDate();
data->start = data->end = QTime::currentTime();
data->dates = false;
}
OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate,
Position pos ) {
data = new Data;
data->event = ev;
data->date = startDate;
if ( pos & Start )
data->start = ev.startDateTime().time();
else
data->start = QTime( 0, 0, 0 );
if ( pos & End )
data->end = ev.endDateTime().time();
else
data->end = QTime( 23, 59, 59 );
data->dates = false;
}
OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) {
data = ev.data;
data->ref();
}
OEffectiveEvent::~OEffectiveEvent() {
if ( data->deref() ) {
delete data;
data = 0;
}
}
OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) {
if ( *this == ev ) return *this;
ev.data->ref();
deref();
data = ev.data;
return *this;
}
void OEffectiveEvent::setStartTime( const QTime& ti) {
changeOrModify();
data->start = ti;
}
void OEffectiveEvent::setEndTime( const QTime& en) {
changeOrModify();
data->end = en;
}
void OEffectiveEvent::setEvent( const OEvent& ev) {
changeOrModify();
data->event = ev;
}
void OEffectiveEvent::setDate( const QDate& da) {
changeOrModify();
data->date = da;
}
void OEffectiveEvent::setEffectiveDates( const QDate& from,
const QDate& to ) {
if (!from.isValid() ) {
data->dates = false;
return;
}
data->startDate = from;
data->endDate = to;
}
QString OEffectiveEvent::description()const {
return data->event.description();
}
QString OEffectiveEvent::location()const {
return data->event.location();
}
QString OEffectiveEvent::note()const {
return data->event.note();
}
OEvent OEffectiveEvent::event()const {
return data->event;
}
QTime OEffectiveEvent::startTime()const {
return data->start;
}
QTime OEffectiveEvent::endTime()const {
return data->end;
}
QDate OEffectiveEvent::date()const {
return data->date;
}
int OEffectiveEvent::length()const {
return (data->end.hour() * 60 - data->start.hour() * 60)
+ QABS(data->start.minute() - data->end.minute() );
}
int OEffectiveEvent::size()const {
return ( data->end.hour() - data->start.hour() ) * 3600
+ (data->end.minute() - data->start.minute() * 60
+ data->end.second() - data->start.second() );
}
QDate OEffectiveEvent::startDate()const {
if ( data->dates )
return data->startDate;
else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer
return data->date;
else
return data->event.startDateTime().date();
}
QDate OEffectiveEvent::endDate()const {
if ( data->dates )
return data->endDate;
else if ( data->event.hasRecurrence() )
return data->date;
else
return data->event.endDateTime().date();
}
void OEffectiveEvent::deref() {