summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/opimaccessbackend.h29
-rw-r--r--libopie/pim/opimaccesstemplate.h82
-rw-r--r--libopie/pim/opimrecord.cpp90
-rw-r--r--libopie/pim/opimrecord.h117
-rw-r--r--libopie/pim/orecordlist.h44
-rw-r--r--libopie/pim/otodo.cpp507
-rw-r--r--libopie/pim/otodo.h205
-rw-r--r--libopie2/opiepim/backend/opimaccessbackend.h29
-rw-r--r--libopie2/opiepim/core/opimaccesstemplate.h82
-rw-r--r--libopie2/opiepim/core/opimrecord.cpp90
-rw-r--r--libopie2/opiepim/core/opimrecord.h117
-rw-r--r--libopie2/opiepim/orecordlist.h44
-rw-r--r--libopie2/opiepim/otodo.cpp507
-rw-r--r--libopie2/opiepim/otodo.h205
14 files changed, 2148 insertions, 0 deletions
diff --git a/libopie/pim/opimaccessbackend.h b/libopie/pim/opimaccessbackend.h
new file mode 100644
index 0000000..d9af589
--- a/dev/null
+++ b/libopie/pim/opimaccessbackend.h
@@ -0,0 +1,29 @@
+#ifndef OPIE_PIM_ACCESS_BACKEND
+#define OPIE_PIM_ACCESS_BACKEND
+
+#include <qarray.h>
+
+#include <opie/opimrecord.h>
+
+template <class T = OPimRecord>
+class OPimAccessBackend {
+public:
+ OPimAccessBackend() {
+ }
+ ~OPimAccessBackend() {
+ }
+ virtual void load() = 0;
+ virtual void reload() = 0;
+ virtual void save() = 0;
+ virtual QArray<int> allRecords() = 0;
+ virtual QArray<int> queryByExample( const T& t, int sort ) = 0;
+ virtual T find(int uid ) = 0;
+ virtual void clear() = 0;
+ virtual bool add( const T& t ) = 0;
+ virtual bool remove( int uid ) = 0;
+ virtual void replace( const T& t ) = 0;
+
+
+};
+
+#endif
diff --git a/libopie/pim/opimaccesstemplate.h b/libopie/pim/opimaccesstemplate.h
new file mode 100644
index 0000000..f2a241d
--- a/dev/null
+++ b/libopie/pim/opimaccesstemplate.h
@@ -0,0 +1,82 @@
+#ifndef OPIE_PIM_ACCESS_TEMPLATE_H
+#define OPIE_PIM_ACCESS_TEMPLATE_H
+
+#include <qarray.h>
+
+#include <opie/opimrecord.h>
+#include <opie/opimaccessbackend.h>
+#include <opie/orecordlist.h>
+
+template <class T = OPimRecord >
+class OPimAccessTemplate {
+public:
+ typedef ORecordList<T> List;
+ typedef OPimAccessBackend<T> BackEnd;
+ OPimAccessTemplate( BackEnd* end)
+ : m_backEnd( end ) {
+ }
+ ~OPimAccessTemplate() {
+ delete m_backEnd;
+ }
+ virtual void load() {
+ m_backEnd->load();
+ }
+ virtual void reload() {
+ m_backEnd->reload();
+ }
+ virtual void save() {
+ m_backEnd->save();
+ }
+
+ /*
+ *do array to Records conversion
+ * QArray<int> ids
+ */
+ virtual List allRecords()const {
+ QArray<int> ints = m_backEnd->allRecords();
+
+ List lis( ints, this );
+ return lis;
+ }
+ virtual List queryByExample( const T& t, int sortOrder ) {
+ QArray<int> ints = m_backEnd->query( t, sortOrder );
+ List lis( ints, this );
+
+ return lis;
+ }
+ /* implement QCache here */
+ virtual T find( int uid ) {
+ T t = m_backEnd->find( uid );
+ return t;
+ }
+
+ /* invalidate cache here */
+ virtual void clear() {
+ invalidateCache();
+ m_backEnd->clear();
+ }
+ virtual bool add( const T& t ) {
+ return m_backEnd->add( t );
+ }
+
+ /* only the uid matters */
+ virtual bool remove( const T& t ) {
+ /* remove from cache */
+ return m_backEnd->remove( t.uid() );
+ }
+ virtual bool remove( int uid ) {
+ /* remove from cache */
+ return m_backEnd->remove(uid);
+ }
+ virtual bool replace( const T& t) {
+ return m_backEnd->replace( t );
+ }
+protected:
+ void invalidateCache() {
+
+ }
+ BackEnd* m_backEnd;
+
+};
+
+#endif
diff --git a/libopie/pim/opimrecord.cpp b/libopie/pim/opimrecord.cpp
new file mode 100644
index 0000000..95de1df
--- a/dev/null
+++ b/libopie/pim/opimrecord.cpp
@@ -0,0 +1,90 @@
+#include "opimrecord.h"
+
+OPimRecord::OPimRecord( int uid )
+ : Qtopia::Record() {
+ setUid( uid );
+ if ( uid == 1 )
+ assignUid();
+}
+OPimRecord::~OPimRecord() {
+}
+OPimRecord::OPimRecord( OPimRecord& rec )
+ : Qtopia::Record( rec )
+{
+ (*this) = rec;
+}
+
+OPimRecord &OPimRecord::operator=( const OPimRecord& rec) {
+ /* how do I call the parent copy operator ? */
+ setUid( rec.uid() );
+ setCategories( rec.categories() );
+ return *this;
+}
+QStringList OPimRecord::categoryNames()const {
+ QStringList list;
+
+ return list;
+}
+void OPimRecord::setCategoryName( const QStringList& ) {
+
+}
+void OPimRecord::addCategoryName( const QString& ) {
+
+}
+bool OPimRecord::isEmpty()const {
+ return ( uid() == 0 );
+}
+QStringList OPimRecord::relatedApps()const{
+ QStringList list;
+ QMap<QString, QArray<int> >::ConstIterator it;
+ for ( it = m_relations.begin(); it != m_relations.end(); ++it ) {
+ list << it.key();
+ }
+ return list;
+}
+QArray<int> OPimRecord::relations(const QString& app )const {
+ QArray<int> tmp;
+ QMap<QString, QArray<int> >::ConstIterator it;
+ it = m_relations.find( app);
+ if ( it != m_relations.end() )
+ tmp = it.data();
+ return tmp;
+}
+void OPimRecord::clearRelation( const QString& app ) {
+ m_relations.remove( app );
+}
+void OPimRecord::addRelation( const QString& app, int id ) {
+
+ QMap<QString, QArray<int> >::Iterator it;
+ QArray<int> tmp;
+
+ it = m_relations.find( app );
+ if ( it == m_relations.end() ) {
+ tmp.resize(1 );
+ tmp[0] = id;
+ }else{
+ tmp = it.data();
+ tmp.resize( tmp.size() + 1 );
+ tmp[tmp.size() - 1] = id;
+ }
+ m_relations.replace( app, tmp );
+}
+void OPimRecord::setRelations( const QString& app, QArray<int> ids ) {
+
+ QMap<QString, QArray<int> >::Iterator it;
+ QArray<int> tmp;
+
+ it = m_relations.find( app);
+ if ( it == m_relations.end() ) {
+ tmp = ids;
+ }else{
+ tmp = it.data();
+ int offset = tmp.size()-1;
+ tmp.resize( tmp.size() + ids.size() );
+ for (uint i = 0; i < ids.size(); i++ ) {
+ tmp[offset+i] = ids[i];
+ }
+
+ }
+ m_relations.replace( app, tmp );
+}
diff --git a/libopie/pim/opimrecord.h b/libopie/pim/opimrecord.h
new file mode 100644
index 0000000..a0e0413
--- a/dev/null
+++ b/libopie/pim/opimrecord.h
@@ -0,0 +1,117 @@
+#ifndef OPIE_PIM_RECORD_H
+#define OPIE_PIM_RECORD_H
+
+#include <qmap.h>
+#include <qstring.h>
+#include <qstringlist.h>
+
+#include <qpe/palmtoprecord.h>
+
+class OPimRecord : public Qtopia::Record {
+public:
+ /**
+ * uid of 0 isEmpty
+ * uid of 1 will be assigned a new one
+ */
+ OPimRecord(int uid = 0);
+ ~OPimRecord();
+
+ /**
+ * copy c'tor
+ */
+ OPimRecord( OPimRecord& rec );
+
+ /**
+ * copy operator
+ */
+ OPimRecord &operator=( const OPimRecord& );
+
+ /**
+ * category names resolved
+ */
+ QStringList categoryNames()const;
+
+ /**
+ * set category names they will be resolved
+ */
+ void setCategoryName( const QStringList& );
+
+ /**
+ * addCategoryName adds a name
+ * to the internal category list
+ */
+ void addCategoryName( const QString& );
+
+ /**
+ * if a Record isEmpty
+ */
+ virtual bool isEmpty()const;
+
+ /**
+ * toRichText summary
+ */
+ virtual QString toRichText()const = 0;
+
+ /**
+ * a small one line summary
+ */
+ virtual QString toShortText()const = 0;
+
+ /**
+ * the name of the Record
+ */
+ virtual QString type()const = 0;
+
+ /**
+ * converts the internal structure to a map
+ */
+ virtual QMap<int, QString> toMap()const = 0;
+
+ /**
+ * key value representation of extra items
+ */
+ virtual QMap<QString, QString> toExtraMap()const = 0;
+
+ /**
+ * the name for a recordField
+ */
+ virtual QString recordField(int)const = 0;
+
+ /**
+ * the related apps names
+ */
+ QStringList relatedApps()const;
+
+ /**
+ * the realtions between an app
+ */
+ QArray<int> relations( const QString& app )const;
+
+ /**
+ *
+ */
+ void clearRelation( const QString& app );
+
+ /**
+ *
+ */
+ void addRelation( const QString& app, int id );
+
+ /**
+ *
+ */
+ void setRelations( const QString&, QArray<int> ids );
+
+protected:
+ QString crossToString()const;
+
+private:
+ class OPimRecordPrivate;
+ OPimRecordPrivate *d;
+ QMap<QString, QArray<int> > m_relations;
+
+};
+
+
+
+#endif
diff --git a/libopie/pim/orecordlist.h b/libopie/pim/orecordlist.h
new file mode 100644
index 0000000..c17186f
--- a/dev/null
+++ b/libopie/pim/orecordlist.h
@@ -0,0 +1,44 @@
+
+#ifndef OPIE_RECORD_LIST_H
+#define OPIE_RECORD_LIST_H
+
+#include <opie/opimaccesstemplate.h>
+#include <opie/opimrecord.h>
+
+template <class T = OPimRecord >
+class ORecordList {
+public:
+ class Iterator {
+ friend class ORecordList;
+ public:
+ Iterator() {}
+ ~Iterator() {}
+ Iterator(const Iterator& ) {}
+ Iterator &operator=(const Iterator& );
+ T &operator*() {}
+ Iterator &operator++();
+
+ bool operator==( const Iterator& it );
+ bool operator!=( const Iterator& it );
+
+ }
+ ORecordList( const QArray<int>& ids,
+ OPimAccessTemplate<T>* acc )
+ : m_ids(ids ), m_acc( acc ) {
+
+ }
+ ~ORecordList() {
+
+ }
+ Iterator begin();
+ Iterator end();
+ /*
+ ConstIterator begin()const;
+ ConstIterator end()const;
+ */
+private:
+ QArray<int> ids;
+ OPimAccessTemplate<T>* m_acc;
+};
+
+#endif
diff --git a/libopie/pim/otodo.cpp b/libopie/pim/otodo.cpp
new file mode 100644
index 0000000..d8e0447
--- a/dev/null
+++ b/libopie/pim/otodo.cpp
@@ -0,0 +1,507 @@
+
+#include <qobject.h>
+#include <qshared.h>
+
+
+
+#include <qpe/palmtopuidgen.h>
+#include <qpe/stringutil.h>
+#include <qpe/palmtoprecord.h>
+#include <qpe/stringutil.h>
+#include <qpe/categories.h>
+#include <qpe/categoryselect.h>
+
+#include "todoevent.h"
+
+using namespace Opie;
+
+Qtopia::UidGen ToDoEvent::m_gen;
+
+struct ToDoEvent::ToDoEventData : public QShared {
+ ToDoEventData() : QShared() {
+ };
+
+ QDate date;
+ bool isCompleted:1;
+ bool hasDate:1;
+ int priority;
+ QStringList category;
+ QString desc;
+ QString sum;
+ QMap<QString, QString> extra;
+ QMap<QString, QArray<int> > relations;
+ int uid;
+ ushort prog;
+ bool hasAlarmDateTime :1;
+ QDateTime alarmDateTime;
+};
+
+ToDoEvent::ToDoEvent(const ToDoEvent &event )
+ : data( event.data )
+{
+ data->ref();
+ //qWarning("ref up");
+}
+ToDoEvent::~ToDoEvent() {
+ if ( data->deref() ) {
+ //qWarning("ToDoEvent::dereffing");
+ delete data;
+ data = 0l;
+ }
+}
+
+ToDoEvent::ToDoEvent(bool completed, int priority,
+ const QStringList &category,
+ const QString& summary,
+ const QString &description,
+ ushort progress,
+ bool hasDate, QDate date, int uid )
+{
+ //qWarning("ToDoEventData");
+ data = new ToDoEventData;
+ data->date = date;
+ data->isCompleted = completed;
+ data->hasDate = hasDate;
+ data->priority = priority;
+ data->category = category;
+ data->sum = summary;
+ data->prog = progress;
+ data->desc = Qtopia::simplifyMultiLineSpace(description );
+ if (uid == -1 ) {
+ uid = m_gen.generate();
+
+ }// generated the ids
+ m_gen.store( uid );
+
+ data->uid = uid;
+ data->hasAlarmDateTime = false;
+
+}
+QArray<int> ToDoEvent::categories()const
+{
+ qWarning( "ToDoEvent:cats" + data->category.join(";") );
+ QArray<int> array(data->category.count() ); // currently the datebook can be only in one category
+ array = Qtopia::Record::idsFromString( data->category.join(";") );
+ return array;
+}
+bool ToDoEvent::match( const QRegExp &regExp )const
+{
+ if( QString::number( data->priority ).find( regExp ) != -1 ){
+ return true;
+ }else if( data->hasDate && data->date.toString().find( regExp) != -1 ){
+ return true;
+ }else if(data->desc.find( regExp ) != -1 ){
+ return true;
+ }
+ return false;
+}
+bool ToDoEvent::isCompleted() const
+{
+ return data->isCompleted;
+}
+bool ToDoEvent::hasDueDate() const
+{
+ return data->hasDate;
+}
+bool ToDoEvent::hasAlarmDateTime() const
+{
+ return data->hasAlarmDateTime;
+}
+int ToDoEvent::priority()const
+{
+ return data->priority;
+}
+QStringList ToDoEvent::allCategories()const
+{
+ return data->category;
+}
+QString ToDoEvent::extra(const QString& )const
+{
+ return QString::null;
+}
+QString ToDoEvent::summary() const
+{
+ return data->sum;
+}
+ushort ToDoEvent::progress() const
+{
+ return data->prog;
+}
+QStringList ToDoEvent::relatedApps() const
+{
+ QStringList list;
+ QMap<QString, QArray<int> >::ConstIterator it;
+ for ( it = data->relations.begin(); it != data->relations.end(); ++it ) {
+ list << it.key();
+ }
+ return list;
+}
+QArray<int> ToDoEvent::relations( const QString& app)const
+{
+ QArray<int> tmp;
+ QMap<QString, QArray<int> >::ConstIterator it;
+ it = data->relations.find( app);
+ if ( it != data->relations.end() )
+ tmp = it.data();
+ return tmp;
+}
+void ToDoEvent::insertCategory(const QString &str )
+{
+ changeOrModify();
+ qWarning("insert category;" + str );
+ data->category.append( str );
+}
+void ToDoEvent::clearCategories()
+{
+ changeOrModify();
+ data->category.clear();
+}
+void ToDoEvent::setCategories(const QStringList &list )
+{
+ changeOrModify();
+ qWarning("set categories" + list.join(";") );
+ data->category = list;
+}
+QDate ToDoEvent::dueDate()const
+{
+ return data->date;
+}
+
+QDateTime ToDoEvent::alarmDateTime() const
+{
+ return data->alarmDateTime;
+}
+
+QString ToDoEvent::description()const
+{
+ return data->desc;
+}
+void ToDoEvent::setCompleted( bool completed )
+{
+ changeOrModify();
+ data->isCompleted = completed;
+}
+void ToDoEvent::setHasDueDate( bool hasDate )
+{
+ changeOrModify();
+ data->hasDate = hasDate;
+}
+void ToDoEvent::setHasAlarmDateTime( bool hasAlarmDateTime )
+{
+ changeOrModify();
+ data->hasAlarmDateTime = hasAlarmDateTime;
+}
+void ToDoEvent::setDescription(const QString &desc )
+{
+ changeOrModify();
+ data->desc = Qtopia::simplifyMultiLineSpace(desc );
+}
+void ToDoEvent::setExtra( const QString&, const QString& )
+{
+
+}
+void ToDoEvent::setSummary( const QString& sum )
+{
+ changeOrModify();
+ data->sum = sum;
+}
+void ToDoEvent::setCategory( const QString &cat )
+{
+ changeOrModify();
+ //qWarning("setCategory %s", cat.latin1() );
+ data->category.clear();
+ data->category << cat;
+}
+void ToDoEvent::setPriority(int prio )
+{
+ changeOrModify();
+ data->priority = prio;
+}
+void ToDoEvent::setDueDate( QDate date )
+{
+ changeOrModify();
+ data->date = date;
+}
+void ToDoEvent::setAlarmDateTime( const QDateTime& alarm )
+{
+ changeOrModify();
+ data->alarmDateTime = alarm;
+}
+void ToDoEvent::addRelated( const QString &app, int id )
+{
+ changeOrModify();
+
+ QMap<QString, QArray<int> >::Iterator it;
+ QArray<int> tmp;
+ it = data->relations.find( app );
+ if ( it == data->relations.end() ) {
+ tmp.resize(1 );
+ tmp[0] = id;
+ }else{
+ tmp = it.data();
+ tmp.resize( tmp.size() + 1 );
+ tmp[tmp.size() - 1] = id;
+ }
+ data->relations.replace( app, tmp );
+}
+void ToDoEvent::addRelated(const QString& app, QArray<int> ids )
+{
+ changeOrModify();
+
+ QMap<QString, QArray<int> >::Iterator it;
+ QArray<int> tmp;
+ it = data->relations.find( app);
+ if ( it == data->relations.end() ) { // not there
+ /** tmp.resize( ids.size() ); stupid??
+ */
+ tmp = ids;
+ }else{
+ tmp = it.data();
+ int offset = tmp.size()-1;
+ tmp.resize( tmp.size() + ids.size() );
+ for (uint i = 0; i < ids.size(); i++ ) {
+ tmp[offset+i] = ids[i];
+ }
+
+ }
+ data->relations.replace( app, tmp );
+}
+void ToDoEvent::clearRelated( const QString& app )
+{
+ changeOrModify();
+ data->relations.remove( app );
+}
+bool ToDoEvent::isOverdue( )
+{
+ if( data->hasDate )
+ return QDate::currentDate() > data->date;
+ return false;
+}
+void ToDoEvent::setProgress(ushort progress )
+{
+ changeOrModify();
+ data->prog = progress;
+}
+/*!
+ Returns a richt text string
+*/
+QString ToDoEvent::richText() const
+{
+ QString text;
+ QStringList catlist;
+
+ // Description of the todo
+ if ( !summary().isEmpty() ) {
+ text += "<b>" + QObject::tr( "Summary:") + "</b><br>";
+ text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
+ }
+ if( !description().isEmpty() ){
+ text += "<b>" + QObject::tr( "Description:" ) + "</b><br>";
+ text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) ;
+ }
+ text += "<br><br><br>";
+
+ text += "<b>" + QObject::tr( "Priority:") +" </b>"
+ + QString::number( priority() ) + " <br>";
+ text += "<b>" + QObject::tr( "Progress:") + " </b>"
+ + QString::number( progress() ) + " %<br>";
+ if (hasDueDate() ){
+ text += "<b>" + QObject::tr( "Deadline:") + " </b>";
+ text += dueDate().toString();
+ text += "<br>";
+ }
+ if (hasAlarmDateTime() ){
+ text += "<b>" + QObject::tr( "Alarmed Notification:") + " </b>";
+ text += alarmDateTime().toString();
+ text += "<br>";
+ }
+
+ // Open database of all categories and get the list of
+ // the categories this todoevent belongs to.
+ // Then print them...
+ // I am not sure whether there is no better way doing this !?
+ Categories catdb;
+ bool firstloop = true;
+ catdb.load( categoryFileName() );
+ catlist = allCategories();
+
+ text += "<b>" + QObject::tr( "Category:") + "</b> ";
+ for ( QStringList::Iterator it = catlist.begin(); it != catlist.end(); ++it ) {
+ if (!firstloop){
+ text += ", ";
+ }
+ firstloop = false;
+ text += catdb.label ("todo", (*it).toInt());
+ }
+ text += "<br>";
+ return text;
+}
+
+bool ToDoEvent::operator<( const ToDoEvent &toDoEvent )const{
+ if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
+ if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
+ if( hasDueDate() && toDoEvent.hasDueDate() ){
+ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
+ return priority() < toDoEvent.priority();
+ }else{
+ return dueDate() < toDoEvent.dueDate();
+ }
+ }
+ return false;
+}
+bool ToDoEvent::operator<=(const ToDoEvent &toDoEvent )const
+{
+ if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
+ if( !hasDueDate() && toDoEvent.hasDueDate() ) return true;
+ if( hasDueDate() && toDoEvent.hasDueDate() ){
+ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
+ return priority() <= toDoEvent.priority();
+ }else{
+ return dueDate() <= toDoEvent.dueDate();
+ }
+ }
+ return true;
+}
+bool ToDoEvent::operator>(const ToDoEvent &toDoEvent )const
+{
+ if( !hasDueDate() && !toDoEvent.hasDueDate() ) return false;
+ if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
+ if( hasDueDate() && toDoEvent.hasDueDate() ){
+ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
+ return priority() > toDoEvent.priority();
+ }else{
+ return dueDate() > toDoEvent.dueDate();
+ }
+ }
+ return false;
+}
+bool ToDoEvent::operator>=(const ToDoEvent &toDoEvent )const
+{
+ if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
+ if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
+ if( hasDueDate() && toDoEvent.hasDueDate() ){
+ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
+ return priority() > toDoEvent.priority();
+ }else{
+ return dueDate() > toDoEvent.dueDate();
+ }
+ }
+ return true;
+}
+bool ToDoEvent::operator==(const ToDoEvent &toDoEvent )const
+{
+ if( data->priority == toDoEvent.data->priority &&
+ data->priority == toDoEvent.data->prog &&
+ data->isCompleted == toDoEvent.data->isCompleted &&
+ data->hasDate == toDoEvent.data->hasDate &&
+ data->date == toDoEvent.data->date &&
+ data->category == toDoEvent.data->category &&
+ data->sum == toDoEvent.data->sum &&
+ data->desc == toDoEvent.data->desc &&
+ data->hasAlarmDateTime == toDoEvent.data->hasAlarmDateTime &&
+ data->alarmDateTime == toDoEvent.data->alarmDateTime )
+ return true;
+
+ return false;
+}
+void ToDoEvent::deref() {
+
+ //qWarning("deref in ToDoEvent");
+ if ( data->deref() ) {
+ //qWarning("deleting");
+ delete data;
+ d= 0;
+ }
+}
+ToDoEvent &ToDoEvent::operator=(const ToDoEvent &item )
+{
+ //qWarning("operator= ref ");
+ item.data->ref();
+ deref();
+
+ data = item.data;
+
+
+ return *this;
+}
+
+QMap<int, QString> ToDoEvent::toMap() const {
+ QMap<int, QString> map;
+
+ map.insert( Uid, QString::number( data->uid ) );
+ map.insert( Category, data->category.join(";") );
+ map.insert( HasDate, QString::number( data->hasDate ) );
+ map.insert( Completed, QString::number( data->isCompleted ) );
+ map.insert( Description, data->desc );
+ map.insert( Summary, data->sum );
+ map.insert( Priority, QString::number( data->priority ) );
+ map.insert( DateDay, QString::number( data->date.day() ) );
+ map.insert( DateMonth, QString::number( data->date.month() ) );
+ map.insert( DateYear, QString::number( data->date.year() ) );
+ map.insert( Progress, QString::number( data->prog ) );
+ map.insert( CrossReference, crossToString() );
+ map.insert( HasAlarmDateTime, QString::number( data->hasAlarmDateTime ) );
+ map.insert( AlarmDateTime, data->alarmDateTime.toString() );
+
+ return map;
+}
+
+
+QString ToDoEvent::crossToString()const {
+ QString str;
+ QMap<QString, QArray<int> >::ConstIterator it;
+ for (it = data->relations.begin(); it != data->relations.end(); ++it ) {
+ QArray<int> id = it.data();
+ for ( uint i = 0; i < id.size(); ++i ) {
+ str += it.key() + "," + QString::number( i ) + ";";
+ }
+ }
+ str = str.remove( str.length()-1, 1); // strip the ;
+ //qWarning("IDS " + str );
+
+ return str;
+}
+int ToDoEvent::uid()const {
+ return data->uid;
+}
+void ToDoEvent::setUid( int id ) {
+ if ( id == -1 )
+ id = m_gen.generate();
+ m_gen.store(id );
+ changeOrModify();
+ data->uid = id;
+}
+QMap<QString, QString> ToDoEvent::extras()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 ToDoEvent::changeOrModify() {
+ if ( data->count != 1 ) {
+ //qWarning("changeOrModify");
+ data->deref();
+ ToDoEventData* d2 = new ToDoEventData();
+ copy(data, d2 );
+ data = d2;
+ }
+}
+void ToDoEvent::copy( ToDoEventData* src, ToDoEventData* dest ) {
+ dest->date = src->date;
+ dest->isCompleted = src->isCompleted;
+ dest->hasDate = src->hasDate;
+ dest->priority = src->priority;
+ dest->category = src->category;
+ dest->desc = src->desc;
+ dest->sum = src->sum;
+ dest->extra = src->extra;
+ dest->relations = src->relations;
+ dest->uid = src->uid;
+ dest->prog = src->prog;
+ dest->hasAlarmDateTime = src->hasAlarmDateTime;
+ dest->alarmDateTime = src->alarmDateTime;
+}
+
+
diff --git a/libopie/pim/otodo.h b/libopie/pim/otodo.h
new file mode 100644
index 0000000..429108a
--- a/dev/null
+++ b/libopie/pim/otodo.h
@@ -0,0 +1,205 @@
+
+#ifndef OPIE_TODO_EVENT_H
+#define OPIE_TODO_EVENT_H
+
+
+#include <qarray.h>
+#include <qmap.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+#include <qdatetime.h>
+#include <qvaluelist.h>
+
+#include <qpe/recordfields.h>
+#include <qpe/palmtopuidgen.h>
+
+#include <opie/opimrecord.h>
+
+
+class OTodo : public OPimRecord {
+public:
+ typedef QValueList<ToDoEvent> ValueList;
+ enum RecordFields {
+ Uid = Qtopia::UID_ID,
+ Category = Qtopia::CATEGORY_ID,
+ HasDate,
+ Completed,
+ Description,
+ Summary,
+ Priority,
+ DateDay,
+ DateMonth,
+ DateYear,
+ Progress,
+ CrossReference,
+ HasAlarmDateTime,
+ AlarmDateTime
+ };
+ public:
+ // priorities from Very low to very high
+ enum TaskPriority { VeryHigh=1, High, Normal, Low, VeryLow };
+
+ /* Constructs a new ToDoEvent
+ @param completed Is the TodoEvent completed
+ @param priority What is the priority of this ToDoEvent
+ @param category Which category does it belong( uid )
+ @param summary A small summary of the todo
+ @param description What is this ToDoEvent about
+ @param hasDate Does this Event got a deadline
+ @param date what is the deadline?
+ @param uid what is the UUID of this Event
+ **/
+ OTodo( bool completed = false, int priority = Normal,
+ const QStringList &category = QStringList(),
+ const QString &summary = QString::null ,
+ const QString &description = QString::null,
+ ushort progress = 0,
+ bool hasDate = false, QDate date = QDate::currentDate(),
+ int uid = -1 );
+
+ /* Copy c'tor
+
+ **/
+ OTodo(const OTodo & );
+
+ /**
+ *destructor
+ */
+ ~OTodo();
+
+ /**
+ * Is this event completed?
+ */
+ bool isCompleted() const;
+
+ /**
+ * Does this Event have a deadline
+ */
+ bool hasDueDate() const;
+
+ /**
+ * Does this Event has an alarm time ?
+ */
+ bool hasAlarmDateTime() const;
+
+ /**
+ * What is the priority?
+ */
+ int priority()const ;
+
+ /**
+ * progress as ushort 0, 20, 40, 60, 80 or 100%
+ */
+ ushort progress() const;
+
+ /**
+ * The due Date
+ */
+ QDate dueDate()const;
+
+ /**
+ * Alarm Date and Time
+ */
+ QDateTime alarmDateTime()const;
+
+ /**
+ * The description of the todo
+ */
+ QString description()const;
+
+ /**
+ * A small summary of the todo
+ */
+ QString summary() const;
+
+ /**
+ * @reimplemented
+ * Return this todoevent in a RichText formatted QString
+ */
+ QString toRichText() 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
+ */
+ void setHasDueDate( bool hasDate );
+
+ /**
+ * set if this todo has an alarm time and date
+ */
+ void setHasAlarmDateTime ( bool hasAlarm );
+
+ /**
+ * Set the priority of the Todo
+ */
+ void setPriority(int priority );
+
+ /**
+ * Set the progress.
+ */
+ void setProgress( ushort progress );
+
+ /**
+ * set the end date
+ */
+ void setDueDate( QDate date );
+
+ /**
+ * set the alarm time
+ */
+ void setAlarmDateTime ( const QDateTime& alarm );
+
+ void setDescription(const QString& );
+ void setSummary(const QString& );
+ bool isOverdue();
+
+
+ bool match( const QRegExp &r )const;
+
+ bool operator<(const OTodo &toDoEvent )const;
+ bool operator<=(const OTodo &toDoEvent )const;
+ bool operator!=(const OTodo &toDoEvent )const;
+ bool operator>(const OTodo &toDoEvent )const;
+ bool operator>=(const OTodo &toDoEvent)const;
+ bool operator==(const OTodo &toDoEvent )const;
+ ToDoEvent &operator=(const OTodo &toDoEvent );
+
+ private:
+ class OTodoPrivate;
+ struct OTodoEventData;
+
+ void deref();
+ void changeOrModify();
+ void copy( OTodoData* src, OTodoData* dest );
+ ToDoEventPrivate *d;
+ ToDoEventData *data;
+
+ static Qtopia::UidGen m_gen;
+};
+ inline bool ToDoEvent::operator!=(const ToDoEvent &toDoEvent )const {
+ return !(*this == toDoEvent);
+ }
+};
+
+#endif
diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h
new file mode 100644
index 0000000..d9af589
--- a/dev/null
+++ b/libopie2/opiepim/backend/opimaccessbackend.h
@@ -0,0 +1,29 @@
+#ifndef OPIE_PIM_ACCESS_BACKEND
+#define OPIE_PIM_ACCESS_BACKEND
+
+#include <qarray.h>
+
+#include <opie/opimrecord.h>
+
+template <class T = OPimRecord>
+class OPimAccessBackend {
+public:
+ OPimAccessBackend() {
+ }
+ ~OPimAccessBackend() {
+ }
+ virtual void load() = 0;
+ virtual void reload() = 0;
+ virtual void save() = 0;
+ virtual QArray<int> allRecords() = 0;
+ virtual QArray<int> queryByExample( const T& t, int sort ) = 0;
+ virtual T find(int uid ) = 0;
+ virtual void clear() = 0;
+ virtual bool add( const T& t ) = 0;
+ virtual bool remove( int uid ) = 0;
+ virtual void replace( const T& t ) = 0;
+
+
+};
+
+#endif
diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h
new file mode 100644
index 0000000..f2a241d
--- a/dev/null
+++ b/libopie2/opiepim/core/opimaccesstemplate.h
@@ -0,0 +1,82 @@
+#ifndef OPIE_PIM_ACCESS_TEMPLATE_H
+#define OPIE_PIM_ACCESS_TEMPLATE_H
+
+#include <qarray.h>
+
+#include <opie/opimrecord.h>
+#include <opie/opimaccessbackend.h>
+#include <opie/orecordlist.h>
+
+template <class T = OPimRecord >
+class OPimAccessTemplate {
+public:
+ typedef ORecordList<T> List;
+ typedef OPimAccessBackend<T> BackEnd;
+ OPimAccessTemplate( BackEnd* end)
+ : m_backEnd( end ) {
+ }
+ ~OPimAccessTemplate() {
+ delete m_backEnd;
+ }
+ virtual void load() {
+ m_backEnd->load();
+ }
+ virtual void reload() {
+ m_backEnd->reload();
+ }
+ virtual void save() {
+ m_backEnd->save();
+ }
+
+ /*
+ *do array to Records conversion
+ * QArray<int> ids
+ */
+ virtual List allRecords()const {
+ QArray<int> ints = m_backEnd->allRecords();
+
+ List lis( ints, this );
+ return lis;
+ }
+ virtual List queryByExample( const T& t, int sortOrder ) {
+ QArray<int> ints = m_backEnd->query( t, sortOrder );
+ List lis( ints, this );
+
+ return lis;
+ }
+ /* implement QCache here */
+ virtual T find( int uid ) {
+ T t = m_backEnd->find( uid );
+ return t;
+ }
+
+ /* invalidate cache here */
+ virtual void clear() {
+ invalidateCache();
+ m_backEnd->clear();
+ }
+ virtual bool add( const T& t ) {
+ return m_backEnd->add( t );
+ }
+
+ /* only the uid matters */
+ virtual bool remove( const T& t ) {
+ /* remove from cache */
+ return m_backEnd->remove( t.uid() );
+ }
+ virtual bool remove( int uid ) {
+ /* remove from cache */
+ return m_backEnd->remove(uid);
+ }
+ virtual bool replace( const T& t) {
+ return m_backEnd->replace( t );
+ }
+protected:
+ void invalidateCache() {
+
+ }
+ BackEnd* m_backEnd;
+
+};
+
+#endif
diff --git a/libopie2/opiepim/core/opimrecord.cpp b/libopie2/opiepim/core/opimrecord.cpp
new file mode 100644
index 0000000..95de1df
--- a/dev/null
+++ b/libopie2/opiepim/core/opimrecord.cpp
@@ -0,0 +1,90 @@
+#include "opimrecord.h"
+
+OPimRecord::OPimRecord( int uid )
+ : Qtopia::Record() {
+ setUid( uid );
+ if ( uid == 1 )
+ assignUid();
+}
+OPimRecord::~OPimRecord() {
+}
+OPimRecord::OPimRecord( OPimRecord& rec )
+ : Qtopia::Record( rec )
+{
+ (*this) = rec;
+}
+
+OPimRecord &OPimRecord::operator=( const OPimRecord& rec) {
+ /* how do I call the parent copy operator ? */
+ setUid( rec.uid() );
+ setCategories( rec.categories() );
+ return *this;
+}
+QStringList OPimRecord::categoryNames()const {
+ QStringList list;
+
+ return list;
+}
+void OPimRecord::setCategoryName( const QStringList& ) {
+
+}
+void OPimRecord::addCategoryName( const QString& ) {
+
+}
+bool OPimRecord::isEmpty()const {
+ return ( uid() == 0 );
+}
+QStringList OPimRecord::relatedApps()const{
+ QStringList list;
+ QMap<QString, QArray<int> >::ConstIterator it;
+ for ( it = m_relations.begin(); it != m_relations.end(); ++it ) {
+ list << it.key();
+ }
+ return list;
+}
+QArray<int> OPimRecord::relations(const QString& app )const {
+ QArray<int> tmp;
+ QMap<QString, QArray<int> >::ConstIterator it;
+ it = m_relations.find( app);
+ if ( it != m_relations.end() )
+ tmp = it.data();
+ return tmp;
+}
+void OPimRecord::clearRelation( const QString& app ) {
+ m_relations.remove( app );
+}
+void OPimRecord::addRelation( const QString& app, int id ) {
+
+ QMap<QString, QArray<int> >::Iterator it;
+ QArray<int> tmp;
+
+ it = m_relations.find( app );
+ if ( it == m_relations.end() ) {
+ tmp.resize(1 );
+ tmp[0] = id;
+ }else{
+ tmp = it.data();
+ tmp.resize( tmp.size() + 1 );
+ tmp[tmp.size() - 1] = id;
+ }
+ m_relations.replace( app, tmp );
+}
+void OPimRecord::setRelations( const QString& app, QArray<int> ids ) {
+
+ QMap<QString, QArray<int> >::Iterator it;
+ QArray<int> tmp;
+
+ it = m_relations.find( app);
+ if ( it == m_relations.end() ) {
+ tmp = ids;
+ }else{
+ tmp = it.data();
+ int offset = tmp.size()-1;
+ tmp.resize( tmp.size() + ids.size() );
+ for (uint i = 0; i < ids.size(); i++ ) {
+ tmp[offset+i] = ids[i];
+ }
+
+ }
+ m_relations.replace( app, tmp );
+}
diff --git a/libopie2/opiepim/core/opimrecord.h b/libopie2/opiepim/core/opimrecord.h
new file mode 100644
index 0000000..a0e0413
--- a/dev/null
+++ b/libopie2/opiepim/core/opimrecord.h
@@ -0,0 +1,117 @@
+#ifndef OPIE_PIM_RECORD_H
+#define OPIE_PIM_RECORD_H
+
+#include <qmap.h>
+#include <qstring.h>
+#include <qstringlist.h>
+
+#include <qpe/palmtoprecord.h>
+
+class OPimRecord : public Qtopia::Record {
+public:
+ /**
+ * uid of 0 isEmpty
+ * uid of 1 will be assigned a new one
+ */
+ OPimRecord(int uid = 0);
+ ~OPimRecord();
+
+ /**
+ * copy c'tor
+ */
+ OPimRecord( OPimRecord& rec );
+
+ /**
+ * copy operator
+ */
+ OPimRecord &operator=( const OPimRecord& );
+
+ /**
+ * category names resolved
+ */
+ QStringList categoryNames()const;
+
+ /**
+ * set category names they will be resolved
+ */
+ void setCategoryName( const QStringList& );
+
+ /**
+ * addCategoryName adds a name
+ * to the internal category list
+ */
+ void addCategoryName( const QString& );
+
+ /**
+ * if a Record isEmpty
+ */
+ virtual bool isEmpty()const;
+
+ /**
+ * toRichText summary
+ */
+ virtual QString toRichText()const = 0;
+
+ /**
+ * a small one line summary
+ */
+ virtual QString toShortText()const = 0;
+
+ /**
+ * the name of the Record
+ */
+ virtual QString type()const = 0;
+
+ /**
+ * converts the internal structure to a map
+ */
+ virtual QMap<int, QString> toMap()const = 0;
+
+ /**
+ * key value representation of extra items
+ */
+ virtual QMap<QString, QString> toExtraMap()const = 0;
+
+ /**
+ * the name for a recordField
+ */
+ virtual QString recordField(int)const = 0;
+
+ /**
+ * the related apps names
+ */
+ QStringList relatedApps()const;
+
+ /**
+ * the realtions between an app
+ */
+ QArray<int> relations( const QString& app )const;
+
+ /**
+ *
+ */
+ void clearRelation( const QString& app );
+
+ /**
+ *
+ */
+ void addRelation( const QString& app, int id );
+
+ /**
+ *
+ */
+ void setRelations( const QString&, QArray<int> ids );
+
+protected:
+ QString crossToString()const;
+
+private:
+ class OPimRecordPrivate;
+ OPimRecordPrivate *d;
+ QMap<QString, QArray<int> > m_relations;
+
+};
+
+
+
+#endif
diff --git a/libopie2/opiepim/orecordlist.h b/libopie2/opiepim/orecordlist.h
new file mode 100644
index 0000000..c17186f
--- a/dev/null
+++ b/libopie2/opiepim/orecordlist.h
@@ -0,0 +1,44 @@
+
+#ifndef OPIE_RECORD_LIST_H
+#define OPIE_RECORD_LIST_H
+
+#include <opie/opimaccesstemplate.h>
+#include <opie/opimrecord.h>
+
+template <class T = OPimRecord >
+class ORecordList {
+public:
+ class Iterator {
+ friend class ORecordList;
+ public:
+ Iterator() {}
+ ~Iterator() {}
+ Iterator(const Iterator& ) {}
+ Iterator &operator=(const Iterator& );
+ T &operator*() {}
+ Iterator &operator++();
+
+ bool operator==( const Iterator& it );
+ bool operator!=( const Iterator& it );
+
+ }
+ ORecordList( const QArray<int>& ids,
+ OPimAccessTemplate<T>* acc )
+ : m_ids(ids ), m_acc( acc ) {
+
+ }
+ ~ORecordList() {
+
+ }
+ Iterator begin();
+ Iterator end();
+ /*
+ ConstIterator begin()const;
+ ConstIterator end()const;
+ */
+private:
+ QArray<int> ids;
+ OPimAccessTemplate<T>* m_acc;
+};
+
+#endif
diff --git a/libopie2/opiepim/otodo.cpp b/libopie2/opiepim/otodo.cpp
new file mode 100644
index 0000000..d8e0447
--- a/dev/null
+++ b/libopie2/opiepim/otodo.cpp
@@ -0,0 +1,507 @@
+
+#include <qobject.h>
+#include <qshared.h>
+
+
+
+#include <qpe/palmtopuidgen.h>
+#include <qpe/stringutil.h>
+#include <qpe/palmtoprecord.h>
+#include <qpe/stringutil.h>
+#include <qpe/categories.h>
+#include <qpe/categoryselect.h>
+
+#include "todoevent.h"
+
+using namespace Opie;
+
+Qtopia::UidGen ToDoEvent::m_gen;
+
+struct ToDoEvent::ToDoEventData : public QShared {
+ ToDoEventData() : QShared() {
+ };
+
+ QDate date;
+ bool isCompleted:1;
+ bool hasDate:1;
+ int priority;
+ QStringList category;
+ QString desc;
+ QString sum;
+ QMap<QString, QString> extra;
+ QMap<QString, QArray<int> > relations;
+ int uid;
+ ushort prog;
+ bool hasAlarmDateTime :1;
+ QDateTime alarmDateTime;
+};
+
+ToDoEvent::ToDoEvent(const ToDoEvent &event )
+ : data( event.data )
+{
+ data->ref();
+ //qWarning("ref up");
+}
+ToDoEvent::~ToDoEvent() {
+ if ( data->deref() ) {
+ //qWarning("ToDoEvent::dereffing");
+ delete data;
+ data = 0l;
+ }
+}
+
+ToDoEvent::ToDoEvent(bool completed, int priority,
+ const QStringList &category,
+ const QString& summary,
+ const QString &description,
+ ushort progress,
+ bool hasDate, QDate date, int uid )
+{
+ //qWarning("ToDoEventData");
+ data = new ToDoEventData;
+ data->date = date;
+ data->isCompleted = completed;
+ data->hasDate = hasDate;
+ data->priority = priority;
+ data->category = category;
+ data->sum = summary;
+ data->prog = progress;
+ data->desc = Qtopia::simplifyMultiLineSpace(description );
+ if (uid == -1 ) {
+ uid = m_gen.generate();
+
+ }// generated the ids
+ m_gen.store( uid );
+
+ data->uid = uid;
+ data->hasAlarmDateTime = false;
+
+}
+QArray<int> ToDoEvent::categories()const
+{
+ qWarning( "ToDoEvent:cats" + data->category.join(";") );
+ QArray<int> array(data->category.count() ); // currently the datebook can be only in one category
+ array = Qtopia::Record::idsFromString( data->category.join(";") );
+ return array;
+}
+bool ToDoEvent::match( const QRegExp &regExp )const
+{
+ if( QString::number( data->priority ).find( regExp ) != -1 ){
+ return true;
+ }else if( data->hasDate && data->date.toString().find( regExp) != -1 ){
+ return true;
+ }else if(data->desc.find( regExp ) != -1 ){
+ return true;
+ }
+ return false;
+}
+bool ToDoEvent::isCompleted() const
+{
+ return data->isCompleted;
+}
+bool ToDoEvent::hasDueDate() const
+{
+ return data->hasDate;
+}
+bool ToDoEvent::hasAlarmDateTime() const
+{
+ return data->hasAlarmDateTime;
+}
+int ToDoEvent::priority()const
+{
+ return data->priority;
+}
+QStringList ToDoEvent::allCategories()const
+{
+ return data->category;
+}
+QString ToDoEvent::extra(const QString& )const
+{
+ return QString::null;
+}
+QString ToDoEvent::summary() const
+{
+ return data->sum;
+}
+ushort ToDoEvent::progress() const
+{
+ return data->prog;
+}
+QStringList ToDoEvent::relatedApps() const
+{
+ QStringList list;
+ QMap<QString, QArray<int> >::ConstIterator it;
+ for ( it = data->relations.begin(); it != data->relations.end(); ++it ) {
+ list << it.key();
+ }
+ return list;
+}
+QArray<int> ToDoEvent::relations( const QString& app)const
+{
+ QArray<int> tmp;
+ QMap<QString, QArray<int> >::ConstIterator it;
+ it = data->relations.find( app);
+ if ( it != data->relations.end() )
+ tmp = it.data();
+ return tmp;
+}
+void ToDoEvent::insertCategory(const QString &str )
+{
+ changeOrModify();
+ qWarning("insert category;" + str );
+ data->category.append( str );
+}
+void ToDoEvent::clearCategories()
+{
+ changeOrModify();
+ data->category.clear();
+}
+void ToDoEvent::setCategories(const QStringList &list )
+{
+ changeOrModify();
+ qWarning("set categories" + list.join(";") );
+ data->category = list;
+}
+QDate ToDoEvent::dueDate()const
+{
+ return data->date;
+}
+
+QDateTime ToDoEvent::alarmDateTime() const
+{
+ return data->alarmDateTime;
+}
+
+QString ToDoEvent::description()const
+{
+ return data->desc;
+}
+void ToDoEvent::setCompleted( bool completed )
+{
+ changeOrModify();
+ data->isCompleted = completed;
+}
+void ToDoEvent::setHasDueDate( bool hasDate )
+{
+ changeOrModify();
+ data->hasDate = hasDate;
+}
+void ToDoEvent::setHasAlarmDateTime( bool hasAlarmDateTime )
+{
+ changeOrModify();
+ data->hasAlarmDateTime = hasAlarmDateTime;
+}
+void ToDoEvent::setDescription(const QString &desc )
+{
+ changeOrModify();
+ data->desc = Qtopia::simplifyMultiLineSpace(desc );
+}
+void ToDoEvent::setExtra( const QString&, const QString& )
+{
+
+}
+void ToDoEvent::setSummary( const QString& sum )
+{
+ changeOrModify();
+ data->sum = sum;
+}
+void ToDoEvent::setCategory( const QString &cat )
+{
+ changeOrModify();
+ //qWarning("setCategory %s", cat.latin1() );
+ data->category.clear();
+ data->category << cat;
+}
+void ToDoEvent::setPriority(int prio )
+{
+ changeOrModify();
+ data->priority = prio;
+}
+void ToDoEvent::setDueDate( QDate date )
+{
+ changeOrModify();
+ data->date = date;
+}
+void ToDoEvent::setAlarmDateTime( const QDateTime& alarm )
+{
+ changeOrModify();
+ data->alarmDateTime = alarm;
+}
+void ToDoEvent::addRelated( const QString &app, int id )
+{
+ changeOrModify();
+
+ QMap<QString, QArray<int> >::Iterator it;
+ QArray<int> tmp;
+ it = data->relations.find( app );
+ if ( it == data->relations.end() ) {
+ tmp.resize(1 );
+ tmp[0] = id;
+ }else{
+ tmp = it.data();
+ tmp.resize( tmp.size() + 1 );
+ tmp[tmp.size() - 1] = id;
+ }
+ data->relations.replace( app, tmp );
+}
+void ToDoEvent::addRelated(const QString& app, QArray<int> ids )
+{
+ changeOrModify();
+
+ QMap<QString, QArray<int> >::Iterator it;
+ QArray<int> tmp;
+ it = data->relations.find( app);
+ if ( it == data->relations.end() ) { // not there
+ /** tmp.resize( ids.size() ); stupid??
+ */
+ tmp = ids;
+ }else{
+ tmp = it.data();
+ int offset = tmp.size()-1;
+ tmp.resize( tmp.size() + ids.size() );
+ for (uint i = 0; i < ids.size(); i++ ) {
+ tmp[offset+i] = ids[i];
+ }
+
+ }
+ data->relations.replace( app, tmp );
+}
+void ToDoEvent::clearRelated( const QString& app )
+{
+ changeOrModify();
+ data->relations.remove( app );
+}
+bool ToDoEvent::isOverdue( )
+{
+ if( data->hasDate )
+ return QDate::currentDate() > data->date;
+ return false;
+}
+void ToDoEvent::setProgress(ushort progress )
+{
+ changeOrModify();
+ data->prog = progress;
+}
+/*!
+ Returns a richt text string
+*/
+QString ToDoEvent::richText() const
+{
+ QString text;
+ QStringList catlist;
+
+ // Description of the todo
+ if ( !summary().isEmpty() ) {
+ text += "<b>" + QObject::tr( "Summary:") + "</b><br>";
+ text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
+ }
+ if( !description().isEmpty() ){
+ text += "<b>" + QObject::tr( "Description:" ) + "</b><br>";
+ text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) ;
+ }
+ text += "<br><br><br>";
+
+ text += "<b>" + QObject::tr( "Priority:") +" </b>"
+ + QString::number( priority() ) + " <br>";
+ text += "<b>" + QObject::tr( "Progress:") + " </b>"
+ + QString::number( progress() ) + " %<br>";
+ if (hasDueDate() ){
+ text += "<b>" + QObject::tr( "Deadline:") + " </b>";
+ text += dueDate().toString();
+ text += "<br>";
+ }
+ if (hasAlarmDateTime() ){
+ text += "<b>" + QObject::tr( "Alarmed Notification:") + " </b>";
+ text += alarmDateTime().toString();
+ text += "<br>";
+ }
+
+ // Open database of all categories and get the list of
+ // the categories this todoevent belongs to.
+ // Then print them...
+ // I am not sure whether there is no better way doing this !?
+ Categories catdb;
+ bool firstloop = true;
+ catdb.load( categoryFileName() );
+ catlist = allCategories();
+
+ text += "<b>" + QObject::tr( "Category:") + "</b> ";
+ for ( QStringList::Iterator it = catlist.begin(); it != catlist.end(); ++it ) {
+ if (!firstloop){
+ text += ", ";
+ }
+ firstloop = false;
+ text += catdb.label ("todo", (*it).toInt());
+ }
+ text += "<br>";
+ return text;
+}
+
+bool ToDoEvent::operator<( const ToDoEvent &toDoEvent )const{
+ if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
+ if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
+ if( hasDueDate() && toDoEvent.hasDueDate() ){
+ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
+ return priority() < toDoEvent.priority();
+ }else{
+ return dueDate() < toDoEvent.dueDate();
+ }
+ }
+ return false;
+}
+bool ToDoEvent::operator<=(const ToDoEvent &toDoEvent )const
+{
+ if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
+ if( !hasDueDate() && toDoEvent.hasDueDate() ) return true;
+ if( hasDueDate() && toDoEvent.hasDueDate() ){
+ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
+ return priority() <= toDoEvent.priority();
+ }else{
+ return dueDate() <= toDoEvent.dueDate();
+ }
+ }
+ return true;
+}
+bool ToDoEvent::operator>(const ToDoEvent &toDoEvent )const
+{
+ if( !hasDueDate() && !toDoEvent.hasDueDate() ) return false;
+ if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
+ if( hasDueDate() && toDoEvent.hasDueDate() ){
+ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
+ return priority() > toDoEvent.priority();
+ }else{
+ return dueDate() > toDoEvent.dueDate();
+ }
+ }
+ return false;
+}
+bool ToDoEvent::operator>=(const ToDoEvent &toDoEvent )const
+{
+ if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
+ if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
+ if( hasDueDate() && toDoEvent.hasDueDate() ){
+ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
+ return priority() > toDoEvent.priority();
+ }else{
+ return dueDate() > toDoEvent.dueDate();
+ }
+ }
+ return true;
+}
+bool ToDoEvent::operator==(const ToDoEvent &toDoEvent )const
+{
+ if( data->priority == toDoEvent.data->priority &&
+ data->priority == toDoEvent.data->prog &&
+ data->isCompleted == toDoEvent.data->isCompleted &&
+ data->hasDate == toDoEvent.data->hasDate &&
+ data->date == toDoEvent.data->date &&
+ data->category == toDoEvent.data->category &&
+ data->sum == toDoEvent.data->sum &&
+ data->desc == toDoEvent.data->desc &&
+ data->hasAlarmDateTime == toDoEvent.data->hasAlarmDateTime &&
+ data->alarmDateTime == toDoEvent.data->alarmDateTime )
+ return true;
+
+ return false;
+}
+void ToDoEvent::deref() {
+
+ //qWarning("deref in ToDoEvent");
+ if ( data->deref() ) {
+ //qWarning("deleting");
+ delete data;
+ d= 0;
+ }
+}
+ToDoEvent &ToDoEvent::operator=(const ToDoEvent &item )
+{
+ //qWarning("operator= ref ");
+ item.data->ref();
+ deref();
+
+ data = item.data;
+
+
+ return *this;
+}
+
+QMap<int, QString> ToDoEvent::toMap() const {
+ QMap<int, QString> map;
+
+ map.insert( Uid, QString::number( data->uid ) );
+ map.insert( Category, data->category.join(";") );
+ map.insert( HasDate, QString::number( data->hasDate ) );
+ map.insert( Completed, QString::number( data->isCompleted ) );
+ map.insert( Description, data->desc );
+ map.insert( Summary, data->sum );
+ map.insert( Priority, QString::number( data->priority ) );
+ map.insert( DateDay, QString::number( data->date.day() ) );
+ map.insert( DateMonth, QString::number( data->date.month() ) );
+ map.insert( DateYear, QString::number( data->date.year() ) );
+ map.insert( Progress, QString::number( data->prog ) );
+ map.insert( CrossReference, crossToString() );
+ map.insert( HasAlarmDateTime, QString::number( data->hasAlarmDateTime ) );
+ map.insert( AlarmDateTime, data->alarmDateTime.toString() );
+
+ return map;
+}
+
+
+QString ToDoEvent::crossToString()const {
+ QString str;
+ QMap<QString, QArray<int> >::ConstIterator it;
+ for (it = data->relations.begin(); it != data->relations.end(); ++it ) {
+ QArray<int> id = it.data();
+ for ( uint i = 0; i < id.size(); ++i ) {
+ str += it.key() + "," + QString::number( i ) + ";";
+ }
+ }
+ str = str.remove( str.length()-1, 1); // strip the ;
+ //qWarning("IDS " + str );
+
+ return str;
+}
+int ToDoEvent::uid()const {
+ return data->uid;
+}
+void ToDoEvent::setUid( int id ) {
+ if ( id == -1 )
+ id = m_gen.generate();
+ m_gen.store(id );
+ changeOrModify();
+ data->uid = id;
+}
+QMap<QString, QString> ToDoEvent::extras()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 ToDoEvent::changeOrModify() {
+ if ( data->count != 1 ) {
+ //qWarning("changeOrModify");
+ data->deref();
+ ToDoEventData* d2 = new ToDoEventData();
+ copy(data, d2 );
+ data = d2;
+ }
+}
+void ToDoEvent::copy( ToDoEventData* src, ToDoEventData* dest ) {
+ dest->date = src->date;
+ dest->isCompleted = src->isCompleted;
+ dest->hasDate = src->hasDate;
+ dest->priority = src->priority;
+ dest->category = src->category;
+ dest->desc = src->desc;
+ dest->sum = src->sum;
+ dest->extra = src->extra;
+ dest->relations = src->relations;
+ dest->uid = src->uid;
+ dest->prog = src->prog;
+ dest->hasAlarmDateTime = src->hasAlarmDateTime;
+ dest->alarmDateTime = src->alarmDateTime;
+}
+
+
diff --git a/libopie2/opiepim/otodo.h b/libopie2/opiepim/otodo.h
new file mode 100644
index 0000000..429108a
--- a/dev/null
+++ b/libopie2/opiepim/otodo.h
@@ -0,0 +1,205 @@
+
+#ifndef OPIE_TODO_EVENT_H
+#define OPIE_TODO_EVENT_H
+
+
+#include <qarray.h>
+#include <qmap.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+#include <qdatetime.h>
+#include <qvaluelist.h>
+
+#include <qpe/recordfields.h>
+#include <qpe/palmtopuidgen.h>
+
+#include <opie/opimrecord.h>
+
+
+class OTodo : public OPimRecord {
+public:
+ typedef QValueList<ToDoEvent> ValueList;
+ enum RecordFields {
+ Uid = Qtopia::UID_ID,
+ Category = Qtopia::CATEGORY_ID,
+ HasDate,
+ Completed,
+ Description,
+ Summary,
+ Priority,
+ DateDay,
+ DateMonth,
+ DateYear,
+ Progress,
+ CrossReference,
+ HasAlarmDateTime,
+ AlarmDateTime
+ };
+ public:
+ // priorities from Very low to very high
+ enum TaskPriority { VeryHigh=1, High, Normal, Low, VeryLow };
+
+ /* Constructs a new ToDoEvent
+ @param completed Is the TodoEvent completed
+ @param priority What is the priority of this ToDoEvent
+ @param category Which category does it belong( uid )
+ @param summary A small summary of the todo
+ @param description What is this ToDoEvent about
+ @param hasDate Does this Event got a deadline
+ @param date what is the deadline?
+ @param uid what is the UUID of this Event
+ **/
+ OTodo( bool completed = false, int priority = Normal,
+ const QStringList &category = QStringList(),
+ const QString &summary = QString::null ,
+ const QString &description = QString::null,
+ ushort progress = 0,
+ bool hasDate = false, QDate date = QDate::currentDate(),
+ int uid = -1 );
+
+ /* Copy c'tor
+
+ **/
+ OTodo(const OTodo & );
+
+ /**
+ *destructor
+ */
+ ~OTodo();
+
+ /**
+ * Is this event completed?
+ */
+ bool isCompleted() const;
+
+ /**
+ * Does this Event have a deadline
+ */
+ bool hasDueDate() const;
+
+ /**
+ * Does this Event has an alarm time ?
+ */
+ bool hasAlarmDateTime() const;
+
+ /**
+ * What is the priority?
+ */
+ int priority()const ;
+
+ /**
+ * progress as ushort 0, 20, 40, 60, 80 or 100%
+ */
+ ushort progress() const;
+
+ /**
+ * The due Date
+ */
+ QDate dueDate()const;
+
+ /**
+ * Alarm Date and Time
+ */
+ QDateTime alarmDateTime()const;
+
+ /**
+ * The description of the todo
+ */
+ QString description()const;
+
+ /**
+ * A small summary of the todo
+ */
+ QString summary() const;
+
+ /**
+ * @reimplemented
+ * Return this todoevent in a RichText formatted QString
+ */
+ QString toRichText() 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
+ */
+ void setHasDueDate( bool hasDate );
+
+ /**
+ * set if this todo has an alarm time and date
+ */
+ void setHasAlarmDateTime ( bool hasAlarm );
+
+ /**
+ * Set the priority of the Todo
+ */
+ void setPriority(int priority );
+
+ /**
+ * Set the progress.
+ */
+ void setProgress( ushort progress );
+
+ /**
+ * set the end date
+ */
+ void setDueDate( QDate date );
+
+ /**
+ * set the alarm time
+ */
+ void setAlarmDateTime ( const QDateTime& alarm );
+
+ void setDescription(const QString& );
+ void setSummary(const QString& );
+ bool isOverdue();
+
+
+ bool match( const QRegExp &r )const;
+
+ bool operator<(const OTodo &toDoEvent )const;
+ bool operator<=(const OTodo &toDoEvent )const;
+ bool operator!=(const OTodo &toDoEvent )const;
+ bool operator>(const OTodo &toDoEvent )const;
+ bool operator>=(const OTodo &toDoEvent)const;
+ bool operator==(const OTodo &toDoEvent )const;
+ ToDoEvent &operator=(const OTodo &toDoEvent );
+
+ private:
+ class OTodoPrivate;
+ struct OTodoEventData;
+
+ void deref();
+ void changeOrModify();
+ void copy( OTodoData* src, OTodoData* dest );
+ ToDoEventPrivate *d;
+ ToDoEventData *data;
+
+ static Qtopia::UidGen m_gen;
+};
+ inline bool ToDoEvent::operator!=(const ToDoEvent &toDoEvent )const {
+ return !(*this == toDoEvent);
+ }
+};
+
+#endif