#include #include #include #include #include #include #include #include #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 extra; QMap > 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 ToDoEvent::categories()const { qWarning( "ToDoEvent:cats" + data->category.join(";") ); QArray 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 >::ConstIterator it; for ( it = data->relations.begin(); it != data->relations.end(); ++it ) { list << it.key(); } return list; } QArray ToDoEvent::relations( const QString& app)const { QArray tmp; QMap >::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 >::Iterator it; QArray 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 ids ) { changeOrModify(); QMap >::Iterator it; QArray 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 += "" + QObject::tr( "Summary:") + "
"; text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "
" ) + "
"; } if( !description().isEmpty() ){ text += "" + QObject::tr( "Description:" ) + "
"; text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "
" ) ; } text += "


"; text += "" + QObject::tr( "Priority:") +" " + QString::number( priority() ) + "
"; text += "" + QObject::tr( "Progress:") + " " + QString::number( progress() ) + " %
"; if (hasDueDate() ){ text += "" + QObject::tr( "Deadline:") + " "; text += dueDate().toString(); text += "
"; } if (hasAlarmDateTime() ){ text += "" + QObject::tr( "Alarmed Notification:") + " "; text += alarmDateTime().toString(); text += "
"; } // 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 += "" + QObject::tr( "Category:") + " "; for ( QStringList::Iterator it = catlist.begin(); it != catlist.end(); ++it ) { if (!firstloop){ text += ", "; } firstloop = false; text += catdb.label ("todo", (*it).toInt()); } text += "
"; 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 ToDoEvent::toMap() const { QMap 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 >::ConstIterator it; for (it = data->relations.begin(); it != data->relations.end(); ++it ) { QArray 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 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; }