author | zecke <zecke> | 2003-06-20 15:40:07 (UTC) |
---|---|---|
committer | zecke <zecke> | 2003-06-20 15:40:07 (UTC) |
commit | ec80e207cce9ebb55be771603fc47a4e7892fd6c (patch) (side-by-side diff) | |
tree | 0ec055e15a0ca1ec9ff0e9c674ecbcca389acbf4 /libopie2 | |
parent | c57f817ceca0eff0f6f3e90ad01654252911c1c5 (diff) | |
download | opie-ec80e207cce9ebb55be771603fc47a4e7892fd6c.zip opie-ec80e207cce9ebb55be771603fc47a4e7892fd6c.tar.gz opie-ec80e207cce9ebb55be771603fc47a4e7892fd6c.tar.bz2 |
toExtraMap is no more virtual
we save custom entries now
setExtraMap added as well
-rw-r--r-- | libopie2/opiepim/backend/otodoaccessxml.cpp | 23 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimrecord.cpp | 6 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimrecord.h | 8 | ||||
-rw-r--r-- | libopie2/opiepim/ocontact.cpp | 8 | ||||
-rw-r--r-- | libopie2/opiepim/oevent.cpp | 3 | ||||
-rw-r--r-- | libopie2/opiepim/oevent.h | 1 | ||||
-rw-r--r-- | libopie2/opiepim/otodo.cpp | 3 | ||||
-rw-r--r-- | libopie2/opiepim/otodo.h | 1 |
8 files changed, 37 insertions, 16 deletions
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp index 2b62f0d..3d15354 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.cpp +++ b/libopie2/opiepim/backend/otodoaccessxml.cpp @@ -244,596 +244,619 @@ bool OTodoAccessXML::save() { return false; int written; QString out; out = "<!DOCTYPE Tasks>\n<Tasks>\n"; // for all todos QMap<int, OTodo>::Iterator it; for (it = m_events.begin(); it != m_events.end(); ++it ) { out+= "<Task " + toString( (*it) ) + " />\n"; QCString cstr = out.utf8(); written = f.writeBlock( cstr.data(), cstr.length() ); /* less written then we wanted */ if ( written != (int)cstr.length() ) { f.close(); QFile::remove( strNewFile ); return false; } out = QString::null; } out += "</Tasks>"; QCString cstr = out.utf8(); written = f.writeBlock( cstr.data(), cstr.length() ); if ( written != (int)cstr.length() ) { f.close(); QFile::remove( strNewFile ); return false; } /* flush before renaming */ f.close(); if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { // qWarning("error renaming"); QFile::remove( strNewFile ); } m_changed = false; return true; } QArray<int> OTodoAccessXML::allRecords()const { QArray<int> ids( m_events.count() ); QMap<int, OTodo>::ConstIterator it; int i = 0; for ( it = m_events.begin(); it != m_events.end(); ++it ) { ids[i] = it.key(); i++; } return ids; } QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int, const QDateTime& ) { QArray<int> ids(0); return ids; } OTodo OTodoAccessXML::find( int uid )const { OTodo todo; todo.setUid( 0 ); // isEmpty() QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); if ( it != m_events.end() ) todo = it.data(); return todo; } void OTodoAccessXML::clear() { if (m_opened ) m_changed = true; m_events.clear(); } bool OTodoAccessXML::add( const OTodo& todo ) { // qWarning("add"); m_changed = true; m_events.insert( todo.uid(), todo ); return true; } bool OTodoAccessXML::remove( int uid ) { m_changed = true; m_events.remove( uid ); return true; } bool OTodoAccessXML::replace( const OTodo& todo) { m_changed = true; m_events.replace( todo.uid(), todo ); return true; } QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates ) { QArray<int> ids( m_events.count() ); QMap<int, OTodo>::Iterator it; int i = 0; for ( it = m_events.begin(); it != m_events.end(); ++it ) { if ( !it.data().hasDueDate() ) { if ( includeNoDates ) { ids[i] = it.key(); i++; } }else if ( it.data().dueDate() >= start && it.data().dueDate() <= end ) { ids[i] = it.key(); i++; } } ids.resize( i ); return ids; } QArray<int> OTodoAccessXML::overDue() { QArray<int> ids( m_events.count() ); int i = 0; QMap<int, OTodo>::Iterator it; for ( it = m_events.begin(); it != m_events.end(); ++it ) { if ( it.data().isOverdue() ) { ids[i] = it.key(); i++; } } ids.resize( i ); return ids; } /* private */ void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, const QCString& attr, const QString& val) { // qWarning("parse to do from XMLElement" ); int *find=0; find = (*dict)[ attr.data() ]; if (!find ) { // qWarning("Unknown option" + it.key() ); ev.setCustomField( attr, val ); return; } switch( *find ) { case OTodo::Uid: ev.setUid( val.toInt() ); break; case OTodo::Category: ev.setCategories( ev.idsFromString( val ) ); break; case OTodo::HasDate: ev.setHasDueDate( val.toInt() ); break; case OTodo::Completed: ev.setCompleted( val.toInt() ); break; case OTodo::Description: ev.setDescription( val ); break; case OTodo::Summary: ev.setSummary( val ); break; case OTodo::Priority: ev.setPriority( val.toInt() ); break; case OTodo::DateDay: m_day = val.toInt(); break; case OTodo::DateMonth: m_month = val.toInt(); break; case OTodo::DateYear: m_year = val.toInt(); break; case OTodo::Progress: ev.setProgress( val.toInt() ); break; case OTodo::CompletedDate: ev.setCompletedDate( OConversion::dateFromString( val ) ); break; case OTodo::StartDate: ev.setStartDate( OConversion::dateFromString( val ) ); break; case OTodo::State: ev.setState( val.toInt() ); break; case OTodo::Alarms:{ OPimNotifyManager &manager = ev.notifiers(); QStringList als = QStringList::split(";", val ); for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) { QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty qWarning("alarm: %s", alarm.join("___").latin1() ); qWarning("alarm[0]: %s %s", alarm[0].latin1(), OConversion::dateTimeFromString( alarm[0] ).toString().latin1() ); OPimAlarm al( alarm[2].toInt(), OConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() ); manager.add( al ); } } break; case OTodo::Reminders:{ OPimNotifyManager &manager = ev.notifiers(); QStringList rems = QStringList::split(";", val ); for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) { OPimReminder rem( (*it).toInt() ); manager.add( rem ); } } break; case OTodo::CrossReference: { /* * A cross refernce looks like * appname,id;appname,id * we need to split it up */ QStringList refs = QStringList::split(';', val ); QStringList::Iterator strIt; for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { int pos = (*strIt).find(','); if ( pos > -1 ) ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); } break; } /* Recurrence stuff below + post processing later */ case FRType: if ( val == "Daily" ) recur()->setType( ORecur::Daily ); else if ( val == "Weekly" ) recur()->setType( ORecur::Weekly); else if ( val == "MonthlyDay" ) recur()->setType( ORecur::MonthlyDay ); else if ( val == "MonthlyDate" ) recur()->setType( ORecur::MonthlyDate ); else if ( val == "Yearly" ) recur()->setType( ORecur::Yearly ); else recur()->setType( ORecur::NoRepeat ); break; case FRWeekdays: recur()->setDays( val.toInt() ); break; case FRPosition: recur()->setPosition( val.toInt() ); break; case FRFreq: recur()->setFrequency( val.toInt() ); break; case FRHasEndDate: recur()->setHasEndDate( val.toInt() ); break; case FREndDate: { rp_end = (time_t) val.toLong(); break; } default: + ev.setCustomField( attr, val ); break; } } + +// from PalmtopRecord... GPL ### FIXME +namespace { +QString customToXml(const QMap<QString, QString>& customMap ) +{ + //qWarning(QString("writing custom %1").arg(customMap.count())); + QString buf(" "); + for ( QMap<QString, QString>::ConstIterator cit = customMap.begin(); + cit != customMap.end(); ++cit) { +// qWarning(".ITEM."); + buf += cit.key(); + buf += "=\""; + buf += Qtopia::escapeString(cit.data()); + buf += "\" "; + } + return buf; +} + + +} + QString OTodoAccessXML::toString( const OTodo& ev )const { QString str; str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; str += "Categories=\"" + toString( ev.categories() ) + "\" "; str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; if ( ev.hasDueDate() ) { str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; } // qWarning( "Uid %d", ev.uid() ); str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; // append the extra options /* FIXME Qtopia::Record this is currently not * possible you can set custom fields * but don' iterate over the list * I may do #define private protected * for this case - cough --zecke */ /* QMap<QString, QString> extras = ev.extras(); QMap<QString, QString>::Iterator extIt; for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) str += extIt.key() + "=\"" + extIt.data() + "\" "; */ // cross refernce if ( ev.hasRecurrence() ) { str += ev.recurrence().toString(); } if ( ev.hasStartDate() ) str += "StartDate=\""+ OConversion::dateToString( ev.startDate() ) +"\" "; if ( ev.hasCompletedDate() ) str += "CompletedDate=\""+ OConversion::dateToString( ev.completedDate() ) +"\" "; if ( ev.hasState() ) str += "State=\""+QString::number( ev.state().state() )+"\" "; /* * save reminders and notifiers! * DATE_TIME:DURATION:SOUND:NOT_USED_YET;OTHER_DATE_TIME:OTHER:DURATION:SOUND:.... */ if ( ev.hasNotifiers() ) { OPimNotifyManager manager = ev.notifiers(); OPimNotifyManager::Alarms alarms = manager.alarms(); if (!alarms.isEmpty() ) { QStringList als; OPimNotifyManager::Alarms::Iterator it = alarms.begin(); for ( ; it != alarms.end(); ++it ) { /* only if time is valid */ if ( (*it).dateTime().isValid() ) { als << OConversion::dateTimeToString( (*it).dateTime() ) + ":" + QString::number( (*it).duration() ) + ":" + QString::number( (*it).sound() ) + ":"; } } // now write the list qWarning("als: %s", als.join("____________").latin1() ); str += "Alarms=\""+als.join(";") +"\" "; } /* * now the same for reminders but more easy. We just save the uid of the OEvent. */ OPimNotifyManager::Reminders reminders = manager.reminders(); if (!reminders.isEmpty() ) { OPimNotifyManager::Reminders::Iterator it = reminders.begin(); QStringList records; for ( ; it != reminders.end(); ++it ) { records << QString::number( (*it).recordUid() ); } str += "Reminders=\""+ records.join(";") +"\" "; } } + str += customToXml( ev.toExtraMap() ); return str; } QString OTodoAccessXML::toString( const QArray<int>& ints ) const { return Qtopia::Record::idsToString( ints ); } /* internal class for sorting * * Inspired by todoxmlio.cpp from TT */ struct OTodoXMLContainer { OTodo todo; }; namespace { inline QString string( const OTodo& todo) { return todo.summary().isEmpty() ? todo.description().left(20 ) : todo.summary(); } inline int completed( const OTodo& todo1, const OTodo& todo2) { int ret = 0; if ( todo1.isCompleted() ) ret++; if ( todo2.isCompleted() ) ret--; return ret; } inline int priority( const OTodo& t1, const OTodo& t2) { return ( t1.priority() - t2.priority() ); } inline int description( const OTodo& t1, const OTodo& t2) { return QString::compare( string(t1), string(t2) ); } inline int deadline( const OTodo& t1, const OTodo& t2) { int ret = 0; if ( t1.hasDueDate() && t2.hasDueDate() ) ret = t2.dueDate().daysTo( t1.dueDate() ); else if ( t1.hasDueDate() ) ret = -1; else if ( t2.hasDueDate() ) ret = 1; else ret = 0; return ret; } }; /* * Returns: * 0 if item1 == item2 * * non-zero if item1 != item2 * * This function returns int rather than bool so that reimplementations * can return one of three values and use it to sort by: * * 0 if item1 == item2 * * > 0 (positive integer) if item1 > item2 * * < 0 (negative integer) if item1 < item2 * */ class OTodoXMLVector : public QVector<OTodoXMLContainer> { public: OTodoXMLVector(int size, bool asc, int sort) : QVector<OTodoXMLContainer>( size ) { setAutoDelete( true ); m_asc = asc; m_sort = sort; } /* return the summary/description */ QString string( const OTodo& todo) { return todo.summary().isEmpty() ? todo.description().left(20 ) : todo.summary(); } /** * we take the sortorder( switch on it ) * */ int compareItems( Item d1, Item d2 ) { bool seComp, sePrio, seDesc, seDeadline; seComp = sePrio = seDeadline = seDesc = false; int ret =0; OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; /* same item */ if ( con1->todo.uid() == con2->todo.uid() ) return 0; switch ( m_sort ) { /* completed */ case 0: { ret = completed( con1->todo, con2->todo ); seComp = TRUE; break; } /* priority */ case 1: { ret = priority( con1->todo, con2->todo ); sePrio = TRUE; break; } /* description */ case 2: { ret = description( con1->todo, con2->todo ); seDesc = TRUE; break; } /* deadline */ case 3: { ret = deadline( con1->todo, con2->todo ); seDeadline = TRUE; break; } default: ret = 0; break; }; /* * FIXME do better sorting if the first sort criteria * ret equals 0 start with complete and so on... */ /* twist it we're not ascending*/ if (!m_asc) ret = ret * -1; if ( ret ) return ret; // default did not gave difference let's try it other way around /* * General try if already checked if not test * and return * 1.Completed * 2.Priority * 3.Description * 4.DueDate */ if (!seComp ) { if ( (ret = completed( con1->todo, con2->todo ) ) ) { if (!m_asc ) ret *= -1; return ret; } } if (!sePrio ) { if ( (ret = priority( con1->todo, con2->todo ) ) ) { if (!m_asc ) ret *= -1; return ret; } } if (!seDesc ) { if ( (ret = description(con1->todo, con2->todo ) ) ) { if (!m_asc) ret *= -1; return ret; } } if (!seDeadline) { if ( (ret = deadline( con1->todo, con2->todo ) ) ) { if (!m_asc) ret *= -1; return ret; } } return 0; } private: bool m_asc; int m_sort; }; QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, int sortFilter, int cat ) { OTodoXMLVector vector(m_events.count(), asc,sortOrder ); QMap<int, OTodo>::Iterator it; int item = 0; bool bCat = sortFilter & 1 ? true : false; bool bOnly = sortFilter & 2 ? true : false; bool comp = sortFilter & 4 ? true : false; for ( it = m_events.begin(); it != m_events.end(); ++it ) { /* show category */ /* -1 == unfiled */ if ( bCat && cat == -1 ) { if(!(*it).categories().isEmpty() ) continue; }else if ( bCat && cat != 0) if (!(*it).categories().contains( cat ) ) { continue; } /* isOverdue but we should not show overdue - why?*/ /* if ( (*it).isOverdue() && !bOnly ) { qWarning("item is overdue but !bOnly"); continue; } */ if ( !(*it).isOverdue() && bOnly ) { continue; } if ((*it).isCompleted() && comp ) { continue; } OTodoXMLContainer* con = new OTodoXMLContainer(); con->todo = (*it); vector.insert(item, con ); item++; } vector.resize( item ); /* sort it now */ vector.sort(); /* now get the uids */ QArray<int> array( vector.count() ); for (uint i= 0; i < vector.count(); i++ ) { array[i] = ( vector.at(i) )->todo.uid(); } return array; }; void OTodoAccessXML::removeAllCompleted() { for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { if ( (*it).isCompleted() ) m_events.remove( it ); } } QBitArray OTodoAccessXML::supports()const { static QBitArray ar = sup(); return ar; } QBitArray OTodoAccessXML::sup() { QBitArray ar( OTodo::CompletedDate +1 ); ar.fill( true ); ar[OTodo::CrossReference] = false; ar[OTodo::State ] = false; ar[OTodo::Reminders] = false; ar[OTodo::Notifiers] = false; ar[OTodo::Maintainer] = false; return ar; } QArray<int> OTodoAccessXML::matchRegexp( const QRegExp &r ) const { QArray<int> m_currentQuery( m_events.count() ); uint arraycounter = 0; diff --git a/libopie2/opiepim/core/opimrecord.cpp b/libopie2/opiepim/core/opimrecord.cpp index 0c9734d..2365748 100644 --- a/libopie2/opiepim/core/opimrecord.cpp +++ b/libopie2/opiepim/core/opimrecord.cpp @@ -1,176 +1,182 @@ #include <qarray.h> #include <qpe/categories.h> #include <qpe/categoryselect.h> #include "opimrecord.h" Qtopia::UidGen OPimRecord::m_uidGen( Qtopia::UidGen::Qtopia ); OPimRecord::OPimRecord( int uid ) : Qtopia::Record() { m_lastHit = -1; setUid( uid ); } OPimRecord::~OPimRecord() { } OPimRecord::OPimRecord( const OPimRecord& rec ) : Qtopia::Record( rec ) { (*this) = rec; } OPimRecord &OPimRecord::operator=( const OPimRecord& rec) { if ( this == &rec ) return *this; Qtopia::Record::operator=( rec ); m_xrefman = rec.m_xrefman; m_lastHit = rec.m_lastHit; return *this; } /* * category names */ QStringList OPimRecord::categoryNames( const QString& appname ) const { QStringList list; QArray<int> cats = categories(); Categories catDB; catDB.load( categoryFileName() ); for (uint i = 0; i < cats.count(); i++ ) { list << catDB.label( appname, cats[i] ); } return list; } void OPimRecord::setCategoryNames( const QStringList& ) { } void OPimRecord::addCategoryName( const QString& ) { Categories catDB; catDB.load( categoryFileName() ); } bool OPimRecord::isEmpty()const { return ( uid() == 0 ); } /*QString OPimRecord::crossToString()const { QString str; QMap<QString, QArray<int> >::ConstIterator it; for (it = m_relations.begin(); it != m_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; }*/ /* if uid = 1 assign a new one */ void OPimRecord::setUid( int uid ) { if ( uid == 1) uid = uidGen().generate(); Qtopia::Record::setUid( uid ); }; Qtopia::UidGen &OPimRecord::uidGen() { return m_uidGen; } OPimXRefManager &OPimRecord::xrefmanager() { return m_xrefman; } int OPimRecord::rtti(){ return 0; } /** * now let's put our data into the stream */ /* * First read UID * Categories * XRef */ bool OPimRecord::loadFromStream( QDataStream& stream ) { int Int; uint UInt; stream >> Int; setUid(Int); /** Categories */ stream >> UInt; QArray<int> array(UInt); for (uint i = 0; i < UInt; i++ ) { stream >> array[i]; } setCategories( array ); /* * now we do the X-Ref stuff */ OPimXRef xref; stream >> UInt; for ( uint i = 0; i < UInt; i++ ) { xref.setPartner( OPimXRef::One, partner( stream ) ); xref.setPartner( OPimXRef::Two, partner( stream ) ); m_xrefman.add( xref ); } return true; } bool OPimRecord::saveToStream( QDataStream& stream )const { /** UIDs */ stream << uid(); /** Categories */ stream << categories().count(); for ( uint i = 0; i < categories().count(); i++ ) { stream << categories()[i]; } /* * first the XRef count * then the xrefs */ stream << m_xrefman.list().count(); for ( OPimXRef::ValueList::ConstIterator it = m_xrefman.list().begin(); it != m_xrefman.list().end(); ++it ) { flush( (*it).partner( OPimXRef::One), stream ); flush( (*it).partner( OPimXRef::Two), stream ); } return true; } void OPimRecord::flush( const OPimXRefPartner& par, QDataStream& str ) const{ str << par.service(); str << par.uid(); str << par.field(); } OPimXRefPartner OPimRecord::partner( QDataStream& stream ) { OPimXRefPartner par; QString str; int i; stream >> str; par.setService( str ); stream >> i; par.setUid( i ); stream >> i ; par.setField( i ); return par; } void OPimRecord::setLastHitField( int lastHit )const { m_lastHit = lastHit; } int OPimRecord::lastHitField()const{ return m_lastHit; } +QMap<QString, QString> OPimRecord::toExtraMap()const { + return customMap; +} +void OPimRecord::setExtraMap( const QMap<QString, QString>& map) { + customMap = map; +} diff --git a/libopie2/opiepim/core/opimrecord.h b/libopie2/opiepim/core/opimrecord.h index 494c78e..563b19c 100644 --- a/libopie2/opiepim/core/opimrecord.h +++ b/libopie2/opiepim/core/opimrecord.h @@ -1,151 +1,157 @@ #ifndef OPIE_PIM_RECORD_H #define OPIE_PIM_RECORD_H #include <qdatastream.h> #include <qmap.h> #include <qstring.h> #include <qstringlist.h> +/* + * we need to get customMap which is private... + */ +#define private protected #include <qpe/palmtoprecord.h> +#undef private #include <opie/opimxrefmanager.h> /** * This is the base class for * all PIM Records * */ class OPimRecord : public Qtopia::Record { public: /** * c'tor * uid of 0 isEmpty * uid of 1 will be assigned a new one */ OPimRecord(int uid = 0); ~OPimRecord(); /** * copy c'tor */ OPimRecord( const OPimRecord& rec ); /** * copy operator */ OPimRecord &operator=( const OPimRecord& ); /** * category names resolved */ QStringList categoryNames( const QString& appname )const; /** * set category names they will be resolved */ void setCategoryNames( const QStringList& ); /** * addCategoryName adds a name * to the internal category list */ void addCategoryName( const QString& ); /** * if a Record isEmpty * it's empty if it's 0 */ 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; /** * matches the Records the regular expression? */ virtual bool match( const QString ®exp ) const {setLastHitField( -1 ); return Qtopia::Record::match(QRegExp(regexp));}; /** * if implemented this function returns which item has been * last hit by the match() function. * or -1 if not implemented or no hit has occured */ int lastHitField()const; /** * 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; + QMap<QString, QString> toExtraMap()const; + void setExtraMap( const QMap<QString, QString>& ); /** * the name for a recordField */ virtual QString recordField(int)const = 0; /** * returns a reference of the * Cross Reference Manager * Partner 'One' is THIS PIM RECORD! * 'Two' is the Partner where we link to */ OPimXRefManager& xrefmanager(); /** * set the uid */ virtual void setUid( int uid ); /* * used inside the Templates for casting * REIMPLEMENT in your .... */ static int rtti(); /** * some marshalling and de marshalling code * saves the OPimRecord * to and from a DataStream */ virtual bool loadFromStream(QDataStream& ); virtual bool saveToStream( QDataStream& stream )const; protected: // need to be const cause it is called from const methods mutable int m_lastHit; void setLastHitField( int lastHit )const; Qtopia::UidGen &uidGen(); // QString crossToString()const; private: class OPimRecordPrivate; OPimRecordPrivate *d; OPimXRefManager m_xrefman; static Qtopia::UidGen m_uidGen; private: void flush( const OPimXRefPartner&, QDataStream& stream )const; OPimXRefPartner partner( QDataStream& ); }; #endif diff --git a/libopie2/opiepim/ocontact.cpp b/libopie2/opiepim/ocontact.cpp index a2fb68c..be4ce0a 100644 --- a/libopie2/opiepim/ocontact.cpp +++ b/libopie2/opiepim/ocontact.cpp @@ -729,416 +729,410 @@ QString OContact::displayHomeAddress() const /*! Returns the full name of the contact */ QString OContact::fullName() const { QString title = find( Qtopia::Title ); QString firstName = find( Qtopia::FirstName ); QString middleName = find( Qtopia::MiddleName ); QString lastName = find( Qtopia::LastName ); QString suffix = find( Qtopia::Suffix ); QString name = title; if ( !firstName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += firstName; } if ( !middleName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += middleName; } if ( !lastName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += lastName; } if ( !suffix.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += suffix; } return name.simplifyWhiteSpace(); } /*! Returns a list of the names of the children of the contact. */ QStringList OContact::childrenList() const { return QStringList::split( " ", find( Qtopia::Children ) ); } /*! \fn void OContact::insertEmail( const QString &email ) Insert \a email into the email list. Ensures \a email can only be added once. If there is no default email address set, it sets it to the \a email. */ /*! \fn void OContact::removeEmail( const QString &email ) Removes the \a email from the email list. If the default email was \a email, then the default email address is assigned to the first email in the email list */ /*! \fn void OContact::clearEmails() Clears the email list. */ /*! \fn void OContact::insertEmails( const QStringList &emailList ) Appends the \a emailList to the exiting email list */ /*! Returns a list of email addresses belonging to the contact, including the default email address. */ QStringList OContact::emailList() const { QString emailStr = emails(); QStringList r; if ( !emailStr.isEmpty() ) { qDebug(" emailstr "); QStringList l = QStringList::split( emailSeparator(), emailStr ); for ( QStringList::ConstIterator it = l.begin();it != l.end();++it ) r += (*it).simplifyWhiteSpace(); } return r; } /*! \overload Generates the string for the contact to be filed as from the first, middle and last name of the contact. */ void OContact::setFileAs() { QString lastName, firstName, middleName, fileas; lastName = find( Qtopia::LastName ); firstName = find( Qtopia::FirstName ); middleName = find( Qtopia::MiddleName ); if ( !lastName.isEmpty() && !firstName.isEmpty() && !middleName.isEmpty() ) fileas = lastName + ", " + firstName + " " + middleName; else if ( !lastName.isEmpty() && !firstName.isEmpty() ) fileas = lastName + ", " + firstName; else if ( !lastName.isEmpty() || !firstName.isEmpty() || !middleName.isEmpty() ) fileas = firstName + ( firstName.isEmpty() ? "" : " " ) + middleName + ( middleName.isEmpty() ? "" : " " ) + lastName; replace( Qtopia::FileAs, fileas ); } /*! \internal Appends the contact information to \a buf. */ void OContact::save( QString &buf ) const { static const QStringList SLFIELDS = fields(); // I'm expecting "<Contact " in front of this... for ( QMap<int, QString>::ConstIterator it = mMap.begin(); it != mMap.end(); ++it ) { const QString &value = it.data(); int key = it.key(); if ( !value.isEmpty() ) { if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid) continue; key -= Qtopia::AddressCategory+1; buf += SLFIELDS[key]; buf += "=\"" + Qtopia::escapeString(value) + "\" "; } } buf += customToXml(); if ( categories().count() > 0 ) buf += "Categories=\"" + idsToString( categories() ) + "\" "; buf += "Uid=\"" + QString::number( uid() ) + "\" "; // You need to close this yourself } /*! \internal Returns the list of fields belonging to a contact Never change order of this list ! It has to be regarding enum AddressBookFields !! */ QStringList OContact::fields() { QStringList list; list.append( "Title" ); // Not Used! list.append( "FirstName" ); list.append( "MiddleName" ); list.append( "LastName" ); list.append( "Suffix" ); list.append( "FileAs" ); list.append( "JobTitle" ); list.append( "Department" ); list.append( "Company" ); list.append( "BusinessPhone" ); list.append( "BusinessFax" ); list.append( "BusinessMobile" ); list.append( "DefaultEmail" ); list.append( "Emails" ); list.append( "HomePhone" ); list.append( "HomeFax" ); list.append( "HomeMobile" ); list.append( "BusinessStreet" ); list.append( "BusinessCity" ); list.append( "BusinessState" ); list.append( "BusinessZip" ); list.append( "BusinessCountry" ); list.append( "BusinessPager" ); list.append( "BusinessWebPage" ); list.append( "Office" ); list.append( "Profession" ); list.append( "Assistant" ); list.append( "Manager" ); list.append( "HomeStreet" ); list.append( "HomeCity" ); list.append( "HomeState" ); list.append( "HomeZip" ); list.append( "HomeCountry" ); list.append( "HomeWebPage" ); list.append( "Spouse" ); list.append( "Gender" ); list.append( "Birthday" ); list.append( "Anniversary" ); list.append( "Nickname" ); list.append( "Children" ); list.append( "Notes" ); list.append( "Groups" ); return list; } /*! Sets the list of email address for contact to those contained in \a str. Email address should be separated by ';'s. */ void OContact::setEmails( const QString &str ) { replace( Qtopia::Emails, str ); if ( str.isEmpty() ) setDefaultEmail( QString::null ); } /*! Sets the list of children for the contact to those contained in \a str. */ void OContact::setChildren( const QString &str ) { replace( Qtopia::Children, str ); } /*! \overload Returns TRUE if the contact matches the regular expression \a regexp. Otherwise returns FALSE. */ bool OContact::match( const QRegExp &r ) const { setLastHitField( -1 ); bool match; match = false; QMap<int, QString>::ConstIterator it; for ( it = mMap.begin(); it != mMap.end(); ++it ) { if ( (*it).find( r ) > -1 ) { setLastHitField( it.key() ); match = true; break; } } return match; } QString OContact::toShortText() const { return ( fullName() ); } QString OContact::type() const { return QString::fromLatin1( "OContact" ); } -// Definition is missing ! (se) -QMap<QString,QString> OContact::toExtraMap() const -{ - qWarning ("Function not implemented: OContact::toExtraMap()"); - QMap <QString,QString> useless; - return useless; -} + class QString OContact::recordField( int pos ) const { QStringList SLFIELDS = fields(); // ?? why this ? (se) return SLFIELDS[pos]; } // In future releases, we should store birthday and anniversary // internally as QDate instead of QString ! // QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se) /*! \fn void OContact::setBirthday( const QDate& date ) Sets the birthday for the contact to \a date. If date is null the current stored date will be removed. */ void OContact::setBirthday( const QDate &v ) { if ( v.isNull() ){ qWarning( "Remove Birthday"); replace( Qtopia::Birthday, QString::null ); return; } if ( v.isValid() ) replace( Qtopia::Birthday, OConversion::dateToString( v ) ); } /*! \fn void OContact::setAnniversary( const QDate &date ) Sets the anniversary of the contact to \a date. If date is null, the current stored date will be removed. */ void OContact::setAnniversary( const QDate &v ) { if ( v.isNull() ){ qWarning( "Remove Anniversary"); replace( Qtopia::Anniversary, QString::null ); return; } if ( v.isValid() ) replace( Qtopia::Anniversary, OConversion::dateToString( v ) ); } /*! \fn QDate OContact::birthday() const Returns the birthday of the contact. */ QDate OContact::birthday() const { QString str = find( Qtopia::Birthday ); qWarning ("Birthday %s", str.latin1() ); if ( !str.isEmpty() ) return OConversion::dateFromString ( str ); else return QDate(); } /*! \fn QDate OContact::anniversary() const Returns the anniversary of the contact. */ QDate OContact::anniversary() const { QDate empty; QString str = find( Qtopia::Anniversary ); qWarning ("Anniversary %s", str.latin1() ); if ( !str.isEmpty() ) return OConversion::dateFromString ( str ); else return empty; } void OContact::insertEmail( const QString &v ) { //qDebug("insertEmail %s", v.latin1()); QString e = v.simplifyWhiteSpace(); QString def = defaultEmail(); // if no default, set it as the default email and don't insert if ( def.isEmpty() ) { setDefaultEmail( e ); // will insert into the list for us return; } // otherwise, insert assuming doesn't already exist QString emailsStr = find( Qtopia::Emails ); if ( emailsStr.contains( e )) return; if ( !emailsStr.isEmpty() ) emailsStr += emailSeparator(); emailsStr += e; replace( Qtopia::Emails, emailsStr ); } void OContact::removeEmail( const QString &v ) { QString e = v.simplifyWhiteSpace(); QString def = defaultEmail(); QString emailsStr = find( Qtopia::Emails ); QStringList emails = emailList(); // otherwise, must first contain it if ( !emailsStr.contains( e ) ) return; // remove it //qDebug(" removing email from list %s", e.latin1()); emails.remove( e ); // reset the string emailsStr = emails.join(emailSeparator()); // Sharp's brain dead separator replace( Qtopia::Emails, emailsStr ); // if default, then replace the default email with the first one if ( def == e ) { //qDebug("removeEmail is default; setting new default"); if ( !emails.count() ) clearEmails(); else // setDefaultEmail will remove e from the list setDefaultEmail( emails.first() ); } } void OContact::clearEmails() { mMap.remove( Qtopia::DefaultEmail ); mMap.remove( Qtopia::Emails ); } void OContact::setDefaultEmail( const QString &v ) { QString e = v.simplifyWhiteSpace(); //qDebug("OContact::setDefaultEmail %s", e.latin1()); replace( Qtopia::DefaultEmail, e ); if ( !e.isEmpty() ) insertEmail( e ); } void OContact::insertEmails( const QStringList &v ) { for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) insertEmail( *it ); } int OContact::rtti() { return OPimResolver::AddressBook; } void OContact::setUid( int i ) { OPimRecord::setUid(i); replace( Qtopia::AddressUid , QString::number(i)); } diff --git a/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp index e4f5d92..7bcf944 100644 --- a/libopie2/opiepim/oevent.cpp +++ b/libopie2/opiepim/oevent.cpp @@ -107,474 +107,471 @@ void OEvent::setLocation( const QString& loc ) { QString OEvent::location()const { return data->location; } OPimNotifyManager &OEvent::notifiers()const { // I hope we can skip the changeOrModify here // the notifier should take care of it // and OPimNotify is shared too if (!data->manager ) data->manager = new OPimNotifyManager; return *data->manager; } bool OEvent::hasNotifiers()const { if (!data->manager ) return false; if (data->manager->reminders().isEmpty() && data->manager->alarms().isEmpty() ) return false; return true; } ORecur OEvent::recurrence()const { if (!data->recur) data->recur = new ORecur; return *data->recur; } void OEvent::setRecurrence( const ORecur& rec) { changeOrModify(); if (data->recur ) (*data->recur) = rec; else data->recur = new ORecur( rec ); } bool OEvent::hasRecurrence()const { if (!data->recur ) return false; return data->recur->doesRecur(); } QString OEvent::note()const { return data->note; } void OEvent::setNote( const QString& note ) { changeOrModify(); data->note = note; } QDateTime OEvent::createdDateTime()const { return data->created; } void OEvent::setCreatedDateTime( const QDateTime& time ) { changeOrModify(); data->created = time; } QDateTime OEvent::startDateTime()const { if ( data->isAllDay ) return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); return data->start; } QDateTime OEvent::startDateTimeInZone()const { /* if no timezone, or all day event or if the current and this timeZone match... */ if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); OTimeZone zone(data->timezone ); return zone.toDateTime( data->start, OTimeZone::current() ); } void OEvent::setStartDateTime( const QDateTime& dt ) { changeOrModify(); data->start = dt; } QDateTime OEvent::endDateTime()const { /* * if all Day event the end time needs * to be on the same day as the start */ if ( data->isAllDay ) return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); return data->end; } QDateTime OEvent::endDateTimeInZone()const { /* if no timezone, or all day event or if the current and this timeZone match... */ if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); OTimeZone zone(data->timezone ); return zone.toDateTime( data->end, OTimeZone::current() ); } void OEvent::setEndDateTime( const QDateTime& dt ) { changeOrModify(); data->end = dt; } bool OEvent::isMultipleDay()const { return data->end.date().day() - data->start.date().day(); } bool OEvent::isAllDay()const { return data->isAllDay; } void OEvent::setAllDay( bool allDay ) { changeOrModify(); data->isAllDay = allDay; if (allDay ) data->timezone = "UTC"; } void OEvent::setTimeZone( const QString& tz ) { changeOrModify(); data->timezone = tz; } QString OEvent::timeZone()const { if (data->isAllDay ) return QString::fromLatin1("UTC"); return data->timezone; } bool OEvent::match( const QRegExp& re )const { if ( re.match( data->description ) != -1 ){ setLastHitField( Qtopia::DatebookDescription ); return true; } if ( re.match( data->note ) != -1 ){ setLastHitField( Qtopia::Note ); return true; } if ( re.match( data->location ) != -1 ){ setLastHitField( Qtopia::Location ); return true; } if ( re.match( data->start.toString() ) != -1 ){ setLastHitField( Qtopia::StartDateTime ); return true; } if ( re.match( data->end.toString() ) != -1 ){ setLastHitField( Qtopia::EndDateTime ); return true; } return false; } QString OEvent::toRichText()const { QString text, value; // description text += "<b><h3><img src=\"datebook/DateBook\">"; if ( !description().isEmpty() ) { text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "" ); } text += "</h3></b><br><hr><br>"; // location if ( !(value = location()).isEmpty() ) { text += "<b>" + QObject::tr( "Location:" ) + "</b> "; text += Qtopia::escapeString(value) + "<br>"; } // all day event if ( isAllDay() ) { text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>"; } // multiple day event else if ( isMultipleDay () ) { text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>"; } // start & end times else { // start time if ( startDateTime().isValid() ) { text += "<b>" + QObject::tr( "Start:") + "</b> "; text += Qtopia::escapeString(startDateTime().toString() ). replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; } // end time if ( endDateTime().isValid() ) { text += "<b>" + QObject::tr( "End:") + "</b> "; text += Qtopia::escapeString(endDateTime().toString() ). replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; } } // categories if ( categoryNames("Calendar").count() ){ text += "<b>" + QObject::tr( "Category:") + "</b> "; text += categoryNames("Calendar").join(", "); text += "<br>"; } //notes if ( !note().isEmpty() ) { text += "<b>" + QObject::tr( "Note:") + "</b><br>"; text += note(); // text += Qtopia::escapeString(note() ). // replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; } return text; } QString OEvent::toShortText()const { QString text; text += QString::number( startDateTime().date().day() ); text += "."; text += QString::number( startDateTime().date().month() ); text += "."; text += QString::number( startDateTime().date().year() ); text += " "; text += QString::number( startDateTime().time().hour() ); text += ":"; text += QString::number( startDateTime().time().minute() ); text += " - "; text += description(); return text; } QString OEvent::type()const { return QString::fromLatin1("OEvent"); } QString OEvent::recordField( int /*id */ )const { return QString::null; } int OEvent::rtti() { return OPimResolver::DateBook; } bool OEvent::loadFromStream( QDataStream& ) { return true; } bool OEvent::saveToStream( QDataStream& )const { return true; } void OEvent::changeOrModify() { if ( data->count != 1 ) { data->deref(); Data* d2 = new Data; d2->description = data->description; d2->location = data->location; if (data->manager ) d2->manager = new OPimNotifyManager( *data->manager ); if ( data->recur ) d2->recur = new ORecur( *data->recur ); d2->note = data->note; d2->created = data->created; d2->start = data->start; d2->end = data->end; d2->isAllDay = data->isAllDay; d2->timezone = data->timezone; d2->parent = data->parent; if ( data->child ) { d2->child = new QArray<int>( *data->child ); d2->child->detach(); } data = d2; } } void OEvent::deref() { if ( data->deref() ) { delete data; data = 0; } } // FIXME QMap<int, QString> OEvent::toMap()const { return QMap<int, QString>(); } -QMap<QString, QString> OEvent::toExtraMap()const { - return QMap<QString, QString>(); -} int OEvent::parent()const { return data->parent; } void OEvent::setParent( int uid ) { changeOrModify(); data->parent = uid; } QArray<int> OEvent::children() const{ if (!data->child) return QArray<int>(); else return data->child->copy(); } void OEvent::setChildren( const QArray<int>& arr ) { changeOrModify(); if (data->child) delete data->child; data->child = new QArray<int>( arr ); data->child->detach(); } void OEvent::addChild( int uid ) { changeOrModify(); if (!data->child ) { data->child = new QArray<int>(1); (*data->child)[0] = uid; }else{ int count = data->child->count(); data->child->resize( count + 1 ); (*data->child)[count] = uid; } } void OEvent::removeChild( int uid ) { if (!data->child || !data->child->contains( uid ) ) return; changeOrModify(); QArray<int> newAr( data->child->count() - 1 ); int j = 0; uint count = data->child->count(); for ( uint i = 0; i < count; i++ ) { if ( (*data->child)[i] != uid ) { newAr[j] = (*data->child)[i]; j++; } } (*data->child) = newAr; } struct OEffectiveEvent::Data : public QShared { Data() : QShared() { } OEvent event; QDate date; QTime start, end; QDate startDate, endDate; bool dates : 1; }; OEffectiveEvent::OEffectiveEvent() { data = new Data; data->date = QDate::currentDate(); data->start = data->end = QTime::currentTime(); data->dates = false; } OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, Position pos ) { data = new Data; data->event = ev; data->date = startDate; if ( pos & Start ) data->start = ev.startDateTime().time(); else data->start = QTime( 0, 0, 0 ); if ( pos & End ) data->end = ev.endDateTime().time(); else data->end = QTime( 23, 59, 59 ); data->dates = false; } OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { data = ev.data; data->ref(); } OEffectiveEvent::~OEffectiveEvent() { if ( data->deref() ) { delete data; data = 0; } } OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { if ( *this == ev ) return *this; ev.data->ref(); deref(); data = ev.data; return *this; } void OEffectiveEvent::setStartTime( const QTime& ti) { changeOrModify(); data->start = ti; } void OEffectiveEvent::setEndTime( const QTime& en) { changeOrModify(); data->end = en; } void OEffectiveEvent::setEvent( const OEvent& ev) { changeOrModify(); data->event = ev; } void OEffectiveEvent::setDate( const QDate& da) { changeOrModify(); data->date = da; } void OEffectiveEvent::setEffectiveDates( const QDate& from, const QDate& to ) { if (!from.isValid() ) { data->dates = false; return; } data->startDate = from; data->endDate = to; } QString OEffectiveEvent::description()const { return data->event.description(); } QString OEffectiveEvent::location()const { return data->event.location(); } QString OEffectiveEvent::note()const { return data->event.note(); } OEvent OEffectiveEvent::event()const { return data->event; } QTime OEffectiveEvent::startTime()const { return data->start; } QTime OEffectiveEvent::endTime()const { return data->end; } QDate OEffectiveEvent::date()const { return data->date; } int OEffectiveEvent::length()const { return (data->end.hour() * 60 - data->start.hour() * 60) + QABS(data->start.minute() - data->end.minute() ); } int OEffectiveEvent::size()const { return ( data->end.hour() - data->start.hour() ) * 3600 + (data->end.minute() - data->start.minute() * 60 + data->end.second() - data->start.second() ); } QDate OEffectiveEvent::startDate()const { if ( data->dates ) return data->startDate; else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer return data->date; else return data->event.startDateTime().date(); } QDate OEffectiveEvent::endDate()const { if ( data->dates ) return data->endDate; else if ( data->event.hasRecurrence() ) return data->date; else return data->event.endDateTime().date(); } void OEffectiveEvent::deref() { if ( data->deref() ) { delete data; data = 0; } } void OEffectiveEvent::changeOrModify() { if ( data->count != 1 ) { data->deref(); Data* d2 = new Data; d2->event = data->event; d2->date = data->date; d2->start = data->start; d2->end = data->end; d2->startDate = data->startDate; d2->endDate = data->endDate; d2->dates = data->dates; data = d2; } } bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{ if ( data->date < e.date() ) return TRUE; if ( data->date == e.date() ) return ( startTime() < e.startTime() ); else return FALSE; } bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const{ return (data->date <= e.date() ); } bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const { return ( date() == e.date() && startTime() == e.startTime() && endTime()== e.endTime() && event() == e.event() ); } bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const { return !(*this == e ); } bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const { return !(*this <= e ); } bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const { return !(*this < e); } diff --git a/libopie2/opiepim/oevent.h b/libopie2/opiepim/oevent.h index b696d81..30f442e 100644 --- a/libopie2/opiepim/oevent.h +++ b/libopie2/opiepim/oevent.h @@ -1,221 +1,220 @@ // CONTAINS GPLed code of TT #ifndef OPIE_PIM_EVENT_H #define OPIE_PIM_EVENT_H #include <qstring.h> #include <qdatetime.h> #include <qvaluelist.h> #include <qpe/recordfields.h> #include <qpe/palmtopuidgen.h> #include "otimezone.h" #include "opimrecord.h" struct OCalendarHelper { /** calculate the week number of the date */ static int week( const QDate& ); /** calculate the occurence of week days since the start of the month */ static int ocurrence( const QDate& ); // returns the dayOfWeek for the *first* day it finds (ignores // any further days!). Returns 1 (Monday) if there isn't any day found static int dayOfWeek( char day ); /** returns the diff of month */ static int monthDiff( const QDate& first, const QDate& second ); }; class OPimNotifyManager; class ORecur; /** * This is the container for all Events. It encapsules all * available information for a single Event * @short container for events. */ class OEvent : public OPimRecord { public: typedef QValueList<OEvent> ValueList; /** * RecordFields contain possible attributes */ enum RecordFields { Uid = Qtopia::UID_ID, Category = Qtopia::CATEGORY_ID, Description, Location, Alarm, Reminder, Recurrence, Note, Created, StartDate, EndDate, AllDay, TimeZone }; /** * Start with an Empty OEvent. UID == 0 means that it is empty */ OEvent(int uid = 0); /** * copy c'tor */ OEvent( const OEvent& ); ~OEvent(); OEvent &operator=( const OEvent& ); QString description()const; void setDescription( const QString& description ); QString location()const; void setLocation( const QString& loc ); bool hasNotifiers()const; OPimNotifyManager ¬ifiers()const; ORecur recurrence()const; void setRecurrence( const ORecur& ); bool hasRecurrence()const; QString note()const; void setNote( const QString& note ); QDateTime createdDateTime()const; void setCreatedDateTime( const QDateTime& dt); /** set the date to dt. dt is the QDateTime in localtime */ void setStartDateTime( const QDateTime& ); /** returns the datetime in the local timeZone */ QDateTime startDateTime()const; /** returns the start datetime in the current zone */ QDateTime startDateTimeInZone()const; /** in current timezone */ void setEndDateTime( const QDateTime& ); /** in current timezone */ QDateTime endDateTime()const; QDateTime endDateTimeInZone()const; bool isMultipleDay()const; bool isAllDay()const; void setAllDay( bool isAllDay ); /* pin this event to a timezone! FIXME */ void setTimeZone( const QString& timeZone ); QString timeZone()const; virtual bool match( const QRegExp& )const; /** For exception to recurrence here is a list of children... */ QArray<int> children()const; void setChildren( const QArray<int>& ); void addChild( int uid ); void removeChild( int uid ); /** return the parent OEvent */ int parent()const; void setParent( int uid ); /* needed reimp */ QString toRichText()const; QString toShortText()const; QString type()const; QMap<int, QString> toMap()const; - QMap<QString, QString> toExtraMap()const; QString recordField(int )const; static int rtti(); bool loadFromStream( QDataStream& ); bool saveToStream( QDataStream& )const; /* bool operator==( const OEvent& ); bool operator!=( const OEvent& ); bool operator<( const OEvent& ); bool operator<=( const OEvent& ); bool operator>( const OEvent& ); bool operator>=(const OEvent& ); */ private: inline void changeOrModify(); void deref(); struct Data; Data* data; class Private; Private* priv; }; /** * AN Event can span through multiple days. We split up a multiday eve */ class OEffectiveEvent { public: typedef QValueList<OEffectiveEvent> ValueList; enum Position { MidWay, Start, End, StartEnd }; // If we calculate the effective event of a multi-day event // we have to figure out whether we are at the first day, // at the end, or anywhere else ("middle"). This is important // for the start/end times (00:00/23:59) // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- // day event // Start: start time -> 23:59 // End: 00:00 -> end time // Start | End == StartEnd: for single-day events (default) // here we draw start time -> end time OEffectiveEvent(); OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); OEffectiveEvent( const OEffectiveEvent& ); OEffectiveEvent &operator=(const OEffectiveEvent& ); ~OEffectiveEvent(); void setStartTime( const QTime& ); void setEndTime( const QTime& ); void setEvent( const OEvent& ); void setDate( const QDate& ); void setEffectiveDates( const QDate& from, const QDate& to ); QString description()const; QString location()const; QString note()const; OEvent event()const; QTime startTime()const; QTime endTime()const; QDate date()const; /* return the length in hours */ int length()const; int size()const; QDate startDate()const; QDate endDate()const; bool operator<( const OEffectiveEvent &e ) const; bool operator<=( const OEffectiveEvent &e ) const; bool operator==( const OEffectiveEvent &e ) const; bool operator!=( const OEffectiveEvent &e ) const; bool operator>( const OEffectiveEvent &e ) const; bool operator>= ( const OEffectiveEvent &e ) const; private: void deref(); inline void changeOrModify(); class Private; Private* priv; struct Data; Data* data; }; #endif diff --git a/libopie2/opiepim/otodo.cpp b/libopie2/opiepim/otodo.cpp index c84eeeb..38b93f7 100644 --- a/libopie2/opiepim/otodo.cpp +++ b/libopie2/opiepim/otodo.cpp @@ -207,313 +207,310 @@ void OTodo::setDescription(const QString &desc ) 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 += "<b><h3><img src=\"todo/TodoList\">"; if ( !summary().isEmpty() ) { text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "" ); } text += "</h3></b><br><hr><br>"; // description if( !description().isEmpty() ){ text += "<b>" + QObject::tr( "Description:" ) + "</b><br>"; text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) ; } // priority int priorityval = priority(); text += "<b>" + QObject::tr( "Priority:") +" </b><img src=\"todo/priority" + QString::number( priorityval ) + "\">"; // text += "<b>" + QObject::tr( "Priority:") +"</b><img src=\"todo/priority" + // QString::number( priority() ) + "\"><br>"; 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 += "<br>"; // progress text += "<b>" + QObject::tr( "Progress:") + " </b>" + QString::number( progress() ) + " %<br>"; // due date if (hasDueDate() ){ QDate dd = dueDate(); int off = QDate::currentDate().daysTo( dd ); text += "<b>" + QObject::tr( "Deadline:" ) + " </b><font color=\""; if ( off < 0 ) text += "#FF0000"; else if ( off == 0 ) text += "#FFFF00"; else if ( off > 0 ) text += "#00FF00"; text += "\">" + dd.toString() + "</font><br>"; } // categories text += "<b>" + QObject::tr( "Category:") + "</b> "; text += categoryNames( "Todo List" ).join(", "); text += "<br>"; 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<int, QString> OTodo::toMap() const { QMap<int, QString> 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; } -QMap<QString, QString> OTodo::toExtraMap()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 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; } diff --git a/libopie2/opiepim/otodo.h b/libopie2/opiepim/otodo.h index 4d5ee36..f9a345a 100644 --- a/libopie2/opiepim/otodo.h +++ b/libopie2/opiepim/otodo.h @@ -1,295 +1,294 @@ #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 OPimState; class ORecur; class OPimMaintainer; class OPimNotifyManager; class OTodo : public OPimRecord { public: typedef QValueList<OTodo> ValueList; enum RecordFields { Uid = Qtopia::UID_ID, Category = Qtopia::CATEGORY_ID, HasDate, Completed, Description, Summary, Priority, DateDay, DateMonth, DateYear, Progress, CrossReference, State, Recurrence, Alarms, Reminders, Notifiers, Maintainer, StartDate, CompletedDate }; 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 = 0 /*empty*/ ); OTodo( bool completed, int priority, const QArray<int>& category, const QString& summary = QString::null, const QString& description = QString::null, ushort progress = 0, bool hasDate = false, QDate date = QDate::currentDate(), int uid = 0 /* empty */ ); /** Copy c'tor * */ OTodo(const OTodo & ); /** *destructor */ ~OTodo(); /** * Is this event completed? */ bool isCompleted() const; /** * Does this Event have a deadline */ bool hasDueDate() const; bool hasStartDate()const; bool hasCompletedDate()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; /** * When did it start? */ QDate startDate()const; /** * When was it completed? */ QDate completedDate()const; /** * does it have a state? */ bool hasState()const; /** * What is the state of this OTodo? */ OPimState state()const; /** * has recurrence? */ bool hasRecurrence()const; /** * the recurrance of this */ ORecur recurrence()const; /** * does this OTodo have a maintainer? */ bool hasMaintainer()const; /** * the Maintainer of this OTodo */ OPimMaintainer maintainer()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; bool hasNotifiers()const; /* * FIXME check if the sharing is still fine!! -zecke * ### CHECK If API is fine */ /** * return a reference to our notifiers... */ OPimNotifyManager ¬ifiers(); /** * */ const OPimNotifyManager ¬ifiers()const; /** * reimplementations */ QString type()const; QString toShortText()const; - QMap<QString, QString> toExtraMap()const; QString recordField(int id )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 ); // FIXME we do not have these for start, completed // cause we'll use the isNull() of QDate for figuring // out if it's has a date... // decide what to do here? -zecke /** * Set the priority of the Todo */ void setPriority(int priority ); /** * Set the progress. */ void setProgress( ushort progress ); /** * set the end date */ void setDueDate( const QDate& date ); /** * set the start date */ void setStartDate( const QDate& date ); /** * set the completed date */ void setCompletedDate( const QDate& date ); void setRecurrence( const ORecur& ); /** * set the alarm time */ void setAlarmDateTime ( const QDateTime& alarm ); void setDescription(const QString& ); void setSummary(const QString& ); /** * set the state of a Todo * @param state State what the todo should take */ void setState( const OPimState& state); /** * set the Maintainer Mode */ void setMaintainer( const OPimMaintainer& ); bool isOverdue(); virtual 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; OTodo &operator=(const OTodo &toDoEvent ); static int rtti(); private: class OTodoPrivate; struct OTodoData; void deref(); inline void changeOrModify(); void copy( OTodoData* src, OTodoData* dest ); OTodoPrivate *d; OTodoData *data; }; inline bool OTodo::operator!=(const OTodo &toDoEvent )const { return !(*this == toDoEvent); } #endif |