-rw-r--r-- | libopie/libopie.pro | 6 | ||||
-rw-r--r-- | libopie/pim/opimrecord.cpp | 63 | ||||
-rw-r--r-- | libopie/pim/opimrecord.h | 33 | ||||
-rw-r--r-- | libopie/pim/opimxref.cpp | 47 | ||||
-rw-r--r-- | libopie/pim/opimxref.h | 7 | ||||
-rw-r--r-- | libopie/pim/opimxrefmanager.cpp | 69 | ||||
-rw-r--r-- | libopie/pim/opimxrefmanager.h | 5 | ||||
-rw-r--r-- | libopie/pim/opimxrefpartner.cpp | 43 | ||||
-rw-r--r-- | libopie/pim/otodoaccessxml.cpp | 18 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccessxml.cpp | 18 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimrecord.cpp | 63 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimrecord.h | 33 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimxref.cpp | 47 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimxref.h | 7 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimxrefmanager.cpp | 69 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimxrefmanager.h | 5 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimxrefpartner.cpp | 43 |
17 files changed, 374 insertions, 202 deletions
diff --git a/libopie/libopie.pro b/libopie/libopie.pro index 79d15bb..3e6156e 100644 --- a/libopie/libopie.pro +++ b/libopie/libopie.pro @@ -1,83 +1,89 @@ TEMPLATE = lib CONFIG += qte warn_on release HEADERS = ofontmenu.h \ ocolorbutton.h \ ofiledialog.h ofileselector.h tododb.h \ ocheckitem.h todoevent.h todoresource.h \ todovcalresource.h xmltree.h \ colordialog.h colorpopupmenu.h \ oclickablelabel.h oprocctrl.h \ oprocess.h odevice.h \ otimepicker.h otabwidget.h \ otabbar.h otabinfo.h \ ofontselector.h \ pim/opimrecord.h \ pim/otodo.h \ pim/orecordlist.h \ pim/opimaccesstemplate.h \ pim/opimaccessbackend.h \ pim/otodoaccess.h \ pim/otodoaccessbackend.h \ pim/ocontact.h \ pim/ocontactaccess.h \ pim/ocontactaccessbackend.h \ pim/ocontactaccessbackend_xml.h \ pim/ocontactaccessbackend_vcard.h \ pim/obackendfactory.h \ pim/opimcache.h \ pim/otodoaccessvcal.h \ pim/orecur.h \ pim/opimstate.h \ + pim/opimxrefpartner.h \ + pim/opimxref.h \ + pim/opimxrefmanager.h \ orecurrancewidget.h \ oticker.h # pim/otodoaccesssql.h \ SOURCES = ofontmenu.cc \ ocolorbutton.cpp \ xmltree.cc \ ofiledialog.cc ofileselector.cc \ ocheckitem.cpp tododb.cpp todoevent.cpp \ todovcalresource.cpp colordialog.cpp \ colorpopupmenu.cpp oclickablelabel.cpp \ oprocctrl.cpp oprocess.cpp \ odevice.cpp otimepicker.cpp \ otabwidget.cpp otabbar.cpp \ ofontselector.cpp \ pim/otodo.cpp \ pim/opimrecord.cpp \ pim/otodoaccess.cpp \ pim/otodoaccessbackend.cpp \ pim/otodoaccessxml.cpp \ pim/ocontact.cpp \ pim/ocontactaccess.cpp \ pim/ocontactaccessbackend_vcard.cpp \ pim/otodoaccessvcal.cpp \ pim/orecur.cpp \ pim/opimstate.cpp \ + pim/opimxrefpartner.cpp \ + pim/opimxref.cpp \ + pim/opimxrefmanager.cpp \ orecurrancewidget.cpp \ oticker.cpp # pim/otodoaccesssql.cpp \ TARGET = opie INCLUDEPATH += $(OPIEDIR)/include DESTDIR = $(QTDIR)/lib$(PROJMAK) #VERSION = 1.0.0 # LIBS += -lopiesql INTERFACES = otimepickerbase.ui orecurrancebase.ui TRANSLATIONS = ../i18n/de/libopie.ts \ ../i18n/en/libopie.ts \ ../i18n/es/libopie.ts \ ../i18n/fr/libopie.ts \ ../i18n/hu/libopie.ts \ ../i18n/ja/libopie.ts \ ../i18n/ko/libopie.ts \ ../i18n/no/libopie.ts \ ../i18n/pl/libopie.ts \ ../i18n/pt/libopie.ts \ ../i18n/pt_BR/libopie.ts \ ../i18n/sl/libopie.ts \ ../i18n/zh_CN/libopie.ts \ ../i18n/zh_TW/libopie.ts diff --git a/libopie/pim/opimrecord.cpp b/libopie/pim/opimrecord.cpp index 21cf131..0e3be9d 100644 --- a/libopie/pim/opimrecord.cpp +++ b/libopie/pim/opimrecord.cpp @@ -1,132 +1,81 @@ #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() { setUid( uid ); } OPimRecord::~OPimRecord() { } OPimRecord::OPimRecord( const OPimRecord& rec ) : Qtopia::Record( rec ) { (*this) = rec; } OPimRecord &OPimRecord::operator=( const OPimRecord& rec) { Qtopia::Record::operator=( rec ); - m_relations = rec.m_relations; + m_xrefman = rec.m_xrefman; return *this; } /* * category names */ QStringList OPimRecord::categoryNames()const { QStringList list; QArray<int> cats = categories(); Categories catDB; catDB.load( categoryFileName() ); for (uint i = 0; i < cats.count(); i++ ) { list << catDB.label("Todo List", 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 ); } -QStringList OPimRecord::relatedApps()const{ - QStringList list; - QMap<QString, QArray<int> >::ConstIterator it; - for ( it = m_relations.begin(); it != m_relations.end(); ++it ) { - list << it.key(); - } - return list; -} -QArray<int> OPimRecord::relations(const QString& app )const { - QArray<int> tmp; - QMap<QString, QArray<int> >::ConstIterator it; - it = m_relations.find( app); - if ( it != m_relations.end() ) - tmp = it.data(); - return tmp; -} -void OPimRecord::clearRelation( const QString& app ) { - m_relations.remove( app ); -} -void OPimRecord::addRelation( const QString& app, int id ) { - - QMap<QString, QArray<int> >::Iterator it; - QArray<int> tmp; - - it = m_relations.find( app ); - if ( it == m_relations.end() ) { - tmp.resize(1 ); - tmp[0] = id; - }else{ - tmp = it.data(); - tmp.resize( tmp.size() + 1 ); - tmp[tmp.size() - 1] = id; - } - m_relations.replace( app, tmp ); -} -void OPimRecord::setRelations( const QString& app, QArray<int> ids ) { - - QMap<QString, QArray<int> >::Iterator it; - QArray<int> tmp; - - it = m_relations.find( app); - if ( it == m_relations.end() ) { - tmp = ids; - }else{ - tmp = it.data(); - int offset = tmp.size()-1; - tmp.resize( tmp.size() + ids.size() ); - for (uint i = 0; i < ids.size(); i++ ) { - tmp[offset+i] = ids[i]; - } - - } - m_relations.replace( app, tmp ); -} -QString OPimRecord::crossToString()const { +/*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; +} diff --git a/libopie/pim/opimrecord.h b/libopie/pim/opimrecord.h index d9ccad4..1642a5e 100644 --- a/libopie/pim/opimrecord.h +++ b/libopie/pim/opimrecord.h @@ -1,133 +1,116 @@ #ifndef OPIE_PIM_RECORD_H #define OPIE_PIM_RECORD_H #include <qmap.h> #include <qstring.h> #include <qstringlist.h> #include <qpe/palmtoprecord.h> +#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; /** * 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; /** * converts the internal structure to a map */ virtual QMap<int, QString> toMap()const = 0; /** * key value representation of extra items */ virtual QMap<QString, QString> toExtraMap()const = 0; /** * the name for a recordField */ virtual QString recordField(int)const = 0; /** - * the related apps names + * returns a reference of the + * Cross Reference Manager + * Partner One is THIS PIM RECORD! + * Two is the Partner where we link to */ - QStringList relatedApps()const; - - /** - * the realtions between an app - */ - QArray<int> relations( const QString& app )const; - - /** - * clear the relations for all relations - * with app - */ - void clearRelation( const QString& app ); - - /** - * add a relation - */ - void addRelation( const QString& app, int id ); - - /** - * set the relations for an app - */ - void setRelations( const QString&, QArray<int> ids ); + OPimXRefManager& xrefmanager(); /** * set the uid */ virtual void setUid( int uid ); protected: Qtopia::UidGen &uidGen(); - QString crossToString()const; +// QString crossToString()const; private: class OPimRecordPrivate; OPimRecordPrivate *d; - QMap<QString, QArray<int> > m_relations; + OPimXRefManager m_xrefman; static Qtopia::UidGen m_uidGen; }; #endif diff --git a/libopie/pim/opimxref.cpp b/libopie/pim/opimxref.cpp new file mode 100644 index 0000000..5cae871 --- a/dev/null +++ b/libopie/pim/opimxref.cpp @@ -0,0 +1,47 @@ +#include "opimxref.h" + +OPimXRef::OPimXRef( const OPimXRefPartner& one, const OPimXRefPartner& two ) + : m_partners(2) +{ + m_partners[0] = one; + m_partners[1] = two; +} +OPimXRef::OPimXRef() + : m_partners(2) +{ + +} +OPimXRef::OPimXRef( const OPimXRef& ref) { + *this = ref; +} +OPimXRef::~OPimXRef() { +} +OPimXRef &OPimXRef::operator=( const OPimXRef& ref) { + m_partners = ref.m_partners; + m_partners.detach(); + + return* this; +} +bool OPimXRef::operator==( const OPimXRef& oper ) { + if ( m_partners == oper.m_partners ) return true; + + return false; +} +OPimXRefPartner OPimXRef::partner( enum Partners par) const{ + return m_partners[par]; +} +void OPimXRef::setPartner( enum Partners par, const OPimXRefPartner& part) { + m_partners[par] = part; +} +bool OPimXRef::containsString( const QString& string ) const{ + if ( m_partners[One].appName() == string || + m_partners[Two].appName() == string ) return true; + + return false; +} +bool OPimXRef::containsUid( int uid ) const{ + if ( m_partners[One].uid() == uid || + m_partners[Two].uid() == uid ) return true; + + return false; +} diff --git a/libopie/pim/opimxref.h b/libopie/pim/opimxref.h index 72154ac..354739a 100644 --- a/libopie/pim/opimxref.h +++ b/libopie/pim/opimxref.h @@ -1,36 +1,39 @@ #ifndef OPIM_XREF_H #define OPIM_XREF_H #include <qarray.h> #include <qvaluelist.h> #include <opie/opimxrefpartner.h> /** * this is a Cross Referecne between * two Cross Reference Partners */ class OPimXRef { public: typedef QValueList<OPimXRef> ValueList; enum Partners { One, Two }; OPimXRef( const OPimXRefPartner& ONE, const OPimXRefPartner& ); OPimXRef(); OPimXRef( const OPimXRef& ); ~OPimXRef(); OPimXRef &operator=( const OPimXRef& ); - bool operator==( const OPimXRef ); + bool operator==( const OPimXRef& ); - OPimXRefPartner partner( enum Partners ); + OPimXRefPartner partner( enum Partners )const; void setPartner( enum Partners, const OPimXRefPartner& ); + bool containsString( const QString& appName)const; + bool containsUid( int uid )const; + private: QArray<OPimXRefPartner> m_partners; class Private; Private *d; }; #endif diff --git a/libopie/pim/opimxrefmanager.cpp b/libopie/pim/opimxrefmanager.cpp new file mode 100644 index 0000000..d49f5f5 --- a/dev/null +++ b/libopie/pim/opimxrefmanager.cpp @@ -0,0 +1,69 @@ +#include "opimxrefmanager.h" + + +OPimXRefManager::OPimXRefManager() { +} +OPimXRefManager::OPimXRefManager( const OPimXRefManager& ref) { + m_list = ref.m_list; +} +OPimXRefManager &OPimXRefManager::operator=( const OPimXRefManager& ref) { + m_list = ref.m_list; + return *this; +} +bool OPimXRefManager::operator==( const OPimXRefManager& /*ref*/) { + // if ( m_list == ref.m_list ) return true; + + return false; +} +void OPimXRefManager::add( const OPimXRef& ref) { + m_list.append( ref ); +} +void OPimXRefManager::remove( const OPimXRef& ref) { + m_list.remove( ref ); +} +void OPimXRefManager::replace( const OPimXRef& ref) { + m_list.remove( ref ); + m_list.append( ref ); +} +void OPimXRefManager::clear() { + m_list.clear(); +} +QStringList OPimXRefManager::apps()const { + OPimXRef::ValueList::ConstIterator it; + QStringList list; + + QString str; + for ( it = m_list.begin(); it != m_list.end(); ++it ) { + str = (*it).partner( OPimXRef::One ).appName(); + if ( !list.contains( str ) ) list << str; + + str = (*it).partner( OPimXRef::Two ).appName(); + if ( !list.contains( str ) ) list << str; + } + return list; +} +OPimXRef::ValueList OPimXRefManager::list()const { + return m_list; +} +OPimXRef::ValueList OPimXRefManager::list( const QString& appName )const{ + OPimXRef::ValueList list; + OPimXRef::ValueList::ConstIterator it; + + for ( it = m_list.begin(); it != m_list.end(); ++it ) { + if ( (*it).containsString( appName ) ) + list.append( (*it) ); + } + + return list; +} +OPimXRef::ValueList OPimXRefManager::list( int uid )const { + OPimXRef::ValueList list; + OPimXRef::ValueList::ConstIterator it; + + for ( it = m_list.begin(); it != m_list.end(); ++it ) { + if ( (*it).containsUid( uid ) ) + list.append( (*it) ); + } + + return list; +} diff --git a/libopie/pim/opimxrefmanager.h b/libopie/pim/opimxrefmanager.h index 147895d..9b003a3 100644 --- a/libopie/pim/opimxrefmanager.h +++ b/libopie/pim/opimxrefmanager.h @@ -1,36 +1,41 @@ #ifndef OPIM_XREF_MANAGER_H #define OPIM_XREF_MANAGER_H +#include <qstringlist.h> + #include <opie/opimxref.h> /** * This is a simple manager for * OPimXRefs. * It allows addition, removing, replacing * clearing and 'querying' the XRef... */ class OPimXRefManager { public: OPimXRefManager(); OPimXRefManager( const OPimXRefManager& ); ~OPimXRefManager(); OPimXRefManager& operator=( const OPimXRefManager& ); bool operator==( const OPimXRefManager& ); void add( const OPimXRef& ); void remove( const OPimXRef& ); void replace( const OPimXRef& ); void clear(); /** * apps participating */ QStringList apps()const; OPimXRef::ValueList list()const; OPimXRef::ValueList list( const QString& appName )const; OPimXRef::ValueList list( int uid )const; + +private: + OPimXRef::ValueList m_list; }; #endif diff --git a/libopie/pim/opimxrefpartner.cpp b/libopie/pim/opimxrefpartner.cpp new file mode 100644 index 0000000..028f4e6 --- a/dev/null +++ b/libopie/pim/opimxrefpartner.cpp @@ -0,0 +1,43 @@ +#include "opimxrefpartner.h" + +OPimXRefPartner::OPimXRefPartner( const QString& appName, + int uid, int field ) + : m_app(appName), m_uid(uid), m_field( field ) { +} +OPimXRefPartner::OPimXRefPartner( const OPimXRefPartner& ref ) { + *this = ref; +} +OPimXRefPartner::~OPimXRefPartner() { +} +OPimXRefPartner &OPimXRefPartner::operator=( const OPimXRefPartner& par ) { + m_app = par.m_app; + m_uid = par.m_uid; + m_field = par.m_field; + + return *this; +} +bool OPimXRefPartner::operator==( const OPimXRefPartner& par ) { + if ( m_app != par.m_app ) return false; + if ( m_uid != par.m_uid ) return false; + if ( m_field != par.m_field ) return false; + + return true; +} +QString OPimXRefPartner::appName()const { + return m_app; +} +int OPimXRefPartner::uid()const { + return m_uid; +} +int OPimXRefPartner::field()const { + return m_field; +} +void OPimXRefPartner::setAppName( const QString& appName ) { + m_app = appName; +} +void OPimXRefPartner::setUid( int uid ) { + m_uid = uid; +} +void OPimXRefPartner::setField( int field ) { + m_field = field; +} diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp index 591e467..c1682c6 100644 --- a/libopie/pim/otodoaccessxml.cpp +++ b/libopie/pim/otodoaccessxml.cpp @@ -1,634 +1,618 @@ #include <qfile.h> #include <qvector.h> #include <qpe/global.h> #include <qpe/stringutil.h> #include <qpe/timeconversion.h> #include <opie/xmltree.h> #include "otodoaccessxml.h" OTodoAccessXML::OTodoAccessXML( const QString& appName, const QString& fileName ) : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) { if (!fileName.isEmpty() ) m_file = fileName; else m_file = Global::applicationFileName( "todolist", "todolist.xml" ); } OTodoAccessXML::~OTodoAccessXML() { } bool OTodoAccessXML::load() { m_opened = true; m_changed = false; /* initialize dict */ /* * UPDATE dict if you change anything!!! */ QAsciiDict<int> dict(15); dict.setAutoDelete( TRUE ); dict.insert("Categories" , new int(OTodo::Category) ); dict.insert("Uid" , new int(OTodo::Uid) ); dict.insert("HasDate" , new int(OTodo::HasDate) ); dict.insert("Completed" , new int(OTodo::Completed) ); dict.insert("Description" , new int(OTodo::Description) ); dict.insert("Summary" , new int(OTodo::Summary) ); dict.insert("Priority" , new int(OTodo::Priority) ); dict.insert("DateDay" , new int(OTodo::DateDay) ); dict.insert("DateMonth" , new int(OTodo::DateMonth) ); dict.insert("DateYear" , new int(OTodo::DateYear) ); dict.insert("Progress" , new int(OTodo::Progress) ); dict.insert("Completed", new int(OTodo::Completed) ); dict.insert("CrossReference", new int(OTodo::CrossReference) ); dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // here the custom XML parser from TT it's GPL // but we want to push that to TT..... QFile f(m_file ); if (!f.open(IO_ReadOnly) ) return false; QByteArray ba = f.readAll(); f.close(); char* dt = ba.data(); int len = ba.size(); int i = 0; char *point; const char* collectionString = "<Task "; while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) { i = point -dt; i+= strlen(collectionString); OTodo ev; m_year = m_month = m_day = 0; while ( TRUE ) { while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) ++i; if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) break; // we have another attribute, read it. int j = i; while ( j < len && dt[j] != '=' ) ++j; QCString attr( dt+i, j-i+1); i = ++j; // skip = // find the start of quotes while ( i < len && dt[i] != '"' ) ++i; j = ++i; bool haveUtf = FALSE; bool haveEnt = FALSE; while ( j < len && dt[j] != '"' ) { if ( ((unsigned char)dt[j]) > 0x7f ) haveUtf = TRUE; if ( dt[j] == '&' ) haveEnt = TRUE; ++j; } if ( i == j ) { // empty value i = j + 1; continue; } QCString value( dt+i, j-i+1 ); i = j + 1; QString str = (haveUtf ? QString::fromUtf8( value ) : QString::fromLatin1( value ) ); if ( haveEnt ) str = Qtopia::plainString( str ); /* * add key + value */ todo( &dict, ev, attr, str ); } /* * now add it */ if (m_events.contains( ev.uid() ) || ev.uid() == 0) { ev.setUid( 1 ); m_changed = true; } if ( ev.hasDueDate() ) { ev.setDueDate( QDate(m_year, m_month, m_day) ); } m_events.insert(ev.uid(), ev ); m_year = m_month = m_day = -1; } qWarning("counts %d records loaded!", m_events.count() ); return true; } bool OTodoAccessXML::reload() { return load(); } bool OTodoAccessXML::save() { // qWarning("saving"); if (!m_opened || !m_changed ) { // qWarning("not saving"); return true; } QString strNewFile = m_file + ".new"; QFile f( strNewFile ); if (!f.open( IO_WriteOnly|IO_Raw ) ) 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 ) { 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::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() ); + ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); } break; } case OTodo::HasAlarmDateTime: ev.setHasAlarmDateTime( val.toInt() ); break; case OTodo::AlarmDateTime: { /* this sounds better ;) zecke */ ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) ); break; } default: break; } } 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 - QStringList list = ev.relatedApps(); - QStringList::Iterator listIt; - QString refs; - str += "CrossReference=\""; - bool added = false; - for ( listIt = list.begin(); listIt != list.end(); ++listIt ) { - added = true; - QArray<int> ints = ev.relations( (*listIt) ); - for ( uint i = 0; i< ints.count(); i++ ) { - str += (*listIt) + "," + QString::number( i ) + ";"; - } - } - if ( added ) - str = str.remove( str.length()-1, 1 ); - - str += "\" "; str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" "; 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 ) { qWarning("sorted! %d cat", 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 */ if ( bCat && cat != 0) if (!(*it).categories().contains( cat ) ) { qWarning("category mis match"); continue; } /* isOverdue but we should not show overdue - why?*/ /* if ( (*it).isOverdue() && !bOnly ) { qWarning("item is overdue but !bOnly"); continue; } */ if ( !(*it).isOverdue() && bOnly ) { qWarning("item is not overdue but bOnly checked"); continue; } if ((*it).isCompleted() && comp ) { qWarning("completed continue!"); continue; } OTodoXMLContainer* con = new OTodoXMLContainer(); con->todo = (*it); vector.insert(item, con ); item++; } qWarning("XXX %d Items added", 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(); } qWarning("array count = %d %d", array.count(), vector.count() ); return array; }; diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp index 591e467..c1682c6 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.cpp +++ b/libopie2/opiepim/backend/otodoaccessxml.cpp @@ -1,634 +1,618 @@ #include <qfile.h> #include <qvector.h> #include <qpe/global.h> #include <qpe/stringutil.h> #include <qpe/timeconversion.h> #include <opie/xmltree.h> #include "otodoaccessxml.h" OTodoAccessXML::OTodoAccessXML( const QString& appName, const QString& fileName ) : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) { if (!fileName.isEmpty() ) m_file = fileName; else m_file = Global::applicationFileName( "todolist", "todolist.xml" ); } OTodoAccessXML::~OTodoAccessXML() { } bool OTodoAccessXML::load() { m_opened = true; m_changed = false; /* initialize dict */ /* * UPDATE dict if you change anything!!! */ QAsciiDict<int> dict(15); dict.setAutoDelete( TRUE ); dict.insert("Categories" , new int(OTodo::Category) ); dict.insert("Uid" , new int(OTodo::Uid) ); dict.insert("HasDate" , new int(OTodo::HasDate) ); dict.insert("Completed" , new int(OTodo::Completed) ); dict.insert("Description" , new int(OTodo::Description) ); dict.insert("Summary" , new int(OTodo::Summary) ); dict.insert("Priority" , new int(OTodo::Priority) ); dict.insert("DateDay" , new int(OTodo::DateDay) ); dict.insert("DateMonth" , new int(OTodo::DateMonth) ); dict.insert("DateYear" , new int(OTodo::DateYear) ); dict.insert("Progress" , new int(OTodo::Progress) ); dict.insert("Completed", new int(OTodo::Completed) ); dict.insert("CrossReference", new int(OTodo::CrossReference) ); dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // here the custom XML parser from TT it's GPL // but we want to push that to TT..... QFile f(m_file ); if (!f.open(IO_ReadOnly) ) return false; QByteArray ba = f.readAll(); f.close(); char* dt = ba.data(); int len = ba.size(); int i = 0; char *point; const char* collectionString = "<Task "; while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) { i = point -dt; i+= strlen(collectionString); OTodo ev; m_year = m_month = m_day = 0; while ( TRUE ) { while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) ++i; if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) break; // we have another attribute, read it. int j = i; while ( j < len && dt[j] != '=' ) ++j; QCString attr( dt+i, j-i+1); i = ++j; // skip = // find the start of quotes while ( i < len && dt[i] != '"' ) ++i; j = ++i; bool haveUtf = FALSE; bool haveEnt = FALSE; while ( j < len && dt[j] != '"' ) { if ( ((unsigned char)dt[j]) > 0x7f ) haveUtf = TRUE; if ( dt[j] == '&' ) haveEnt = TRUE; ++j; } if ( i == j ) { // empty value i = j + 1; continue; } QCString value( dt+i, j-i+1 ); i = j + 1; QString str = (haveUtf ? QString::fromUtf8( value ) : QString::fromLatin1( value ) ); if ( haveEnt ) str = Qtopia::plainString( str ); /* * add key + value */ todo( &dict, ev, attr, str ); } /* * now add it */ if (m_events.contains( ev.uid() ) || ev.uid() == 0) { ev.setUid( 1 ); m_changed = true; } if ( ev.hasDueDate() ) { ev.setDueDate( QDate(m_year, m_month, m_day) ); } m_events.insert(ev.uid(), ev ); m_year = m_month = m_day = -1; } qWarning("counts %d records loaded!", m_events.count() ); return true; } bool OTodoAccessXML::reload() { return load(); } bool OTodoAccessXML::save() { // qWarning("saving"); if (!m_opened || !m_changed ) { // qWarning("not saving"); return true; } QString strNewFile = m_file + ".new"; QFile f( strNewFile ); if (!f.open( IO_WriteOnly|IO_Raw ) ) 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 ) { 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::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() ); + ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); } break; } case OTodo::HasAlarmDateTime: ev.setHasAlarmDateTime( val.toInt() ); break; case OTodo::AlarmDateTime: { /* this sounds better ;) zecke */ ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) ); break; } default: break; } } 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 - QStringList list = ev.relatedApps(); - QStringList::Iterator listIt; - QString refs; - str += "CrossReference=\""; - bool added = false; - for ( listIt = list.begin(); listIt != list.end(); ++listIt ) { - added = true; - QArray<int> ints = ev.relations( (*listIt) ); - for ( uint i = 0; i< ints.count(); i++ ) { - str += (*listIt) + "," + QString::number( i ) + ";"; - } - } - if ( added ) - str = str.remove( str.length()-1, 1 ); - - str += "\" "; str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" "; 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 ) { qWarning("sorted! %d cat", 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 */ if ( bCat && cat != 0) if (!(*it).categories().contains( cat ) ) { qWarning("category mis match"); continue; } /* isOverdue but we should not show overdue - why?*/ /* if ( (*it).isOverdue() && !bOnly ) { qWarning("item is overdue but !bOnly"); continue; } */ if ( !(*it).isOverdue() && bOnly ) { qWarning("item is not overdue but bOnly checked"); continue; } if ((*it).isCompleted() && comp ) { qWarning("completed continue!"); continue; } OTodoXMLContainer* con = new OTodoXMLContainer(); con->todo = (*it); vector.insert(item, con ); item++; } qWarning("XXX %d Items added", 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(); } qWarning("array count = %d %d", array.count(), vector.count() ); return array; }; diff --git a/libopie2/opiepim/core/opimrecord.cpp b/libopie2/opiepim/core/opimrecord.cpp index 21cf131..0e3be9d 100644 --- a/libopie2/opiepim/core/opimrecord.cpp +++ b/libopie2/opiepim/core/opimrecord.cpp @@ -1,132 +1,81 @@ #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() { setUid( uid ); } OPimRecord::~OPimRecord() { } OPimRecord::OPimRecord( const OPimRecord& rec ) : Qtopia::Record( rec ) { (*this) = rec; } OPimRecord &OPimRecord::operator=( const OPimRecord& rec) { Qtopia::Record::operator=( rec ); - m_relations = rec.m_relations; + m_xrefman = rec.m_xrefman; return *this; } /* * category names */ QStringList OPimRecord::categoryNames()const { QStringList list; QArray<int> cats = categories(); Categories catDB; catDB.load( categoryFileName() ); for (uint i = 0; i < cats.count(); i++ ) { list << catDB.label("Todo List", 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 ); } -QStringList OPimRecord::relatedApps()const{ - QStringList list; - QMap<QString, QArray<int> >::ConstIterator it; - for ( it = m_relations.begin(); it != m_relations.end(); ++it ) { - list << it.key(); - } - return list; -} -QArray<int> OPimRecord::relations(const QString& app )const { - QArray<int> tmp; - QMap<QString, QArray<int> >::ConstIterator it; - it = m_relations.find( app); - if ( it != m_relations.end() ) - tmp = it.data(); - return tmp; -} -void OPimRecord::clearRelation( const QString& app ) { - m_relations.remove( app ); -} -void OPimRecord::addRelation( const QString& app, int id ) { - - QMap<QString, QArray<int> >::Iterator it; - QArray<int> tmp; - - it = m_relations.find( app ); - if ( it == m_relations.end() ) { - tmp.resize(1 ); - tmp[0] = id; - }else{ - tmp = it.data(); - tmp.resize( tmp.size() + 1 ); - tmp[tmp.size() - 1] = id; - } - m_relations.replace( app, tmp ); -} -void OPimRecord::setRelations( const QString& app, QArray<int> ids ) { - - QMap<QString, QArray<int> >::Iterator it; - QArray<int> tmp; - - it = m_relations.find( app); - if ( it == m_relations.end() ) { - tmp = ids; - }else{ - tmp = it.data(); - int offset = tmp.size()-1; - tmp.resize( tmp.size() + ids.size() ); - for (uint i = 0; i < ids.size(); i++ ) { - tmp[offset+i] = ids[i]; - } - - } - m_relations.replace( app, tmp ); -} -QString OPimRecord::crossToString()const { +/*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; +} diff --git a/libopie2/opiepim/core/opimrecord.h b/libopie2/opiepim/core/opimrecord.h index d9ccad4..1642a5e 100644 --- a/libopie2/opiepim/core/opimrecord.h +++ b/libopie2/opiepim/core/opimrecord.h @@ -1,133 +1,116 @@ #ifndef OPIE_PIM_RECORD_H #define OPIE_PIM_RECORD_H #include <qmap.h> #include <qstring.h> #include <qstringlist.h> #include <qpe/palmtoprecord.h> +#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; /** * 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; /** * converts the internal structure to a map */ virtual QMap<int, QString> toMap()const = 0; /** * key value representation of extra items */ virtual QMap<QString, QString> toExtraMap()const = 0; /** * the name for a recordField */ virtual QString recordField(int)const = 0; /** - * the related apps names + * returns a reference of the + * Cross Reference Manager + * Partner One is THIS PIM RECORD! + * Two is the Partner where we link to */ - QStringList relatedApps()const; - - /** - * the realtions between an app - */ - QArray<int> relations( const QString& app )const; - - /** - * clear the relations for all relations - * with app - */ - void clearRelation( const QString& app ); - - /** - * add a relation - */ - void addRelation( const QString& app, int id ); - - /** - * set the relations for an app - */ - void setRelations( const QString&, QArray<int> ids ); + OPimXRefManager& xrefmanager(); /** * set the uid */ virtual void setUid( int uid ); protected: Qtopia::UidGen &uidGen(); - QString crossToString()const; +// QString crossToString()const; private: class OPimRecordPrivate; OPimRecordPrivate *d; - QMap<QString, QArray<int> > m_relations; + OPimXRefManager m_xrefman; static Qtopia::UidGen m_uidGen; }; #endif diff --git a/libopie2/opiepim/core/opimxref.cpp b/libopie2/opiepim/core/opimxref.cpp new file mode 100644 index 0000000..5cae871 --- a/dev/null +++ b/libopie2/opiepim/core/opimxref.cpp @@ -0,0 +1,47 @@ +#include "opimxref.h" + +OPimXRef::OPimXRef( const OPimXRefPartner& one, const OPimXRefPartner& two ) + : m_partners(2) +{ + m_partners[0] = one; + m_partners[1] = two; +} +OPimXRef::OPimXRef() + : m_partners(2) +{ + +} +OPimXRef::OPimXRef( const OPimXRef& ref) { + *this = ref; +} +OPimXRef::~OPimXRef() { +} +OPimXRef &OPimXRef::operator=( const OPimXRef& ref) { + m_partners = ref.m_partners; + m_partners.detach(); + + return* this; +} +bool OPimXRef::operator==( const OPimXRef& oper ) { + if ( m_partners == oper.m_partners ) return true; + + return false; +} +OPimXRefPartner OPimXRef::partner( enum Partners par) const{ + return m_partners[par]; +} +void OPimXRef::setPartner( enum Partners par, const OPimXRefPartner& part) { + m_partners[par] = part; +} +bool OPimXRef::containsString( const QString& string ) const{ + if ( m_partners[One].appName() == string || + m_partners[Two].appName() == string ) return true; + + return false; +} +bool OPimXRef::containsUid( int uid ) const{ + if ( m_partners[One].uid() == uid || + m_partners[Two].uid() == uid ) return true; + + return false; +} diff --git a/libopie2/opiepim/core/opimxref.h b/libopie2/opiepim/core/opimxref.h index 72154ac..354739a 100644 --- a/libopie2/opiepim/core/opimxref.h +++ b/libopie2/opiepim/core/opimxref.h @@ -1,36 +1,39 @@ #ifndef OPIM_XREF_H #define OPIM_XREF_H #include <qarray.h> #include <qvaluelist.h> #include <opie/opimxrefpartner.h> /** * this is a Cross Referecne between * two Cross Reference Partners */ class OPimXRef { public: typedef QValueList<OPimXRef> ValueList; enum Partners { One, Two }; OPimXRef( const OPimXRefPartner& ONE, const OPimXRefPartner& ); OPimXRef(); OPimXRef( const OPimXRef& ); ~OPimXRef(); OPimXRef &operator=( const OPimXRef& ); - bool operator==( const OPimXRef ); + bool operator==( const OPimXRef& ); - OPimXRefPartner partner( enum Partners ); + OPimXRefPartner partner( enum Partners )const; void setPartner( enum Partners, const OPimXRefPartner& ); + bool containsString( const QString& appName)const; + bool containsUid( int uid )const; + private: QArray<OPimXRefPartner> m_partners; class Private; Private *d; }; #endif diff --git a/libopie2/opiepim/core/opimxrefmanager.cpp b/libopie2/opiepim/core/opimxrefmanager.cpp new file mode 100644 index 0000000..d49f5f5 --- a/dev/null +++ b/libopie2/opiepim/core/opimxrefmanager.cpp @@ -0,0 +1,69 @@ +#include "opimxrefmanager.h" + + +OPimXRefManager::OPimXRefManager() { +} +OPimXRefManager::OPimXRefManager( const OPimXRefManager& ref) { + m_list = ref.m_list; +} +OPimXRefManager &OPimXRefManager::operator=( const OPimXRefManager& ref) { + m_list = ref.m_list; + return *this; +} +bool OPimXRefManager::operator==( const OPimXRefManager& /*ref*/) { + // if ( m_list == ref.m_list ) return true; + + return false; +} +void OPimXRefManager::add( const OPimXRef& ref) { + m_list.append( ref ); +} +void OPimXRefManager::remove( const OPimXRef& ref) { + m_list.remove( ref ); +} +void OPimXRefManager::replace( const OPimXRef& ref) { + m_list.remove( ref ); + m_list.append( ref ); +} +void OPimXRefManager::clear() { + m_list.clear(); +} +QStringList OPimXRefManager::apps()const { + OPimXRef::ValueList::ConstIterator it; + QStringList list; + + QString str; + for ( it = m_list.begin(); it != m_list.end(); ++it ) { + str = (*it).partner( OPimXRef::One ).appName(); + if ( !list.contains( str ) ) list << str; + + str = (*it).partner( OPimXRef::Two ).appName(); + if ( !list.contains( str ) ) list << str; + } + return list; +} +OPimXRef::ValueList OPimXRefManager::list()const { + return m_list; +} +OPimXRef::ValueList OPimXRefManager::list( const QString& appName )const{ + OPimXRef::ValueList list; + OPimXRef::ValueList::ConstIterator it; + + for ( it = m_list.begin(); it != m_list.end(); ++it ) { + if ( (*it).containsString( appName ) ) + list.append( (*it) ); + } + + return list; +} +OPimXRef::ValueList OPimXRefManager::list( int uid )const { + OPimXRef::ValueList list; + OPimXRef::ValueList::ConstIterator it; + + for ( it = m_list.begin(); it != m_list.end(); ++it ) { + if ( (*it).containsUid( uid ) ) + list.append( (*it) ); + } + + return list; +} diff --git a/libopie2/opiepim/core/opimxrefmanager.h b/libopie2/opiepim/core/opimxrefmanager.h index 147895d..9b003a3 100644 --- a/libopie2/opiepim/core/opimxrefmanager.h +++ b/libopie2/opiepim/core/opimxrefmanager.h @@ -1,36 +1,41 @@ #ifndef OPIM_XREF_MANAGER_H #define OPIM_XREF_MANAGER_H +#include <qstringlist.h> + #include <opie/opimxref.h> /** * This is a simple manager for * OPimXRefs. * It allows addition, removing, replacing * clearing and 'querying' the XRef... */ class OPimXRefManager { public: OPimXRefManager(); OPimXRefManager( const OPimXRefManager& ); ~OPimXRefManager(); OPimXRefManager& operator=( const OPimXRefManager& ); bool operator==( const OPimXRefManager& ); void add( const OPimXRef& ); void remove( const OPimXRef& ); void replace( const OPimXRef& ); void clear(); /** * apps participating */ QStringList apps()const; OPimXRef::ValueList list()const; OPimXRef::ValueList list( const QString& appName )const; OPimXRef::ValueList list( int uid )const; + +private: + OPimXRef::ValueList m_list; }; #endif diff --git a/libopie2/opiepim/core/opimxrefpartner.cpp b/libopie2/opiepim/core/opimxrefpartner.cpp new file mode 100644 index 0000000..028f4e6 --- a/dev/null +++ b/libopie2/opiepim/core/opimxrefpartner.cpp @@ -0,0 +1,43 @@ +#include "opimxrefpartner.h" + +OPimXRefPartner::OPimXRefPartner( const QString& appName, + int uid, int field ) + : m_app(appName), m_uid(uid), m_field( field ) { +} +OPimXRefPartner::OPimXRefPartner( const OPimXRefPartner& ref ) { + *this = ref; +} +OPimXRefPartner::~OPimXRefPartner() { +} +OPimXRefPartner &OPimXRefPartner::operator=( const OPimXRefPartner& par ) { + m_app = par.m_app; + m_uid = par.m_uid; + m_field = par.m_field; + + return *this; +} +bool OPimXRefPartner::operator==( const OPimXRefPartner& par ) { + if ( m_app != par.m_app ) return false; + if ( m_uid != par.m_uid ) return false; + if ( m_field != par.m_field ) return false; + + return true; +} +QString OPimXRefPartner::appName()const { + return m_app; +} +int OPimXRefPartner::uid()const { + return m_uid; +} +int OPimXRefPartner::field()const { + return m_field; +} +void OPimXRefPartner::setAppName( const QString& appName ) { + m_app = appName; +} +void OPimXRefPartner::setUid( int uid ) { + m_uid = uid; +} +void OPimXRefPartner::setField( int field ) { + m_field = field; +} |