summaryrefslogtreecommitdiff
path: root/libopie
authorzecke <zecke>2002-09-22 22:21:51 (UTC)
committer zecke <zecke>2002-09-22 22:21:51 (UTC)
commite49230a12104b718c46a34c81b6c0e608c9d40be (patch) (side-by-side diff)
tree4ef2e58c366a8cf7c4abe04838e255b38613fbcb /libopie
parent3049d9418b882283814ca71baa98420b2a6745db (diff)
downloadopie-e49230a12104b718c46a34c81b6c0e608c9d40be.zip
opie-e49230a12104b718c46a34c81b6c0e608c9d40be.tar.gz
opie-e49230a12104b718c46a34c81b6c0e608c9d40be.tar.bz2
Add XML resources for todolist and compile fixes for RecordList
Diffstat (limited to 'libopie') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/opimaccessbackend.h28
-rw-r--r--libopie/pim/opimaccesstemplate.h53
-rw-r--r--libopie/pim/orecordlist.h29
-rw-r--r--libopie/pim/otemplatebase.h2
-rw-r--r--libopie/pim/otodo.cpp15
-rw-r--r--libopie/pim/otodo.h10
-rw-r--r--libopie/pim/otodoaccess.cpp71
-rw-r--r--libopie/pim/otodoaccess.h79
-rw-r--r--libopie/pim/otodoaccessbackend.cpp10
-rw-r--r--libopie/pim/otodoaccessbackend.h18
-rw-r--r--libopie/pim/otodoaccessxml.cpp362
-rw-r--r--libopie/pim/otodoaccessxml.h53
12 files changed, 665 insertions, 65 deletions
diff --git a/libopie/pim/opimaccessbackend.h b/libopie/pim/opimaccessbackend.h
index 5707b58..c27acbb 100644
--- a/libopie/pim/opimaccessbackend.h
+++ b/libopie/pim/opimaccessbackend.h
@@ -10,74 +10,74 @@
* OPimAccessBackend is the base class
* for all private backends
* it operates on OPimRecord as the base class
* and it's responsible for fast manipulating
* the resource the implementation takes care
* of
*/
template <class T = OPimRecord>
class OPimAccessBackend {
public:
OPimAccessBackend();
virtual ~OPimAccessBackend();
-
+
/**
* load the resource
*/
- virtual void load() = 0;
-
+ virtual bool load() = 0;
+
/**
* reload the resource
*/
- virtual void reload() = 0;
-
+ virtual bool reload() = 0;
+
/**
* save the resource and
* all it's changes
*/
- virtual void save() = 0;
-
+ virtual bool save() = 0;
+
/**
* return an array of
* all available uids
*/
virtual QArray<int> allRecords()const = 0;
-
+
/**
* queryByExample for T with the SortOrder
* sort
*/
virtual QArray<int> queryByExample( const T& t, int sort ) = 0;
-
+
/**
* find the OPimRecord with uid @param uid
* returns T and T.isEmpty() if nothing was found
*/
- virtual T find(int uid ) = 0;
-
+ virtual T find(int uid )const = 0;
+
/**
* clear the back end
*/
virtual void clear() = 0;
-
+
/**
* add T
*/
virtual bool add( const T& t ) = 0;
-
+
/**
* remove
*/
virtual bool remove( int uid ) = 0;
-
+
/**
* replace a record with T.uid()
*/
virtual bool replace( const T& t ) = 0;
};
template <class T>
OPimAccessBackend<T>::OPimAccessBackend() {
}
diff --git a/libopie/pim/opimaccesstemplate.h b/libopie/pim/opimaccesstemplate.h
index 36f5a99..31ab516 100644
--- a/libopie/pim/opimaccesstemplate.h
+++ b/libopie/pim/opimaccesstemplate.h
@@ -5,162 +5,163 @@
#include <opie/opimrecord.h>
#include <opie/opimaccessbackend.h>
#include <opie/orecordlist.h>
#include "otemplatebase.h"
/**
* Thats the frontend to our OPIE PIM
* Library. Either you want to use it's
* interface or you want to implement
* your own Access lib
- * Just create a OPimRecord and inherit from
+ * Just create a OPimRecord and inherit from
* the plugins
*/
template <class T = OPimRecord >
class OPimAccessTemplate : public OTemplateBase<T> {
public:
typedef ORecordList<T> List;
typedef OPimAccessBackend<T> BackEnd;
/**
* our sort order
* should be safe explaining
*/
enum SortOrder { WildCards = 0, IgnoreCase = 1,
RegExp = 2, ExactMatch = 4 };
/**
* c'tor BackEnd
*/
OPimAccessTemplate( BackEnd* end);
virtual ~OPimAccessTemplate();
-
+
/**
* load from the backend
*/
- virtual void load();
-
+ virtual bool load();
+
/**
* reload from the backend
*/
- virtual void reload();
-
+ virtual bool reload();
+
/**
- * save to the backend
+ * save to the backend
*/
- virtual void save();
+ virtual bool save();
/**
* if the resource was changed externally
*/
bool wasChangedExternally()const;
-
+
/**
* return a List of records
* you can iterate over them
*/
virtual List allRecords()const;
-
+
/**
- * queryByExample
+ * queryByExample
*/
virtual List queryByExample( const T& t, int sortOrder );
-
+
/**
* find the OPimRecord uid
*/
- virtual T find( int uid );
+ virtual T find( int uid )const;
/* invalidate cache here */
/**
* clears the backend and invalidates the backend
*/
virtual void clear() ;
-
+
/**
* add T to the backend
*/
virtual bool add( const T& t ) ;
/* only the uid matters */
/**
* remove T from the backend
*/
virtual bool remove( const T& t );
-
+
/**
* remove the OPimRecord with uid
*/
virtual bool remove( int uid );
-
+
/**
* replace T from backend
*/
virtual bool replace( const T& t) ;
protected:
/**
* invalidate the cache
*/
void invalidateCache();
-
+
+ void setBackEnd( BackEnd* end );
/**
* returns the backend
*/
BackEnd* backEnd();
BackEnd* m_backEnd;
};
template <class T>
OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end )
: OTemplateBase<T>(), m_backEnd( end )
{
}
template <class T>
OPimAccessTemplate<T>::~OPimAccessTemplate() {
qWarning("~OPimAccessTemplate<T>");
delete m_backEnd;
}
template <class T>
-void OPimAccessTemplate<T>::load() {
- m_backEnd->load();
+bool OPimAccessTemplate<T>::load() {
+ return m_backEnd->load();
}
template <class T>
-void OPimAccessTemplate<T>::reload() {
- m_backEnd->reload();
+bool OPimAccessTemplate<T>::reload() {
+ return m_backEnd->reload();
}
template <class T>
-void OPimAccessTemplate<T>::save() {
- m_backEnd->save();
+bool OPimAccessTemplate<T>::save() {
+ return m_backEnd->save();
}
template <class T>
OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const {
QArray<int> ints = m_backEnd->allRecords();
List lis(ints, this );
return lis;
}
template <class T>
OPimAccessTemplate<T>::List
OPimAccessTemplate<T>::queryByExample( const T& t, int sortOrder ) {
QArray<int> ints = m_backEnd->queryByExample( t, sortOrder );
List lis(ints, this );
return lis;
}
template <class T>
-T OPimAccessTemplate<T>::find( int uid ) {
+T OPimAccessTemplate<T>::find( int uid ) const{
T t = m_backEnd->find( uid );
return t;
}
template <class T>
void OPimAccessTemplate<T>::clear() {
invalidateCache();
m_backEnd->clear();
}
template <class T>
bool OPimAccessTemplate<T>::add( const T& t ) {
return m_backEnd->add( t );
}
@@ -179,13 +180,17 @@ bool OPimAccessTemplate<T>::replace( const T& t ) {
template <class T>
void OPimAccessTemplate<T>::invalidateCache() {
}
template <class T>
OPimAccessTemplate<T>::BackEnd* OPimAccessTemplate<T>::backEnd() {
return m_backEnd;
}
template <class T>
bool OPimAccessTemplate<T>::wasChangedExternally()const {
return false;
}
+template <class T>
+void OPimAccessTemplate<T>::setBackEnd( BackEnd* end ) {
+ m_backEnd = end;
+}
#endif
diff --git a/libopie/pim/orecordlist.h b/libopie/pim/orecordlist.h
index 3b30a73..75bb33c 100644
--- a/libopie/pim/orecordlist.h
+++ b/libopie/pim/orecordlist.h
@@ -5,88 +5,90 @@
#include <qarray.h>
#include "otemplatebase.h"
#include "opimrecord.h"
/**
* Our List Iterator
* it behaves like STL or Qt
*
* for(it = list.begin(); it != list.end(); ++it )
* doSomeCoolStuff( (*it) );
*/
+template <class T> class ORecordList;
template <class T = OPimRecord>
class ORecordListIterator {
+ friend class ORecordList<T>;
public:
typedef OTemplateBase<T> Base;
-
+
/**
* The c'tor used internally from
* ORecordList
*/
ORecordListIterator( const QArray<int>, const Base* );
-
+
/**
* The standard c'tor
*/
ORecordListIterator();
~ORecordListIterator();
-
+
ORecordListIterator( const ORecordListIterator& );
ORecordListIterator &operator=(const ORecordListIterator& );
-
+
/**
- * a * operator ;)
+ * a * operator ;)
* use it like this T = (*it);
*/
T &operator*();
ORecordListIterator &operator++();
ORecordListIterator &operator--();
bool operator==( const ORecordListIterator& it );
bool operator!=( const ORecordListIterator& it );
private:
QArray<int> m_uids;
int m_current;
const Base* m_temp;
bool m_end : 1;
T m_record;
/* d pointer for future versions */
class IteratorPrivate;
IteratorPrivate *d;
};
/**
* The recordlist used as a return type
* from OPimAccessTemplate
- */
+ */
template <class T = OPimRecord >
class ORecordList {
public:
typedef OTemplateBase<T> Base;
typedef ORecordListIterator<T> Iterator;
-
- /**
+
+ /**
* c'tor
*/
ORecordList( const QArray<int>& ids,
const Base* );
~ORecordList();
-
+
/**
* the first iterator
*/
Iterator begin();
-
+
/**
* the end
*/
Iterator end();
/*
ConstIterator begin()const;
ConstIterator end()const;
*/
private:
QArray<int> m_ids;
const Base* m_acc;
};
@@ -96,55 +98,57 @@ template <class T>
ORecordListIterator<T>::ORecordListIterator() {
m_current = 0;
m_temp = 0l;
m_end = true;
}
template <class T>
ORecordListIterator<T>::~ORecordListIterator() {
/* nothing to delete */
}
template <class T>
ORecordListIterator<T>::ORecordListIterator( const ORecordListIterator<T>& it) {
+ qWarning("ORecordListIterator");
m_uids = it.m_uids;
m_current = it.m_current;
m_temp = it.m_temp;
m_end = it.m_end;
m_record = it.m_record;
}
template <class T>
ORecordListIterator<T> &ORecordListIterator<T>::operator=( const ORecordListIterator<T>& it) {
m_uids = it.m_uids;
m_current = it.m_current;
m_temp = it.m_temp;
m_end = it.m_end;
m_record = it.m_record;
return *this;
}
template <class T>
T &ORecordListIterator<T>::operator*() {
+ qWarning("operator* %d %d", m_current, m_uids[m_current] );
if (!m_end )
m_record = m_temp->find( m_uids[m_current] );
else
m_record = T();
return m_record;
}
template <class T>
ORecordListIterator<T> &ORecordListIterator<T>::operator++() {
- if (m_current < m_uids.count() ) {
+ if (m_current < (int)m_uids.count() ) {
m_end = false;
++m_current;
}else
m_end = true;
return *this;
}
template <class T>
ORecordListIterator<T> &ORecordListIterator<T>::operator--() {
if ( m_current > 0 ) {
--m_current;
m_end = false;
@@ -180,22 +184,25 @@ ORecordListIterator<T>::ORecordListIterator( const QArray<int> uids,
template <class T>
ORecordList<T>::ORecordList( const QArray<int>& ids,
const Base* acc )
: m_ids( ids ), m_acc( acc )
{
}
template <class T>
ORecordList<T>::~ORecordList() {
/* nothing to do here */
}
template <class T>
ORecordList<T>::Iterator ORecordList<T>::begin() {
+ qWarning("ORecordList::begin");
Iterator it( m_ids, m_acc );
return it;
}
template <class T>
ORecordList<T>::Iterator ORecordList<T>::end() {
Iterator it( m_ids, m_acc );
it.m_end = true;
it.m_current = m_ids.count();
+
+ return it;
}
#endif
diff --git a/libopie/pim/otemplatebase.h b/libopie/pim/otemplatebase.h
index add1de4..f71417b 100644
--- a/libopie/pim/otemplatebase.h
+++ b/libopie/pim/otemplatebase.h
@@ -4,18 +4,18 @@
#include "opimrecord.h"
/**
* internal template base
*/
template <class T = OPimRecord>
class OTemplateBase {
public:
OTemplateBase() {
};
virtual ~OTemplateBase() {
}
- virtual T find( int uid ) = 0;
+ virtual T find( int uid )const = 0;
};
#endif
diff --git a/libopie/pim/otodo.cpp b/libopie/pim/otodo.cpp
index 8239ba6..b3c14e6 100644
--- a/libopie/pim/otodo.cpp
+++ b/libopie/pim/otodo.cpp
@@ -27,66 +27,71 @@ struct OTodo::OTodoData : public QShared {
QString desc;
QString sum;
QMap<QString, QString> extra;
ushort prog;
bool hasAlarmDateTime :1;
QDateTime alarmDateTime;
};
OTodo::OTodo(const OTodo &event )
: OPimRecord( event ), data( event.data )
{
data->ref();
- //qWarning("ref up");
+ qWarning("ref up");
}
OTodo::~OTodo() {
+ qWarning("~OTodo " + data->sum );
if ( data->deref() ) {
- //qWarning("OTodo::dereffing");
+ qWarning("OTodo::dereffing");
delete data;
data = 0l;
}
}
OTodo::OTodo(bool completed, int priority,
const QArray<int> &category,
const QString& summary,
const QString &description,
ushort progress,
bool hasDate, QDate date, int uid )
: OPimRecord( uid )
{
- //qWarning("OTodoData");
+ qWarning("OTodoData " + summary);
setCategories( category );
+
data = new OTodoData;
+
data->date = date;
data->isCompleted = completed;
data->hasDate = hasDate;
data->priority = priority;
data->sum = summary;
data->prog = progress;
data->desc = Qtopia::simplifyMultiLineSpace(description );
data->hasAlarmDateTime = false;
}
OTodo::OTodo(bool completed, int priority,
const QStringList &category,
const QString& summary,
const QString &description,
ushort progress,
bool hasDate, QDate date, int uid )
: OPimRecord( uid )
{
- //qWarning("OTodoData");
+ qWarning("OTodoData" + summary);
setCategories( idsFromString( category.join(";") ) );
+
data = new OTodoData;
data->date = date;
+
data->isCompleted = completed;
data->hasDate = hasDate;
data->priority = priority;
data->sum = summary;
data->prog = progress;
data->desc = Qtopia::simplifyMultiLineSpace(description );
data->hasAlarmDateTime = false;
}
bool OTodo::match( const QRegExp &regExp )const
{
if( QString::number( data->priority ).find( regExp ) != -1 ){
@@ -341,25 +346,25 @@ QMap<int, QString> OTodo::toMap() const {
}
QMap<QString, QString> OTodo::toExtraMap()const {
return data->extra;
}
/**
* change or modify looks at the ref count and either
* creates a new QShared Object or it can modify it
* right in place
*/
void OTodo::changeOrModify() {
if ( data->count != 1 ) {
- //qWarning("changeOrModify");
+ qWarning("changeOrModify");
data->deref();
OTodoData* d2 = new OTodoData();
copy(data, d2 );
data = d2;
}
}
void OTodo::copy( OTodoData* src, OTodoData* dest ) {
dest->date = src->date;
dest->isCompleted = src->isCompleted;
dest->hasDate = src->hasDate;
dest->priority = src->priority;
dest->desc = src->desc;
diff --git a/libopie/pim/otodo.h b/libopie/pim/otodo.h
index 75af44c..1443e4f 100644
--- a/libopie/pim/otodo.h
+++ b/libopie/pim/otodo.h
@@ -126,34 +126,24 @@ public:
*/
QString toRichText() const;
/**
* reimplementation
*/
QString type()const;
QString toShortText()const;
QMap<QString, QString> toExtraMap()const;
QString recordField(int id )const;
/**
- * returns a list of apps which have related items
- */
- QStringList relatedApps()const;
-
- /**
- * returns all relations for one app
- */
- QArray<int> relations( const QString& app )const;
-
- /**
* toMap puts all data into the map. int relates
* to ToDoEvent RecordFields enum
*/
QMap<int, QString> toMap()const;
/**
* Set if this Todo is completed
*/
void setCompleted(bool completed );
/**
* set if this todo got an end data
diff --git a/libopie/pim/otodoaccess.cpp b/libopie/pim/otodoaccess.cpp
new file mode 100644
index 0000000..a65cf5c
--- a/dev/null
+++ b/libopie/pim/otodoaccess.cpp
@@ -0,0 +1,71 @@
+#include <qdatetime.h>
+
+#include <qpe/alarmserver.h>
+
+#include "otodoaccessxml.h"
+#include "otodoaccess.h"
+
+
+OTodoAccess::OTodoAccess( OTodoAccessBackend* end )
+ : QObject(), OPimAccessTemplate<OTodo>( end ), m_todoBackEnd( end )
+{
+ if (end == 0l )
+ m_todoBackEnd = new OTodoAccessXML( "Todolist" );
+
+ setBackEnd( m_todoBackEnd );
+}
+OTodoAccess::~OTodoAccess() {
+ qWarning("~OTodoAccess");
+}
+void OTodoAccess::mergeWith( const QValueList<OTodo>& list ) {
+ QValueList<OTodo>::ConstIterator it;
+ for ( it = list.begin(); it != list.end(); ++it ) {
+ replace( (*it) );
+ }
+}
+OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start,
+ const QDate& end,
+ bool includeNoDates ) {
+ QArray<int> ints = m_todoBackEnd->effectiveToDos( start, end, includeNoDates );
+
+ List lis( ints, this );
+ return lis;
+}
+OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start,
+ bool includeNoDates ) {
+ return effectiveToDos( start, QDate::currentDate(),
+ includeNoDates );
+}
+OTodoAccess::List OTodoAccess::overDue() {
+ List lis( m_todoBackEnd->overDue(), this );
+ return lis;
+}
+void OTodoAccess::addAlarm( const OTodo& event) {
+ if (!event.hasAlarmDateTime() )
+ return;
+
+ QDateTime now = QDateTime::currentDateTime();
+ QDateTime schedule = event.alarmDateTime();
+
+ if ( schedule > now ){
+ AlarmServer::addAlarm( schedule,
+ "QPE/Application/todolist",
+ "alarm(QDateTime,int)", event.uid() );
+
+ }
+}
+void OTodoAccess::delAlarm( int uid) {
+
+ QDateTime schedule; // Create null DateTime
+
+ // I hope this will remove all scheduled alarms
+ // with the given uid !?
+ // If not: I have to rethink how to remove already
+ // scheduled events... (se)
+ // it should be fine -zecke
+ qWarning("Removing alarm for event with uid %d", uid );
+ AlarmServer::deleteAlarm( schedule ,
+ "QPE/Application/todolist",
+ "alarm(QDateTime,int)", uid );
+}
+
diff --git a/libopie/pim/otodoaccess.h b/libopie/pim/otodoaccess.h
new file mode 100644
index 0000000..c43efe9
--- a/dev/null
+++ b/libopie/pim/otodoaccess.h
@@ -0,0 +1,79 @@
+#ifndef OPIE_TODO_ACCESS_H
+#define OPIE_TODO_ACCESS_H
+
+#include <qobject.h>
+#include <qvaluelist.h>
+
+#include "otodo.h"
+#include "otodoaccessbackend.h"
+#include "opimaccesstemplate.h"
+
+
+/**
+ * OTodoAccess
+ * the class to get access to
+ * the todolist
+ */
+class OTodoAccess : public QObject, public OPimAccessTemplate<OTodo> {
+ Q_OBJECT
+public:
+ /**
+ * if you use 0l
+ * the default resource will be
+ * icked up
+ */
+ OTodoAccess( OTodoAccessBackend* = 0l);
+ ~OTodoAccess();
+
+
+ /* our functions here */
+ /**
+ * include todos from start to end
+ * includeNoDates whether or not to include
+ * events with no dates
+ */
+ List effectiveToDos( const QDate& start,
+ const QDate& end,
+ bool includeNoDates = true );
+
+ /**
+ * start
+ * end date taken from the currentDate()
+ */
+ List effectiveToDos( const QDate& start,
+ bool includeNoDates = true );
+
+
+ /**
+ * return overdue OTodos
+ */
+ List overDue();
+ /**
+ * merge a list of OTodos into
+ * the resource
+ */
+ void mergeWith( const QValueList<OTodo>& );
+
+ /**
+ * add an Alarm to the AlarmServer
+ */
+ void addAlarm( const OTodo& );
+
+ /**
+ * delete an alarm with the uid from
+ * the alarm server
+ */
+ void delAlarm( int uid );
+
+signals:
+ /**
+ * if the OTodoAccess was changed
+ */
+ void signalChanged( const OTodoAccess* );
+private:
+ OTodoAccessBackend* m_todoBackEnd;
+ class OTodoAccessPrivate;
+ OTodoAccessPrivate* d;
+};
+
+#endif
diff --git a/libopie/pim/otodoaccessbackend.cpp b/libopie/pim/otodoaccessbackend.cpp
new file mode 100644
index 0000000..baaeecc
--- a/dev/null
+++ b/libopie/pim/otodoaccessbackend.cpp
@@ -0,0 +1,10 @@
+
+#include "otodoaccessbackend.h"
+
+OTodoAccessBackend::OTodoAccessBackend()
+ : OPimAccessBackend<OTodo>()
+{
+}
+OTodoAccessBackend::~OTodoAccessBackend() {
+
+}
diff --git a/libopie/pim/otodoaccessbackend.h b/libopie/pim/otodoaccessbackend.h
new file mode 100644
index 0000000..ebe2189
--- a/dev/null
+++ b/libopie/pim/otodoaccessbackend.h
@@ -0,0 +1,18 @@
+#ifndef OPIE_TODO_ACCESS_BACKEND_H
+#define OPIE_TODO_ACCESS_BACKEND_H
+
+#include "otodo.h"
+#include "opimaccessbackend.h"
+
+class OTodoAccessBackend : public OPimAccessBackend<OTodo> {
+public:
+ OTodoAccessBackend();
+ ~OTodoAccessBackend();
+ virtual QArray<int> effectiveToDos( const QDate& start,
+ const QDate& end,
+ bool includeNoDates ) = 0;
+ virtual QArray<int> overDue() = 0;
+
+};
+
+#endif
diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp
new file mode 100644
index 0000000..21756c9
--- a/dev/null
+++ b/libopie/pim/otodoaccessxml.cpp
@@ -0,0 +1,362 @@
+#include <qfile.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 = false;
+ m_changed = false;
+ /* initialize dict */
+ /*
+ * UPDATE dict if you change anything!!!
+ */
+ QAsciiDict<int> dict(15);
+ 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("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) );
+ dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) );
+
+ Opie::XMLElement *root = Opie::XMLElement::load( m_file );
+ int day, year, month;
+ day = year = month = -1;
+
+ /* if opened */
+ if ( root != 0l ) {
+ Opie::XMLElement *element = root->firstChild();
+ if ( element == 0l )
+ return false;
+
+ element = element->firstChild();
+
+ while ( element ) {
+ if ( element->tagName() != QString::fromLatin1("Task") ) {
+ element = element->nextChild();
+ continue;
+ }
+ /* here is the right element for a task */
+ OTodo ev = todo( &dict, element );
+ m_events.insert( ev.uid(), ev );
+
+ element = element->nextChild();
+ }
+ return true;
+ }else {
+ qWarning("could not parse");
+ return false;;
+ }
+ delete root;
+
+ m_opened = true;
+ return true;
+}
+bool OTodoAccessXML::reload() {
+ return load();
+}
+bool OTodoAccessXML::save() {
+ if (!m_opened || !m_changed )
+ 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();
+
+ if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
+ qWarning("error renaming");
+ QFile::remove( strNewFile );
+ }
+
+ m_changed = false;
+ return true;
+}
+QArray<int> OTodoAccessXML::allRecords()const {
+ QArray<int> ids( m_events.count() );
+ QMap<int, OTodo>::ConstIterator it;
+ int i = 0;
+
+ for ( it = m_events.begin(); it != m_events.end(); ++it ) {
+ ids[i] = it.key();
+ i++;
+ }
+ return ids;
+}
+QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int sort ) {
+ QArray<int> ids(0);
+ return ids;
+}
+OTodo OTodoAccessXML::find( int uid )const {
+ OTodo todo;
+ todo.setUid( 0 ); // isEmpty()
+ QMap<int, OTodo>::ConstIterator it = m_events.find( uid );
+ if ( it != m_events.end() )
+ todo = it.data();
+
+ return todo;
+}
+void OTodoAccessXML::clear() {
+ if (m_opened )
+ m_changed = true;
+
+ m_events.clear();
+}
+bool OTodoAccessXML::add( const OTodo& todo ) {
+ m_changed = true;
+ m_events.insert( todo.uid(), todo );
+
+ return true;
+}
+bool OTodoAccessXML::remove( int uid ) {
+ m_changed = true;
+ m_events.remove( uid );
+
+ return true;
+}
+bool OTodoAccessXML::replace( const OTodo& todo) {
+ m_changed = true;
+ m_events.replace( todo.uid(), todo );
+
+ return true;
+}
+QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
+ const QDate& end,
+ bool includeNoDates ) {
+ QArray<int> ids( m_events.count() );
+ QMap<int, OTodo>::Iterator it;
+
+ int i = 0;
+ for ( it = m_events.begin(); it != m_events.end(); ++it ) {
+ if ( !it.data().hasDueDate() ) {
+ if ( includeNoDates ) {
+ ids[i] = it.key();
+ i++;
+ }
+ }else if ( it.data().dueDate() >= start &&
+ it.data().dueDate() <= end ) {
+ ids[i] = it.key();
+ i++;
+ }
+ }
+ ids.resize( i );
+ return ids;
+}
+QArray<int> OTodoAccessXML::overDue() {
+ QArray<int> ids( m_events.count() );
+ int i = 0;
+
+ QMap<int, OTodo>::Iterator it;
+ for ( it = m_events.begin(); it != m_events.end(); ++it ) {
+ if ( it.data().isOverdue() ) {
+ ids[i] = it.key();
+ i++;
+ }
+ }
+ ids.resize( i );
+ return ids;
+}
+
+
+/* private */
+OTodo OTodoAccessXML::todo( QAsciiDict<int>* dict, Opie::XMLElement* element)const {
+ qWarning("parse to do from XMLElement" );
+ OTodo ev;
+ QMap<QString, QString> attributes = element->attributes();
+ QMap<QString, QString>::Iterator it;
+
+ int *find=0;
+ int day, month, year;
+ day = month = year = -1;
+ for ( it = attributes.begin(); it != attributes.end(); ++it ) {
+ find = (*dict)[ it.key() ];
+ if (!find ) {
+ qWarning("Unknown option" + it.key() );
+ ev.setCustomField( it.key(), it.data() );
+ continue;
+ }
+
+ switch( *find ) {
+ case OTodo::Uid:
+ ev.setUid( it.data().toInt() );
+ break;
+ case OTodo::Category:
+ ev.setCategories( ev.idsFromString( it.data() ) );
+ break;
+ case OTodo::HasDate:
+ ev.setHasDueDate( it.data().toInt() );
+ break;
+ case OTodo::Completed:
+ ev.setCompleted( it.data().toInt() );
+ break;
+ case OTodo::Description:
+ ev.setDescription( it.data() );
+ break;
+ case OTodo::Summary:
+ ev.setSummary( it.data() );
+ break;
+ case OTodo::Priority:
+ ev.setPriority( it.data().toInt() );
+ break;
+ case OTodo::DateDay:
+ day = it.data().toInt();
+ break;
+ case OTodo::DateMonth:
+ month = it.data().toInt();
+ break;
+ case OTodo::DateYear:
+ year = it.data().toInt();
+ break;
+ case OTodo::Progress:
+ ev.setProgress( it.data().toInt() );
+ break;
+ case OTodo::CrossReference:
+ {
+ /*
+ * A cross refernce looks like
+ * appname,id;appname,id
+ * we need to split it up
+ */
+ QStringList refs = QStringList::split(';', it.data() );
+ QStringList::Iterator strIt;
+ for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
+ int pos = (*strIt).find(',');
+ if ( pos > -1 )
+ ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
+
+ }
+ break;
+ }
+ case OTodo::HasAlarmDateTime:
+ ev.setHasAlarmDateTime( it.data().toInt() );
+ break;
+ case OTodo::AlarmDateTime: {
+ /* this sounds better ;) zecke */
+ ev.setAlarmDateTime( TimeConversion::fromISO8601( it.data().local8Bit() ) );
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if ( ev.hasDueDate() ) {
+ QDate date( year, month, day );
+ ev.setDueDate( date );
+ }
+
+ return ev;
+}
+QString OTodoAccessXML::toString( const OTodo& ev )const {
+ QString str;
+
+ str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
+ str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
+ str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
+ str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
+
+ str += "Categories=\"" + toString( ev.categories() ) + "\" ";
+ str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
+ str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
+
+ if ( ev.hasDueDate() ) {
+ str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
+ str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
+ str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
+ }
+ str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
+
+// append the extra options
+ /* FIXME Qtopia::Record this is currently not
+ * possible you can set custom fields
+ * but don' iterate over the list
+ * I may do #define private protected
+ * for this case - cough --zecke
+ */
+ /*
+ QMap<QString, QString> extras = ev.extras();
+ QMap<QString, QString>::Iterator extIt;
+ for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
+ str += extIt.key() + "=\"" + extIt.data() + "\" ";
+ */
+ // cross refernce
+ QStringList list = ev.relatedApps();
+ QStringList::Iterator listIt;
+ QString refs;
+ str += "CrossReference=\"";
+ bool added = false;
+ for ( listIt = list.begin(); listIt != list.end(); ++listIt ) {
+ added = true;
+ QArray<int> ints = ev.relations( (*listIt) );
+ for ( uint i = 0; i< ints.count(); i++ ) {
+ str += (*listIt) + "," + QString::number( i ) + ";";
+ }
+ }
+ if ( added )
+ str = str.remove( str.length()-1, 1 );
+
+ str += "\" ";
+
+ str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" ";
+
+ return str;
+}
+QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
+ return Qtopia::Record::idsToString( ints );
+}
diff --git a/libopie/pim/otodoaccessxml.h b/libopie/pim/otodoaccessxml.h
new file mode 100644
index 0000000..be9109d
--- a/dev/null
+++ b/libopie/pim/otodoaccessxml.h
@@ -0,0 +1,53 @@
+#ifndef OPIE_TODO_ACCESS_XML_H
+#define OPIE_TODO_ACCESS_XML_H
+
+#include <qasciidict.h>
+#include <qmap.h>
+
+#include "otodoaccessbackend.h"
+
+namespace Opie {
+ class XMLElement;
+};
+
+class OTodoAccessXML : public OTodoAccessBackend {
+public:
+ /**
+ * fileName if Empty we will use the default path
+ */
+ OTodoAccessXML( const QString& appName,
+ const QString& fileName = QString::null );
+ ~OTodoAccessXML();
+
+ bool load();
+ bool reload();
+ bool save();
+
+ QArray<int> allRecords()const;
+ QArray<int> queryByExample( const OTodo&, int sort );
+ OTodo find( int uid )const;
+ void clear();
+ bool add( const OTodo& );
+ bool remove( int uid );
+ bool replace( const OTodo& );
+
+ /* our functions */
+ QArray<int> effectiveToDos( const QDate& start,
+ const QDate& end,
+ bool includeNoDates );
+ QArray<int> overDue();
+private:
+ OTodo todo( QAsciiDict<int>*, Opie::XMLElement* )const;
+ QString toString( const OTodo& )const;
+ QString toString( const QArray<int>& ints ) const;
+ QMap<int, OTodo> m_events;
+ QString m_file;
+ QString m_app;
+ bool m_opened : 1;
+ bool m_changed : 1;
+ class OTodoAccessXMLPrivate;
+ OTodoAccessXMLPrivate* d;
+
+};
+
+#endif