summaryrefslogtreecommitdiff
authorzecke <zecke>2003-05-07 15:26:59 (UTC)
committer zecke <zecke>2003-05-07 15:26:59 (UTC)
commite150dfd5151aa59eb373aa58df5d9644c6c65b52 (patch) (unidiff)
tree4cbc036ef9bfc51d9938d6ff6a433081c0b400b8
parent1a550df3248342a8c863951ba733b862ca222216 (diff)
downloadopie-e150dfd5151aa59eb373aa58df5d9644c6c65b52.zip
opie-e150dfd5151aa59eb373aa58df5d9644c6c65b52.tar.gz
opie-e150dfd5151aa59eb373aa58df5d9644c6c65b52.tar.bz2
Make it possible to see what a backend supports
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/otodoaccess.cpp6
-rw-r--r--libopie/pim/otodoaccess.h15
-rw-r--r--libopie/pim/otodoaccessbackend.h3
-rw-r--r--libopie/pim/otodoaccessvcal.cpp20
-rw-r--r--libopie/pim/otodoaccessvcal.h2
-rw-r--r--libopie/pim/otodoaccessxml.cpp16
-rw-r--r--libopie/pim/otodoaccessxml.h2
-rw-r--r--libopie2/opiepim/backend/otodoaccessbackend.h3
-rw-r--r--libopie2/opiepim/backend/otodoaccessvcal.cpp20
-rw-r--r--libopie2/opiepim/backend/otodoaccessvcal.h2
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp16
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.h2
-rw-r--r--libopie2/opiepim/core/otodoaccess.cpp6
-rw-r--r--libopie2/opiepim/core/otodoaccess.h15
14 files changed, 126 insertions, 2 deletions
diff --git a/libopie/pim/otodoaccess.cpp b/libopie/pim/otodoaccess.cpp
index 5e89a1b..37f6fbc 100644
--- a/libopie/pim/otodoaccess.cpp
+++ b/libopie/pim/otodoaccess.cpp
@@ -1,56 +1,62 @@
1#include <qdatetime.h> 1#include <qdatetime.h>
2 2
3#include <qpe/alarmserver.h> 3#include <qpe/alarmserver.h>
4 4
5// #include "otodoaccesssql.h" 5// #include "otodoaccesssql.h"
6#include "otodoaccess.h" 6#include "otodoaccess.h"
7#include "obackendfactory.h" 7#include "obackendfactory.h"
8 8
9OTodoAccess::OTodoAccess( OTodoAccessBackend* end, enum Access ) 9OTodoAccess::OTodoAccess( OTodoAccessBackend* end, enum Access )
10 : QObject(), OPimAccessTemplate<OTodo>( end ), m_todoBackEnd( end ) 10 : QObject(), OPimAccessTemplate<OTodo>( end ), m_todoBackEnd( end )
11{ 11{
12// if (end == 0l ) 12// if (end == 0l )
13// m_todoBackEnd = new OTodoAccessBackendSQL( QString::null); 13// m_todoBackEnd = new OTodoAccessBackendSQL( QString::null);
14 14
15 // Zecke: Du musst hier noch für das XML-Backend einen Appnamen übergeben ! 15 // Zecke: Du musst hier noch für das XML-Backend einen Appnamen übergeben !
16 if (end == 0l ) 16 if (end == 0l )
17 m_todoBackEnd = OBackendFactory<OTodoAccessBackend>::Default ("todo", QString::null); 17 m_todoBackEnd = OBackendFactory<OTodoAccessBackend>::Default ("todo", QString::null);
18 18
19 setBackEnd( m_todoBackEnd ); 19 setBackEnd( m_todoBackEnd );
20} 20}
21OTodoAccess::~OTodoAccess() { 21OTodoAccess::~OTodoAccess() {
22// qWarning("~OTodoAccess"); 22// qWarning("~OTodoAccess");
23} 23}
24void OTodoAccess::mergeWith( const QValueList<OTodo>& list ) { 24void OTodoAccess::mergeWith( const QValueList<OTodo>& list ) {
25 QValueList<OTodo>::ConstIterator it; 25 QValueList<OTodo>::ConstIterator it;
26 for ( it = list.begin(); it != list.end(); ++it ) { 26 for ( it = list.begin(); it != list.end(); ++it ) {
27 replace( (*it) ); 27 replace( (*it) );
28 } 28 }
29} 29}
30OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start, 30OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start,
31 const QDate& end, 31 const QDate& end,
32 bool includeNoDates ) { 32 bool includeNoDates ) {
33 QArray<int> ints = m_todoBackEnd->effectiveToDos( start, end, includeNoDates ); 33 QArray<int> ints = m_todoBackEnd->effectiveToDos( start, end, includeNoDates );
34 34
35 List lis( ints, this ); 35 List lis( ints, this );
36 return lis; 36 return lis;
37} 37}
38OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start, 38OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start,
39 bool includeNoDates ) { 39 bool includeNoDates ) {
40 return effectiveToDos( start, QDate::currentDate(), 40 return effectiveToDos( start, QDate::currentDate(),
41 includeNoDates ); 41 includeNoDates );
42} 42}
43OTodoAccess::List OTodoAccess::overDue() { 43OTodoAccess::List OTodoAccess::overDue() {
44 List lis( m_todoBackEnd->overDue(), this ); 44 List lis( m_todoBackEnd->overDue(), this );
45 return lis; 45 return lis;
46} 46}
47/* sort order */ 47/* sort order */
48OTodoAccess::List OTodoAccess::sorted( bool ascending, int sort,int filter, int cat ) { 48OTodoAccess::List OTodoAccess::sorted( bool ascending, int sort,int filter, int cat ) {
49 QArray<int> ints = m_todoBackEnd->sorted( ascending, sort, 49 QArray<int> ints = m_todoBackEnd->sorted( ascending, sort,
50 filter, cat ); 50 filter, cat );
51 OTodoAccess::List list( ints, this ); 51 OTodoAccess::List list( ints, this );
52 return list; 52 return list;
53} 53}
54void OTodoAccess::removeAllCompleted() { 54void OTodoAccess::removeAllCompleted() {
55 m_todoBackEnd->removeAllCompleted(); 55 m_todoBackEnd->removeAllCompleted();
56} 56}
57QBitArray OTodoAccess::backendSupport( const QString& ) const{
58 return m_todoBackEnd->supports();
59}
60bool OTodoAccess::backendSupports( int attr, const QString& ar) const{
61 return backendSupport(ar).testBit( attr );
62}
diff --git a/libopie/pim/otodoaccess.h b/libopie/pim/otodoaccess.h
index a626731..916923f 100644
--- a/libopie/pim/otodoaccess.h
+++ b/libopie/pim/otodoaccess.h
@@ -1,90 +1,105 @@
1#ifndef OPIE_TODO_ACCESS_H 1#ifndef OPIE_TODO_ACCESS_H
2#define OPIE_TODO_ACCESS_H 2#define OPIE_TODO_ACCESS_H
3 3
4#include <qobject.h> 4#include <qobject.h>
5#include <qvaluelist.h> 5#include <qvaluelist.h>
6 6
7#include "otodo.h" 7#include "otodo.h"
8#include "otodoaccessbackend.h" 8#include "otodoaccessbackend.h"
9#include "opimaccesstemplate.h" 9#include "opimaccesstemplate.h"
10 10
11 11
12/** 12/**
13 * OTodoAccess 13 * OTodoAccess
14 * the class to get access to 14 * the class to get access to
15 * the todolist 15 * the todolist
16 */ 16 */
17class OTodoAccess : public QObject, public OPimAccessTemplate<OTodo> { 17class OTodoAccess : public QObject, public OPimAccessTemplate<OTodo> {
18 Q_OBJECT 18 Q_OBJECT
19public: 19public:
20 enum SortOrder { Completed = 0, 20 enum SortOrder { Completed = 0,
21 Priority, 21 Priority,
22 Description, 22 Description,
23 Deadline }; 23 Deadline };
24 enum SortFilter{ Category =1, 24 enum SortFilter{ Category =1,
25 OnlyOverDue= 2, 25 OnlyOverDue= 2,
26 DoNotShowCompleted =4 }; 26 DoNotShowCompleted =4 };
27 /** 27 /**
28 * if you use 0l 28 * if you use 0l
29 * the default resource will be 29 * the default resource will be
30 * picked up 30 * picked up
31 */ 31 */
32 OTodoAccess( OTodoAccessBackend* = 0l, enum Access acc = Random ); 32 OTodoAccess( OTodoAccessBackend* = 0l, enum Access acc = Random );
33 ~OTodoAccess(); 33 ~OTodoAccess();
34 34
35 35
36 /* our functions here */ 36 /* our functions here */
37 /** 37 /**
38 * include todos from start to end 38 * include todos from start to end
39 * includeNoDates whether or not to include 39 * includeNoDates whether or not to include
40 * events with no dates 40 * events with no dates
41 */ 41 */
42 List effectiveToDos( const QDate& start, 42 List effectiveToDos( const QDate& start,
43 const QDate& end, 43 const QDate& end,
44 bool includeNoDates = true ); 44 bool includeNoDates = true );
45 45
46 /** 46 /**
47 * start 47 * start
48 * end date taken from the currentDate() 48 * end date taken from the currentDate()
49 */ 49 */
50 List effectiveToDos( const QDate& start, 50 List effectiveToDos( const QDate& start,
51 bool includeNoDates = true ); 51 bool includeNoDates = true );
52 52
53 53
54 /** 54 /**
55 * return overdue OTodos 55 * return overdue OTodos
56 */ 56 */
57 List overDue(); 57 List overDue();
58 58
59 /** 59 /**
60 * 60 *
61 */ 61 */
62 List sorted( bool ascending, int sortOrder, int sortFilter, int cat ); 62 List sorted( bool ascending, int sortOrder, int sortFilter, int cat );
63 63
64 /** 64 /**
65 * merge a list of OTodos into 65 * merge a list of OTodos into
66 * the resource 66 * the resource
67 */ 67 */
68 void mergeWith( const QValueList<OTodo>& ); 68 void mergeWith( const QValueList<OTodo>& );
69 69
70 /** 70 /**
71 * delete all already completed items 71 * delete all already completed items
72 */ 72 */
73 void removeAllCompleted(); 73 void removeAllCompleted();
74 74
75 /**
76 * request information about what a backend supports.
77 * Supports in the sense of beeing able to store.
78 * This is related to the enum in OTodo
79 *
80 * @param backend Will be used in the future when we support multiple backend
81 */
82 QBitArray backendSupport( const QString& backend = QString::null )const;
83
84 /**
85 * see above but for a specefic attribute. This method was added for convience
86 * @param attr The attribute to be queried for
87 * @param backend Will be used in the future when we support multiple backends
88 */
89 bool backendSupports( int attr, const QString& backend = QString::null )const;
75signals: 90signals:
76 /** 91 /**
77 * if the OTodoAccess was changed 92 * if the OTodoAccess was changed
78 */ 93 */
79 void changed( const OTodoAccess* ); 94 void changed( const OTodoAccess* );
80 void changed( const OTodoAccess*, int uid ); 95 void changed( const OTodoAccess*, int uid );
81 void added( const OTodoAccess*, int uid ); 96 void added( const OTodoAccess*, int uid );
82 void removed( const OTodoAccess*, int uid ); 97 void removed( const OTodoAccess*, int uid );
83private: 98private:
84 int m_cat; 99 int m_cat;
85 OTodoAccessBackend* m_todoBackEnd; 100 OTodoAccessBackend* m_todoBackEnd;
86 class OTodoAccessPrivate; 101 class OTodoAccessPrivate;
87 OTodoAccessPrivate* d; 102 OTodoAccessPrivate* d;
88}; 103};
89 104
90#endif 105#endif
diff --git a/libopie/pim/otodoaccessbackend.h b/libopie/pim/otodoaccessbackend.h
index 7944a2c..05e8ca9 100644
--- a/libopie/pim/otodoaccessbackend.h
+++ b/libopie/pim/otodoaccessbackend.h
@@ -1,21 +1,24 @@
1#ifndef OPIE_TODO_ACCESS_BACKEND_H 1#ifndef OPIE_TODO_ACCESS_BACKEND_H
2#define OPIE_TODO_ACCESS_BACKEND_H 2#define OPIE_TODO_ACCESS_BACKEND_H
3 3
4#include <qbitarray.h>
5
4#include "otodo.h" 6#include "otodo.h"
5#include "opimaccessbackend.h" 7#include "opimaccessbackend.h"
6 8
7class OTodoAccessBackend : public OPimAccessBackend<OTodo> { 9class OTodoAccessBackend : public OPimAccessBackend<OTodo> {
8public: 10public:
9 OTodoAccessBackend(); 11 OTodoAccessBackend();
10 ~OTodoAccessBackend(); 12 ~OTodoAccessBackend();
11 virtual QArray<int> effectiveToDos( const QDate& start, 13 virtual QArray<int> effectiveToDos( const QDate& start,
12 const QDate& end, 14 const QDate& end,
13 bool includeNoDates ) = 0; 15 bool includeNoDates ) = 0;
14 virtual QArray<int> overDue() = 0; 16 virtual QArray<int> overDue() = 0;
15 virtual QArray<int> sorted( bool asc, int sortOrder, int sortFilter, 17 virtual QArray<int> sorted( bool asc, int sortOrder, int sortFilter,
16 int cat ) = 0; 18 int cat ) = 0;
17 virtual void removeAllCompleted() = 0; 19 virtual void removeAllCompleted() = 0;
20 virtual QBitArray supports()const = 0;
18 21
19}; 22};
20 23
21#endif 24#endif
diff --git a/libopie/pim/otodoaccessvcal.cpp b/libopie/pim/otodoaccessvcal.cpp
index 2136283..9bc16c6 100644
--- a/libopie/pim/otodoaccessvcal.cpp
+++ b/libopie/pim/otodoaccessvcal.cpp
@@ -1,201 +1,221 @@
1#include <qfile.h> 1#include <qfile.h>
2 2
3#include <qtopia/private/vobject_p.h> 3#include <qtopia/private/vobject_p.h>
4#include <qtopia/timeconversion.h> 4#include <qtopia/timeconversion.h>
5#include <qtopia/private/qfiledirect_p.h> 5#include <qtopia/private/qfiledirect_p.h>
6 6
7#include "otodoaccessvcal.h" 7#include "otodoaccessvcal.h"
8 8
9namespace { 9namespace {
10 static OTodo eventByVObj( VObject *obj ){ 10 static OTodo eventByVObj( VObject *obj ){
11 OTodo event; 11 OTodo event;
12 VObject *ob; 12 VObject *ob;
13 QCString name; 13 QCString name;
14 // no uid, attendees, ... and no fun 14 // no uid, attendees, ... and no fun
15 // description 15 // description
16 if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){ 16 if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){
17 name = vObjectStringZValue( ob ); 17 name = vObjectStringZValue( ob );
18 event.setDescription( name ); 18 event.setDescription( name );
19 } 19 }
20 // summary 20 // summary
21 if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) { 21 if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) {
22 name = vObjectStringZValue( ob ); 22 name = vObjectStringZValue( ob );
23 event.setSummary( name ); 23 event.setSummary( name );
24 } 24 }
25 // completed 25 // completed
26 if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){ 26 if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){
27 name = vObjectStringZValue( ob ); 27 name = vObjectStringZValue( ob );
28 if( name == "COMPLETED" ){ 28 if( name == "COMPLETED" ){
29 event.setCompleted( true ); 29 event.setCompleted( true );
30 }else{ 30 }else{
31 event.setCompleted( false ); 31 event.setCompleted( false );
32 } 32 }
33 }else 33 }else
34 event.setCompleted( false ); 34 event.setCompleted( false );
35 // priority 35 // priority
36 if ((ob = isAPropertyOf(obj, VCPriorityProp))) { 36 if ((ob = isAPropertyOf(obj, VCPriorityProp))) {
37 name = vObjectStringZValue( ob ); 37 name = vObjectStringZValue( ob );
38 bool ok; 38 bool ok;
39 event.setPriority(name.toInt(&ok) ); 39 event.setPriority(name.toInt(&ok) );
40 } 40 }
41 //due date 41 //due date
42 if((ob = isAPropertyOf(obj, VCDueProp)) ){ 42 if((ob = isAPropertyOf(obj, VCDueProp)) ){
43 event.setHasDueDate( true ); 43 event.setHasDueDate( true );
44 name = vObjectStringZValue( ob ); 44 name = vObjectStringZValue( ob );
45 event.setDueDate( TimeConversion::fromISO8601( name).date() ); 45 event.setDueDate( TimeConversion::fromISO8601( name).date() );
46 } 46 }
47 // categories 47 // categories
48 if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){ 48 if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){
49 name = vObjectStringZValue( ob ); 49 name = vObjectStringZValue( ob );
50 qWarning("Categories:%s", name.data() ); 50 qWarning("Categories:%s", name.data() );
51 } 51 }
52 52
53 event.setUid( 1 ); 53 event.setUid( 1 );
54 return event; 54 return event;
55 }; 55 };
56 static VObject *vobjByEvent( const OTodo &event ) { 56 static VObject *vobjByEvent( const OTodo &event ) {
57 VObject *task = newVObject( VCTodoProp ); 57 VObject *task = newVObject( VCTodoProp );
58 if( task == 0 ) 58 if( task == 0 )
59 return 0l; 59 return 0l;
60 60
61 if( event.hasDueDate() ) { 61 if( event.hasDueDate() ) {
62 QTime time(0, 0, 0); 62 QTime time(0, 0, 0);
63 QDateTime date(event.dueDate(), time ); 63 QDateTime date(event.dueDate(), time );
64 addPropValue( task, VCDueProp, 64 addPropValue( task, VCDueProp,
65 TimeConversion::toISO8601( date ) ); 65 TimeConversion::toISO8601( date ) );
66 } 66 }
67 67
68 if( event.isCompleted() ) 68 if( event.isCompleted() )
69 addPropValue( task, VCStatusProp, "COMPLETED"); 69 addPropValue( task, VCStatusProp, "COMPLETED");
70 70
71 QString string = QString::number(event.priority() ); 71 QString string = QString::number(event.priority() );
72 addPropValue( task, VCPriorityProp, string.local8Bit() ); 72 addPropValue( task, VCPriorityProp, string.local8Bit() );
73 73
74 addPropValue( task, VCCategoriesProp, 74 addPropValue( task, VCCategoriesProp,
75 event.idsToString( event.categories() ).local8Bit() ); 75 event.idsToString( event.categories() ).local8Bit() );
76 76
77 addPropValue( task, VCDescriptionProp, 77 addPropValue( task, VCDescriptionProp,
78 event.description().local8Bit() ); 78 event.description().local8Bit() );
79 79
80 addPropValue( task, VCSummaryProp, 80 addPropValue( task, VCSummaryProp,
81 event.summary().local8Bit() ); 81 event.summary().local8Bit() );
82 return task; 82 return task;
83}; 83};
84} 84}
85 85
86OTodoAccessVCal::OTodoAccessVCal( const QString& path ) 86OTodoAccessVCal::OTodoAccessVCal( const QString& path )
87 : m_dirty(false), m_file( path ) 87 : m_dirty(false), m_file( path )
88{ 88{
89} 89}
90OTodoAccessVCal::~OTodoAccessVCal() { 90OTodoAccessVCal::~OTodoAccessVCal() {
91} 91}
92bool OTodoAccessVCal::load() { 92bool OTodoAccessVCal::load() {
93 m_map.clear(); 93 m_map.clear();
94 m_dirty = false; 94 m_dirty = false;
95 95
96 VObject* vcal = 0l; 96 VObject* vcal = 0l;
97 vcal = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); 97 vcal = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() );
98 if (!vcal ) 98 if (!vcal )
99 return false; 99 return false;
100 100
101 // Iterate over the list 101 // Iterate over the list
102 VObjectIterator it; 102 VObjectIterator it;
103 VObject* vobj; 103 VObject* vobj;
104 104
105 initPropIterator(&it, vcal); 105 initPropIterator(&it, vcal);
106 106
107 while( moreIteration( &it ) ) { 107 while( moreIteration( &it ) ) {
108 vobj = ::nextVObject( &it ); 108 vobj = ::nextVObject( &it );
109 QCString name = ::vObjectName( vobj ); 109 QCString name = ::vObjectName( vobj );
110 if( name == VCTodoProp ){ 110 if( name == VCTodoProp ){
111 OTodo to = eventByVObj( vobj ); 111 OTodo to = eventByVObj( vobj );
112 m_map.insert( to.uid(), to ); 112 m_map.insert( to.uid(), to );
113 } 113 }
114 } 114 }
115 115
116 // Should I do a delete vcal? 116 // Should I do a delete vcal?
117 117
118 return true; 118 return true;
119} 119}
120bool OTodoAccessVCal::reload() { 120bool OTodoAccessVCal::reload() {
121 return load(); 121 return load();
122} 122}
123bool OTodoAccessVCal::save() { 123bool OTodoAccessVCal::save() {
124 if (!m_dirty ) 124 if (!m_dirty )
125 return true; 125 return true;
126 126
127 QFileDirect file( m_file ); 127 QFileDirect file( m_file );
128 if (!file.open(IO_WriteOnly ) ) 128 if (!file.open(IO_WriteOnly ) )
129 return false; 129 return false;
130 130
131 VObject *obj; 131 VObject *obj;
132 obj = newVObject( VCCalProp ); 132 obj = newVObject( VCCalProp );
133 addPropValue( obj, VCVersionProp, "1.0" ); 133 addPropValue( obj, VCVersionProp, "1.0" );
134 VObject *vo; 134 VObject *vo;
135 for(QMap<int, OTodo>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ 135 for(QMap<int, OTodo>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){
136 vo = vobjByEvent( it.data() ); 136 vo = vobjByEvent( it.data() );
137 addVObjectProp(obj, vo ); 137 addVObjectProp(obj, vo );
138 } 138 }
139 writeVObject( file.directHandle(), obj ); 139 writeVObject( file.directHandle(), obj );
140 cleanVObject( obj ); 140 cleanVObject( obj );
141 cleanStrTbl(); 141 cleanStrTbl();
142 142
143 m_dirty = false; 143 m_dirty = false;
144 return true; 144 return true;
145} 145}
146void OTodoAccessVCal::clear() { 146void OTodoAccessVCal::clear() {
147 m_map.clear(); 147 m_map.clear();
148 m_dirty = true; 148 m_dirty = true;
149} 149}
150bool OTodoAccessVCal::add( const OTodo& to ) { 150bool OTodoAccessVCal::add( const OTodo& to ) {
151 m_map.insert( to.uid(), to ); 151 m_map.insert( to.uid(), to );
152 m_dirty = true; 152 m_dirty = true;
153 return true; 153 return true;
154} 154}
155bool OTodoAccessVCal::remove( int uid ) { 155bool OTodoAccessVCal::remove( int uid ) {
156 m_map.remove( uid ); 156 m_map.remove( uid );
157 m_dirty = true; 157 m_dirty = true;
158 return true; 158 return true;
159} 159}
160void OTodoAccessVCal::removeAllCompleted() { 160void OTodoAccessVCal::removeAllCompleted() {
161 for ( QMap<int, OTodo>::Iterator it = m_map.begin(); it != m_map.end(); ++it ) { 161 for ( QMap<int, OTodo>::Iterator it = m_map.begin(); it != m_map.end(); ++it ) {
162 if ( (*it).isCompleted() ) 162 if ( (*it).isCompleted() )
163 m_map.remove( it ); 163 m_map.remove( it );
164 } 164 }
165} 165}
166bool OTodoAccessVCal::replace( const OTodo& to ) { 166bool OTodoAccessVCal::replace( const OTodo& to ) {
167 m_map.replace( to.uid(), to ); 167 m_map.replace( to.uid(), to );
168 m_dirty = true; 168 m_dirty = true;
169 return true; 169 return true;
170} 170}
171OTodo OTodoAccessVCal::find(int uid )const { 171OTodo OTodoAccessVCal::find(int uid )const {
172 return m_map[uid]; 172 return m_map[uid];
173} 173}
174QArray<int> OTodoAccessVCal::sorted( bool, int, int, int ) { 174QArray<int> OTodoAccessVCal::sorted( bool, int, int, int ) {
175 QArray<int> ar(0); 175 QArray<int> ar(0);
176 return ar; 176 return ar;
177} 177}
178QArray<int> OTodoAccessVCal::allRecords()const { 178QArray<int> OTodoAccessVCal::allRecords()const {
179 QArray<int> ar( m_map.count() ); 179 QArray<int> ar( m_map.count() );
180 QMap<int, OTodo>::ConstIterator it; 180 QMap<int, OTodo>::ConstIterator it;
181 int i = 0; 181 int i = 0;
182 for ( it = m_map.begin(); it != m_map.end(); ++it ) { 182 for ( it = m_map.begin(); it != m_map.end(); ++it ) {
183 ar[i] = it.key(); 183 ar[i] = it.key();
184 i++; 184 i++;
185 } 185 }
186 return ar; 186 return ar;
187} 187}
188QArray<int> OTodoAccessVCal::queryByExample( const OTodo&, int, const QDateTime& ) { 188QArray<int> OTodoAccessVCal::queryByExample( const OTodo&, int, const QDateTime& ) {
189 QArray<int> ar(0); 189 QArray<int> ar(0);
190 return ar; 190 return ar;
191} 191}
192QArray<int> OTodoAccessVCal::effectiveToDos( const QDate& , 192QArray<int> OTodoAccessVCal::effectiveToDos( const QDate& ,
193 const QDate& , 193 const QDate& ,
194 bool ) { 194 bool ) {
195 QArray<int> ar(0); 195 QArray<int> ar(0);
196 return ar; 196 return ar;
197} 197}
198QArray<int> OTodoAccessVCal::overDue() { 198QArray<int> OTodoAccessVCal::overDue() {
199 QArray<int> ar(0); 199 QArray<int> ar(0);
200 return ar; 200 return ar;
201} 201}
202QBitArray OTodoAccessVCal::supports()const {
203 static QBitArray ar = sup();
204
205 return ar;
206}
207QBitArray OTodoAccessVCal::sup() {
208 QBitArray ar ( OTodo::CompletedDate +1 );
209 ar.fill( true );
210
211 ar[OTodo::CrossReference] = false;
212 ar[OTodo::State ] = false;
213 ar[OTodo::Reminders] = false;
214 ar[OTodo::Notifiers] = false;
215 ar[OTodo::Maintainer] = false;
216 ar[OTodo::Progress] = false;
217 ar[OTodo::Alarms ] = false;
218 ar[OTodo::Recurrence] = false;
219
220 return ar;
221}
diff --git a/libopie/pim/otodoaccessvcal.h b/libopie/pim/otodoaccessvcal.h
index a90ee9c..489416b 100644
--- a/libopie/pim/otodoaccessvcal.h
+++ b/libopie/pim/otodoaccessvcal.h
@@ -1,37 +1,39 @@
1#ifndef OPIE_OTODO_ACCESS_VCAL_H 1#ifndef OPIE_OTODO_ACCESS_VCAL_H
2#define OPIE_OTODO_ACCESS_VCAL_H 2#define OPIE_OTODO_ACCESS_VCAL_H
3 3
4#include "otodoaccessbackend.h" 4#include "otodoaccessbackend.h"
5 5
6class OTodoAccessVCal : public OTodoAccessBackend { 6class OTodoAccessVCal : public OTodoAccessBackend {
7public: 7public:
8 OTodoAccessVCal(const QString& ); 8 OTodoAccessVCal(const QString& );
9 ~OTodoAccessVCal(); 9 ~OTodoAccessVCal();
10 10
11 bool load(); 11 bool load();
12 bool reload(); 12 bool reload();
13 bool save(); 13 bool save();
14 14
15 QArray<int> allRecords()const; 15 QArray<int> allRecords()const;
16 QArray<int> queryByExample( const OTodo& t, int sort, const QDateTime& d = QDateTime() ); 16 QArray<int> queryByExample( const OTodo& t, int sort, const QDateTime& d = QDateTime() );
17 QArray<int> effectiveToDos( const QDate& start, 17 QArray<int> effectiveToDos( const QDate& start,
18 const QDate& end, 18 const QDate& end,
19 bool includeNoDates ); 19 bool includeNoDates );
20 QArray<int> overDue(); 20 QArray<int> overDue();
21 QArray<int> sorted( bool asc, int sortOrder, int sortFilter, 21 QArray<int> sorted( bool asc, int sortOrder, int sortFilter,
22 int cat ); 22 int cat );
23 OTodo find(int uid)const; 23 OTodo find(int uid)const;
24 void clear(); 24 void clear();
25 bool add( const OTodo& ); 25 bool add( const OTodo& );
26 bool remove( int uid ); 26 bool remove( int uid );
27 bool replace( const OTodo& ); 27 bool replace( const OTodo& );
28 28
29 void removeAllCompleted(); 29 void removeAllCompleted();
30 virtual QBitArray supports()const;
30 31
31private: 32private:
33 static QBitArray sup();
32 bool m_dirty : 1; 34 bool m_dirty : 1;
33 QString m_file; 35 QString m_file;
34 QMap<int, OTodo> m_map; 36 QMap<int, OTodo> m_map;
35}; 37};
36 38
37#endif 39#endif
diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp
index 71e8787..55f268b 100644
--- a/libopie/pim/otodoaccessxml.cpp
+++ b/libopie/pim/otodoaccessxml.cpp
@@ -1,675 +1,689 @@
1#include <errno.h> 1#include <errno.h>
2#include <fcntl.h> 2#include <fcntl.h>
3 3
4#include <sys/mman.h> 4#include <sys/mman.h>
5#include <sys/stat.h> 5#include <sys/stat.h>
6#include <sys/types.h> 6#include <sys/types.h>
7 7
8#include <unistd.h> 8#include <unistd.h>
9 9
10 10
11#include <qfile.h> 11#include <qfile.h>
12#include <qvector.h> 12#include <qvector.h>
13 13
14#include <qpe/global.h> 14#include <qpe/global.h>
15#include <qpe/stringutil.h> 15#include <qpe/stringutil.h>
16#include <qpe/timeconversion.h> 16#include <qpe/timeconversion.h>
17 17
18#include "otodoaccessxml.h" 18#include "otodoaccessxml.h"
19 19
20namespace { 20namespace {
21 // FROM TT again 21 // FROM TT again
22char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) 22char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
23{ 23{
24 char needleChar; 24 char needleChar;
25 char haystackChar; 25 char haystackChar;
26 if (!needle || !haystack || !hLen || !nLen) 26 if (!needle || !haystack || !hLen || !nLen)
27 return 0; 27 return 0;
28 28
29 const char* hsearch = haystack; 29 const char* hsearch = haystack;
30 30
31 if ((needleChar = *needle++) != 0) { 31 if ((needleChar = *needle++) != 0) {
32 nLen--; //(to make up for needle++) 32 nLen--; //(to make up for needle++)
33 do { 33 do {
34 do { 34 do {
35 if ((haystackChar = *hsearch++) == 0) 35 if ((haystackChar = *hsearch++) == 0)
36 return (0); 36 return (0);
37 if (hsearch >= haystack + hLen) 37 if (hsearch >= haystack + hLen)
38 return (0); 38 return (0);
39 } while (haystackChar != needleChar); 39 } while (haystackChar != needleChar);
40 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); 40 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
41 hsearch--; 41 hsearch--;
42 } 42 }
43 return ((char *)hsearch); 43 return ((char *)hsearch);
44} 44}
45} 45}
46 46
47 47
48OTodoAccessXML::OTodoAccessXML( const QString& appName, 48OTodoAccessXML::OTodoAccessXML( const QString& appName,
49 const QString& fileName ) 49 const QString& fileName )
50 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) 50 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
51{ 51{
52 if (!fileName.isEmpty() ) 52 if (!fileName.isEmpty() )
53 m_file = fileName; 53 m_file = fileName;
54 else 54 else
55 m_file = Global::applicationFileName( "todolist", "todolist.xml" ); 55 m_file = Global::applicationFileName( "todolist", "todolist.xml" );
56} 56}
57OTodoAccessXML::~OTodoAccessXML() { 57OTodoAccessXML::~OTodoAccessXML() {
58 58
59} 59}
60bool OTodoAccessXML::load() { 60bool OTodoAccessXML::load() {
61 m_opened = true; 61 m_opened = true;
62 m_changed = false; 62 m_changed = false;
63 /* initialize dict */ 63 /* initialize dict */
64 /* 64 /*
65 * UPDATE dict if you change anything!!! 65 * UPDATE dict if you change anything!!!
66 */ 66 */
67 QAsciiDict<int> dict(21); 67 QAsciiDict<int> dict(21);
68 dict.setAutoDelete( TRUE ); 68 dict.setAutoDelete( TRUE );
69 dict.insert("Categories" , new int(OTodo::Category) ); 69 dict.insert("Categories" , new int(OTodo::Category) );
70 dict.insert("Uid" , new int(OTodo::Uid) ); 70 dict.insert("Uid" , new int(OTodo::Uid) );
71 dict.insert("HasDate" , new int(OTodo::HasDate) ); 71 dict.insert("HasDate" , new int(OTodo::HasDate) );
72 dict.insert("Completed" , new int(OTodo::Completed) ); 72 dict.insert("Completed" , new int(OTodo::Completed) );
73 dict.insert("Description" , new int(OTodo::Description) ); 73 dict.insert("Description" , new int(OTodo::Description) );
74 dict.insert("Summary" , new int(OTodo::Summary) ); 74 dict.insert("Summary" , new int(OTodo::Summary) );
75 dict.insert("Priority" , new int(OTodo::Priority) ); 75 dict.insert("Priority" , new int(OTodo::Priority) );
76 dict.insert("DateDay" , new int(OTodo::DateDay) ); 76 dict.insert("DateDay" , new int(OTodo::DateDay) );
77 dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 77 dict.insert("DateMonth" , new int(OTodo::DateMonth) );
78 dict.insert("DateYear" , new int(OTodo::DateYear) ); 78 dict.insert("DateYear" , new int(OTodo::DateYear) );
79 dict.insert("Progress" , new int(OTodo::Progress) ); 79 dict.insert("Progress" , new int(OTodo::Progress) );
80 dict.insert("Completed", new int(OTodo::Completed) ); 80 dict.insert("Completed", new int(OTodo::Completed) );
81 dict.insert("CrossReference", new int(OTodo::CrossReference) ); 81 dict.insert("CrossReference", new int(OTodo::CrossReference) );
82 dict.insert("State", new int(OTodo::State) ); 82 dict.insert("State", new int(OTodo::State) );
83 dict.insert("Recurrence", new int(OTodo::Recurrence) ); 83 dict.insert("Recurrence", new int(OTodo::Recurrence) );
84 dict.insert("Alarms", new int(OTodo::Alarms) ); 84 dict.insert("Alarms", new int(OTodo::Alarms) );
85 dict.insert("Reminders", new int(OTodo::Reminders) ); 85 dict.insert("Reminders", new int(OTodo::Reminders) );
86 dict.insert("Notifiers", new int(OTodo::Notifiers) ); 86 dict.insert("Notifiers", new int(OTodo::Notifiers) );
87 dict.insert("Maintainer", new int(OTodo::Maintainer) ); 87 dict.insert("Maintainer", new int(OTodo::Maintainer) );
88 88
89 // here the custom XML parser from TT it's GPL 89 // here the custom XML parser from TT it's GPL
90 // but we want to push OpiePIM... to TT..... 90 // but we want to push OpiePIM... to TT.....
91 // mmap part from zecke :) 91 // mmap part from zecke :)
92 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); 92 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
93 struct stat attribut; 93 struct stat attribut;
94 if ( fd < 0 ) return false; 94 if ( fd < 0 ) return false;
95 95
96 if ( fstat(fd, &attribut ) == -1 ) { 96 if ( fstat(fd, &attribut ) == -1 ) {
97 ::close( fd ); 97 ::close( fd );
98 return false; 98 return false;
99 } 99 }
100 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 100 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
101 if ( map_addr == ( (caddr_t)-1) ) { 101 if ( map_addr == ( (caddr_t)-1) ) {
102 ::close(fd ); 102 ::close(fd );
103 return false; 103 return false;
104 } 104 }
105 /* advise the kernel who we want to read it */ 105 /* advise the kernel who we want to read it */
106 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); 106 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
107 /* we do not the file any more */ 107 /* we do not the file any more */
108 ::close( fd ); 108 ::close( fd );
109 109
110 char* dt = (char*)map_addr; 110 char* dt = (char*)map_addr;
111 int len = attribut.st_size; 111 int len = attribut.st_size;
112 int i = 0; 112 int i = 0;
113 char *point; 113 char *point;
114 const char* collectionString = "<Task "; 114 const char* collectionString = "<Task ";
115 int strLen = strlen(collectionString); 115 int strLen = strlen(collectionString);
116 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { 116 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) {
117 i = point -dt; 117 i = point -dt;
118 i+= strLen; 118 i+= strLen;
119 qWarning("Found a start at %d %d", i, (point-dt) ); 119 qWarning("Found a start at %d %d", i, (point-dt) );
120 120
121 OTodo ev; 121 OTodo ev;
122 m_year = m_month = m_day = 0; 122 m_year = m_month = m_day = 0;
123 123
124 while ( TRUE ) { 124 while ( TRUE ) {
125 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 125 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
126 ++i; 126 ++i;
127 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 127 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
128 break; 128 break;
129 129
130 // we have another attribute, read it. 130 // we have another attribute, read it.
131 int j = i; 131 int j = i;
132 while ( j < len && dt[j] != '=' ) 132 while ( j < len && dt[j] != '=' )
133 ++j; 133 ++j;
134 QCString attr( dt+i, j-i+1); 134 QCString attr( dt+i, j-i+1);
135 135
136 i = ++j; // skip = 136 i = ++j; // skip =
137 137
138 // find the start of quotes 138 // find the start of quotes
139 while ( i < len && dt[i] != '"' ) 139 while ( i < len && dt[i] != '"' )
140 ++i; 140 ++i;
141 j = ++i; 141 j = ++i;
142 142
143 bool haveUtf = FALSE; 143 bool haveUtf = FALSE;
144 bool haveEnt = FALSE; 144 bool haveEnt = FALSE;
145 while ( j < len && dt[j] != '"' ) { 145 while ( j < len && dt[j] != '"' ) {
146 if ( ((unsigned char)dt[j]) > 0x7f ) 146 if ( ((unsigned char)dt[j]) > 0x7f )
147 haveUtf = TRUE; 147 haveUtf = TRUE;
148 if ( dt[j] == '&' ) 148 if ( dt[j] == '&' )
149 haveEnt = TRUE; 149 haveEnt = TRUE;
150 ++j; 150 ++j;
151 } 151 }
152 if ( i == j ) { 152 if ( i == j ) {
153 // empty value 153 // empty value
154 i = j + 1; 154 i = j + 1;
155 continue; 155 continue;
156 } 156 }
157 157
158 QCString value( dt+i, j-i+1 ); 158 QCString value( dt+i, j-i+1 );
159 i = j + 1; 159 i = j + 1;
160 160
161 QString str = (haveUtf ? QString::fromUtf8( value ) 161 QString str = (haveUtf ? QString::fromUtf8( value )
162 : QString::fromLatin1( value ) ); 162 : QString::fromLatin1( value ) );
163 if ( haveEnt ) 163 if ( haveEnt )
164 str = Qtopia::plainString( str ); 164 str = Qtopia::plainString( str );
165 165
166 /* 166 /*
167 * add key + value 167 * add key + value
168 */ 168 */
169 todo( &dict, ev, attr, str ); 169 todo( &dict, ev, attr, str );
170 170
171 } 171 }
172 /* 172 /*
173 * now add it 173 * now add it
174 */ 174 */
175 qWarning("End at %d", i ); 175 qWarning("End at %d", i );
176 if (m_events.contains( ev.uid() ) || ev.uid() == 0) { 176 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
177 ev.setUid( 1 ); 177 ev.setUid( 1 );
178 m_changed = true; 178 m_changed = true;
179 } 179 }
180 if ( ev.hasDueDate() ) { 180 if ( ev.hasDueDate() ) {
181 ev.setDueDate( QDate(m_year, m_month, m_day) ); 181 ev.setDueDate( QDate(m_year, m_month, m_day) );
182 } 182 }
183 m_events.insert(ev.uid(), ev ); 183 m_events.insert(ev.uid(), ev );
184 m_year = m_month = m_day = -1; 184 m_year = m_month = m_day = -1;
185 } 185 }
186 186
187 munmap(map_addr, attribut.st_size ); 187 munmap(map_addr, attribut.st_size );
188 188
189 qWarning("counts %d records loaded!", m_events.count() ); 189 qWarning("counts %d records loaded!", m_events.count() );
190 return true; 190 return true;
191} 191}
192bool OTodoAccessXML::reload() { 192bool OTodoAccessXML::reload() {
193 m_events.clear(); 193 m_events.clear();
194 return load(); 194 return load();
195} 195}
196bool OTodoAccessXML::save() { 196bool OTodoAccessXML::save() {
197// qWarning("saving"); 197// qWarning("saving");
198 if (!m_opened || !m_changed ) { 198 if (!m_opened || !m_changed ) {
199// qWarning("not saving"); 199// qWarning("not saving");
200 return true; 200 return true;
201 } 201 }
202 QString strNewFile = m_file + ".new"; 202 QString strNewFile = m_file + ".new";
203 QFile f( strNewFile ); 203 QFile f( strNewFile );
204 if (!f.open( IO_WriteOnly|IO_Raw ) ) 204 if (!f.open( IO_WriteOnly|IO_Raw ) )
205 return false; 205 return false;
206 206
207 int written; 207 int written;
208 QString out; 208 QString out;
209 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 209 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
210 210
211 // for all todos 211 // for all todos
212 QMap<int, OTodo>::Iterator it; 212 QMap<int, OTodo>::Iterator it;
213 for (it = m_events.begin(); it != m_events.end(); ++it ) { 213 for (it = m_events.begin(); it != m_events.end(); ++it ) {
214 out+= "<Task " + toString( (*it) ) + " />\n"; 214 out+= "<Task " + toString( (*it) ) + " />\n";
215 QCString cstr = out.utf8(); 215 QCString cstr = out.utf8();
216 written = f.writeBlock( cstr.data(), cstr.length() ); 216 written = f.writeBlock( cstr.data(), cstr.length() );
217 217
218 /* less written then we wanted */ 218 /* less written then we wanted */
219 if ( written != (int)cstr.length() ) { 219 if ( written != (int)cstr.length() ) {
220 f.close(); 220 f.close();
221 QFile::remove( strNewFile ); 221 QFile::remove( strNewFile );
222 return false; 222 return false;
223 } 223 }
224 out = QString::null; 224 out = QString::null;
225 } 225 }
226 226
227 out += "</Tasks>"; 227 out += "</Tasks>";
228 QCString cstr = out.utf8(); 228 QCString cstr = out.utf8();
229 written = f.writeBlock( cstr.data(), cstr.length() ); 229 written = f.writeBlock( cstr.data(), cstr.length() );
230 230
231 if ( written != (int)cstr.length() ) { 231 if ( written != (int)cstr.length() ) {
232 f.close(); 232 f.close();
233 QFile::remove( strNewFile ); 233 QFile::remove( strNewFile );
234 return false; 234 return false;
235 } 235 }
236 /* flush before renaming */ 236 /* flush before renaming */
237 f.close(); 237 f.close();
238 238
239 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 239 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
240// qWarning("error renaming"); 240// qWarning("error renaming");
241 QFile::remove( strNewFile ); 241 QFile::remove( strNewFile );
242 } 242 }
243 243
244 m_changed = false; 244 m_changed = false;
245 return true; 245 return true;
246} 246}
247QArray<int> OTodoAccessXML::allRecords()const { 247QArray<int> OTodoAccessXML::allRecords()const {
248 QArray<int> ids( m_events.count() ); 248 QArray<int> ids( m_events.count() );
249 QMap<int, OTodo>::ConstIterator it; 249 QMap<int, OTodo>::ConstIterator it;
250 int i = 0; 250 int i = 0;
251 251
252 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 252 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
253 ids[i] = it.key(); 253 ids[i] = it.key();
254 i++; 254 i++;
255 } 255 }
256 return ids; 256 return ids;
257} 257}
258QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int, const QDateTime& ) { 258QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int, const QDateTime& ) {
259 QArray<int> ids(0); 259 QArray<int> ids(0);
260 return ids; 260 return ids;
261} 261}
262OTodo OTodoAccessXML::find( int uid )const { 262OTodo OTodoAccessXML::find( int uid )const {
263 OTodo todo; 263 OTodo todo;
264 todo.setUid( 0 ); // isEmpty() 264 todo.setUid( 0 ); // isEmpty()
265 QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); 265 QMap<int, OTodo>::ConstIterator it = m_events.find( uid );
266 if ( it != m_events.end() ) 266 if ( it != m_events.end() )
267 todo = it.data(); 267 todo = it.data();
268 268
269 return todo; 269 return todo;
270} 270}
271void OTodoAccessXML::clear() { 271void OTodoAccessXML::clear() {
272 if (m_opened ) 272 if (m_opened )
273 m_changed = true; 273 m_changed = true;
274 274
275 m_events.clear(); 275 m_events.clear();
276} 276}
277bool OTodoAccessXML::add( const OTodo& todo ) { 277bool OTodoAccessXML::add( const OTodo& todo ) {
278// qWarning("add"); 278// qWarning("add");
279 m_changed = true; 279 m_changed = true;
280 m_events.insert( todo.uid(), todo ); 280 m_events.insert( todo.uid(), todo );
281 281
282 return true; 282 return true;
283} 283}
284bool OTodoAccessXML::remove( int uid ) { 284bool OTodoAccessXML::remove( int uid ) {
285 m_changed = true; 285 m_changed = true;
286 m_events.remove( uid ); 286 m_events.remove( uid );
287 287
288 return true; 288 return true;
289} 289}
290bool OTodoAccessXML::replace( const OTodo& todo) { 290bool OTodoAccessXML::replace( const OTodo& todo) {
291 m_changed = true; 291 m_changed = true;
292 m_events.replace( todo.uid(), todo ); 292 m_events.replace( todo.uid(), todo );
293 293
294 return true; 294 return true;
295} 295}
296QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, 296QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
297 const QDate& end, 297 const QDate& end,
298 bool includeNoDates ) { 298 bool includeNoDates ) {
299 QArray<int> ids( m_events.count() ); 299 QArray<int> ids( m_events.count() );
300 QMap<int, OTodo>::Iterator it; 300 QMap<int, OTodo>::Iterator it;
301 301
302 int i = 0; 302 int i = 0;
303 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 303 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
304 if ( !it.data().hasDueDate() ) { 304 if ( !it.data().hasDueDate() ) {
305 if ( includeNoDates ) { 305 if ( includeNoDates ) {
306 ids[i] = it.key(); 306 ids[i] = it.key();
307 i++; 307 i++;
308 } 308 }
309 }else if ( it.data().dueDate() >= start && 309 }else if ( it.data().dueDate() >= start &&
310 it.data().dueDate() <= end ) { 310 it.data().dueDate() <= end ) {
311 ids[i] = it.key(); 311 ids[i] = it.key();
312 i++; 312 i++;
313 } 313 }
314 } 314 }
315 ids.resize( i ); 315 ids.resize( i );
316 return ids; 316 return ids;
317} 317}
318QArray<int> OTodoAccessXML::overDue() { 318QArray<int> OTodoAccessXML::overDue() {
319 QArray<int> ids( m_events.count() ); 319 QArray<int> ids( m_events.count() );
320 int i = 0; 320 int i = 0;
321 321
322 QMap<int, OTodo>::Iterator it; 322 QMap<int, OTodo>::Iterator it;
323 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 323 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
324 if ( it.data().isOverdue() ) { 324 if ( it.data().isOverdue() ) {
325 ids[i] = it.key(); 325 ids[i] = it.key();
326 i++; 326 i++;
327 } 327 }
328 } 328 }
329 ids.resize( i ); 329 ids.resize( i );
330 return ids; 330 return ids;
331} 331}
332 332
333 333
334/* private */ 334/* private */
335void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, 335void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
336 const QCString& attr, const QString& val) { 336 const QCString& attr, const QString& val) {
337// qWarning("parse to do from XMLElement" ); 337// qWarning("parse to do from XMLElement" );
338 338
339 int *find=0; 339 int *find=0;
340 340
341 find = (*dict)[ attr.data() ]; 341 find = (*dict)[ attr.data() ];
342 if (!find ) { 342 if (!find ) {
343// qWarning("Unknown option" + it.key() ); 343// qWarning("Unknown option" + it.key() );
344 ev.setCustomField( attr, val ); 344 ev.setCustomField( attr, val );
345 return; 345 return;
346 } 346 }
347 347
348 switch( *find ) { 348 switch( *find ) {
349 case OTodo::Uid: 349 case OTodo::Uid:
350 ev.setUid( val.toInt() ); 350 ev.setUid( val.toInt() );
351 break; 351 break;
352 case OTodo::Category: 352 case OTodo::Category:
353 ev.setCategories( ev.idsFromString( val ) ); 353 ev.setCategories( ev.idsFromString( val ) );
354 break; 354 break;
355 case OTodo::HasDate: 355 case OTodo::HasDate:
356 ev.setHasDueDate( val.toInt() ); 356 ev.setHasDueDate( val.toInt() );
357 break; 357 break;
358 case OTodo::Completed: 358 case OTodo::Completed:
359 ev.setCompleted( val.toInt() ); 359 ev.setCompleted( val.toInt() );
360 break; 360 break;
361 case OTodo::Description: 361 case OTodo::Description:
362 ev.setDescription( val ); 362 ev.setDescription( val );
363 break; 363 break;
364 case OTodo::Summary: 364 case OTodo::Summary:
365 ev.setSummary( val ); 365 ev.setSummary( val );
366 break; 366 break;
367 case OTodo::Priority: 367 case OTodo::Priority:
368 ev.setPriority( val.toInt() ); 368 ev.setPriority( val.toInt() );
369 break; 369 break;
370 case OTodo::DateDay: 370 case OTodo::DateDay:
371 m_day = val.toInt(); 371 m_day = val.toInt();
372 break; 372 break;
373 case OTodo::DateMonth: 373 case OTodo::DateMonth:
374 m_month = val.toInt(); 374 m_month = val.toInt();
375 break; 375 break;
376 case OTodo::DateYear: 376 case OTodo::DateYear:
377 m_year = val.toInt(); 377 m_year = val.toInt();
378 break; 378 break;
379 case OTodo::Progress: 379 case OTodo::Progress:
380 ev.setProgress( val.toInt() ); 380 ev.setProgress( val.toInt() );
381 break; 381 break;
382 case OTodo::CrossReference: 382 case OTodo::CrossReference:
383 { 383 {
384 /* 384 /*
385 * A cross refernce looks like 385 * A cross refernce looks like
386 * appname,id;appname,id 386 * appname,id;appname,id
387 * we need to split it up 387 * we need to split it up
388 */ 388 */
389 QStringList refs = QStringList::split(';', val ); 389 QStringList refs = QStringList::split(';', val );
390 QStringList::Iterator strIt; 390 QStringList::Iterator strIt;
391 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 391 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
392 int pos = (*strIt).find(','); 392 int pos = (*strIt).find(',');
393 if ( pos > -1 ) 393 if ( pos > -1 )
394 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 394 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
395 395
396 } 396 }
397 break; 397 break;
398 } 398 }
399 default: 399 default:
400 break; 400 break;
401 } 401 }
402} 402}
403QString OTodoAccessXML::toString( const OTodo& ev )const { 403QString OTodoAccessXML::toString( const OTodo& ev )const {
404 QString str; 404 QString str;
405 405
406 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 406 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
407 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 407 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
408 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 408 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
409 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 409 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
410 410
411 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 411 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
412 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 412 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
413 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 413 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
414 414
415 if ( ev.hasDueDate() ) { 415 if ( ev.hasDueDate() ) {
416 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 416 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
417 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 417 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
418 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 418 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
419 } 419 }
420// qWarning( "Uid %d", ev.uid() ); 420// qWarning( "Uid %d", ev.uid() );
421 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 421 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
422 422
423// append the extra options 423// append the extra options
424 /* FIXME Qtopia::Record this is currently not 424 /* FIXME Qtopia::Record this is currently not
425 * possible you can set custom fields 425 * possible you can set custom fields
426 * but don' iterate over the list 426 * but don' iterate over the list
427 * I may do #define private protected 427 * I may do #define private protected
428 * for this case - cough --zecke 428 * for this case - cough --zecke
429 */ 429 */
430 /* 430 /*
431 QMap<QString, QString> extras = ev.extras(); 431 QMap<QString, QString> extras = ev.extras();
432 QMap<QString, QString>::Iterator extIt; 432 QMap<QString, QString>::Iterator extIt;
433 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 433 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
434 str += extIt.key() + "=\"" + extIt.data() + "\" "; 434 str += extIt.key() + "=\"" + extIt.data() + "\" ";
435 */ 435 */
436 // cross refernce 436 // cross refernce
437 437
438 438
439 return str; 439 return str;
440} 440}
441QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 441QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
442 return Qtopia::Record::idsToString( ints ); 442 return Qtopia::Record::idsToString( ints );
443} 443}
444 444
445/* internal class for sorting 445/* internal class for sorting
446 * 446 *
447 * Inspired by todoxmlio.cpp from TT 447 * Inspired by todoxmlio.cpp from TT
448 */ 448 */
449 449
450struct OTodoXMLContainer { 450struct OTodoXMLContainer {
451 OTodo todo; 451 OTodo todo;
452}; 452};
453 453
454namespace { 454namespace {
455 inline QString string( const OTodo& todo) { 455 inline QString string( const OTodo& todo) {
456 return todo.summary().isEmpty() ? 456 return todo.summary().isEmpty() ?
457 todo.description().left(20 ) : 457 todo.description().left(20 ) :
458 todo.summary(); 458 todo.summary();
459 } 459 }
460 inline int completed( const OTodo& todo1, const OTodo& todo2) { 460 inline int completed( const OTodo& todo1, const OTodo& todo2) {
461 int ret = 0; 461 int ret = 0;
462 if ( todo1.isCompleted() ) ret++; 462 if ( todo1.isCompleted() ) ret++;
463 if ( todo2.isCompleted() ) ret--; 463 if ( todo2.isCompleted() ) ret--;
464 return ret; 464 return ret;
465 } 465 }
466 inline int priority( const OTodo& t1, const OTodo& t2) { 466 inline int priority( const OTodo& t1, const OTodo& t2) {
467 return ( t1.priority() - t2.priority() ); 467 return ( t1.priority() - t2.priority() );
468 } 468 }
469 inline int description( const OTodo& t1, const OTodo& t2) { 469 inline int description( const OTodo& t1, const OTodo& t2) {
470 return QString::compare( string(t1), string(t2) ); 470 return QString::compare( string(t1), string(t2) );
471 } 471 }
472 inline int deadline( const OTodo& t1, const OTodo& t2) { 472 inline int deadline( const OTodo& t1, const OTodo& t2) {
473 int ret = 0; 473 int ret = 0;
474 if ( t1.hasDueDate() && 474 if ( t1.hasDueDate() &&
475 t2.hasDueDate() ) 475 t2.hasDueDate() )
476 ret = t2.dueDate().daysTo( t1.dueDate() ); 476 ret = t2.dueDate().daysTo( t1.dueDate() );
477 else if ( t1.hasDueDate() ) 477 else if ( t1.hasDueDate() )
478 ret = -1; 478 ret = -1;
479 else if ( t2.hasDueDate() ) 479 else if ( t2.hasDueDate() )
480 ret = 1; 480 ret = 1;
481 else 481 else
482 ret = 0; 482 ret = 0;
483 483
484 return ret; 484 return ret;
485 } 485 }
486 486
487}; 487};
488 488
489/* 489/*
490 * Returns: 490 * Returns:
491 * 0 if item1 == item2 491 * 0 if item1 == item2
492 * 492 *
493 * non-zero if item1 != item2 493 * non-zero if item1 != item2
494 * 494 *
495 * This function returns int rather than bool so that reimplementations 495 * This function returns int rather than bool so that reimplementations
496 * can return one of three values and use it to sort by: 496 * can return one of three values and use it to sort by:
497 * 497 *
498 * 0 if item1 == item2 498 * 0 if item1 == item2
499 * 499 *
500 * > 0 (positive integer) if item1 > item2 500 * > 0 (positive integer) if item1 > item2
501 * 501 *
502 * < 0 (negative integer) if item1 < item2 502 * < 0 (negative integer) if item1 < item2
503 * 503 *
504 */ 504 */
505class OTodoXMLVector : public QVector<OTodoXMLContainer> { 505class OTodoXMLVector : public QVector<OTodoXMLContainer> {
506public: 506public:
507 OTodoXMLVector(int size, bool asc, int sort) 507 OTodoXMLVector(int size, bool asc, int sort)
508 : QVector<OTodoXMLContainer>( size ) 508 : QVector<OTodoXMLContainer>( size )
509 { 509 {
510 setAutoDelete( true ); 510 setAutoDelete( true );
511 m_asc = asc; 511 m_asc = asc;
512 m_sort = sort; 512 m_sort = sort;
513 } 513 }
514 /* return the summary/description */ 514 /* return the summary/description */
515 QString string( const OTodo& todo) { 515 QString string( const OTodo& todo) {
516 return todo.summary().isEmpty() ? 516 return todo.summary().isEmpty() ?
517 todo.description().left(20 ) : 517 todo.description().left(20 ) :
518 todo.summary(); 518 todo.summary();
519 } 519 }
520 /** 520 /**
521 * we take the sortorder( switch on it ) 521 * we take the sortorder( switch on it )
522 * 522 *
523 */ 523 */
524 int compareItems( Item d1, Item d2 ) { 524 int compareItems( Item d1, Item d2 ) {
525 bool seComp, sePrio, seDesc, seDeadline; 525 bool seComp, sePrio, seDesc, seDeadline;
526 seComp = sePrio = seDeadline = seDesc = false; 526 seComp = sePrio = seDeadline = seDesc = false;
527 int ret =0; 527 int ret =0;
528 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; 528 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
529 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; 529 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
530 530
531 /* same item */ 531 /* same item */
532 if ( con1->todo.uid() == con2->todo.uid() ) 532 if ( con1->todo.uid() == con2->todo.uid() )
533 return 0; 533 return 0;
534 534
535 switch ( m_sort ) { 535 switch ( m_sort ) {
536 /* completed */ 536 /* completed */
537 case 0: { 537 case 0: {
538 ret = completed( con1->todo, con2->todo ); 538 ret = completed( con1->todo, con2->todo );
539 seComp = TRUE; 539 seComp = TRUE;
540 break; 540 break;
541 } 541 }
542 /* priority */ 542 /* priority */
543 case 1: { 543 case 1: {
544 ret = priority( con1->todo, con2->todo ); 544 ret = priority( con1->todo, con2->todo );
545 sePrio = TRUE; 545 sePrio = TRUE;
546 break; 546 break;
547 } 547 }
548 /* description */ 548 /* description */
549 case 2: { 549 case 2: {
550 ret = description( con1->todo, con2->todo ); 550 ret = description( con1->todo, con2->todo );
551 seDesc = TRUE; 551 seDesc = TRUE;
552 break; 552 break;
553 } 553 }
554 /* deadline */ 554 /* deadline */
555 case 3: { 555 case 3: {
556 ret = deadline( con1->todo, con2->todo ); 556 ret = deadline( con1->todo, con2->todo );
557 seDeadline = TRUE; 557 seDeadline = TRUE;
558 break; 558 break;
559 } 559 }
560 default: 560 default:
561 ret = 0; 561 ret = 0;
562 break; 562 break;
563 }; 563 };
564 /* 564 /*
565 * FIXME do better sorting if the first sort criteria 565 * FIXME do better sorting if the first sort criteria
566 * ret equals 0 start with complete and so on... 566 * ret equals 0 start with complete and so on...
567 */ 567 */
568 568
569 /* twist it we're not ascending*/ 569 /* twist it we're not ascending*/
570 if (!m_asc) 570 if (!m_asc)
571 ret = ret * -1; 571 ret = ret * -1;
572 572
573 if ( ret ) 573 if ( ret )
574 return ret; 574 return ret;
575 575
576 // default did not gave difference let's try it other way around 576 // default did not gave difference let's try it other way around
577 /* 577 /*
578 * General try if already checked if not test 578 * General try if already checked if not test
579 * and return 579 * and return
580 * 1.Completed 580 * 1.Completed
581 * 2.Priority 581 * 2.Priority
582 * 3.Description 582 * 3.Description
583 * 4.DueDate 583 * 4.DueDate
584 */ 584 */
585 if (!seComp ) { 585 if (!seComp ) {
586 if ( (ret = completed( con1->todo, con2->todo ) ) ) { 586 if ( (ret = completed( con1->todo, con2->todo ) ) ) {
587 if (!m_asc ) ret *= -1; 587 if (!m_asc ) ret *= -1;
588 return ret; 588 return ret;
589 } 589 }
590 } 590 }
591 if (!sePrio ) { 591 if (!sePrio ) {
592 if ( (ret = priority( con1->todo, con2->todo ) ) ) { 592 if ( (ret = priority( con1->todo, con2->todo ) ) ) {
593 if (!m_asc ) ret *= -1; 593 if (!m_asc ) ret *= -1;
594 return ret; 594 return ret;
595 } 595 }
596 } 596 }
597 if (!seDesc ) { 597 if (!seDesc ) {
598 if ( (ret = description(con1->todo, con2->todo ) ) ) { 598 if ( (ret = description(con1->todo, con2->todo ) ) ) {
599 if (!m_asc) ret *= -1; 599 if (!m_asc) ret *= -1;
600 return ret; 600 return ret;
601 } 601 }
602 } 602 }
603 if (!seDeadline) { 603 if (!seDeadline) {
604 if ( (ret = deadline( con1->todo, con2->todo ) ) ) { 604 if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
605 if (!m_asc) ret *= -1; 605 if (!m_asc) ret *= -1;
606 return ret; 606 return ret;
607 } 607 }
608 } 608 }
609 609
610 return 0; 610 return 0;
611 } 611 }
612 private: 612 private:
613 bool m_asc; 613 bool m_asc;
614 int m_sort; 614 int m_sort;
615 615
616}; 616};
617 617
618QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, 618QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder,
619 int sortFilter, int cat ) { 619 int sortFilter, int cat ) {
620 qWarning("sorted! %d cat", cat); 620 qWarning("sorted! %d cat", cat);
621 OTodoXMLVector vector(m_events.count(), asc,sortOrder ); 621 OTodoXMLVector vector(m_events.count(), asc,sortOrder );
622 QMap<int, OTodo>::Iterator it; 622 QMap<int, OTodo>::Iterator it;
623 int item = 0; 623 int item = 0;
624 624
625 bool bCat = sortFilter & 1 ? true : false; 625 bool bCat = sortFilter & 1 ? true : false;
626 bool bOnly = sortFilter & 2 ? true : false; 626 bool bOnly = sortFilter & 2 ? true : false;
627 bool comp = sortFilter & 4 ? true : false; 627 bool comp = sortFilter & 4 ? true : false;
628 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 628 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
629 629
630 /* show category */ 630 /* show category */
631 if ( bCat && cat != 0) 631 if ( bCat && cat != 0)
632 if (!(*it).categories().contains( cat ) ) { 632 if (!(*it).categories().contains( cat ) ) {
633 qWarning("category mis match"); 633 qWarning("category mis match");
634 continue; 634 continue;
635 } 635 }
636 /* isOverdue but we should not show overdue - why?*/ 636 /* isOverdue but we should not show overdue - why?*/
637/* if ( (*it).isOverdue() && !bOnly ) { 637/* if ( (*it).isOverdue() && !bOnly ) {
638 qWarning("item is overdue but !bOnly"); 638 qWarning("item is overdue but !bOnly");
639 continue; 639 continue;
640 } 640 }
641*/ 641*/
642 if ( !(*it).isOverdue() && bOnly ) { 642 if ( !(*it).isOverdue() && bOnly ) {
643 qWarning("item is not overdue but bOnly checked"); 643 qWarning("item is not overdue but bOnly checked");
644 continue; 644 continue;
645 } 645 }
646 646
647 if ((*it).isCompleted() && comp ) { 647 if ((*it).isCompleted() && comp ) {
648 qWarning("completed continue!"); 648 qWarning("completed continue!");
649 continue; 649 continue;
650 } 650 }
651 651
652 652
653 OTodoXMLContainer* con = new OTodoXMLContainer(); 653 OTodoXMLContainer* con = new OTodoXMLContainer();
654 con->todo = (*it); 654 con->todo = (*it);
655 vector.insert(item, con ); 655 vector.insert(item, con );
656 item++; 656 item++;
657 } 657 }
658 qWarning("XXX %d Items added", item); 658 qWarning("XXX %d Items added", item);
659 vector.resize( item ); 659 vector.resize( item );
660 /* sort it now */ 660 /* sort it now */
661 vector.sort(); 661 vector.sort();
662 /* now get the uids */ 662 /* now get the uids */
663 QArray<int> array( vector.count() ); 663 QArray<int> array( vector.count() );
664 for (uint i= 0; i < vector.count(); i++ ) { 664 for (uint i= 0; i < vector.count(); i++ ) {
665 array[i] = ( vector.at(i) )->todo.uid(); 665 array[i] = ( vector.at(i) )->todo.uid();
666 } 666 }
667 qWarning("array count = %d %d", array.count(), vector.count() );
668 return array; 667 return array;
669}; 668};
670void OTodoAccessXML::removeAllCompleted() { 669void OTodoAccessXML::removeAllCompleted() {
671 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { 670 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
672 if ( (*it).isCompleted() ) 671 if ( (*it).isCompleted() )
673 m_events.remove( it ); 672 m_events.remove( it );
674 } 673 }
675} 674}
675QBitArray OTodoAccessXML::supports()const {
676 static QBitArray ar = sup();
677 return ar;
678}
679QBitArray OTodoAccessXML::sup() {
680 QBitArray ar( OTodo::CompletedDate +1 );
681 ar.fill( true );
682 ar[OTodo::CrossReference] = false;
683 ar[OTodo::State ] = false;
684 ar[OTodo::Reminders] = false;
685 ar[OTodo::Notifiers] = false;
686 ar[OTodo::Maintainer] = false;
687
688 return ar;
689}
diff --git a/libopie/pim/otodoaccessxml.h b/libopie/pim/otodoaccessxml.h
index 1032c92..cc4a16f 100644
--- a/libopie/pim/otodoaccessxml.h
+++ b/libopie/pim/otodoaccessxml.h
@@ -1,57 +1,59 @@
1#ifndef OPIE_TODO_ACCESS_XML_H 1#ifndef OPIE_TODO_ACCESS_XML_H
2#define OPIE_TODO_ACCESS_XML_H 2#define OPIE_TODO_ACCESS_XML_H
3 3
4#include <qasciidict.h> 4#include <qasciidict.h>
5#include <qmap.h> 5#include <qmap.h>
6 6
7#include "otodoaccessbackend.h" 7#include "otodoaccessbackend.h"
8 8
9namespace Opie { 9namespace Opie {
10 class XMLElement; 10 class XMLElement;
11}; 11};
12 12
13class OTodoAccessXML : public OTodoAccessBackend { 13class OTodoAccessXML : public OTodoAccessBackend {
14public: 14public:
15 /** 15 /**
16 * fileName if Empty we will use the default path 16 * fileName if Empty we will use the default path
17 */ 17 */
18 OTodoAccessXML( const QString& appName, 18 OTodoAccessXML( const QString& appName,
19 const QString& fileName = QString::null ); 19 const QString& fileName = QString::null );
20 ~OTodoAccessXML(); 20 ~OTodoAccessXML();
21 21
22 bool load(); 22 bool load();
23 bool reload(); 23 bool reload();
24 bool save(); 24 bool save();
25 25
26 QArray<int> allRecords()const; 26 QArray<int> allRecords()const;
27 QArray<int> queryByExample( const OTodo&, int querysettings, const QDateTime& d = QDateTime() ); 27 QArray<int> queryByExample( const OTodo&, int querysettings, const QDateTime& d = QDateTime() );
28 OTodo find( int uid )const; 28 OTodo find( int uid )const;
29 void clear(); 29 void clear();
30 bool add( const OTodo& ); 30 bool add( const OTodo& );
31 bool remove( int uid ); 31 bool remove( int uid );
32 void removeAllCompleted(); 32 void removeAllCompleted();
33 bool replace( const OTodo& ); 33 bool replace( const OTodo& );
34 34
35 /* our functions */ 35 /* our functions */
36 QArray<int> effectiveToDos( const QDate& start, 36 QArray<int> effectiveToDos( const QDate& start,
37 const QDate& end, 37 const QDate& end,
38 bool includeNoDates ); 38 bool includeNoDates );
39 QArray<int> overDue(); 39 QArray<int> overDue();
40 QArray<int> sorted( bool asc, int sortOrder, 40 QArray<int> sorted( bool asc, int sortOrder,
41 int sortFilter, int cat ); 41 int sortFilter, int cat );
42 QBitArray supports()const;
42private: 43private:
44 static QBitArray sup();
43 void todo( QAsciiDict<int>*, OTodo&,const QCString&,const QString& ); 45 void todo( QAsciiDict<int>*, OTodo&,const QCString&,const QString& );
44 QString toString( const OTodo& )const; 46 QString toString( const OTodo& )const;
45 QString toString( const QArray<int>& ints ) const; 47 QString toString( const QArray<int>& ints ) const;
46 QMap<int, OTodo> m_events; 48 QMap<int, OTodo> m_events;
47 QString m_file; 49 QString m_file;
48 QString m_app; 50 QString m_app;
49 bool m_opened : 1; 51 bool m_opened : 1;
50 bool m_changed : 1; 52 bool m_changed : 1;
51 class OTodoAccessXMLPrivate; 53 class OTodoAccessXMLPrivate;
52 OTodoAccessXMLPrivate* d; 54 OTodoAccessXMLPrivate* d;
53 int m_year, m_month, m_day; 55 int m_year, m_month, m_day;
54 56
55}; 57};
56 58
57#endif 59#endif
diff --git a/libopie2/opiepim/backend/otodoaccessbackend.h b/libopie2/opiepim/backend/otodoaccessbackend.h
index 7944a2c..05e8ca9 100644
--- a/libopie2/opiepim/backend/otodoaccessbackend.h
+++ b/libopie2/opiepim/backend/otodoaccessbackend.h
@@ -1,21 +1,24 @@
1#ifndef OPIE_TODO_ACCESS_BACKEND_H 1#ifndef OPIE_TODO_ACCESS_BACKEND_H
2#define OPIE_TODO_ACCESS_BACKEND_H 2#define OPIE_TODO_ACCESS_BACKEND_H
3 3
4#include <qbitarray.h>
5
4#include "otodo.h" 6#include "otodo.h"
5#include "opimaccessbackend.h" 7#include "opimaccessbackend.h"
6 8
7class OTodoAccessBackend : public OPimAccessBackend<OTodo> { 9class OTodoAccessBackend : public OPimAccessBackend<OTodo> {
8public: 10public:
9 OTodoAccessBackend(); 11 OTodoAccessBackend();
10 ~OTodoAccessBackend(); 12 ~OTodoAccessBackend();
11 virtual QArray<int> effectiveToDos( const QDate& start, 13 virtual QArray<int> effectiveToDos( const QDate& start,
12 const QDate& end, 14 const QDate& end,
13 bool includeNoDates ) = 0; 15 bool includeNoDates ) = 0;
14 virtual QArray<int> overDue() = 0; 16 virtual QArray<int> overDue() = 0;
15 virtual QArray<int> sorted( bool asc, int sortOrder, int sortFilter, 17 virtual QArray<int> sorted( bool asc, int sortOrder, int sortFilter,
16 int cat ) = 0; 18 int cat ) = 0;
17 virtual void removeAllCompleted() = 0; 19 virtual void removeAllCompleted() = 0;
20 virtual QBitArray supports()const = 0;
18 21
19}; 22};
20 23
21#endif 24#endif
diff --git a/libopie2/opiepim/backend/otodoaccessvcal.cpp b/libopie2/opiepim/backend/otodoaccessvcal.cpp
index 2136283..9bc16c6 100644
--- a/libopie2/opiepim/backend/otodoaccessvcal.cpp
+++ b/libopie2/opiepim/backend/otodoaccessvcal.cpp
@@ -1,201 +1,221 @@
1#include <qfile.h> 1#include <qfile.h>
2 2
3#include <qtopia/private/vobject_p.h> 3#include <qtopia/private/vobject_p.h>
4#include <qtopia/timeconversion.h> 4#include <qtopia/timeconversion.h>
5#include <qtopia/private/qfiledirect_p.h> 5#include <qtopia/private/qfiledirect_p.h>
6 6
7#include "otodoaccessvcal.h" 7#include "otodoaccessvcal.h"
8 8
9namespace { 9namespace {
10 static OTodo eventByVObj( VObject *obj ){ 10 static OTodo eventByVObj( VObject *obj ){
11 OTodo event; 11 OTodo event;
12 VObject *ob; 12 VObject *ob;
13 QCString name; 13 QCString name;
14 // no uid, attendees, ... and no fun 14 // no uid, attendees, ... and no fun
15 // description 15 // description
16 if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){ 16 if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){
17 name = vObjectStringZValue( ob ); 17 name = vObjectStringZValue( ob );
18 event.setDescription( name ); 18 event.setDescription( name );
19 } 19 }
20 // summary 20 // summary
21 if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) { 21 if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) {
22 name = vObjectStringZValue( ob ); 22 name = vObjectStringZValue( ob );
23 event.setSummary( name ); 23 event.setSummary( name );
24 } 24 }
25 // completed 25 // completed
26 if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){ 26 if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){
27 name = vObjectStringZValue( ob ); 27 name = vObjectStringZValue( ob );
28 if( name == "COMPLETED" ){ 28 if( name == "COMPLETED" ){
29 event.setCompleted( true ); 29 event.setCompleted( true );
30 }else{ 30 }else{
31 event.setCompleted( false ); 31 event.setCompleted( false );
32 } 32 }
33 }else 33 }else
34 event.setCompleted( false ); 34 event.setCompleted( false );
35 // priority 35 // priority
36 if ((ob = isAPropertyOf(obj, VCPriorityProp))) { 36 if ((ob = isAPropertyOf(obj, VCPriorityProp))) {
37 name = vObjectStringZValue( ob ); 37 name = vObjectStringZValue( ob );
38 bool ok; 38 bool ok;
39 event.setPriority(name.toInt(&ok) ); 39 event.setPriority(name.toInt(&ok) );
40 } 40 }
41 //due date 41 //due date
42 if((ob = isAPropertyOf(obj, VCDueProp)) ){ 42 if((ob = isAPropertyOf(obj, VCDueProp)) ){
43 event.setHasDueDate( true ); 43 event.setHasDueDate( true );
44 name = vObjectStringZValue( ob ); 44 name = vObjectStringZValue( ob );
45 event.setDueDate( TimeConversion::fromISO8601( name).date() ); 45 event.setDueDate( TimeConversion::fromISO8601( name).date() );
46 } 46 }
47 // categories 47 // categories
48 if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){ 48 if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){
49 name = vObjectStringZValue( ob ); 49 name = vObjectStringZValue( ob );
50 qWarning("Categories:%s", name.data() ); 50 qWarning("Categories:%s", name.data() );
51 } 51 }
52 52
53 event.setUid( 1 ); 53 event.setUid( 1 );
54 return event; 54 return event;
55 }; 55 };
56 static VObject *vobjByEvent( const OTodo &event ) { 56 static VObject *vobjByEvent( const OTodo &event ) {
57 VObject *task = newVObject( VCTodoProp ); 57 VObject *task = newVObject( VCTodoProp );
58 if( task == 0 ) 58 if( task == 0 )
59 return 0l; 59 return 0l;
60 60
61 if( event.hasDueDate() ) { 61 if( event.hasDueDate() ) {
62 QTime time(0, 0, 0); 62 QTime time(0, 0, 0);
63 QDateTime date(event.dueDate(), time ); 63 QDateTime date(event.dueDate(), time );
64 addPropValue( task, VCDueProp, 64 addPropValue( task, VCDueProp,
65 TimeConversion::toISO8601( date ) ); 65 TimeConversion::toISO8601( date ) );
66 } 66 }
67 67
68 if( event.isCompleted() ) 68 if( event.isCompleted() )
69 addPropValue( task, VCStatusProp, "COMPLETED"); 69 addPropValue( task, VCStatusProp, "COMPLETED");
70 70
71 QString string = QString::number(event.priority() ); 71 QString string = QString::number(event.priority() );
72 addPropValue( task, VCPriorityProp, string.local8Bit() ); 72 addPropValue( task, VCPriorityProp, string.local8Bit() );
73 73
74 addPropValue( task, VCCategoriesProp, 74 addPropValue( task, VCCategoriesProp,
75 event.idsToString( event.categories() ).local8Bit() ); 75 event.idsToString( event.categories() ).local8Bit() );
76 76
77 addPropValue( task, VCDescriptionProp, 77 addPropValue( task, VCDescriptionProp,
78 event.description().local8Bit() ); 78 event.description().local8Bit() );
79 79
80 addPropValue( task, VCSummaryProp, 80 addPropValue( task, VCSummaryProp,
81 event.summary().local8Bit() ); 81 event.summary().local8Bit() );
82 return task; 82 return task;
83}; 83};
84} 84}
85 85
86OTodoAccessVCal::OTodoAccessVCal( const QString& path ) 86OTodoAccessVCal::OTodoAccessVCal( const QString& path )
87 : m_dirty(false), m_file( path ) 87 : m_dirty(false), m_file( path )
88{ 88{
89} 89}
90OTodoAccessVCal::~OTodoAccessVCal() { 90OTodoAccessVCal::~OTodoAccessVCal() {
91} 91}
92bool OTodoAccessVCal::load() { 92bool OTodoAccessVCal::load() {
93 m_map.clear(); 93 m_map.clear();
94 m_dirty = false; 94 m_dirty = false;
95 95
96 VObject* vcal = 0l; 96 VObject* vcal = 0l;
97 vcal = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); 97 vcal = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() );
98 if (!vcal ) 98 if (!vcal )
99 return false; 99 return false;
100 100
101 // Iterate over the list 101 // Iterate over the list
102 VObjectIterator it; 102 VObjectIterator it;
103 VObject* vobj; 103 VObject* vobj;
104 104
105 initPropIterator(&it, vcal); 105 initPropIterator(&it, vcal);
106 106
107 while( moreIteration( &it ) ) { 107 while( moreIteration( &it ) ) {
108 vobj = ::nextVObject( &it ); 108 vobj = ::nextVObject( &it );
109 QCString name = ::vObjectName( vobj ); 109 QCString name = ::vObjectName( vobj );
110 if( name == VCTodoProp ){ 110 if( name == VCTodoProp ){
111 OTodo to = eventByVObj( vobj ); 111 OTodo to = eventByVObj( vobj );
112 m_map.insert( to.uid(), to ); 112 m_map.insert( to.uid(), to );
113 } 113 }
114 } 114 }
115 115
116 // Should I do a delete vcal? 116 // Should I do a delete vcal?
117 117
118 return true; 118 return true;
119} 119}
120bool OTodoAccessVCal::reload() { 120bool OTodoAccessVCal::reload() {
121 return load(); 121 return load();
122} 122}
123bool OTodoAccessVCal::save() { 123bool OTodoAccessVCal::save() {
124 if (!m_dirty ) 124 if (!m_dirty )
125 return true; 125 return true;
126 126
127 QFileDirect file( m_file ); 127 QFileDirect file( m_file );
128 if (!file.open(IO_WriteOnly ) ) 128 if (!file.open(IO_WriteOnly ) )
129 return false; 129 return false;
130 130
131 VObject *obj; 131 VObject *obj;
132 obj = newVObject( VCCalProp ); 132 obj = newVObject( VCCalProp );
133 addPropValue( obj, VCVersionProp, "1.0" ); 133 addPropValue( obj, VCVersionProp, "1.0" );
134 VObject *vo; 134 VObject *vo;
135 for(QMap<int, OTodo>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ 135 for(QMap<int, OTodo>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){
136 vo = vobjByEvent( it.data() ); 136 vo = vobjByEvent( it.data() );
137 addVObjectProp(obj, vo ); 137 addVObjectProp(obj, vo );
138 } 138 }
139 writeVObject( file.directHandle(), obj ); 139 writeVObject( file.directHandle(), obj );
140 cleanVObject( obj ); 140 cleanVObject( obj );
141 cleanStrTbl(); 141 cleanStrTbl();
142 142
143 m_dirty = false; 143 m_dirty = false;
144 return true; 144 return true;
145} 145}
146void OTodoAccessVCal::clear() { 146void OTodoAccessVCal::clear() {
147 m_map.clear(); 147 m_map.clear();
148 m_dirty = true; 148 m_dirty = true;
149} 149}
150bool OTodoAccessVCal::add( const OTodo& to ) { 150bool OTodoAccessVCal::add( const OTodo& to ) {
151 m_map.insert( to.uid(), to ); 151 m_map.insert( to.uid(), to );
152 m_dirty = true; 152 m_dirty = true;
153 return true; 153 return true;
154} 154}
155bool OTodoAccessVCal::remove( int uid ) { 155bool OTodoAccessVCal::remove( int uid ) {
156 m_map.remove( uid ); 156 m_map.remove( uid );
157 m_dirty = true; 157 m_dirty = true;
158 return true; 158 return true;
159} 159}
160void OTodoAccessVCal::removeAllCompleted() { 160void OTodoAccessVCal::removeAllCompleted() {
161 for ( QMap<int, OTodo>::Iterator it = m_map.begin(); it != m_map.end(); ++it ) { 161 for ( QMap<int, OTodo>::Iterator it = m_map.begin(); it != m_map.end(); ++it ) {
162 if ( (*it).isCompleted() ) 162 if ( (*it).isCompleted() )
163 m_map.remove( it ); 163 m_map.remove( it );
164 } 164 }
165} 165}
166bool OTodoAccessVCal::replace( const OTodo& to ) { 166bool OTodoAccessVCal::replace( const OTodo& to ) {
167 m_map.replace( to.uid(), to ); 167 m_map.replace( to.uid(), to );
168 m_dirty = true; 168 m_dirty = true;
169 return true; 169 return true;
170} 170}
171OTodo OTodoAccessVCal::find(int uid )const { 171OTodo OTodoAccessVCal::find(int uid )const {
172 return m_map[uid]; 172 return m_map[uid];
173} 173}
174QArray<int> OTodoAccessVCal::sorted( bool, int, int, int ) { 174QArray<int> OTodoAccessVCal::sorted( bool, int, int, int ) {
175 QArray<int> ar(0); 175 QArray<int> ar(0);
176 return ar; 176 return ar;
177} 177}
178QArray<int> OTodoAccessVCal::allRecords()const { 178QArray<int> OTodoAccessVCal::allRecords()const {
179 QArray<int> ar( m_map.count() ); 179 QArray<int> ar( m_map.count() );
180 QMap<int, OTodo>::ConstIterator it; 180 QMap<int, OTodo>::ConstIterator it;
181 int i = 0; 181 int i = 0;
182 for ( it = m_map.begin(); it != m_map.end(); ++it ) { 182 for ( it = m_map.begin(); it != m_map.end(); ++it ) {
183 ar[i] = it.key(); 183 ar[i] = it.key();
184 i++; 184 i++;
185 } 185 }
186 return ar; 186 return ar;
187} 187}
188QArray<int> OTodoAccessVCal::queryByExample( const OTodo&, int, const QDateTime& ) { 188QArray<int> OTodoAccessVCal::queryByExample( const OTodo&, int, const QDateTime& ) {
189 QArray<int> ar(0); 189 QArray<int> ar(0);
190 return ar; 190 return ar;
191} 191}
192QArray<int> OTodoAccessVCal::effectiveToDos( const QDate& , 192QArray<int> OTodoAccessVCal::effectiveToDos( const QDate& ,
193 const QDate& , 193 const QDate& ,
194 bool ) { 194 bool ) {
195 QArray<int> ar(0); 195 QArray<int> ar(0);
196 return ar; 196 return ar;
197} 197}
198QArray<int> OTodoAccessVCal::overDue() { 198QArray<int> OTodoAccessVCal::overDue() {
199 QArray<int> ar(0); 199 QArray<int> ar(0);
200 return ar; 200 return ar;
201} 201}
202QBitArray OTodoAccessVCal::supports()const {
203 static QBitArray ar = sup();
204
205 return ar;
206}
207QBitArray OTodoAccessVCal::sup() {
208 QBitArray ar ( OTodo::CompletedDate +1 );
209 ar.fill( true );
210
211 ar[OTodo::CrossReference] = false;
212 ar[OTodo::State ] = false;
213 ar[OTodo::Reminders] = false;
214 ar[OTodo::Notifiers] = false;
215 ar[OTodo::Maintainer] = false;
216 ar[OTodo::Progress] = false;
217 ar[OTodo::Alarms ] = false;
218 ar[OTodo::Recurrence] = false;
219
220 return ar;
221}
diff --git a/libopie2/opiepim/backend/otodoaccessvcal.h b/libopie2/opiepim/backend/otodoaccessvcal.h
index a90ee9c..489416b 100644
--- a/libopie2/opiepim/backend/otodoaccessvcal.h
+++ b/libopie2/opiepim/backend/otodoaccessvcal.h
@@ -1,37 +1,39 @@
1#ifndef OPIE_OTODO_ACCESS_VCAL_H 1#ifndef OPIE_OTODO_ACCESS_VCAL_H
2#define OPIE_OTODO_ACCESS_VCAL_H 2#define OPIE_OTODO_ACCESS_VCAL_H
3 3
4#include "otodoaccessbackend.h" 4#include "otodoaccessbackend.h"
5 5
6class OTodoAccessVCal : public OTodoAccessBackend { 6class OTodoAccessVCal : public OTodoAccessBackend {
7public: 7public:
8 OTodoAccessVCal(const QString& ); 8 OTodoAccessVCal(const QString& );
9 ~OTodoAccessVCal(); 9 ~OTodoAccessVCal();
10 10
11 bool load(); 11 bool load();
12 bool reload(); 12 bool reload();
13 bool save(); 13 bool save();
14 14
15 QArray<int> allRecords()const; 15 QArray<int> allRecords()const;
16 QArray<int> queryByExample( const OTodo& t, int sort, const QDateTime& d = QDateTime() ); 16 QArray<int> queryByExample( const OTodo& t, int sort, const QDateTime& d = QDateTime() );
17 QArray<int> effectiveToDos( const QDate& start, 17 QArray<int> effectiveToDos( const QDate& start,
18 const QDate& end, 18 const QDate& end,
19 bool includeNoDates ); 19 bool includeNoDates );
20 QArray<int> overDue(); 20 QArray<int> overDue();
21 QArray<int> sorted( bool asc, int sortOrder, int sortFilter, 21 QArray<int> sorted( bool asc, int sortOrder, int sortFilter,
22 int cat ); 22 int cat );
23 OTodo find(int uid)const; 23 OTodo find(int uid)const;
24 void clear(); 24 void clear();
25 bool add( const OTodo& ); 25 bool add( const OTodo& );
26 bool remove( int uid ); 26 bool remove( int uid );
27 bool replace( const OTodo& ); 27 bool replace( const OTodo& );
28 28
29 void removeAllCompleted(); 29 void removeAllCompleted();
30 virtual QBitArray supports()const;
30 31
31private: 32private:
33 static QBitArray sup();
32 bool m_dirty : 1; 34 bool m_dirty : 1;
33 QString m_file; 35 QString m_file;
34 QMap<int, OTodo> m_map; 36 QMap<int, OTodo> m_map;
35}; 37};
36 38
37#endif 39#endif
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp
index 71e8787..55f268b 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.cpp
+++ b/libopie2/opiepim/backend/otodoaccessxml.cpp
@@ -1,675 +1,689 @@
1#include <errno.h> 1#include <errno.h>
2#include <fcntl.h> 2#include <fcntl.h>
3 3
4#include <sys/mman.h> 4#include <sys/mman.h>
5#include <sys/stat.h> 5#include <sys/stat.h>
6#include <sys/types.h> 6#include <sys/types.h>
7 7
8#include <unistd.h> 8#include <unistd.h>
9 9
10 10
11#include <qfile.h> 11#include <qfile.h>
12#include <qvector.h> 12#include <qvector.h>
13 13
14#include <qpe/global.h> 14#include <qpe/global.h>
15#include <qpe/stringutil.h> 15#include <qpe/stringutil.h>
16#include <qpe/timeconversion.h> 16#include <qpe/timeconversion.h>
17 17
18#include "otodoaccessxml.h" 18#include "otodoaccessxml.h"
19 19
20namespace { 20namespace {
21 // FROM TT again 21 // FROM TT again
22char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) 22char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
23{ 23{
24 char needleChar; 24 char needleChar;
25 char haystackChar; 25 char haystackChar;
26 if (!needle || !haystack || !hLen || !nLen) 26 if (!needle || !haystack || !hLen || !nLen)
27 return 0; 27 return 0;
28 28
29 const char* hsearch = haystack; 29 const char* hsearch = haystack;
30 30
31 if ((needleChar = *needle++) != 0) { 31 if ((needleChar = *needle++) != 0) {
32 nLen--; //(to make up for needle++) 32 nLen--; //(to make up for needle++)
33 do { 33 do {
34 do { 34 do {
35 if ((haystackChar = *hsearch++) == 0) 35 if ((haystackChar = *hsearch++) == 0)
36 return (0); 36 return (0);
37 if (hsearch >= haystack + hLen) 37 if (hsearch >= haystack + hLen)
38 return (0); 38 return (0);
39 } while (haystackChar != needleChar); 39 } while (haystackChar != needleChar);
40 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); 40 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
41 hsearch--; 41 hsearch--;
42 } 42 }
43 return ((char *)hsearch); 43 return ((char *)hsearch);
44} 44}
45} 45}
46 46
47 47
48OTodoAccessXML::OTodoAccessXML( const QString& appName, 48OTodoAccessXML::OTodoAccessXML( const QString& appName,
49 const QString& fileName ) 49 const QString& fileName )
50 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) 50 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
51{ 51{
52 if (!fileName.isEmpty() ) 52 if (!fileName.isEmpty() )
53 m_file = fileName; 53 m_file = fileName;
54 else 54 else
55 m_file = Global::applicationFileName( "todolist", "todolist.xml" ); 55 m_file = Global::applicationFileName( "todolist", "todolist.xml" );
56} 56}
57OTodoAccessXML::~OTodoAccessXML() { 57OTodoAccessXML::~OTodoAccessXML() {
58 58
59} 59}
60bool OTodoAccessXML::load() { 60bool OTodoAccessXML::load() {
61 m_opened = true; 61 m_opened = true;
62 m_changed = false; 62 m_changed = false;
63 /* initialize dict */ 63 /* initialize dict */
64 /* 64 /*
65 * UPDATE dict if you change anything!!! 65 * UPDATE dict if you change anything!!!
66 */ 66 */
67 QAsciiDict<int> dict(21); 67 QAsciiDict<int> dict(21);
68 dict.setAutoDelete( TRUE ); 68 dict.setAutoDelete( TRUE );
69 dict.insert("Categories" , new int(OTodo::Category) ); 69 dict.insert("Categories" , new int(OTodo::Category) );
70 dict.insert("Uid" , new int(OTodo::Uid) ); 70 dict.insert("Uid" , new int(OTodo::Uid) );
71 dict.insert("HasDate" , new int(OTodo::HasDate) ); 71 dict.insert("HasDate" , new int(OTodo::HasDate) );
72 dict.insert("Completed" , new int(OTodo::Completed) ); 72 dict.insert("Completed" , new int(OTodo::Completed) );
73 dict.insert("Description" , new int(OTodo::Description) ); 73 dict.insert("Description" , new int(OTodo::Description) );
74 dict.insert("Summary" , new int(OTodo::Summary) ); 74 dict.insert("Summary" , new int(OTodo::Summary) );
75 dict.insert("Priority" , new int(OTodo::Priority) ); 75 dict.insert("Priority" , new int(OTodo::Priority) );
76 dict.insert("DateDay" , new int(OTodo::DateDay) ); 76 dict.insert("DateDay" , new int(OTodo::DateDay) );
77 dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 77 dict.insert("DateMonth" , new int(OTodo::DateMonth) );
78 dict.insert("DateYear" , new int(OTodo::DateYear) ); 78 dict.insert("DateYear" , new int(OTodo::DateYear) );
79 dict.insert("Progress" , new int(OTodo::Progress) ); 79 dict.insert("Progress" , new int(OTodo::Progress) );
80 dict.insert("Completed", new int(OTodo::Completed) ); 80 dict.insert("Completed", new int(OTodo::Completed) );
81 dict.insert("CrossReference", new int(OTodo::CrossReference) ); 81 dict.insert("CrossReference", new int(OTodo::CrossReference) );
82 dict.insert("State", new int(OTodo::State) ); 82 dict.insert("State", new int(OTodo::State) );
83 dict.insert("Recurrence", new int(OTodo::Recurrence) ); 83 dict.insert("Recurrence", new int(OTodo::Recurrence) );
84 dict.insert("Alarms", new int(OTodo::Alarms) ); 84 dict.insert("Alarms", new int(OTodo::Alarms) );
85 dict.insert("Reminders", new int(OTodo::Reminders) ); 85 dict.insert("Reminders", new int(OTodo::Reminders) );
86 dict.insert("Notifiers", new int(OTodo::Notifiers) ); 86 dict.insert("Notifiers", new int(OTodo::Notifiers) );
87 dict.insert("Maintainer", new int(OTodo::Maintainer) ); 87 dict.insert("Maintainer", new int(OTodo::Maintainer) );
88 88
89 // here the custom XML parser from TT it's GPL 89 // here the custom XML parser from TT it's GPL
90 // but we want to push OpiePIM... to TT..... 90 // but we want to push OpiePIM... to TT.....
91 // mmap part from zecke :) 91 // mmap part from zecke :)
92 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); 92 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
93 struct stat attribut; 93 struct stat attribut;
94 if ( fd < 0 ) return false; 94 if ( fd < 0 ) return false;
95 95
96 if ( fstat(fd, &attribut ) == -1 ) { 96 if ( fstat(fd, &attribut ) == -1 ) {
97 ::close( fd ); 97 ::close( fd );
98 return false; 98 return false;
99 } 99 }
100 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 100 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
101 if ( map_addr == ( (caddr_t)-1) ) { 101 if ( map_addr == ( (caddr_t)-1) ) {
102 ::close(fd ); 102 ::close(fd );
103 return false; 103 return false;
104 } 104 }
105 /* advise the kernel who we want to read it */ 105 /* advise the kernel who we want to read it */
106 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); 106 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
107 /* we do not the file any more */ 107 /* we do not the file any more */
108 ::close( fd ); 108 ::close( fd );
109 109
110 char* dt = (char*)map_addr; 110 char* dt = (char*)map_addr;
111 int len = attribut.st_size; 111 int len = attribut.st_size;
112 int i = 0; 112 int i = 0;
113 char *point; 113 char *point;
114 const char* collectionString = "<Task "; 114 const char* collectionString = "<Task ";
115 int strLen = strlen(collectionString); 115 int strLen = strlen(collectionString);
116 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { 116 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) {
117 i = point -dt; 117 i = point -dt;
118 i+= strLen; 118 i+= strLen;
119 qWarning("Found a start at %d %d", i, (point-dt) ); 119 qWarning("Found a start at %d %d", i, (point-dt) );
120 120
121 OTodo ev; 121 OTodo ev;
122 m_year = m_month = m_day = 0; 122 m_year = m_month = m_day = 0;
123 123
124 while ( TRUE ) { 124 while ( TRUE ) {
125 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 125 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
126 ++i; 126 ++i;
127 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 127 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
128 break; 128 break;
129 129
130 // we have another attribute, read it. 130 // we have another attribute, read it.
131 int j = i; 131 int j = i;
132 while ( j < len && dt[j] != '=' ) 132 while ( j < len && dt[j] != '=' )
133 ++j; 133 ++j;
134 QCString attr( dt+i, j-i+1); 134 QCString attr( dt+i, j-i+1);
135 135
136 i = ++j; // skip = 136 i = ++j; // skip =
137 137
138 // find the start of quotes 138 // find the start of quotes
139 while ( i < len && dt[i] != '"' ) 139 while ( i < len && dt[i] != '"' )
140 ++i; 140 ++i;
141 j = ++i; 141 j = ++i;
142 142
143 bool haveUtf = FALSE; 143 bool haveUtf = FALSE;
144 bool haveEnt = FALSE; 144 bool haveEnt = FALSE;
145 while ( j < len && dt[j] != '"' ) { 145 while ( j < len && dt[j] != '"' ) {
146 if ( ((unsigned char)dt[j]) > 0x7f ) 146 if ( ((unsigned char)dt[j]) > 0x7f )
147 haveUtf = TRUE; 147 haveUtf = TRUE;
148 if ( dt[j] == '&' ) 148 if ( dt[j] == '&' )
149 haveEnt = TRUE; 149 haveEnt = TRUE;
150 ++j; 150 ++j;
151 } 151 }
152 if ( i == j ) { 152 if ( i == j ) {
153 // empty value 153 // empty value
154 i = j + 1; 154 i = j + 1;
155 continue; 155 continue;
156 } 156 }
157 157
158 QCString value( dt+i, j-i+1 ); 158 QCString value( dt+i, j-i+1 );
159 i = j + 1; 159 i = j + 1;
160 160
161 QString str = (haveUtf ? QString::fromUtf8( value ) 161 QString str = (haveUtf ? QString::fromUtf8( value )
162 : QString::fromLatin1( value ) ); 162 : QString::fromLatin1( value ) );
163 if ( haveEnt ) 163 if ( haveEnt )
164 str = Qtopia::plainString( str ); 164 str = Qtopia::plainString( str );
165 165
166 /* 166 /*
167 * add key + value 167 * add key + value
168 */ 168 */
169 todo( &dict, ev, attr, str ); 169 todo( &dict, ev, attr, str );
170 170
171 } 171 }
172 /* 172 /*
173 * now add it 173 * now add it
174 */ 174 */
175 qWarning("End at %d", i ); 175 qWarning("End at %d", i );
176 if (m_events.contains( ev.uid() ) || ev.uid() == 0) { 176 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
177 ev.setUid( 1 ); 177 ev.setUid( 1 );
178 m_changed = true; 178 m_changed = true;
179 } 179 }
180 if ( ev.hasDueDate() ) { 180 if ( ev.hasDueDate() ) {
181 ev.setDueDate( QDate(m_year, m_month, m_day) ); 181 ev.setDueDate( QDate(m_year, m_month, m_day) );
182 } 182 }
183 m_events.insert(ev.uid(), ev ); 183 m_events.insert(ev.uid(), ev );
184 m_year = m_month = m_day = -1; 184 m_year = m_month = m_day = -1;
185 } 185 }
186 186
187 munmap(map_addr, attribut.st_size ); 187 munmap(map_addr, attribut.st_size );
188 188
189 qWarning("counts %d records loaded!", m_events.count() ); 189 qWarning("counts %d records loaded!", m_events.count() );
190 return true; 190 return true;
191} 191}
192bool OTodoAccessXML::reload() { 192bool OTodoAccessXML::reload() {
193 m_events.clear(); 193 m_events.clear();
194 return load(); 194 return load();
195} 195}
196bool OTodoAccessXML::save() { 196bool OTodoAccessXML::save() {
197// qWarning("saving"); 197// qWarning("saving");
198 if (!m_opened || !m_changed ) { 198 if (!m_opened || !m_changed ) {
199// qWarning("not saving"); 199// qWarning("not saving");
200 return true; 200 return true;
201 } 201 }
202 QString strNewFile = m_file + ".new"; 202 QString strNewFile = m_file + ".new";
203 QFile f( strNewFile ); 203 QFile f( strNewFile );
204 if (!f.open( IO_WriteOnly|IO_Raw ) ) 204 if (!f.open( IO_WriteOnly|IO_Raw ) )
205 return false; 205 return false;
206 206
207 int written; 207 int written;
208 QString out; 208 QString out;
209 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 209 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
210 210
211 // for all todos 211 // for all todos
212 QMap<int, OTodo>::Iterator it; 212 QMap<int, OTodo>::Iterator it;
213 for (it = m_events.begin(); it != m_events.end(); ++it ) { 213 for (it = m_events.begin(); it != m_events.end(); ++it ) {
214 out+= "<Task " + toString( (*it) ) + " />\n"; 214 out+= "<Task " + toString( (*it) ) + " />\n";
215 QCString cstr = out.utf8(); 215 QCString cstr = out.utf8();
216 written = f.writeBlock( cstr.data(), cstr.length() ); 216 written = f.writeBlock( cstr.data(), cstr.length() );
217 217
218 /* less written then we wanted */ 218 /* less written then we wanted */
219 if ( written != (int)cstr.length() ) { 219 if ( written != (int)cstr.length() ) {
220 f.close(); 220 f.close();
221 QFile::remove( strNewFile ); 221 QFile::remove( strNewFile );
222 return false; 222 return false;
223 } 223 }
224 out = QString::null; 224 out = QString::null;
225 } 225 }
226 226
227 out += "</Tasks>"; 227 out += "</Tasks>";
228 QCString cstr = out.utf8(); 228 QCString cstr = out.utf8();
229 written = f.writeBlock( cstr.data(), cstr.length() ); 229 written = f.writeBlock( cstr.data(), cstr.length() );
230 230
231 if ( written != (int)cstr.length() ) { 231 if ( written != (int)cstr.length() ) {
232 f.close(); 232 f.close();
233 QFile::remove( strNewFile ); 233 QFile::remove( strNewFile );
234 return false; 234 return false;
235 } 235 }
236 /* flush before renaming */ 236 /* flush before renaming */
237 f.close(); 237 f.close();
238 238
239 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 239 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
240// qWarning("error renaming"); 240// qWarning("error renaming");
241 QFile::remove( strNewFile ); 241 QFile::remove( strNewFile );
242 } 242 }
243 243
244 m_changed = false; 244 m_changed = false;
245 return true; 245 return true;
246} 246}
247QArray<int> OTodoAccessXML::allRecords()const { 247QArray<int> OTodoAccessXML::allRecords()const {
248 QArray<int> ids( m_events.count() ); 248 QArray<int> ids( m_events.count() );
249 QMap<int, OTodo>::ConstIterator it; 249 QMap<int, OTodo>::ConstIterator it;
250 int i = 0; 250 int i = 0;
251 251
252 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 252 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
253 ids[i] = it.key(); 253 ids[i] = it.key();
254 i++; 254 i++;
255 } 255 }
256 return ids; 256 return ids;
257} 257}
258QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int, const QDateTime& ) { 258QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int, const QDateTime& ) {
259 QArray<int> ids(0); 259 QArray<int> ids(0);
260 return ids; 260 return ids;
261} 261}
262OTodo OTodoAccessXML::find( int uid )const { 262OTodo OTodoAccessXML::find( int uid )const {
263 OTodo todo; 263 OTodo todo;
264 todo.setUid( 0 ); // isEmpty() 264 todo.setUid( 0 ); // isEmpty()
265 QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); 265 QMap<int, OTodo>::ConstIterator it = m_events.find( uid );
266 if ( it != m_events.end() ) 266 if ( it != m_events.end() )
267 todo = it.data(); 267 todo = it.data();
268 268
269 return todo; 269 return todo;
270} 270}
271void OTodoAccessXML::clear() { 271void OTodoAccessXML::clear() {
272 if (m_opened ) 272 if (m_opened )
273 m_changed = true; 273 m_changed = true;
274 274
275 m_events.clear(); 275 m_events.clear();
276} 276}
277bool OTodoAccessXML::add( const OTodo& todo ) { 277bool OTodoAccessXML::add( const OTodo& todo ) {
278// qWarning("add"); 278// qWarning("add");
279 m_changed = true; 279 m_changed = true;
280 m_events.insert( todo.uid(), todo ); 280 m_events.insert( todo.uid(), todo );
281 281
282 return true; 282 return true;
283} 283}
284bool OTodoAccessXML::remove( int uid ) { 284bool OTodoAccessXML::remove( int uid ) {
285 m_changed = true; 285 m_changed = true;
286 m_events.remove( uid ); 286 m_events.remove( uid );
287 287
288 return true; 288 return true;
289} 289}
290bool OTodoAccessXML::replace( const OTodo& todo) { 290bool OTodoAccessXML::replace( const OTodo& todo) {
291 m_changed = true; 291 m_changed = true;
292 m_events.replace( todo.uid(), todo ); 292 m_events.replace( todo.uid(), todo );
293 293
294 return true; 294 return true;
295} 295}
296QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, 296QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
297 const QDate& end, 297 const QDate& end,
298 bool includeNoDates ) { 298 bool includeNoDates ) {
299 QArray<int> ids( m_events.count() ); 299 QArray<int> ids( m_events.count() );
300 QMap<int, OTodo>::Iterator it; 300 QMap<int, OTodo>::Iterator it;
301 301
302 int i = 0; 302 int i = 0;
303 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 303 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
304 if ( !it.data().hasDueDate() ) { 304 if ( !it.data().hasDueDate() ) {
305 if ( includeNoDates ) { 305 if ( includeNoDates ) {
306 ids[i] = it.key(); 306 ids[i] = it.key();
307 i++; 307 i++;
308 } 308 }
309 }else if ( it.data().dueDate() >= start && 309 }else if ( it.data().dueDate() >= start &&
310 it.data().dueDate() <= end ) { 310 it.data().dueDate() <= end ) {
311 ids[i] = it.key(); 311 ids[i] = it.key();
312 i++; 312 i++;
313 } 313 }
314 } 314 }
315 ids.resize( i ); 315 ids.resize( i );
316 return ids; 316 return ids;
317} 317}
318QArray<int> OTodoAccessXML::overDue() { 318QArray<int> OTodoAccessXML::overDue() {
319 QArray<int> ids( m_events.count() ); 319 QArray<int> ids( m_events.count() );
320 int i = 0; 320 int i = 0;
321 321
322 QMap<int, OTodo>::Iterator it; 322 QMap<int, OTodo>::Iterator it;
323 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 323 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
324 if ( it.data().isOverdue() ) { 324 if ( it.data().isOverdue() ) {
325 ids[i] = it.key(); 325 ids[i] = it.key();
326 i++; 326 i++;
327 } 327 }
328 } 328 }
329 ids.resize( i ); 329 ids.resize( i );
330 return ids; 330 return ids;
331} 331}
332 332
333 333
334/* private */ 334/* private */
335void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, 335void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
336 const QCString& attr, const QString& val) { 336 const QCString& attr, const QString& val) {
337// qWarning("parse to do from XMLElement" ); 337// qWarning("parse to do from XMLElement" );
338 338
339 int *find=0; 339 int *find=0;
340 340
341 find = (*dict)[ attr.data() ]; 341 find = (*dict)[ attr.data() ];
342 if (!find ) { 342 if (!find ) {
343// qWarning("Unknown option" + it.key() ); 343// qWarning("Unknown option" + it.key() );
344 ev.setCustomField( attr, val ); 344 ev.setCustomField( attr, val );
345 return; 345 return;
346 } 346 }
347 347
348 switch( *find ) { 348 switch( *find ) {
349 case OTodo::Uid: 349 case OTodo::Uid:
350 ev.setUid( val.toInt() ); 350 ev.setUid( val.toInt() );
351 break; 351 break;
352 case OTodo::Category: 352 case OTodo::Category:
353 ev.setCategories( ev.idsFromString( val ) ); 353 ev.setCategories( ev.idsFromString( val ) );
354 break; 354 break;
355 case OTodo::HasDate: 355 case OTodo::HasDate:
356 ev.setHasDueDate( val.toInt() ); 356 ev.setHasDueDate( val.toInt() );
357 break; 357 break;
358 case OTodo::Completed: 358 case OTodo::Completed:
359 ev.setCompleted( val.toInt() ); 359 ev.setCompleted( val.toInt() );
360 break; 360 break;
361 case OTodo::Description: 361 case OTodo::Description:
362 ev.setDescription( val ); 362 ev.setDescription( val );
363 break; 363 break;
364 case OTodo::Summary: 364 case OTodo::Summary:
365 ev.setSummary( val ); 365 ev.setSummary( val );
366 break; 366 break;
367 case OTodo::Priority: 367 case OTodo::Priority:
368 ev.setPriority( val.toInt() ); 368 ev.setPriority( val.toInt() );
369 break; 369 break;
370 case OTodo::DateDay: 370 case OTodo::DateDay:
371 m_day = val.toInt(); 371 m_day = val.toInt();
372 break; 372 break;
373 case OTodo::DateMonth: 373 case OTodo::DateMonth:
374 m_month = val.toInt(); 374 m_month = val.toInt();
375 break; 375 break;
376 case OTodo::DateYear: 376 case OTodo::DateYear:
377 m_year = val.toInt(); 377 m_year = val.toInt();
378 break; 378 break;
379 case OTodo::Progress: 379 case OTodo::Progress:
380 ev.setProgress( val.toInt() ); 380 ev.setProgress( val.toInt() );
381 break; 381 break;
382 case OTodo::CrossReference: 382 case OTodo::CrossReference:
383 { 383 {
384 /* 384 /*
385 * A cross refernce looks like 385 * A cross refernce looks like
386 * appname,id;appname,id 386 * appname,id;appname,id
387 * we need to split it up 387 * we need to split it up
388 */ 388 */
389 QStringList refs = QStringList::split(';', val ); 389 QStringList refs = QStringList::split(';', val );
390 QStringList::Iterator strIt; 390 QStringList::Iterator strIt;
391 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 391 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
392 int pos = (*strIt).find(','); 392 int pos = (*strIt).find(',');
393 if ( pos > -1 ) 393 if ( pos > -1 )
394 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 394 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
395 395
396 } 396 }
397 break; 397 break;
398 } 398 }
399 default: 399 default:
400 break; 400 break;
401 } 401 }
402} 402}
403QString OTodoAccessXML::toString( const OTodo& ev )const { 403QString OTodoAccessXML::toString( const OTodo& ev )const {
404 QString str; 404 QString str;
405 405
406 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 406 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
407 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 407 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
408 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 408 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
409 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 409 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
410 410
411 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 411 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
412 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 412 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
413 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 413 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
414 414
415 if ( ev.hasDueDate() ) { 415 if ( ev.hasDueDate() ) {
416 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 416 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
417 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 417 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
418 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 418 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
419 } 419 }
420// qWarning( "Uid %d", ev.uid() ); 420// qWarning( "Uid %d", ev.uid() );
421 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 421 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
422 422
423// append the extra options 423// append the extra options
424 /* FIXME Qtopia::Record this is currently not 424 /* FIXME Qtopia::Record this is currently not
425 * possible you can set custom fields 425 * possible you can set custom fields
426 * but don' iterate over the list 426 * but don' iterate over the list
427 * I may do #define private protected 427 * I may do #define private protected
428 * for this case - cough --zecke 428 * for this case - cough --zecke
429 */ 429 */
430 /* 430 /*
431 QMap<QString, QString> extras = ev.extras(); 431 QMap<QString, QString> extras = ev.extras();
432 QMap<QString, QString>::Iterator extIt; 432 QMap<QString, QString>::Iterator extIt;
433 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 433 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
434 str += extIt.key() + "=\"" + extIt.data() + "\" "; 434 str += extIt.key() + "=\"" + extIt.data() + "\" ";
435 */ 435 */
436 // cross refernce 436 // cross refernce
437 437
438 438
439 return str; 439 return str;
440} 440}
441QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 441QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
442 return Qtopia::Record::idsToString( ints ); 442 return Qtopia::Record::idsToString( ints );
443} 443}
444 444
445/* internal class for sorting 445/* internal class for sorting
446 * 446 *
447 * Inspired by todoxmlio.cpp from TT 447 * Inspired by todoxmlio.cpp from TT
448 */ 448 */
449 449
450struct OTodoXMLContainer { 450struct OTodoXMLContainer {
451 OTodo todo; 451 OTodo todo;
452}; 452};
453 453
454namespace { 454namespace {
455 inline QString string( const OTodo& todo) { 455 inline QString string( const OTodo& todo) {
456 return todo.summary().isEmpty() ? 456 return todo.summary().isEmpty() ?
457 todo.description().left(20 ) : 457 todo.description().left(20 ) :
458 todo.summary(); 458 todo.summary();
459 } 459 }
460 inline int completed( const OTodo& todo1, const OTodo& todo2) { 460 inline int completed( const OTodo& todo1, const OTodo& todo2) {
461 int ret = 0; 461 int ret = 0;
462 if ( todo1.isCompleted() ) ret++; 462 if ( todo1.isCompleted() ) ret++;
463 if ( todo2.isCompleted() ) ret--; 463 if ( todo2.isCompleted() ) ret--;
464 return ret; 464 return ret;
465 } 465 }
466 inline int priority( const OTodo& t1, const OTodo& t2) { 466 inline int priority( const OTodo& t1, const OTodo& t2) {
467 return ( t1.priority() - t2.priority() ); 467 return ( t1.priority() - t2.priority() );
468 } 468 }
469 inline int description( const OTodo& t1, const OTodo& t2) { 469 inline int description( const OTodo& t1, const OTodo& t2) {
470 return QString::compare( string(t1), string(t2) ); 470 return QString::compare( string(t1), string(t2) );
471 } 471 }
472 inline int deadline( const OTodo& t1, const OTodo& t2) { 472 inline int deadline( const OTodo& t1, const OTodo& t2) {
473 int ret = 0; 473 int ret = 0;
474 if ( t1.hasDueDate() && 474 if ( t1.hasDueDate() &&
475 t2.hasDueDate() ) 475 t2.hasDueDate() )
476 ret = t2.dueDate().daysTo( t1.dueDate() ); 476 ret = t2.dueDate().daysTo( t1.dueDate() );
477 else if ( t1.hasDueDate() ) 477 else if ( t1.hasDueDate() )
478 ret = -1; 478 ret = -1;
479 else if ( t2.hasDueDate() ) 479 else if ( t2.hasDueDate() )
480 ret = 1; 480 ret = 1;
481 else 481 else
482 ret = 0; 482 ret = 0;
483 483
484 return ret; 484 return ret;
485 } 485 }
486 486
487}; 487};
488 488
489/* 489/*
490 * Returns: 490 * Returns:
491 * 0 if item1 == item2 491 * 0 if item1 == item2
492 * 492 *
493 * non-zero if item1 != item2 493 * non-zero if item1 != item2
494 * 494 *
495 * This function returns int rather than bool so that reimplementations 495 * This function returns int rather than bool so that reimplementations
496 * can return one of three values and use it to sort by: 496 * can return one of three values and use it to sort by:
497 * 497 *
498 * 0 if item1 == item2 498 * 0 if item1 == item2
499 * 499 *
500 * > 0 (positive integer) if item1 > item2 500 * > 0 (positive integer) if item1 > item2
501 * 501 *
502 * < 0 (negative integer) if item1 < item2 502 * < 0 (negative integer) if item1 < item2
503 * 503 *
504 */ 504 */
505class OTodoXMLVector : public QVector<OTodoXMLContainer> { 505class OTodoXMLVector : public QVector<OTodoXMLContainer> {
506public: 506public:
507 OTodoXMLVector(int size, bool asc, int sort) 507 OTodoXMLVector(int size, bool asc, int sort)
508 : QVector<OTodoXMLContainer>( size ) 508 : QVector<OTodoXMLContainer>( size )
509 { 509 {
510 setAutoDelete( true ); 510 setAutoDelete( true );
511 m_asc = asc; 511 m_asc = asc;
512 m_sort = sort; 512 m_sort = sort;
513 } 513 }
514 /* return the summary/description */ 514 /* return the summary/description */
515 QString string( const OTodo& todo) { 515 QString string( const OTodo& todo) {
516 return todo.summary().isEmpty() ? 516 return todo.summary().isEmpty() ?
517 todo.description().left(20 ) : 517 todo.description().left(20 ) :
518 todo.summary(); 518 todo.summary();
519 } 519 }
520 /** 520 /**
521 * we take the sortorder( switch on it ) 521 * we take the sortorder( switch on it )
522 * 522 *
523 */ 523 */
524 int compareItems( Item d1, Item d2 ) { 524 int compareItems( Item d1, Item d2 ) {
525 bool seComp, sePrio, seDesc, seDeadline; 525 bool seComp, sePrio, seDesc, seDeadline;
526 seComp = sePrio = seDeadline = seDesc = false; 526 seComp = sePrio = seDeadline = seDesc = false;
527 int ret =0; 527 int ret =0;
528 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; 528 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
529 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; 529 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
530 530
531 /* same item */ 531 /* same item */
532 if ( con1->todo.uid() == con2->todo.uid() ) 532 if ( con1->todo.uid() == con2->todo.uid() )
533 return 0; 533 return 0;
534 534
535 switch ( m_sort ) { 535 switch ( m_sort ) {
536 /* completed */ 536 /* completed */
537 case 0: { 537 case 0: {
538 ret = completed( con1->todo, con2->todo ); 538 ret = completed( con1->todo, con2->todo );
539 seComp = TRUE; 539 seComp = TRUE;
540 break; 540 break;
541 } 541 }
542 /* priority */ 542 /* priority */
543 case 1: { 543 case 1: {
544 ret = priority( con1->todo, con2->todo ); 544 ret = priority( con1->todo, con2->todo );
545 sePrio = TRUE; 545 sePrio = TRUE;
546 break; 546 break;
547 } 547 }
548 /* description */ 548 /* description */
549 case 2: { 549 case 2: {
550 ret = description( con1->todo, con2->todo ); 550 ret = description( con1->todo, con2->todo );
551 seDesc = TRUE; 551 seDesc = TRUE;
552 break; 552 break;
553 } 553 }
554 /* deadline */ 554 /* deadline */
555 case 3: { 555 case 3: {
556 ret = deadline( con1->todo, con2->todo ); 556 ret = deadline( con1->todo, con2->todo );
557 seDeadline = TRUE; 557 seDeadline = TRUE;
558 break; 558 break;
559 } 559 }
560 default: 560 default:
561 ret = 0; 561 ret = 0;
562 break; 562 break;
563 }; 563 };
564 /* 564 /*
565 * FIXME do better sorting if the first sort criteria 565 * FIXME do better sorting if the first sort criteria
566 * ret equals 0 start with complete and so on... 566 * ret equals 0 start with complete and so on...
567 */ 567 */
568 568
569 /* twist it we're not ascending*/ 569 /* twist it we're not ascending*/
570 if (!m_asc) 570 if (!m_asc)
571 ret = ret * -1; 571 ret = ret * -1;
572 572
573 if ( ret ) 573 if ( ret )
574 return ret; 574 return ret;
575 575
576 // default did not gave difference let's try it other way around 576 // default did not gave difference let's try it other way around
577 /* 577 /*
578 * General try if already checked if not test 578 * General try if already checked if not test
579 * and return 579 * and return
580 * 1.Completed 580 * 1.Completed
581 * 2.Priority 581 * 2.Priority
582 * 3.Description 582 * 3.Description
583 * 4.DueDate 583 * 4.DueDate
584 */ 584 */
585 if (!seComp ) { 585 if (!seComp ) {
586 if ( (ret = completed( con1->todo, con2->todo ) ) ) { 586 if ( (ret = completed( con1->todo, con2->todo ) ) ) {
587 if (!m_asc ) ret *= -1; 587 if (!m_asc ) ret *= -1;
588 return ret; 588 return ret;
589 } 589 }
590 } 590 }
591 if (!sePrio ) { 591 if (!sePrio ) {
592 if ( (ret = priority( con1->todo, con2->todo ) ) ) { 592 if ( (ret = priority( con1->todo, con2->todo ) ) ) {
593 if (!m_asc ) ret *= -1; 593 if (!m_asc ) ret *= -1;
594 return ret; 594 return ret;
595 } 595 }
596 } 596 }
597 if (!seDesc ) { 597 if (!seDesc ) {
598 if ( (ret = description(con1->todo, con2->todo ) ) ) { 598 if ( (ret = description(con1->todo, con2->todo ) ) ) {
599 if (!m_asc) ret *= -1; 599 if (!m_asc) ret *= -1;
600 return ret; 600 return ret;
601 } 601 }
602 } 602 }
603 if (!seDeadline) { 603 if (!seDeadline) {
604 if ( (ret = deadline( con1->todo, con2->todo ) ) ) { 604 if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
605 if (!m_asc) ret *= -1; 605 if (!m_asc) ret *= -1;
606 return ret; 606 return ret;
607 } 607 }
608 } 608 }
609 609
610 return 0; 610 return 0;
611 } 611 }
612 private: 612 private:
613 bool m_asc; 613 bool m_asc;
614 int m_sort; 614 int m_sort;
615 615
616}; 616};
617 617
618QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, 618QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder,
619 int sortFilter, int cat ) { 619 int sortFilter, int cat ) {
620 qWarning("sorted! %d cat", cat); 620 qWarning("sorted! %d cat", cat);
621 OTodoXMLVector vector(m_events.count(), asc,sortOrder ); 621 OTodoXMLVector vector(m_events.count(), asc,sortOrder );
622 QMap<int, OTodo>::Iterator it; 622 QMap<int, OTodo>::Iterator it;
623 int item = 0; 623 int item = 0;
624 624
625 bool bCat = sortFilter & 1 ? true : false; 625 bool bCat = sortFilter & 1 ? true : false;
626 bool bOnly = sortFilter & 2 ? true : false; 626 bool bOnly = sortFilter & 2 ? true : false;
627 bool comp = sortFilter & 4 ? true : false; 627 bool comp = sortFilter & 4 ? true : false;
628 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 628 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
629 629
630 /* show category */ 630 /* show category */
631 if ( bCat && cat != 0) 631 if ( bCat && cat != 0)
632 if (!(*it).categories().contains( cat ) ) { 632 if (!(*it).categories().contains( cat ) ) {
633 qWarning("category mis match"); 633 qWarning("category mis match");
634 continue; 634 continue;
635 } 635 }
636 /* isOverdue but we should not show overdue - why?*/ 636 /* isOverdue but we should not show overdue - why?*/
637/* if ( (*it).isOverdue() && !bOnly ) { 637/* if ( (*it).isOverdue() && !bOnly ) {
638 qWarning("item is overdue but !bOnly"); 638 qWarning("item is overdue but !bOnly");
639 continue; 639 continue;
640 } 640 }
641*/ 641*/
642 if ( !(*it).isOverdue() && bOnly ) { 642 if ( !(*it).isOverdue() && bOnly ) {
643 qWarning("item is not overdue but bOnly checked"); 643 qWarning("item is not overdue but bOnly checked");
644 continue; 644 continue;
645 } 645 }
646 646
647 if ((*it).isCompleted() && comp ) { 647 if ((*it).isCompleted() && comp ) {
648 qWarning("completed continue!"); 648 qWarning("completed continue!");
649 continue; 649 continue;
650 } 650 }
651 651
652 652
653 OTodoXMLContainer* con = new OTodoXMLContainer(); 653 OTodoXMLContainer* con = new OTodoXMLContainer();
654 con->todo = (*it); 654 con->todo = (*it);
655 vector.insert(item, con ); 655 vector.insert(item, con );
656 item++; 656 item++;
657 } 657 }
658 qWarning("XXX %d Items added", item); 658 qWarning("XXX %d Items added", item);
659 vector.resize( item ); 659 vector.resize( item );
660 /* sort it now */ 660 /* sort it now */
661 vector.sort(); 661 vector.sort();
662 /* now get the uids */ 662 /* now get the uids */
663 QArray<int> array( vector.count() ); 663 QArray<int> array( vector.count() );
664 for (uint i= 0; i < vector.count(); i++ ) { 664 for (uint i= 0; i < vector.count(); i++ ) {
665 array[i] = ( vector.at(i) )->todo.uid(); 665 array[i] = ( vector.at(i) )->todo.uid();
666 } 666 }
667 qWarning("array count = %d %d", array.count(), vector.count() );
668 return array; 667 return array;
669}; 668};
670void OTodoAccessXML::removeAllCompleted() { 669void OTodoAccessXML::removeAllCompleted() {
671 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { 670 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
672 if ( (*it).isCompleted() ) 671 if ( (*it).isCompleted() )
673 m_events.remove( it ); 672 m_events.remove( it );
674 } 673 }
675} 674}
675QBitArray OTodoAccessXML::supports()const {
676 static QBitArray ar = sup();
677 return ar;
678}
679QBitArray OTodoAccessXML::sup() {
680 QBitArray ar( OTodo::CompletedDate +1 );
681 ar.fill( true );
682 ar[OTodo::CrossReference] = false;
683 ar[OTodo::State ] = false;
684 ar[OTodo::Reminders] = false;
685 ar[OTodo::Notifiers] = false;
686 ar[OTodo::Maintainer] = false;
687
688 return ar;
689}
diff --git a/libopie2/opiepim/backend/otodoaccessxml.h b/libopie2/opiepim/backend/otodoaccessxml.h
index 1032c92..cc4a16f 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.h
+++ b/libopie2/opiepim/backend/otodoaccessxml.h
@@ -1,57 +1,59 @@
1#ifndef OPIE_TODO_ACCESS_XML_H 1#ifndef OPIE_TODO_ACCESS_XML_H
2#define OPIE_TODO_ACCESS_XML_H 2#define OPIE_TODO_ACCESS_XML_H
3 3
4#include <qasciidict.h> 4#include <qasciidict.h>
5#include <qmap.h> 5#include <qmap.h>
6 6
7#include "otodoaccessbackend.h" 7#include "otodoaccessbackend.h"
8 8
9namespace Opie { 9namespace Opie {
10 class XMLElement; 10 class XMLElement;
11}; 11};
12 12
13class OTodoAccessXML : public OTodoAccessBackend { 13class OTodoAccessXML : public OTodoAccessBackend {
14public: 14public:
15 /** 15 /**
16 * fileName if Empty we will use the default path 16 * fileName if Empty we will use the default path
17 */ 17 */
18 OTodoAccessXML( const QString& appName, 18 OTodoAccessXML( const QString& appName,
19 const QString& fileName = QString::null ); 19 const QString& fileName = QString::null );
20 ~OTodoAccessXML(); 20 ~OTodoAccessXML();
21 21
22 bool load(); 22 bool load();
23 bool reload(); 23 bool reload();
24 bool save(); 24 bool save();
25 25
26 QArray<int> allRecords()const; 26 QArray<int> allRecords()const;
27 QArray<int> queryByExample( const OTodo&, int querysettings, const QDateTime& d = QDateTime() ); 27 QArray<int> queryByExample( const OTodo&, int querysettings, const QDateTime& d = QDateTime() );
28 OTodo find( int uid )const; 28 OTodo find( int uid )const;
29 void clear(); 29 void clear();
30 bool add( const OTodo& ); 30 bool add( const OTodo& );
31 bool remove( int uid ); 31 bool remove( int uid );
32 void removeAllCompleted(); 32 void removeAllCompleted();
33 bool replace( const OTodo& ); 33 bool replace( const OTodo& );
34 34
35 /* our functions */ 35 /* our functions */
36 QArray<int> effectiveToDos( const QDate& start, 36 QArray<int> effectiveToDos( const QDate& start,
37 const QDate& end, 37 const QDate& end,
38 bool includeNoDates ); 38 bool includeNoDates );
39 QArray<int> overDue(); 39 QArray<int> overDue();
40 QArray<int> sorted( bool asc, int sortOrder, 40 QArray<int> sorted( bool asc, int sortOrder,
41 int sortFilter, int cat ); 41 int sortFilter, int cat );
42 QBitArray supports()const;
42private: 43private:
44 static QBitArray sup();
43 void todo( QAsciiDict<int>*, OTodo&,const QCString&,const QString& ); 45 void todo( QAsciiDict<int>*, OTodo&,const QCString&,const QString& );
44 QString toString( const OTodo& )const; 46 QString toString( const OTodo& )const;
45 QString toString( const QArray<int>& ints ) const; 47 QString toString( const QArray<int>& ints ) const;
46 QMap<int, OTodo> m_events; 48 QMap<int, OTodo> m_events;
47 QString m_file; 49 QString m_file;
48 QString m_app; 50 QString m_app;
49 bool m_opened : 1; 51 bool m_opened : 1;
50 bool m_changed : 1; 52 bool m_changed : 1;
51 class OTodoAccessXMLPrivate; 53 class OTodoAccessXMLPrivate;
52 OTodoAccessXMLPrivate* d; 54 OTodoAccessXMLPrivate* d;
53 int m_year, m_month, m_day; 55 int m_year, m_month, m_day;
54 56
55}; 57};
56 58
57#endif 59#endif
diff --git a/libopie2/opiepim/core/otodoaccess.cpp b/libopie2/opiepim/core/otodoaccess.cpp
index 5e89a1b..37f6fbc 100644
--- a/libopie2/opiepim/core/otodoaccess.cpp
+++ b/libopie2/opiepim/core/otodoaccess.cpp
@@ -1,56 +1,62 @@
1#include <qdatetime.h> 1#include <qdatetime.h>
2 2
3#include <qpe/alarmserver.h> 3#include <qpe/alarmserver.h>
4 4
5// #include "otodoaccesssql.h" 5// #include "otodoaccesssql.h"
6#include "otodoaccess.h" 6#include "otodoaccess.h"
7#include "obackendfactory.h" 7#include "obackendfactory.h"
8 8
9OTodoAccess::OTodoAccess( OTodoAccessBackend* end, enum Access ) 9OTodoAccess::OTodoAccess( OTodoAccessBackend* end, enum Access )
10 : QObject(), OPimAccessTemplate<OTodo>( end ), m_todoBackEnd( end ) 10 : QObject(), OPimAccessTemplate<OTodo>( end ), m_todoBackEnd( end )
11{ 11{
12// if (end == 0l ) 12// if (end == 0l )
13// m_todoBackEnd = new OTodoAccessBackendSQL( QString::null); 13// m_todoBackEnd = new OTodoAccessBackendSQL( QString::null);
14 14
15 // Zecke: Du musst hier noch für das XML-Backend einen Appnamen übergeben ! 15 // Zecke: Du musst hier noch für das XML-Backend einen Appnamen übergeben !
16 if (end == 0l ) 16 if (end == 0l )
17 m_todoBackEnd = OBackendFactory<OTodoAccessBackend>::Default ("todo", QString::null); 17 m_todoBackEnd = OBackendFactory<OTodoAccessBackend>::Default ("todo", QString::null);
18 18
19 setBackEnd( m_todoBackEnd ); 19 setBackEnd( m_todoBackEnd );
20} 20}
21OTodoAccess::~OTodoAccess() { 21OTodoAccess::~OTodoAccess() {
22// qWarning("~OTodoAccess"); 22// qWarning("~OTodoAccess");
23} 23}
24void OTodoAccess::mergeWith( const QValueList<OTodo>& list ) { 24void OTodoAccess::mergeWith( const QValueList<OTodo>& list ) {
25 QValueList<OTodo>::ConstIterator it; 25 QValueList<OTodo>::ConstIterator it;
26 for ( it = list.begin(); it != list.end(); ++it ) { 26 for ( it = list.begin(); it != list.end(); ++it ) {
27 replace( (*it) ); 27 replace( (*it) );
28 } 28 }
29} 29}
30OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start, 30OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start,
31 const QDate& end, 31 const QDate& end,
32 bool includeNoDates ) { 32 bool includeNoDates ) {
33 QArray<int> ints = m_todoBackEnd->effectiveToDos( start, end, includeNoDates ); 33 QArray<int> ints = m_todoBackEnd->effectiveToDos( start, end, includeNoDates );
34 34
35 List lis( ints, this ); 35 List lis( ints, this );
36 return lis; 36 return lis;
37} 37}
38OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start, 38OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start,
39 bool includeNoDates ) { 39 bool includeNoDates ) {
40 return effectiveToDos( start, QDate::currentDate(), 40 return effectiveToDos( start, QDate::currentDate(),
41 includeNoDates ); 41 includeNoDates );
42} 42}
43OTodoAccess::List OTodoAccess::overDue() { 43OTodoAccess::List OTodoAccess::overDue() {
44 List lis( m_todoBackEnd->overDue(), this ); 44 List lis( m_todoBackEnd->overDue(), this );
45 return lis; 45 return lis;
46} 46}
47/* sort order */ 47/* sort order */
48OTodoAccess::List OTodoAccess::sorted( bool ascending, int sort,int filter, int cat ) { 48OTodoAccess::List OTodoAccess::sorted( bool ascending, int sort,int filter, int cat ) {
49 QArray<int> ints = m_todoBackEnd->sorted( ascending, sort, 49 QArray<int> ints = m_todoBackEnd->sorted( ascending, sort,
50 filter, cat ); 50 filter, cat );
51 OTodoAccess::List list( ints, this ); 51 OTodoAccess::List list( ints, this );
52 return list; 52 return list;
53} 53}
54void OTodoAccess::removeAllCompleted() { 54void OTodoAccess::removeAllCompleted() {
55 m_todoBackEnd->removeAllCompleted(); 55 m_todoBackEnd->removeAllCompleted();
56} 56}
57QBitArray OTodoAccess::backendSupport( const QString& ) const{
58 return m_todoBackEnd->supports();
59}
60bool OTodoAccess::backendSupports( int attr, const QString& ar) const{
61 return backendSupport(ar).testBit( attr );
62}
diff --git a/libopie2/opiepim/core/otodoaccess.h b/libopie2/opiepim/core/otodoaccess.h
index a626731..916923f 100644
--- a/libopie2/opiepim/core/otodoaccess.h
+++ b/libopie2/opiepim/core/otodoaccess.h
@@ -1,90 +1,105 @@
1#ifndef OPIE_TODO_ACCESS_H 1#ifndef OPIE_TODO_ACCESS_H
2#define OPIE_TODO_ACCESS_H 2#define OPIE_TODO_ACCESS_H
3 3
4#include <qobject.h> 4#include <qobject.h>
5#include <qvaluelist.h> 5#include <qvaluelist.h>
6 6
7#include "otodo.h" 7#include "otodo.h"
8#include "otodoaccessbackend.h" 8#include "otodoaccessbackend.h"
9#include "opimaccesstemplate.h" 9#include "opimaccesstemplate.h"
10 10
11 11
12/** 12/**
13 * OTodoAccess 13 * OTodoAccess
14 * the class to get access to 14 * the class to get access to
15 * the todolist 15 * the todolist
16 */ 16 */
17class OTodoAccess : public QObject, public OPimAccessTemplate<OTodo> { 17class OTodoAccess : public QObject, public OPimAccessTemplate<OTodo> {
18 Q_OBJECT 18 Q_OBJECT
19public: 19public:
20 enum SortOrder { Completed = 0, 20 enum SortOrder { Completed = 0,
21 Priority, 21 Priority,
22 Description, 22 Description,
23 Deadline }; 23 Deadline };
24 enum SortFilter{ Category =1, 24 enum SortFilter{ Category =1,
25 OnlyOverDue= 2, 25 OnlyOverDue= 2,
26 DoNotShowCompleted =4 }; 26 DoNotShowCompleted =4 };
27 /** 27 /**
28 * if you use 0l 28 * if you use 0l
29 * the default resource will be 29 * the default resource will be
30 * picked up 30 * picked up
31 */ 31 */
32 OTodoAccess( OTodoAccessBackend* = 0l, enum Access acc = Random ); 32 OTodoAccess( OTodoAccessBackend* = 0l, enum Access acc = Random );
33 ~OTodoAccess(); 33 ~OTodoAccess();
34 34
35 35
36 /* our functions here */ 36 /* our functions here */
37 /** 37 /**
38 * include todos from start to end 38 * include todos from start to end
39 * includeNoDates whether or not to include 39 * includeNoDates whether or not to include
40 * events with no dates 40 * events with no dates
41 */ 41 */
42 List effectiveToDos( const QDate& start, 42 List effectiveToDos( const QDate& start,
43 const QDate& end, 43 const QDate& end,
44 bool includeNoDates = true ); 44 bool includeNoDates = true );
45 45
46 /** 46 /**
47 * start 47 * start
48 * end date taken from the currentDate() 48 * end date taken from the currentDate()
49 */ 49 */
50 List effectiveToDos( const QDate& start, 50 List effectiveToDos( const QDate& start,
51 bool includeNoDates = true ); 51 bool includeNoDates = true );
52 52
53 53
54 /** 54 /**
55 * return overdue OTodos 55 * return overdue OTodos
56 */ 56 */
57 List overDue(); 57 List overDue();
58 58
59 /** 59 /**
60 * 60 *
61 */ 61 */
62 List sorted( bool ascending, int sortOrder, int sortFilter, int cat ); 62 List sorted( bool ascending, int sortOrder, int sortFilter, int cat );
63 63
64 /** 64 /**
65 * merge a list of OTodos into 65 * merge a list of OTodos into
66 * the resource 66 * the resource
67 */ 67 */
68 void mergeWith( const QValueList<OTodo>& ); 68 void mergeWith( const QValueList<OTodo>& );
69 69
70 /** 70 /**
71 * delete all already completed items 71 * delete all already completed items
72 */ 72 */
73 void removeAllCompleted(); 73 void removeAllCompleted();
74 74
75 /**
76 * request information about what a backend supports.
77 * Supports in the sense of beeing able to store.
78 * This is related to the enum in OTodo
79 *
80 * @param backend Will be used in the future when we support multiple backend
81 */
82 QBitArray backendSupport( const QString& backend = QString::null )const;
83
84 /**
85 * see above but for a specefic attribute. This method was added for convience
86 * @param attr The attribute to be queried for
87 * @param backend Will be used in the future when we support multiple backends
88 */
89 bool backendSupports( int attr, const QString& backend = QString::null )const;
75signals: 90signals:
76 /** 91 /**
77 * if the OTodoAccess was changed 92 * if the OTodoAccess was changed
78 */ 93 */
79 void changed( const OTodoAccess* ); 94 void changed( const OTodoAccess* );
80 void changed( const OTodoAccess*, int uid ); 95 void changed( const OTodoAccess*, int uid );
81 void added( const OTodoAccess*, int uid ); 96 void added( const OTodoAccess*, int uid );
82 void removed( const OTodoAccess*, int uid ); 97 void removed( const OTodoAccess*, int uid );
83private: 98private:
84 int m_cat; 99 int m_cat;
85 OTodoAccessBackend* m_todoBackEnd; 100 OTodoAccessBackend* m_todoBackEnd;
86 class OTodoAccessPrivate; 101 class OTodoAccessPrivate;
87 OTodoAccessPrivate* d; 102 OTodoAccessPrivate* d;
88}; 103};
89 104
90#endif 105#endif