author | zecke <zecke> | 2002-09-20 12:59:29 (UTC) |
---|---|---|
committer | zecke <zecke> | 2002-09-20 12:59:29 (UTC) |
commit | a05c10c9744020be31c3038b2de3401b5cc673fb (patch) (side-by-side diff) | |
tree | 20d059bf00fc1199c34a60a8be4cb842ebfe4d14 | |
parent | 7099778ab711f78cfd86dadad1b8af993e008f38 (diff) | |
download | opie-a05c10c9744020be31c3038b2de3401b5cc673fb.zip opie-a05c10c9744020be31c3038b2de3401b5cc673fb.tar.gz opie-a05c10c9744020be31c3038b2de3401b5cc673fb.tar.bz2 |
Our new common template based start for Accessing and Manipulating
the Records
The CROSS_REFERENCE branch will get ported to it.
We use templates for several reasons
They allow us to share code and to be easily extended
I've to make them not inline to save memory...
I've to port all DBs and Record related classes
-rw-r--r-- | libopie/pim/opimaccessbackend.h | 29 | ||||
-rw-r--r-- | libopie/pim/opimaccesstemplate.h | 82 | ||||
-rw-r--r-- | libopie/pim/opimrecord.cpp | 90 | ||||
-rw-r--r-- | libopie/pim/opimrecord.h | 117 | ||||
-rw-r--r-- | libopie/pim/orecordlist.h | 44 | ||||
-rw-r--r-- | libopie/pim/otodo.cpp | 507 | ||||
-rw-r--r-- | libopie/pim/otodo.h | 205 | ||||
-rw-r--r-- | libopie2/opiepim/backend/opimaccessbackend.h | 29 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimaccesstemplate.h | 82 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimrecord.cpp | 90 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimrecord.h | 117 | ||||
-rw-r--r-- | libopie2/opiepim/orecordlist.h | 44 | ||||
-rw-r--r-- | libopie2/opiepim/otodo.cpp | 507 | ||||
-rw-r--r-- | libopie2/opiepim/otodo.h | 205 |
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 ®Exp )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 ®Exp )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 |