summaryrefslogtreecommitdiff
path: root/libopie/pim/otodo.cpp
Unidiff
Diffstat (limited to 'libopie/pim/otodo.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/otodo.cpp507
1 files changed, 507 insertions, 0 deletions
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