/* This file is part of the Opie Project Copyright (C) The Main Author =. Copyright (C) The Opie Team .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "otodo.h" /* OPIE */ #include #include #include #include #include #include #include #include #include #include #include /* QT */ #include #include namespace Opie { struct OTodo::OTodoData : public QShared { OTodoData() : QShared() { recur = 0; state = 0; maintainer = 0; notifiers = 0; }; ~OTodoData() { delete recur; delete maintainer; delete notifiers; } QDate date; bool isCompleted: 1; bool hasDate: 1; int priority; QString desc; QString sum; QMap extra; ushort prog; OPimState *state; ORecur *recur; OPimMaintainer *maintainer; QDate start; QDate completed; OPimNotifyManager *notifiers; }; OTodo::OTodo( const OTodo &event ) : OPimRecord( event ), data( event.data ) { data->ref(); // qWarning("ref up"); } OTodo::~OTodo() { // qWarning("~OTodo " ); if ( data->deref() ) { // qWarning("OTodo::dereffing"); delete data; data = 0l; } } OTodo::OTodo( bool completed, int priority, const QArray &category, const QString& summary, const QString &description, ushort progress, bool hasDate, QDate date, int uid ) : OPimRecord( uid ) { // qWarning("OTodoData " + summary); setCategories( category ); data = new OTodoData; data->date = date; data->isCompleted = completed; data->hasDate = hasDate; data->priority = priority; data->sum = summary; data->prog = progress; data->desc = Qtopia::simplifyMultiLineSpace( description ); } OTodo::OTodo( bool completed, int priority, const QStringList &category, const QString& summary, const QString &description, ushort progress, bool hasDate, QDate date, int uid ) : OPimRecord( uid ) { // qWarning("OTodoData" + summary); setCategories( idsFromString( category.join( ";" ) ) ); data = new OTodoData; data->date = date; data->isCompleted = completed; data->hasDate = hasDate; data->priority = priority; data->sum = summary; data->prog = progress; data->desc = Qtopia::simplifyMultiLineSpace( description ); } bool OTodo::match( const QRegExp ®Exp ) const { if ( QString::number( data->priority ).find( regExp ) != -1 ) { setLastHitField( Priority ); return true; } else if ( data->hasDate && data->date.toString().find( regExp ) != -1 ) { setLastHitField( HasDate ); return true; } else if ( data->desc.find( regExp ) != -1 ) { setLastHitField( Description ); return true; } else if ( data->sum.find( regExp ) != -1 ) { setLastHitField( Summary ); return true; } return false; } bool OTodo::isCompleted() const { return data->isCompleted; } bool OTodo::hasDueDate() const { return data->hasDate; } bool OTodo::hasStartDate() const { return data->start.isValid(); } bool OTodo::hasCompletedDate() const { return data->completed.isValid(); } int OTodo::priority() const { return data->priority; } QString OTodo::summary() const { return data->sum; } ushort OTodo::progress() const { return data->prog; } QDate OTodo::dueDate() const { return data->date; } QDate OTodo::startDate() const { return data->start; } QDate OTodo::completedDate() const { return data->completed; } QString OTodo::description() const { return data->desc; } bool OTodo::hasState() const { if ( !data->state ) return false; return ( data->state->state() != OPimState::Undefined ); } OPimState OTodo::state() const { if ( !data->state ) { OPimState state; return state; } return ( *data->state ); } bool OTodo::hasRecurrence() const { if ( !data->recur ) return false; return data->recur->doesRecur(); } ORecur OTodo::recurrence() const { if ( !data->recur ) return ORecur(); return ( *data->recur ); } bool OTodo::hasMaintainer() const { if ( !data->maintainer ) return false; return ( data->maintainer->mode() != OPimMaintainer::Undefined ); } OPimMaintainer OTodo::maintainer() const { if ( !data->maintainer ) return OPimMaintainer(); return ( *data->maintainer ); } void OTodo::setCompleted( bool completed ) { changeOrModify(); data->isCompleted = completed; } void OTodo::setHasDueDate( bool hasDate ) { changeOrModify(); data->hasDate = hasDate; } void OTodo::setDescription( const QString &desc ) { // qWarning( "desc " + desc ); changeOrModify(); data->desc = Qtopia::simplifyMultiLineSpace( desc ); } void OTodo::setSummary( const QString& sum ) { changeOrModify(); data->sum = sum; } void OTodo::setPriority( int prio ) { changeOrModify(); data->priority = prio; } void OTodo::setDueDate( const QDate& date ) { changeOrModify(); data->date = date; } void OTodo::setStartDate( const QDate& date ) { changeOrModify(); data->start = date; } void OTodo::setCompletedDate( const QDate& date ) { changeOrModify(); data->completed = date; } void OTodo::setState( const OPimState& state ) { changeOrModify(); if ( data->state ) ( *data->state ) = state; else data->state = new OPimState( state ); } void OTodo::setRecurrence( const ORecur& rec ) { changeOrModify(); if ( data->recur ) ( *data->recur ) = rec; else data->recur = new ORecur( rec ); } void OTodo::setMaintainer( const OPimMaintainer& pim ) { changeOrModify(); if ( data->maintainer ) ( *data->maintainer ) = pim; else data->maintainer = new OPimMaintainer( pim ); } bool OTodo::isOverdue( ) { if ( data->hasDate && !data->isCompleted ) return QDate::currentDate() > data->date; return false; } void OTodo::setProgress( ushort progress ) { changeOrModify(); data->prog = progress; } QString OTodo::toShortText() const { return summary(); } /*! Returns a richt text string */ QString OTodo::toRichText() const { QString text; QStringList catlist; // summary text += "

