-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 |