-rw-r--r-- | libopie/pim/otodoaccesssql.cpp | 9 | ||||
-rw-r--r-- | libopie/pim/otodoaccessvcal.cpp | 192 | ||||
-rw-r--r-- | libopie/pim/otodoaccessvcal.h | 35 |
3 files changed, 232 insertions, 4 deletions
diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp index ea8b3c9..9ef6b7c 100644 --- a/libopie/pim/otodoaccesssql.cpp +++ b/libopie/pim/otodoaccesssql.cpp @@ -97,404 +97,405 @@ namespace { class OverDueQuery : public OSQLQuery { public: OverDueQuery(); ~OverDueQuery(); QString query()const; }; class EffQuery : public OSQLQuery { public: EffQuery( const QDate&, const QDate&, bool inc ); ~EffQuery(); QString query()const; private: QString with()const; QString out()const; QDate m_start; QDate m_end; bool m_inc :1; }; CreateQuery::CreateQuery() : OSQLQuery() {} CreateQuery::~CreateQuery() {} QString CreateQuery::query()const { QString qu; qu += "create table todolist( uid, categories, completed, progress, "; qu += "summary, DueDate, priority, description )"; return qu; } LoadQuery::LoadQuery() : OSQLQuery() {} LoadQuery::~LoadQuery() {} QString LoadQuery::query()const { QString qu; qu += "select distinct uid from todolist"; return qu; } InsertQuery::InsertQuery( const OTodo& todo ) : OSQLQuery(), m_todo( todo ) { } InsertQuery::~InsertQuery() { } /* * converts from a OTodo to a query * we leave out X-Ref + Alarms */ QString InsertQuery::query()const{ int year, month, day; year = month = day = 0; if (m_todo.hasDueDate() ) { QDate date = m_todo.dueDate(); year = date.year(); month = date.month(); day = date.day(); } QString qu; qu = "insert into todolist VALUES(" + QString::number( m_todo.uid() ) + ",'" + m_todo.idsToString( m_todo.categories() ) + "',"; qu += QString::number( m_todo.isCompleted() ) + "," + QString::number( m_todo.progress() ) + ","; qu += "'"+m_todo.summary()+"','"+QString::number(year)+"-"+QString::number(month)+"-"+QString::number(day)+"',"; qu += QString::number(m_todo.priority() ) +",'" + m_todo.description() + "')"; qWarning("add %s", qu.latin1() ); return qu; } RemoveQuery::RemoveQuery(int uid ) : OSQLQuery(), m_uid( uid ) {} RemoveQuery::~RemoveQuery() {} QString RemoveQuery::query()const { QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); return qu; } ClearQuery::ClearQuery() : OSQLQuery() {} ClearQuery::~ClearQuery() {} QString ClearQuery::query()const { QString qu = "drop table todolist"; return qu; } FindQuery::FindQuery(int uid) : OSQLQuery(), m_uid(uid ) { } FindQuery::FindQuery(const QArray<int>& ints) : OSQLQuery(), m_uids(ints){ } FindQuery::~FindQuery() { } QString FindQuery::query()const{ if (m_uids.count() == 0 ) return single(); else return multi(); } QString FindQuery::single()const{ QString qu = "select uid, categories, completed, progress, summary, "; qu += "DueDate, priority, description from todolist where uid = " + QString::number(m_uid); return qu; } QString FindQuery::multi()const { QString qu = "select uid, categories, completed, progress, summary, "; qu += "DueDate, priority, description from todolist where "; for (uint i = 0; i < m_uids.count(); i++ ) { qu += " UID = " + QString::number( m_uids[i] ) + " OR"; } qu.remove( qu.length()-2, 2 ); return qu; } OverDueQuery::OverDueQuery(): OSQLQuery() {} OverDueQuery::~OverDueQuery() {} QString OverDueQuery::query()const { QDate date = QDate::currentDate(); QString str; str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); return str; } EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} EffQuery::~EffQuery() {} QString EffQuery::query()const { return m_inc ? with() : out(); } QString EffQuery::with()const { QString str; str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); return str; } QString EffQuery::out()const { QString str; str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); return str; } }; OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) : OTodoAccessBackend(), m_dict(15), m_dirty(true) { QString fi = file; if ( fi.isEmpty() ) fi = Global::applicationFileName( "todolist", "todolist.db" ); OSQLManager man; m_driver = man.standard(); m_driver->setUrl(fi); fillDict(); } OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ } bool OTodoAccessBackendSQL::load(){ if (!m_driver->open() ) return false; CreateQuery creat; OSQLResult res = m_driver->query(&creat ); m_dirty = true; return true; } bool OTodoAccessBackendSQL::reload(){ return load(); } bool OTodoAccessBackendSQL::save(){ return m_driver->close(); } QArray<int> OTodoAccessBackendSQL::allRecords()const { if (m_dirty ) update(); return m_uids; } QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int ){ QArray<int> ints(0); return ints; } OTodo OTodoAccessBackendSQL::find(int uid ) const{ FindQuery query( uid ); return todo( m_driver->query(&query) ); } +#define CACHE 32 OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, uint cur, Frontend::CacheDirection dir ) const{ qWarning("searching for %d", uid ); - QArray<int> search( 8 ); + QArray<int> search( CACHE ); uint size =0; OTodo to; - // we try to cache 8 items + // we try to cache CACHE items switch( dir ) { /* forward */ case 0: - for (uint i = cur; i < ints.count() && size < 8; i++ ) { + for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { qWarning("size %d %d", size, ints[i] ); search[size] = ints[i]; size++; } break; /* reverse */ case 1: - for (uint i = cur; i != 0 && size < 8; i-- ) { + for (uint i = cur; i != 0 && size < CACHE; i-- ) { search[size] = ints[i]; size++; } break; } search.resize( size ); FindQuery query( search ); OSQLResult res = m_driver->query( &query ); if ( res.state() != OSQLResult::Success ) return to; return todo( res ); } void OTodoAccessBackendSQL::clear() { ClearQuery cle; OSQLResult res = m_driver->query( &cle ); CreateQuery qu; res = m_driver->query(&qu); } bool OTodoAccessBackendSQL::add( const OTodo& t) { InsertQuery ins( t ); OSQLResult res = m_driver->query( &ins ); if ( res.state() == OSQLResult::Failure ) return false; int c = m_uids.count(); m_uids.resize( c+1 ); m_uids[c] = t.uid(); return true; } bool OTodoAccessBackendSQL::remove( int uid ) { RemoveQuery rem( uid ); OSQLResult res = m_driver->query(&rem ); if ( res.state() == OSQLResult::Failure ) return false; m_dirty = true; return true; } /* * FIXME better set query * but we need the cache for that * now we remove */ bool OTodoAccessBackendSQL::replace( const OTodo& t) { remove( t.uid() ); bool b= add(t); m_dirty = false; // we changed some stuff but the UID stayed the same return b; } QArray<int> OTodoAccessBackendSQL::overDue() { OverDueQuery qu; return uids( m_driver->query(&qu ) ); } QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, const QDate& t, bool u) { EffQuery ef(s, t, u ); return uids (m_driver->query(&ef) ); } /* * */ QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, int sortFilter, int cat ) { qWarning("sorted %d, %d", asc, sortOrder ); QString query; query = "select uid from todolist WHERE "; /* * Sort Filter stuff * not that straight forward * */ /* Category */ if ( sortFilter & 1 ) { QString str; if (cat != 0 ) str = QString::number( cat ); query += " categories like '%" +str+"%' AND"; } /* Show only overdue */ if ( sortFilter & 2 ) { QDate date = QDate::currentDate(); QString due; QString base; base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); query += " " + base + " AND"; } /* not show completed */ if ( sortFilter & 4 ) { query += " completed = 0 AND"; }else{ query += " ( completed = 1 OR completed = 0) AND"; } /* srtip the end */ query = query.remove( query.length()-3, 3 ); /* * sort order stuff * quite straight forward */ query += "ORDER BY "; switch( sortOrder ) { /* completed */ case 0: query += "completed"; break; case 1: query += "priority"; break; case 2: query += "description"; break; case 3: query += "DueDate"; break; } if ( !asc ) { qWarning("not ascending!"); query += " DESC"; } qWarning( query ); OSQLRawQuery raw(query ); return uids( m_driver->query(&raw) ); } bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ if ( str == "0-0-0" ) return false; else{ int day, year, month; QStringList list = QStringList::split("-", str ); year = list[0].toInt(); month = list[1].toInt(); day = list[2].toInt(); da.setYMD( year, month, day ); return true; } } OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ if ( res.state() == OSQLResult::Failure ) { OTodo to; return to; } OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it = list.begin(); qWarning("todo1"); OTodo to = todo( (*it) ); cache( to ); ++it; for ( ; it != list.end(); ++it ) { qWarning("caching"); cache( todo( (*it) ) ); } return to; } OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const { qWarning("todo"); bool has = false; QDate da = QDate::currentDate(); has = date( da, item.data("DueDate") ); QStringList cats = QStringList::split(";", item.data("categories") ); OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), cats, item.data("summary"), item.data("description"), item.data("progress").toUShort(), has, da, item.data("uid").toInt() ); return to; } OTodo OTodoAccessBackendSQL::todo( int uid )const { FindQuery find( uid ); return todo( m_driver->query(&find) ); } /* * update the dict */ void OTodoAccessBackendSQL::fillDict() { /* initialize dict */ /* * UPDATE dict if you change anything!!! */ m_dict.setAutoDelete( TRUE ); m_dict.insert("Categories" , new int(OTodo::Category) ); m_dict.insert("Uid" , new int(OTodo::Uid) ); m_dict.insert("HasDate" , new int(OTodo::HasDate) ); m_dict.insert("Completed" , new int(OTodo::Completed) ); m_dict.insert("Description" , new int(OTodo::Description) ); diff --git a/libopie/pim/otodoaccessvcal.cpp b/libopie/pim/otodoaccessvcal.cpp new file mode 100644 index 0000000..ac70ea0 --- a/dev/null +++ b/libopie/pim/otodoaccessvcal.cpp @@ -0,0 +1,192 @@ +#include <qfile.h> + +#include <qtopia/private/vobject_p.h> +#include <qtopia/timeconversion.h> +#include <qtopia/private/qfiledirect_p.h> + +#include "otodoaccessvcal.h" + +namespace { + static OTodo eventByVObj( VObject *obj ){ + OTodo event; + VObject *ob; + QCString name; + // no uid, attendees, ... and no fun + // description + if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){ + name = vObjectStringZValue( ob ); + event.setDescription( name ); + } + // summary + if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) { + name = vObjectStringZValue( ob ); + event.setSummary( name ); + } + // completed + if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){ + name = vObjectStringZValue( ob ); + if( name == "COMPLETED" ){ + event.setCompleted( true ); + }else{ + event.setCompleted( false ); + } + }else + event.setCompleted( false ); + // priority + if ((ob = isAPropertyOf(obj, VCPriorityProp))) { + name = vObjectStringZValue( ob ); + bool ok; + event.setPriority(name.toInt(&ok) ); + } + //due date + if((ob = isAPropertyOf(obj, VCDueProp)) ){ + event.setHasDueDate( true ); + name = vObjectStringZValue( ob ); + event.setDueDate( TimeConversion::fromISO8601( name).date() ); + } + // categories + if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){ + name = vObjectStringZValue( ob ); + qWarning("Categories:%s", name.data() ); + } + + event.setUid( 1 ); + return event; + }; + static VObject *vobjByEvent( const OTodo &event ) { + VObject *task = newVObject( VCTodoProp ); + if( task == 0 ) + return 0l; + + if( event.hasDueDate() ) + addPropValue( task, VCDueProp, + TimeConversion::toISO8601( event.dueDate() ) ); + + if( event.isCompleted() ) + addPropValue( task, VCStatusProp, "COMPLETED"); + + QString string = QString::number(event.priority() ); + addPropValue( task, VCPriorityProp, string.local8Bit() ); + + addPropValue( task, VCCategoriesProp, + event.idsToString( event.categories() ).local8Bit() ); + + addPropValue( task, VCDescriptionProp, + event.description().local8Bit() ); + + addPropValue( task, VCSummaryProp, + event.summary().local8Bit() ); + return task; +}; +} + +OTodoAccessVCal::OTodoAccessVCal( const QString& path ) + : m_dirty(false), m_file( path ) +{ +} +OTodoAccessVCal::~OTodoAccessVCal() { +} +bool OTodoAccessVCal::load() { + m_map.clear(); + m_dirty = false; + + VObject* vcal = 0l; + vcal = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); + if (!vcal ) + return false; + + // Iterate over the list + VObjectIterator it; + VObject* vobj; + + initPropIterator(&it, vcal); + + while( moreIteration( &it ) ) { + vobj = ::nextVObject( &it ); + QCString name = ::vObjectName( vobj ); + if( name == VCTodoProp ){ + OTodo to = eventByVObj( vobj ); + m_map.insert( to.uid(), to ); + } + } + + // Should I do a delete vcal? + + return true; +} +bool OTodoAccessVCal::reload() { + return load(); +} +bool OTodoAccessVCal::save() { + if (!m_dirty ) + return true; + + QFileDirect file( m_file ); + if (!file.open(IO_WriteOnly ) ) + return false; + + VObject *obj; + obj = newVObject( VCCalProp ); + addPropValue( obj, VCVersionProp, "1.0" ); + VObject *vo; + for(QMap<int, OTodo>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ + vo = vobjByEvent( it.data() ); + addVObjectProp(obj, vo ); + } + writeVObject( file.directHandle(), obj ); + cleanVObject( obj ); + cleanStrTbl(); + + m_dirty = false; + return true; +} +void OTodoAccessVCal::clear() { + m_map.clear(); + m_dirty = true; +} +bool OTodoAccessVCal::add( const OTodo& to ) { + m_map.insert( to.uid(), to ); + m_dirty = true; + return true; +} +bool OTodoAccessVCal::remove( int uid ) { + m_map.remove( uid ); + m_dirty = true; + return true; +} +bool OTodoAccessVCal::replace( const OTodo& to ) { + m_map.replace( to.uid(), to ); + m_dirty = true; + return true; +} +OTodo OTodoAccessVCal::find(int uid )const { + return m_map[uid]; +} +QArray<int> OTodoAccessVCal::sorted( bool, int, int, int ) { + QArray<int> ar(0); + return ar; +} +QArray<int> OTodoAccessVCal::allRecords()const { + QArray<int> ar( m_map.count() ); + QMap<int, OTodo>::ConstIterator it; + int i = 0; + for ( it = m_map.begin(); it != m_map.end(); ++it ) { + ar[i] = it.key(); + i++; + } + return ar; +} +QArray<int> OTodoAccessVCal::queryByExample( const OTodo&, int ) { + QArray<int> ar(0); + return ar; +} +QArray<int> OTodoAccessVCal::effectiveToDos( const QDate& , + const QDate& , + bool ) { + QArray<int> ar(0); + return ar; +} +QArray<int> OTodoAccessVCal::overDue() { + QArray<int> ar(0); + return ar; +} diff --git a/libopie/pim/otodoaccessvcal.h b/libopie/pim/otodoaccessvcal.h new file mode 100644 index 0000000..4499a7e --- a/dev/null +++ b/libopie/pim/otodoaccessvcal.h @@ -0,0 +1,35 @@ +#ifndef OPIE_OTODO_ACCESS_VCAL_H +#define OPIE_OTODO_ACCESS_VCAL_H + +#include "otodoaccessbackend.h" + +class OTodoAccessVCal : public OTodoAccessBackend { +public: + OTodoAccessVCal(const QString& ); + ~OTodoAccessVCal(); + + bool load(); + bool reload(); + bool save(); + + QArray<int> allRecords()const; + QArray<int> queryByExample( const OTodo& t, int sort ); + QArray<int> effectiveToDos( const QDate& start, + const QDate& end, + bool includeNoDates ); + QArray<int> overDue(); + QArray<int> sorted( bool asc, int sortOrder, int sortFilter, + int cat ); + OTodo find(int uid)const; + void clear(); + bool add( const OTodo& ); + bool remove( int uid ); + bool replace( const OTodo& ); + +private: + bool m_dirty : 1; + QString m_file; + QMap<int, OTodo> m_map; +}; + +#endif |