"; if ( !summary().isEmpty() ) { text += Qtopia::escapeString( summary() ).replace( QRegExp( "[\n]" ), "" ); } text += "




"; // description if ( !description().isEmpty() ) { text += "" + QObject::tr( "Description:" ) + "
"; text += Qtopia::escapeString( description() ).replace( QRegExp( "[\n]" ), "
" ) + "
"; } // priority int priorityval = priority(); text += "" + QObject::tr( "Priority:" ) + " "; switch ( priorityval ) { case 1 : text += QObject::tr( "Very high" ); break; case 2 : text += QObject::tr( "High" ); break; case 3 : text += QObject::tr( "Normal" ); break; case 4 : text += QObject::tr( "Low" ); break; case 5 : text += QObject::tr( "Very low" ); break; }; text += "
"; // progress text += "" + QObject::tr( "Progress:" ) + " " + QString::number( progress() ) + " %
"; // due date if ( hasDueDate() ) { QDate dd = dueDate(); int off = QDate::currentDate().daysTo( dd ); text += "" + QObject::tr( "Deadline:" ) + " 0 ) text += "#00FF00"; text += "\">" + dd.toString() + "
"; } // categories text += "" + QObject::tr( "Category:" ) + " "; text += categoryNames( "Todo List" ).join( ", " ); text += "
"; return text; } bool OTodo::hasNotifiers() const { if ( !data->notifiers ) return false; return !data->notifiers->isEmpty(); } OPimNotifyManager& OTodo::notifiers() { if ( !data->notifiers ) data->notifiers = new OPimNotifyManager; return ( *data->notifiers ); } const OPimNotifyManager& OTodo::notifiers() const { if ( !data->notifiers ) data->notifiers = new OPimNotifyManager; return ( *data->notifiers ); } bool OTodo::operator<( const OTodo &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 OTodo::operator<=( const OTodo &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 OTodo::operator>( const OTodo &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 OTodo::operator>=( const OTodo &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 OTodo::operator==( const OTodo &toDoEvent ) const { if ( data->priority != toDoEvent.data->priority ) return false; if ( data->priority != toDoEvent.data->prog ) return false; if ( data->isCompleted != toDoEvent.data->isCompleted ) return false; if ( data->hasDate != toDoEvent.data->hasDate ) return false; if ( data->date != toDoEvent.data->date ) return false; if ( data->sum != toDoEvent.data->sum ) return false; if ( data->desc != toDoEvent.data->desc ) return false; if ( data->maintainer != toDoEvent.data->maintainer ) return false; return OPimRecord::operator==( toDoEvent ); } void OTodo::deref() { // qWarning("deref in ToDoEvent"); if ( data->deref() ) { // qWarning("deleting"); delete data; data = 0; } } OTodo &OTodo::operator=( const OTodo &item ) { if ( this == &item ) return * this; OPimRecord::operator=( item ); //qWarning("operator= ref "); item.data->ref(); deref(); data = item.data; return *this; } QMap OTodo::toMap() const { QMap map; map.insert( Uid, QString::number( uid() ) ); map.insert( Category, idsToString( categories() ) ); 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() ); /* FIXME!!! map.insert( State, ); map.insert( Recurrence, ); map.insert( Reminders, ); map. */ return map; } /** * change or modify looks at the ref count and either * creates a new QShared Object or it can modify it * right in place */ void OTodo::changeOrModify() { if ( data->count != 1 ) { qWarning( "changeOrModify" ); data->deref(); OTodoData* d2 = new OTodoData(); copy( data, d2 ); data = d2; } } // WATCHOUT /* * if you add something to the Data struct * be sure to copy it here */ void OTodo::copy( OTodoData* src, OTodoData* dest ) { dest->date = src->date; dest->isCompleted = src->isCompleted; dest->hasDate = src->hasDate; dest->priority = src->priority; dest->desc = src->desc; dest->sum = src->sum; dest->extra = src->extra; dest->prog = src->prog; if ( src->state ) dest->state = new OPimState( *src->state ); if ( src->recur ) dest->recur = new ORecur( *src->recur ); if ( src->maintainer ) dest->maintainer = new OPimMaintainer( *src->maintainer ) ; dest->start = src->start; dest->completed = src->completed; if ( src->notifiers ) dest->notifiers = new OPimNotifyManager( *src->notifiers ); } QString OTodo::type() const { return QString::fromLatin1( "OTodo" ); } QString OTodo::recordField( int /*id*/ ) const { return QString::null; } int OTodo::rtti() { return OPimResolver::TodoList; } }