summaryrefslogtreecommitdiff
authorzecke <zecke>2002-09-20 12:59:29 (UTC)
committer zecke <zecke>2002-09-20 12:59:29 (UTC)
commita05c10c9744020be31c3038b2de3401b5cc673fb (patch) (unidiff)
tree20d059bf00fc1199c34a60a8be4cb842ebfe4d14
parent7099778ab711f78cfd86dadad1b8af993e008f38 (diff)
downloadopie-a05c10c9744020be31c3038b2de3401b5cc673fb.zip
opie-a05c10c9744020be31c3038b2de3401b5cc673fb.tar.gz
opie-a05c10c9744020be31c3038b2de3401b5cc673fb.tar.bz2
Our new common template based start for Accessing and Manipulating
the Records The CROSS_REFERENCE branch will get ported to it. We use templates for several reasons They allow us to share code and to be easily extended I've to make them not inline to save memory... I've to port all DBs and Record related classes
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--libopie/pim/opimaccessbackend.h29
-rw-r--r--libopie/pim/opimaccesstemplate.h82
-rw-r--r--libopie/pim/opimrecord.cpp90
-rw-r--r--libopie/pim/opimrecord.h117
-rw-r--r--libopie/pim/orecordlist.h44
-rw-r--r--libopie/pim/otodo.cpp507
-rw-r--r--libopie/pim/otodo.h205
-rw-r--r--libopie2/opiepim/backend/opimaccessbackend.h29
-rw-r--r--libopie2/opiepim/core/opimaccesstemplate.h82
-rw-r--r--libopie2/opiepim/core/opimrecord.cpp90
-rw-r--r--libopie2/opiepim/core/opimrecord.h117
-rw-r--r--libopie2/opiepim/orecordlist.h44
-rw-r--r--libopie2/opiepim/otodo.cpp507
-rw-r--r--libopie2/opiepim/otodo.h205
14 files changed, 2148 insertions, 0 deletions
diff --git a/libopie/pim/opimaccessbackend.h b/libopie/pim/opimaccessbackend.h
new file mode 100644
index 0000000..d9af589
--- a/dev/null
+++ b/libopie/pim/opimaccessbackend.h
@@ -0,0 +1,29 @@
1#ifndef OPIE_PIM_ACCESS_BACKEND
2#define OPIE_PIM_ACCESS_BACKEND
3
4#include <qarray.h>
5
6#include <opie/opimrecord.h>
7
8template <class T = OPimRecord>
9class OPimAccessBackend {
10public:
11 OPimAccessBackend() {
12 }
13 ~OPimAccessBackend() {
14 }
15 virtual void load() = 0;
16 virtual void reload() = 0;
17 virtual void save() = 0;
18 virtual QArray<int> allRecords() = 0;
19 virtual QArray<int> queryByExample( const T& t, int sort ) = 0;
20 virtual T find(int uid ) = 0;
21 virtual void clear() = 0;
22 virtual bool add( const T& t ) = 0;
23 virtual bool remove( int uid ) = 0;
24 virtual void replace( const T& t ) = 0;
25
26
27};
28
29#endif
diff --git a/libopie/pim/opimaccesstemplate.h b/libopie/pim/opimaccesstemplate.h
new file mode 100644
index 0000000..f2a241d
--- a/dev/null
+++ b/libopie/pim/opimaccesstemplate.h
@@ -0,0 +1,82 @@
1#ifndef OPIE_PIM_ACCESS_TEMPLATE_H
2#define OPIE_PIM_ACCESS_TEMPLATE_H
3
4#include <qarray.h>
5
6#include <opie/opimrecord.h>
7#include <opie/opimaccessbackend.h>
8#include <opie/orecordlist.h>
9
10template <class T = OPimRecord >
11class OPimAccessTemplate {
12public:
13 typedef ORecordList<T> List;
14 typedef OPimAccessBackend<T> BackEnd;
15 OPimAccessTemplate( BackEnd* end)
16 : m_backEnd( end ) {
17 }
18 ~OPimAccessTemplate() {
19 delete m_backEnd;
20 }
21 virtual void load() {
22 m_backEnd->load();
23 }
24 virtual void reload() {
25 m_backEnd->reload();
26 }
27 virtual void save() {
28 m_backEnd->save();
29 }
30
31 /*
32 *do array to Records conversion
33 * QArray<int> ids
34 */
35 virtual List allRecords()const {
36 QArray<int> ints = m_backEnd->allRecords();
37
38 List lis( ints, this );
39 return lis;
40 }
41 virtual List queryByExample( const T& t, int sortOrder ) {
42 QArray<int> ints = m_backEnd->query( t, sortOrder );
43 List lis( ints, this );
44
45 return lis;
46 }
47 /* implement QCache here */
48 virtual T find( int uid ) {
49 T t = m_backEnd->find( uid );
50 return t;
51 }
52
53 /* invalidate cache here */
54 virtual void clear() {
55 invalidateCache();
56 m_backEnd->clear();
57 }
58 virtual bool add( const T& t ) {
59 return m_backEnd->add( t );
60 }
61
62 /* only the uid matters */
63 virtual bool remove( const T& t ) {
64 /* remove from cache */
65 return m_backEnd->remove( t.uid() );
66 }
67 virtual bool remove( int uid ) {
68 /* remove from cache */
69 return m_backEnd->remove(uid);
70 }
71 virtual bool replace( const T& t) {
72 return m_backEnd->replace( t );
73 }
74protected:
75 void invalidateCache() {
76
77 }
78 BackEnd* m_backEnd;
79
80};
81
82#endif
diff --git a/libopie/pim/opimrecord.cpp b/libopie/pim/opimrecord.cpp
new file mode 100644
index 0000000..95de1df
--- a/dev/null
+++ b/libopie/pim/opimrecord.cpp
@@ -0,0 +1,90 @@
1#include "opimrecord.h"
2
3OPimRecord::OPimRecord( int uid )
4 : Qtopia::Record() {
5 setUid( uid );
6 if ( uid == 1 )
7 assignUid();
8}
9OPimRecord::~OPimRecord() {
10}
11OPimRecord::OPimRecord( OPimRecord& rec )
12 : Qtopia::Record( rec )
13{
14 (*this) = rec;
15}
16
17OPimRecord &OPimRecord::operator=( const OPimRecord& rec) {
18 /* how do I call the parent copy operator ? */
19 setUid( rec.uid() );
20 setCategories( rec.categories() );
21 return *this;
22}
23QStringList OPimRecord::categoryNames()const {
24 QStringList list;
25
26 return list;
27}
28void OPimRecord::setCategoryName( const QStringList& ) {
29
30}
31void OPimRecord::addCategoryName( const QString& ) {
32
33}
34bool OPimRecord::isEmpty()const {
35 return ( uid() == 0 );
36}
37QStringList OPimRecord::relatedApps()const{
38 QStringList list;
39 QMap<QString, QArray<int> >::ConstIterator it;
40 for ( it = m_relations.begin(); it != m_relations.end(); ++it ) {
41 list << it.key();
42 }
43 return list;
44}
45QArray<int> OPimRecord::relations(const QString& app )const {
46 QArray<int> tmp;
47 QMap<QString, QArray<int> >::ConstIterator it;
48 it = m_relations.find( app);
49 if ( it != m_relations.end() )
50 tmp = it.data();
51 return tmp;
52}
53void OPimRecord::clearRelation( const QString& app ) {
54 m_relations.remove( app );
55}
56void OPimRecord::addRelation( const QString& app, int id ) {
57
58 QMap<QString, QArray<int> >::Iterator it;
59 QArray<int> tmp;
60
61 it = m_relations.find( app );
62 if ( it == m_relations.end() ) {
63 tmp.resize(1 );
64 tmp[0] = id;
65 }else{
66 tmp = it.data();
67 tmp.resize( tmp.size() + 1 );
68 tmp[tmp.size() - 1] = id;
69 }
70 m_relations.replace( app, tmp );
71}
72void OPimRecord::setRelations( const QString& app, QArray<int> ids ) {
73
74 QMap<QString, QArray<int> >::Iterator it;
75 QArray<int> tmp;
76
77 it = m_relations.find( app);
78 if ( it == m_relations.end() ) {
79 tmp = ids;
80 }else{
81 tmp = it.data();
82 int offset = tmp.size()-1;
83 tmp.resize( tmp.size() + ids.size() );
84 for (uint i = 0; i < ids.size(); i++ ) {
85 tmp[offset+i] = ids[i];
86 }
87
88 }
89 m_relations.replace( app, tmp );
90}
diff --git a/libopie/pim/opimrecord.h b/libopie/pim/opimrecord.h
new file mode 100644
index 0000000..a0e0413
--- a/dev/null
+++ b/libopie/pim/opimrecord.h
@@ -0,0 +1,117 @@
1#ifndef OPIE_PIM_RECORD_H
2#define OPIE_PIM_RECORD_H
3
4#include <qmap.h>
5#include <qstring.h>
6#include <qstringlist.h>
7
8#include <qpe/palmtoprecord.h>
9
10class OPimRecord : public Qtopia::Record {
11public:
12 /**
13 * uid of 0 isEmpty
14 * uid of 1 will be assigned a new one
15 */
16 OPimRecord(int uid = 0);
17 ~OPimRecord();
18
19 /**
20 * copy c'tor
21 */
22 OPimRecord( OPimRecord& rec );
23
24 /**
25 * copy operator
26 */
27 OPimRecord &operator=( const OPimRecord& );
28
29 /**
30 * category names resolved
31 */
32 QStringList categoryNames()const;
33
34 /**
35 * set category names they will be resolved
36 */
37 void setCategoryName( const QStringList& );
38
39 /**
40 * addCategoryName adds a name
41 * to the internal category list
42 */
43 void addCategoryName( const QString& );
44
45 /**
46 * if a Record isEmpty
47 */
48 virtual bool isEmpty()const;
49
50 /**
51 * toRichText summary
52 */
53 virtual QString toRichText()const = 0;
54
55 /**
56 * a small one line summary
57 */
58 virtual QString toShortText()const = 0;
59
60 /**
61 * the name of the Record
62 */
63 virtual QString type()const = 0;
64
65 /**
66 * converts the internal structure to a map
67 */
68 virtual QMap<int, QString> toMap()const = 0;
69
70 /**
71 * key value representation of extra items
72 */
73 virtual QMap<QString, QString> toExtraMap()const = 0;
74
75 /**
76 * the name for a recordField
77 */
78 virtual QString recordField(int)const = 0;
79
80 /**
81 * the related apps names
82 */
83 QStringList relatedApps()const;
84
85 /**
86 * the realtions between an app
87 */
88 QArray<int> relations( const QString& app )const;
89
90 /**
91 *
92 */
93 void clearRelation( const QString& app );
94
95 /**
96 *
97 */
98 void addRelation( const QString& app, int id );
99
100 /**
101 *
102 */
103 void setRelations( const QString&, QArray<int> ids );
104
105protected:
106 QString crossToString()const;
107
108private:
109 class OPimRecordPrivate;
110 OPimRecordPrivate *d;
111 QMap<QString, QArray<int> > m_relations;
112
113};
114
115
116
117#endif
diff --git a/libopie/pim/orecordlist.h b/libopie/pim/orecordlist.h
new file mode 100644
index 0000000..c17186f
--- a/dev/null
+++ b/libopie/pim/orecordlist.h
@@ -0,0 +1,44 @@
1
2#ifndef OPIE_RECORD_LIST_H
3#define OPIE_RECORD_LIST_H
4
5#include <opie/opimaccesstemplate.h>
6#include <opie/opimrecord.h>
7
8template <class T = OPimRecord >
9class ORecordList {
10public:
11 class Iterator {
12 friend class ORecordList;
13 public:
14 Iterator() {}
15 ~Iterator() {}
16 Iterator(const Iterator& ) {}
17 Iterator &operator=(const Iterator& );
18 T &operator*() {}
19 Iterator &operator++();
20
21 bool operator==( const Iterator& it );
22 bool operator!=( const Iterator& it );
23
24 }
25 ORecordList( const QArray<int>& ids,
26 OPimAccessTemplate<T>* acc )
27 : m_ids(ids ), m_acc( acc ) {
28
29 }
30 ~ORecordList() {
31
32 }
33 Iterator begin();
34 Iterator end();
35 /*
36 ConstIterator begin()const;
37 ConstIterator end()const;
38 */
39private:
40 QArray<int> ids;
41 OPimAccessTemplate<T>* m_acc;
42};
43
44#endif
diff --git a/libopie/pim/otodo.cpp b/libopie/pim/otodo.cpp
new file mode 100644
index 0000000..d8e0447
--- a/dev/null
+++ b/libopie/pim/otodo.cpp
@@ -0,0 +1,507 @@
1
2#include <qobject.h>
3#include <qshared.h>
4
5
6
7#include <qpe/palmtopuidgen.h>
8#include <qpe/stringutil.h>
9#include <qpe/palmtoprecord.h>
10#include <qpe/stringutil.h>
11#include <qpe/categories.h>
12#include <qpe/categoryselect.h>
13
14#include "todoevent.h"
15
16using namespace Opie;
17
18Qtopia::UidGen ToDoEvent::m_gen;
19
20struct ToDoEvent::ToDoEventData : public QShared {
21 ToDoEventData() : QShared() {
22 };
23
24 QDate date;
25 bool isCompleted:1;
26 bool hasDate:1;
27 int priority;
28 QStringList category;
29 QString desc;
30 QString sum;
31 QMap<QString, QString> extra;
32 QMap<QString, QArray<int> > relations;
33 int uid;
34 ushort prog;
35 bool hasAlarmDateTime :1;
36 QDateTime alarmDateTime;
37};
38
39ToDoEvent::ToDoEvent(const ToDoEvent &event )
40 : data( event.data )
41{
42 data->ref();
43 //qWarning("ref up");
44}
45ToDoEvent::~ToDoEvent() {
46 if ( data->deref() ) {
47 //qWarning("ToDoEvent::dereffing");
48 delete data;
49 data = 0l;
50 }
51}
52
53ToDoEvent::ToDoEvent(bool completed, int priority,
54 const QStringList &category,
55 const QString& summary,
56 const QString &description,
57 ushort progress,
58 bool hasDate, QDate date, int uid )
59{
60 //qWarning("ToDoEventData");
61 data = new ToDoEventData;
62 data->date = date;
63 data->isCompleted = completed;
64 data->hasDate = hasDate;
65 data->priority = priority;
66 data->category = category;
67 data->sum = summary;
68 data->prog = progress;
69 data->desc = Qtopia::simplifyMultiLineSpace(description );
70 if (uid == -1 ) {
71 uid = m_gen.generate();
72
73 }// generated the ids
74 m_gen.store( uid );
75
76 data->uid = uid;
77 data->hasAlarmDateTime = false;
78
79}
80QArray<int> ToDoEvent::categories()const
81{
82 qWarning( "ToDoEvent:cats" + data->category.join(";") );
83 QArray<int> array(data->category.count() ); // currently the datebook can be only in one category
84 array = Qtopia::Record::idsFromString( data->category.join(";") );
85 return array;
86}
87bool ToDoEvent::match( const QRegExp &regExp )const
88{
89 if( QString::number( data->priority ).find( regExp ) != -1 ){
90 return true;
91 }else if( data->hasDate && data->date.toString().find( regExp) != -1 ){
92 return true;
93 }else if(data->desc.find( regExp ) != -1 ){
94 return true;
95 }
96 return false;
97}
98bool ToDoEvent::isCompleted() const
99{
100 return data->isCompleted;
101}
102bool ToDoEvent::hasDueDate() const
103{
104 return data->hasDate;
105}
106bool ToDoEvent::hasAlarmDateTime() const
107{
108 return data->hasAlarmDateTime;
109}
110int ToDoEvent::priority()const
111{
112 return data->priority;
113}
114QStringList ToDoEvent::allCategories()const
115{
116 return data->category;
117}
118QString ToDoEvent::extra(const QString& )const
119{
120 return QString::null;
121}
122QString ToDoEvent::summary() const
123{
124 return data->sum;
125}
126ushort ToDoEvent::progress() const
127{
128 return data->prog;
129}
130QStringList ToDoEvent::relatedApps() const
131{
132 QStringList list;
133 QMap<QString, QArray<int> >::ConstIterator it;
134 for ( it = data->relations.begin(); it != data->relations.end(); ++it ) {
135 list << it.key();
136 }
137 return list;
138}
139QArray<int> ToDoEvent::relations( const QString& app)const
140{
141 QArray<int> tmp;
142 QMap<QString, QArray<int> >::ConstIterator it;
143 it = data->relations.find( app);
144 if ( it != data->relations.end() )
145 tmp = it.data();
146 return tmp;
147}
148void ToDoEvent::insertCategory(const QString &str )
149{
150 changeOrModify();
151 qWarning("insert category;" + str );
152 data->category.append( str );
153}
154void ToDoEvent::clearCategories()
155{
156 changeOrModify();
157 data->category.clear();
158}
159void ToDoEvent::setCategories(const QStringList &list )
160{
161 changeOrModify();
162 qWarning("set categories" + list.join(";") );
163 data->category = list;
164}
165QDate ToDoEvent::dueDate()const
166{
167 return data->date;
168}
169
170QDateTime ToDoEvent::alarmDateTime() const
171{
172 return data->alarmDateTime;
173}
174
175QString ToDoEvent::description()const
176{
177 return data->desc;
178}
179void ToDoEvent::setCompleted( bool completed )
180{
181 changeOrModify();
182 data->isCompleted = completed;
183}
184void ToDoEvent::setHasDueDate( bool hasDate )
185{
186 changeOrModify();
187 data->hasDate = hasDate;
188}
189void ToDoEvent::setHasAlarmDateTime( bool hasAlarmDateTime )
190{
191 changeOrModify();
192 data->hasAlarmDateTime = hasAlarmDateTime;
193}
194void ToDoEvent::setDescription(const QString &desc )
195{
196 changeOrModify();
197 data->desc = Qtopia::simplifyMultiLineSpace(desc );
198}
199void ToDoEvent::setExtra( const QString&, const QString& )
200{
201
202}
203void ToDoEvent::setSummary( const QString& sum )
204{
205 changeOrModify();
206 data->sum = sum;
207}
208void ToDoEvent::setCategory( const QString &cat )
209{
210 changeOrModify();
211 //qWarning("setCategory %s", cat.latin1() );
212 data->category.clear();
213 data->category << cat;
214}
215void ToDoEvent::setPriority(int prio )
216{
217 changeOrModify();
218 data->priority = prio;
219}
220void ToDoEvent::setDueDate( QDate date )
221{
222 changeOrModify();
223 data->date = date;
224}
225void ToDoEvent::setAlarmDateTime( const QDateTime& alarm )
226{
227 changeOrModify();
228 data->alarmDateTime = alarm;
229}
230void ToDoEvent::addRelated( const QString &app, int id )
231{
232 changeOrModify();
233
234 QMap<QString, QArray<int> >::Iterator it;
235 QArray<int> tmp;
236 it = data->relations.find( app );
237 if ( it == data->relations.end() ) {
238 tmp.resize(1 );
239 tmp[0] = id;
240 }else{
241 tmp = it.data();
242 tmp.resize( tmp.size() + 1 );
243 tmp[tmp.size() - 1] = id;
244 }
245 data->relations.replace( app, tmp );
246}
247void ToDoEvent::addRelated(const QString& app, QArray<int> ids )
248{
249 changeOrModify();
250
251 QMap<QString, QArray<int> >::Iterator it;
252 QArray<int> tmp;
253 it = data->relations.find( app);
254 if ( it == data->relations.end() ) { // not there
255 /** tmp.resize( ids.size() ); stupid??
256 */
257 tmp = ids;
258 }else{
259 tmp = it.data();
260 int offset = tmp.size()-1;
261 tmp.resize( tmp.size() + ids.size() );
262 for (uint i = 0; i < ids.size(); i++ ) {
263 tmp[offset+i] = ids[i];
264 }
265
266 }
267 data->relations.replace( app, tmp );
268}
269void ToDoEvent::clearRelated( const QString& app )
270{
271 changeOrModify();
272 data->relations.remove( app );
273}
274bool ToDoEvent::isOverdue( )
275{
276 if( data->hasDate )
277 return QDate::currentDate() > data->date;
278 return false;
279}
280void ToDoEvent::setProgress(ushort progress )
281{
282 changeOrModify();
283 data->prog = progress;
284}
285/*!
286 Returns a richt text string
287*/
288QString ToDoEvent::richText() const
289{
290 QString text;
291 QStringList catlist;
292
293 // Description of the todo
294 if ( !summary().isEmpty() ) {
295 text += "<b>" + QObject::tr( "Summary:") + "</b><br>";
296 text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
297 }
298 if( !description().isEmpty() ){
299 text += "<b>" + QObject::tr( "Description:" ) + "</b><br>";
300 text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) ;
301 }
302 text += "<br><br><br>";
303
304 text += "<b>" + QObject::tr( "Priority:") +" </b>"
305 + QString::number( priority() ) + " <br>";
306 text += "<b>" + QObject::tr( "Progress:") + " </b>"
307 + QString::number( progress() ) + " %<br>";
308 if (hasDueDate() ){
309 text += "<b>" + QObject::tr( "Deadline:") + " </b>";
310 text += dueDate().toString();
311 text += "<br>";
312 }
313 if (hasAlarmDateTime() ){
314 text += "<b>" + QObject::tr( "Alarmed Notification:") + " </b>";
315 text += alarmDateTime().toString();
316 text += "<br>";
317 }
318
319 // Open database of all categories and get the list of
320 // the categories this todoevent belongs to.
321 // Then print them...
322 // I am not sure whether there is no better way doing this !?
323 Categories catdb;
324 bool firstloop = true;
325 catdb.load( categoryFileName() );
326 catlist = allCategories();
327
328 text += "<b>" + QObject::tr( "Category:") + "</b> ";
329 for ( QStringList::Iterator it = catlist.begin(); it != catlist.end(); ++it ) {
330 if (!firstloop){
331 text += ", ";
332 }
333 firstloop = false;
334 text += catdb.label ("todo", (*it).toInt());
335 }
336 text += "<br>";
337 return text;
338}
339
340bool ToDoEvent::operator<( const ToDoEvent &toDoEvent )const{
341 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
342 if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
343 if( hasDueDate() && toDoEvent.hasDueDate() ){
344 if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
345 return priority() < toDoEvent.priority();
346 }else{
347 return dueDate() < toDoEvent.dueDate();
348 }
349 }
350 return false;
351}
352bool ToDoEvent::operator<=(const ToDoEvent &toDoEvent )const
353{
354 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
355 if( !hasDueDate() && toDoEvent.hasDueDate() ) return true;
356 if( hasDueDate() && toDoEvent.hasDueDate() ){
357 if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
358 return priority() <= toDoEvent.priority();
359 }else{
360 return dueDate() <= toDoEvent.dueDate();
361 }
362 }
363 return true;
364}
365bool ToDoEvent::operator>(const ToDoEvent &toDoEvent )const
366{
367 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return false;
368 if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
369 if( hasDueDate() && toDoEvent.hasDueDate() ){
370 if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
371 return priority() > toDoEvent.priority();
372 }else{
373 return dueDate() > toDoEvent.dueDate();
374 }
375 }
376 return false;
377}
378bool ToDoEvent::operator>=(const ToDoEvent &toDoEvent )const
379{
380 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
381 if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
382 if( hasDueDate() && toDoEvent.hasDueDate() ){
383 if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
384 return priority() > toDoEvent.priority();
385 }else{
386 return dueDate() > toDoEvent.dueDate();
387 }
388 }
389 return true;
390}
391bool ToDoEvent::operator==(const ToDoEvent &toDoEvent )const
392{
393 if( data->priority == toDoEvent.data->priority &&
394 data->priority == toDoEvent.data->prog &&
395 data->isCompleted == toDoEvent.data->isCompleted &&
396 data->hasDate == toDoEvent.data->hasDate &&
397 data->date == toDoEvent.data->date &&
398 data->category == toDoEvent.data->category &&
399 data->sum == toDoEvent.data->sum &&
400 data->desc == toDoEvent.data->desc &&
401 data->hasAlarmDateTime == toDoEvent.data->hasAlarmDateTime &&
402 data->alarmDateTime == toDoEvent.data->alarmDateTime )
403 return true;
404
405 return false;
406}
407void ToDoEvent::deref() {
408
409 //qWarning("deref in ToDoEvent");
410 if ( data->deref() ) {
411 //qWarning("deleting");
412 delete data;
413 d= 0;
414 }
415}
416ToDoEvent &ToDoEvent::operator=(const ToDoEvent &item )
417{
418 //qWarning("operator= ref ");
419 item.data->ref();
420 deref();
421
422 data = item.data;
423
424
425 return *this;
426}
427
428QMap<int, QString> ToDoEvent::toMap() const {
429 QMap<int, QString> map;
430
431 map.insert( Uid, QString::number( data->uid ) );
432 map.insert( Category, data->category.join(";") );
433 map.insert( HasDate, QString::number( data->hasDate ) );
434 map.insert( Completed, QString::number( data->isCompleted ) );
435 map.insert( Description, data->desc );
436 map.insert( Summary, data->sum );
437 map.insert( Priority, QString::number( data->priority ) );
438 map.insert( DateDay, QString::number( data->date.day() ) );
439 map.insert( DateMonth, QString::number( data->date.month() ) );
440 map.insert( DateYear, QString::number( data->date.year() ) );
441 map.insert( Progress, QString::number( data->prog ) );
442 map.insert( CrossReference, crossToString() );
443 map.insert( HasAlarmDateTime, QString::number( data->hasAlarmDateTime ) );
444 map.insert( AlarmDateTime, data->alarmDateTime.toString() );
445
446 return map;
447}
448
449
450QString ToDoEvent::crossToString()const {
451 QString str;
452 QMap<QString, QArray<int> >::ConstIterator it;
453 for (it = data->relations.begin(); it != data->relations.end(); ++it ) {
454 QArray<int> id = it.data();
455 for ( uint i = 0; i < id.size(); ++i ) {
456 str += it.key() + "," + QString::number( i ) + ";";
457 }
458 }
459 str = str.remove( str.length()-1, 1); // strip the ;
460 //qWarning("IDS " + str );
461
462 return str;
463}
464int ToDoEvent::uid()const {
465 return data->uid;
466}
467void ToDoEvent::setUid( int id ) {
468 if ( id == -1 )
469 id = m_gen.generate();
470 m_gen.store(id );
471 changeOrModify();
472 data->uid = id;
473}
474QMap<QString, QString> ToDoEvent::extras()const {
475 return data->extra;
476}
477/**
478 * change or modify looks at the ref count and either
479 * creates a new QShared Object or it can modify it
480 * right in place
481 */
482void ToDoEvent::changeOrModify() {
483 if ( data->count != 1 ) {
484 //qWarning("changeOrModify");
485 data->deref();
486 ToDoEventData* d2 = new ToDoEventData();
487 copy(data, d2 );
488 data = d2;
489 }
490}
491void ToDoEvent::copy( ToDoEventData* src, ToDoEventData* dest ) {
492 dest->date = src->date;
493 dest->isCompleted = src->isCompleted;
494 dest->hasDate = src->hasDate;
495 dest->priority = src->priority;
496 dest->category = src->category;
497 dest->desc = src->desc;
498 dest->sum = src->sum;
499 dest->extra = src->extra;
500 dest->relations = src->relations;
501 dest->uid = src->uid;
502 dest->prog = src->prog;
503 dest->hasAlarmDateTime = src->hasAlarmDateTime;
504 dest->alarmDateTime = src->alarmDateTime;
505}
506
507
diff --git a/libopie/pim/otodo.h b/libopie/pim/otodo.h
new file mode 100644
index 0000000..429108a
--- a/dev/null
+++ b/libopie/pim/otodo.h
@@ -0,0 +1,205 @@
1
2#ifndef OPIE_TODO_EVENT_H
3#define OPIE_TODO_EVENT_H
4
5
6#include <qarray.h>
7#include <qmap.h>
8#include <qregexp.h>
9#include <qstringlist.h>
10#include <qdatetime.h>
11#include <qvaluelist.h>
12
13#include <qpe/recordfields.h>
14#include <qpe/palmtopuidgen.h>
15
16#include <opie/opimrecord.h>
17
18
19class OTodo : public OPimRecord {
20public:
21 typedef QValueList<ToDoEvent> ValueList;
22 enum RecordFields {
23 Uid = Qtopia::UID_ID,
24 Category = Qtopia::CATEGORY_ID,
25 HasDate,
26 Completed,
27 Description,
28 Summary,
29 Priority,
30 DateDay,
31 DateMonth,
32 DateYear,
33 Progress,
34 CrossReference,
35 HasAlarmDateTime,
36 AlarmDateTime
37 };
38 public:
39 // priorities from Very low to very high
40 enum TaskPriority { VeryHigh=1, High, Normal, Low, VeryLow };
41
42 /* Constructs a new ToDoEvent
43 @param completed Is the TodoEvent completed
44 @param priority What is the priority of this ToDoEvent
45 @param category Which category does it belong( uid )
46 @param summary A small summary of the todo
47 @param description What is this ToDoEvent about
48 @param hasDate Does this Event got a deadline
49 @param date what is the deadline?
50 @param uid what is the UUID of this Event
51 **/
52 OTodo( bool completed = false, int priority = Normal,
53 const QStringList &category = QStringList(),
54 const QString &summary = QString::null ,
55 const QString &description = QString::null,
56 ushort progress = 0,
57 bool hasDate = false, QDate date = QDate::currentDate(),
58 int uid = -1 );
59
60 /* Copy c'tor
61
62 **/
63 OTodo(const OTodo & );
64
65 /**
66 *destructor
67 */
68 ~OTodo();
69
70 /**
71 * Is this event completed?
72 */
73 bool isCompleted() const;
74
75 /**
76 * Does this Event have a deadline
77 */
78 bool hasDueDate() const;
79
80 /**
81 * Does this Event has an alarm time ?
82 */
83 bool hasAlarmDateTime() const;
84
85 /**
86 * What is the priority?
87 */
88 int priority()const ;
89
90 /**
91 * progress as ushort 0, 20, 40, 60, 80 or 100%
92 */
93 ushort progress() const;
94
95 /**
96 * The due Date
97 */
98 QDate dueDate()const;
99
100 /**
101 * Alarm Date and Time
102 */
103 QDateTime alarmDateTime()const;
104
105 /**
106 * The description of the todo
107 */
108 QString description()const;
109
110 /**
111 * A small summary of the todo
112 */
113 QString summary() const;
114
115 /**
116 * @reimplemented
117 * Return this todoevent in a RichText formatted QString
118 */
119 QString toRichText() const;
120
121
122 /**
123 * returns a list of apps which have related items
124 */
125 QStringList relatedApps()const;
126
127 /**
128 * returns all relations for one app
129 */
130 QArray<int> relations( const QString& app )const;
131
132 /**
133 * toMap puts all data into the map. int relates
134 * to ToDoEvent RecordFields enum
135 */
136 QMap<int, QString> toMap()const;
137
138 /**
139 * Set if this Todo is completed
140 */
141 void setCompleted(bool completed );
142
143 /**
144 * set if this todo got an end data
145 */
146 void setHasDueDate( bool hasDate );
147
148 /**
149 * set if this todo has an alarm time and date
150 */
151 void setHasAlarmDateTime ( bool hasAlarm );
152
153 /**
154 * Set the priority of the Todo
155 */
156 void setPriority(int priority );
157
158 /**
159 * Set the progress.
160 */
161 void setProgress( ushort progress );
162
163 /**
164 * set the end date
165 */
166 void setDueDate( QDate date );
167
168 /**
169 * set the alarm time
170 */
171 void setAlarmDateTime ( const QDateTime& alarm );
172
173 void setDescription(const QString& );
174 void setSummary(const QString& );
175 bool isOverdue();
176
177
178 bool match( const QRegExp &r )const;
179
180 bool operator<(const OTodo &toDoEvent )const;
181 bool operator<=(const OTodo &toDoEvent )const;
182 bool operator!=(const OTodo &toDoEvent )const;
183 bool operator>(const OTodo &toDoEvent )const;
184 bool operator>=(const OTodo &toDoEvent)const;
185 bool operator==(const OTodo &toDoEvent )const;
186 ToDoEvent &operator=(const OTodo &toDoEvent );
187
188 private:
189 class OTodoPrivate;
190 struct OTodoEventData;
191
192 void deref();
193 void changeOrModify();
194 void copy( OTodoData* src, OTodoData* dest );
195 ToDoEventPrivate *d;
196 ToDoEventData *data;
197
198 static Qtopia::UidGen m_gen;
199};
200 inline bool ToDoEvent::operator!=(const ToDoEvent &toDoEvent )const {
201 return !(*this == toDoEvent);
202 }
203};
204
205#endif
diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h
new file mode 100644
index 0000000..d9af589
--- a/dev/null
+++ b/libopie2/opiepim/backend/opimaccessbackend.h
@@ -0,0 +1,29 @@
1#ifndef OPIE_PIM_ACCESS_BACKEND
2#define OPIE_PIM_ACCESS_BACKEND
3
4#include <qarray.h>
5
6#include <opie/opimrecord.h>
7
8template <class T = OPimRecord>
9class OPimAccessBackend {
10public:
11 OPimAccessBackend() {
12 }
13 ~OPimAccessBackend() {
14 }
15 virtual void load() = 0;
16 virtual void reload() = 0;
17 virtual void save() = 0;
18 virtual QArray<int> allRecords() = 0;
19 virtual QArray<int> queryByExample( const T& t, int sort ) = 0;
20 virtual T find(int uid ) = 0;
21 virtual void clear() = 0;
22 virtual bool add( const T& t ) = 0;
23 virtual bool remove( int uid ) = 0;
24 virtual void replace( const T& t ) = 0;
25
26
27};
28
29#endif
diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h
new file mode 100644
index 0000000..f2a241d
--- a/dev/null
+++ b/libopie2/opiepim/core/opimaccesstemplate.h
@@ -0,0 +1,82 @@
1#ifndef OPIE_PIM_ACCESS_TEMPLATE_H
2#define OPIE_PIM_ACCESS_TEMPLATE_H
3
4#include <qarray.h>
5
6#include <opie/opimrecord.h>
7#include <opie/opimaccessbackend.h>
8#include <opie/orecordlist.h>
9
10template <class T = OPimRecord >
11class OPimAccessTemplate {
12public:
13 typedef ORecordList<T> List;
14 typedef OPimAccessBackend<T> BackEnd;
15 OPimAccessTemplate( BackEnd* end)
16 : m_backEnd( end ) {
17 }
18 ~OPimAccessTemplate() {
19 delete m_backEnd;
20 }
21 virtual void load() {
22 m_backEnd->load();
23 }
24 virtual void reload() {
25 m_backEnd->reload();
26 }
27 virtual void save() {
28 m_backEnd->save();
29 }
30
31 /*
32 *do array to Records conversion
33 * QArray<int> ids
34 */
35 virtual List allRecords()const {
36 QArray<int> ints = m_backEnd->allRecords();
37
38 List lis( ints, this );
39 return lis;
40 }
41 virtual List queryByExample( const T& t, int sortOrder ) {
42 QArray<int> ints = m_backEnd->query( t, sortOrder );
43 List lis( ints, this );
44
45 return lis;
46 }
47 /* implement QCache here */
48 virtual T find( int uid ) {
49 T t = m_backEnd->find( uid );
50 return t;
51 }
52
53 /* invalidate cache here */
54 virtual void clear() {
55 invalidateCache();
56 m_backEnd->clear();
57 }
58 virtual bool add( const T& t ) {
59 return m_backEnd->add( t );
60 }
61
62 /* only the uid matters */
63 virtual bool remove( const T& t ) {
64 /* remove from cache */
65 return m_backEnd->remove( t.uid() );
66 }
67 virtual bool remove( int uid ) {
68 /* remove from cache */
69 return m_backEnd->remove(uid);
70 }
71 virtual bool replace( const T& t) {
72 return m_backEnd->replace( t );
73 }
74protected:
75 void invalidateCache() {
76
77 }
78 BackEnd* m_backEnd;
79
80};
81
82#endif
diff --git a/libopie2/opiepim/core/opimrecord.cpp b/libopie2/opiepim/core/opimrecord.cpp
new file mode 100644
index 0000000..95de1df
--- a/dev/null
+++ b/libopie2/opiepim/core/opimrecord.cpp
@@ -0,0 +1,90 @@
1#include "opimrecord.h"
2
3OPimRecord::OPimRecord( int uid )
4 : Qtopia::Record() {
5 setUid( uid );
6 if ( uid == 1 )
7 assignUid();
8}
9OPimRecord::~OPimRecord() {
10}
11OPimRecord::OPimRecord( OPimRecord& rec )
12 : Qtopia::Record( rec )
13{
14 (*this) = rec;
15}
16
17OPimRecord &OPimRecord::operator=( const OPimRecord& rec) {
18 /* how do I call the parent copy operator ? */
19 setUid( rec.uid() );
20 setCategories( rec.categories() );
21 return *this;
22}
23QStringList OPimRecord::categoryNames()const {
24 QStringList list;
25
26 return list;
27}
28void OPimRecord::setCategoryName( const QStringList& ) {
29
30}
31void OPimRecord::addCategoryName( const QString& ) {
32
33}
34bool OPimRecord::isEmpty()const {
35 return ( uid() == 0 );
36}
37QStringList OPimRecord::relatedApps()const{
38 QStringList list;
39 QMap<QString, QArray<int> >::ConstIterator it;
40 for ( it = m_relations.begin(); it != m_relations.end(); ++it ) {
41 list << it.key();
42 }
43 return list;
44}
45QArray<int> OPimRecord::relations(const QString& app )const {
46 QArray<int> tmp;
47 QMap<QString, QArray<int> >::ConstIterator it;
48 it = m_relations.find( app);
49 if ( it != m_relations.end() )
50 tmp = it.data();
51 return tmp;
52}
53void OPimRecord::clearRelation( const QString& app ) {
54 m_relations.remove( app );
55}
56void OPimRecord::addRelation( const QString& app, int id ) {
57
58 QMap<QString, QArray<int> >::Iterator it;
59 QArray<int> tmp;
60
61 it = m_relations.find( app );
62 if ( it == m_relations.end() ) {
63 tmp.resize(1 );
64 tmp[0] = id;
65 }else{
66 tmp = it.data();
67 tmp.resize( tmp.size() + 1 );
68 tmp[tmp.size() - 1] = id;
69 }
70 m_relations.replace( app, tmp );
71}
72void OPimRecord::setRelations( const QString& app, QArray<int> ids ) {
73
74 QMap<QString, QArray<int> >::Iterator it;
75 QArray<int> tmp;
76
77 it = m_relations.find( app);
78 if ( it == m_relations.end() ) {
79 tmp = ids;
80 }else{
81 tmp = it.data();
82 int offset = tmp.size()-1;
83 tmp.resize( tmp.size() + ids.size() );
84 for (uint i = 0; i < ids.size(); i++ ) {
85 tmp[offset+i] = ids[i];
86 }
87
88 }
89 m_relations.replace( app, tmp );
90}
diff --git a/libopie2/opiepim/core/opimrecord.h b/libopie2/opiepim/core/opimrecord.h
new file mode 100644
index 0000000..a0e0413
--- a/dev/null
+++ b/libopie2/opiepim/core/opimrecord.h
@@ -0,0 +1,117 @@
1#ifndef OPIE_PIM_RECORD_H
2#define OPIE_PIM_RECORD_H
3
4#include <qmap.h>
5#include <qstring.h>
6#include <qstringlist.h>
7
8#include <qpe/palmtoprecord.h>
9
10class OPimRecord : public Qtopia::Record {
11public:
12 /**
13 * uid of 0 isEmpty
14 * uid of 1 will be assigned a new one
15 */
16 OPimRecord(int uid = 0);
17 ~OPimRecord();
18
19 /**
20 * copy c'tor
21 */
22 OPimRecord( OPimRecord& rec );
23
24 /**
25 * copy operator
26 */
27 OPimRecord &operator=( const OPimRecord& );
28
29 /**
30 * category names resolved
31 */
32 QStringList categoryNames()const;
33
34 /**
35 * set category names they will be resolved
36 */
37 void setCategoryName( const QStringList& );
38
39 /**
40 * addCategoryName adds a name
41 * to the internal category list
42 */
43 void addCategoryName( const QString& );
44
45 /**
46 * if a Record isEmpty
47 */
48 virtual bool isEmpty()const;
49
50 /**
51 * toRichText summary
52 */
53 virtual QString toRichText()const = 0;
54
55 /**
56 * a small one line summary
57 */
58 virtual QString toShortText()const = 0;
59
60 /**
61 * the name of the Record
62 */
63 virtual QString type()const = 0;
64
65 /**
66 * converts the internal structure to a map
67 */
68 virtual QMap<int, QString> toMap()const = 0;
69
70 /**
71 * key value representation of extra items
72 */
73 virtual QMap<QString, QString> toExtraMap()const = 0;
74
75 /**
76 * the name for a recordField
77 */
78 virtual QString recordField(int)const = 0;
79
80 /**
81 * the related apps names
82 */
83 QStringList relatedApps()const;
84
85 /**
86 * the realtions between an app
87 */
88 QArray<int> relations( const QString& app )const;
89
90 /**
91 *
92 */
93 void clearRelation( const QString& app );
94
95 /**
96 *
97 */
98 void addRelation( const QString& app, int id );
99
100 /**
101 *
102 */
103 void setRelations( const QString&, QArray<int> ids );
104
105protected:
106 QString crossToString()const;
107
108private:
109 class OPimRecordPrivate;
110 OPimRecordPrivate *d;
111 QMap<QString, QArray<int> > m_relations;
112
113};
114
115
116
117#endif
diff --git a/libopie2/opiepim/orecordlist.h b/libopie2/opiepim/orecordlist.h
new file mode 100644
index 0000000..c17186f
--- a/dev/null
+++ b/libopie2/opiepim/orecordlist.h
@@ -0,0 +1,44 @@
1
2#ifndef OPIE_RECORD_LIST_H
3#define OPIE_RECORD_LIST_H
4
5#include <opie/opimaccesstemplate.h>
6#include <opie/opimrecord.h>
7
8template <class T = OPimRecord >
9class ORecordList {
10public:
11 class Iterator {
12 friend class ORecordList;
13 public:
14 Iterator() {}
15 ~Iterator() {}
16 Iterator(const Iterator& ) {}
17 Iterator &operator=(const Iterator& );
18 T &operator*() {}
19 Iterator &operator++();
20
21 bool operator==( const Iterator& it );
22 bool operator!=( const Iterator& it );
23
24 }
25 ORecordList( const QArray<int>& ids,
26 OPimAccessTemplate<T>* acc )
27 : m_ids(ids ), m_acc( acc ) {
28
29 }
30 ~ORecordList() {
31
32 }
33 Iterator begin();
34 Iterator end();
35 /*
36 ConstIterator begin()const;
37 ConstIterator end()const;
38 */
39private:
40 QArray<int> ids;
41 OPimAccessTemplate<T>* m_acc;
42};
43
44#endif
diff --git a/libopie2/opiepim/otodo.cpp b/libopie2/opiepim/otodo.cpp
new file mode 100644
index 0000000..d8e0447
--- a/dev/null
+++ b/libopie2/opiepim/otodo.cpp
@@ -0,0 +1,507 @@
1
2#include <qobject.h>
3#include <qshared.h>
4
5
6
7#include <qpe/palmtopuidgen.h>
8#include <qpe/stringutil.h>
9#include <qpe/palmtoprecord.h>
10#include <qpe/stringutil.h>
11#include <qpe/categories.h>
12#include <qpe/categoryselect.h>
13
14#include "todoevent.h"
15
16using namespace Opie;
17
18Qtopia::UidGen ToDoEvent::m_gen;
19
20struct ToDoEvent::ToDoEventData : public QShared {
21 ToDoEventData() : QShared() {
22 };
23
24 QDate date;
25 bool isCompleted:1;
26 bool hasDate:1;
27 int priority;
28 QStringList category;
29 QString desc;
30 QString sum;
31 QMap<QString, QString> extra;
32 QMap<QString, QArray<int> > relations;
33 int uid;
34 ushort prog;
35 bool hasAlarmDateTime :1;
36 QDateTime alarmDateTime;
37};
38
39ToDoEvent::ToDoEvent(const ToDoEvent &event )
40 : data( event.data )
41{
42 data->ref();
43 //qWarning("ref up");
44}
45ToDoEvent::~ToDoEvent() {
46 if ( data->deref() ) {
47 //qWarning("ToDoEvent::dereffing");
48 delete data;
49 data = 0l;
50 }
51}
52
53ToDoEvent::ToDoEvent(bool completed, int priority,
54 const QStringList &category,
55 const QString& summary,
56 const QString &description,
57 ushort progress,
58 bool hasDate, QDate date, int uid )
59{
60 //qWarning("ToDoEventData");
61 data = new ToDoEventData;
62 data->date = date;
63 data->isCompleted = completed;
64 data->hasDate = hasDate;
65 data->priority = priority;
66 data->category = category;
67 data->sum = summary;
68 data->prog = progress;
69 data->desc = Qtopia::simplifyMultiLineSpace(description );
70 if (uid == -1 ) {
71 uid = m_gen.generate();
72
73 }// generated the ids
74 m_gen.store( uid );
75
76 data->uid = uid;
77 data->hasAlarmDateTime = false;
78
79}
80QArray<int> ToDoEvent::categories()const
81{
82 qWarning( "ToDoEvent:cats" + data->category.join(";") );
83 QArray<int> array(data->category.count() ); // currently the datebook can be only in one category
84 array = Qtopia::Record::idsFromString( data->category.join(";") );
85 return array;
86}
87bool ToDoEvent::match( const QRegExp &regExp )const
88{
89 if( QString::number( data->priority ).find( regExp ) != -1 ){
90 return true;
91 }else if( data->hasDate && data->date.toString().find( regExp) != -1 ){
92 return true;
93 }else if(data->desc.find( regExp ) != -1 ){
94 return true;
95 }
96 return false;
97}
98bool ToDoEvent::isCompleted() const
99{
100 return data->isCompleted;
101}
102bool ToDoEvent::hasDueDate() const
103{
104 return data->hasDate;
105}
106bool ToDoEvent::hasAlarmDateTime() const
107{
108 return data->hasAlarmDateTime;
109}
110int ToDoEvent::priority()const
111{
112 return data->priority;
113}
114QStringList ToDoEvent::allCategories()const
115{
116 return data->category;
117}
118QString ToDoEvent::extra(const QString& )const
119{
120 return QString::null;
121}
122QString ToDoEvent::summary() const
123{
124 return data->sum;
125}
126ushort ToDoEvent::progress() const
127{
128 return data->prog;
129}
130QStringList ToDoEvent::relatedApps() const
131{
132 QStringList list;
133 QMap<QString, QArray<int> >::ConstIterator it;
134 for ( it = data->relations.begin(); it != data->relations.end(); ++it ) {
135 list << it.key();
136 }
137 return list;
138}
139QArray<int> ToDoEvent::relations( const QString& app)const
140{
141 QArray<int> tmp;
142 QMap<QString, QArray<int> >::ConstIterator it;
143 it = data->relations.find( app);
144 if ( it != data->relations.end() )
145 tmp = it.data();
146 return tmp;
147}
148void ToDoEvent::insertCategory(const QString &str )
149{
150 changeOrModify();
151 qWarning("insert category;" + str );
152 data->category.append( str );
153}
154void ToDoEvent::clearCategories()
155{
156 changeOrModify();
157 data->category.clear();
158}
159void ToDoEvent::setCategories(const QStringList &list )
160{
161 changeOrModify();
162 qWarning("set categories" + list.join(";") );
163 data->category = list;
164}
165QDate ToDoEvent::dueDate()const
166{
167 return data->date;
168}
169
170QDateTime ToDoEvent::alarmDateTime() const
171{
172 return data->alarmDateTime;
173}
174
175QString ToDoEvent::description()const
176{
177 return data->desc;
178}
179void ToDoEvent::setCompleted( bool completed )
180{
181 changeOrModify();
182 data->isCompleted = completed;
183}
184void ToDoEvent::setHasDueDate( bool hasDate )
185{
186 changeOrModify();
187 data->hasDate = hasDate;
188}
189void ToDoEvent::setHasAlarmDateTime( bool hasAlarmDateTime )
190{
191 changeOrModify();
192 data->hasAlarmDateTime = hasAlarmDateTime;
193}
194void ToDoEvent::setDescription(const QString &desc )
195{
196 changeOrModify();
197 data->desc = Qtopia::simplifyMultiLineSpace(desc );
198}
199void ToDoEvent::setExtra( const QString&, const QString& )
200{
201
202}
203void ToDoEvent::setSummary( const QString& sum )
204{
205 changeOrModify();
206 data->sum = sum;
207}
208void ToDoEvent::setCategory( const QString &cat )
209{
210 changeOrModify();
211 //qWarning("setCategory %s", cat.latin1() );
212 data->category.clear();
213 data->category << cat;
214}
215void ToDoEvent::setPriority(int prio )
216{
217 changeOrModify();
218 data->priority = prio;
219}
220void ToDoEvent::setDueDate( QDate date )
221{
222 changeOrModify();
223 data->date = date;
224}
225void ToDoEvent::setAlarmDateTime( const QDateTime& alarm )
226{
227 changeOrModify();
228 data->alarmDateTime = alarm;
229}
230void ToDoEvent::addRelated( const QString &app, int id )
231{
232 changeOrModify();
233
234 QMap<QString, QArray<int> >::Iterator it;
235 QArray<int> tmp;
236 it = data->relations.find( app );
237 if ( it == data->relations.end() ) {
238 tmp.resize(1 );
239 tmp[0] = id;
240 }else{
241 tmp = it.data();
242 tmp.resize( tmp.size() + 1 );
243 tmp[tmp.size() - 1] = id;
244 }
245 data->relations.replace( app, tmp );
246}
247void ToDoEvent::addRelated(const QString& app, QArray<int> ids )
248{
249 changeOrModify();
250
251 QMap<QString, QArray<int> >::Iterator it;
252 QArray<int> tmp;
253 it = data->relations.find( app);
254 if ( it == data->relations.end() ) { // not there
255 /** tmp.resize( ids.size() ); stupid??
256 */
257 tmp = ids;
258 }else{
259 tmp = it.data();
260 int offset = tmp.size()-1;
261 tmp.resize( tmp.size() + ids.size() );
262 for (uint i = 0; i < ids.size(); i++ ) {
263 tmp[offset+i] = ids[i];
264 }
265
266 }
267 data->relations.replace( app, tmp );
268}
269void ToDoEvent::clearRelated( const QString& app )
270{
271 changeOrModify();
272 data->relations.remove( app );
273}
274bool ToDoEvent::isOverdue( )
275{
276 if( data->hasDate )
277 return QDate::currentDate() > data->date;
278 return false;
279}
280void ToDoEvent::setProgress(ushort progress )
281{
282 changeOrModify();
283 data->prog = progress;
284}
285/*!
286 Returns a richt text string
287*/
288QString ToDoEvent::richText() const
289{
290 QString text;
291 QStringList catlist;
292
293 // Description of the todo
294 if ( !summary().isEmpty() ) {
295 text += "<b>" + QObject::tr( "Summary:") + "</b><br>";
296 text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
297 }
298 if( !description().isEmpty() ){
299 text += "<b>" + QObject::tr( "Description:" ) + "</b><br>";
300 text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) ;
301 }
302 text += "<br><br><br>";
303
304 text += "<b>" + QObject::tr( "Priority:") +" </b>"
305 + QString::number( priority() ) + " <br>";
306 text += "<b>" + QObject::tr( "Progress:") + " </b>"
307 + QString::number( progress() ) + " %<br>";
308 if (hasDueDate() ){
309 text += "<b>" + QObject::tr( "Deadline:") + " </b>";
310 text += dueDate().toString();
311 text += "<br>";
312 }
313 if (hasAlarmDateTime() ){
314 text += "<b>" + QObject::tr( "Alarmed Notification:") + " </b>";
315 text += alarmDateTime().toString();
316 text += "<br>";
317 }
318
319 // Open database of all categories and get the list of
320 // the categories this todoevent belongs to.
321 // Then print them...
322 // I am not sure whether there is no better way doing this !?
323 Categories catdb;
324 bool firstloop = true;
325 catdb.load( categoryFileName() );
326 catlist = allCategories();
327
328 text += "<b>" + QObject::tr( "Category:") + "</b> ";
329 for ( QStringList::Iterator it = catlist.begin(); it != catlist.end(); ++it ) {
330 if (!firstloop){
331 text += ", ";
332 }
333 firstloop = false;
334 text += catdb.label ("todo", (*it).toInt());
335 }
336 text += "<br>";
337 return text;
338}
339
340bool ToDoEvent::operator<( const ToDoEvent &toDoEvent )const{
341 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
342 if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
343 if( hasDueDate() && toDoEvent.hasDueDate() ){
344 if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
345 return priority() < toDoEvent.priority();
346 }else{
347 return dueDate() < toDoEvent.dueDate();
348 }
349 }
350 return false;
351}
352bool ToDoEvent::operator<=(const ToDoEvent &toDoEvent )const
353{
354 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
355 if( !hasDueDate() && toDoEvent.hasDueDate() ) return true;
356 if( hasDueDate() && toDoEvent.hasDueDate() ){
357 if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
358 return priority() <= toDoEvent.priority();
359 }else{
360 return dueDate() <= toDoEvent.dueDate();
361 }
362 }
363 return true;
364}
365bool ToDoEvent::operator>(const ToDoEvent &toDoEvent )const
366{
367 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return false;
368 if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
369 if( hasDueDate() && toDoEvent.hasDueDate() ){
370 if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
371 return priority() > toDoEvent.priority();
372 }else{
373 return dueDate() > toDoEvent.dueDate();
374 }
375 }
376 return false;
377}
378bool ToDoEvent::operator>=(const ToDoEvent &toDoEvent )const
379{
380 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
381 if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
382 if( hasDueDate() && toDoEvent.hasDueDate() ){
383 if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
384 return priority() > toDoEvent.priority();
385 }else{
386 return dueDate() > toDoEvent.dueDate();
387 }
388 }
389 return true;
390}
391bool ToDoEvent::operator==(const ToDoEvent &toDoEvent )const
392{
393 if( data->priority == toDoEvent.data->priority &&
394 data->priority == toDoEvent.data->prog &&
395 data->isCompleted == toDoEvent.data->isCompleted &&
396 data->hasDate == toDoEvent.data->hasDate &&
397 data->date == toDoEvent.data->date &&
398 data->category == toDoEvent.data->category &&
399 data->sum == toDoEvent.data->sum &&
400 data->desc == toDoEvent.data->desc &&
401 data->hasAlarmDateTime == toDoEvent.data->hasAlarmDateTime &&
402 data->alarmDateTime == toDoEvent.data->alarmDateTime )
403 return true;
404
405 return false;
406}
407void ToDoEvent::deref() {
408
409 //qWarning("deref in ToDoEvent");
410 if ( data->deref() ) {
411 //qWarning("deleting");
412 delete data;
413 d= 0;
414 }
415}
416ToDoEvent &ToDoEvent::operator=(const ToDoEvent &item )
417{
418 //qWarning("operator= ref ");
419 item.data->ref();
420 deref();
421
422 data = item.data;
423
424
425 return *this;
426}
427
428QMap<int, QString> ToDoEvent::toMap() const {
429 QMap<int, QString> map;
430
431 map.insert( Uid, QString::number( data->uid ) );
432 map.insert( Category, data->category.join(";") );
433 map.insert( HasDate, QString::number( data->hasDate ) );
434 map.insert( Completed, QString::number( data->isCompleted ) );
435 map.insert( Description, data->desc );
436 map.insert( Summary, data->sum );
437 map.insert( Priority, QString::number( data->priority ) );
438 map.insert( DateDay, QString::number( data->date.day() ) );
439 map.insert( DateMonth, QString::number( data->date.month() ) );
440 map.insert( DateYear, QString::number( data->date.year() ) );
441 map.insert( Progress, QString::number( data->prog ) );
442 map.insert( CrossReference, crossToString() );
443 map.insert( HasAlarmDateTime, QString::number( data->hasAlarmDateTime ) );
444 map.insert( AlarmDateTime, data->alarmDateTime.toString() );
445
446 return map;
447}
448
449
450QString ToDoEvent::crossToString()const {
451 QString str;
452 QMap<QString, QArray<int> >::ConstIterator it;
453 for (it = data->relations.begin(); it != data->relations.end(); ++it ) {
454 QArray<int> id = it.data();
455 for ( uint i = 0; i < id.size(); ++i ) {
456 str += it.key() + "," + QString::number( i ) + ";";
457 }
458 }
459 str = str.remove( str.length()-1, 1); // strip the ;
460 //qWarning("IDS " + str );
461
462 return str;
463}
464int ToDoEvent::uid()const {
465 return data->uid;
466}
467void ToDoEvent::setUid( int id ) {
468 if ( id == -1 )
469 id = m_gen.generate();
470 m_gen.store(id );
471 changeOrModify();
472 data->uid = id;
473}
474QMap<QString, QString> ToDoEvent::extras()const {
475 return data->extra;
476}
477/**
478 * change or modify looks at the ref count and either
479 * creates a new QShared Object or it can modify it
480 * right in place
481 */
482void ToDoEvent::changeOrModify() {
483 if ( data->count != 1 ) {
484 //qWarning("changeOrModify");
485 data->deref();
486 ToDoEventData* d2 = new ToDoEventData();
487 copy(data, d2 );
488 data = d2;
489 }
490}
491void ToDoEvent::copy( ToDoEventData* src, ToDoEventData* dest ) {
492 dest->date = src->date;
493 dest->isCompleted = src->isCompleted;
494 dest->hasDate = src->hasDate;
495 dest->priority = src->priority;
496 dest->category = src->category;
497 dest->desc = src->desc;
498 dest->sum = src->sum;
499 dest->extra = src->extra;
500 dest->relations = src->relations;
501 dest->uid = src->uid;
502 dest->prog = src->prog;
503 dest->hasAlarmDateTime = src->hasAlarmDateTime;
504 dest->alarmDateTime = src->alarmDateTime;
505}
506
507
diff --git a/libopie2/opiepim/otodo.h b/libopie2/opiepim/otodo.h
new file mode 100644
index 0000000..429108a
--- a/dev/null
+++ b/libopie2/opiepim/otodo.h
@@ -0,0 +1,205 @@
1
2#ifndef OPIE_TODO_EVENT_H
3#define OPIE_TODO_EVENT_H
4
5
6#include <qarray.h>
7#include <qmap.h>
8#include <qregexp.h>
9#include <qstringlist.h>
10#include <qdatetime.h>
11#include <qvaluelist.h>
12
13#include <qpe/recordfields.h>
14#include <qpe/palmtopuidgen.h>
15
16#include <opie/opimrecord.h>
17
18
19class OTodo : public OPimRecord {
20public:
21 typedef QValueList<ToDoEvent> ValueList;
22 enum RecordFields {
23 Uid = Qtopia::UID_ID,
24 Category = Qtopia::CATEGORY_ID,
25 HasDate,
26 Completed,
27 Description,
28 Summary,
29 Priority,
30 DateDay,
31 DateMonth,
32 DateYear,
33 Progress,
34 CrossReference,
35 HasAlarmDateTime,
36 AlarmDateTime
37 };
38 public:
39 // priorities from Very low to very high
40 enum TaskPriority { VeryHigh=1, High, Normal, Low, VeryLow };
41
42 /* Constructs a new ToDoEvent
43 @param completed Is the TodoEvent completed
44 @param priority What is the priority of this ToDoEvent
45 @param category Which category does it belong( uid )
46 @param summary A small summary of the todo
47 @param description What is this ToDoEvent about
48 @param hasDate Does this Event got a deadline
49 @param date what is the deadline?
50 @param uid what is the UUID of this Event
51 **/
52 OTodo( bool completed = false, int priority = Normal,
53 const QStringList &category = QStringList(),
54 const QString &summary = QString::null ,
55 const QString &description = QString::null,
56 ushort progress = 0,
57 bool hasDate = false, QDate date = QDate::currentDate(),
58 int uid = -1 );
59
60 /* Copy c'tor
61
62 **/
63 OTodo(const OTodo & );
64
65 /**
66 *destructor
67 */
68 ~OTodo();
69
70 /**
71 * Is this event completed?
72 */
73 bool isCompleted() const;
74
75 /**
76 * Does this Event have a deadline
77 */
78 bool hasDueDate() const;
79
80 /**
81 * Does this Event has an alarm time ?
82 */
83 bool hasAlarmDateTime() const;
84
85 /**
86 * What is the priority?
87 */
88 int priority()const ;
89
90 /**
91 * progress as ushort 0, 20, 40, 60, 80 or 100%
92 */
93 ushort progress() const;
94
95 /**
96 * The due Date
97 */
98 QDate dueDate()const;
99
100 /**
101 * Alarm Date and Time
102 */
103 QDateTime alarmDateTime()const;
104
105 /**
106 * The description of the todo
107 */
108 QString description()const;
109
110 /**
111 * A small summary of the todo
112 */
113 QString summary() const;
114
115 /**
116 * @reimplemented
117 * Return this todoevent in a RichText formatted QString
118 */
119 QString toRichText() const;
120
121
122 /**
123 * returns a list of apps which have related items
124 */
125 QStringList relatedApps()const;
126
127 /**
128 * returns all relations for one app
129 */
130 QArray<int> relations( const QString& app )const;
131
132 /**
133 * toMap puts all data into the map. int relates
134 * to ToDoEvent RecordFields enum
135 */
136 QMap<int, QString> toMap()const;
137
138 /**
139 * Set if this Todo is completed
140 */
141 void setCompleted(bool completed );
142
143 /**
144 * set if this todo got an end data
145 */
146 void setHasDueDate( bool hasDate );
147
148 /**
149 * set if this todo has an alarm time and date
150 */
151 void setHasAlarmDateTime ( bool hasAlarm );
152
153 /**
154 * Set the priority of the Todo
155 */
156 void setPriority(int priority );
157
158 /**
159 * Set the progress.
160 */
161 void setProgress( ushort progress );
162
163 /**
164 * set the end date
165 */
166 void setDueDate( QDate date );
167
168 /**
169 * set the alarm time
170 */
171 void setAlarmDateTime ( const QDateTime& alarm );
172
173 void setDescription(const QString& );
174 void setSummary(const QString& );
175 bool isOverdue();
176
177
178 bool match( const QRegExp &r )const;
179
180 bool operator<(const OTodo &toDoEvent )const;
181 bool operator<=(const OTodo &toDoEvent )const;
182 bool operator!=(const OTodo &toDoEvent )const;
183 bool operator>(const OTodo &toDoEvent )const;
184 bool operator>=(const OTodo &toDoEvent)const;
185 bool operator==(const OTodo &toDoEvent )const;
186 ToDoEvent &operator=(const OTodo &toDoEvent );
187
188 private:
189 class OTodoPrivate;
190 struct OTodoEventData;
191
192 void deref();
193 void changeOrModify();
194 void copy( OTodoData* src, OTodoData* dest );
195 ToDoEventPrivate *d;
196 ToDoEventData *data;
197
198 static Qtopia::UidGen m_gen;
199};
200 inline bool ToDoEvent::operator!=(const ToDoEvent &toDoEvent )const {
201 return !(*this == toDoEvent);
202 }
203};
204
205#endif