author | eilers <eilers> | 2003-12-08 15:18:10 (UTC) |
---|---|---|
committer | eilers <eilers> | 2003-12-08 15:18:10 (UTC) |
commit | 6974a4bbdc674a2a5d41d801f80035a183faedb5 (patch) (unidiff) | |
tree | 09a719ef263047e92ffb866da13168b7f7d41f23 /libopie/pim | |
parent | 7f2f736597490fd1592d7ed1f40e4abf824673c0 (diff) | |
download | opie-6974a4bbdc674a2a5d41d801f80035a183faedb5.zip opie-6974a4bbdc674a2a5d41d801f80035a183faedb5.tar.gz opie-6974a4bbdc674a2a5d41d801f80035a183faedb5.tar.bz2 |
Committing unfinished sql implementation before merging to libopie2 starts..
-rw-r--r-- | libopie/pim/ocontactaccessbackend_sql.cpp | 11 | ||||
-rw-r--r-- | libopie/pim/ocontactaccessbackend_sql.h | 5 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend_sql.cpp | 221 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend_sql.h | 60 | ||||
-rw-r--r-- | libopie/pim/odatebookaccessbackend_xml.cpp | 12 | ||||
-rw-r--r-- | libopie/pim/oevent.cpp | 131 | ||||
-rw-r--r-- | libopie/pim/oevent.h | 38 | ||||
-rw-r--r-- | libopie/pim/orecur.cpp | 8 | ||||
-rw-r--r-- | libopie/pim/orecur.h | 1 | ||||
-rw-r--r-- | libopie/pim/otodoaccesssql.cpp | 5 |
10 files changed, 471 insertions, 21 deletions
diff --git a/libopie/pim/ocontactaccessbackend_sql.cpp b/libopie/pim/ocontactaccessbackend_sql.cpp index 132c9fc..dd9dbde 100644 --- a/libopie/pim/ocontactaccessbackend_sql.cpp +++ b/libopie/pim/ocontactaccessbackend_sql.cpp | |||
@@ -1,64 +1,67 @@ | |||
1 | /* | 1 | /* |
2 | * SQL Backend for the OPIE-Contact Database. | 2 | * SQL Backend for the OPIE-Contact Database. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | 4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) |
5 | * | 5 | * |
6 | * ===================================================================== | 6 | * ===================================================================== |
7 | *This program is free software; you can redistribute it and/or | 7 | *This program is free software; you can redistribute it and/or |
8 | *modify it under the terms of the GNU Library General Public | 8 | *modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either | 9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. | 10 | * version 2 of the License, or (at your option) any later version. |
11 | * ===================================================================== | 11 | * ===================================================================== |
12 | * ===================================================================== | 12 | * ===================================================================== |
13 | * Version: $Id$ | 13 | * Version: $Id$ |
14 | * ===================================================================== | 14 | * ===================================================================== |
15 | * History: | 15 | * History: |
16 | * $Log$ | 16 | * $Log$ |
17 | * Revision 1.3 2003/12/08 15:18:10 eilers | ||
18 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
19 | * | ||
17 | * Revision 1.2 2003/09/29 07:44:26 eilers | 20 | * Revision 1.2 2003/09/29 07:44:26 eilers |
18 | * Improvement of PIM-SQL Databases, but search queries are still limited. | 21 | * Improvement of PIM-SQL Databases, but search queries are still limited. |
19 | * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. | 22 | * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. |
20 | * Todo: Started to add new attributes. Some type conversions missing. | 23 | * Todo: Started to add new attributes. Some type conversions missing. |
21 | * | 24 | * |
22 | * Revision 1.1 2003/09/22 14:31:16 eilers | 25 | * Revision 1.1 2003/09/22 14:31:16 eilers |
23 | * Added first experimental incarnation of sql-backend for addressbook. | 26 | * Added first experimental incarnation of sql-backend for addressbook. |
24 | * Some modifications to be able to compile the todo sql-backend. | 27 | * Some modifications to be able to compile the todo sql-backend. |
25 | * A lot of changes fill follow... | 28 | * A lot of changes fill follow... |
26 | * | 29 | * |
27 | */ | 30 | */ |
28 | 31 | ||
29 | #include "ocontactaccessbackend_sql.h" | 32 | #include "ocontactaccessbackend_sql.h" |
30 | 33 | ||
31 | #include <qarray.h> | 34 | #include <qarray.h> |
32 | #include <qdatetime.h> | 35 | #include <qdatetime.h> |
33 | #include <qstringlist.h> | 36 | #include <qstringlist.h> |
34 | 37 | ||
35 | #include <qpe/global.h> | 38 | #include <qpe/global.h> |
36 | #include <qpe/recordfields.h> | 39 | #include <qpe/recordfields.h> |
37 | 40 | ||
38 | #include <opie/ocontactfields.h> | 41 | #include <opie/ocontactfields.h> |
39 | #include <opie/oconversion.h> | 42 | #include <opie/oconversion.h> |
40 | #include <opie2/osqldriver.h> | 43 | #include <opie2/osqldriver.h> |
41 | #include <opie2/osqlresult.h> | 44 | #include <opie2/osqlresult.h> |
42 | #include <opie2/osqlmanager.h> | 45 | #include <opie2/osqlmanager.h> |
43 | #include <opie2/osqlquery.h> | 46 | #include <opie2/osqlquery.h> |
44 | 47 | ||
45 | 48 | ||
46 | 49 | ||
47 | 50 | ||
48 | // If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead | 51 | // If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead |
49 | // vertical like "uid, type, value". | 52 | // vertical like "uid, type, value". |
50 | // DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! | 53 | // DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! |
51 | #define __STORE_HORIZONTAL_ | 54 | #define __STORE_HORIZONTAL_ |
52 | 55 | ||
53 | // Distinct loading is not very fast. If I expect that every person has just | 56 | // Distinct loading is not very fast. If I expect that every person has just |
54 | // one (and always one) 'Last Name', I can request all uid's for existing lastnames, | 57 | // one (and always one) 'Last Name', I can request all uid's for existing lastnames, |
55 | // which is faster.. | 58 | // which is faster.. |
56 | // But this may not be true for all entries, like company contacts.. | 59 | // But this may not be true for all entries, like company contacts.. |
57 | // The current AddressBook application handles this problem, but other may not.. (eilers) | 60 | // The current AddressBook application handles this problem, but other may not.. (eilers) |
58 | #define __USE_SUPERFAST_LOADQUERY | 61 | #define __USE_SUPERFAST_LOADQUERY |
59 | 62 | ||
60 | 63 | ||
61 | /* | 64 | /* |
62 | * Implementation of used query types | 65 | * Implementation of used query types |
63 | * CREATE query | 66 | * CREATE query |
64 | * LOAD query | 67 | * LOAD query |
@@ -409,118 +412,124 @@ namespace { | |||
409 | for (uint i = 0; i < m_uids.count(); i++ ) { | 412 | for (uint i = 0; i < m_uids.count(); i++ ) { |
410 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | 413 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; |
411 | } | 414 | } |
412 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. | 415 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. |
413 | return qu; | 416 | return qu; |
414 | } | 417 | } |
415 | */ | 418 | */ |
416 | #ifdef __STORE_HORIZONTAL_ | 419 | #ifdef __STORE_HORIZONTAL_ |
417 | QString FindQuery::single()const{ | 420 | QString FindQuery::single()const{ |
418 | QString qu = "select *"; | 421 | QString qu = "select *"; |
419 | qu += " from addressbook where uid = " + QString::number(m_uid); | 422 | qu += " from addressbook where uid = " + QString::number(m_uid); |
420 | 423 | ||
421 | // qWarning("find query: %s", qu.latin1() ); | 424 | // qWarning("find query: %s", qu.latin1() ); |
422 | return qu; | 425 | return qu; |
423 | } | 426 | } |
424 | #else | 427 | #else |
425 | QString FindQuery::single()const{ | 428 | QString FindQuery::single()const{ |
426 | QString qu = "select uid, type, value from addressbook where uid = "; | 429 | QString qu = "select uid, type, value from addressbook where uid = "; |
427 | qu += QString::number(m_uid); | 430 | qu += QString::number(m_uid); |
428 | return qu; | 431 | return qu; |
429 | } | 432 | } |
430 | #endif | 433 | #endif |
431 | 434 | ||
432 | 435 | ||
433 | FindCustomQuery::FindCustomQuery(int uid) | 436 | FindCustomQuery::FindCustomQuery(int uid) |
434 | : OSQLQuery(), m_uid( uid ) { | 437 | : OSQLQuery(), m_uid( uid ) { |
435 | } | 438 | } |
436 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) | 439 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) |
437 | : OSQLQuery(), m_uids( ints ){ | 440 | : OSQLQuery(), m_uids( ints ){ |
438 | } | 441 | } |
439 | FindCustomQuery::~FindCustomQuery() { | 442 | FindCustomQuery::~FindCustomQuery() { |
440 | } | 443 | } |
441 | QString FindCustomQuery::query()const{ | 444 | QString FindCustomQuery::query()const{ |
442 | // if ( m_uids.count() == 0 ) | 445 | // if ( m_uids.count() == 0 ) |
443 | return single(); | 446 | return single(); |
444 | } | 447 | } |
445 | QString FindCustomQuery::single()const{ | 448 | QString FindCustomQuery::single()const{ |
446 | QString qu = "select uid, type, value from custom_data where uid = "; | 449 | QString qu = "select uid, type, value from custom_data where uid = "; |
447 | qu += QString::number(m_uid); | 450 | qu += QString::number(m_uid); |
448 | return qu; | 451 | return qu; |
449 | } | 452 | } |
450 | 453 | ||
451 | }; | 454 | }; |
452 | 455 | ||
453 | 456 | ||
454 | /* --------------------------------------------------------------------------- */ | 457 | /* --------------------------------------------------------------------------- */ |
455 | 458 | ||
456 | OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, | 459 | OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, |
457 | const QString& filename ): m_changed(false) | 460 | const QString& filename ): |
461 | OContactAccessBackend(), m_changed(false), m_driver( NULL ) | ||
458 | { | 462 | { |
459 | qWarning("C'tor OContactAccessBackend_SQL starts"); | 463 | qWarning("C'tor OContactAccessBackend_SQL starts"); |
460 | QTime t; | 464 | QTime t; |
461 | t.start(); | 465 | t.start(); |
462 | 466 | ||
463 | /* Expecting to access the default filename if nothing else is set */ | 467 | /* Expecting to access the default filename if nothing else is set */ |
464 | if ( filename.isEmpty() ){ | 468 | if ( filename.isEmpty() ){ |
465 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); | 469 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); |
466 | } else | 470 | } else |
467 | m_fileName = filename; | 471 | m_fileName = filename; |
468 | 472 | ||
469 | // Get the standart sql-driver from the OSQLManager.. | 473 | // Get the standart sql-driver from the OSQLManager.. |
470 | OSQLManager man; | 474 | OSQLManager man; |
471 | m_driver = man.standard(); | 475 | m_driver = man.standard(); |
472 | m_driver->setUrl( m_fileName ); | 476 | m_driver->setUrl( m_fileName ); |
473 | 477 | ||
474 | load(); | 478 | load(); |
475 | 479 | ||
476 | qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); | 480 | qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); |
477 | } | 481 | } |
478 | 482 | ||
483 | OContactAccessBackend_SQL::~OContactAccessBackend_SQL () | ||
484 | { | ||
485 | if( m_driver ) | ||
486 | delete m_driver; | ||
487 | } | ||
479 | 488 | ||
480 | bool OContactAccessBackend_SQL::load () | 489 | bool OContactAccessBackend_SQL::load () |
481 | { | 490 | { |
482 | if (!m_driver->open() ) | 491 | if (!m_driver->open() ) |
483 | return false; | 492 | return false; |
484 | 493 | ||
485 | // Don't expect that the database exists. | 494 | // Don't expect that the database exists. |
486 | // It is save here to create the table, even if it | 495 | // It is save here to create the table, even if it |
487 | // do exist. ( Is that correct for all databases ?? ) | 496 | // do exist. ( Is that correct for all databases ?? ) |
488 | CreateQuery creat; | 497 | CreateQuery creat; |
489 | OSQLResult res = m_driver->query( &creat ); | 498 | OSQLResult res = m_driver->query( &creat ); |
490 | 499 | ||
491 | update(); | 500 | update(); |
492 | 501 | ||
493 | return true; | 502 | return true; |
494 | 503 | ||
495 | } | 504 | } |
496 | 505 | ||
497 | bool OContactAccessBackend_SQL::reload() | 506 | bool OContactAccessBackend_SQL::reload() |
498 | { | 507 | { |
499 | return load(); | 508 | return load(); |
500 | } | 509 | } |
501 | 510 | ||
502 | bool OContactAccessBackend_SQL::save() | 511 | bool OContactAccessBackend_SQL::save() |
503 | { | 512 | { |
504 | return m_driver->close(); | 513 | return m_driver->close(); |
505 | } | 514 | } |
506 | 515 | ||
507 | 516 | ||
508 | void OContactAccessBackend_SQL::clear () | 517 | void OContactAccessBackend_SQL::clear () |
509 | { | 518 | { |
510 | ClearQuery cle; | 519 | ClearQuery cle; |
511 | OSQLResult res = m_driver->query( &cle ); | 520 | OSQLResult res = m_driver->query( &cle ); |
512 | CreateQuery qu; | 521 | CreateQuery qu; |
513 | res = m_driver->query(&qu); | 522 | res = m_driver->query(&qu); |
514 | } | 523 | } |
515 | 524 | ||
516 | bool OContactAccessBackend_SQL::wasChangedExternally() | 525 | bool OContactAccessBackend_SQL::wasChangedExternally() |
517 | { | 526 | { |
518 | return false; | 527 | return false; |
519 | } | 528 | } |
520 | 529 | ||
521 | QArray<int> OContactAccessBackend_SQL::allRecords() const | 530 | QArray<int> OContactAccessBackend_SQL::allRecords() const |
522 | { | 531 | { |
523 | 532 | ||
524 | // FIXME: Think about cute handling of changed tables.. | 533 | // FIXME: Think about cute handling of changed tables.. |
525 | // Thus, we don't have to call update here... | 534 | // Thus, we don't have to call update here... |
526 | if ( m_changed ) | 535 | if ( m_changed ) |
diff --git a/libopie/pim/ocontactaccessbackend_sql.h b/libopie/pim/ocontactaccessbackend_sql.h index bb22551..b8f1d8d 100644 --- a/libopie/pim/ocontactaccessbackend_sql.h +++ b/libopie/pim/ocontactaccessbackend_sql.h | |||
@@ -1,96 +1,101 @@ | |||
1 | /* | 1 | /* |
2 | * SQL Backend for the OPIE-Contact Database. | 2 | * SQL Backend for the OPIE-Contact Database. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | 4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) |
5 | * | 5 | * |
6 | * ===================================================================== | 6 | * ===================================================================== |
7 | *This program is free software; you can redistribute it and/or | 7 | *This program is free software; you can redistribute it and/or |
8 | *modify it under the terms of the GNU Library General Public | 8 | *modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either | 9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. | 10 | * version 2 of the License, or (at your option) any later version. |
11 | * ===================================================================== | 11 | * ===================================================================== |
12 | * | 12 | * |
13 | * | 13 | * |
14 | * ===================================================================== | 14 | * ===================================================================== |
15 | * Version: $Id$ | 15 | * Version: $Id$ |
16 | * ===================================================================== | 16 | * ===================================================================== |
17 | * History: | 17 | * History: |
18 | * $Log$ | 18 | * $Log$ |
19 | * Revision 1.2 2003/12/08 15:18:11 eilers | ||
20 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
21 | * | ||
19 | * Revision 1.1 2003/09/22 14:31:16 eilers | 22 | * Revision 1.1 2003/09/22 14:31:16 eilers |
20 | * Added first experimental incarnation of sql-backend for addressbook. | 23 | * Added first experimental incarnation of sql-backend for addressbook. |
21 | * Some modifications to be able to compile the todo sql-backend. | 24 | * Some modifications to be able to compile the todo sql-backend. |
22 | * A lot of changes fill follow... | 25 | * A lot of changes fill follow... |
23 | * | 26 | * |
24 | * | 27 | * |
25 | */ | 28 | */ |
26 | 29 | ||
27 | #ifndef _OContactAccessBackend_SQL_ | 30 | #ifndef _OContactAccessBackend_SQL_ |
28 | #define _OContactAccessBackend_SQL_ | 31 | #define _OContactAccessBackend_SQL_ |
29 | 32 | ||
30 | #include "ocontactaccessbackend.h" | 33 | #include "ocontactaccessbackend.h" |
31 | #include "ocontactaccess.h" | 34 | #include "ocontactaccess.h" |
32 | 35 | ||
33 | #include <qlist.h> | 36 | #include <qlist.h> |
34 | #include <qdict.h> | 37 | #include <qdict.h> |
35 | 38 | ||
36 | class OSQLDriver; | 39 | class OSQLDriver; |
37 | class OSQLResult; | 40 | class OSQLResult; |
38 | class OSQLResultItem; | 41 | class OSQLResultItem; |
39 | 42 | ||
40 | /* the default xml implementation */ | 43 | /* the default xml implementation */ |
41 | /** | 44 | /** |
42 | * This class is the SQL implementation of a Contact backend | 45 | * This class is the SQL implementation of a Contact backend |
43 | * it does implement everything available for OContact. | 46 | * it does implement everything available for OContact. |
44 | * @see OPimAccessBackend for more information of available methods | 47 | * @see OPimAccessBackend for more information of available methods |
45 | */ | 48 | */ |
46 | class OContactAccessBackend_SQL : public OContactAccessBackend { | 49 | class OContactAccessBackend_SQL : public OContactAccessBackend { |
47 | public: | 50 | public: |
48 | OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); | 51 | OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); |
49 | 52 | ||
53 | ~OContactAccessBackend_SQL (); | ||
54 | |||
50 | bool save(); | 55 | bool save(); |
51 | 56 | ||
52 | bool load (); | 57 | bool load (); |
53 | 58 | ||
54 | void clear (); | 59 | void clear (); |
55 | 60 | ||
56 | bool wasChangedExternally(); | 61 | bool wasChangedExternally(); |
57 | 62 | ||
58 | QArray<int> allRecords() const; | 63 | QArray<int> allRecords() const; |
59 | 64 | ||
60 | OContact find ( int uid ) const; | 65 | OContact find ( int uid ) const; |
61 | // FIXME: Add lookahead-cache support ! | 66 | // FIXME: Add lookahead-cache support ! |
62 | //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; | 67 | //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; |
63 | 68 | ||
64 | QArray<int> queryByExample ( const OContact &query, int settings, | 69 | QArray<int> queryByExample ( const OContact &query, int settings, |
65 | const QDateTime& d ); | 70 | const QDateTime& d ); |
66 | 71 | ||
67 | QArray<int> matchRegexp( const QRegExp &r ) const; | 72 | QArray<int> matchRegexp( const QRegExp &r ) const; |
68 | 73 | ||
69 | const uint querySettings(); | 74 | const uint querySettings(); |
70 | 75 | ||
71 | bool hasQuerySettings (uint querySettings) const; | 76 | bool hasQuerySettings (uint querySettings) const; |
72 | 77 | ||
73 | // Currently only asc implemented.. | 78 | // Currently only asc implemented.. |
74 | QArray<int> sorted( bool asc, int , int , int ); | 79 | QArray<int> sorted( bool asc, int , int , int ); |
75 | bool add ( const OContact &newcontact ); | 80 | bool add ( const OContact &newcontact ); |
76 | 81 | ||
77 | bool replace ( const OContact &contact ); | 82 | bool replace ( const OContact &contact ); |
78 | 83 | ||
79 | bool remove ( int uid ); | 84 | bool remove ( int uid ); |
80 | bool reload(); | 85 | bool reload(); |
81 | 86 | ||
82 | private: | 87 | private: |
83 | QArray<int> extractUids( OSQLResult& res ) const; | 88 | QArray<int> extractUids( OSQLResult& res ) const; |
84 | QMap<int, QString> requestNonCustom( int uid ) const; | 89 | QMap<int, QString> requestNonCustom( int uid ) const; |
85 | QMap<QString, QString> requestCustom( int uid ) const; | 90 | QMap<QString, QString> requestCustom( int uid ) const; |
86 | void update(); | 91 | void update(); |
87 | 92 | ||
88 | protected: | 93 | protected: |
89 | bool m_changed; | 94 | bool m_changed; |
90 | QString m_fileName; | 95 | QString m_fileName; |
91 | QArray<int> m_uids; | 96 | QArray<int> m_uids; |
92 | 97 | ||
93 | OSQLDriver* m_driver; | 98 | OSQLDriver* m_driver; |
94 | }; | 99 | }; |
95 | 100 | ||
96 | #endif | 101 | #endif |
diff --git a/libopie/pim/odatebookaccessbackend_sql.cpp b/libopie/pim/odatebookaccessbackend_sql.cpp new file mode 100644 index 0000000..9769bf7 --- a/dev/null +++ b/libopie/pim/odatebookaccessbackend_sql.cpp | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * SQL Backend for the OPIE-Calender Database. | ||
3 | * | ||
4 | * Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * | ||
6 | * ===================================================================== | ||
7 | *This program is free software; you can redistribute it and/or | ||
8 | *modify it under the terms of the GNU Library General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2 of the License, or (at your option) any later version. | ||
11 | * ===================================================================== | ||
12 | * ===================================================================== | ||
13 | * Version: $Id$ | ||
14 | * ===================================================================== | ||
15 | * History: | ||
16 | * $Log$ | ||
17 | * Revision 1.1 2003/12/08 15:18:12 eilers | ||
18 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
19 | * | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | |||
26 | #include <qarray.h> | ||
27 | #include <qstringlist.h> | ||
28 | |||
29 | #include "orecur.h" | ||
30 | #include "odatebookaccessbackend_sql.h" | ||
31 | |||
32 | #include <opie2/osqldriver.h> | ||
33 | #include <opie2/osqlresult.h> | ||
34 | #include <opie2/osqlmanager.h> | ||
35 | #include <opie2/osqlquery.h> | ||
36 | |||
37 | namespace { | ||
38 | |||
39 | |||
40 | |||
41 | }; | ||
42 | |||
43 | ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , | ||
44 | const QString& fileName ) | ||
45 | : ODateBookAccessBackend(), m_driver( NULL ) | ||
46 | { | ||
47 | m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; | ||
48 | |||
49 | // Get the standart sql-driver from the OSQLManager.. | ||
50 | OSQLManager man; | ||
51 | m_driver = man.standard(); | ||
52 | m_driver->setUrl( m_fileName ); | ||
53 | |||
54 | initFields(); | ||
55 | |||
56 | load(); | ||
57 | } | ||
58 | |||
59 | ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { | ||
60 | } | ||
61 | |||
62 | void ODateBookAccessBackend_SQL::initFields() | ||
63 | { | ||
64 | |||
65 | // This map contains the translation of the fieldtype id's to | ||
66 | // the names of the table columns | ||
67 | m_fieldMap.insert( OEvent::FUid, "uid" ); | ||
68 | m_fieldMap.insert( OEvent::FCategories, "Categories" ); | ||
69 | m_fieldMap.insert( OEvent::FDescription, "Description" ); | ||
70 | m_fieldMap.insert( OEvent::FLocation, "Location" ); | ||
71 | m_fieldMap.insert( OEvent::FType, "Type" ); | ||
72 | m_fieldMap.insert( OEvent::FAlarm, "Alarm" ); | ||
73 | m_fieldMap.insert( OEvent::FSound, "Sound" ); | ||
74 | m_fieldMap.insert( OEvent::FRType, "RType" ); | ||
75 | m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" ); | ||
76 | m_fieldMap.insert( OEvent::FRPosition, "RPosition" ); | ||
77 | m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); | ||
78 | m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); | ||
79 | m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); | ||
80 | m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); | ||
81 | m_fieldMap.insert( OEvent::FRExeptions, "RExceptions" ); | ||
82 | m_fieldMap.insert( OEvent::FStart, "Start" ); | ||
83 | m_fieldMap.insert( OEvent::FEnd, "End" ); | ||
84 | m_fieldMap.insert( OEvent::FNote, "Note" ); | ||
85 | m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); | ||
86 | m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); | ||
87 | m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); | ||
88 | } | ||
89 | |||
90 | bool ODateBookAccessBackend_SQL::load() | ||
91 | { | ||
92 | if (!m_driver->open() ) | ||
93 | return false; | ||
94 | |||
95 | // Don't expect that the database exists. | ||
96 | // It is save here to create the table, even if it | ||
97 | // do exist. ( Is that correct for all databases ?? ) | ||
98 | QStringqu = "create table datebook( uid INTEGER PRIMARY KEY "; | ||
99 | |||
100 | QMap<int, QString>::Iterator it; | ||
101 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | ||
102 | qu += QString( ",\"%1\" VARCHAR(10)" ).arg( it.data() ); | ||
103 | } | ||
104 | qu += " );"; | ||
105 | |||
106 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; | ||
107 | |||
108 | OSQLRawQuery raw( qu ); | ||
109 | OSQLResult res = m_driver->query( &raw ); | ||
110 | if ( res.state() != OSQLResult::Success ) | ||
111 | return false; | ||
112 | |||
113 | update(); | ||
114 | |||
115 | return true; | ||
116 | } | ||
117 | |||
118 | void ODateBookAccessBackend_SQL::update() | ||
119 | { | ||
120 | |||
121 | QString qu = "select uid from datebook"; | ||
122 | OSQLRawQuery raw( qu ); | ||
123 | OSQLResult res = m_driver->query( &raw ); | ||
124 | if ( res.state() != OSQLResult::Success ){ | ||
125 | m_uids.clear(); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | m_uids = extractUids( res ); | ||
130 | |||
131 | } | ||
132 | |||
133 | QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const | ||
134 | { | ||
135 | qWarning("extractUids"); | ||
136 | |||
137 | OSQLResultItem::ValueList list = res.results(); | ||
138 | OSQLResultItem::ValueList::Iterator it; | ||
139 | QArray<int> ints(list.count() ); | ||
140 | qWarning(" count = %d", list.count() ); | ||
141 | |||
142 | int i = 0; | ||
143 | for (it = list.begin(); it != list.end(); ++it ) { | ||
144 | ints[i] = (*it).data("uid").toInt(); | ||
145 | i++; | ||
146 | } | ||
147 | |||
148 | return ints; | ||
149 | |||
150 | } | ||
151 | |||
152 | bool ODateBookAccessBackend_SQL::reload() | ||
153 | { | ||
154 | return load(); | ||
155 | } | ||
156 | |||
157 | bool ODateBookAccessBackend_SQL::save() | ||
158 | { | ||
159 | return m_driver->close(); | ||
160 | } | ||
161 | |||
162 | QArray<int> ODateBookAccessBackend_SQL::allRecords()const | ||
163 | { | ||
164 | return m_uids; | ||
165 | } | ||
166 | |||
167 | QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) { | ||
168 | return QArray<int>(); | ||
169 | } | ||
170 | |||
171 | void ODateBookAccessBackend_SQL::clear() | ||
172 | { | ||
173 | QString qu = "drop table datebook;"; | ||
174 | qu += "drop table custom_data;"; | ||
175 | |||
176 | OSQLRawQuery raw( qu ); | ||
177 | OSQLResult res = m_driver->query( &raw ); | ||
178 | |||
179 | } | ||
180 | |||
181 | |||
182 | OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ | ||
183 | } | ||
184 | |||
185 | bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) { | ||
186 | return true; | ||
187 | } | ||
188 | bool ODateBookAccessBackend_SQL::remove( int uid ) { | ||
189 | |||
190 | return true; | ||
191 | } | ||
192 | bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) { | ||
193 | remove( ev.uid() ); | ||
194 | return add( ev ); | ||
195 | } | ||
196 | QArray<int> ODateBookAccessBackend_SQL::rawEvents()const { | ||
197 | return allRecords(); | ||
198 | } | ||
199 | QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const { | ||
200 | |||
201 | return ints; | ||
202 | } | ||
203 | QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const { | ||
204 | |||
205 | return ints; | ||
206 | } | ||
207 | OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() { | ||
208 | |||
209 | return list; | ||
210 | } | ||
211 | OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() { | ||
212 | |||
213 | return list; | ||
214 | } | ||
215 | |||
216 | |||
217 | QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | ||
218 | { | ||
219 | |||
220 | return m_currentQuery; | ||
221 | } | ||
diff --git a/libopie/pim/odatebookaccessbackend_sql.h b/libopie/pim/odatebookaccessbackend_sql.h new file mode 100644 index 0000000..85e0d4f --- a/dev/null +++ b/libopie/pim/odatebookaccessbackend_sql.h | |||
@@ -0,0 +1,60 @@ | |||
1 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | ||
2 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | ||
3 | |||
4 | #include <qmap.h> | ||
5 | |||
6 | #include "odatebookaccessbackend.h" | ||
7 | |||
8 | class OSQLDriver; | ||
9 | |||
10 | /** | ||
11 | * This is the default SQL implementation for DateBoook SQL storage | ||
12 | * It fully implements the interface | ||
13 | * @see ODateBookAccessBackend | ||
14 | * @see OPimAccessBackend | ||
15 | */ | ||
16 | class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { | ||
17 | public: | ||
18 | ODateBookAccessBackend_SQL( const QString& appName, | ||
19 | const QString& fileName = QString::null); | ||
20 | ~ODateBookAccessBackend_SQL(); | ||
21 | |||
22 | bool load(); | ||
23 | bool reload(); | ||
24 | bool save(); | ||
25 | |||
26 | QArray<int> allRecords()const; | ||
27 | QArray<int> matchRegexp(const QRegExp &r) const; | ||
28 | QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() ); | ||
29 | OEvent find( int uid )const; | ||
30 | void clear(); | ||
31 | bool add( const OEvent& ev ); | ||
32 | bool remove( int uid ); | ||
33 | bool replace( const OEvent& ev ); | ||
34 | |||
35 | QArray<UID> rawEvents()const; | ||
36 | QArray<UID> rawRepeats()const; | ||
37 | QArray<UID> nonRepeats()const; | ||
38 | |||
39 | OEvent::ValueList directNonRepeats(); | ||
40 | OEvent::ValueList directRawRepeats(); | ||
41 | |||
42 | private: | ||
43 | bool loadFile(); | ||
44 | QString m_fileName; | ||
45 | QArray<int> m_uids; | ||
46 | |||
47 | QMap<int, QString> m_fieldMap; | ||
48 | |||
49 | OSQLDriver* m_driver; | ||
50 | |||
51 | class Private; | ||
52 | Private *d; | ||
53 | |||
54 | void initFields(); | ||
55 | void update(); | ||
56 | QArray<int> extractUids( OSQLResult& res ) const; | ||
57 | |||
58 | }; | ||
59 | |||
60 | #endif | ||
diff --git a/libopie/pim/odatebookaccessbackend_xml.cpp b/libopie/pim/odatebookaccessbackend_xml.cpp index 39c43c5..929d004 100644 --- a/libopie/pim/odatebookaccessbackend_xml.cpp +++ b/libopie/pim/odatebookaccessbackend_xml.cpp | |||
@@ -32,102 +32,104 @@ char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) | |||
32 | return 0; | 32 | return 0; |
33 | 33 | ||
34 | const char* hsearch = haystack; | 34 | const char* hsearch = haystack; |
35 | 35 | ||
36 | if ((needleChar = *needle++) != 0) { | 36 | if ((needleChar = *needle++) != 0) { |
37 | nLen--; //(to make up for needle++) | 37 | nLen--; //(to make up for needle++) |
38 | do { | 38 | do { |
39 | do { | 39 | do { |
40 | if ((haystackChar = *hsearch++) == 0) | 40 | if ((haystackChar = *hsearch++) == 0) |
41 | return (0); | 41 | return (0); |
42 | if (hsearch >= haystack + hLen) | 42 | if (hsearch >= haystack + hLen) |
43 | return (0); | 43 | return (0); |
44 | } while (haystackChar != needleChar); | 44 | } while (haystackChar != needleChar); |
45 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); | 45 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); |
46 | hsearch--; | 46 | hsearch--; |
47 | } | 47 | } |
48 | return ((char *)hsearch); | 48 | return ((char *)hsearch); |
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
52 | namespace { | 52 | namespace { |
53 | time_t start, end, created, rp_end; | 53 | time_t start, end, created, rp_end; |
54 | ORecur* rec; | 54 | ORecur* rec; |
55 | ORecur* recur() { | 55 | ORecur* recur() { |
56 | if (!rec) | 56 | if (!rec) |
57 | rec = new ORecur; | 57 | rec = new ORecur; |
58 | 58 | ||
59 | return rec; | 59 | return rec; |
60 | } | 60 | } |
61 | int alarmTime; | 61 | int alarmTime; |
62 | int snd; | 62 | int snd; |
63 | enum Attribute{ | 63 | enum Attribute{ |
64 | FDescription = 0, | 64 | FDescription = 0, |
65 | FLocation, | 65 | FLocation, |
66 | FCategories, | 66 | FCategories, |
67 | FUid, | 67 | FUid, |
68 | FType, | 68 | FType, |
69 | FAlarm, | 69 | FAlarm, |
70 | FSound, | 70 | FSound, |
71 | FRType, | 71 | FRType, |
72 | FRWeekdays, | 72 | FRWeekdays, |
73 | FRPosition, | 73 | FRPosition, |
74 | FRFreq, | 74 | FRFreq, |
75 | FRHasEndDate, | 75 | FRHasEndDate, |
76 | FREndDate, | 76 | FREndDate, |
77 | FRStart, | 77 | FRStart, |
78 | FREnd, | 78 | FREnd, |
79 | FNote, | 79 | FNote, |
80 | FCreated, | 80 | FCreated, // Should't this be called FRCreated ? |
81 | FTimeZone, | 81 | FTimeZone, |
82 | FRecParent, | 82 | FRecParent, |
83 | FRecChildren, | 83 | FRecChildren, |
84 | FExceptions | 84 | FExceptions |
85 | }; | 85 | }; |
86 | |||
87 | // FIXME: Use OEvent::toMap() here !! (eilers) | ||
86 | inline void save( const OEvent& ev, QString& buf ) { | 88 | inline void save( const OEvent& ev, QString& buf ) { |
87 | qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); | 89 | qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); |
88 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; | 90 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; |
89 | if (!ev.location().isEmpty() ) | 91 | if (!ev.location().isEmpty() ) |
90 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; | 92 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; |
91 | 93 | ||
92 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; | 94 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; |
93 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; | 95 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; |
94 | 96 | ||
95 | if (ev.isAllDay() ) | 97 | if (ev.isAllDay() ) |
96 | buf += " type=\"AllDay\""; // is that all ?? (eilers) | 98 | buf += " type=\"AllDay\""; // is that all ?? (eilers) |
97 | 99 | ||
98 | if (ev.hasNotifiers() ) { | 100 | if (ev.hasNotifiers() ) { |
99 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first | 101 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first |
100 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; | 102 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; |
101 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; | 103 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; |
102 | if ( alarm.sound() == OPimAlarm::Loud ) | 104 | if ( alarm.sound() == OPimAlarm::Loud ) |
103 | buf += "loud"; | 105 | buf += "loud"; |
104 | else | 106 | else |
105 | buf += "silent"; | 107 | buf += "silent"; |
106 | buf += "\""; | 108 | buf += "\""; |
107 | } | 109 | } |
108 | if ( ev.hasRecurrence() ) { | 110 | if ( ev.hasRecurrence() ) { |
109 | buf += ev.recurrence().toString(); | 111 | buf += ev.recurrence().toString(); |
110 | } | 112 | } |
111 | 113 | ||
112 | /* | 114 | /* |
113 | * fscking timezones :) well, we'll first convert | 115 | * fscking timezones :) well, we'll first convert |
114 | * the QDateTime to a QDateTime in UTC time | 116 | * the QDateTime to a QDateTime in UTC time |
115 | * and then we'll create a nice time_t | 117 | * and then we'll create a nice time_t |
116 | */ | 118 | */ |
117 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | 119 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); |
118 | buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; | 120 | buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; |
119 | buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; | 121 | buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; |
120 | if (!ev.note().isEmpty() ) { | 122 | if (!ev.note().isEmpty() ) { |
121 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; | 123 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; |
122 | } | 124 | } |
123 | 125 | ||
124 | buf += " timezone=\""; | 126 | buf += " timezone=\""; |
125 | if ( ev.timeZone().isEmpty() ) | 127 | if ( ev.timeZone().isEmpty() ) |
126 | buf += "None"; | 128 | buf += "None"; |
127 | else | 129 | else |
128 | buf += ev.timeZone(); | 130 | buf += ev.timeZone(); |
129 | buf += "\""; | 131 | buf += "\""; |
130 | 132 | ||
131 | if (ev.parent() != 0 ) { | 133 | if (ev.parent() != 0 ) { |
132 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; | 134 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; |
133 | } | 135 | } |
@@ -230,265 +232,269 @@ bool ODateBookAccessBackend_XML::save() { | |||
230 | } | 232 | } |
231 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { | 233 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { |
232 | QArray<int> ints( m_raw.count()+ m_rep.count() ); | 234 | QArray<int> ints( m_raw.count()+ m_rep.count() ); |
233 | uint i = 0; | 235 | uint i = 0; |
234 | QMap<int, OEvent>::ConstIterator it; | 236 | QMap<int, OEvent>::ConstIterator it; |
235 | 237 | ||
236 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 238 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
237 | ints[i] = it.key(); | 239 | ints[i] = it.key(); |
238 | i++; | 240 | i++; |
239 | } | 241 | } |
240 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 242 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
241 | ints[i] = it.key(); | 243 | ints[i] = it.key(); |
242 | i++; | 244 | i++; |
243 | } | 245 | } |
244 | 246 | ||
245 | return ints; | 247 | return ints; |
246 | } | 248 | } |
247 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int, const QDateTime& ) { | 249 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int, const QDateTime& ) { |
248 | return QArray<int>(); | 250 | return QArray<int>(); |
249 | } | 251 | } |
250 | void ODateBookAccessBackend_XML::clear() { | 252 | void ODateBookAccessBackend_XML::clear() { |
251 | m_changed = true; | 253 | m_changed = true; |
252 | m_raw.clear(); | 254 | m_raw.clear(); |
253 | m_rep.clear(); | 255 | m_rep.clear(); |
254 | } | 256 | } |
255 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ | 257 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ |
256 | if ( m_raw.contains( uid ) ) | 258 | if ( m_raw.contains( uid ) ) |
257 | return m_raw[uid]; | 259 | return m_raw[uid]; |
258 | else | 260 | else |
259 | return m_rep[uid]; | 261 | return m_rep[uid]; |
260 | } | 262 | } |
261 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { | 263 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { |
262 | m_changed = true; | 264 | m_changed = true; |
263 | if (ev.hasRecurrence() ) | 265 | if (ev.hasRecurrence() ) |
264 | m_rep.insert( ev.uid(), ev ); | 266 | m_rep.insert( ev.uid(), ev ); |
265 | else | 267 | else |
266 | m_raw.insert( ev.uid(), ev ); | 268 | m_raw.insert( ev.uid(), ev ); |
267 | 269 | ||
268 | return true; | 270 | return true; |
269 | } | 271 | } |
270 | bool ODateBookAccessBackend_XML::remove( int uid ) { | 272 | bool ODateBookAccessBackend_XML::remove( int uid ) { |
271 | m_changed = true; | 273 | m_changed = true; |
272 | m_rep.remove( uid ); | 274 | m_rep.remove( uid ); |
273 | m_rep.remove( uid ); | 275 | m_rep.remove( uid ); |
274 | 276 | ||
275 | return true; | 277 | return true; |
276 | } | 278 | } |
277 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { | 279 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { |
278 | replace( ev.uid() ); | 280 | replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers) |
279 | return add( ev ); | 281 | return add( ev ); |
280 | } | 282 | } |
281 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { | 283 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { |
282 | return allRecords(); | 284 | return allRecords(); |
283 | } | 285 | } |
284 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { | 286 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { |
285 | QArray<int> ints( m_rep.count() ); | 287 | QArray<int> ints( m_rep.count() ); |
286 | uint i = 0; | 288 | uint i = 0; |
287 | QMap<int, OEvent>::ConstIterator it; | 289 | QMap<int, OEvent>::ConstIterator it; |
288 | 290 | ||
289 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 291 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
290 | ints[i] = it.key(); | 292 | ints[i] = it.key(); |
291 | i++; | 293 | i++; |
292 | } | 294 | } |
293 | 295 | ||
294 | return ints; | 296 | return ints; |
295 | } | 297 | } |
296 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { | 298 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { |
297 | QArray<int> ints( m_raw.count() ); | 299 | QArray<int> ints( m_raw.count() ); |
298 | uint i = 0; | 300 | uint i = 0; |
299 | QMap<int, OEvent>::ConstIterator it; | 301 | QMap<int, OEvent>::ConstIterator it; |
300 | 302 | ||
301 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 303 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
302 | ints[i] = it.key(); | 304 | ints[i] = it.key(); |
303 | i++; | 305 | i++; |
304 | } | 306 | } |
305 | 307 | ||
306 | return ints; | 308 | return ints; |
307 | } | 309 | } |
308 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { | 310 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { |
309 | OEvent::ValueList list; | 311 | OEvent::ValueList list; |
310 | QMap<int, OEvent>::ConstIterator it; | 312 | QMap<int, OEvent>::ConstIterator it; |
311 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) | 313 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) |
312 | list.append( it.data() ); | 314 | list.append( it.data() ); |
313 | 315 | ||
314 | return list; | 316 | return list; |
315 | } | 317 | } |
316 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { | 318 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { |
317 | OEvent::ValueList list; | 319 | OEvent::ValueList list; |
318 | QMap<int, OEvent>::ConstIterator it; | 320 | QMap<int, OEvent>::ConstIterator it; |
319 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) | 321 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) |
320 | list.append( it.data() ); | 322 | list.append( it.data() ); |
321 | 323 | ||
322 | return list; | 324 | return list; |
323 | } | 325 | } |
326 | |||
327 | // FIXME: Use OEvent::fromMap() (eilers) | ||
324 | bool ODateBookAccessBackend_XML::loadFile() { | 328 | bool ODateBookAccessBackend_XML::loadFile() { |
325 | m_changed = false; | 329 | m_changed = false; |
326 | 330 | ||
327 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); | 331 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); |
328 | if ( fd < 0 ) return false; | 332 | if ( fd < 0 ) return false; |
329 | 333 | ||
330 | struct stat attribute; | 334 | struct stat attribute; |
331 | if ( ::fstat(fd, &attribute ) == -1 ) { | 335 | if ( ::fstat(fd, &attribute ) == -1 ) { |
332 | ::close( fd ); | 336 | ::close( fd ); |
333 | return false; | 337 | return false; |
334 | } | 338 | } |
335 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 339 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
336 | if ( map_addr == ( (caddr_t)-1) ) { | 340 | if ( map_addr == ( (caddr_t)-1) ) { |
337 | ::close( fd ); | 341 | ::close( fd ); |
338 | return false; | 342 | return false; |
339 | } | 343 | } |
340 | 344 | ||
341 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); | 345 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); |
342 | ::close( fd ); | 346 | ::close( fd ); |
343 | 347 | ||
344 | QAsciiDict<int> dict(FExceptions+1); | 348 | QAsciiDict<int> dict(FExceptions+1); |
345 | dict.setAutoDelete( true ); | 349 | dict.setAutoDelete( true ); |
346 | dict.insert( "description", new int(FDescription) ); | 350 | dict.insert( "description", new int(FDescription) ); |
347 | dict.insert( "location", new int(FLocation) ); | 351 | dict.insert( "location", new int(FLocation) ); |
348 | dict.insert( "categories", new int(FCategories) ); | 352 | dict.insert( "categories", new int(FCategories) ); |
349 | dict.insert( "uid", new int(FUid) ); | 353 | dict.insert( "uid", new int(FUid) ); |
350 | dict.insert( "type", new int(FType) ); | 354 | dict.insert( "type", new int(FType) ); |
351 | dict.insert( "alarm", new int(FAlarm) ); | 355 | dict.insert( "alarm", new int(FAlarm) ); |
352 | dict.insert( "sound", new int(FSound) ); | 356 | dict.insert( "sound", new int(FSound) ); |
353 | dict.insert( "rtype", new int(FRType) ); | 357 | dict.insert( "rtype", new int(FRType) ); |
354 | dict.insert( "rweekdays", new int(FRWeekdays) ); | 358 | dict.insert( "rweekdays", new int(FRWeekdays) ); |
355 | dict.insert( "rposition", new int(FRPosition) ); | 359 | dict.insert( "rposition", new int(FRPosition) ); |
356 | dict.insert( "rfreq", new int(FRFreq) ); | 360 | dict.insert( "rfreq", new int(FRFreq) ); |
357 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); | 361 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); |
358 | dict.insert( "enddt", new int(FREndDate) ); | 362 | dict.insert( "enddt", new int(FREndDate) ); |
359 | dict.insert( "start", new int(FRStart) ); | 363 | dict.insert( "start", new int(FRStart) ); |
360 | dict.insert( "end", new int(FREnd) ); | 364 | dict.insert( "end", new int(FREnd) ); |
361 | dict.insert( "note", new int(FNote) ); | 365 | dict.insert( "note", new int(FNote) ); |
362 | dict.insert( "created", new int(FCreated) ); | 366 | dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? |
363 | dict.insert( "recparent", new int(FRecParent) ); | 367 | dict.insert( "recparent", new int(FRecParent) ); |
364 | dict.insert( "recchildren", new int(FRecChildren) ); | 368 | dict.insert( "recchildren", new int(FRecChildren) ); |
365 | dict.insert( "exceptions", new int(FExceptions) ); | 369 | dict.insert( "exceptions", new int(FExceptions) ); |
366 | dict.insert( "timezone", new int(FTimeZone) ); | 370 | dict.insert( "timezone", new int(FTimeZone) ); |
367 | 371 | ||
368 | char* dt = (char*)map_addr; | 372 | char* dt = (char*)map_addr; |
369 | int len = attribute.st_size; | 373 | int len = attribute.st_size; |
370 | int i = 0; | 374 | int i = 0; |
371 | char* point; | 375 | char* point; |
372 | const char* collectionString = "<event "; | 376 | const char* collectionString = "<event "; |
373 | int strLen = ::strlen(collectionString); | 377 | int strLen = ::strlen(collectionString); |
374 | int *find; | 378 | int *find; |
375 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { | 379 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { |
376 | i = point -dt; | 380 | i = point -dt; |
377 | i+= strLen; | 381 | i+= strLen; |
378 | 382 | ||
379 | alarmTime = -1; | 383 | alarmTime = -1; |
380 | snd = 0; // silent | 384 | snd = 0; // silent |
381 | 385 | ||
382 | OEvent ev; | 386 | OEvent ev; |
383 | rec = 0; | 387 | rec = 0; |
384 | 388 | ||
385 | while ( TRUE ) { | 389 | while ( TRUE ) { |
386 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 390 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
387 | ++i; | 391 | ++i; |
388 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 392 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
389 | break; | 393 | break; |
390 | 394 | ||
391 | 395 | ||
392 | // we have another attribute, read it. | 396 | // we have another attribute, read it. |
393 | int j = i; | 397 | int j = i; |
394 | while ( j < len && dt[j] != '=' ) | 398 | while ( j < len && dt[j] != '=' ) |
395 | ++j; | 399 | ++j; |
396 | QCString attr( dt+i, j-i+1); | 400 | QCString attr( dt+i, j-i+1); |
397 | 401 | ||
398 | i = ++j; // skip = | 402 | i = ++j; // skip = |
399 | 403 | ||
400 | // find the start of quotes | 404 | // find the start of quotes |
401 | while ( i < len && dt[i] != '"' ) | 405 | while ( i < len && dt[i] != '"' ) |
402 | ++i; | 406 | ++i; |
403 | j = ++i; | 407 | j = ++i; |
404 | 408 | ||
405 | bool haveUtf = FALSE; | 409 | bool haveUtf = FALSE; |
406 | bool haveEnt = FALSE; | 410 | bool haveEnt = FALSE; |
407 | while ( j < len && dt[j] != '"' ) { | 411 | while ( j < len && dt[j] != '"' ) { |
408 | if ( ((unsigned char)dt[j]) > 0x7f ) | 412 | if ( ((unsigned char)dt[j]) > 0x7f ) |
409 | haveUtf = TRUE; | 413 | haveUtf = TRUE; |
410 | if ( dt[j] == '&' ) | 414 | if ( dt[j] == '&' ) |
411 | haveEnt = TRUE; | 415 | haveEnt = TRUE; |
412 | ++j; | 416 | ++j; |
413 | } | 417 | } |
414 | if ( i == j ) { | 418 | if ( i == j ) { |
415 | // empty value | 419 | // empty value |
416 | i = j + 1; | 420 | i = j + 1; |
417 | continue; | 421 | continue; |
418 | } | 422 | } |
419 | 423 | ||
420 | QCString value( dt+i, j-i+1 ); | 424 | QCString value( dt+i, j-i+1 ); |
421 | i = j + 1; | 425 | i = j + 1; |
422 | 426 | ||
423 | QString str = (haveUtf ? QString::fromUtf8( value ) | 427 | QString str = (haveUtf ? QString::fromUtf8( value ) |
424 | : QString::fromLatin1( value ) ); | 428 | : QString::fromLatin1( value ) ); |
425 | if ( haveEnt ) | 429 | if ( haveEnt ) |
426 | str = Qtopia::plainString( str ); | 430 | str = Qtopia::plainString( str ); |
427 | 431 | ||
428 | /* | 432 | /* |
429 | * add key + value | 433 | * add key + value |
430 | */ | 434 | */ |
431 | find = dict[attr.data()]; | 435 | find = dict[attr.data()]; |
432 | if (!find) | 436 | if (!find) |
433 | ev.setCustomField( attr, str ); | 437 | ev.setCustomField( attr, str ); |
434 | else { | 438 | else { |
435 | setField( ev, *find, str ); | 439 | setField( ev, *find, str ); |
436 | } | 440 | } |
437 | } | 441 | } |
438 | /* time to finalize */ | 442 | /* time to finalize */ |
439 | finalizeRecord( ev ); | 443 | finalizeRecord( ev ); |
440 | delete rec; | 444 | delete rec; |
441 | } | 445 | } |
442 | ::munmap(map_addr, attribute.st_size ); | 446 | ::munmap(map_addr, attribute.st_size ); |
443 | m_changed = false; // changed during add | 447 | m_changed = false; // changed during add |
444 | 448 | ||
445 | return true; | 449 | return true; |
446 | } | 450 | } |
451 | |||
452 | // FIXME: Use OEvent::fromMap() which makes this obsolete.. (eilers) | ||
447 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { | 453 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { |
448 | /* AllDay is alway in UTC */ | 454 | /* AllDay is alway in UTC */ |
449 | if ( ev.isAllDay() ) { | 455 | if ( ev.isAllDay() ) { |
450 | OTimeZone utc = OTimeZone::utc(); | 456 | OTimeZone utc = OTimeZone::utc(); |
451 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); | 457 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); |
452 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); | 458 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); |
453 | ev.setTimeZone( "UTC"); // make sure it is really utc | 459 | ev.setTimeZone( "UTC"); // make sure it is really utc |
454 | }else { | 460 | }else { |
455 | /* to current date time */ | 461 | /* to current date time */ |
456 | // qWarning(" Start is %d", start ); | 462 | // qWarning(" Start is %d", start ); |
457 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | 463 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); |
458 | QDateTime date = zone.toDateTime( start ); | 464 | QDateTime date = zone.toDateTime( start ); |
459 | qWarning(" Start is %s", date.toString().latin1() ); | 465 | qWarning(" Start is %s", date.toString().latin1() ); |
460 | ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); | 466 | ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); |
461 | 467 | ||
462 | date = zone.toDateTime( end ); | 468 | date = zone.toDateTime( end ); |
463 | ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); | 469 | ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); |
464 | } | 470 | } |
465 | if ( rec && rec->doesRecur() ) { | 471 | if ( rec && rec->doesRecur() ) { |
466 | OTimeZone utc = OTimeZone::utc(); | 472 | OTimeZone utc = OTimeZone::utc(); |
467 | ORecur recu( *rec ); // call copy c'tor; | 473 | ORecur recu( *rec ); // call copy c'tor; |
468 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); | 474 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); |
469 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); | 475 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); |
470 | recu.setStart( ev.startDateTime().date() ); | 476 | recu.setStart( ev.startDateTime().date() ); |
471 | ev.setRecurrence( recu ); | 477 | ev.setRecurrence( recu ); |
472 | } | 478 | } |
473 | 479 | ||
474 | if (alarmTime != -1 ) { | 480 | if (alarmTime != -1 ) { |
475 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); | 481 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); |
476 | OPimAlarm al( snd , dt ); | 482 | OPimAlarm al( snd , dt ); |
477 | ev.notifiers().add( al ); | 483 | ev.notifiers().add( al ); |
478 | } | 484 | } |
479 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { | 485 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { |
480 | qWarning("already contains assign uid"); | 486 | qWarning("already contains assign uid"); |
481 | ev.setUid( 1 ); | 487 | ev.setUid( 1 ); |
482 | } | 488 | } |
483 | qWarning("addind %d %s", ev.uid(), ev.description().latin1() ); | 489 | qWarning("addind %d %s", ev.uid(), ev.description().latin1() ); |
484 | if ( ev.hasRecurrence() ) | 490 | if ( ev.hasRecurrence() ) |
485 | m_rep.insert( ev.uid(), ev ); | 491 | m_rep.insert( ev.uid(), ev ); |
486 | else | 492 | else |
487 | m_raw.insert( ev.uid(), ev ); | 493 | m_raw.insert( ev.uid(), ev ); |
488 | 494 | ||
489 | } | 495 | } |
490 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { | 496 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { |
491 | // qWarning(" setting %s", value.latin1() ); | 497 | // qWarning(" setting %s", value.latin1() ); |
492 | switch( id ) { | 498 | switch( id ) { |
493 | case FDescription: | 499 | case FDescription: |
494 | e.setDescription( value ); | 500 | e.setDescription( value ); |
diff --git a/libopie/pim/oevent.cpp b/libopie/pim/oevent.cpp index 7bcf944..c916297 100644 --- a/libopie/pim/oevent.cpp +++ b/libopie/pim/oevent.cpp | |||
@@ -1,49 +1,50 @@ | |||
1 | #include <qshared.h> | 1 | #include <qshared.h> |
2 | #include <qarray.h> | ||
2 | 3 | ||
3 | #include <qpe/palmtopuidgen.h> | 4 | #include <qpe/palmtopuidgen.h> |
4 | #include <qpe/categories.h> | 5 | #include <qpe/categories.h> |
5 | #include <qpe/stringutil.h> | 6 | #include <qpe/stringutil.h> |
6 | 7 | ||
7 | #include "orecur.h" | 8 | #include "orecur.h" |
8 | #include "opimresolver.h" | 9 | #include "opimresolver.h" |
9 | #include "opimnotifymanager.h" | 10 | #include "opimnotifymanager.h" |
10 | 11 | ||
11 | #include "oevent.h" | 12 | #include "oevent.h" |
12 | 13 | ||
13 | int OCalendarHelper::week( const QDate& date) { | 14 | int OCalendarHelper::week( const QDate& date) { |
14 | // Calculates the week this date is in within that | 15 | // Calculates the week this date is in within that |
15 | // month. Equals the "row" is is in in the month view | 16 | // month. Equals the "row" is is in in the month view |
16 | int week = 1; | 17 | int week = 1; |
17 | QDate tmp( date.year(), date.month(), 1 ); | 18 | QDate tmp( date.year(), date.month(), 1 ); |
18 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) | 19 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) |
19 | ++week; | 20 | ++week; |
20 | 21 | ||
21 | week += ( date.day() - 1 ) / 7; | 22 | week += ( date.day() - 1 ) / 7; |
22 | 23 | ||
23 | return week; | 24 | return week; |
24 | } | 25 | } |
25 | int OCalendarHelper::ocurrence( const QDate& date) { | 26 | int OCalendarHelper::ocurrence( const QDate& date) { |
26 | // calculates the number of occurrances of this day of the | 27 | // calculates the number of occurrances of this day of the |
27 | // week till the given date (e.g 3rd Wednesday of the month) | 28 | // week till the given date (e.g 3rd Wednesday of the month) |
28 | return ( date.day() - 1 ) / 7 + 1; | 29 | return ( date.day() - 1 ) / 7 + 1; |
29 | } | 30 | } |
30 | int OCalendarHelper::dayOfWeek( char day ) { | 31 | int OCalendarHelper::dayOfWeek( char day ) { |
31 | int dayOfWeek = 1; | 32 | int dayOfWeek = 1; |
32 | char i = ORecur::MON; | 33 | char i = ORecur::MON; |
33 | while ( !( i & day ) && i <= ORecur::SUN ) { | 34 | while ( !( i & day ) && i <= ORecur::SUN ) { |
34 | i <<= 1; | 35 | i <<= 1; |
35 | ++dayOfWeek; | 36 | ++dayOfWeek; |
36 | } | 37 | } |
37 | return dayOfWeek; | 38 | return dayOfWeek; |
38 | } | 39 | } |
39 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { | 40 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { |
40 | return ( second.year() - first.year() ) * 12 + | 41 | return ( second.year() - first.year() ) * 12 + |
41 | second.month() - first.month(); | 42 | second.month() - first.month(); |
42 | } | 43 | } |
43 | 44 | ||
44 | struct OEvent::Data : public QShared { | 45 | struct OEvent::Data : public QShared { |
45 | Data() : QShared() { | 46 | Data() : QShared() { |
46 | child = 0; | 47 | child = 0; |
47 | recur = 0; | 48 | recur = 0; |
48 | manager = 0; | 49 | manager = 0; |
49 | isAllDay = false; | 50 | isAllDay = false; |
@@ -311,100 +312,226 @@ QString OEvent::type()const { | |||
311 | } | 312 | } |
312 | QString OEvent::recordField( int /*id */ )const { | 313 | QString OEvent::recordField( int /*id */ )const { |
313 | return QString::null; | 314 | return QString::null; |
314 | } | 315 | } |
315 | int OEvent::rtti() { | 316 | int OEvent::rtti() { |
316 | return OPimResolver::DateBook; | 317 | return OPimResolver::DateBook; |
317 | } | 318 | } |
318 | bool OEvent::loadFromStream( QDataStream& ) { | 319 | bool OEvent::loadFromStream( QDataStream& ) { |
319 | return true; | 320 | return true; |
320 | } | 321 | } |
321 | bool OEvent::saveToStream( QDataStream& )const { | 322 | bool OEvent::saveToStream( QDataStream& )const { |
322 | return true; | 323 | return true; |
323 | } | 324 | } |
324 | void OEvent::changeOrModify() { | 325 | void OEvent::changeOrModify() { |
325 | if ( data->count != 1 ) { | 326 | if ( data->count != 1 ) { |
326 | data->deref(); | 327 | data->deref(); |
327 | Data* d2 = new Data; | 328 | Data* d2 = new Data; |
328 | d2->description = data->description; | 329 | d2->description = data->description; |
329 | d2->location = data->location; | 330 | d2->location = data->location; |
330 | 331 | ||
331 | if (data->manager ) | 332 | if (data->manager ) |
332 | d2->manager = new OPimNotifyManager( *data->manager ); | 333 | d2->manager = new OPimNotifyManager( *data->manager ); |
333 | 334 | ||
334 | if ( data->recur ) | 335 | if ( data->recur ) |
335 | d2->recur = new ORecur( *data->recur ); | 336 | d2->recur = new ORecur( *data->recur ); |
336 | 337 | ||
337 | d2->note = data->note; | 338 | d2->note = data->note; |
338 | d2->created = data->created; | 339 | d2->created = data->created; |
339 | d2->start = data->start; | 340 | d2->start = data->start; |
340 | d2->end = data->end; | 341 | d2->end = data->end; |
341 | d2->isAllDay = data->isAllDay; | 342 | d2->isAllDay = data->isAllDay; |
342 | d2->timezone = data->timezone; | 343 | d2->timezone = data->timezone; |
343 | d2->parent = data->parent; | 344 | d2->parent = data->parent; |
344 | 345 | ||
345 | if ( data->child ) { | 346 | if ( data->child ) { |
346 | d2->child = new QArray<int>( *data->child ); | 347 | d2->child = new QArray<int>( *data->child ); |
347 | d2->child->detach(); | 348 | d2->child->detach(); |
348 | } | 349 | } |
349 | 350 | ||
350 | data = d2; | 351 | data = d2; |
351 | } | 352 | } |
352 | } | 353 | } |
353 | void OEvent::deref() { | 354 | void OEvent::deref() { |
354 | if ( data->deref() ) { | 355 | if ( data->deref() ) { |
355 | delete data; | 356 | delete data; |
356 | data = 0; | 357 | data = 0; |
357 | } | 358 | } |
358 | } | 359 | } |
359 | // FIXME | 360 | // Exporting Event data to map. Using the same |
361 | // encoding as ODateBookAccessBackend_xml does.. | ||
362 | // Thus, we could remove the stuff there and use this | ||
363 | // for it and for all other places.. | ||
364 | // Encoding should happen at one place, only ! (eilers) | ||
360 | QMap<int, QString> OEvent::toMap()const { | 365 | QMap<int, QString> OEvent::toMap()const { |
361 | return QMap<int, QString>(); | 366 | QMap<int, QString> retMap; |
367 | |||
368 | retMap.insert( OEvent::FUid, QString::number( uid() ) ); | ||
369 | retMap.insert( OEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) )); | ||
370 | retMap.insert( OEvent::FDescription, Qtopia::escapeString( description() ) ); | ||
371 | retMap.insert( OEvent::FLocation, Qtopia::escapeString( location() ) ); | ||
372 | retMap.insert( OEvent::FType, isAllDay() ? "AllDay" : "" ); | ||
373 | OPimAlarm alarm = notifiers().alarms()[0]; | ||
374 | retMap.insert( OEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); | ||
375 | retMap.insert( OEvent::FSound, (alarm.sound() == OPimAlarm::Loud) ? "loud" : "silent" ); | ||
376 | |||
377 | OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); | ||
378 | retMap.insert( OEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OTimeZone::utc() ) ) ) ); | ||
379 | retMap.insert( OEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OTimeZone::utc() ) ) ) ); | ||
380 | retMap.insert( OEvent::FNote, Qtopia::escapeString( note() ) ); | ||
381 | retMap.insert( OEvent::FTimeZone, timeZone().isEmpty() ? "None" : timeZone() ); | ||
382 | if( parent() ) | ||
383 | retMap.insert( OEvent::FRecParent, QString::number( parent() ) ); | ||
384 | if( children().count() ){ | ||
385 | QArray<int> childr = children(); | ||
386 | QString buf; | ||
387 | for ( uint i = 0; i < childr.count(); i++ ) { | ||
388 | if ( i != 0 ) buf += " "; | ||
389 | buf += QString::number( childr[i] ); | ||
390 | } | ||
391 | retMap.insert( OEvent::FRecChildren, buf ); | ||
392 | } | ||
393 | |||
394 | // Add recurrence stuff | ||
395 | if( hasRecurrence() ){ | ||
396 | ORecur recur = recurrence(); | ||
397 | QMap<int, QString> recFields = recur.toMap(); | ||
398 | retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); | ||
399 | retMap.insert( OEvent::FRWeekdays, recFields[ORecur::RWeekdays] ); | ||
400 | retMap.insert( OEvent::FRPosition, recFields[ORecur::RPosition] ); | ||
401 | retMap.insert( OEvent::FRFreq, recFields[ORecur::RFreq] ); | ||
402 | retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] ); | ||
403 | retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] ); | ||
404 | retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] ); | ||
405 | retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] ); | ||
406 | } | ||
407 | |||
408 | return retMap; | ||
409 | } | ||
410 | |||
411 | void OEvent::fromMap( const QMap<int, QString>& map ) | ||
412 | { | ||
413 | |||
414 | // We just want to set the UID if it is really stored. | ||
415 | if ( !map[OEvent::FUid].isEmpty() ) | ||
416 | setUid( map[OEvent::FUid].toInt() ); | ||
417 | |||
418 | setCategories( idsFromString( map[OEvent::FCategories] ) ); | ||
419 | setDescription( map[OEvent::FDescription] ); | ||
420 | setLocation( map[OEvent::FLocation] ); | ||
421 | |||
422 | if ( map[OEvent::FType] == "AllDay" ) | ||
423 | setAllDay( true ); | ||
424 | else | ||
425 | setAllDay( false ); | ||
426 | |||
427 | int alarmTime = -1; | ||
428 | if( !map[OEvent::FAlarm].isEmpty() ) | ||
429 | alarmTime = map[OEvent::FAlarm].toInt(); | ||
430 | |||
431 | int sound = ( ( map[OEvent::FSound] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent ); | ||
432 | if ( ( alarmTime != -1 ) ){ | ||
433 | QDateTime dt = startDateTime().addSecs( -1*alarmTime*60 ); | ||
434 | OPimAlarm al( sound , dt ); | ||
435 | notifiers().add( al ); | ||
436 | } | ||
437 | if ( !map[OEvent::FTimeZone].isEmpty() && ( map[OEvent::FTimeZone] != "None" ) ){ | ||
438 | setTimeZone( map[OEvent::FTimeZone] ); | ||
439 | } | ||
440 | |||
441 | time_t start = (time_t) map[OEvent::FStart].toLong(); | ||
442 | time_t end = (time_t) map[OEvent::FEnd].toLong(); | ||
443 | |||
444 | /* AllDay is always in UTC */ | ||
445 | if ( isAllDay() ) { | ||
446 | OTimeZone utc = OTimeZone::utc(); | ||
447 | setStartDateTime( utc.fromUTCDateTime( start ) ); | ||
448 | setEndDateTime ( utc.fromUTCDateTime( end ) ); | ||
449 | setTimeZone( "UTC"); // make sure it is really utc | ||
450 | }else { | ||
451 | /* to current date time */ | ||
452 | // qWarning(" Start is %d", start ); | ||
453 | OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); | ||
454 | QDateTime date = zone.toDateTime( start ); | ||
455 | qWarning(" Start is %s", date.toString().latin1() ); | ||
456 | setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); | ||
457 | |||
458 | date = zone.toDateTime( end ); | ||
459 | setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); | ||
460 | } | ||
461 | |||
462 | if ( !map[OEvent::FRecParent].isEmpty() ) | ||
463 | setParent( map[OEvent::FRecParent].toInt() ); | ||
464 | |||
465 | if ( !map[OEvent::FRecChildren].isEmpty() ){ | ||
466 | QStringList list = QStringList::split(' ', map[OEvent::FRecChildren] ); | ||
467 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { | ||
468 | addChild( (*it).toInt() ); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | // Fill recurrence stuff and put it directly into the ORecur-Object using fromMap.. | ||
473 | if( !map[OEvent::FRType].isEmpty() ){ | ||
474 | QMap<int, QString> recFields; | ||
475 | recFields.insert( ORecur::RType, map[OEvent::FRType] ); | ||
476 | recFields.insert( ORecur::RWeekdays, map[OEvent::FRWeekdays] ); | ||
477 | recFields.insert( ORecur::RPosition, map[OEvent::FRPosition] ); | ||
478 | recFields.insert( ORecur::RFreq, map[OEvent::FRFreq] ); | ||
479 | recFields.insert( ORecur::RHasEndDate, map[OEvent::FRHasEndDate] ); | ||
480 | recFields.insert( ORecur::EndDate, map[OEvent::FREndDate] ); | ||
481 | recFields.insert( ORecur::Created, map[OEvent::FRCreated] ); | ||
482 | recFields.insert( ORecur::Exceptions, map[OEvent::FRExceptions] ); | ||
483 | ORecur recur( recFields ); | ||
484 | setRecurrence( recur ); | ||
485 | } | ||
486 | |||
362 | } | 487 | } |
488 | |||
489 | |||
363 | int OEvent::parent()const { | 490 | int OEvent::parent()const { |
364 | return data->parent; | 491 | return data->parent; |
365 | } | 492 | } |
366 | void OEvent::setParent( int uid ) { | 493 | void OEvent::setParent( int uid ) { |
367 | changeOrModify(); | 494 | changeOrModify(); |
368 | data->parent = uid; | 495 | data->parent = uid; |
369 | } | 496 | } |
370 | QArray<int> OEvent::children() const{ | 497 | QArray<int> OEvent::children() const{ |
371 | if (!data->child) return QArray<int>(); | 498 | if (!data->child) return QArray<int>(); |
372 | else | 499 | else |
373 | return data->child->copy(); | 500 | return data->child->copy(); |
374 | } | 501 | } |
375 | void OEvent::setChildren( const QArray<int>& arr ) { | 502 | void OEvent::setChildren( const QArray<int>& arr ) { |
376 | changeOrModify(); | 503 | changeOrModify(); |
377 | if (data->child) delete data->child; | 504 | if (data->child) delete data->child; |
378 | 505 | ||
379 | data->child = new QArray<int>( arr ); | 506 | data->child = new QArray<int>( arr ); |
380 | data->child->detach(); | 507 | data->child->detach(); |
381 | } | 508 | } |
382 | void OEvent::addChild( int uid ) { | 509 | void OEvent::addChild( int uid ) { |
383 | changeOrModify(); | 510 | changeOrModify(); |
384 | if (!data->child ) { | 511 | if (!data->child ) { |
385 | data->child = new QArray<int>(1); | 512 | data->child = new QArray<int>(1); |
386 | (*data->child)[0] = uid; | 513 | (*data->child)[0] = uid; |
387 | }else{ | 514 | }else{ |
388 | int count = data->child->count(); | 515 | int count = data->child->count(); |
389 | data->child->resize( count + 1 ); | 516 | data->child->resize( count + 1 ); |
390 | (*data->child)[count] = uid; | 517 | (*data->child)[count] = uid; |
391 | } | 518 | } |
392 | } | 519 | } |
393 | void OEvent::removeChild( int uid ) { | 520 | void OEvent::removeChild( int uid ) { |
394 | if (!data->child || !data->child->contains( uid ) ) return; | 521 | if (!data->child || !data->child->contains( uid ) ) return; |
395 | changeOrModify(); | 522 | changeOrModify(); |
396 | QArray<int> newAr( data->child->count() - 1 ); | 523 | QArray<int> newAr( data->child->count() - 1 ); |
397 | int j = 0; | 524 | int j = 0; |
398 | uint count = data->child->count(); | 525 | uint count = data->child->count(); |
399 | for ( uint i = 0; i < count; i++ ) { | 526 | for ( uint i = 0; i < count; i++ ) { |
400 | if ( (*data->child)[i] != uid ) { | 527 | if ( (*data->child)[i] != uid ) { |
401 | newAr[j] = (*data->child)[i]; | 528 | newAr[j] = (*data->child)[i]; |
402 | j++; | 529 | j++; |
403 | } | 530 | } |
404 | } | 531 | } |
405 | (*data->child) = newAr; | 532 | (*data->child) = newAr; |
406 | } | 533 | } |
407 | struct OEffectiveEvent::Data : public QShared { | 534 | struct OEffectiveEvent::Data : public QShared { |
408 | Data() : QShared() { | 535 | Data() : QShared() { |
409 | } | 536 | } |
410 | OEvent event; | 537 | OEvent event; |
diff --git a/libopie/pim/oevent.h b/libopie/pim/oevent.h index 30f442e..9218c97 100644 --- a/libopie/pim/oevent.h +++ b/libopie/pim/oevent.h | |||
@@ -1,182 +1,192 @@ | |||
1 | // CONTAINS GPLed code of TT | 1 | // CONTAINS GPLed code of TT |
2 | 2 | ||
3 | #ifndef OPIE_PIM_EVENT_H | 3 | #ifndef OPIE_PIM_EVENT_H |
4 | #define OPIE_PIM_EVENT_H | 4 | #define OPIE_PIM_EVENT_H |
5 | 5 | ||
6 | #include <qstring.h> | 6 | #include <qstring.h> |
7 | #include <qdatetime.h> | 7 | #include <qdatetime.h> |
8 | #include <qvaluelist.h> | 8 | #include <qvaluelist.h> |
9 | 9 | ||
10 | #include <qpe/recordfields.h> | 10 | #include <qpe/recordfields.h> |
11 | #include <qpe/palmtopuidgen.h> | 11 | #include <qpe/palmtopuidgen.h> |
12 | 12 | ||
13 | #include "otimezone.h" | 13 | #include "otimezone.h" |
14 | #include "opimrecord.h" | 14 | #include "opimrecord.h" |
15 | 15 | ||
16 | struct OCalendarHelper { | 16 | struct OCalendarHelper { |
17 | /** calculate the week number of the date */ | 17 | /** calculate the week number of the date */ |
18 | static int week( const QDate& ); | 18 | static int week( const QDate& ); |
19 | /** calculate the occurence of week days since the start of the month */ | 19 | /** calculate the occurence of week days since the start of the month */ |
20 | static int ocurrence( const QDate& ); | 20 | static int ocurrence( const QDate& ); |
21 | 21 | ||
22 | // returns the dayOfWeek for the *first* day it finds (ignores | 22 | // returns the dayOfWeek for the *first* day it finds (ignores |
23 | // any further days!). Returns 1 (Monday) if there isn't any day found | 23 | // any further days!). Returns 1 (Monday) if there isn't any day found |
24 | static int dayOfWeek( char day ); | 24 | static int dayOfWeek( char day ); |
25 | 25 | ||
26 | /** returns the diff of month */ | 26 | /** returns the diff of month */ |
27 | static int monthDiff( const QDate& first, const QDate& second ); | 27 | static int monthDiff( const QDate& first, const QDate& second ); |
28 | 28 | ||
29 | }; | 29 | }; |
30 | 30 | ||
31 | class OPimNotifyManager; | 31 | class OPimNotifyManager; |
32 | class ORecur; | 32 | class ORecur; |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * This is the container for all Events. It encapsules all | 35 | * This is the container for all Events. It encapsules all |
36 | * available information for a single Event | 36 | * available information for a single Event |
37 | * @short container for events. | 37 | * @short container for events. |
38 | */ | 38 | */ |
39 | class OEvent : public OPimRecord { | 39 | class OEvent : public OPimRecord { |
40 | public: | 40 | public: |
41 | typedef QValueList<OEvent> ValueList; | 41 | typedef QValueList<OEvent> ValueList; |
42 | /** | 42 | /** |
43 | * RecordFields contain possible attributes | 43 | * RecordFields contain possible attributes |
44 | * used in the Results of toMap().. | ||
44 | */ | 45 | */ |
45 | enum RecordFields { | 46 | enum RecordFields { |
46 | Uid = Qtopia::UID_ID, | 47 | FUid = Qtopia::UID_ID, |
47 | Category = Qtopia::CATEGORY_ID, | 48 | FCategories = Qtopia::CATEGORY_ID, |
48 | Description, | 49 | FDescription = 0, |
49 | Location, | 50 | FLocation, |
50 | Alarm, | 51 | FType, |
51 | Reminder, | 52 | FAlarm, |
52 | Recurrence, | 53 | FSound, |
53 | Note, | 54 | FRType, |
54 | Created, | 55 | FRWeekdays, |
55 | StartDate, | 56 | FRPosition, |
56 | EndDate, | 57 | FRFreq, |
57 | AllDay, | 58 | FRHasEndDate, |
58 | TimeZone | 59 | FREndDate, |
60 | FRCreated, | ||
61 | FRExceptions, | ||
62 | FStart, | ||
63 | FEnd, | ||
64 | FNote, | ||
65 | FTimeZone, | ||
66 | FRecParent, | ||
67 | FRecChildren, | ||
59 | }; | 68 | }; |
60 | 69 | ||
61 | /** | 70 | /** |
62 | * Start with an Empty OEvent. UID == 0 means that it is empty | 71 | * Start with an Empty OEvent. UID == 0 means that it is empty |
63 | */ | 72 | */ |
64 | OEvent(int uid = 0); | 73 | OEvent(int uid = 0); |
65 | 74 | ||
66 | /** | 75 | /** |
67 | * copy c'tor | 76 | * copy c'tor |
68 | */ | 77 | */ |
69 | OEvent( const OEvent& ); | 78 | OEvent( const OEvent& ); |
70 | ~OEvent(); | 79 | ~OEvent(); |
71 | OEvent &operator=( const OEvent& ); | 80 | OEvent &operator=( const OEvent& ); |
72 | 81 | ||
73 | QString description()const; | 82 | QString description()const; |
74 | void setDescription( const QString& description ); | 83 | void setDescription( const QString& description ); |
75 | 84 | ||
76 | QString location()const; | 85 | QString location()const; |
77 | void setLocation( const QString& loc ); | 86 | void setLocation( const QString& loc ); |
78 | 87 | ||
79 | bool hasNotifiers()const; | 88 | bool hasNotifiers()const; |
80 | OPimNotifyManager ¬ifiers()const; | 89 | OPimNotifyManager ¬ifiers()const; |
81 | 90 | ||
82 | ORecur recurrence()const; | 91 | ORecur recurrence()const; |
83 | void setRecurrence( const ORecur& ); | 92 | void setRecurrence( const ORecur& ); |
84 | bool hasRecurrence()const; | 93 | bool hasRecurrence()const; |
85 | 94 | ||
86 | QString note()const; | 95 | QString note()const; |
87 | void setNote( const QString& note ); | 96 | void setNote( const QString& note ); |
88 | 97 | ||
89 | 98 | ||
90 | QDateTime createdDateTime()const; | 99 | QDateTime createdDateTime()const; |
91 | void setCreatedDateTime( const QDateTime& dt); | 100 | void setCreatedDateTime( const QDateTime& dt); |
92 | 101 | ||
93 | /** set the date to dt. dt is the QDateTime in localtime */ | 102 | /** set the date to dt. dt is the QDateTime in localtime */ |
94 | void setStartDateTime( const QDateTime& ); | 103 | void setStartDateTime( const QDateTime& ); |
95 | /** returns the datetime in the local timeZone */ | 104 | /** returns the datetime in the local timeZone */ |
96 | QDateTime startDateTime()const; | 105 | QDateTime startDateTime()const; |
97 | 106 | ||
98 | /** returns the start datetime in the current zone */ | 107 | /** returns the start datetime in the current zone */ |
99 | QDateTime startDateTimeInZone()const; | 108 | QDateTime startDateTimeInZone()const; |
100 | 109 | ||
101 | /** in current timezone */ | 110 | /** in current timezone */ |
102 | void setEndDateTime( const QDateTime& ); | 111 | void setEndDateTime( const QDateTime& ); |
103 | /** in current timezone */ | 112 | /** in current timezone */ |
104 | QDateTime endDateTime()const; | 113 | QDateTime endDateTime()const; |
105 | QDateTime endDateTimeInZone()const; | 114 | QDateTime endDateTimeInZone()const; |
106 | 115 | ||
107 | bool isMultipleDay()const; | 116 | bool isMultipleDay()const; |
108 | bool isAllDay()const; | 117 | bool isAllDay()const; |
109 | void setAllDay( bool isAllDay ); | 118 | void setAllDay( bool isAllDay ); |
110 | 119 | ||
111 | /* pin this event to a timezone! FIXME */ | 120 | /* pin this event to a timezone! FIXME */ |
112 | void setTimeZone( const QString& timeZone ); | 121 | void setTimeZone( const QString& timeZone ); |
113 | QString timeZone()const; | 122 | QString timeZone()const; |
114 | 123 | ||
115 | 124 | ||
116 | virtual bool match( const QRegExp& )const; | 125 | virtual bool match( const QRegExp& )const; |
117 | 126 | ||
118 | /** For exception to recurrence here is a list of children... */ | 127 | /** For exception to recurrence here is a list of children... */ |
119 | QArray<int> children()const; | 128 | QArray<int> children()const; |
120 | void setChildren( const QArray<int>& ); | 129 | void setChildren( const QArray<int>& ); |
121 | void addChild( int uid ); | 130 | void addChild( int uid ); |
122 | void removeChild( int uid ); | 131 | void removeChild( int uid ); |
123 | 132 | ||
124 | /** return the parent OEvent */ | 133 | /** return the parent OEvent */ |
125 | int parent()const; | 134 | int parent()const; |
126 | void setParent( int uid ); | 135 | void setParent( int uid ); |
127 | 136 | ||
128 | 137 | ||
129 | /* needed reimp */ | 138 | /* needed reimp */ |
130 | QString toRichText()const; | 139 | QString toRichText()const; |
131 | QString toShortText()const; | 140 | QString toShortText()const; |
132 | QString type()const; | 141 | QString type()const; |
133 | 142 | ||
134 | QMap<int, QString> toMap()const; | 143 | QMap<int, QString> toMap()const; |
144 | void fromMap( const QMap<int, QString>& map ); | ||
135 | QString recordField(int )const; | 145 | QString recordField(int )const; |
136 | 146 | ||
137 | static int rtti(); | 147 | static int rtti(); |
138 | 148 | ||
139 | bool loadFromStream( QDataStream& ); | 149 | bool loadFromStream( QDataStream& ); |
140 | bool saveToStream( QDataStream& )const; | 150 | bool saveToStream( QDataStream& )const; |
141 | 151 | ||
142 | /* bool operator==( const OEvent& ); | 152 | /* bool operator==( const OEvent& ); |
143 | bool operator!=( const OEvent& ); | 153 | bool operator!=( const OEvent& ); |
144 | bool operator<( const OEvent& ); | 154 | bool operator<( const OEvent& ); |
145 | bool operator<=( const OEvent& ); | 155 | bool operator<=( const OEvent& ); |
146 | bool operator>( const OEvent& ); | 156 | bool operator>( const OEvent& ); |
147 | bool operator>=(const OEvent& ); | 157 | bool operator>=(const OEvent& ); |
148 | */ | 158 | */ |
149 | private: | 159 | private: |
150 | inline void changeOrModify(); | 160 | inline void changeOrModify(); |
151 | void deref(); | 161 | void deref(); |
152 | struct Data; | 162 | struct Data; |
153 | Data* data; | 163 | Data* data; |
154 | class Private; | 164 | class Private; |
155 | Private* priv; | 165 | Private* priv; |
156 | 166 | ||
157 | }; | 167 | }; |
158 | 168 | ||
159 | /** | 169 | /** |
160 | * AN Event can span through multiple days. We split up a multiday eve | 170 | * AN Event can span through multiple days. We split up a multiday eve |
161 | */ | 171 | */ |
162 | class OEffectiveEvent { | 172 | class OEffectiveEvent { |
163 | public: | 173 | public: |
164 | typedef QValueList<OEffectiveEvent> ValueList; | 174 | typedef QValueList<OEffectiveEvent> ValueList; |
165 | enum Position { MidWay, Start, End, StartEnd }; | 175 | enum Position { MidWay, Start, End, StartEnd }; |
166 | // If we calculate the effective event of a multi-day event | 176 | // If we calculate the effective event of a multi-day event |
167 | // we have to figure out whether we are at the first day, | 177 | // we have to figure out whether we are at the first day, |
168 | // at the end, or anywhere else ("middle"). This is important | 178 | // at the end, or anywhere else ("middle"). This is important |
169 | // for the start/end times (00:00/23:59) | 179 | // for the start/end times (00:00/23:59) |
170 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- | 180 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- |
171 | // day event | 181 | // day event |
172 | // Start: start time -> 23:59 | 182 | // Start: start time -> 23:59 |
173 | // End: 00:00 -> end time | 183 | // End: 00:00 -> end time |
174 | // Start | End == StartEnd: for single-day events (default) | 184 | // Start | End == StartEnd: for single-day events (default) |
175 | // here we draw start time -> end time | 185 | // here we draw start time -> end time |
176 | OEffectiveEvent(); | 186 | OEffectiveEvent(); |
177 | OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); | 187 | OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); |
178 | OEffectiveEvent( const OEffectiveEvent& ); | 188 | OEffectiveEvent( const OEffectiveEvent& ); |
179 | OEffectiveEvent &operator=(const OEffectiveEvent& ); | 189 | OEffectiveEvent &operator=(const OEffectiveEvent& ); |
180 | ~OEffectiveEvent(); | 190 | ~OEffectiveEvent(); |
181 | 191 | ||
182 | void setStartTime( const QTime& ); | 192 | void setStartTime( const QTime& ); |
diff --git a/libopie/pim/orecur.cpp b/libopie/pim/orecur.cpp index 8c9ad46..f46f22e 100644 --- a/libopie/pim/orecur.cpp +++ b/libopie/pim/orecur.cpp | |||
@@ -1,84 +1,92 @@ | |||
1 | #include <time.h> | 1 | #include <time.h> |
2 | 2 | ||
3 | #include <qshared.h> | 3 | #include <qshared.h> |
4 | 4 | ||
5 | #include <qtopia/timeconversion.h> | 5 | #include <qtopia/timeconversion.h> |
6 | 6 | ||
7 | #include "otimezone.h" | 7 | #include "otimezone.h" |
8 | #include "orecur.h" | 8 | #include "orecur.h" |
9 | 9 | ||
10 | struct ORecur::Data : public QShared { | 10 | struct ORecur::Data : public QShared { |
11 | Data() : QShared() { | 11 | Data() : QShared() { |
12 | type = ORecur::NoRepeat; | 12 | type = ORecur::NoRepeat; |
13 | freq = -1; | 13 | freq = -1; |
14 | days = 0; | 14 | days = 0; |
15 | pos = 0; | 15 | pos = 0; |
16 | create = QDateTime::currentDateTime(); | 16 | create = QDateTime::currentDateTime(); |
17 | hasEnd = FALSE; | 17 | hasEnd = FALSE; |
18 | end = QDate::currentDate(); | 18 | end = QDate::currentDate(); |
19 | } | 19 | } |
20 | char days; // Q_UINT8 for 8 seven days;) | 20 | char days; // Q_UINT8 for 8 seven days;) |
21 | ORecur::RepeatType type; | 21 | ORecur::RepeatType type; |
22 | int freq; | 22 | int freq; |
23 | int pos; | 23 | int pos; |
24 | bool hasEnd : 1; | 24 | bool hasEnd : 1; |
25 | QDate end; | 25 | QDate end; |
26 | QDateTime create; | 26 | QDateTime create; |
27 | int rep; | 27 | int rep; |
28 | QString app; | 28 | QString app; |
29 | ExceptionList list; | 29 | ExceptionList list; |
30 | QDate start; | 30 | QDate start; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | 33 | ||
34 | ORecur::ORecur() { | 34 | ORecur::ORecur() { |
35 | data = new Data; | 35 | data = new Data; |
36 | } | 36 | } |
37 | |||
38 | ORecur::ORecur( const QMap<int, QString>& map ) | ||
39 | { | ||
40 | ORecur(); | ||
41 | fromMap( map ); | ||
42 | } | ||
43 | |||
44 | |||
37 | ORecur::ORecur( const ORecur& rec) | 45 | ORecur::ORecur( const ORecur& rec) |
38 | : data( rec.data ) | 46 | : data( rec.data ) |
39 | { | 47 | { |
40 | data->ref(); | 48 | data->ref(); |
41 | } | 49 | } |
42 | ORecur::~ORecur() { | 50 | ORecur::~ORecur() { |
43 | if ( data->deref() ) { | 51 | if ( data->deref() ) { |
44 | delete data; | 52 | delete data; |
45 | data = 0l; | 53 | data = 0l; |
46 | } | 54 | } |
47 | } | 55 | } |
48 | void ORecur::deref() { | 56 | void ORecur::deref() { |
49 | if ( data->deref() ) { | 57 | if ( data->deref() ) { |
50 | delete data; | 58 | delete data; |
51 | data = 0l; | 59 | data = 0l; |
52 | } | 60 | } |
53 | } | 61 | } |
54 | bool ORecur::operator==( const ORecur& )const { | 62 | bool ORecur::operator==( const ORecur& )const { |
55 | return false; | 63 | return false; |
56 | } | 64 | } |
57 | ORecur &ORecur::operator=( const ORecur& re) { | 65 | ORecur &ORecur::operator=( const ORecur& re) { |
58 | if ( *this == re ) return *this; | 66 | if ( *this == re ) return *this; |
59 | 67 | ||
60 | re.data->ref(); | 68 | re.data->ref(); |
61 | deref(); | 69 | deref(); |
62 | data = re.data; | 70 | data = re.data; |
63 | 71 | ||
64 | return *this; | 72 | return *this; |
65 | } | 73 | } |
66 | bool ORecur::doesRecur()const { | 74 | bool ORecur::doesRecur()const { |
67 | return !( type() == NoRepeat ); | 75 | return !( type() == NoRepeat ); |
68 | } | 76 | } |
69 | /* | 77 | /* |
70 | * we try to be smart here | 78 | * we try to be smart here |
71 | * | 79 | * |
72 | */ | 80 | */ |
73 | bool ORecur::doesRecur( const QDate& date ) { | 81 | bool ORecur::doesRecur( const QDate& date ) { |
74 | /* the day before the recurrance */ | 82 | /* the day before the recurrance */ |
75 | QDate da = date.addDays(-1); | 83 | QDate da = date.addDays(-1); |
76 | 84 | ||
77 | QDate recur; | 85 | QDate recur; |
78 | if (!nextOcurrence( da, recur ) ) | 86 | if (!nextOcurrence( da, recur ) ) |
79 | return false; | 87 | return false; |
80 | 88 | ||
81 | return (recur == date); | 89 | return (recur == date); |
82 | } | 90 | } |
83 | // FIXME unuglify! | 91 | // FIXME unuglify! |
84 | // GPL from Datebookdb.cpp | 92 | // GPL from Datebookdb.cpp |
diff --git a/libopie/pim/orecur.h b/libopie/pim/orecur.h index 47901b0..7750c12 100644 --- a/libopie/pim/orecur.h +++ b/libopie/pim/orecur.h | |||
@@ -1,72 +1,73 @@ | |||
1 | /* | 1 | /* |
2 | * GPL from TT | 2 | * GPL from TT |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #ifndef OPIE_RECUR_H | 5 | #ifndef OPIE_RECUR_H |
6 | #define OPIE_RECUR_H | 6 | #define OPIE_RECUR_H |
7 | 7 | ||
8 | #include <sys/types.h> | 8 | #include <sys/types.h> |
9 | 9 | ||
10 | #include <qdatetime.h> | 10 | #include <qdatetime.h> |
11 | #include <qvaluelist.h> | 11 | #include <qvaluelist.h> |
12 | #include <qmap.h> | 12 | #include <qmap.h> |
13 | 13 | ||
14 | class ORecur { | 14 | class ORecur { |
15 | public: | 15 | public: |
16 | typedef QValueList<QDate> ExceptionList; | 16 | typedef QValueList<QDate> ExceptionList; |
17 | enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, | 17 | enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, |
18 | MonthlyDate, Yearly }; | 18 | MonthlyDate, Yearly }; |
19 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, | 19 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, |
20 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; | 20 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; |
21 | enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate, | 21 | enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate, |
22 | EndDate, Created, Exceptions }; | 22 | EndDate, Created, Exceptions }; |
23 | 23 | ||
24 | ORecur(); | 24 | ORecur(); |
25 | ORecur( const QMap<int, QString>& map ); | ||
25 | ORecur( const ORecur& ); | 26 | ORecur( const ORecur& ); |
26 | ~ORecur(); | 27 | ~ORecur(); |
27 | 28 | ||
28 | ORecur &operator=( const ORecur& ); | 29 | ORecur &operator=( const ORecur& ); |
29 | bool operator==(const ORecur& )const; | 30 | bool operator==(const ORecur& )const; |
30 | 31 | ||
31 | bool doesRecur()const; | 32 | bool doesRecur()const; |
32 | /* if it recurrs on that day */ | 33 | /* if it recurrs on that day */ |
33 | bool doesRecur( const QDate& ); | 34 | bool doesRecur( const QDate& ); |
34 | RepeatType type()const; | 35 | RepeatType type()const; |
35 | int frequency()const; | 36 | int frequency()const; |
36 | int position()const; | 37 | int position()const; |
37 | char days()const; | 38 | char days()const; |
38 | bool hasEndDate()const; | 39 | bool hasEndDate()const; |
39 | QDate start()const; | 40 | QDate start()const; |
40 | QDate endDate()const; | 41 | QDate endDate()const; |
41 | QDateTime createdDateTime()const; | 42 | QDateTime createdDateTime()const; |
42 | /** | 43 | /** |
43 | * starting on monday=0, sunday=6 | 44 | * starting on monday=0, sunday=6 |
44 | * for convience | 45 | * for convience |
45 | */ | 46 | */ |
46 | bool repeatOnWeekDay( int day )const; | 47 | bool repeatOnWeekDay( int day )const; |
47 | 48 | ||
48 | /** | 49 | /** |
49 | * FromWhereToStart is not included!!! | 50 | * FromWhereToStart is not included!!! |
50 | */ | 51 | */ |
51 | bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); | 52 | bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); |
52 | 53 | ||
53 | /** | 54 | /** |
54 | * The module this ORecur belongs to | 55 | * The module this ORecur belongs to |
55 | */ | 56 | */ |
56 | QString service()const; | 57 | QString service()const; |
57 | 58 | ||
58 | /* | 59 | /* |
59 | * reference to the exception list | 60 | * reference to the exception list |
60 | */ | 61 | */ |
61 | ExceptionList &exceptions(); | 62 | ExceptionList &exceptions(); |
62 | 63 | ||
63 | /** | 64 | /** |
64 | * the current repetition | 65 | * the current repetition |
65 | */ | 66 | */ |
66 | int repetition()const; | 67 | int repetition()const; |
67 | 68 | ||
68 | void setType( const RepeatType& ); | 69 | void setType( const RepeatType& ); |
69 | void setFrequency( int freq ); | 70 | void setFrequency( int freq ); |
70 | void setPosition( int pos ); | 71 | void setPosition( int pos ); |
71 | void setDays( char c); | 72 | void setDays( char c); |
72 | void setEndDate( const QDate& dt ); | 73 | void setEndDate( const QDate& dt ); |
diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp index 3913661..75a0860 100644 --- a/libopie/pim/otodoaccesssql.cpp +++ b/libopie/pim/otodoaccesssql.cpp | |||
@@ -254,109 +254,112 @@ namespace { | |||
254 | QString FindQuery::single()const{ | 254 | QString FindQuery::single()const{ |
255 | QString qu = "select * from todolist where uid = " + QString::number(m_uid); | 255 | QString qu = "select * from todolist where uid = " + QString::number(m_uid); |
256 | return qu; | 256 | return qu; |
257 | } | 257 | } |
258 | QString FindQuery::multi()const { | 258 | QString FindQuery::multi()const { |
259 | QString qu = "select * from todolist where "; | 259 | QString qu = "select * from todolist where "; |
260 | for (uint i = 0; i < m_uids.count(); i++ ) { | 260 | for (uint i = 0; i < m_uids.count(); i++ ) { |
261 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | 261 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; |
262 | } | 262 | } |
263 | qu.remove( qu.length()-2, 2 ); | 263 | qu.remove( qu.length()-2, 2 ); |
264 | return qu; | 264 | return qu; |
265 | } | 265 | } |
266 | 266 | ||
267 | OverDueQuery::OverDueQuery(): OSQLQuery() {} | 267 | OverDueQuery::OverDueQuery(): OSQLQuery() {} |
268 | OverDueQuery::~OverDueQuery() {} | 268 | OverDueQuery::~OverDueQuery() {} |
269 | QString OverDueQuery::query()const { | 269 | QString OverDueQuery::query()const { |
270 | QDate date = QDate::currentDate(); | 270 | QDate date = QDate::currentDate(); |
271 | QString str; | 271 | QString str; |
272 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); | 272 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); |
273 | 273 | ||
274 | return str; | 274 | return str; |
275 | } | 275 | } |
276 | 276 | ||
277 | 277 | ||
278 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) | 278 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) |
279 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} | 279 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} |
280 | EffQuery::~EffQuery() {} | 280 | EffQuery::~EffQuery() {} |
281 | QString EffQuery::query()const { | 281 | QString EffQuery::query()const { |
282 | return m_inc ? with() : out(); | 282 | return m_inc ? with() : out(); |
283 | } | 283 | } |
284 | QString EffQuery::with()const { | 284 | QString EffQuery::with()const { |
285 | QString str; | 285 | QString str; |
286 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") | 286 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") |
287 | .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) | 287 | .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) |
288 | .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); | 288 | .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); |
289 | return str; | 289 | return str; |
290 | } | 290 | } |
291 | QString EffQuery::out()const { | 291 | QString EffQuery::out()const { |
292 | QString str; | 292 | QString str; |
293 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") | 293 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") |
294 | .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) | 294 | .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) |
295 | .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); | 295 | .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); |
296 | 296 | ||
297 | return str; | 297 | return str; |
298 | } | 298 | } |
299 | }; | 299 | }; |
300 | 300 | ||
301 | OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) | 301 | OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) |
302 | : OTodoAccessBackend(), m_dict(15), m_dirty(true) | 302 | : OTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true) |
303 | { | 303 | { |
304 | QString fi = file; | 304 | QString fi = file; |
305 | if ( fi.isEmpty() ) | 305 | if ( fi.isEmpty() ) |
306 | fi = Global::applicationFileName( "todolist", "todolist.db" ); | 306 | fi = Global::applicationFileName( "todolist", "todolist.db" ); |
307 | OSQLManager man; | 307 | OSQLManager man; |
308 | m_driver = man.standard(); | 308 | m_driver = man.standard(); |
309 | m_driver->setUrl(fi); | 309 | m_driver->setUrl(fi); |
310 | // fillDict(); | 310 | // fillDict(); |
311 | } | 311 | } |
312 | 312 | ||
313 | OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ | 313 | OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ |
314 | if( m_driver ) | ||
315 | delete m_driver; | ||
314 | } | 316 | } |
317 | |||
315 | bool OTodoAccessBackendSQL::load(){ | 318 | bool OTodoAccessBackendSQL::load(){ |
316 | if (!m_driver->open() ) | 319 | if (!m_driver->open() ) |
317 | return false; | 320 | return false; |
318 | 321 | ||
319 | CreateQuery creat; | 322 | CreateQuery creat; |
320 | OSQLResult res = m_driver->query(&creat ); | 323 | OSQLResult res = m_driver->query(&creat ); |
321 | 324 | ||
322 | m_dirty = true; | 325 | m_dirty = true; |
323 | return true; | 326 | return true; |
324 | } | 327 | } |
325 | bool OTodoAccessBackendSQL::reload(){ | 328 | bool OTodoAccessBackendSQL::reload(){ |
326 | return load(); | 329 | return load(); |
327 | } | 330 | } |
328 | 331 | ||
329 | bool OTodoAccessBackendSQL::save(){ | 332 | bool OTodoAccessBackendSQL::save(){ |
330 | return m_driver->close(); | 333 | return m_driver->close(); |
331 | } | 334 | } |
332 | QArray<int> OTodoAccessBackendSQL::allRecords()const { | 335 | QArray<int> OTodoAccessBackendSQL::allRecords()const { |
333 | if (m_dirty ) | 336 | if (m_dirty ) |
334 | update(); | 337 | update(); |
335 | 338 | ||
336 | return m_uids; | 339 | return m_uids; |
337 | } | 340 | } |
338 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ | 341 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ |
339 | QArray<int> ints(0); | 342 | QArray<int> ints(0); |
340 | return ints; | 343 | return ints; |
341 | } | 344 | } |
342 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ | 345 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ |
343 | FindQuery query( uid ); | 346 | FindQuery query( uid ); |
344 | return todo( m_driver->query(&query) ); | 347 | return todo( m_driver->query(&query) ); |
345 | 348 | ||
346 | } | 349 | } |
347 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, | 350 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, |
348 | uint cur, Frontend::CacheDirection dir ) const{ | 351 | uint cur, Frontend::CacheDirection dir ) const{ |
349 | uint CACHE = readAhead(); | 352 | uint CACHE = readAhead(); |
350 | qWarning("searching for %d", uid ); | 353 | qWarning("searching for %d", uid ); |
351 | QArray<int> search( CACHE ); | 354 | QArray<int> search( CACHE ); |
352 | uint size =0; | 355 | uint size =0; |
353 | OTodo to; | 356 | OTodo to; |
354 | 357 | ||
355 | // we try to cache CACHE items | 358 | // we try to cache CACHE items |
356 | switch( dir ) { | 359 | switch( dir ) { |
357 | /* forward */ | 360 | /* forward */ |
358 | case 0: // FIXME: Not a good style to use magic numbers here (eilers) | 361 | case 0: // FIXME: Not a good style to use magic numbers here (eilers) |
359 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { | 362 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { |
360 | qWarning("size %d %d", size, ints[i] ); | 363 | qWarning("size %d %d", size, ints[i] ); |
361 | search[size] = ints[i]; | 364 | search[size] = ints[i]; |
362 | size++; | 365 | size++; |