author | alwin <alwin> | 2004-02-20 02:06:52 (UTC) |
---|---|---|
committer | alwin <alwin> | 2004-02-20 02:06:52 (UTC) |
commit | 55f4d502486e01927356908223622e435c975f7e (patch) (side-by-side diff) | |
tree | 824b5c1e8992564677c4f39473bc108a32a2cf2a | |
parent | 060b4fc7a3fd5c1b5f745167fe084f7486719b7e (diff) | |
download | opie-55f4d502486e01927356908223622e435c975f7e.zip opie-55f4d502486e01927356908223622e435c975f7e.tar.gz opie-55f4d502486e01927356908223622e435c975f7e.tar.bz2 |
moved the opie pim stuff to libopie2 - pim. Tried to resort them, may be someone should take a look for a better file order. but now all applications can start using libopiepim2 instead of libopie1-pim-stuff.
71 files changed, 2286 insertions, 824 deletions
diff --git a/libopie2/opiepim/backend/backends.pro b/libopie2/opiepim/backend/backends.pro new file mode 100644 index 0000000..4231a00 --- a/dev/null +++ b/libopie2/opiepim/backend/backends.pro @@ -0,0 +1,31 @@ +SOURCES += core/backends/ocontactaccessbackend_sql.cpp \ + core/backends/ocontactaccessbackend_vcard.cpp \ + core/backends/ocontactaccessbackend_xml.cpp \ + core/backends/ocontactaccess.cpp \ + core/backends/odatebookaccessbackend.cpp \ + core/backends/odatebookaccessbackend_xml.cpp \ + core/backends/otodoaccessbackend.cpp \ + core/backends/otodoaccess.cpp \ + core/backends/otodoaccesssql.cpp \ + core/backends/otodoaccessvcal.cpp \ + core/backends/otodoaccessxml.cpp \ + core/backends/odatebookaccess.cpp \ + core/backends/odatebookaccessbackend_sql.cpp + +HEADERS += core/backends/obackendfactory.h \ + core/backends/ocontactaccessbackend.h \ + core/backends/ocontactaccessbackend_sql.h \ + core/backends/ocontactaccessbackend_vcard.h \ + core/backends/ocontactaccessbackend_xml.h \ + core/backends/ocontactaccess.h \ + core/backends/odatebookaccessbackend.h \ + core/backends/odatebookaccessbackend_sql.h \ + core/backends/odatebookaccessbackend_xml.h \ + core/backends/opimaccessbackend.h \ + core/backends/opimaccesstemplate.h \ + core/backends/otodoaccessbackend.h \ + core/backends/otodoaccess.h \ + core/backends/otodoaccesssql.h \ + core/backends/otodoaccessvcal.h \ + core/backends/otodoaccessxml.h \ + core/backends/odatebookaccess.h diff --git a/libopie2/opiepim/backend/obackendfactory.h b/libopie2/opiepim/backend/obackendfactory.h index 761ab9a..346e2f5 100644 --- a/libopie2/opiepim/backend/obackendfactory.h +++ b/libopie2/opiepim/backend/obackendfactory.h @@ -1,194 +1,150 @@ /* - * Class to manage Backends. - * - * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; - * either version 2 of the License, or (at your option) any later - * version. + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/* * ===================================================================== * ToDo: Use plugins * ===================================================================== - * Version: $Id$ - * ===================================================================== - * History: - * $Log$ - * Revision 1.9 2003/12/22 10:19:26 eilers - * Finishing implementation of sql-backend for datebook. But I have to - * port the PIM datebook application to use it, before I could debug the - * whole stuff. - * Thus, PIM-Database backend is finished, but highly experimental. And some - * parts are still generic. For instance, the "queryByExample()" methods are - * not (or not fully) implemented. Todo: custom-entries not stored. - * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular - * expression search in the database, which is not supported by sqlite ! - * Therefore we need either an extended sqlite or a workaround which would - * be very slow and memory consuming.. - * - * Revision 1.8 2003/09/22 14:31:16 eilers - * Added first experimental incarnation of sql-backend for addressbook. - * Some modifications to be able to compile the todo sql-backend. - * A lot of changes fill follow... - * - * Revision 1.7 2003/08/01 12:30:16 eilers - * Merging changes from BRANCH_1_0 to HEAD - * - * Revision 1.6.4.1 2003/06/30 14:34:19 eilers - * Patches from Zecke: - * Fixing and cleaning up extraMap handling - * Adding d_ptr for binary compatibility in the future - * - * Revision 1.6 2003/04/13 18:07:10 zecke - * More API doc - * QString -> const QString& - * QString = 0l -> QString::null - * - * Revision 1.5 2003/02/21 23:31:52 zecke - * Add XML datebookresource - * -clean up todoaccessxml header - * -implement some more stuff in the oeven tester - * -extend DefaultFactory to not crash and to use datebook - * - * -reading of OEvents is working nicely.. saving will be added - * tomorrow - * -fix spelling in ODateBookAcces - * - * Revision 1.4 2002/10/14 15:55:18 eilers - * Redeactivate SQL.. ;) - * - * Revision 1.3 2002/10/10 17:08:58 zecke - * The Cache is finally in place - * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;) - * The read ahead functionality does not make sense for XMLs backends because most of the stuff is already in memory. While using readahead on SQL makes things a lot faster.... - * I still have to fully implement read ahead - * This change is bic but sc - * - * Revision 1.2 2002/10/08 09:27:36 eilers - * Fixed libopie.pro to include the new pim-API. - * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to - * compile itself would need to install libsqlite, libopiesql... - * Therefore, the backend currently uses XML only.. - * - * Revision 1.1 2002/10/07 17:35:01 eilers - * added OBackendFactory for advanced backend access - * - * - * ===================================================================== */ #ifndef OPIE_BACKENDFACTORY_H_ #define OPIE_BACKENDFACTORY_H_ #include <qstring.h> #include <qasciidict.h> #include <qpe/config.h> -#include "otodoaccessxml.h" -#include "ocontactaccessbackend_xml.h" -#include "odatebookaccessbackend_xml.h" +#include <opie2/otodoaccessxml.h> +#include <opie2/ocontactaccessbackend_xml.h> +#include <opie2/odatebookaccessbackend_xml.h> #ifdef __USE_SQL -#include "otodoaccesssql.h" -#include "ocontactaccessbackend_sql.h" -#include "odatebookaccessbackend_sql.h" +#include <opie2/otodoaccesssql.h> +#include <opie2/ocontactaccessbackend_sql.h> +#include <opie2/odatebookaccessbackend_sql.h> #endif +namespace Opie { + class OBackendPrivate; /** * This class is our factory. It will give us the default implementations * of at least Todolist, Contacts and Datebook. In the future this class will * allow users to switch the backend with ( XML->SQLite ) without the need * to recompile.# * This class as the whole PIM Api is making use of templates * * <pre> * OTodoAccessBackend* backend = OBackEndFactory<OTodoAccessBackend>::Default("todo", QString::null ); * backend->load(); * </pre> * * @author Stefan Eilers * @version 0.1 */ template<class T> class OBackendFactory { public: OBackendFactory() {}; enum BACKENDS { TODO, CONTACT, DATE }; /** * Returns a backend implementation for backendName * @param backendName the type of the backend * @param appName will be passed on to the backend */ static T* Default( const QString backendName, const QString& appName ){ // __asm__("int3"); Config config( "pimaccess" ); config.setGroup ( backendName ); QString backend = config.readEntry( "usebackend" ); qWarning("Selected backend for %s is: %s", backendName.latin1(), backend.latin1() ); QAsciiDict<int> dict ( 3 ); dict.setAutoDelete ( TRUE ); dict.insert( "todo", new int (TODO) ); dict.insert( "contact", new int (CONTACT) ); dict.insert( "datebook", new int(DATE) ); int *find = dict[ backendName ]; if (!find ) return 0; switch ( *find ){ case TODO: #ifdef __USE_SQL if ( backend == "sql" ) return (T*) new OTodoAccessBackendSQL(""); #else if ( backend == "sql" ) qWarning ("OBackendFactory:: sql Backend for TODO not implemented! Using XML instead!"); #endif return (T*) new OTodoAccessXML( appName ); case CONTACT: #ifdef __USE_SQL if ( backend == "sql" ) return (T*) new OContactAccessBackend_SQL(""); #else if ( backend == "sql" ) qWarning ("OBackendFactory:: sql Backend for CONTACT not implemented! Using XML instead!"); #endif return (T*) new OContactAccessBackend_XML( appName ); case DATE: #ifdef __USE_SQL if ( backend == "sql" ) return (T*) new ODateBookAccessBackend_SQL(""); #else if ( backend == "sql" ) qWarning("OBackendFactory:: sql Backend for DATEBOOK not implemented! Using XML instead!"); #endif return (T*) new ODateBookAccessBackend_XML( appName ); default: return NULL; } } private: OBackendPrivate* d; }; +} #endif diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.h b/libopie2/opiepim/backend/ocontactaccessbackend.h index 0eac6dc..6113cea 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend.h @@ -1,128 +1,114 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ /** * The class responsible for managing a backend. * The implementation of this abstract class contains * the complete database handling. * * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; - * either version 2 of the License, or (at your option) any later - * version. - * ===================================================================== - * ToDo: Define enum for query settings - * ===================================================================== - * Version: $Id$ - * ===================================================================== - * History: - * $Log$ - * Revision 1.7 2004/02/19 02:05:37 zecke - * Add notes for API fixes and BC stuff - * - * Revision 1.6 2003/08/01 12:30:16 eilers - * Merging changes from BRANCH_1_0 to HEAD - * - * Revision 1.5.4.1 2003/06/30 14:34:19 eilers - * Patches from Zecke: - * Fixing and cleaning up extraMap handling - * Adding d_ptr for binary compatibility in the future - * - * Revision 1.5 2003/04/13 18:07:10 zecke - * More API doc - * QString -> const QString& - * QString = 0l -> QString::null - * - * Revision 1.4 2002/11/13 14:14:51 eilers - * Added sorted for Contacts.. - * - * Revision 1.3 2002/11/01 15:10:42 eilers - * Added regExp-search in database for all fields in a contact. - * - * Revision 1.2 2002/10/07 17:34:24 eilers - * added OBackendFactory for advanced backend access - * - * Revision 1.1 2002/09/27 17:11:44 eilers - * Added API for accessing the Contact-Database ! It is compiling, but - * please do not expect that anything is working ! - * I will debug that stuff in the next time .. - * Please read README_COMPILE for compiling ! - * - * ===================================================================== - * */ #ifndef _OCONTACTACCESSBACKEND_H_ #define _OCONTACTACCESSBACKEND_H_ -#include "ocontact.h" -#include "opimaccessbackend.h" +#include <opie2/ocontact.h> +#include <opie2/opimaccessbackend.h> #include <qregexp.h> +namespace Opie { /** * This class represents the interface of all Contact Backends. * Derivates of this class will be used to access the contacts. * As implementation currently XML and vCard exist. This class needs to be implemented * if you want to provide your own storage. * In all queries a list of uids is passed on instead of loading the actual record! * * @see OContactAccessBackend_VCard * @see OContactAccessBackend_XML */ class OContactAccessBackend: public OPimAccessBackend<OContact> { public: /** * @todo make non line in regard to BC guide of KDE */ OContactAccessBackend() {} /** * @todo make non inline in regard to the BC guide of KDE */ virtual ~OContactAccessBackend() {} /** * Return if database was changed externally. * This may just make sense on file based databases like a XML-File. * It is used to prevent to overwrite the current database content * if the file was already changed by something else ! * If this happens, we have to reload before save our data. * If we use real databases, this should be handled by the database * management system themselve, therefore this function should always return false in * this case. It is not our problem to handle this conflict ... * @return <i>true</i> if the database was changed and if save without reload will * be dangerous. <i>false</i> if the database was not changed or it is save to write * in this situation. */ virtual bool wasChangedExternally() = 0; virtual QArray<int> matchRegexp( const QRegExp &r ) const = 0; /** * Return all possible settings. * @return All settings provided by the current backend * (i.e.: query_WildCards & query_IgnoreCase) */ virtual const uint querySettings() = 0; /** * Check whether settings are correct. * @return <i>true</i> if the given settings are correct and possible. */ virtual bool hasQuerySettings (uint querySettings) const = 0; /** * FIXME!!! * Returns a sorted list of records either ascendinf or descending for a giving criteria and category */ virtual QArray<int> sorted( bool ascending, int sortOrder, int sortFilter, int cat ) = 0; private: class Private; Private *d; }; + +} + #endif diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp index a5be4c8..d0c8052 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp @@ -1,942 +1,935 @@ /* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/* * SQL Backend for the OPIE-Contact Database. - * - * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * ===================================================================== - * ===================================================================== - * Version: $Id$ - * ===================================================================== - * History: - * $Log$ - * Revision 1.4 2003/12/22 10:19:26 eilers - * Finishing implementation of sql-backend for datebook. But I have to - * port the PIM datebook application to use it, before I could debug the - * whole stuff. - * Thus, PIM-Database backend is finished, but highly experimental. And some - * parts are still generic. For instance, the "queryByExample()" methods are - * not (or not fully) implemented. Todo: custom-entries not stored. - * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular - * expression search in the database, which is not supported by sqlite ! - * Therefore we need either an extended sqlite or a workaround which would - * be very slow and memory consuming.. - * - * Revision 1.3 2003/12/08 15:18:10 eilers - * Committing unfinished sql implementation before merging to libopie2 starts.. - * - * Revision 1.2 2003/09/29 07:44:26 eilers - * Improvement of PIM-SQL Databases, but search queries are still limited. - * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. - * Todo: Started to add new attributes. Some type conversions missing. - * - * Revision 1.1 2003/09/22 14:31:16 eilers - * Added first experimental incarnation of sql-backend for addressbook. - * Some modifications to be able to compile the todo sql-backend. - * A lot of changes fill follow... - * */ #include "ocontactaccessbackend_sql.h" #include <qarray.h> #include <qdatetime.h> #include <qstringlist.h> #include <qpe/global.h> #include <qpe/recordfields.h> -#include <opie/ocontactfields.h> -#include <opie/oconversion.h> +#include <opie2/ocontactfields.h> +#include <opie2/oconversion.h> #include <opie2/osqldriver.h> #include <opie2/osqlresult.h> #include <opie2/osqlmanager.h> #include <opie2/osqlquery.h> // If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead // vertical like "uid, type, value". // DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! #define __STORE_HORIZONTAL_ // Distinct loading is not very fast. If I expect that every person has just // one (and always one) 'Last Name', I can request all uid's for existing lastnames, // which is faster.. // But this may not be true for all entries, like company contacts.. // The current AddressBook application handles this problem, but other may not.. (eilers) #define __USE_SUPERFAST_LOADQUERY /* * Implementation of used query types * CREATE query * LOAD query * INSERT * REMOVE * CLEAR */ -namespace { +namespace Opie { /** * CreateQuery for the Todolist Table */ class CreateQuery : public OSQLQuery { public: CreateQuery(); ~CreateQuery(); QString query()const; }; /** * Clears (delete) a Table */ class ClearQuery : public OSQLQuery { public: ClearQuery(); ~ClearQuery(); QString query()const; }; /** * LoadQuery * this one queries for all uids */ class LoadQuery : public OSQLQuery { public: LoadQuery(); ~LoadQuery(); QString query()const; }; /** * inserts/adds a OContact to the table */ class InsertQuery : public OSQLQuery { public: InsertQuery(const OContact& ); ~InsertQuery(); QString query()const; private: OContact m_contact; }; /** * removes one from the table */ class RemoveQuery : public OSQLQuery { public: RemoveQuery(int uid ); ~RemoveQuery(); QString query()const; private: int m_uid; }; /** * a find query for noncustom elements */ class FindQuery : public OSQLQuery { public: FindQuery(int uid); FindQuery(const QArray<int>& ); ~FindQuery(); QString query()const; private: QString single()const; QString multi()const; QArray<int> m_uids; int m_uid; }; /** * a find query for custom elements */ class FindCustomQuery : public OSQLQuery { public: FindCustomQuery(int uid); FindCustomQuery(const QArray<int>& ); ~FindCustomQuery(); QString query()const; private: QString single()const; QString multi()const; QArray<int> m_uids; int m_uid; }; // We using three tables to store the information: // 1. addressbook : It contains General information about the contact (non custom) // 2. custom_data : Not official supported entries // All tables are connected by the uid of the contact. // Maybe I should add a table for meta-information ? CreateQuery::CreateQuery() : OSQLQuery() {} CreateQuery::~CreateQuery() {} QString CreateQuery::query()const { QString qu; #ifdef __STORE_HORIZONTAL_ qu += "create table addressbook( uid PRIMARY KEY "; QStringList fieldList = OContactFields::untrfields( false ); for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); } qu += " );"; qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; #else qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));"; qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );"; #endif // __STORE_HORIZONTAL_ return qu; } ClearQuery::ClearQuery() : OSQLQuery() {} ClearQuery::~ClearQuery() {} QString ClearQuery::query()const { QString qu = "drop table addressbook;"; qu += "drop table custom_data;"; // qu += "drop table dates;"; return qu; } LoadQuery::LoadQuery() : OSQLQuery() {} LoadQuery::~LoadQuery() {} QString LoadQuery::query()const { QString qu; #ifdef __STORE_HORIZONTAL_ qu += "select uid from addressbook"; #else # ifndef __USE_SUPERFAST_LOADQUERY qu += "select distinct uid from addressbook"; # else qu += "select uid from addressbook where type = 'Last Name'"; # endif // __USE_SUPERFAST_LOADQUERY #endif // __STORE_HORIZONTAL_ return qu; } InsertQuery::InsertQuery( const OContact& contact ) : OSQLQuery(), m_contact( contact ) { } InsertQuery::~InsertQuery() { } /* * converts from a OContact to a query */ QString InsertQuery::query()const{ #ifdef __STORE_HORIZONTAL_ QString qu; qu += "insert into addressbook VALUES( " + QString::number( m_contact.uid() ); // Get all information out of the contact-class // Remember: The category is stored in contactMap, too ! QMap<int, QString> contactMap = m_contact.toMap(); QStringList fieldList = OContactFields::untrfields( false ); QMap<QString, int> translate = OContactFields::untrFieldsToId(); for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ // Convert Column-String to Id and get value for this id.. // Hmmm.. Maybe not very cute solution.. int id = translate[*it]; switch ( id ){ case Qtopia::Birthday:{ // These entries should stored in a special format // year-month-day QDate day = m_contact.birthday(); if ( day.isValid() ){ qu += QString(",\"%1-%2-%3\"") .arg( day.year() ) .arg( day.month() ) .arg( day.day() ); } else { qu += ",\"\""; } } break; case Qtopia::Anniversary:{ // These entries should stored in a special format // year-month-day QDate day = m_contact.anniversary(); if ( day.isValid() ){ qu += QString(",\"%1-%2-%3\"") .arg( day.year() ) .arg( day.month() ) .arg( day.day() ); } else { qu += ",\"\""; } } break; default: qu += QString( ",\"%1\"" ).arg( contactMap[id] ); } } qu += " );"; #else // Get all information out of the contact-class // Remember: The category is stored in contactMap, too ! QMap<int, QString> contactMap = m_contact.toMap(); QMap<QString, QString> addressbook_db; // Get the translation from the ID to the String QMap<int, QString> transMap = OContactFields::idToUntrFields(); for( QMap<int, QString>::Iterator it = contactMap.begin(); it != contactMap.end(); ++it ){ switch ( it.key() ){ case Qtopia::Birthday:{ // These entries should stored in a special format // year-month-day QDate day = m_contact.birthday(); addressbook_db.insert( transMap[it.key()], QString("%1-%2-%3") .arg( day.year() ) .arg( day.month() ) .arg( day.day() ) ); } break; case Qtopia::Anniversary:{ // These entries should stored in a special format // year-month-day QDate day = m_contact.anniversary(); addressbook_db.insert( transMap[it.key()], QString("%1-%2-%3") .arg( day.year() ) .arg( day.month() ) .arg( day.day() ) ); } break; case Qtopia::AddressUid: // Ignore UID break; default: // Translate id to String addressbook_db.insert( transMap[it.key()], it.data() ); break; } } // Now convert this whole stuff into a SQL String, beginning with // the addressbook table.. QString qu; // qu += "begin transaction;"; int id = 0; for( QMap<QString, QString>::Iterator it = addressbook_db.begin(); it != addressbook_db.end(); ++it ){ qu += "insert into addressbook VALUES(" + QString::number( m_contact.uid() ) + "," + QString::number( id++ ) + ",'" + it.key() //.latin1() + "'," + "0" // Priority for future enhancements + ",'" + it.data() //.latin1() + "');"; } #endif //__STORE_HORIZONTAL_ // Now add custom data.. #ifdef __STORE_HORIZONTAL_ int id = 0; #endif id = 0; QMap<QString, QString> customMap = m_contact.toExtraMap(); for( QMap<QString, QString>::Iterator it = customMap.begin(); it != customMap.end(); ++it ){ qu += "insert into custom_data VALUES(" + QString::number( m_contact.uid() ) + "," + QString::number( id++ ) + ",'" + it.key() //.latin1() + "'," + "0" // Priority for future enhancements + ",'" + it.data() //.latin1() + "');"; } // qu += "commit;"; qWarning("add %s", qu.latin1() ); return qu; } RemoveQuery::RemoveQuery(int uid ) : OSQLQuery(), m_uid( uid ) {} RemoveQuery::~RemoveQuery() {} QString RemoveQuery::query()const { QString qu = "DELETE from addressbook where uid = " + QString::number(m_uid) + ";"; qu += "DELETE from custom_data where uid = " + QString::number(m_uid) + ";"; return qu; } FindQuery::FindQuery(int uid) : OSQLQuery(), m_uid( uid ) { } FindQuery::FindQuery(const QArray<int>& ints) : OSQLQuery(), m_uids( ints ){ } FindQuery::~FindQuery() { } QString FindQuery::query()const{ // if ( m_uids.count() == 0 ) return single(); } /* else return multi(); } QString FindQuery::multi()const { QString qu = "select uid, type, value from addressbook where"; for (uint i = 0; i < m_uids.count(); i++ ) { qu += " UID = " + QString::number( m_uids[i] ) + " OR"; } qu.remove( qu.length()-2, 2 ); // Hmmmm.. return qu; } */ #ifdef __STORE_HORIZONTAL_ QString FindQuery::single()const{ QString qu = "select *"; qu += " from addressbook where uid = " + QString::number(m_uid); // qWarning("find query: %s", qu.latin1() ); return qu; } #else QString FindQuery::single()const{ QString qu = "select uid, type, value from addressbook where uid = "; qu += QString::number(m_uid); return qu; } #endif FindCustomQuery::FindCustomQuery(int uid) : OSQLQuery(), m_uid( uid ) { } FindCustomQuery::FindCustomQuery(const QArray<int>& ints) : OSQLQuery(), m_uids( ints ){ } FindCustomQuery::~FindCustomQuery() { } QString FindCustomQuery::query()const{ // if ( m_uids.count() == 0 ) return single(); } QString FindCustomQuery::single()const{ QString qu = "select uid, type, value from custom_data where uid = "; qu += QString::number(m_uid); return qu; } }; /* --------------------------------------------------------------------------- */ +namespace Opie { + OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, const QString& filename ): OContactAccessBackend(), m_changed(false), m_driver( NULL ) { qWarning("C'tor OContactAccessBackend_SQL starts"); QTime t; t.start(); /* Expecting to access the default filename if nothing else is set */ if ( filename.isEmpty() ){ m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); } else m_fileName = filename; // Get the standart sql-driver from the OSQLManager.. OSQLManager man; m_driver = man.standard(); m_driver->setUrl( m_fileName ); load(); qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); } OContactAccessBackend_SQL::~OContactAccessBackend_SQL () { if( m_driver ) delete m_driver; } bool OContactAccessBackend_SQL::load () { if (!m_driver->open() ) return false; // Don't expect that the database exists. // It is save here to create the table, even if it // do exist. ( Is that correct for all databases ?? ) CreateQuery creat; OSQLResult res = m_driver->query( &creat ); update(); return true; } bool OContactAccessBackend_SQL::reload() { return load(); } bool OContactAccessBackend_SQL::save() { return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) } void OContactAccessBackend_SQL::clear () { ClearQuery cle; OSQLResult res = m_driver->query( &cle ); reload(); } bool OContactAccessBackend_SQL::wasChangedExternally() { return false; } QArray<int> OContactAccessBackend_SQL::allRecords() const { // FIXME: Think about cute handling of changed tables.. // Thus, we don't have to call update here... if ( m_changed ) ((OContactAccessBackend_SQL*)this)->update(); return m_uids; } bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) { InsertQuery ins( newcontact ); OSQLResult res = m_driver->query( &ins ); if ( res.state() == OSQLResult::Failure ) return false; int c = m_uids.count(); m_uids.resize( c+1 ); m_uids[c] = newcontact.uid(); return true; } bool OContactAccessBackend_SQL::remove ( int uid ) { RemoveQuery rem( uid ); OSQLResult res = m_driver->query(&rem ); if ( res.state() == OSQLResult::Failure ) return false; m_changed = true; return true; } bool OContactAccessBackend_SQL::replace ( const OContact &contact ) { if ( !remove( contact.uid() ) ) return false; return add( contact ); } OContact OContactAccessBackend_SQL::find ( int uid ) const { qWarning("OContactAccessBackend_SQL::find()"); QTime t; t.start(); OContact retContact( requestNonCustom( uid ) ); retContact.setExtraMap( requestCustom( uid ) ); qWarning("OContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() ); return retContact; } QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ) { QString qu = "SELECT uid FROM addressbook WHERE"; QMap<int, QString> queryFields = query.toMap(); QStringList fieldList = OContactFields::untrfields( false ); QMap<QString, int> translate = OContactFields::untrFieldsToId(); // Convert every filled field to a SQL-Query bool isAnyFieldSelected = false; for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ int id = translate[*it]; QString queryStr = queryFields[id]; if ( !queryStr.isEmpty() ){ isAnyFieldSelected = true; switch( id ){ default: // Switching between case sensitive and insensitive... // LIKE is not case sensitive, GLOB is case sensitive // Do exist a better solution to switch this ? if ( settings & OContactAccess::IgnoreCase ) qu += "(\"" + *it + "\"" + " LIKE " + "'" + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND "; else qu += "(\"" + *it + "\"" + " GLOB " + "'" + queryStr + "'" + ") AND "; } } } // Skip trailing "AND" if ( isAnyFieldSelected ) qu = qu.left( qu.length() - 4 ); qWarning( "queryByExample query: %s", qu.latin1() ); // Execute query and return the received uid's OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ QArray<int> empty; return empty; } QArray<int> list = extractUids( res ); return list; } QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const { QArray<int> nix(0); return nix; } const uint OContactAccessBackend_SQL::querySettings() { return OContactAccess::IgnoreCase || OContactAccess::WildCards; } bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const { /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay * may be added with any of the other settings. IgnoreCase should never used alone. * Wildcards, RegExp, ExactMatch should never used at the same time... */ // Step 1: Check whether the given settings are supported by this backend if ( ( querySettings & ( OContactAccess::IgnoreCase | OContactAccess::WildCards // | OContactAccess::DateDiff // | OContactAccess::DateYear // | OContactAccess::DateMonth // | OContactAccess::DateDay // | OContactAccess::RegExp // | OContactAccess::ExactMatch ) ) != querySettings ) return false; // Step 2: Check whether the given combinations are ok.. // IngoreCase alone is invalid if ( querySettings == OContactAccess::IgnoreCase ) return false; // WildCards, RegExp and ExactMatch should never used at the same time switch ( querySettings & ~( OContactAccess::IgnoreCase | OContactAccess::DateDiff | OContactAccess::DateYear | OContactAccess::DateMonth | OContactAccess::DateDay ) ){ case OContactAccess::RegExp: return ( true ); case OContactAccess::WildCards: return ( true ); case OContactAccess::ExactMatch: return ( true ); case 0: // one of the upper removed bits were set.. return ( true ); default: return ( false ); } } QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int ) { QTime t; t.start(); #ifdef __STORE_HORIZONTAL_ QString query = "SELECT uid FROM addressbook "; query += "ORDER BY \"Last Name\" "; #else QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' "; query += "ORDER BY upper( value )"; #endif if ( !asc ) query += "DESC"; // qWarning("sorted query is: %s", query.latin1() ); OSQLRawQuery raw( query ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ QArray<int> empty; return empty; } QArray<int> list = extractUids( res ); qWarning("sorted needed %d ms!", t.elapsed() ); return list; } void OContactAccessBackend_SQL::update() { qWarning("Update starts"); QTime t; t.start(); // Now load the database set and extract the uid's // which will be held locally LoadQuery lo; OSQLResult res = m_driver->query(&lo); if ( res.state() != OSQLResult::Success ) return; m_uids = extractUids( res ); m_changed = false; qWarning("Update ends %d ms", t.elapsed() ); } QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const { qWarning("extractUids"); QTime t; t.start(); OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it; QArray<int> ints(list.count() ); qWarning(" count = %d", list.count() ); int i = 0; for (it = list.begin(); it != list.end(); ++it ) { ints[i] = (*it).data("uid").toInt(); i++; } qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); return ints; } #ifdef __STORE_HORIZONTAL_ QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const { QTime t; t.start(); QMap<int, QString> nonCustomMap; int t2needed = 0; int t3needed = 0; QTime t2; t2.start(); FindQuery query( uid ); OSQLResult res_noncustom = m_driver->query( &query ); t2needed = t2.elapsed(); OSQLResultItem resItem = res_noncustom.first(); QTime t3; t3.start(); // Now loop through all columns QStringList fieldList = OContactFields::untrfields( false ); QMap<QString, int> translate = OContactFields::untrFieldsToId(); for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ // Get data for the selected column and store it with the // corresponding id into the map.. int id = translate[*it]; QString value = resItem.data( (*it) ); // qWarning("Reading %s... found: %s", (*it).latin1(), value.latin1() ); switch( id ){ case Qtopia::Birthday: case Qtopia::Anniversary:{ // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) QStringList list = QStringList::split( '-', value ); QStringList::Iterator lit = list.begin(); int year = (*lit).toInt(); int month = (*(++lit)).toInt(); int day = (*(++lit)).toInt(); if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){ QDate date( year, month, day ); nonCustomMap.insert( id, OConversion::dateToString( date ) ); } } break; case Qtopia::AddressCategory: qWarning("Category is: %s", value.latin1() ); default: nonCustomMap.insert( id, value ); } } // First insert uid nonCustomMap.insert( Qtopia::AddressUid, resItem.data( "uid" ) ); t3needed = t3.elapsed(); // qWarning("Adding UID: %s", resItem.data( "uid" ).latin1() ); qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", t.elapsed(), t2needed, t3needed ); return nonCustomMap; } #else QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const { QTime t; t.start(); QMap<int, QString> nonCustomMap; int t2needed = 0; QTime t2; t2.start(); FindQuery query( uid ); OSQLResult res_noncustom = m_driver->query( &query ); t2needed = t2.elapsed(); if ( res_noncustom.state() == OSQLResult::Failure ) { qWarning("OSQLResult::Failure in find query !!"); QMap<int, QString> empty; return empty; } int t3needed = 0; QTime t3; t3.start(); QMap<QString, int> translateMap = OContactFields::untrFieldsToId(); OSQLResultItem::ValueList list = res_noncustom.results(); OSQLResultItem::ValueList::Iterator it = list.begin(); for ( ; it != list.end(); ++it ) { if ( (*it).data("type") != "" ){ int typeId = translateMap[(*it).data( "type" )]; switch( typeId ){ case Qtopia::Birthday: case Qtopia::Anniversary:{ // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) QStringList list = QStringList::split( '-', (*it).data( "value" ) ); QStringList::Iterator lit = list.begin(); int year = (*lit).toInt(); qWarning("1. %s", (*lit).latin1()); int month = (*(++lit)).toInt(); qWarning("2. %s", (*lit).latin1()); int day = (*(++lit)).toInt(); qWarning("3. %s", (*lit).latin1()); qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day ); QDate date( year, month, day ); nonCustomMap.insert( typeId, OConversion::dateToString( date ) ); } break; default: nonCustomMap.insert( typeId, (*it).data( "value" ) ); } } } // Add UID to Map.. nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) ); t3needed = t3.elapsed(); qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", t.elapsed(), t2needed, t3needed ); return nonCustomMap; } #endif // __STORE_HORIZONTAL_ QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const { QTime t; t.start(); QMap<QString, QString> customMap; FindCustomQuery query( uid ); OSQLResult res_custom = m_driver->query( &query ); if ( res_custom.state() == OSQLResult::Failure ) { qWarning("OSQLResult::Failure in find query !!"); QMap<QString, QString> empty; return empty; } OSQLResultItem::ValueList list = res_custom.results(); OSQLResultItem::ValueList::Iterator it = list.begin(); for ( ; it != list.end(); ++it ) { customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); } qWarning("RequestCustom needed: %d ms", t.elapsed() ); return customMap; } + +} diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h index b8f1d8d..55b95fd 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h @@ -1,101 +1,109 @@ /* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/* * SQL Backend for the OPIE-Contact Database. - * - * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * ===================================================================== - * - * - * ===================================================================== - * Version: $Id$ - * ===================================================================== - * History: - * $Log$ - * Revision 1.2 2003/12/08 15:18:11 eilers - * Committing unfinished sql implementation before merging to libopie2 starts.. - * - * Revision 1.1 2003/09/22 14:31:16 eilers - * Added first experimental incarnation of sql-backend for addressbook. - * Some modifications to be able to compile the todo sql-backend. - * A lot of changes fill follow... - * - * */ #ifndef _OContactAccessBackend_SQL_ #define _OContactAccessBackend_SQL_ -#include "ocontactaccessbackend.h" -#include "ocontactaccess.h" +#include <opie2/ocontactaccessbackend.h> +#include <opie2/ocontactaccess.h> #include <qlist.h> #include <qdict.h> +/* aren't in namespace Opie yet - alwin */ class OSQLDriver; class OSQLResult; class OSQLResultItem; +namespace Opie { + /* the default xml implementation */ /** * This class is the SQL implementation of a Contact backend * it does implement everything available for OContact. * @see OPimAccessBackend for more information of available methods */ class OContactAccessBackend_SQL : public OContactAccessBackend { public: OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); ~OContactAccessBackend_SQL (); bool save(); bool load (); void clear (); bool wasChangedExternally(); QArray<int> allRecords() const; OContact find ( int uid ) const; // FIXME: Add lookahead-cache support ! //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; QArray<int> queryByExample ( const OContact &query, int settings, const QDateTime& d ); QArray<int> matchRegexp( const QRegExp &r ) const; const uint querySettings(); bool hasQuerySettings (uint querySettings) const; // Currently only asc implemented.. QArray<int> sorted( bool asc, int , int , int ); bool add ( const OContact &newcontact ); bool replace ( const OContact &contact ); bool remove ( int uid ); bool reload(); private: QArray<int> extractUids( OSQLResult& res ) const; QMap<int, QString> requestNonCustom( int uid ) const; QMap<QString, QString> requestCustom( int uid ) const; void update(); protected: bool m_changed; QString m_fileName; QArray<int> m_uids; OSQLDriver* m_driver; }; +} + #endif diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp index b60c5be..f85cf38 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp @@ -1,646 +1,591 @@ /* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/* * VCard Backend for the OPIE-Contact Database. - * - * Copyright (C) 2000 Trolltech AS. All rights reserved. - * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * ===================================================================== - * ToDo: - * - * ===================================================================== - * Version: $Id$ - * ===================================================================== - * History: - * $Log$ - * Revision 1.11 2003/08/01 12:30:16 eilers - * Merging changes from BRANCH_1_0 to HEAD - * - * Revision 1.10.4.3 2003/07/23 08:54:37 eilers - * Default email was added to the list of all emails, which already contains - * the default email.. - * This closes bug #1045 - * - * Revision 1.10.4.2 2003/07/23 08:44:45 eilers - * Importing of Notes in vcard files wasn't implemented. - * Closes bug #1044 - * - * Revision 1.10.4.1 2003/06/02 13:37:49 eilers - * Fixing memory leak - * - * Revision 1.10 2003/04/13 18:07:10 zecke - * More API doc - * QString -> const QString& - * QString = 0l -> QString::null - * - * Revision 1.9 2003/03/21 10:33:09 eilers - * Merged speed optimized xml backend for contacts to main. - * Added QDateTime to querybyexample. For instance, it is now possible to get - * all Birthdays/Anniversaries between two dates. This should be used - * to show all birthdays in the datebook.. - * This change is sourcecode backward compatible but you have to upgrade - * the binaries for today-addressbook. - * - * Revision 1.8 2003/02/21 16:52:49 zecke - * -Remove old Todo classes they're deprecated and today I already using the - * new API - * -Guard against self assignment in OTodo - * -Add test apps for OPIM - * -Opiefied Event classes - * -Added TimeZone handling and pinning of TimeZones to OEvent - * -Adjust ORecur and the widget to better timezone behaviour - * - * Revision 1.7 2003/02/16 22:25:46 zecke - * 0000276 Fix for that bug.. or better temp workaround - * A Preferred Number is HOME|VOICE - * A CellPhone is HOME|VOICE|CELL the type & HOME|VOICE test - * triggers both - * and the cell phone number overrides the other entries.. - * - * as a temp I check that it's not equal to HOME|VOICE|CELL before setting the - * number - * - * The right and final fix would be to reorder the if statement to make it - * if else based and the less common thing put to the bottom - * - * OTodoAccessVcal fix the date for beaming - * - * Revision 1.6 2003/01/13 15:49:31 eilers - * Fixing crash when businesscard.vcf is missing.. - * - * Revision 1.5 2002/12/07 13:26:22 eilers - * Fixing bug in storing anniversary.. - * - * Revision 1.4 2002/11/13 14:14:51 eilers - * Added sorted for Contacts.. - * - * Revision 1.3 2002/11/11 16:41:09 kergoth - * no default arguments in implementation - * - * Revision 1.2 2002/11/10 15:41:53 eilers - * Bugfixes.. - * - * Revision 1.1 2002/11/09 14:34:52 eilers - * Added VCard Backend. - * */ -#include "ocontactaccessbackend_vcard.h" -#include "../../library/backend/vobject_p.h" -#include "../../library/backend/qfiledirect_p.h" +#include <opie2/ocontactaccessbackend_vcard.h> +#include "../../../../library/backend/vobject_p.h" +#include "../../../../library/backend/qfiledirect_p.h" #include <qpe/timeconversion.h> #include <qfile.h> +namespace Opie { + OContactAccessBackend_VCard::OContactAccessBackend_VCard ( const QString& , const QString& filename ): m_dirty( false ), m_file( filename ) { load(); } bool OContactAccessBackend_VCard::load () { m_map.clear(); m_dirty = false; VObject* obj = 0l; if ( QFile::exists(m_file) ){ obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); if ( !obj ) return false; }else{ qWarning("File \"%s\" not found !", m_file.latin1() ); return false; } while ( obj ) { OContact con = parseVObject( obj ); /* * if uid is 0 assign a new one * this at least happens on * Nokia6210 */ if ( con.uid() == 0 ){ con.setUid( 1 ); qWarning("assigned new uid %d",con.uid() ); } m_map.insert( con.uid(), con ); VObject *t = obj; obj = nextVObjectInList(obj); cleanVObject( t ); } return true; } bool OContactAccessBackend_VCard::reload() { return load(); } bool OContactAccessBackend_VCard::save() { if (!m_dirty ) return true; QFileDirect file( m_file ); if (!file.open(IO_WriteOnly ) ) return false; VObject *obj; obj = newVObject( VCCalProp ); addPropValue( obj, VCVersionProp, "1.0" ); VObject *vo; for(QMap<int, OContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ vo = createVObject( *it ); writeVObject( file.directHandle() , vo ); cleanVObject( vo ); } cleanStrTbl(); deleteVObject( obj ); m_dirty = false; return true; } void OContactAccessBackend_VCard::clear () { m_map.clear(); m_dirty = true; // ??? sure ? (se) } bool OContactAccessBackend_VCard::add ( const OContact& newcontact ) { m_map.insert( newcontact.uid(), newcontact ); m_dirty = true; return true; } bool OContactAccessBackend_VCard::remove ( int uid ) { m_map.remove( uid ); m_dirty = true; return true; } bool OContactAccessBackend_VCard::replace ( const OContact &contact ) { m_map.replace( contact.uid(), contact ); m_dirty = true; return true; } OContact OContactAccessBackend_VCard::find ( int uid ) const { return m_map[uid]; } QArray<int> OContactAccessBackend_VCard::allRecords() const { QArray<int> ar( m_map.count() ); QMap<int, OContact>::ConstIterator it; int i = 0; for ( it = m_map.begin(); it != m_map.end(); ++it ) { ar[i] = it.key(); i++; } return ar; } // Not implemented QArray<int> OContactAccessBackend_VCard::queryByExample ( const OContact&, int, const QDateTime& ) { QArray<int> ar(0); return ar; } // Not implemented QArray<int> OContactAccessBackend_VCard::matchRegexp( const QRegExp& ) const { QArray<int> ar(0); return ar; } const uint OContactAccessBackend_VCard::querySettings() { return 0; // No search possible } bool OContactAccessBackend_VCard::hasQuerySettings (uint ) const { return false; // No search possible, therefore all settings invalid ;) } bool OContactAccessBackend_VCard::wasChangedExternally() { return false; // Don't expect concurrent access } // Not implemented QArray<int> OContactAccessBackend_VCard::sorted( bool , int, int, int ) { QArray<int> ar(0); return ar; } // *** Private stuff *** OContact OContactAccessBackend_VCard::parseVObject( VObject *obj ) { OContact c; VObjectIterator it; initPropIterator( &it, obj ); while( moreIteration( &it ) ) { VObject *o = nextVObject( &it ); QCString name = vObjectName( o ); QCString value = vObjectStringZValue( o ); if ( name == VCNameProp ) { VObjectIterator nit; initPropIterator( &nit, o ); while( moreIteration( &nit ) ) { VObject *o = nextVObject( &nit ); QCString name = vObjectTypeInfo( o ); QString value = vObjectStringZValue( o ); if ( name == VCNamePrefixesProp ) c.setTitle( value ); else if ( name == VCNameSuffixesProp ) c.setSuffix( value ); else if ( name == VCFamilyNameProp ) c.setLastName( value ); else if ( name == VCGivenNameProp ) c.setFirstName( value ); else if ( name == VCAdditionalNamesProp ) c.setMiddleName( value ); } } else if ( name == VCAdrProp ) { bool work = TRUE; // default address is work address QString street; QString city; QString region; QString postal; QString country; VObjectIterator nit; initPropIterator( &nit, o ); while( moreIteration( &nit ) ) { VObject *o = nextVObject( &nit ); QCString name = vObjectName( o ); QString value = vObjectStringZValue( o ); if ( name == VCHomeProp ) work = FALSE; else if ( name == VCWorkProp ) work = TRUE; else if ( name == VCStreetAddressProp ) street = value; else if ( name == VCCityProp ) city = value; else if ( name == VCRegionProp ) region = value; else if ( name == VCPostalCodeProp ) postal = value; else if ( name == VCCountryNameProp ) country = value; } if ( work ) { c.setBusinessStreet( street ); c.setBusinessCity( city ); c.setBusinessCountry( country ); c.setBusinessZip( postal ); c.setBusinessState( region ); } else { c.setHomeStreet( street ); c.setHomeCity( city ); c.setHomeCountry( country ); c.setHomeZip( postal ); c.setHomeState( region ); } } else if ( name == VCTelephoneProp ) { enum { HOME = 0x01, WORK = 0x02, VOICE = 0x04, CELL = 0x08, FAX = 0x10, PAGER = 0x20, UNKNOWN = 0x80 }; int type = 0; VObjectIterator nit; initPropIterator( &nit, o ); while( moreIteration( &nit ) ) { VObject *o = nextVObject( &nit ); QCString name = vObjectTypeInfo( o ); if ( name == VCHomeProp ) type |= HOME; else if ( name == VCWorkProp ) type |= WORK; else if ( name == VCVoiceProp ) type |= VOICE; else if ( name == VCCellularProp ) type |= CELL; else if ( name == VCFaxProp ) type |= FAX; else if ( name == VCPagerProp ) type |= PAGER; else if ( name == VCPreferredProp ) ; else type |= UNKNOWN; } if ( (type & UNKNOWN) != UNKNOWN ) { if ( ( type & (HOME|WORK) ) == 0 ) // default type |= HOME; if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default type |= VOICE; qWarning("value %s %d", value.data(), type ); if ( (type & (VOICE|HOME) ) == (VOICE|HOME) && (type & (CELL|HOME) ) != (CELL|HOME) ) c.setHomePhone( value ); if ( ( type & (FAX|HOME) ) == (FAX|HOME) ) c.setHomeFax( value ); if ( ( type & (CELL|HOME) ) == (CELL|HOME) ) c.setHomeMobile( value ); if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) && (type & (CELL|WORK) ) != (CELL|WORK) ) c.setBusinessPhone( value ); if ( ( type & (FAX|WORK) ) == (FAX|WORK) ) c.setBusinessFax( value ); if ( ( type & (CELL|WORK) ) == (CELL|WORK) ) c.setBusinessMobile( value ); if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) ) c.setBusinessPager( value ); } } else if ( name == VCEmailAddressProp ) { QString email = vObjectStringZValue( o ); bool valid = TRUE; VObjectIterator nit; initPropIterator( &nit, o ); while( moreIteration( &nit ) ) { VObject *o = nextVObject( &nit ); QCString name = vObjectTypeInfo( o ); if ( name != VCInternetProp && name != VCHomeProp && name != VCWorkProp && name != VCPreferredProp ) // ### preffered should map to default email valid = FALSE; } if ( valid ) { c.insertEmail( email ); } } else if ( name == VCURLProp ) { VObjectIterator nit; initPropIterator( &nit, o ); while( moreIteration( &nit ) ) { VObject *o = nextVObject( &nit ); QCString name = vObjectTypeInfo( o ); if ( name == VCHomeProp ) c.setHomeWebpage( value ); else if ( name == VCWorkProp ) c.setBusinessWebpage( value ); } } else if ( name == VCOrgProp ) { VObjectIterator nit; initPropIterator( &nit, o ); while( moreIteration( &nit ) ) { VObject *o = nextVObject( &nit ); QCString name = vObjectName( o ); QString value = vObjectStringZValue( o ); if ( name == VCOrgNameProp ) c.setCompany( value ); else if ( name == VCOrgUnitProp ) c.setDepartment( value ); else if ( name == VCOrgUnit2Prop ) c.setOffice( value ); } } else if ( name == VCTitleProp ) { c.setJobTitle( value ); } else if ( name == "X-Qtopia-Profession" ) { c.setProfession( value ); } else if ( name == "X-Qtopia-Manager" ) { c.setManager( value ); } else if ( name == "X-Qtopia-Assistant" ) { c.setAssistant( value ); } else if ( name == "X-Qtopia-Spouse" ) { c.setSpouse( value ); } else if ( name == "X-Qtopia-Gender" ) { c.setGender( value ); } else if ( name == "X-Qtopia-Anniversary" ) { c.setAnniversary( convVCardDateToDate( value ) ); } else if ( name == "X-Qtopia-Nickname" ) { c.setNickname( value ); } else if ( name == "X-Qtopia-Children" ) { c.setChildren( value ); } else if ( name == VCBirthDateProp ) { // Reading Birthdate regarding RFC 2425 (5.8.4) c.setBirthday( convVCardDateToDate( value ) ); } else if ( name == VCCommentProp ) { c.setNotes( value ); } #if 0 else { printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); VObjectIterator nit; initPropIterator( &nit, o ); while( moreIteration( &nit ) ) { VObject *o = nextVObject( &nit ); QCString name = vObjectName( o ); QString value = vObjectStringZValue( o ); printf(" subprop: %s = %s\n", name.data(), value.latin1() ); } } #endif } c.setFileAs(); return c; } VObject* OContactAccessBackend_VCard::createVObject( const OContact &c ) { VObject *vcard = newVObject( VCCardProp ); safeAddPropValue( vcard, VCVersionProp, "2.1" ); safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) ); safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) ); // full name safeAddPropValue( vcard, VCFullNameProp, c.fullName() ); // name properties VObject *name = safeAddProp( vcard, VCNameProp ); safeAddPropValue( name, VCFamilyNameProp, c.lastName() ); safeAddPropValue( name, VCGivenNameProp, c.firstName() ); safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() ); safeAddPropValue( name, VCNamePrefixesProp, c.title() ); safeAddPropValue( name, VCNameSuffixesProp, c.suffix() ); // home properties VObject *home_adr= safeAddProp( vcard, VCAdrProp ); safeAddProp( home_adr, VCHomeProp ); safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() ); safeAddPropValue( home_adr, VCCityProp, c.homeCity() ); safeAddPropValue( home_adr, VCRegionProp, c.homeState() ); safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() ); safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() ); VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() ); safeAddProp( home_phone, VCHomeProp ); home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() ); safeAddProp( home_phone, VCHomeProp ); safeAddProp( home_phone, VCCellularProp ); home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() ); safeAddProp( home_phone, VCHomeProp ); safeAddProp( home_phone, VCFaxProp ); VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() ); safeAddProp( url, VCHomeProp ); // work properties VObject *work_adr= safeAddProp( vcard, VCAdrProp ); safeAddProp( work_adr, VCWorkProp ); safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() ); safeAddPropValue( work_adr, VCCityProp, c.businessCity() ); safeAddPropValue( work_adr, VCRegionProp, c.businessState() ); safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() ); safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() ); VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() ); safeAddProp( work_phone, VCWorkProp ); work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() ); safeAddProp( work_phone, VCWorkProp ); safeAddProp( work_phone, VCCellularProp ); work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() ); safeAddProp( work_phone, VCWorkProp ); safeAddProp( work_phone, VCFaxProp ); work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() ); safeAddProp( work_phone, VCWorkProp ); safeAddProp( work_phone, VCPagerProp ); url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() ); safeAddProp( url, VCWorkProp ); VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() ); safeAddProp( title, VCWorkProp ); QStringList emails = c.emailList(); // emails.prepend( c.defaultEmail() ); Fix for bugreport #1045 for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it ); safeAddProp( email, VCInternetProp ); } safeAddPropValue( vcard, VCNoteProp, c.notes() ); // Exporting Birthday regarding RFC 2425 (5.8.4) if ( c.birthday().isValid() ){ qWarning("Exporting birthday as: %s", convDateToVCardDate( c.birthday() ).latin1() ); safeAddPropValue( vcard, VCBirthDateProp, convDateToVCardDate( c.birthday() ) ); } if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) { VObject *org = safeAddProp( vcard, VCOrgProp ); safeAddPropValue( org, VCOrgNameProp, c.company() ); safeAddPropValue( org, VCOrgUnitProp, c.department() ); safeAddPropValue( org, VCOrgUnit2Prop, c.office() ); } // some values we have to export as custom fields safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() ); safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() ); safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() ); safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() ); safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() ); if ( c.anniversary().isValid() ){ qWarning("Exporting anniversary as: %s", convDateToVCardDate( c.anniversary() ).latin1() ); safeAddPropValue( vcard, "X-Qtopia-Anniversary", convDateToVCardDate( c.anniversary() ) ); } safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() ); safeAddPropValue( vcard, "X-Qtopia-Children", c.children() ); return vcard; } QString OContactAccessBackend_VCard::convDateToVCardDate( const QDate& d ) const { QString str_rfc2425 = QString("%1-%2-%3") .arg( d.year() ) .arg( d.month(), 2 ) .arg( d.day(), 2 ); // Now replace spaces with "0"... int pos = 0; while ( ( pos = str_rfc2425.find (' ') ) > 0 ) str_rfc2425.replace( pos, 1, "0" ); return str_rfc2425; } QDate OContactAccessBackend_VCard::convVCardDateToDate( const QString& datestr ) { int monthPos = datestr.find('-'); int dayPos = datestr.find('-', monthPos+1 ); int sep_ignore = 1; if ( monthPos == -1 || dayPos == -1 ) { qDebug("fromString didn't find - in str = %s; mpos = %d ypos = %d", datestr.latin1(), monthPos, dayPos ); // Ok.. No "-" found, therefore we will try to read other format ( YYYYMMDD ) if ( datestr.length() == 8 ){ monthPos = 4; dayPos = 6; sep_ignore = 0; qDebug("Try with follwing positions str = %s; mpos = %d ypos = %d", datestr.latin1(), monthPos, dayPos ); } else { return QDate(); } } int y = datestr.left( monthPos ).toInt(); int m = datestr.mid( monthPos + sep_ignore, dayPos - monthPos - sep_ignore ).toInt(); int d = datestr.mid( dayPos + sep_ignore ).toInt(); qDebug("TimeConversion::fromString ymd = %s => %d %d %d; mpos = %d ypos = %d", datestr.latin1(), y, m, d, monthPos, dayPos); QDate date ( y,m,d ); return date; } VObject* OContactAccessBackend_VCard::safeAddPropValue( VObject *o, const char *prop, const QString &value ) { VObject *ret = 0; if ( o && !value.isEmpty() ) ret = addPropValue( o, prop, value.latin1() ); return ret; } VObject* OContactAccessBackend_VCard::safeAddProp( VObject *o, const char *prop) { VObject *ret = 0; if ( o ) ret = addProp( o, prop ); return ret; } + +} diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h index 712d769..11be027 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h @@ -1,96 +1,85 @@ /* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/* * VCard Backend for the OPIE-Contact Database. - * - * Copyright (C) 2000 Trolltech AS. All rights reserved. - * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * ===================================================================== - * ToDo: - * - * ===================================================================== - * Version: $Id$ - * ===================================================================== - * History: - * $Log$ - * Revision 1.6 2003/04/13 18:07:10 zecke - * More API doc - * QString -> const QString& - * QString = 0l -> QString::null - * - * Revision 1.5 2003/03/21 10:33:09 eilers - * Merged speed optimized xml backend for contacts to main. - * Added QDateTime to querybyexample. For instance, it is now possible to get - * all Birthdays/Anniversaries between two dates. This should be used - * to show all birthdays in the datebook.. - * This change is sourcecode backward compatible but you have to upgrade - * the binaries for today-addressbook. - * - * Revision 1.4 2002/12/07 13:26:22 eilers - * Fixing bug in storing anniversary.. - * - * Revision 1.3 2002/11/13 14:14:51 eilers - * Added sorted for Contacts.. - * - * Revision 1.2 2002/11/10 15:41:53 eilers - * Bugfixes.. - * - * Revision 1.1 2002/11/09 14:34:52 eilers - * Added VCard Backend. - * */ #ifndef __OCONTACTACCESSBACKEND_VCARD_H_ #define __OCONTACTACCESSBACKEND_VCARD_H_ -#include <opie/ocontact.h> +#include <opie2/ocontact.h> -#include "ocontactaccessbackend.h" +#include <opie2/ocontactaccessbackend.h> class VObject; +namespace Opie { /** * This is the vCard 2.1 implementation of the Contact Storage * @see OContactAccessBackend_XML * @see OPimAccessBackend */ class OContactAccessBackend_VCard : public OContactAccessBackend { public: OContactAccessBackend_VCard ( const QString& appname, const QString& filename = QString::null ); bool load (); bool reload(); bool save(); void clear (); bool add ( const OContact& newcontact ); bool remove ( int uid ); bool replace ( const OContact& contact ); OContact find ( int uid ) const; QArray<int> allRecords() const; QArray<int> queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ); QArray<int> matchRegexp( const QRegExp &r ) const; const uint querySettings(); bool hasQuerySettings (uint querySettings) const; QArray<int> sorted( bool ascending, int sortOrder, int sortFilter, int cat ); bool wasChangedExternally(); private: OContact parseVObject( VObject* obj ); VObject* createVObject( const OContact& c ); QString convDateToVCardDate( const QDate& c ) const; QDate convVCardDateToDate( const QString& datestr ); VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value ); VObject *safeAddProp( VObject* o, const char* prop); bool m_dirty : 1; QString m_file; QMap<int, OContact> m_map; }; +} + #endif diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp index aae7fca..4c3da0c 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp @@ -1,820 +1,751 @@ /* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/* * XML Backend for the OPIE-Contact Database. - * - * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * ===================================================================== - * - * ===================================================================== - * Version: $Id$ - * ===================================================================== - * History: - * $Log$ - * Revision 1.9 2003/09/22 14:31:16 eilers - * Added first experimental incarnation of sql-backend for addressbook. - * Some modifications to be able to compile the todo sql-backend. - * A lot of changes fill follow... - * - * Revision 1.8 2003/08/30 15:28:26 eilers - * Removed some unimportant debug output which causes slow down.. - * - * Revision 1.7 2003/08/01 12:30:16 eilers - * Merging changes from BRANCH_1_0 to HEAD - * - * Revision 1.6 2003/07/07 16:19:47 eilers - * Fixing serious bug in hasQuerySettings() - * - * Revision 1.5 2003/04/13 18:07:10 zecke - * More API doc - * QString -> const QString& - * QString = 0l -> QString::null - * - * Revision 1.4 2003/03/21 14:32:54 mickeyl - * g++ compliance fix: default arguments belong into the declaration, but not the definition - * - * Revision 1.3 2003/03/21 12:26:28 eilers - * Fixing small bug: If we search a birthday from today to today, it returned - * every contact .. - * - * Revision 1.2 2003/03/21 10:33:09 eilers - * Merged speed optimized xml backend for contacts to main. - * Added QDateTime to querybyexample. For instance, it is now possible to get - * all Birthdays/Anniversaries between two dates. This should be used - * to show all birthdays in the datebook.. - * This change is sourcecode backward compatible but you have to upgrade - * the binaries for today-addressbook. - * - * Revision 1.1.2.2 2003/02/11 12:17:28 eilers - * Speed optimization. Removed the sequential search loops. - * - * Revision 1.1.2.1 2003/02/10 15:31:38 eilers - * Writing offsets to debug output.. - * - * Revision 1.1 2003/02/09 15:05:01 eilers - * Nothing happened.. Just some cleanup before I will start.. - * - * Revision 1.12 2003/01/03 16:58:03 eilers - * Reenable debug output - * - * Revision 1.11 2003/01/03 12:31:28 eilers - * Bugfix for calculating data diffs.. - * - * Revision 1.10 2003/01/02 14:27:12 eilers - * Improved query by example: Search by date is possible.. First step - * for a today plugin for birthdays.. - * - * Revision 1.9 2002/12/08 12:48:57 eilers - * Moved journal-enum from ocontact into i the xml-backend.. - * - * Revision 1.8 2002/11/14 17:04:24 eilers - * Sorting will now work if fullname is identical on some entries - * - * Revision 1.7 2002/11/13 15:02:46 eilers - * Small Bug in sorted fixed - * - * Revision 1.6 2002/11/13 14:14:51 eilers - * Added sorted for Contacts.. - * - * Revision 1.5 2002/11/01 15:10:42 eilers - * Added regExp-search in database for all fields in a contact. - * - * Revision 1.4 2002/10/16 10:52:40 eilers - * Added some docu to the interface and now using the cache infrastucture by zecke.. :) - * - * Revision 1.3 2002/10/14 16:21:54 eilers - * Some minor interface updates - * - * Revision 1.2 2002/10/07 17:34:24 eilers - * added OBackendFactory for advanced backend access - * - * Revision 1.1 2002/09/27 17:11:44 eilers - * Added API for accessing the Contact-Database ! It is compiling, but - * please do not expect that anything is working ! - * I will debug that stuff in the next time .. - * Please read README_COMPILE for compiling ! - * - * */ -#include "ocontactaccessbackend_xml.h" +#include <opie2/ocontactaccessbackend_xml.h> #include <qasciidict.h> #include <qdatetime.h> #include <qfile.h> #include <qfileinfo.h> #include <qregexp.h> #include <qarray.h> #include <qmap.h> #include <qdatetime.h> #include <qpe/global.h> #include <opie/xmltree.h> -#include "ocontactaccessbackend.h" -#include "ocontactaccess.h" +#include <opie2/ocontactaccessbackend.h> +#include <opie2/ocontactaccess.h> #include <stdlib.h> #include <errno.h> using namespace Opie; +namespace Opie { OContactAccessBackend_XML::OContactAccessBackend_XML ( const QString& appname, const QString& filename ): m_changed( false ) { // Just m_contactlist should call delete if an entry // is removed. m_contactList.setAutoDelete( true ); m_uidToContact.setAutoDelete( false ); m_appName = appname; /* Set journalfile name ... */ m_journalName = getenv("HOME"); m_journalName +="/.abjournal" + appname; /* Expecting to access the default filename if nothing else is set */ if ( filename.isEmpty() ){ m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); } else m_fileName = filename; /* Load Database now */ load (); } bool OContactAccessBackend_XML::save() { if ( !m_changed ) return true; QString strNewFile = m_fileName + ".new"; QFile f( strNewFile ); if ( !f.open( IO_WriteOnly|IO_Raw ) ) return false; int total_written; int idx_offset = 0; QString out; // Write Header out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" " <Groups>\n" " </Groups>\n" " <Contacts>\n"; QCString cstr = out.utf8(); f.writeBlock( cstr.data(), cstr.length() ); idx_offset += cstr.length(); out = ""; // Write all contacts QListIterator<OContact> it( m_contactList ); for ( ; it.current(); ++it ) { // qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); out += "<Contact "; (*it)->save( out ); out += "/>\n"; cstr = out.utf8(); total_written = f.writeBlock( cstr.data(), cstr.length() ); idx_offset += cstr.length(); if ( total_written != int(cstr.length()) ) { f.close(); QFile::remove( strNewFile ); return false; } out = ""; } out += " </Contacts>\n</AddressBook>\n"; // Write Footer cstr = out.utf8(); total_written = f.writeBlock( cstr.data(), cstr.length() ); if ( total_written != int( cstr.length() ) ) { f.close(); QFile::remove( strNewFile ); return false; } f.close(); // move the file over, I'm just going to use the system call // because, I don't feel like using QDir. if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { qWarning( "problem renaming file %s to %s, errno: %d", strNewFile.latin1(), m_journalName.latin1(), errno ); // remove the tmp file... QFile::remove( strNewFile ); } /* The journalfile should be removed now... */ removeJournal(); m_changed = false; return true; } bool OContactAccessBackend_XML::load () { m_contactList.clear(); m_uidToContact.clear(); /* Load XML-File and journal if it exists */ if ( !load ( m_fileName, false ) ) return false; /* The returncode of the journalfile is ignored due to the * fact that it does not exist when this class is instantiated ! * But there may such a file exist, if the application crashed. * Therefore we try to load it to get the changes before the # * crash happened... */ load (m_journalName, true); return true; } void OContactAccessBackend_XML::clear () { m_contactList.clear(); m_uidToContact.clear(); m_changed = false; } bool OContactAccessBackend_XML::wasChangedExternally() { QFileInfo fi( m_fileName ); QDateTime lastmod = fi.lastModified (); return (lastmod != m_readtime); } QArray<int> OContactAccessBackend_XML::allRecords() const { QArray<int> uid_list( m_contactList.count() ); uint counter = 0; QListIterator<OContact> it( m_contactList ); for( ; it.current(); ++it ){ uid_list[counter++] = (*it)->uid(); } return ( uid_list ); } OContact OContactAccessBackend_XML::find ( int uid ) const { OContact foundContact; //Create empty contact OContact* found = m_uidToContact.find( QString().setNum( uid ) ); if ( found ){ foundContact = *found; } return ( foundContact ); } QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings, const QDateTime& d ) { QArray<int> m_currentQuery( m_contactList.count() ); QListIterator<OContact> it( m_contactList ); uint arraycounter = 0; for( ; it.current(); ++it ){ /* Search all fields and compare them with query object. Store them into list * if all fields matches. */ QDate* queryDate = 0l; QDate* checkDate = 0l; bool allcorrect = true; for ( int i = 0; i < Qtopia::Groups; i++ ) { // Birthday and anniversary are special nonstring fields and should // be handled specially switch ( i ){ case Qtopia::Birthday: queryDate = new QDate( query.birthday() ); checkDate = new QDate( (*it)->birthday() ); case Qtopia::Anniversary: if ( queryDate == 0l ){ queryDate = new QDate( query.anniversary() ); checkDate = new QDate( (*it)->anniversary() ); } if ( queryDate->isValid() ){ if( checkDate->isValid() ){ if ( settings & OContactAccess::DateYear ){ if ( queryDate->year() != checkDate->year() ) allcorrect = false; } if ( settings & OContactAccess::DateMonth ){ if ( queryDate->month() != checkDate->month() ) allcorrect = false; } if ( settings & OContactAccess::DateDay ){ if ( queryDate->day() != checkDate->day() ) allcorrect = false; } if ( settings & OContactAccess::DateDiff ) { QDate current; // If we get an additional date, we // will take this date instead of // the current one.. if ( !d.date().isValid() ) current = QDate::currentDate(); else current = d.date(); // We have to equalize the year, otherwise // the search will fail.. checkDate->setYMD( current.year(), checkDate->month(), checkDate->day() ); if ( *checkDate < current ) checkDate->setYMD( current.year()+1, checkDate->month(), checkDate->day() ); // Check whether the birthday/anniversary date is between // the current/given date and the maximum date // ( maximum time range ) ! qWarning("Checking if %s is between %s and %s ! ", checkDate->toString().latin1(), current.toString().latin1(), queryDate->toString().latin1() ); if ( current.daysTo( *queryDate ) >= 0 ){ if ( !( ( *checkDate >= current ) && ( *checkDate <= *queryDate ) ) ){ allcorrect = false; qWarning (" Nope!.."); } } } } else{ // checkDate is invalid. Therefore this entry is always rejected allcorrect = false; } } delete queryDate; queryDate = 0l; delete checkDate; checkDate = 0l; break; default: /* Just compare fields which are not empty in the query object */ if ( !query.field(i).isEmpty() ){ switch ( settings & ~( OContactAccess::IgnoreCase | OContactAccess::DateDiff | OContactAccess::DateYear | OContactAccess::DateMonth | OContactAccess::DateDay | OContactAccess::MatchOne ) ){ case OContactAccess::RegExp:{ QRegExp expr ( query.field(i), !(settings & OContactAccess::IgnoreCase), false ); if ( expr.find ( (*it)->field(i), 0 ) == -1 ) allcorrect = false; } break; case OContactAccess::WildCards:{ QRegExp expr ( query.field(i), !(settings & OContactAccess::IgnoreCase), true ); if ( expr.find ( (*it)->field(i), 0 ) == -1 ) allcorrect = false; } break; case OContactAccess::ExactMatch:{ if (settings & OContactAccess::IgnoreCase){ if ( query.field(i).upper() != (*it)->field(i).upper() ) allcorrect = false; }else{ if ( query.field(i) != (*it)->field(i) ) allcorrect = false; } } break; } } } } if ( allcorrect ){ m_currentQuery[arraycounter++] = (*it)->uid(); } } // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; } QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const { QArray<int> m_currentQuery( m_contactList.count() ); QListIterator<OContact> it( m_contactList ); uint arraycounter = 0; for( ; it.current(); ++it ){ if ( (*it)->match( r ) ){ m_currentQuery[arraycounter++] = (*it)->uid(); } } // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; } const uint OContactAccessBackend_XML::querySettings() { return ( OContactAccess::WildCards | OContactAccess::IgnoreCase | OContactAccess::RegExp | OContactAccess::ExactMatch | OContactAccess::DateDiff | OContactAccess::DateYear | OContactAccess::DateMonth | OContactAccess::DateDay ); } bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const { /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay * may be added with any of the other settings. IgnoreCase should never used alone. * Wildcards, RegExp, ExactMatch should never used at the same time... */ // Step 1: Check whether the given settings are supported by this backend if ( ( querySettings & ( OContactAccess::IgnoreCase | OContactAccess::WildCards | OContactAccess::DateDiff | OContactAccess::DateYear | OContactAccess::DateMonth | OContactAccess::DateDay | OContactAccess::RegExp | OContactAccess::ExactMatch ) ) != querySettings ) return false; // Step 2: Check whether the given combinations are ok.. // IngoreCase alone is invalid if ( querySettings == OContactAccess::IgnoreCase ) return false; // WildCards, RegExp and ExactMatch should never used at the same time switch ( querySettings & ~( OContactAccess::IgnoreCase | OContactAccess::DateDiff | OContactAccess::DateYear | OContactAccess::DateMonth | OContactAccess::DateDay ) ){ case OContactAccess::RegExp: return ( true ); case OContactAccess::WildCards: return ( true ); case OContactAccess::ExactMatch: return ( true ); case 0: // one of the upper removed bits were set.. return ( true ); default: return ( false ); } } // Currently only asc implemented.. QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int ) { QMap<QString, int> nameToUid; QStringList names; QArray<int> m_currentQuery( m_contactList.count() ); // First fill map and StringList with all Names // Afterwards sort namelist and use map to fill array to return.. QListIterator<OContact> it( m_contactList ); for( ; it.current(); ++it ){ names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); } names.sort(); int i = 0; if ( asc ){ for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) m_currentQuery[i++] = nameToUid[ (*it) ]; }else{ for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) m_currentQuery[i++] = nameToUid[ (*it) ]; } return m_currentQuery; } bool OContactAccessBackend_XML::add ( const OContact &newcontact ) { //qWarning("odefaultbackend: ACTION::ADD"); updateJournal (newcontact, ACTION_ADD); addContact_p( newcontact ); m_changed = true; return true; } bool OContactAccessBackend_XML::replace ( const OContact &contact ) { m_changed = true; OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); if ( found ) { OContact* newCont = new OContact( contact ); updateJournal ( *newCont, ACTION_REPLACE); m_contactList.removeRef ( found ); m_contactList.append ( newCont ); m_uidToContact.remove( QString().setNum( contact.uid() ) ); m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); return true; } else return false; } bool OContactAccessBackend_XML::remove ( int uid ) { m_changed = true; OContact* found = m_uidToContact.find ( QString().setNum( uid ) ); if ( found ) { updateJournal ( *found, ACTION_REMOVE); m_contactList.removeRef ( found ); m_uidToContact.remove( QString().setNum( uid ) ); return true; } else return false; } bool OContactAccessBackend_XML::reload(){ /* Reload is the same as load in this implementation */ return ( load() ); } void OContactAccessBackend_XML::addContact_p( const OContact &newcontact ) { OContact* contRef = new OContact( newcontact ); m_contactList.append ( contRef ); m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); } /* This function loads the xml-database and the journalfile */ bool OContactAccessBackend_XML::load( const QString filename, bool isJournal ) { /* We use the time of the last read to check if the file was * changed externally. */ if ( !isJournal ){ QFileInfo fi( filename ); m_readtime = fi.lastModified (); } const int JOURNALACTION = Qtopia::Notes + 1; const int JOURNALROW = JOURNALACTION + 1; bool foundAction = false; journal_action action = ACTION_ADD; int journalKey = 0; QMap<int, QString> contactMap; QMap<QString, QString> customMap; QMap<QString, QString>::Iterator customIt; QAsciiDict<int> dict( 47 ); dict.setAutoDelete( TRUE ); dict.insert( "Uid", new int(Qtopia::AddressUid) ); dict.insert( "Title", new int(Qtopia::Title) ); dict.insert( "FirstName", new int(Qtopia::FirstName) ); dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); dict.insert( "LastName", new int(Qtopia::LastName) ); dict.insert( "Suffix", new int(Qtopia::Suffix) ); dict.insert( "FileAs", new int(Qtopia::FileAs) ); dict.insert( "Categories", new int(Qtopia::AddressCategory) ); dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); dict.insert( "Emails", new int(Qtopia::Emails) ); dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); dict.insert( "HomeState", new int(Qtopia::HomeState) ); dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); dict.insert( "Company", new int(Qtopia::Company) ); dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); dict.insert( "Department", new int(Qtopia::Department) ); dict.insert( "Office", new int(Qtopia::Office) ); dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); dict.insert( "Profession", new int(Qtopia::Profession) ); dict.insert( "Assistant", new int(Qtopia::Assistant) ); dict.insert( "Manager", new int(Qtopia::Manager) ); dict.insert( "Spouse", new int(Qtopia::Spouse) ); dict.insert( "Children", new int(Qtopia::Children) ); dict.insert( "Gender", new int(Qtopia::Gender) ); dict.insert( "Birthday", new int(Qtopia::Birthday) ); dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); dict.insert( "Nickname", new int(Qtopia::Nickname) ); dict.insert( "Notes", new int(Qtopia::Notes) ); dict.insert( "action", new int(JOURNALACTION) ); dict.insert( "actionrow", new int(JOURNALROW) ); //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() ); XMLElement *root = XMLElement::load( filename ); if(root != 0l ){ // start parsing /* Parse all XML-Elements and put the data into the * Contact-Class */ XMLElement *element = root->firstChild(); //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() ); element = element->firstChild(); /* Search Tag "Contacts" which is the parent of all Contacts */ while( element && !isJournal ){ if( element->tagName() != QString::fromLatin1("Contacts") ){ //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s", // element->tagName().latin1()); element = element->nextChild(); } else { element = element->firstChild(); break; } } /* Parse all Contacts and ignore unknown tags */ while( element ){ if( element->tagName() != QString::fromLatin1("Contact") ){ //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s", // element->tagName().latin1()); element = element->nextChild(); continue; } /* Found alement with tagname "contact", now parse and store all * attributes contained */ //qWarning("OContactDefBack::load element tagName() : %s", // element->tagName().latin1() ); QString dummy; foundAction = false; XMLElement::AttributeMap aMap = element->attributes(); XMLElement::AttributeMap::Iterator it; contactMap.clear(); customMap.clear(); for( it = aMap.begin(); it != aMap.end(); ++it ){ // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); int *find = dict[ it.key() ]; /* Unknown attributes will be stored as "Custom" elements */ if ( !find ) { // qWarning("Attribute %s not known.", it.key().latin1()); //contact.setCustomField(it.key(), it.data()); customMap.insert( it.key(), it.data() ); continue; } /* Check if special conversion is needed and add attribute * into Contact class */ switch( *find ) { /* case Qtopia::AddressUid: contact.setUid( it.data().toInt() ); break; case Qtopia::AddressCategory: contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); break; */ case JOURNALACTION: action = journal_action(it.data().toInt()); foundAction = true; qWarning ("ODefBack(journal)::ACTION found: %d", action); break; case JOURNALROW: journalKey = it.data().toInt(); break; default: // no conversion needed add them to the map contactMap.insert( *find, it.data() ); break; } } /* now generate the Contact contact */ OContact contact( contactMap ); for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { contact.setCustomField( customIt.key(), customIt.data() ); } if (foundAction){ foundAction = false; switch ( action ) { case ACTION_ADD: addContact_p (contact); break; case ACTION_REMOVE: if ( !remove (contact.uid()) ) qWarning ("ODefBack(journal)::Unable to remove uid: %d", contact.uid() ); break; case ACTION_REPLACE: if ( !replace ( contact ) ) qWarning ("ODefBack(journal)::Unable to replace uid: %d", contact.uid() ); break; default: qWarning ("Unknown action: ignored !"); break; } }else{ /* Add contact to list */ addContact_p (contact); } /* Move to next element */ element = element->nextChild(); } }else { qWarning("ODefBack::could not load"); } delete root; qWarning("returning from loading" ); return true; } void OContactAccessBackend_XML::updateJournal( const OContact& cnt, journal_action action ) { QFile f( m_journalName ); bool created = !f.exists(); if ( !f.open(IO_WriteOnly|IO_Append) ) return; QString buf; QCString str; // if the file was created, we have to set the Tag "<CONTACTS>" to // get a XML-File which is readable by our parser. // This is just a cheat, but better than rewrite the parser. if ( created ){ buf = "<Contacts>"; QCString cstr = buf.utf8(); f.writeBlock( cstr.data(), cstr.length() ); } buf = "<Contact "; cnt.save( buf ); buf += " action=\"" + QString::number( (int)action ) + "\" "; buf += "/>\n"; QCString cstr = buf.utf8(); f.writeBlock( cstr.data(), cstr.length() ); } void OContactAccessBackend_XML::removeJournal() { QFile f ( m_journalName ); if ( f.exists() ) f.remove(); } +} diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h index a0cae4d..f439c4c 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h @@ -1,160 +1,108 @@ /* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/* * XML Backend for the OPIE-Contact Database. - * - * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * ===================================================================== - * ToDo: XML-Backend: Automatic reload if something was changed... - * File Locking to protect against concurrent access - * - * - * ===================================================================== - * Version: $Id$ - * ===================================================================== - * History: - * $Log$ - * Revision 1.15 2003/09/22 14:31:16 eilers - * Added first experimental incarnation of sql-backend for addressbook. - * Some modifications to be able to compile the todo sql-backend. - * A lot of changes fill follow... - * - * Revision 1.14 2003/04/13 18:07:10 zecke - * More API doc - * QString -> const QString& - * QString = 0l -> QString::null - * - * Revision 1.13 2003/03/21 10:33:09 eilers - * Merged speed optimized xml backend for contacts to main. - * Added QDateTime to querybyexample. For instance, it is now possible to get - * all Birthdays/Anniversaries between two dates. This should be used - * to show all birthdays in the datebook.. - * This change is sourcecode backward compatible but you have to upgrade - * the binaries for today-addressbook. - * - * Revision 1.12.2.2 2003/02/11 12:17:28 eilers - * Speed optimization. Removed the sequential search loops. - * - * Revision 1.12.2.1 2003/02/09 15:05:01 eilers - * Nothing happened.. Just some cleanup before I will start.. - * - * Revision 1.12 2003/01/03 16:58:03 eilers - * Reenable debug output - * - * Revision 1.11 2003/01/03 12:31:28 eilers - * Bugfix for calculating data diffs.. - * - * Revision 1.10 2003/01/02 14:27:12 eilers - * Improved query by example: Search by date is possible.. First step - * for a today plugin for birthdays.. - * - * Revision 1.9 2002/12/08 12:48:57 eilers - * Moved journal-enum from ocontact into i the xml-backend.. - * - * Revision 1.8 2002/11/14 17:04:24 eilers - * Sorting will now work if fullname is identical on some entries - * - * Revision 1.7 2002/11/13 15:02:46 eilers - * Small Bug in sorted fixed - * - * Revision 1.6 2002/11/13 14:14:51 eilers - * Added sorted for Contacts.. - * - * Revision 1.5 2002/11/01 15:10:42 eilers - * Added regExp-search in database for all fields in a contact. - * - * Revision 1.4 2002/10/16 10:52:40 eilers - * Added some docu to the interface and now using the cache infrastucture by zecke.. :) - * - * Revision 1.3 2002/10/14 16:21:54 eilers - * Some minor interface updates - * - * Revision 1.2 2002/10/07 17:34:24 eilers - * added OBackendFactory for advanced backend access - * - * Revision 1.1 2002/09/27 17:11:44 eilers - * Added API for accessing the Contact-Database ! It is compiling, but - * please do not expect that anything is working ! - * I will debug that stuff in the next time .. - * Please read README_COMPILE for compiling ! - * - * */ #ifndef _OContactAccessBackend_XML_ #define _OContactAccessBackend_XML_ -#include "ocontactaccessbackend.h" -#include "ocontactaccess.h" +#include <opie2/ocontactaccessbackend.h> +#include <opie2/ocontactaccess.h> #include <qlist.h> #include <qdict.h> +namespace Opie { /* the default xml implementation */ /** * This class is the XML implementation of a Contact backend * it does implement everything available for OContact. * @see OPimAccessBackend for more information of available methods */ class OContactAccessBackend_XML : public OContactAccessBackend { public: OContactAccessBackend_XML ( const QString& appname, const QString& filename = QString::null ); bool save(); bool load (); void clear (); bool wasChangedExternally(); QArray<int> allRecords() const; OContact find ( int uid ) const; QArray<int> queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ); QArray<int> matchRegexp( const QRegExp &r ) const; const uint querySettings(); bool hasQuerySettings (uint querySettings) const; // Currently only asc implemented.. QArray<int> sorted( bool asc, int , int , int ); bool add ( const OContact &newcontact ); bool replace ( const OContact &contact ); bool remove ( int uid ); bool reload(); private: enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; void addContact_p( const OContact &newcontact ); /* This function loads the xml-database and the journalfile */ bool load( const QString filename, bool isJournal ); void updateJournal( const OContact& cnt, journal_action action ); void removeJournal(); protected: bool m_changed; QString m_journalName; QString m_fileName; QString m_appName; QList<OContact> m_contactList; QDateTime m_readtime; QDict<OContact> m_uidToContact; }; +} + #endif diff --git a/libopie2/opiepim/backend/odatebookaccessbackend.cpp b/libopie2/opiepim/backend/odatebookaccessbackend.cpp index f0c5d65..9bf4bf0 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend.cpp @@ -1,182 +1,216 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <qtl.h> -#include "orecur.h" +#include <opie2/orecur.h> + +#include <opie2/odatebookaccessbackend.h> -#include "odatebookaccessbackend.h" +using namespace Opie; namespace { /* a small helper to get all NonRepeating events for a range of time */ void events( OEffectiveEvent::ValueList& tmpList, const OEvent::ValueList& events, const QDate& from, const QDate& to ) { QDateTime dtStart, dtEnd; for ( OEvent::ValueList::ConstIterator it = events.begin(); it != events.end(); ++it ) { dtStart = (*it).startDateTime(); dtEnd = (*it).endDateTime(); /* * If in range */ if (dtStart.date() >= from && dtEnd.date() <= to ) { OEffectiveEvent eff; eff.setEvent( (*it) ); eff.setDate( dtStart.date() ); eff.setStartTime( dtStart.time() ); /* if not on the same day */ if ( dtStart.date() != dtEnd.date() ) eff.setEndTime( QTime(23, 59, 0 ) ); else eff.setEndTime( dtEnd.time() ); tmpList.append( eff ); } /* we must also check for end date information... */ if ( dtEnd.date() != dtStart.date() && dtEnd.date() >= from ) { QDateTime dt = dtStart.addDays( 1 ); dt.setTime( QTime(0, 0, 0 ) ); QDateTime dtStop; if ( dtEnd > to ) dtStop = to; else dtStop = dtEnd; while ( dt <= dtStop ) { OEffectiveEvent eff; eff.setEvent( (*it) ); eff.setDate( dt.date() ); if ( dt >= from ) { eff.setStartTime( QTime(0, 0, 0 ) ); if ( dt.date() == dtEnd.date() ) eff.setEndTime( dtEnd.time() ); else eff.setEndTime( QTime(23, 59, 0 ) ); tmpList.append( eff ); } dt = dt.addDays( 1 ); } } } } void repeat( OEffectiveEvent::ValueList& tmpList, const OEvent::ValueList& list, const QDate& from, const QDate& to ) { QDate repeat; for ( OEvent::ValueList::ConstIterator it = list.begin(); it != list.end(); ++it ) { int dur = (*it).startDateTime().date().daysTo( (*it).endDateTime().date() ); QDate itDate = from.addDays(-dur ); ORecur rec = (*it).recurrence(); if ( !rec.hasEndDate() || rec.endDate() > to ) { rec.setEndDate( to ); rec.setHasEndDate( true ); } while (rec.nextOcurrence(itDate, repeat ) ) { if (repeat > to ) break; OEffectiveEvent eff; eff.setDate( repeat ); if ( (*it).isAllDay() ) { eff.setStartTime( QTime(0, 0, 0 ) ); eff.setEndTime( QTime(23, 59, 59 ) ); }else { /* we only occur by days, not hours/minutes/seconds. Hence * the actual end and start times will be the same for * every repeated event. For multi day events this is * fixed up later if on wronge day span */ eff.setStartTime( (*it).startDateTime().time() ); eff.setEndTime( (*it).endDateTime().time() ); } if ( dur != 0 ) { // multi-day repeating events QDate sub_it = QMAX( repeat, from ); QDate startDate = repeat; QDate endDate = startDate.addDays( dur ); while ( sub_it <= endDate && sub_it <= to ) { OEffectiveEvent tmpEff = eff; tmpEff.setEvent( (*it) ); if ( sub_it != startDate ) tmpEff.setStartTime( QTime(0, 0, 0 ) ); if ( sub_it != endDate ) tmpEff.setEndTime( QTime( 23, 59, 59 ) ); tmpEff.setDate( sub_it ); tmpEff.setEffectiveDates( startDate, endDate ); tmpList.append( tmpEff ); sub_it = sub_it.addDays( 1 ); } itDate = endDate; }else { eff.setEvent( (*it) ); tmpList.append( eff ); itDate = repeat.addDays( 1 ); } } } } } +namespace Opie { + ODateBookAccessBackend::ODateBookAccessBackend() : OPimAccessBackend<OEvent>() { } ODateBookAccessBackend::~ODateBookAccessBackend() { } OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDate& from, const QDate& to ) { OEffectiveEvent::ValueList tmpList; OEvent::ValueList list = directNonRepeats(); events( tmpList, list, from, to ); repeat( tmpList, directRawRepeats(),from,to ); list = directRawRepeats(); // Useless, isn't it ? (eilers) qHeapSort( tmpList ); return tmpList; } OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDateTime& dt ) { OEffectiveEvent::ValueList day = effectiveEvents( dt.date(), dt.date() ); OEffectiveEvent::ValueList::Iterator it; OEffectiveEvent::ValueList tmpList; QDateTime dtTmp; for ( it = day.begin(); it != day.end(); ++it ) { dtTmp = QDateTime( (*it).date(), (*it).startTime() ); if ( QABS(dt.secsTo(dtTmp) ) < 60 ) tmpList.append( (*it) ); } return tmpList; } OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) { OEffectiveEvent::ValueList tmpList; OEvent::ValueList list = directNonRepeats(); events( tmpList, list, from, to ); qHeapSort( tmpList ); return tmpList; } OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDateTime& dt ) { OEffectiveEvent::ValueList day = effectiveNonRepeatingEvents( dt.date(), dt.date() ); OEffectiveEvent::ValueList::Iterator it; OEffectiveEvent::ValueList tmpList; QDateTime dtTmp; for ( it = day.begin(); it != day.end(); ++it ) { dtTmp = QDateTime( (*it).date(), (*it).startTime() ); if ( QABS(dt.secsTo(dtTmp) ) < 60 ) tmpList.append( (*it) ); } return tmpList; } + +} diff --git a/libopie2/opiepim/backend/odatebookaccessbackend.h b/libopie2/opiepim/backend/odatebookaccessbackend.h index 3472ab3..6853670 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend.h +++ b/libopie2/opiepim/backend/odatebookaccessbackend.h @@ -1,90 +1,121 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_H #define OPIE_DATE_BOOK_ACCESS_BACKEND_H #include <qarray.h> -#include "opimaccessbackend.h" -#include "oevent.h" +#include <opie2/opimaccessbackend.h> +#include <opie2/oevent.h> +namespace Opie { /** * This class is the interface to the storage of Events. * @see OPimAccessBackend * */ class ODateBookAccessBackend : public OPimAccessBackend<OEvent> { public: typedef int UID; /** * c'tor without parameter */ ODateBookAccessBackend(); ~ODateBookAccessBackend(); /** * This method should return a list of UIDs containing * all events. No filter should be applied * @return list of events */ virtual QArray<UID> rawEvents()const = 0; /** * This method should return a list of UIDs containing * all repeating events. No filter should be applied * @return list of repeating events */ virtual QArray<UID> rawRepeats()const = 0; /** * This mthod should return a list of UIDs containing all non * repeating events. No filter should be applied * @return list of nonrepeating events */ virtual QArray<UID> nonRepeats() const = 0; /** * If you do not want to implement the effectiveEvents methods below * you need to supply it with directNonRepeats. * This method can return empty lists if effectiveEvents is implememted */ virtual OEvent::ValueList directNonRepeats() = 0; /** * Same as above but return raw repeats! */ virtual OEvent::ValueList directRawRepeats() = 0; /* is implemented by default but you can reimplement it*/ /** * Effective Events are special event occuring during a time frame. This method does calcualte * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method * yourself */ virtual OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ); /** * this is an overloaded member function * @see effectiveEvents( const QDate& from, const QDate& to ) */ virtual OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ); /** * Effective Events are special event occuring during a time frame. This method does calcualte * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method * yourself */ virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDate& from, const QDate& to ); /** * this is an overloaded member function * @see effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) */ virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDateTime& start ); private: class Private; Private *d; }; +} + #endif diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp index 756f405..e79696c 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp @@ -1,367 +1,366 @@ /* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/* * SQL Backend for the OPIE-Calender Database. * - * Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de) - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * ===================================================================== - * ===================================================================== - * Version: $Id$ - * ===================================================================== - * History: - * $Log$ - * Revision 1.3 2003/12/22 11:41:39 eilers - * Fixing stupid bug, found by sourcode review.. - * - * Revision 1.2 2003/12/22 10:19:26 eilers - * Finishing implementation of sql-backend for datebook. But I have to - * port the PIM datebook application to use it, before I could debug the - * whole stuff. - * Thus, PIM-Database backend is finished, but highly experimental. And some - * parts are still generic. For instance, the "queryByExample()" methods are - * not (or not fully) implemented. Todo: custom-entries not stored. - * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular - * expression search in the database, which is not supported by sqlite ! - * Therefore we need either an extended sqlite or a workaround which would - * be very slow and memory consuming.. - * - * Revision 1.1 2003/12/08 15:18:12 eilers - * Committing unfinished sql implementation before merging to libopie2 starts.. - * - * */ #include <stdio.h> #include <stdlib.h> #include <qarray.h> #include <qstringlist.h> #include <qpe/global.h> #include <opie2/osqldriver.h> #include <opie2/osqlmanager.h> #include <opie2/osqlquery.h> -#include "orecur.h" -#include "odatebookaccessbackend_sql.h" +#include <opie2/orecur.h> +#include <opie2/odatebookaccessbackend_sql.h> +namespace Opie { ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , const QString& fileName ) : ODateBookAccessBackend(), m_driver( NULL ) { m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; // Get the standart sql-driver from the OSQLManager.. OSQLManager man; m_driver = man.standard(); m_driver->setUrl( m_fileName ); initFields(); load(); } ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { if( m_driver ) delete m_driver; } void ODateBookAccessBackend_SQL::initFields() { // This map contains the translation of the fieldtype id's to // the names of the table columns m_fieldMap.insert( OEvent::FUid, "uid" ); m_fieldMap.insert( OEvent::FCategories, "Categories" ); m_fieldMap.insert( OEvent::FDescription, "Description" ); m_fieldMap.insert( OEvent::FLocation, "Location" ); m_fieldMap.insert( OEvent::FType, "Type" ); m_fieldMap.insert( OEvent::FAlarm, "Alarm" ); m_fieldMap.insert( OEvent::FSound, "Sound" ); m_fieldMap.insert( OEvent::FRType, "RType" ); m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" ); m_fieldMap.insert( OEvent::FRPosition, "RPosition" ); m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); m_fieldMap.insert( OEvent::FRExceptions, "RExceptions" ); m_fieldMap.insert( OEvent::FStart, "Start" ); m_fieldMap.insert( OEvent::FEnd, "End" ); m_fieldMap.insert( OEvent::FNote, "Note" ); m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); // Create a map that maps the column name to the id QMapConstIterator<int, QString> it; for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ m_reverseFieldMap.insert( it.data(), it.key() ); } } bool ODateBookAccessBackend_SQL::load() { if (!m_driver->open() ) return false; // Don't expect that the database exists. // It is save here to create the table, even if it // do exist. ( Is that correct for all databases ?? ) QString qu = "create table datebook( uid INTEGER PRIMARY KEY "; QMap<int, QString>::Iterator it; for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() ); } qu += " );"; qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; qWarning( "command: %s", qu.latin1() ); OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ) return false; update(); return true; } void ODateBookAccessBackend_SQL::update() { QString qu = "select uid from datebook"; OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ // m_uids.clear(); return; } m_uids = extractUids( res ); } bool ODateBookAccessBackend_SQL::reload() { return load(); } bool ODateBookAccessBackend_SQL::save() { return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) } QArray<int> ODateBookAccessBackend_SQL::allRecords()const { return m_uids; } QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) { return QArray<int>(); } void ODateBookAccessBackend_SQL::clear() { QString qu = "drop table datebook;"; qu += "drop table custom_data;"; OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); reload(); } OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ QString qu = "select *"; qu += "from datebook where uid = " + QString::number(uid); OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); OSQLResultItem resItem = res.first(); // Create Map for date event and insert UID QMap<int,QString> dateEventMap; dateEventMap.insert( OEvent::FUid, QString::number( uid ) ); // Now insert the data out of the columns into the map. QMapConstIterator<int, QString> it; for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) ); } // Last step: Put map into date event and return it OEvent retDate( dateEventMap ); return retDate; } // FIXME: Speed up update of uid's.. bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) { QMap<int,QString> eventMap = ev.toMap(); QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() ); QMap<int, QString>::Iterator it; for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ if ( !eventMap[it.key()].isEmpty() ) qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] ); else qu += QString( ",\"\"" ); } qu += " );"; // Add custom entries int id = 0; QMap<QString, QString> customMap = ev.toExtraMap(); for( QMap<QString, QString>::Iterator it = customMap.begin(); it != customMap.end(); ++it ){ qu += "insert into custom_data VALUES(" + QString::number( ev.uid() ) + "," + QString::number( id++ ) + ",'" + it.key() //.latin1() + "'," + "0" // Priority for future enhancements + ",'" + it.data() //.latin1() + "');"; } qWarning("add %s", qu.latin1() ); OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ return false; } // Update list of uid's update(); return true; } // FIXME: Speed up update of uid's.. bool ODateBookAccessBackend_SQL::remove( int uid ) { QString qu = "DELETE from datebook where uid = " + QString::number( uid ) + ";"; qu += "DELETE from custom_data where uid = " + QString::number( uid ) + ";"; OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ return false; } // Update list of uid's update(); return true; } bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) { remove( ev.uid() ); return add( ev ); } QArray<int> ODateBookAccessBackend_SQL::rawEvents()const { return allRecords(); } QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const { QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\""; OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ QArray<int> nix; return nix; } return extractUids( res ); } QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const { QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\""; OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ QArray<int> nix; return nix; } return extractUids( res ); } OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() { QArray<int> nonRepUids = nonRepeats(); OEvent::ValueList list; for (uint i = 0; i < nonRepUids.count(); ++i ){ list.append( find( nonRepUids[i] ) ); } return list; } OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() { QArray<int> rawRepUids = rawRepeats(); OEvent::ValueList list; for (uint i = 0; i < rawRepUids.count(); ++i ){ list.append( find( rawRepUids[i] ) ); } return list; } QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const { QArray<int> null; return null; } /* ===== Private Functions ========================================== */ QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const { qWarning("extractUids"); QTime t; t.start(); OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it; QArray<int> ints(list.count() ); qWarning(" count = %d", list.count() ); int i = 0; for (it = list.begin(); it != list.end(); ++it ) { ints[i] = (*it).data("uid").toInt(); i++; } qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); return ints; } + +} diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h index f39e154..89939ef 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h @@ -1,62 +1,93 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H #define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H #include <qmap.h> #include <opie2/osqlresult.h> -#include "odatebookaccessbackend.h" +#include <opie2/odatebookaccessbackend.h> class OSQLDriver; +namespace Opie { /** * This is the default SQL implementation for DateBoook SQL storage * It fully implements the interface * @see ODateBookAccessBackend * @see OPimAccessBackend */ class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { public: ODateBookAccessBackend_SQL( const QString& appName, const QString& fileName = QString::null); ~ODateBookAccessBackend_SQL(); bool load(); bool reload(); bool save(); QArray<int> allRecords()const; QArray<int> matchRegexp(const QRegExp &r) const; QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() ); OEvent find( int uid )const; void clear(); bool add( const OEvent& ev ); bool remove( int uid ); bool replace( const OEvent& ev ); QArray<UID> rawEvents()const; QArray<UID> rawRepeats()const; QArray<UID> nonRepeats()const; OEvent::ValueList directNonRepeats(); OEvent::ValueList directRawRepeats(); private: bool loadFile(); QString m_fileName; QArray<int> m_uids; QMap<int, QString> m_fieldMap; QMap<QString, int> m_reverseFieldMap; OSQLDriver* m_driver; class Private; Private *d; void initFields(); void update(); QArray<int> extractUids( OSQLResult& res ) const; }; +} + #endif diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp index 929d004..0ebda98 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp @@ -1,612 +1,645 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> #include <unistd.h> #include <qasciidict.h> #include <qfile.h> #include <qtopia/global.h> #include <qtopia/stringutil.h> #include <qtopia/timeconversion.h> -#include "opimnotifymanager.h" -#include "orecur.h" -#include "otimezone.h" -#include "odatebookaccessbackend_xml.h" +#include <opie2/opimnotifymanager.h> +#include <opie2/orecur.h> +#include <opie2/otimezone.h> +#include <opie2/odatebookaccessbackend_xml.h> + +using namespace Opie; namespace { // FROM TT again char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) { char needleChar; char haystackChar; if (!needle || !haystack || !hLen || !nLen) return 0; const char* hsearch = haystack; if ((needleChar = *needle++) != 0) { nLen--; //(to make up for needle++) do { do { if ((haystackChar = *hsearch++) == 0) return (0); if (hsearch >= haystack + hLen) return (0); } while (haystackChar != needleChar); } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); hsearch--; } return ((char *)hsearch); } } namespace { time_t start, end, created, rp_end; ORecur* rec; ORecur* recur() { if (!rec) rec = new ORecur; return rec; } int alarmTime; int snd; enum Attribute{ FDescription = 0, FLocation, FCategories, FUid, FType, FAlarm, FSound, FRType, FRWeekdays, FRPosition, FRFreq, FRHasEndDate, FREndDate, FRStart, FREnd, FNote, FCreated, // Should't this be called FRCreated ? FTimeZone, FRecParent, FRecChildren, FExceptions }; // FIXME: Use OEvent::toMap() here !! (eilers) inline void save( const OEvent& ev, QString& buf ) { qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; if (!ev.location().isEmpty() ) buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; buf += " uid=\"" + QString::number( ev.uid() ) + "\""; if (ev.isAllDay() ) buf += " type=\"AllDay\""; // is that all ?? (eilers) if (ev.hasNotifiers() ) { OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; if ( alarm.sound() == OPimAlarm::Loud ) buf += "loud"; else buf += "silent"; buf += "\""; } if ( ev.hasRecurrence() ) { buf += ev.recurrence().toString(); } /* * fscking timezones :) well, we'll first convert * the QDateTime to a QDateTime in UTC time * and then we'll create a nice time_t */ OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; if (!ev.note().isEmpty() ) { buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; } buf += " timezone=\""; if ( ev.timeZone().isEmpty() ) buf += "None"; else buf += ev.timeZone(); buf += "\""; if (ev.parent() != 0 ) { buf += " recparent=\""+QString::number(ev.parent() )+"\""; } if (ev.children().count() != 0 ) { QArray<int> children = ev.children(); buf += " recchildren=\""; for ( uint i = 0; i < children.count(); i++ ) { if ( i != 0 ) buf += " "; buf += QString::number( children[i] ); } buf+= "\""; } // skip custom writing } inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) { QMap<int, OEvent>::ConstIterator it; QString buf; QCString str; int total_written; for ( it = list.begin(); it != list.end(); ++it ) { buf = "<event"; save( it.data(), buf ); buf += " />\n"; str = buf.utf8(); total_written = file.writeBlock(str.data(), str.length() ); if ( total_written != int(str.length() ) ) return false; } return true; } } +namespace Opie { ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , const QString& fileName ) : ODateBookAccessBackend() { m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; m_changed = false; } ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { } bool ODateBookAccessBackend_XML::load() { return loadFile(); } bool ODateBookAccessBackend_XML::reload() { clear(); return load(); } bool ODateBookAccessBackend_XML::save() { if (!m_changed) return true; int total_written; QString strFileNew = m_name + ".new"; QFile f( strFileNew ); if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; buf += "<events>\n"; QCString str = buf.utf8(); total_written = f.writeBlock( str.data(), str.length() ); if ( total_written != int(str.length() ) ) { f.close(); QFile::remove( strFileNew ); return false; } if (!forAll( m_raw, f ) ) { f.close(); QFile::remove( strFileNew ); return false; } if (!forAll( m_rep, f ) ) { f.close(); QFile::remove( strFileNew ); return false; } buf = "</events>\n</DATEBOOK>\n"; str = buf.utf8(); total_written = f.writeBlock( str.data(), str.length() ); if ( total_written != int(str.length() ) ) { f.close(); QFile::remove( strFileNew ); return false; } f.close(); if ( ::rename( strFileNew, m_name ) < 0 ) { QFile::remove( strFileNew ); return false; } m_changed = false; return true; } QArray<int> ODateBookAccessBackend_XML::allRecords()const { QArray<int> ints( m_raw.count()+ m_rep.count() ); uint i = 0; QMap<int, OEvent>::ConstIterator it; for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { ints[i] = it.key(); i++; } for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { ints[i] = it.key(); i++; } return ints; } QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int, const QDateTime& ) { return QArray<int>(); } void ODateBookAccessBackend_XML::clear() { m_changed = true; m_raw.clear(); m_rep.clear(); } OEvent ODateBookAccessBackend_XML::find( int uid ) const{ if ( m_raw.contains( uid ) ) return m_raw[uid]; else return m_rep[uid]; } bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { m_changed = true; if (ev.hasRecurrence() ) m_rep.insert( ev.uid(), ev ); else m_raw.insert( ev.uid(), ev ); return true; } bool ODateBookAccessBackend_XML::remove( int uid ) { m_changed = true; m_rep.remove( uid ); m_rep.remove( uid ); return true; } bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers) return add( ev ); } QArray<int> ODateBookAccessBackend_XML::rawEvents()const { return allRecords(); } QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { QArray<int> ints( m_rep.count() ); uint i = 0; QMap<int, OEvent>::ConstIterator it; for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { ints[i] = it.key(); i++; } return ints; } QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { QArray<int> ints( m_raw.count() ); uint i = 0; QMap<int, OEvent>::ConstIterator it; for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { ints[i] = it.key(); i++; } return ints; } OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { OEvent::ValueList list; QMap<int, OEvent>::ConstIterator it; for (it = m_raw.begin(); it != m_raw.end(); ++it ) list.append( it.data() ); return list; } OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { OEvent::ValueList list; QMap<int, OEvent>::ConstIterator it; for (it = m_rep.begin(); it != m_rep.end(); ++it ) list.append( it.data() ); return list; } // FIXME: Use OEvent::fromMap() (eilers) bool ODateBookAccessBackend_XML::loadFile() { m_changed = false; int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); if ( fd < 0 ) return false; struct stat attribute; if ( ::fstat(fd, &attribute ) == -1 ) { ::close( fd ); return false; } void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); if ( map_addr == ( (caddr_t)-1) ) { ::close( fd ); return false; } ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); ::close( fd ); QAsciiDict<int> dict(FExceptions+1); dict.setAutoDelete( true ); dict.insert( "description", new int(FDescription) ); dict.insert( "location", new int(FLocation) ); dict.insert( "categories", new int(FCategories) ); dict.insert( "uid", new int(FUid) ); dict.insert( "type", new int(FType) ); dict.insert( "alarm", new int(FAlarm) ); dict.insert( "sound", new int(FSound) ); dict.insert( "rtype", new int(FRType) ); dict.insert( "rweekdays", new int(FRWeekdays) ); dict.insert( "rposition", new int(FRPosition) ); dict.insert( "rfreq", new int(FRFreq) ); dict.insert( "rhasenddate", new int(FRHasEndDate) ); dict.insert( "enddt", new int(FREndDate) ); dict.insert( "start", new int(FRStart) ); dict.insert( "end", new int(FREnd) ); dict.insert( "note", new int(FNote) ); dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? dict.insert( "recparent", new int(FRecParent) ); dict.insert( "recchildren", new int(FRecChildren) ); dict.insert( "exceptions", new int(FExceptions) ); dict.insert( "timezone", new int(FTimeZone) ); char* dt = (char*)map_addr; int len = attribute.st_size; int i = 0; char* point; const char* collectionString = "<event "; int strLen = ::strlen(collectionString); int *find; while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { i = point -dt; i+= strLen; alarmTime = -1; snd = 0; // silent OEvent ev; rec = 0; while ( TRUE ) { while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) ++i; if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) break; // we have another attribute, read it. int j = i; while ( j < len && dt[j] != '=' ) ++j; QCString attr( dt+i, j-i+1); i = ++j; // skip = // find the start of quotes while ( i < len && dt[i] != '"' ) ++i; j = ++i; bool haveUtf = FALSE; bool haveEnt = FALSE; while ( j < len && dt[j] != '"' ) { if ( ((unsigned char)dt[j]) > 0x7f ) haveUtf = TRUE; if ( dt[j] == '&' ) haveEnt = TRUE; ++j; } if ( i == j ) { // empty value i = j + 1; continue; } QCString value( dt+i, j-i+1 ); i = j + 1; QString str = (haveUtf ? QString::fromUtf8( value ) : QString::fromLatin1( value ) ); if ( haveEnt ) str = Qtopia::plainString( str ); /* * add key + value */ find = dict[attr.data()]; if (!find) ev.setCustomField( attr, str ); else { setField( ev, *find, str ); } } /* time to finalize */ finalizeRecord( ev ); delete rec; } ::munmap(map_addr, attribute.st_size ); m_changed = false; // changed during add return true; } // FIXME: Use OEvent::fromMap() which makes this obsolete.. (eilers) void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { /* AllDay is alway in UTC */ if ( ev.isAllDay() ) { OTimeZone utc = OTimeZone::utc(); ev.setStartDateTime( utc.fromUTCDateTime( start ) ); ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); ev.setTimeZone( "UTC"); // make sure it is really utc }else { /* to current date time */ // qWarning(" Start is %d", start ); OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); QDateTime date = zone.toDateTime( start ); qWarning(" Start is %s", date.toString().latin1() ); ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); date = zone.toDateTime( end ); ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); } if ( rec && rec->doesRecur() ) { OTimeZone utc = OTimeZone::utc(); ORecur recu( *rec ); // call copy c'tor; recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); recu.setStart( ev.startDateTime().date() ); ev.setRecurrence( recu ); } if (alarmTime != -1 ) { QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); OPimAlarm al( snd , dt ); ev.notifiers().add( al ); } if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { qWarning("already contains assign uid"); ev.setUid( 1 ); } qWarning("addind %d %s", ev.uid(), ev.description().latin1() ); if ( ev.hasRecurrence() ) m_rep.insert( ev.uid(), ev ); else m_raw.insert( ev.uid(), ev ); } void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { // qWarning(" setting %s", value.latin1() ); switch( id ) { case FDescription: e.setDescription( value ); break; case FLocation: e.setLocation( value ); break; case FCategories: e.setCategories( e.idsFromString( value ) ); break; case FUid: e.setUid( value.toInt() ); break; case FType: if ( value == "AllDay" ) { e.setAllDay( true ); e.setTimeZone( "UTC" ); } break; case FAlarm: alarmTime = value.toInt(); break; case FSound: snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; break; // recurrence stuff case FRType: if ( value == "Daily" ) recur()->setType( ORecur::Daily ); else if ( value == "Weekly" ) recur()->setType( ORecur::Weekly); else if ( value == "MonthlyDay" ) recur()->setType( ORecur::MonthlyDay ); else if ( value == "MonthlyDate" ) recur()->setType( ORecur::MonthlyDate ); else if ( value == "Yearly" ) recur()->setType( ORecur::Yearly ); else recur()->setType( ORecur::NoRepeat ); break; case FRWeekdays: recur()->setDays( value.toInt() ); break; case FRPosition: recur()->setPosition( value.toInt() ); break; case FRFreq: recur()->setFrequency( value.toInt() ); break; case FRHasEndDate: recur()->setHasEndDate( value.toInt() ); break; case FREndDate: { rp_end = (time_t) value.toLong(); break; } case FRStart: { start = (time_t) value.toLong(); break; } case FREnd: { end = ( (time_t) value.toLong() ); break; } case FNote: e.setNote( value ); break; case FCreated: created = value.toInt(); break; case FRecParent: e.setParent( value.toInt() ); break; case FRecChildren:{ QStringList list = QStringList::split(' ', value ); for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { e.addChild( (*it).toInt() ); } } break; case FExceptions:{ QStringList list = QStringList::split(' ', value ); for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); qWarning("adding exception %s", date.toString().latin1() ); recur()->exceptions().append( date ); } } break; case FTimeZone: if ( value != "None" ) e.setTimeZone( value ); break; default: break; } } QArray<int> ODateBookAccessBackend_XML::matchRegexp( const QRegExp &r ) const { QArray<int> m_currentQuery( m_raw.count()+ m_rep.count() ); uint arraycounter = 0; QMap<int, OEvent>::ConstIterator it; for ( it = m_raw.begin(); it != m_raw.end(); ++it ) if ( it.data().match( r ) ) m_currentQuery[arraycounter++] = it.data().uid(); for ( it = m_rep.begin(); it != m_rep.end(); ++it ) if ( it.data().match( r ) ) m_currentQuery[arraycounter++] = it.data().uid(); // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; } + +} diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.h b/libopie2/opiepim/backend/odatebookaccessbackend_xml.h index a5cc0fc..29f5f4f 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.h +++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.h @@ -1,55 +1,86 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H #define OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H #include <qmap.h> -#include "odatebookaccessbackend.h" +#include <opie2/odatebookaccessbackend.h> +namespace Opie { /** * This is the default XML implementation for DateBoook XML storage * It fully implements the interface * @see ODateBookAccessBackend * @see OPimAccessBackend */ class ODateBookAccessBackend_XML : public ODateBookAccessBackend { public: ODateBookAccessBackend_XML( const QString& appName, const QString& fileName = QString::null); ~ODateBookAccessBackend_XML(); bool load(); bool reload(); bool save(); QArray<int> allRecords()const; QArray<int> matchRegexp(const QRegExp &r) const; QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() ); OEvent find( int uid )const; void clear(); bool add( const OEvent& ev ); bool remove( int uid ); bool replace( const OEvent& ev ); QArray<UID> rawEvents()const; QArray<UID> rawRepeats()const; QArray<UID> nonRepeats()const; OEvent::ValueList directNonRepeats(); OEvent::ValueList directRawRepeats(); private: bool m_changed :1 ; bool loadFile(); inline void finalizeRecord( OEvent& ev ); inline void setField( OEvent&, int field, const QString& val ); QString m_name; QMap<int, OEvent> m_raw; QMap<int, OEvent> m_rep; struct Data; Data* data; class Private; Private *d; }; +} + #endif diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h index fd264fc..505358e 100644 --- a/libopie2/opiepim/backend/opimaccessbackend.h +++ b/libopie2/opiepim/backend/opimaccessbackend.h @@ -1,160 +1,192 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_PIM_ACCESS_BACKEND #define OPIE_PIM_ACCESS_BACKEND #include <qarray.h> #include <qdatetime.h> -#include <opie/otemplatebase.h> -#include <opie/opimrecord.h> +#include <opie2/otemplatebase.h> +#include <opie2/opimrecord.h> +namespace Opie { class OPimAccessBackendPrivate; /** * OPimAccessBackend is the base class * for all private backends * it operates on OPimRecord as the base class * and it's responsible for fast manipulating * the resource the implementation takes care * of */ template <class T = OPimRecord> class OPimAccessBackend { public: typedef OTemplateBase<T> Frontend; /** The access hint from the frontend */ OPimAccessBackend(int access = 0); virtual ~OPimAccessBackend(); /** * load the resource */ virtual bool load() = 0; /** * reload the resource */ virtual bool reload() = 0; /** * save the resource and * all it's changes */ virtual bool save() = 0; /** * return an array of * all available uids */ virtual QArray<int> allRecords()const = 0; /** * return a List of records * that match the regex */ virtual QArray<int> matchRegexp(const QRegExp &r) const = 0; /** * queryByExample for T with the given Settings * */ virtual QArray<int> queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() ) = 0; /** * find the OPimRecord with uid @param uid * returns T and T.isEmpty() if nothing was found */ virtual T find(int uid )const = 0; virtual T find(int uid, const QArray<int>& items, uint current, typename Frontend::CacheDirection )const ; /** * clear the back end */ virtual void clear() = 0; /** * add T */ virtual bool add( const T& t ) = 0; /** * remove */ virtual bool remove( int uid ) = 0; /** * replace a record with T.uid() */ virtual bool replace( const T& t ) = 0; /* * setTheFrontEnd!!! */ void setFrontend( Frontend* front ); /** * set the read ahead count */ void setReadAhead( uint count ); protected: int access()const; void cache( const T& t )const; /** * use a prime number here! */ void setSaneCacheSize( int ); uint readAhead()const; private: OPimAccessBackendPrivate *d; Frontend* m_front; uint m_read; int m_acc; }; template <class T> OPimAccessBackend<T>::OPimAccessBackend(int acc) : m_acc( acc ) { m_front = 0l; } template <class T> OPimAccessBackend<T>::~OPimAccessBackend() { } template <class T> void OPimAccessBackend<T>::setFrontend( Frontend* fr ) { m_front = fr; } template <class T> void OPimAccessBackend<T>::cache( const T& t )const { if (m_front ) m_front->cache( t ); } template <class T> void OPimAccessBackend<T>::setSaneCacheSize( int size) { if (m_front ) m_front->setSaneCacheSize( size ); } template <class T> T OPimAccessBackend<T>::find( int uid, const QArray<int>&, uint, typename Frontend::CacheDirection )const { return find( uid ); } template <class T> void OPimAccessBackend<T>::setReadAhead( uint count ) { m_read = count; } template <class T> uint OPimAccessBackend<T>::readAhead()const { return m_read; } template <class T> int OPimAccessBackend<T>::access()const { return m_acc; } + +} + #endif diff --git a/libopie2/opiepim/backend/otodoaccessbackend.cpp b/libopie2/opiepim/backend/otodoaccessbackend.cpp index baaeecc..d27f5ef 100644 --- a/libopie2/opiepim/backend/otodoaccessbackend.cpp +++ b/libopie2/opiepim/backend/otodoaccessbackend.cpp @@ -1,10 +1,41 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ -#include "otodoaccessbackend.h" +#include <opie2/otodoaccessbackend.h> +namespace Opie { OTodoAccessBackend::OTodoAccessBackend() : OPimAccessBackend<OTodo>() { } OTodoAccessBackend::~OTodoAccessBackend() { } + +} diff --git a/libopie2/opiepim/backend/otodoaccessbackend.h b/libopie2/opiepim/backend/otodoaccessbackend.h index 6be95bc..54b52cc 100644 --- a/libopie2/opiepim/backend/otodoaccessbackend.h +++ b/libopie2/opiepim/backend/otodoaccessbackend.h @@ -1,28 +1,59 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_TODO_ACCESS_BACKEND_H #define OPIE_TODO_ACCESS_BACKEND_H #include <qbitarray.h> -#include "otodo.h" -#include "opimaccessbackend.h" +#include <opie2/otodo.h> +#include <opie2/opimaccessbackend.h> +namespace Opie { class OTodoAccessBackend : public OPimAccessBackend<OTodo> { public: OTodoAccessBackend(); ~OTodoAccessBackend(); virtual QArray<int> effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates ) = 0; virtual QArray<int> overDue() = 0; virtual QArray<int> sorted( bool asc, int sortOrder, int sortFilter, int cat ) = 0; virtual void removeAllCompleted() = 0; virtual QBitArray supports()const = 0; private: class Private; Private *d; }; +} + #endif diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp index 3764c7e..944f82a 100644 --- a/libopie2/opiepim/backend/otodoaccesssql.cpp +++ b/libopie2/opiepim/backend/otodoaccesssql.cpp @@ -1,693 +1,726 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <qdatetime.h> #include <qpe/global.h> #include <opie2/osqldriver.h> #include <opie2/osqlresult.h> #include <opie2/osqlmanager.h> #include <opie2/osqlquery.h> -#include "otodoaccesssql.h" -#include "opimstate.h" -#include "opimnotifymanager.h" -#include "orecur.h" +#include <opie2/otodoaccesssql.h> +#include <opie2/opimstate.h> +#include <opie2/opimnotifymanager.h> +#include <opie2/orecur.h> +using namespace Opie; /* * first some query * CREATE query * LOAD query * INSERT * REMOVE * CLEAR */ namespace { /** * CreateQuery for the Todolist Table */ class CreateQuery : public OSQLQuery { public: CreateQuery(); ~CreateQuery(); QString query()const; }; /** * LoadQuery * this one queries for all uids */ class LoadQuery : public OSQLQuery { public: LoadQuery(); ~LoadQuery(); QString query()const; }; /** * inserts/adds a OTodo to the table */ class InsertQuery : public OSQLQuery { public: InsertQuery(const OTodo& ); ~InsertQuery(); QString query()const; private: OTodo m_todo; }; /** * removes one from the table */ class RemoveQuery : public OSQLQuery { public: RemoveQuery(int uid ); ~RemoveQuery(); QString query()const; private: int m_uid; }; /** * Clears (delete) a Table */ class ClearQuery : public OSQLQuery { public: ClearQuery(); ~ClearQuery(); QString query()const; }; /** * a find query */ class FindQuery : public OSQLQuery { public: FindQuery(int uid); FindQuery(const QArray<int>& ); ~FindQuery(); QString query()const; private: QString single()const; QString multi()const; QArray<int> m_uids; int m_uid; }; /** * overdue query */ class OverDueQuery : public OSQLQuery { public: OverDueQuery(); ~OverDueQuery(); QString query()const; }; class EffQuery : public OSQLQuery { public: EffQuery( const QDate&, const QDate&, bool inc ); ~EffQuery(); QString query()const; private: QString with()const; QString out()const; QDate m_start; QDate m_end; bool m_inc :1; }; CreateQuery::CreateQuery() : OSQLQuery() {} CreateQuery::~CreateQuery() {} QString CreateQuery::query()const { QString qu; qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; qu += "description, summary, priority, DueDate, progress , state, "; // This is the recurrance-stuff .. Exceptions are currently not supported (see ORecur.cpp) ! (eilers) qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, "; qu += "reminders, alarms, maintainer, startdate, completeddate);"; qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; return qu; } LoadQuery::LoadQuery() : OSQLQuery() {} LoadQuery::~LoadQuery() {} QString LoadQuery::query()const { QString qu; // We do not need "distinct" here. The primary key is always unique.. //qu += "select distinct uid from todolist"; qu += "select uid from todolist"; return qu; } InsertQuery::InsertQuery( const OTodo& todo ) : OSQLQuery(), m_todo( todo ) { } InsertQuery::~InsertQuery() { } /* * converts from a OTodo to a query * we leave out X-Ref + Alarms */ QString InsertQuery::query()const{ int year, month, day; year = month = day = 0; if (m_todo.hasDueDate() ) { QDate date = m_todo.dueDate(); year = date.year(); month = date.month(); day = date.day(); } int sYear = 0, sMonth = 0, sDay = 0; if( m_todo.hasStartDate() ){ QDate sDate = m_todo.startDate(); sYear = sDate.year(); sMonth= sDate.month(); sDay = sDate.day(); } int eYear = 0, eMonth = 0, eDay = 0; if( m_todo.hasCompletedDate() ){ QDate eDate = m_todo.completedDate(); eYear = eDate.year(); eMonth= eDate.month(); eDay = eDate.day(); } QString qu; QMap<int, QString> recMap = m_todo.recurrence().toMap(); qu = "insert into todolist VALUES(" + QString::number( m_todo.uid() ) + "," + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," + QString::number( m_todo.isCompleted() ) + "," + "'" + m_todo.description() + "'" + "," + "'" + m_todo.summary() + "'" + "," + QString::number(m_todo.priority() ) + "," + "'" + QString::number(year) + "-" + QString::number(month) + "-" + QString::number( day ) + "'" + "," + QString::number( m_todo.progress() ) + "," + QString::number( m_todo.state().state() ) + "," + "'" + recMap[ ORecur::RType ] + "'" + "," + "'" + recMap[ ORecur::RWeekdays ] + "'" + "," + "'" + recMap[ ORecur::RPosition ] + "'" + "," + "'" + recMap[ ORecur::RFreq ] + "'" + "," + "'" + recMap[ ORecur::RHasEndDate ] + "'" + "," + "'" + recMap[ ORecur::EndDate ] + "'" + "," + "'" + recMap[ ORecur::Created ] + "'" + "," + "'" + recMap[ ORecur::Exceptions ] + "'" + ","; if ( m_todo.hasNotifiers() ) { OPimNotifyManager manager = m_todo.notifiers(); qu += "'" + manager.remindersToString() + "'" + "," + "'" + manager.alarmsToString() + "'" + ","; } else{ qu += QString( "''" ) + "," + "''" + ","; } qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) + "'" + QString::number(sYear) + "-" + QString::number(sMonth) + "-" + QString::number(sDay) + "'" + "," + "'" + QString::number(eYear) + "-" + QString::number(eMonth) + "-"+QString::number(eDay) + "'" + ")"; qWarning("add %s", qu.latin1() ); return qu; } RemoveQuery::RemoveQuery(int uid ) : OSQLQuery(), m_uid( uid ) {} RemoveQuery::~RemoveQuery() {} QString RemoveQuery::query()const { QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); return qu; } ClearQuery::ClearQuery() : OSQLQuery() {} ClearQuery::~ClearQuery() {} QString ClearQuery::query()const { QString qu = "drop table todolist"; return qu; } FindQuery::FindQuery(int uid) : OSQLQuery(), m_uid(uid ) { } FindQuery::FindQuery(const QArray<int>& ints) : OSQLQuery(), m_uids(ints){ } FindQuery::~FindQuery() { } QString FindQuery::query()const{ if (m_uids.count() == 0 ) return single(); else return multi(); } QString FindQuery::single()const{ QString qu = "select * from todolist where uid = " + QString::number(m_uid); return qu; } QString FindQuery::multi()const { QString qu = "select * from todolist where "; for (uint i = 0; i < m_uids.count(); i++ ) { qu += " UID = " + QString::number( m_uids[i] ) + " OR"; } qu.remove( qu.length()-2, 2 ); return qu; } OverDueQuery::OverDueQuery(): OSQLQuery() {} OverDueQuery::~OverDueQuery() {} QString OverDueQuery::query()const { QDate date = QDate::currentDate(); QString str; str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); return str; } EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} EffQuery::~EffQuery() {} QString EffQuery::query()const { return m_inc ? with() : out(); } QString EffQuery::with()const { QString str; str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); return str; } QString EffQuery::out()const { QString str; str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); return str; } }; + +namespace Opie { OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) : OTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true) { QString fi = file; if ( fi.isEmpty() ) fi = Global::applicationFileName( "todolist", "todolist.db" ); OSQLManager man; m_driver = man.standard(); m_driver->setUrl(fi); // fillDict(); } OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ if( m_driver ) delete m_driver; } bool OTodoAccessBackendSQL::load(){ if (!m_driver->open() ) return false; CreateQuery creat; OSQLResult res = m_driver->query(&creat ); m_dirty = true; return true; } bool OTodoAccessBackendSQL::reload(){ return load(); } bool OTodoAccessBackendSQL::save(){ return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) } QArray<int> OTodoAccessBackendSQL::allRecords()const { if (m_dirty ) update(); return m_uids; } QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ QArray<int> ints(0); return ints; } OTodo OTodoAccessBackendSQL::find(int uid ) const{ FindQuery query( uid ); return todo( m_driver->query(&query) ); } OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, uint cur, Frontend::CacheDirection dir ) const{ uint CACHE = readAhead(); qWarning("searching for %d", uid ); QArray<int> search( CACHE ); uint size =0; OTodo to; // we try to cache CACHE items switch( dir ) { /* forward */ case 0: // FIXME: Not a good style to use magic numbers here (eilers) for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { qWarning("size %d %d", size, ints[i] ); search[size] = ints[i]; size++; } break; /* reverse */ case 1: // FIXME: Not a good style to use magic numbers here (eilers) for (uint i = cur; i != 0 && size < CACHE; i-- ) { search[size] = ints[i]; size++; } break; } search.resize( size ); FindQuery query( search ); OSQLResult res = m_driver->query( &query ); if ( res.state() != OSQLResult::Success ) return to; return todo( res ); } void OTodoAccessBackendSQL::clear() { ClearQuery cle; OSQLResult res = m_driver->query( &cle ); CreateQuery qu; res = m_driver->query(&qu); } bool OTodoAccessBackendSQL::add( const OTodo& t) { InsertQuery ins( t ); OSQLResult res = m_driver->query( &ins ); if ( res.state() == OSQLResult::Failure ) return false; int c = m_uids.count(); m_uids.resize( c+1 ); m_uids[c] = t.uid(); return true; } bool OTodoAccessBackendSQL::remove( int uid ) { RemoveQuery rem( uid ); OSQLResult res = m_driver->query(&rem ); if ( res.state() == OSQLResult::Failure ) return false; m_dirty = true; return true; } /* * FIXME better set query * but we need the cache for that * now we remove */ bool OTodoAccessBackendSQL::replace( const OTodo& t) { remove( t.uid() ); bool b= add(t); m_dirty = false; // we changed some stuff but the UID stayed the same return b; } QArray<int> OTodoAccessBackendSQL::overDue() { OverDueQuery qu; return uids( m_driver->query(&qu ) ); } QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, const QDate& t, bool u) { EffQuery ef(s, t, u ); return uids (m_driver->query(&ef) ); } /* * */ QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, int sortFilter, int cat ) { qWarning("sorted %d, %d", asc, sortOrder ); QString query; query = "select uid from todolist WHERE "; /* * Sort Filter stuff * not that straight forward * FIXME: Replace magic numbers * */ /* Category */ if ( sortFilter & 1 ) { QString str; if (cat != 0 ) str = QString::number( cat ); query += " categories like '%" +str+"%' AND"; } /* Show only overdue */ if ( sortFilter & 2 ) { QDate date = QDate::currentDate(); QString due; QString base; base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); query += " " + base + " AND"; } /* not show completed */ if ( sortFilter & 4 ) { query += " completed = 0 AND"; }else{ query += " ( completed = 1 OR completed = 0) AND"; } /* srtip the end */ query = query.remove( query.length()-3, 3 ); /* * sort order stuff * quite straight forward */ query += "ORDER BY "; switch( sortOrder ) { /* completed */ case 0: query += "completed"; break; case 1: query += "priority"; break; case 2: query += "summary"; break; case 3: query += "DueDate"; break; } if ( !asc ) { qWarning("not ascending!"); query += " DESC"; } qWarning( query ); OSQLRawQuery raw(query ); return uids( m_driver->query(&raw) ); } bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ if ( str == "0-0-0" ) return false; else{ int day, year, month; QStringList list = QStringList::split("-", str ); year = list[0].toInt(); month = list[1].toInt(); day = list[2].toInt(); da.setYMD( year, month, day ); return true; } } OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ if ( res.state() == OSQLResult::Failure ) { OTodo to; return to; } OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it = list.begin(); qWarning("todo1"); OTodo to = todo( (*it) ); cache( to ); ++it; for ( ; it != list.end(); ++it ) { qWarning("caching"); cache( todo( (*it) ) ); } return to; } OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const { qWarning("todo"); bool hasDueDate = false; QDate dueDate = QDate::currentDate(); hasDueDate = date( dueDate, item.data("DueDate") ); QStringList cats = QStringList::split(";", item.data("categories") ); qWarning("Item is completed: %d", item.data("completed").toInt() ); OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), cats, item.data("summary"), item.data("description"), item.data("progress").toUShort(), hasDueDate, dueDate, item.data("uid").toInt() ); bool isOk; int prioInt = QString( item.data("priority") ).toInt( &isOk ); if ( isOk ) to.setPriority( prioInt ); bool hasStartDate = false; QDate startDate = QDate::currentDate(); hasStartDate = date( startDate, item.data("startdate") ); bool hasCompletedDate = false; QDate completedDate = QDate::currentDate(); hasCompletedDate = date( completedDate, item.data("completeddate") ); if ( hasStartDate ) to.setStartDate( startDate ); if ( hasCompletedDate ) to.setCompletedDate( completedDate ); OPimNotifyManager& manager = to.notifiers(); manager.alarmsFromString( item.data("alarms") ); manager.remindersFromString( item.data("reminders") ); OPimState pimState; pimState.setState( QString( item.data("state") ).toInt() ); to.setState( pimState ); QMap<int, QString> recMap; recMap.insert( ORecur::RType , item.data("RType") ); recMap.insert( ORecur::RWeekdays , item.data("RWeekdays") ); recMap.insert( ORecur::RPosition , item.data("RPosition") ); recMap.insert( ORecur::RFreq , item.data("RFreq") ); recMap.insert( ORecur::RHasEndDate, item.data("RHasEndDate") ); recMap.insert( ORecur::EndDate , item.data("EndDate") ); recMap.insert( ORecur::Created , item.data("Created") ); recMap.insert( ORecur::Exceptions , item.data("Exceptions") ); ORecur recur; recur.fromMap( recMap ); to.setRecurrence( recur ); return to; } OTodo OTodoAccessBackendSQL::todo( int uid )const { FindQuery find( uid ); return todo( m_driver->query(&find) ); } /* * update the dict */ void OTodoAccessBackendSQL::fillDict() { /* initialize dict */ /* * UPDATE dict if you change anything!!! * FIXME: Isn't this dict obsolete ? (eilers) */ m_dict.setAutoDelete( TRUE ); m_dict.insert("Categories" , new int(OTodo::Category) ); m_dict.insert("Uid" , new int(OTodo::Uid) ); m_dict.insert("HasDate" , new int(OTodo::HasDate) ); m_dict.insert("Completed" , new int(OTodo::Completed) ); m_dict.insert("Description" , new int(OTodo::Description) ); m_dict.insert("Summary" , new int(OTodo::Summary) ); m_dict.insert("Priority" , new int(OTodo::Priority) ); m_dict.insert("DateDay" , new int(OTodo::DateDay) ); m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); m_dict.insert("DateYear" , new int(OTodo::DateYear) ); m_dict.insert("Progress" , new int(OTodo::Progress) ); m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers) m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); // m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers) // m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers) } /* * need to be const so let's fool the * compiler :( */ void OTodoAccessBackendSQL::update()const { ((OTodoAccessBackendSQL*)this)->m_dirty = false; LoadQuery lo; OSQLResult res = m_driver->query(&lo); if ( res.state() != OSQLResult::Success ) return; ((OTodoAccessBackendSQL*)this)->m_uids = uids( res ); } QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{ OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it; QArray<int> ints(list.count() ); qWarning(" count = %d", list.count() ); int i = 0; for (it = list.begin(); it != list.end(); ++it ) { ints[i] = (*it).data("uid").toInt(); i++; } return ints; } QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const { #warning OTodoAccessBackendSQL::matchRegexp() not implemented !! #if 0 Copied from xml-backend by not adapted to sql (eilers) QArray<int> m_currentQuery( m_events.count() ); uint arraycounter = 0; QMap<int, OTodo>::ConstIterator it; for (it = m_events.begin(); it != m_events.end(); ++it ) { if ( it.data().match( r ) ) m_currentQuery[arraycounter++] = it.data().uid(); } // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; #endif QArray<int> empty; return empty; } QBitArray OTodoAccessBackendSQL::supports()const { return sup(); } QBitArray OTodoAccessBackendSQL::sup() const{ QBitArray ar( OTodo::CompletedDate + 1 ); ar.fill( true ); ar[OTodo::CrossReference] = false; ar[OTodo::State ] = false; ar[OTodo::Reminders] = false; ar[OTodo::Notifiers] = false; ar[OTodo::Maintainer] = false; return ar; } void OTodoAccessBackendSQL::removeAllCompleted(){ #warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !! } + +} diff --git a/libopie2/opiepim/backend/otodoaccesssql.h b/libopie2/opiepim/backend/otodoaccesssql.h index 1c55567..1a6f614 100644 --- a/libopie2/opiepim/backend/otodoaccesssql.h +++ b/libopie2/opiepim/backend/otodoaccesssql.h @@ -1,56 +1,88 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_PIM_ACCESS_SQL_H #define OPIE_PIM_ACCESS_SQL_H #include <qasciidict.h> -#include "otodoaccessbackend.h" +#include <opie2/otodoaccessbackend.h> class OSQLDriver; class OSQLResult; class OSQLResultItem; + +namespace Opie { + class OTodoAccessBackendSQL : public OTodoAccessBackend { public: OTodoAccessBackendSQL( const QString& file ); ~OTodoAccessBackendSQL(); bool load(); bool reload(); bool save(); QArray<int> allRecords()const; QArray<int> queryByExample( const OTodo& t, int settings, const QDateTime& d = QDateTime() ); OTodo find(int uid)const; OTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; void clear(); bool add( const OTodo& t ); bool remove( int uid ); bool replace( const OTodo& t ); QArray<int> overDue(); QArray<int> effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates ); QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat ); QBitArray supports()const; QArray<int> matchRegexp( const QRegExp &r ) const; void removeAllCompleted(); private: void update()const; void fillDict(); inline bool date( QDate& date, const QString& )const; inline OTodo todo( const OSQLResult& )const; inline OTodo todo( OSQLResultItem& )const; inline QArray<int> uids( const OSQLResult& )const; OTodo todo( int uid )const; QBitArray sup() const; QAsciiDict<int> m_dict; OSQLDriver* m_driver; QArray<int> m_uids; bool m_dirty : 1; }; +} #endif diff --git a/libopie2/opiepim/backend/otodoaccessvcal.cpp b/libopie2/opiepim/backend/otodoaccessvcal.cpp index 6415952..e364ee2 100644 --- a/libopie2/opiepim/backend/otodoaccessvcal.cpp +++ b/libopie2/opiepim/backend/otodoaccessvcal.cpp @@ -1,249 +1,282 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <qfile.h> #include <qtopia/private/vobject_p.h> #include <qtopia/timeconversion.h> #include <qtopia/private/qfiledirect_p.h> -#include "otodoaccessvcal.h" +#include <opie2/otodoaccessvcal.h> + +using namespace Opie; namespace { static OTodo eventByVObj( VObject *obj ){ OTodo event; VObject *ob; QCString name; // no uid, attendees, ... and no fun // description if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){ name = vObjectStringZValue( ob ); #if 0 event.setDescription( name ); #else event.setSummary( name ); #endif } // summary if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) { name = vObjectStringZValue( ob ); #if 0 event.setSummary( name ); #else event.setDescription( name ); #endif } // completed if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){ name = vObjectStringZValue( ob ); if( name == "COMPLETED" ){ event.setCompleted( true ); }else{ event.setCompleted( false ); } }else event.setCompleted( false ); // priority if ((ob = isAPropertyOf(obj, VCPriorityProp))) { name = vObjectStringZValue( ob ); bool ok; event.setPriority(name.toInt(&ok) ); } //due date if((ob = isAPropertyOf(obj, VCDueProp)) ){ event.setHasDueDate( true ); name = vObjectStringZValue( ob ); event.setDueDate( TimeConversion::fromISO8601( name).date() ); } // categories if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){ name = vObjectStringZValue( ob ); qWarning("Categories:%s", name.data() ); } event.setUid( 1 ); return event; }; static VObject *vobjByEvent( const OTodo &event ) { VObject *task = newVObject( VCTodoProp ); if( task == 0 ) return 0l; if( event.hasDueDate() ) { QTime time(0, 0, 0); QDateTime date(event.dueDate(), time ); addPropValue( task, VCDueProp, TimeConversion::toISO8601( date ) ); } if( event.isCompleted() ) addPropValue( task, VCStatusProp, "COMPLETED"); QString string = QString::number(event.priority() ); addPropValue( task, VCPriorityProp, string.local8Bit() ); addPropValue( task, VCCategoriesProp, event.idsToString( event.categories() ).local8Bit() ); #if 0 // There seems a misrepresentation between summary in otodoevent // and summary in vcard. // The same with description.. // Description is summary and vice versa.. Argh.. (eilers) addPropValue( task, VCDescriptionProp, event.description().local8Bit() ); addPropValue( task, VCSummaryProp, event.summary().local8Bit() ); #else addPropValue( task, VCDescriptionProp, event.summary().local8Bit() ); addPropValue( task, VCSummaryProp, event.description().local8Bit() ); #endif return task; }; } +namespace Opie { OTodoAccessVCal::OTodoAccessVCal( const QString& path ) : m_dirty(false), m_file( path ) { } OTodoAccessVCal::~OTodoAccessVCal() { } bool OTodoAccessVCal::load() { m_map.clear(); m_dirty = false; VObject* vcal = 0l; vcal = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); if (!vcal ) return false; // Iterate over the list VObjectIterator it; VObject* vobj; initPropIterator(&it, vcal); while( moreIteration( &it ) ) { vobj = ::nextVObject( &it ); QCString name = ::vObjectName( vobj ); if( name == VCTodoProp ){ OTodo to = eventByVObj( vobj ); m_map.insert( to.uid(), to ); } } // Should I do a delete vcal? return true; } bool OTodoAccessVCal::reload() { return load(); } bool OTodoAccessVCal::save() { if (!m_dirty ) return true; QFileDirect file( m_file ); if (!file.open(IO_WriteOnly ) ) return false; VObject *obj; obj = newVObject( VCCalProp ); addPropValue( obj, VCVersionProp, "1.0" ); VObject *vo; for(QMap<int, OTodo>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ vo = vobjByEvent( it.data() ); addVObjectProp(obj, vo ); } writeVObject( file.directHandle(), obj ); cleanVObject( obj ); cleanStrTbl(); m_dirty = false; return true; } void OTodoAccessVCal::clear() { m_map.clear(); m_dirty = true; } bool OTodoAccessVCal::add( const OTodo& to ) { m_map.insert( to.uid(), to ); m_dirty = true; return true; } bool OTodoAccessVCal::remove( int uid ) { m_map.remove( uid ); m_dirty = true; return true; } void OTodoAccessVCal::removeAllCompleted() { for ( QMap<int, OTodo>::Iterator it = m_map.begin(); it != m_map.end(); ++it ) { if ( (*it).isCompleted() ) m_map.remove( it ); } } bool OTodoAccessVCal::replace( const OTodo& to ) { m_map.replace( to.uid(), to ); m_dirty = true; return true; } OTodo OTodoAccessVCal::find(int uid )const { return m_map[uid]; } QArray<int> OTodoAccessVCal::sorted( bool, int, int, int ) { QArray<int> ar(0); return ar; } QArray<int> OTodoAccessVCal::allRecords()const { QArray<int> ar( m_map.count() ); QMap<int, OTodo>::ConstIterator it; int i = 0; for ( it = m_map.begin(); it != m_map.end(); ++it ) { ar[i] = it.key(); i++; } return ar; } QArray<int> OTodoAccessVCal::matchRegexp(const QRegExp& /* r */)const { QArray<int> ar(0); return ar; } QArray<int> OTodoAccessVCal::queryByExample( const OTodo&, int, const QDateTime& ) { QArray<int> ar(0); return ar; } QArray<int> OTodoAccessVCal::effectiveToDos( const QDate& , const QDate& , bool ) { QArray<int> ar(0); return ar; } QArray<int> OTodoAccessVCal::overDue() { QArray<int> ar(0); return ar; } QBitArray OTodoAccessVCal::supports()const { static QBitArray ar = sup(); return ar; } QBitArray OTodoAccessVCal::sup() { QBitArray ar ( OTodo::CompletedDate +1 ); ar.fill( true ); ar[OTodo::CrossReference] = false; ar[OTodo::State ] = false; ar[OTodo::Reminders] = false; ar[OTodo::Notifiers] = false; ar[OTodo::Maintainer] = false; ar[OTodo::Progress] = false; ar[OTodo::Alarms ] = false; ar[OTodo::Recurrence] = false; return ar; } + +} diff --git a/libopie2/opiepim/backend/otodoaccessvcal.h b/libopie2/opiepim/backend/otodoaccessvcal.h index 2b17147..f9323fb 100644 --- a/libopie2/opiepim/backend/otodoaccessvcal.h +++ b/libopie2/opiepim/backend/otodoaccessvcal.h @@ -1,40 +1,72 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_OTODO_ACCESS_VCAL_H #define OPIE_OTODO_ACCESS_VCAL_H -#include "otodoaccessbackend.h" +#include <opie2/otodoaccessbackend.h> + +namespace Opie { class OTodoAccessVCal : public OTodoAccessBackend { public: OTodoAccessVCal(const QString& ); ~OTodoAccessVCal(); bool load(); bool reload(); bool save(); QArray<int> allRecords()const; QArray<int> matchRegexp(const QRegExp &r) const; QArray<int> queryByExample( const OTodo& t, int sort, const QDateTime& d = QDateTime() ); QArray<int> effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates ); QArray<int> overDue(); QArray<int> sorted( bool asc, int sortOrder, int sortFilter, int cat ); OTodo find(int uid)const; void clear(); bool add( const OTodo& ); bool remove( int uid ); bool replace( const OTodo& ); void removeAllCompleted(); virtual QBitArray supports()const; private: static QBitArray sup(); bool m_dirty : 1; QString m_file; QMap<int, OTodo> m_map; }; +} + #endif diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp index 4a5cb33..2d50ecd 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.cpp +++ b/libopie2/opiepim/backend/otodoaccessxml.cpp @@ -1,876 +1,909 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <errno.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <qfile.h> #include <qvector.h> #include <qpe/global.h> #include <qpe/stringutil.h> #include <qpe/timeconversion.h> -#include "oconversion.h" -#include "opimstate.h" -#include "otimezone.h" -#include "opimnotifymanager.h" -#include "orecur.h" -#include "otodoaccessxml.h" +#include <opie2/oconversion.h> +#include <opie2/opimstate.h> +#include <opie2/otimezone.h> +#include <opie2/opimnotifymanager.h> +#include <opie2/orecur.h> +#include <opie2/otodoaccessxml.h> + +using namespace Opie; namespace { time_t rp_end; ORecur* rec; ORecur *recur() { if (!rec ) rec = new ORecur; return rec; } int snd; enum MoreAttributes { FRType = OTodo::CompletedDate + 2, FRWeekdays, FRPosition, FRFreq, FRHasEndDate, FREndDate, FRStart, FREnd }; // FROM TT again char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) { char needleChar; char haystackChar; if (!needle || !haystack || !hLen || !nLen) return 0; const char* hsearch = haystack; if ((needleChar = *needle++) != 0) { nLen--; //(to make up for needle++) do { do { if ((haystackChar = *hsearch++) == 0) return (0); if (hsearch >= haystack + hLen) return (0); } while (haystackChar != needleChar); } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); hsearch--; } return ((char *)hsearch); } } +namespace Opie { OTodoAccessXML::OTodoAccessXML( const QString& appName, const QString& fileName ) : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) { if (!fileName.isEmpty() ) m_file = fileName; else m_file = Global::applicationFileName( "todolist", "todolist.xml" ); } OTodoAccessXML::~OTodoAccessXML() { } bool OTodoAccessXML::load() { rec = 0; m_opened = true; m_changed = false; /* initialize dict */ /* * UPDATE dict if you change anything!!! */ QAsciiDict<int> dict(26); dict.setAutoDelete( TRUE ); dict.insert("Categories" , new int(OTodo::Category) ); dict.insert("Uid" , new int(OTodo::Uid) ); dict.insert("HasDate" , new int(OTodo::HasDate) ); dict.insert("Completed" , new int(OTodo::Completed) ); dict.insert("Description" , new int(OTodo::Description) ); dict.insert("Summary" , new int(OTodo::Summary) ); dict.insert("Priority" , new int(OTodo::Priority) ); dict.insert("DateDay" , new int(OTodo::DateDay) ); dict.insert("DateMonth" , new int(OTodo::DateMonth) ); dict.insert("DateYear" , new int(OTodo::DateYear) ); dict.insert("Progress" , new int(OTodo::Progress) ); dict.insert("CompletedDate", new int(OTodo::CompletedDate) ); dict.insert("StartDate", new int(OTodo::StartDate) ); dict.insert("CrossReference", new int(OTodo::CrossReference) ); dict.insert("State", new int(OTodo::State) ); dict.insert("Alarms", new int(OTodo::Alarms) ); dict.insert("Reminders", new int(OTodo::Reminders) ); dict.insert("Notifiers", new int(OTodo::Notifiers) ); dict.insert("Maintainer", new int(OTodo::Maintainer) ); dict.insert("rtype", new int(FRType) ); dict.insert("rweekdays", new int(FRWeekdays) ); dict.insert("rposition", new int(FRPosition) ); dict.insert("rfreq", new int(FRFreq) ); dict.insert("start", new int(FRStart) ); dict.insert("rhasenddate", new int(FRHasEndDate) ); dict.insert("enddt", new int(FREndDate) ); // here the custom XML parser from TT it's GPL // but we want to push OpiePIM... to TT..... // mmap part from zecke :) int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); struct stat attribut; if ( fd < 0 ) return false; if ( fstat(fd, &attribut ) == -1 ) { ::close( fd ); return false; } void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); if ( map_addr == ( (caddr_t)-1) ) { ::close(fd ); return false; } /* advise the kernel who we want to read it */ ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); /* we do not the file any more */ ::close( fd ); char* dt = (char*)map_addr; int len = attribut.st_size; int i = 0; char *point; const char* collectionString = "<Task "; int strLen = strlen(collectionString); while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { i = point -dt; i+= strLen; qWarning("Found a start at %d %d", i, (point-dt) ); OTodo ev; m_year = m_month = m_day = 0; while ( TRUE ) { while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) ++i; if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) break; // we have another attribute, read it. int j = i; while ( j < len && dt[j] != '=' ) ++j; QCString attr( dt+i, j-i+1); i = ++j; // skip = // find the start of quotes while ( i < len && dt[i] != '"' ) ++i; j = ++i; bool haveUtf = FALSE; bool haveEnt = FALSE; while ( j < len && dt[j] != '"' ) { if ( ((unsigned char)dt[j]) > 0x7f ) haveUtf = TRUE; if ( dt[j] == '&' ) haveEnt = TRUE; ++j; } if ( i == j ) { // empty value i = j + 1; continue; } QCString value( dt+i, j-i+1 ); i = j + 1; QString str = (haveUtf ? QString::fromUtf8( value ) : QString::fromLatin1( value ) ); if ( haveEnt ) str = Qtopia::plainString( str ); /* * add key + value */ todo( &dict, ev, attr, str ); } /* * now add it */ qWarning("End at %d", i ); if (m_events.contains( ev.uid() ) || ev.uid() == 0) { ev.setUid( 1 ); m_changed = true; } if ( ev.hasDueDate() ) { ev.setDueDate( QDate(m_year, m_month, m_day) ); } if ( rec && rec->doesRecur() ) { OTimeZone utc = OTimeZone::utc(); ORecur recu( *rec ); // call copy c'tor recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() ); recu.setStart( ev.dueDate() ); ev.setRecurrence( recu ); } m_events.insert(ev.uid(), ev ); m_year = m_month = m_day = -1; delete rec; rec = 0; } munmap(map_addr, attribut.st_size ); qWarning("counts %d records loaded!", m_events.count() ); return true; } bool OTodoAccessXML::reload() { m_events.clear(); return load(); } bool OTodoAccessXML::save() { // qWarning("saving"); if (!m_opened || !m_changed ) { // qWarning("not saving"); return true; } QString strNewFile = m_file + ".new"; QFile f( strNewFile ); if (!f.open( IO_WriteOnly|IO_Raw ) ) return false; int written; QString out; out = "<!DOCTYPE Tasks>\n<Tasks>\n"; // for all todos QMap<int, OTodo>::Iterator it; for (it = m_events.begin(); it != m_events.end(); ++it ) { out+= "<Task " + toString( (*it) ) + " />\n"; QCString cstr = out.utf8(); written = f.writeBlock( cstr.data(), cstr.length() ); /* less written then we wanted */ if ( written != (int)cstr.length() ) { f.close(); QFile::remove( strNewFile ); return false; } out = QString::null; } out += "</Tasks>"; QCString cstr = out.utf8(); written = f.writeBlock( cstr.data(), cstr.length() ); if ( written != (int)cstr.length() ) { f.close(); QFile::remove( strNewFile ); return false; } /* flush before renaming */ f.close(); if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { // qWarning("error renaming"); QFile::remove( strNewFile ); } m_changed = false; return true; } QArray<int> OTodoAccessXML::allRecords()const { QArray<int> ids( m_events.count() ); QMap<int, OTodo>::ConstIterator it; int i = 0; for ( it = m_events.begin(); it != m_events.end(); ++it ) { ids[i] = it.key(); i++; } return ids; } QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int, const QDateTime& ) { QArray<int> ids(0); return ids; } OTodo OTodoAccessXML::find( int uid )const { OTodo todo; todo.setUid( 0 ); // isEmpty() QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); if ( it != m_events.end() ) todo = it.data(); return todo; } void OTodoAccessXML::clear() { if (m_opened ) m_changed = true; m_events.clear(); } bool OTodoAccessXML::add( const OTodo& todo ) { // qWarning("add"); m_changed = true; m_events.insert( todo.uid(), todo ); return true; } bool OTodoAccessXML::remove( int uid ) { m_changed = true; m_events.remove( uid ); return true; } bool OTodoAccessXML::replace( const OTodo& todo) { m_changed = true; m_events.replace( todo.uid(), todo ); return true; } QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates ) { QArray<int> ids( m_events.count() ); QMap<int, OTodo>::Iterator it; int i = 0; for ( it = m_events.begin(); it != m_events.end(); ++it ) { if ( !it.data().hasDueDate() ) { if ( includeNoDates ) { ids[i] = it.key(); i++; } }else if ( it.data().dueDate() >= start && it.data().dueDate() <= end ) { ids[i] = it.key(); i++; } } ids.resize( i ); return ids; } QArray<int> OTodoAccessXML::overDue() { QArray<int> ids( m_events.count() ); int i = 0; QMap<int, OTodo>::Iterator it; for ( it = m_events.begin(); it != m_events.end(); ++it ) { if ( it.data().isOverdue() ) { ids[i] = it.key(); i++; } } ids.resize( i ); return ids; } /* private */ void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, const QCString& attr, const QString& val) { // qWarning("parse to do from XMLElement" ); int *find=0; find = (*dict)[ attr.data() ]; if (!find ) { // qWarning("Unknown option" + it.key() ); ev.setCustomField( attr, val ); return; } switch( *find ) { case OTodo::Uid: ev.setUid( val.toInt() ); break; case OTodo::Category: ev.setCategories( ev.idsFromString( val ) ); break; case OTodo::HasDate: ev.setHasDueDate( val.toInt() ); break; case OTodo::Completed: ev.setCompleted( val.toInt() ); break; case OTodo::Description: ev.setDescription( val ); break; case OTodo::Summary: ev.setSummary( val ); break; case OTodo::Priority: ev.setPriority( val.toInt() ); break; case OTodo::DateDay: m_day = val.toInt(); break; case OTodo::DateMonth: m_month = val.toInt(); break; case OTodo::DateYear: m_year = val.toInt(); break; case OTodo::Progress: ev.setProgress( val.toInt() ); break; case OTodo::CompletedDate: ev.setCompletedDate( OConversion::dateFromString( val ) ); break; case OTodo::StartDate: ev.setStartDate( OConversion::dateFromString( val ) ); break; case OTodo::State: ev.setState( val.toInt() ); break; case OTodo::Alarms:{ OPimNotifyManager &manager = ev.notifiers(); QStringList als = QStringList::split(";", val ); for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) { QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty qWarning("alarm: %s", alarm.join("___").latin1() ); qWarning("alarm[0]: %s %s", alarm[0].latin1(), OConversion::dateTimeFromString( alarm[0] ).toString().latin1() ); OPimAlarm al( alarm[2].toInt(), OConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() ); manager.add( al ); } } break; case OTodo::Reminders:{ OPimNotifyManager &manager = ev.notifiers(); QStringList rems = QStringList::split(";", val ); for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) { OPimReminder rem( (*it).toInt() ); manager.add( rem ); } } break; case OTodo::CrossReference: { /* * A cross refernce looks like * appname,id;appname,id * we need to split it up */ QStringList refs = QStringList::split(';', val ); QStringList::Iterator strIt; for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { int pos = (*strIt).find(','); if ( pos > -1 ) ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); } break; } /* Recurrence stuff below + post processing later */ case FRType: if ( val == "Daily" ) recur()->setType( ORecur::Daily ); else if ( val == "Weekly" ) recur()->setType( ORecur::Weekly); else if ( val == "MonthlyDay" ) recur()->setType( ORecur::MonthlyDay ); else if ( val == "MonthlyDate" ) recur()->setType( ORecur::MonthlyDate ); else if ( val == "Yearly" ) recur()->setType( ORecur::Yearly ); else recur()->setType( ORecur::NoRepeat ); break; case FRWeekdays: recur()->setDays( val.toInt() ); break; case FRPosition: recur()->setPosition( val.toInt() ); break; case FRFreq: recur()->setFrequency( val.toInt() ); break; case FRHasEndDate: recur()->setHasEndDate( val.toInt() ); break; case FREndDate: { rp_end = (time_t) val.toLong(); break; } default: ev.setCustomField( attr, val ); break; } } // from PalmtopRecord... GPL ### FIXME namespace { QString customToXml(const QMap<QString, QString>& customMap ) { //qWarning(QString("writing custom %1").arg(customMap.count())); QString buf(" "); for ( QMap<QString, QString>::ConstIterator cit = customMap.begin(); cit != customMap.end(); ++cit) { // qWarning(".ITEM."); buf += cit.key(); buf += "=\""; buf += Qtopia::escapeString(cit.data()); buf += "\" "; } return buf; } } QString OTodoAccessXML::toString( const OTodo& ev )const { QString str; str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; str += "Categories=\"" + toString( ev.categories() ) + "\" "; str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; if ( ev.hasDueDate() ) { str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; } // qWarning( "Uid %d", ev.uid() ); str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; // append the extra options /* FIXME Qtopia::Record this is currently not * possible you can set custom fields * but don' iterate over the list * I may do #define private protected * for this case - cough --zecke */ /* QMap<QString, QString> extras = ev.extras(); QMap<QString, QString>::Iterator extIt; for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) str += extIt.key() + "=\"" + extIt.data() + "\" "; */ // cross refernce if ( ev.hasRecurrence() ) { str += ev.recurrence().toString(); } if ( ev.hasStartDate() ) str += "StartDate=\""+ OConversion::dateToString( ev.startDate() ) +"\" "; if ( ev.hasCompletedDate() ) str += "CompletedDate=\""+ OConversion::dateToString( ev.completedDate() ) +"\" "; if ( ev.hasState() ) str += "State=\""+QString::number( ev.state().state() )+"\" "; /* * save reminders and notifiers! * DATE_TIME:DURATION:SOUND:NOT_USED_YET;OTHER_DATE_TIME:OTHER_DURATION:SOUND:.... */ if ( ev.hasNotifiers() ) { OPimNotifyManager manager = ev.notifiers(); OPimNotifyManager::Alarms alarms = manager.alarms(); if (!alarms.isEmpty() ) { QStringList als; OPimNotifyManager::Alarms::Iterator it = alarms.begin(); for ( ; it != alarms.end(); ++it ) { /* only if time is valid */ if ( (*it).dateTime().isValid() ) { als << OConversion::dateTimeToString( (*it).dateTime() ) + ":" + QString::number( (*it).duration() ) + ":" + QString::number( (*it).sound() ) + ":"; } } // now write the list qWarning("als: %s", als.join("____________").latin1() ); str += "Alarms=\""+als.join(";") +"\" "; } /* * now the same for reminders but more easy. We just save the uid of the OEvent. */ OPimNotifyManager::Reminders reminders = manager.reminders(); if (!reminders.isEmpty() ) { OPimNotifyManager::Reminders::Iterator it = reminders.begin(); QStringList records; for ( ; it != reminders.end(); ++it ) { records << QString::number( (*it).recordUid() ); } str += "Reminders=\""+ records.join(";") +"\" "; } } str += customToXml( ev.toExtraMap() ); return str; } QString OTodoAccessXML::toString( const QArray<int>& ints ) const { return Qtopia::Record::idsToString( ints ); } /* internal class for sorting * * Inspired by todoxmlio.cpp from TT */ struct OTodoXMLContainer { OTodo todo; }; namespace { inline QString string( const OTodo& todo) { return todo.summary().isEmpty() ? todo.description().left(20 ) : todo.summary(); } inline int completed( const OTodo& todo1, const OTodo& todo2) { int ret = 0; if ( todo1.isCompleted() ) ret++; if ( todo2.isCompleted() ) ret--; return ret; } inline int priority( const OTodo& t1, const OTodo& t2) { return ( t1.priority() - t2.priority() ); } inline int description( const OTodo& t1, const OTodo& t2) { return QString::compare( string(t1), string(t2) ); } inline int deadline( const OTodo& t1, const OTodo& t2) { int ret = 0; if ( t1.hasDueDate() && t2.hasDueDate() ) ret = t2.dueDate().daysTo( t1.dueDate() ); else if ( t1.hasDueDate() ) ret = -1; else if ( t2.hasDueDate() ) ret = 1; else ret = 0; return ret; } }; /* * Returns: * 0 if item1 == item2 * * non-zero if item1 != item2 * * This function returns int rather than bool so that reimplementations * can return one of three values and use it to sort by: * * 0 if item1 == item2 * * > 0 (positive integer) if item1 > item2 * * < 0 (negative integer) if item1 < item2 * */ class OTodoXMLVector : public QVector<OTodoXMLContainer> { public: OTodoXMLVector(int size, bool asc, int sort) : QVector<OTodoXMLContainer>( size ) { setAutoDelete( true ); m_asc = asc; m_sort = sort; } /* return the summary/description */ QString string( const OTodo& todo) { return todo.summary().isEmpty() ? todo.description().left(20 ) : todo.summary(); } /** * we take the sortorder( switch on it ) * */ int compareItems( Item d1, Item d2 ) { bool seComp, sePrio, seDesc, seDeadline; seComp = sePrio = seDeadline = seDesc = false; int ret =0; OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; /* same item */ if ( con1->todo.uid() == con2->todo.uid() ) return 0; switch ( m_sort ) { /* completed */ case 0: { ret = completed( con1->todo, con2->todo ); seComp = TRUE; break; } /* priority */ case 1: { ret = priority( con1->todo, con2->todo ); sePrio = TRUE; break; } /* description */ case 2: { ret = description( con1->todo, con2->todo ); seDesc = TRUE; break; } /* deadline */ case 3: { ret = deadline( con1->todo, con2->todo ); seDeadline = TRUE; break; } default: ret = 0; break; }; /* * FIXME do better sorting if the first sort criteria * ret equals 0 start with complete and so on... */ /* twist it we're not ascending*/ if (!m_asc) ret = ret * -1; if ( ret ) return ret; // default did not gave difference let's try it other way around /* * General try if already checked if not test * and return * 1.Completed * 2.Priority * 3.Description * 4.DueDate */ if (!seComp ) { if ( (ret = completed( con1->todo, con2->todo ) ) ) { if (!m_asc ) ret *= -1; return ret; } } if (!sePrio ) { if ( (ret = priority( con1->todo, con2->todo ) ) ) { if (!m_asc ) ret *= -1; return ret; } } if (!seDesc ) { if ( (ret = description(con1->todo, con2->todo ) ) ) { if (!m_asc) ret *= -1; return ret; } } if (!seDeadline) { if ( (ret = deadline( con1->todo, con2->todo ) ) ) { if (!m_asc) ret *= -1; return ret; } } return 0; } private: bool m_asc; int m_sort; }; QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, int sortFilter, int cat ) { OTodoXMLVector vector(m_events.count(), asc,sortOrder ); QMap<int, OTodo>::Iterator it; int item = 0; bool bCat = sortFilter & 1 ? true : false; bool bOnly = sortFilter & 2 ? true : false; bool comp = sortFilter & 4 ? true : false; for ( it = m_events.begin(); it != m_events.end(); ++it ) { /* show category */ /* -1 == unfiled */ if ( bCat && cat == -1 ) { if(!(*it).categories().isEmpty() ) continue; }else if ( bCat && cat != 0) if (!(*it).categories().contains( cat ) ) { continue; } /* isOverdue but we should not show overdue - why?*/ /* if ( (*it).isOverdue() && !bOnly ) { qWarning("item is overdue but !bOnly"); continue; } */ if ( !(*it).isOverdue() && bOnly ) { continue; } if ((*it).isCompleted() && comp ) { continue; } OTodoXMLContainer* con = new OTodoXMLContainer(); con->todo = (*it); vector.insert(item, con ); item++; } vector.resize( item ); /* sort it now */ vector.sort(); /* now get the uids */ QArray<int> array( vector.count() ); for (uint i= 0; i < vector.count(); i++ ) { array[i] = ( vector.at(i) )->todo.uid(); } return array; }; void OTodoAccessXML::removeAllCompleted() { QMap<int, OTodo> events = m_events; for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { if ( (*it).isCompleted() ) events.remove( it.key() ); } m_events = events; } QBitArray OTodoAccessXML::supports()const { static QBitArray ar = sup(); return ar; } QBitArray OTodoAccessXML::sup() { QBitArray ar( OTodo::CompletedDate +1 ); ar.fill( true ); ar[OTodo::CrossReference] = false; ar[OTodo::State ] = false; ar[OTodo::Reminders] = false; ar[OTodo::Notifiers] = false; ar[OTodo::Maintainer] = false; return ar; } QArray<int> OTodoAccessXML::matchRegexp( const QRegExp &r ) const { QArray<int> m_currentQuery( m_events.count() ); uint arraycounter = 0; QMap<int, OTodo>::ConstIterator it; for (it = m_events.begin(); it != m_events.end(); ++it ) { if ( it.data().match( r ) ) m_currentQuery[arraycounter++] = it.data().uid(); } // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; } + +} diff --git a/libopie2/opiepim/backend/otodoaccessxml.h b/libopie2/opiepim/backend/otodoaccessxml.h index e4850a1..d634398 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.h +++ b/libopie2/opiepim/backend/otodoaccessxml.h @@ -1,60 +1,89 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_TODO_ACCESS_XML_H #define OPIE_TODO_ACCESS_XML_H #include <qasciidict.h> #include <qmap.h> -#include "otodoaccessbackend.h" +#include <opie2/otodoaccessbackend.h> namespace Opie { class XMLElement; -}; class OTodoAccessXML : public OTodoAccessBackend { public: /** * fileName if Empty we will use the default path */ OTodoAccessXML( const QString& appName, const QString& fileName = QString::null ); ~OTodoAccessXML(); bool load(); bool reload(); bool save(); QArray<int> allRecords()const; QArray<int> matchRegexp(const QRegExp &r) const; QArray<int> queryByExample( const OTodo&, int querysettings, const QDateTime& d = QDateTime() ); OTodo find( int uid )const; void clear(); bool add( const OTodo& ); bool remove( int uid ); void removeAllCompleted(); bool replace( const OTodo& ); /* our functions */ QArray<int> effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates ); QArray<int> overDue(); QArray<int> sorted( bool asc, int sortOrder, int sortFilter, int cat ); QBitArray supports()const; private: static QBitArray sup(); void todo( QAsciiDict<int>*, OTodo&,const QCString&,const QString& ); QString toString( const OTodo& )const; QString toString( const QArray<int>& ints ) const; QMap<int, OTodo> m_events; QString m_file; QString m_app; bool m_opened : 1; bool m_changed : 1; class OTodoAccessXMLPrivate; OTodoAccessXMLPrivate* d; int m_year, m_month, m_day; }; +}; + #endif diff --git a/libopie2/opiepim/core/core.pro b/libopie2/opiepim/core/core.pro new file mode 100644 index 0000000..dae37f1 --- a/dev/null +++ b/libopie2/opiepim/core/core.pro @@ -0,0 +1,21 @@ +HEADERS += core/oconversion.h \ + core/opimcache.h \ + core/opimmaintainer.h \ + core/opimresolver.h \ + core/opimstate.h \ + core/opimxref.h \ + core/opimxrefmanager.h \ + core/opimxrefpartner.h \ + core/orecur.h \ + core/otemplatebase.h \ + core/otimezone.h \ + +SOURCES += core/oconversion.cpp \ + core/opimmaintainer.cpp \ + core/opimresolver.cpp \ + core/opimstate.cpp \ + core/opimxref.cpp \ + core/opimxrefmanager.cpp \ + core/opimxrefpartner.cpp \ + core/orecur.cpp \ + core/otimezone.cpp \ diff --git a/libopie2/opiepim/core/ocontactaccess.cpp b/libopie2/opiepim/core/ocontactaccess.cpp index 2e3ec1f..f67a40c 100644 --- a/libopie2/opiepim/core/ocontactaccess.cpp +++ b/libopie2/opiepim/core/ocontactaccess.cpp @@ -1,168 +1,152 @@ /* - * Class to manage the Contacts. - * - * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * ===================================================================== - * Info: This class could just work with a change in the header-file - * of the Contact class ! Therefore our libopie only compiles - * with our version of libqpe + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/* * ===================================================================== * ToDo: XML-Backend: Automatic reload if something was changed... * * - * ===================================================================== - * Version: $Id$ - * ===================================================================== - * History: - * $Log$ - * Revision 1.8 2003/05/08 13:55:09 tille - * search stuff - * and match, toRichText & toShortText in oevent - * - * Revision 1.7 2002/11/13 14:14:51 eilers - * Added sorted for Contacts.. - * - * Revision 1.6 2002/11/01 15:10:42 eilers - * Added regExp-search in database for all fields in a contact. - * - * Revision 1.5 2002/10/16 10:52:40 eilers - * Added some docu to the interface and now using the cache infrastucture by zecke.. :) - * - * Revision 1.4 2002/10/14 16:21:54 eilers - * Some minor interface updates - * - * Revision 1.3 2002/10/07 17:34:24 eilers - * added OBackendFactory for advanced backend access - * - * Revision 1.2 2002/10/02 16:18:11 eilers - * debugged and seems to work almost perfectly .. - * - * Revision 1.1 2002/09/27 17:11:44 eilers - * Added API for accessing the Contact-Database ! It is compiling, but - * please do not expect that anything is working ! - * I will debug that stuff in the next time .. - * Please read README_COMPILE for compiling ! - * - * */ #include "ocontactaccess.h" #include "obackendfactory.h" #include <qasciidict.h> #include <qdatetime.h> #include <qfile.h> #include <qregexp.h> #include <qlist.h> #include <qcopchannel_qws.h> //#include <qpe/qcopenvelope_qws.h> #include <qpe/global.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> -#include "ocontactaccessbackend_xml.h" +#include <opie2/ocontactaccessbackend_xml.h> +namespace Opie { OContactAccess::OContactAccess ( const QString appname, const QString , OContactAccessBackend* end, bool autosync ): OPimAccessTemplate<OContact>( end ) { /* take care of the backend. If there is no one defined, we * will use the XML-Backend as default (until we have a cute SQL-Backend..). */ if( end == 0 ) { qWarning ("Using BackendFactory !"); end = OBackendFactory<OContactAccessBackend>::Default( "contact", appname ); } // Set backend locally and in template m_backEnd = end; OPimAccessTemplate<OContact>::setBackEnd (end); /* Connect signal of external db change to function */ QCopChannel *dbchannel = new QCopChannel( "QPE/PIM", this ); connect( dbchannel, SIGNAL(received(const QCString &, const QByteArray &)), this, SLOT(copMessage( const QCString &, const QByteArray &)) ); if ( autosync ){ QCopChannel *syncchannel = new QCopChannel( "QPE/Sync", this ); connect( syncchannel, SIGNAL(received(const QCString &, const QByteArray &)), this, SLOT(copMessage( const QCString &, const QByteArray &)) ); } } OContactAccess::~OContactAccess () { /* The user may forget to save the changed database, therefore try to * do it for him.. */ save(); // delete m_backEnd; is done by template.. } bool OContactAccess::save () { /* If the database was changed externally, we could not save the * Data. This will remove added items which is unacceptable ! * Therefore: Reload database and merge the data... */ if ( OPimAccessTemplate<OContact>::wasChangedExternally() ) reload(); bool status = OPimAccessTemplate<OContact>::save(); if ( !status ) return false; /* Now tell everyone that new data is available. */ QCopEnvelope e( "QPE/PIM", "addressbookUpdated()" ); return true; } const uint OContactAccess::querySettings() { return ( m_backEnd->querySettings() ); } bool OContactAccess::hasQuerySettings ( int querySettings ) const { return ( m_backEnd->hasQuerySettings ( querySettings ) ); } ORecordList<OContact> OContactAccess::sorted( bool ascending, int sortOrder, int sortFilter, int cat ) const { QArray<int> matchingContacts = m_backEnd -> sorted( ascending, sortOrder, sortFilter, cat ); return ( ORecordList<OContact>(matchingContacts, this) ); } bool OContactAccess::wasChangedExternally()const { return ( m_backEnd->wasChangedExternally() ); } void OContactAccess::copMessage( const QCString &msg, const QByteArray & ) { if ( msg == "addressbookUpdated()" ){ qWarning ("OContactAccess: Received addressbokUpdated()"); emit signalChanged ( this ); } else if ( msg == "flush()" ) { qWarning ("OContactAccess: Received flush()"); save (); } else if ( msg == "reload()" ) { qWarning ("OContactAccess: Received reload()"); reload (); emit signalChanged ( this ); } } + +} diff --git a/libopie2/opiepim/core/ocontactaccess.h b/libopie2/opiepim/core/ocontactaccess.h index bd6da40..505c87b 100644 --- a/libopie2/opiepim/core/ocontactaccess.h +++ b/libopie2/opiepim/core/ocontactaccess.h @@ -1,193 +1,158 @@ /* - * Class to manage the Contacts. - * - * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) - * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; - * either version 2 of the License, or (at your option) any later - * version. + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/* * ===================================================================== * ToDo: Define enum for query settings * ===================================================================== - * Version: $Id$ - * ===================================================================== - * History: - * $Log$ - * Revision 1.10 2003/12/22 10:19:26 eilers - * Finishing implementation of sql-backend for datebook. But I have to - * port the PIM datebook application to use it, before I could debug the - * whole stuff. - * Thus, PIM-Database backend is finished, but highly experimental. And some - * parts are still generic. For instance, the "queryByExample()" methods are - * not (or not fully) implemented. Todo: custom-entries not stored. - * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular - * expression search in the database, which is not supported by sqlite ! - * Therefore we need either an extended sqlite or a workaround which would - * be very slow and memory consuming.. - * - * Revision 1.9 2003/08/01 12:30:16 eilers - * Merging changes from BRANCH_1_0 to HEAD - * - * Revision 1.8.2.1 2003/06/30 14:34:19 eilers - * Patches from Zecke: - * Fixing and cleaning up extraMap handling - * Adding d_ptr for binary compatibility in the future - * - * Revision 1.8 2003/05/08 13:55:09 tille - * search stuff - * and match, toRichText & toShortText in oevent - * - * Revision 1.7 2003/04/13 18:07:10 zecke - * More API doc - * QString -> const QString& - * QString = 0l -> QString::null - * - * Revision 1.6 2003/01/02 14:27:12 eilers - * Improved query by example: Search by date is possible.. First step - * for a today plugin for birthdays.. - * - * Revision 1.5 2002/11/13 14:14:51 eilers - * Added sorted for Contacts.. - * - * Revision 1.4 2002/11/01 15:10:42 eilers - * Added regExp-search in database for all fields in a contact. - * - * Revision 1.3 2002/10/16 10:52:40 eilers - * Added some docu to the interface and now using the cache infrastucture by zecke.. :) - * - * Revision 1.2 2002/10/14 16:21:54 eilers - * Some minor interface updates - * - * Revision 1.1 2002/09/27 17:11:44 eilers - * Added API for accessing the Contact-Database ! It is compiling, but - * please do not expect that anything is working ! - * I will debug that stuff in the next time .. - * Please read README_COMPILE for compiling ! - * - * ===================================================================== */ #ifndef _OCONTACTACCESS_H #define _OCONTACTACCESS_H #include <qobject.h> #include <qpe/qcopenvelope_qws.h> #include <qvaluelist.h> #include <qfileinfo.h> -#include "ocontact.h" -#include "ocontactaccessbackend.h" -#include "opimaccesstemplate.h" +#include <opie2/ocontact.h> +#include <opie2/ocontactaccessbackend.h> +#include <opie2/opimaccesstemplate.h> +namespace Opie { /** * Class to access the contacts database. * This is just a frontend for the real database handling which is * done by the backend. * This class is used to access the Contacts on a system. This class as any OPIE PIM * class is backend independent. * @author Stefan Eilers, Holger Freyther * @see OPimAccessTemplate */ class OContactAccess: public QObject, public OPimAccessTemplate<OContact> { Q_OBJECT public: /** * Create Database with contacts (addressbook). * @param appname Name of application which wants access to the database * (i.e. "todolist") * @param filename The name of the database file. If not set, the default one * is used. * @param backend Pointer to an alternative Backend. If not set, we will use * the default backend. * @param handlesync If <b>true</b> the database stores the current state * automatically if it receives the signals <i>flush()</i> and <i>reload()</i> * which are used before and after synchronisation. If the application wants * to react itself, it should be disabled by setting it to <b>false</b> * @see OContactAccessBackend */ OContactAccess (const QString appname, const QString filename = 0l, OContactAccessBackend* backend = 0l, bool handlesync = true); ~OContactAccess (); /** Constants for query. * Use this constants to set the query parameters. * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes ! * @see queryByExample() */ enum QuerySettings { WildCards = 0x0001, IgnoreCase = 0x0002, RegExp = 0x0004, ExactMatch = 0x0008, MatchOne = 0x0010, // Only one Entry must match DateDiff = 0x0020, // Find all entries from today until given date DateYear = 0x0040, // The year matches DateMonth = 0x0080, // The month matches DateDay = 0x0100, // The day matches }; /** Return all Contacts in a sorted manner. * @param ascending true: Sorted in acending order. * @param sortOrder Currently not implemented. Just defined to stay compatible to otodoaccess * @param sortFilter Currently not implemented. Just defined to stay compatible to otodoaccess * @param cat Currently not implemented. Just defined to stay compatible to otodoaccess */ List sorted( bool ascending, int sortOrder, int sortFilter, int cat ) const; /** Return all possible settings. * @return All settings provided by the current backend * (i.e.: query_WildCards & query_IgnoreCase) */ const uint querySettings(); /** Check whether settings are correct. * @return <i>true</i> if the given settings are correct and possible. */ bool hasQuerySettings ( int querySettings ) const; /** * if the resource was changed externally. * You should use the signal instead of polling possible changes ! */ bool wasChangedExternally()const; /** Save contacts database. * Save is more a "commit". After calling this function, all changes are public available. * @return true if successful */ bool save(); signals: /* Signal is emitted if the database was changed. Therefore * we may need to reload to stay consistent. * @param which Pointer to the database who created this event. This pointer * is useful if an application has to handle multiple databases at the same time. * @see reload() */ void signalChanged ( const OContactAccess *which ); private: // class OContactAccessPrivate; // OContactAccessPrivate* d; OContactAccessBackend *m_backEnd; bool m_loading:1; private slots: void copMessage( const QCString &msg, const QByteArray &data ); private: class Private; Private *d; }; + +} + #endif diff --git a/libopie2/opiepim/core/oconversion.cpp b/libopie2/opiepim/core/oconversion.cpp index 0d15414..b7eebef 100644 --- a/libopie2/opiepim/core/oconversion.cpp +++ b/libopie2/opiepim/core/oconversion.cpp @@ -1,113 +1,132 @@ -/**********************************************************************
-** Copyright (C) 2003 by Stefan Eilers (eilers.stefan@epost.de)
-**
-** This file may be distributed and/or modified under the terms of the
-** GNU Lesser General Public License version 2 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.
-**
-** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-**
-**********************************************************************/
-
-#include "oconversion.h"
+/*
+ This file is part of the Opie Project
+ Copyright (C) The Main Author <main-author@whereever.org>
+ =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
+ .=l.
+ .>+-=
+ _;:, .> :=|. This program is free software; you can
+.> <`_, > . <= redistribute it and/or modify it under
+:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
+.="- .-=="i, .._ License as published by the Free Software
+ - . .-<_> .<> Foundation; either version 2 of the License,
+ ._= =} : or (at your option) any later version.
+ .%`+i> _;_.
+ .i_,=:_. -<s. This program is distributed in the hope that
+ + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
+ : .. .:, . . . without even the implied warranty of
+ =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
+ _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
+..}^=.= = ; Library General Public License for more
+++= -. .` .: details.
+ : = ...= . :.=-
+ -. .:....=;==+<; You should have received a copy of the GNU
+ -_. . . )=. = Library General Public License along with
+ -- :-=` this library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <opie2/oconversion.h>
#include <qpe/timeconversion.h>
+namespace Opie {
+
QString OConversion::dateToString( const QDate &d )
{
if ( d.isNull() || !d.isValid() )
return QString::null;
// ISO format in year, month, day (YYYYMMDD); e.g. 20021231
QString year = QString::number( d.year() );
QString month = QString::number( d.month() );
month = month.rightJustify( 2, '0' );
QString day = QString::number( d.day() );
day = day.rightJustify( 2, '0' );
QString str = year + month + day;
//qDebug( "\tPimContact dateToStr = %s", str.latin1() );
return str;
}
QDate OConversion::dateFromString( const QString& s )
{
QDate date;
if ( s.isEmpty() )
return date;
// Be backward compatible to old Opie format:
// Try to load old format. If it fails, try new ISO-Format!
date = TimeConversion::fromString ( s );
if ( date.isValid() )
return date;
// Read ISO-Format (YYYYMMDD)
int year = s.mid(0, 4).toInt();
int month = s.mid(4,2).toInt();
int day = s.mid(6,2).toInt();
// do some quick sanity checking -eilers
// but we isValid() again? -zecke
if ( year < 1900 || year > 3000 ) {
qWarning( "PimContact year is not in range");
return date;
}
if ( month < 0 || month > 12 ) {
qWarning( "PimContact month is not in range");
return date;
}
if ( day < 0 || day > 31 ) {
qWarning( "PimContact day is not in range");
return date;
}
date.setYMD( year, month, day );
if ( !date.isValid() ) {
qWarning( "PimContact date is not valid");
return date;
}
return date;
}
QString OConversion::dateTimeToString( const QDateTime& dt ) {
if (!dt.isValid() || dt.isNull() ) return QString::null;
QString year = QString::number( dt.date().year() );
QString month = QString::number( dt.date().month() );
QString day = QString::number( dt.date().day() );
QString hour = QString::number( dt.time().hour() );
QString min = QString::number( dt.time().minute() );
QString sec = QString::number( dt.time().second() );
month = month.rightJustify( 2, '0' );
day = day. rightJustify( 2, '0' );
hour = hour. rightJustify( 2, '0' );
min = min. rightJustify( 2, '0' );
sec = sec. rightJustify( 2, '0' );
QString str = day + month + year + hour + min + sec;
return str;
}
QDateTime OConversion::dateTimeFromString( const QString& str) {
if ( str.isEmpty() ) return QDateTime();
int day = str.mid(0, 2).toInt();
int month = str.mid(2, 2).toInt();
int year = str.mid(4, 4).toInt();
int hour = str.mid(8, 2).toInt();
int min = str.mid(10, 2).toInt();
int sec = str.mid(12, 2).toInt();
QDate date( year, month, day );
QTime time( hour, min, sec );
QDateTime dt( date, time );
return dt;
}
+}
\ No newline at end of file diff --git a/libopie2/opiepim/core/oconversion.h b/libopie2/opiepim/core/oconversion.h index 4c0a497..3c4fdf3 100644 --- a/libopie2/opiepim/core/oconversion.h +++ b/libopie2/opiepim/core/oconversion.h @@ -1,48 +1,62 @@ -/********************************************************************** -** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. -** Copyright (C) 2002-2003 by Stefan Eilers (eilers.stefan@epost.de) -** -** This file may be distributed and/or modified under the terms of the -** GNU General Public License version 2 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -** See http://www.trolltech.com/gpl/ for GPL licensing information. -** -** Contact info@trolltech.com if any conditions of this licensing are -** not clear to you. -**********************************************************************/ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef __oconversion_h__ #define __oconversion_h__ /* #include <time.h> */ /* #include <sys/types.h> */ #include <qdatetime.h> -/* FIXME namespace? -zecke */ +namespace Opie { + class OConversion { public: static QString dateToString( const QDate &d ); static QDate dateFromString( const QString &datestr ); /** * simple function to store DateTime as string and read from string * no timezone changing is done * DDMMYYYYHHMMSS is the simple format */ static QString dateTimeToString( const QDateTime& ); static QDateTime dateTimeFromString( const QString& ); private: class Private; Private* d; }; +} + #endif // __oconversion_h__ diff --git a/libopie2/opiepim/core/odatebookaccess.cpp b/libopie2/opiepim/core/odatebookaccess.cpp index d95fed6..8c527f6 100644 --- a/libopie2/opiepim/core/odatebookaccess.cpp +++ b/libopie2/opiepim/core/odatebookaccess.cpp @@ -1,81 +1,112 @@ -#include "obackendfactory.h" -#include "odatebookaccess.h" +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <opie2/obackendfactory.h> +#include <opie2/odatebookaccess.h> +namespace Opie { /** * Simple constructor * It takes a ODateBookAccessBackend as parent. If it is 0 the default implementation * will be used! * @param back The backend to be used or 0 for the default backend * @param ac What kind of access is intended */ ODateBookAccess::ODateBookAccess( ODateBookAccessBackend* back, enum Access ac ) : OPimAccessTemplate<OEvent>( back ) { if (!back ) back = OBackendFactory<ODateBookAccessBackend>::Default("datebook", QString::null ); m_backEnd = back; setBackEnd( m_backEnd ); } ODateBookAccess::~ODateBookAccess() { } /** * @return all events available */ ODateBookAccess::List ODateBookAccess::rawEvents()const { QArray<int> ints = m_backEnd->rawEvents(); List lis( ints, this ); return lis; } /** * @return all repeating events */ ODateBookAccess::List ODateBookAccess::rawRepeats()const { QArray<int> ints = m_backEnd->rawRepeats(); List lis( ints, this ); return lis; } /** * @return all non repeating events */ ODateBookAccess::List ODateBookAccess::nonRepeats()const { QArray<int> ints = m_backEnd->nonRepeats(); List lis( ints, this ); return lis; } /** * @return dates in the time span between from and to * @param from Include all events from... * @param to Include all events to... */ OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDate& from, const QDate& to ) const { return m_backEnd->effectiveEvents( from, to ); } /** * @return all events at a given datetime */ OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDateTime& start ) const { return m_backEnd->effectiveEvents( start ); } /** * @return non repeating dates in the time span between from and to * @param from Include all events from... * @param to Include all events to... */ OEffectiveEvent::ValueList ODateBookAccess::effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) const { return m_backEnd->effectiveNonRepeatingEvents( from, to ); } /** * @return all non repeating events at a given datetime */ OEffectiveEvent::ValueList ODateBookAccess::effectiveNonRepeatingEvents( const QDateTime& start ) const { return m_backEnd->effectiveNonRepeatingEvents( start ); } + +} diff --git a/libopie2/opiepim/core/odatebookaccess.h b/libopie2/opiepim/core/odatebookaccess.h index 62196da..38dc754 100644 --- a/libopie2/opiepim/core/odatebookaccess.h +++ b/libopie2/opiepim/core/odatebookaccess.h @@ -1,44 +1,75 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_DATE_BOOK_ACCESS_H #define OPIE_DATE_BOOK_ACCESS_H #include "odatebookaccessbackend.h" #include "opimaccesstemplate.h" -#include "oevent.h" +#include <opie2/oevent.h> +namespace Opie { /** * This is the object orientated datebook database. It'll use OBackendFactory * to query for a backend. * All access to the datebook should be done via this class. * Make sure to load and save the datebook this is not part of * destructing and creating the object * * @author Holger Freyther, Stefan Eilers */ class ODateBookAccess : public OPimAccessTemplate<OEvent> { public: ODateBookAccess( ODateBookAccessBackend* = 0l, enum Access acc = Random ); ~ODateBookAccess(); /* return all events */ List rawEvents()const; /* return repeating events */ List rawRepeats()const; /* return non repeating events */ List nonRepeats()const; /* return non repeating events (from,to) */ OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ) const; OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ) const; OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) const; OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDateTime& start ) const; private: ODateBookAccessBackend* m_backEnd; class Private; Private* d; }; +} + #endif diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h index ecbeb68..5826cbc 100644 --- a/libopie2/opiepim/core/opimaccesstemplate.h +++ b/libopie2/opiepim/core/opimaccesstemplate.h @@ -1,302 +1,335 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_PIM_ACCESS_TEMPLATE_H #define OPIE_PIM_ACCESS_TEMPLATE_H #include <qarray.h> -#include <opie/opimrecord.h> -#include <opie/opimaccessbackend.h> -#include <opie/orecordlist.h> +#include <opie2/opimrecord.h> +#include <opie2/opimaccessbackend.h> +#include <opie2/orecordlist.h> + +#include <opie2/opimcache.h> +#include <opie2/otemplatebase.h> -#include "opimcache.h" -#include "otemplatebase.h" +namespace Opie { class OPimAccessTemplatePrivate; /** * Thats the frontend to our OPIE PIM * Library. Either you want to use it's * interface or you want to implement * your own Access lib * Just create a OPimRecord and inherit from * the plugins */ template <class T = OPimRecord > class OPimAccessTemplate : public OTemplateBase<T> { public: enum Access { Random = 0, SortedAccess }; typedef ORecordList<T> List; typedef OPimAccessBackend<T> BackEnd; typedef OPimCache<T> Cache; /** * c'tor BackEnd * enum Access a small hint on how to handle the backend */ OPimAccessTemplate( BackEnd* end); virtual ~OPimAccessTemplate(); /** * load from the backend */ bool load(); /** Reload database. * You should execute this function if the external database * was changed. * This function will load the external database and afterwards * rejoin the local changes. Therefore the local database will be set consistent. */ virtual bool reload(); /** Save contacts database. * Save is more a "commit". After calling this function, all changes are public available. * @return true if successful */ bool save(); /** * if the resource was changed externally * You should use the signal handling instead of polling possible changes ! * zecke: Do you implement a signal for otodoaccess ? */ bool wasChangedExternally()const; /** * return a List of records * you can iterate over them */ virtual List allRecords()const; /** * return a List of records * that match the regex */ virtual List matchRegexp( const QRegExp &r ) const; /** * queryByExample. * @see otodoaccess, ocontactaccess */ virtual List queryByExample( const T& t, int querySettings, const QDateTime& d = QDateTime() ); /** * find the OPimRecord uid */ virtual T find( int uid )const; /** * read ahead cache find method ;) */ virtual T find( int uid, const QArray<int>&, uint current, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const; /* invalidate cache here */ /** * clears the backend and invalidates the backend */ void clear() ; /** * add T to the backend * @param t The item to add. * @return <i>true</i> if added successfully. */ virtual bool add( const T& t ) ; bool add( const OPimRecord& ); /* only the uid matters */ /** * remove T from the backend * @param t The item to remove * @return <i>true</i> if successful. */ virtual bool remove( const T& t ); /** * remove the OPimRecord with uid * @param uid The ID of the item to remove * @return <i>true</i> if successful. */ bool remove( int uid ); bool remove( const OPimRecord& ); /** * replace T from backend * @param t The item to replace * @return <i>true</i> if successful. */ virtual bool replace( const T& t) ; void setReadAhead( uint count ); /** * @internal */ void cache( const T& )const; void setSaneCacheSize( int ); QArray<int> records()const; protected: /** * invalidate the cache */ void invalidateCache(); void setBackEnd( BackEnd* end ); /** * returns the backend */ BackEnd* backEnd(); BackEnd* m_backEnd; Cache m_cache; private: OPimAccessTemplatePrivate *d; }; template <class T> OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end ) : OTemplateBase<T>(), m_backEnd( end ) { if (end ) end->setFrontend( this ); } template <class T> OPimAccessTemplate<T>::~OPimAccessTemplate() { qWarning("~OPimAccessTemplate<T>"); delete m_backEnd; } template <class T> bool OPimAccessTemplate<T>::load() { invalidateCache(); return m_backEnd->load(); } template <class T> bool OPimAccessTemplate<T>::reload() { invalidateCache(); // zecke: I think this should be added (se) return m_backEnd->reload(); } template <class T> bool OPimAccessTemplate<T>::save() { return m_backEnd->save(); } template <class T> typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const { QArray<int> ints = m_backEnd->allRecords(); List lis(ints, this ); return lis; } template <class T> typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::matchRegexp( const QRegExp &r )const { QArray<int> ints = m_backEnd->matchRegexp( r ); List lis(ints, this ); return lis; } template <class T> QArray<int> OPimAccessTemplate<T>::records()const { return m_backEnd->allRecords(); } template <class T> typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::queryByExample( const T& t, int settings, const QDateTime& d ) { QArray<int> ints = m_backEnd->queryByExample( t, settings, d ); List lis(ints, this ); return lis; } template <class T> T OPimAccessTemplate<T>::find( int uid ) const{ T t = m_backEnd->find( uid ); cache( t ); return t; } template <class T> T OPimAccessTemplate<T>::find( int uid, const QArray<int>& ar, uint current, typename OTemplateBase<T>::CacheDirection dir )const { /* * better do T.isEmpty() * after a find this way we would * avoid two finds in QCache... */ // qWarning("find it now %d", uid ); if (m_cache.contains( uid ) ) { return m_cache.find( uid ); } T t = m_backEnd->find( uid, ar, current, dir ); cache( t ); return t; } template <class T> void OPimAccessTemplate<T>::clear() { invalidateCache(); m_backEnd->clear(); } template <class T> bool OPimAccessTemplate<T>::add( const T& t ) { cache( t ); return m_backEnd->add( t ); } template <class T> bool OPimAccessTemplate<T>::add( const OPimRecord& rec) { /* same type */ if ( rec.rtti() == T::rtti() ) { const T &t = static_cast<const T&>(rec); return add(t); } return false; } template <class T> bool OPimAccessTemplate<T>::remove( const T& t ) { return remove( t.uid() ); } template <class T> bool OPimAccessTemplate<T>::remove( int uid ) { m_cache.remove( uid ); return m_backEnd->remove( uid ); } template <class T> bool OPimAccessTemplate<T>::remove( const OPimRecord& rec) { return remove( rec.uid() ); } template <class T> bool OPimAccessTemplate<T>::replace( const T& t ) { m_cache.replace( t ); return m_backEnd->replace( t ); } template <class T> void OPimAccessTemplate<T>::invalidateCache() { m_cache.invalidate(); } template <class T> typename OPimAccessTemplate<T>::BackEnd* OPimAccessTemplate<T>::backEnd() { return m_backEnd; } template <class T> bool OPimAccessTemplate<T>::wasChangedExternally()const { return false; } template <class T> void OPimAccessTemplate<T>::setBackEnd( BackEnd* end ) { m_backEnd = end; if (m_backEnd ) m_backEnd->setFrontend( this ); } template <class T> void OPimAccessTemplate<T>::cache( const T& t ) const{ /* hacky we need to work around the const*/ ((OPimAccessTemplate<T>*)this)->m_cache.add( t ); } template <class T> void OPimAccessTemplate<T>::setSaneCacheSize( int size ) { m_cache.setSize( size ); } template <class T> void OPimAccessTemplate<T>::setReadAhead( uint count ) { m_backEnd->setReadAhead( count ); } + +} + #endif diff --git a/libopie2/opiepim/core/opimcache.h b/libopie2/opiepim/core/opimcache.h index 7f7cff5..e70a910 100644 --- a/libopie2/opiepim/core/opimcache.h +++ b/libopie2/opiepim/core/opimcache.h @@ -1,131 +1,162 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_PIM_CACHE_H #define OPIE_PIM_CACHE_H #include <qintcache.h> -#include "opimrecord.h" +#include <opie2/opimrecord.h> +namespace Opie { class OPimCacheItemPrivate; template <class T = OPimRecord> class OPimCacheItem { public: OPimCacheItem( const T& t = T() ); OPimCacheItem( const OPimCacheItem& ); ~OPimCacheItem(); OPimCacheItem &operator=( const OPimCacheItem& ); T record()const; void setRecord( const T& ); private: T m_t; OPimCacheItemPrivate *d; }; class OPimCachePrivate; /** * OPimCache for caching the items * We support adding, removing * and finding */ template <class T = OPimRecord> class OPimCache { public: typedef OPimCacheItem<T> Item; OPimCache(); OPimCache( const OPimCache& ); ~OPimCache(); OPimCache &operator=( const OPimCache& ); bool contains(int uid)const; void invalidate(); void setSize( int size ); T find(int uid )const; void add( const T& ); void remove( int uid ); void replace( const T& ); private: QIntCache<Item> m_cache; OPimCachePrivate* d; }; // Implementation template <class T> OPimCacheItem<T>::OPimCacheItem( const T& t ) : m_t(t) { } template <class T> OPimCacheItem<T>::~OPimCacheItem() { } template <class T> T OPimCacheItem<T>::record()const { return m_t; } template <class T> void OPimCacheItem<T>::setRecord( const T& t ) { m_t = t; } // Cache template <class T> OPimCache<T>::OPimCache() : m_cache(100, 53 ) { m_cache.setAutoDelete( TRUE ); } template <class T> OPimCache<T>::~OPimCache() { } template <class T> bool OPimCache<T>::contains(int uid )const { Item* it = m_cache.find( uid, FALSE ); if (!it) return false; return true; } template <class T> void OPimCache<T>::invalidate() { m_cache.clear(); } template <class T> void OPimCache<T>::setSize( int size ) { m_cache.setMaxCost( size ); } template <class T> T OPimCache<T>::find(int uid )const { Item *it = m_cache.find( uid ); if (it) return it->record(); return T(); } template <class T> void OPimCache<T>::add( const T& t ) { Item* it = 0l; it = m_cache.find(t.uid(), FALSE ); if (it ) it->setRecord( t ); it = new Item( t ); if (!m_cache.insert( t.uid(), it ) ) delete it; } template <class T> void OPimCache<T>::remove( int uid ) { m_cache.remove( uid ); } template <class T> void OPimCache<T>::replace( const T& t) { Item *it = m_cache.find( t.uid() ); if ( it ) { it->setRecord( t ); } } +} + #endif diff --git a/libopie2/opiepim/core/opimmaintainer.cpp b/libopie2/opiepim/core/opimmaintainer.cpp index 92cb25a..b2eff12 100644 --- a/libopie2/opiepim/core/opimmaintainer.cpp +++ b/libopie2/opiepim/core/opimmaintainer.cpp @@ -1,37 +1,69 @@ -#include "opimmaintainer.h" +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <opie2/opimmaintainer.h> + +namespace Opie { OPimMaintainer::OPimMaintainer( int mode, int uid ) : m_mode(mode), m_uid(uid ) {} OPimMaintainer::~OPimMaintainer() { } OPimMaintainer::OPimMaintainer( const OPimMaintainer& main ) { *this = main; } OPimMaintainer &OPimMaintainer::operator=( const OPimMaintainer& main ) { m_mode = main.m_mode; m_uid = main.m_uid; return *this; } bool OPimMaintainer::operator==( const OPimMaintainer& main ) { if (m_mode != main.m_mode ) return false; if (m_uid != main.m_uid ) return false; return true; } bool OPimMaintainer::operator!=( const OPimMaintainer& main ) { return !(*this == main ); } int OPimMaintainer::mode()const { return m_mode; } int OPimMaintainer::uid()const { return m_uid; } void OPimMaintainer::setMode( int mo) { m_mode = mo; } void OPimMaintainer::setUid( int uid ) { m_uid = uid; } + +} diff --git a/libopie2/opiepim/core/opimmaintainer.h b/libopie2/opiepim/core/opimmaintainer.h index 793d066..46bc9d2 100644 --- a/libopie2/opiepim/core/opimmaintainer.h +++ b/libopie2/opiepim/core/opimmaintainer.h @@ -1,40 +1,71 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_PIM_MAINTAINER_H #define OPIE_PIM_MAINTAINER_H #include <qstring.h> +namespace Opie { /** * Who maintains what? */ class OPimMaintainer { public: enum Mode { Undefined = -1, Nothing = 0, Responsible, DoneBy, Coordinating, }; OPimMaintainer( int mode = Undefined, int uid = 0); OPimMaintainer( const OPimMaintainer& ); ~OPimMaintainer(); OPimMaintainer &operator=( const OPimMaintainer& ); bool operator==( const OPimMaintainer& ); bool operator!=( const OPimMaintainer& ); int mode()const; int uid()const; void setMode( int mode ); void setUid( int uid ); private: int m_mode; int m_uid; class Private; Private *d; }; +} + #endif diff --git a/libopie2/opiepim/core/opimnotify.cpp b/libopie2/opiepim/core/opimnotify.cpp index af5514b..c61f9da 100644 --- a/libopie2/opiepim/core/opimnotify.cpp +++ b/libopie2/opiepim/core/opimnotify.cpp @@ -1,227 +1,258 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <qshared.h> -#include "opimnotify.h" +#include <opie2/opimnotify.h> + +namespace Opie { struct OPimNotify::Data : public QShared { Data() : QShared(),dur(-1),parent(0) { } QDateTime start; int dur; QString application; int parent; }; OPimNotify::OPimNotify( const QDateTime& start, int duration, int parent ) { data = new Data; data->start = start; data->dur = duration; data->parent = parent; } OPimNotify::OPimNotify( const OPimNotify& noti) : data( noti.data ) { data->ref(); } OPimNotify::~OPimNotify() { if ( data->deref() ) { delete data; data = 0l; } } OPimNotify &OPimNotify::operator=( const OPimNotify& noti) { noti.data->ref(); deref(); data = noti.data; return *this; } bool OPimNotify::operator==( const OPimNotify& noti ) { if ( data == noti.data ) return true; if ( data->dur != noti.data->dur ) return false; if ( data->parent != noti.data->parent ) return false; if ( data->application != noti.data->application ) return false; if ( data->start != noti.data->start ) return false; return true; } QDateTime OPimNotify::dateTime()const { return data->start; } QString OPimNotify::service()const { return data->application; } int OPimNotify::parent()const { return data->parent; } int OPimNotify::duration()const { return data->dur; } QDateTime OPimNotify::endTime()const { return QDateTime( data->start.date(), data->start.time().addSecs( data->dur) ); } void OPimNotify::setDateTime( const QDateTime& time ) { copyIntern(); data->start = time; } void OPimNotify::setDuration( int dur ) { copyIntern(); data->dur = dur; } void OPimNotify::setParent( int uid ) { copyIntern(); data->parent = uid; } void OPimNotify::setService( const QString& str ) { copyIntern(); data->application = str; } void OPimNotify::copyIntern() { if ( data->count != 1 ) { data->deref(); Data* dat = new Data; dat->start = data->start; dat->dur = data->dur; dat->application = data->application; dat->parent = data->parent; data = dat; } } void OPimNotify::deref() { if ( data->deref() ) { delete data; data = 0; } } /***********************************************************/ struct OPimAlarm::Data : public QShared { Data() : QShared() { sound = 1; } int sound; QString file; }; OPimAlarm::OPimAlarm( int sound, const QDateTime& start, int duration, int parent ) : OPimNotify( start, duration, parent ) { data = new Data; data->sound = sound; } OPimAlarm::OPimAlarm( const OPimAlarm& al) : OPimNotify(al), data( al.data ) { data->ref(); } OPimAlarm::~OPimAlarm() { if ( data->deref() ) { delete data; data = 0l; } } OPimAlarm &OPimAlarm::operator=( const OPimAlarm& al) { OPimNotify::operator=( al ); deref(); al.data->ref(); data = al.data; return *this; } bool OPimAlarm::operator==( const OPimAlarm& al) { if ( data->sound != al.data->sound ) return false; else if ( data->sound == Custom && data->file != al.data->file ) return false; return OPimNotify::operator==( al ); } QString OPimAlarm::type()const { return QString::fromLatin1("OPimAlarm"); } int OPimAlarm::sound()const { return data->sound; } QString OPimAlarm::file()const { return data->file; } void OPimAlarm::setSound( int snd) { copyIntern(); data->sound = snd; } void OPimAlarm::setFile( const QString& sound ) { copyIntern(); data->file = sound; } void OPimAlarm::deref() { if ( data->deref() ) { delete data; data = 0l; } } void OPimAlarm::copyIntern() { if ( data->count != 1 ) { data->deref(); Data *newDat = new Data; newDat->sound = data->sound; newDat->file = data->file; data = newDat; } } /************************/ struct OPimReminder::Data : public QShared { Data() : QShared(), record( 0) { } int record; }; OPimReminder::OPimReminder( int uid, const QDateTime& start, int dur, int parent ) : OPimNotify( start, dur, parent ) { data = new Data; data->record = uid; } OPimReminder::OPimReminder( const OPimReminder& rem ) : OPimNotify( rem ), data( rem.data ) { data->ref(); } OPimReminder& OPimReminder::operator=( const OPimReminder& rem) { OPimNotify::operator=(rem ); deref(); rem.data->ref(); data = rem.data; return *this; } bool OPimReminder::operator==( const OPimReminder& rem) { if ( data->record != rem.data->record ) return false; return OPimNotify::operator==( rem ); } QString OPimReminder::type()const { return QString::fromLatin1("OPimReminder"); } int OPimReminder::recordUid()const { return data->record; } void OPimReminder::setRecordUid( int uid ) { copyIntern(); data->record = uid; } void OPimReminder::deref() { if ( data->deref() ) { delete data; data = 0l; } } void OPimReminder::copyIntern() { if ( data->count != 1 ) { Data* da = new Data; da->record = data->record; data = da; } } +} diff --git a/libopie2/opiepim/core/opimnotify.h b/libopie2/opiepim/core/opimnotify.h index 58417db..fed3970 100644 --- a/libopie2/opiepim/core/opimnotify.h +++ b/libopie2/opiepim/core/opimnotify.h @@ -1,144 +1,176 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_PIM_NOTIFY_H #define OPIE_PIM_NOTIFY_H #include <qdatetime.h> #include <qvaluelist.h> + +namespace Opie { /** * This is the base class of Notifiers. Possible * notifiers would be Alarms, Reminders * What they share is that they have * A DateTime, Type, Duration * This is what this base class takes care of * on top of that it's shared */ /* * TALK to eilers: have a class OPimDuration which sets the Duration * given on the Due/Start Date? -zecke * discuss: do we need a uid for the notify? -zecke */ class OPimNotify { public: typedef QValueList<OPimNotify> ValueList; OPimNotify( const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 ); OPimNotify( const OPimNotify& ); virtual ~OPimNotify(); OPimNotify &operator=(const OPimNotify& ); bool operator==( const OPimNotify& ); virtual QString type()const = 0; /** start date */ QDateTime dateTime()const; QString service()const; /** * RETURN the parent uid */ int parent()const; /** * in Seconds */ int duration()const; /** * Start Time + Duration */ QDateTime endTime()const; void setDateTime( const QDateTime& ); void setDuration( int dur ); void setParent(int uid ); void setService( const QString& ); private: inline void copyIntern(); void deref(); struct Data; Data* data; /* d-pointer */ class NotifyPrivate; NotifyPrivate* d; }; /** * An alarm is a sound/mail/buzzer played/send * at a given time to inform about * an Event */ class OPimAlarm : public OPimNotify { public: enum Sound{Loud=1, Silent=0, Custom=2 }; OPimAlarm( int sound = Silent, const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 ); OPimAlarm( const OPimAlarm& ); ~OPimAlarm(); OPimAlarm &operator=( const OPimAlarm& ); bool operator==( const OPimAlarm& ); QString type()const; int sound()const; QString file()const; void setSound( int ); /* only when sound is custom... */ void setFile( const QString& sound ); private: void deref(); void copyIntern(); struct Data; Data * data; class Private; Private* d; }; /** * A Reminder will be put into the * datebook * Note that the returned dateTime() may be not valid. * In these cases one must resolve the uid and get the OEvent */ class OPimReminder : public OPimNotify { public: /** * c'tor of a reminder * @param uid The uid of the Record inside the Datebook * @param start the StartDate invalid for all day... * @param duration The duration of the event ( -1 for all day ) * @param parent The 'parent' record of this reminder */ OPimReminder( int uid = 0, const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 ); OPimReminder( const OPimReminder& ); OPimReminder &operator=(const OPimReminder& ); QString type()const; bool operator==( const OPimReminder& ); /** * the uid of the alarm * inside the 'datebook' application */ int recordUid()const; void setRecordUid( int uid ); private: void deref(); void copyIntern(); struct Data; Data* data; class Private; Private *d; }; +} + #endif diff --git a/libopie2/opiepim/core/opimnotifymanager.cpp b/libopie2/opiepim/core/opimnotifymanager.cpp index d6f0ead..1771fad 100644 --- a/libopie2/opiepim/core/opimnotifymanager.cpp +++ b/libopie2/opiepim/core/opimnotifymanager.cpp @@ -1,162 +1,193 @@ -#include "opimnotifymanager.h" +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <opie2/opimnotifymanager.h> -#include "oconversion.h" +#include <opie2/oconversion.h> #include <qstringlist.h> +namespace Opie { + OPimNotifyManager::OPimNotifyManager( const Reminders& rem, const Alarms& al) : m_rem( rem ), m_al( al ) {} OPimNotifyManager::~OPimNotifyManager() { } /* use static_cast and type instead of dynamic... */ void OPimNotifyManager::add( const OPimNotify& noti) { if ( noti.type() == QString::fromLatin1("OPimReminder") ) { const OPimReminder& rem = static_cast<const OPimReminder&>(noti); m_rem.append( rem ); }else if ( noti.type() == QString::fromLatin1("OPimAlarm") ) { const OPimAlarm& al = static_cast<const OPimAlarm&>(noti); m_al.append( al ); } } void OPimNotifyManager::remove( const OPimNotify& noti) { if ( noti.type() == QString::fromLatin1("OPimReminder") ) { const OPimReminder& rem = static_cast<const OPimReminder&>(noti); m_rem.remove( rem ); }else if ( noti.type() == QString::fromLatin1("OPimAlarm") ) { const OPimAlarm& al = static_cast<const OPimAlarm&>(noti); m_al.remove( al ); } } void OPimNotifyManager::replace( const OPimNotify& noti) { if ( noti.type() == QString::fromLatin1("OPimReminder") ) { const OPimReminder& rem = static_cast<const OPimReminder&>(noti); m_rem.remove( rem ); m_rem.append( rem ); }else if ( noti.type() == QString::fromLatin1("OPimAlarm") ) { const OPimAlarm& al = static_cast<const OPimAlarm&>(noti); m_al.remove( al ); m_al.append( al ); } } OPimNotifyManager::Reminders OPimNotifyManager::reminders()const { return m_rem; } OPimNotifyManager::Alarms OPimNotifyManager::alarms()const { return m_al; } OPimAlarm OPimNotifyManager::alarmAtDateTime( const QDateTime& when, bool& found ) const { Alarms::ConstIterator it; found = true; for ( it = m_al.begin(); it != m_al.end(); ++it ){ if ( (*it).dateTime() == when ) return (*it); } // Fall through if nothing could be found found = false; OPimAlarm empty; return empty; } void OPimNotifyManager::setAlarms( const Alarms& al) { m_al = al; } void OPimNotifyManager::setReminders( const Reminders& rem) { m_rem = rem; } /* FIXME!!! */ /** * The idea is to check if the provider for our service * is online * if it is we will use QCOP * if not the Factory to get the backend... * Qtopia1.6 services would be kewl to have here.... */ void OPimNotifyManager::registerNotify( const OPimNotify& ) { } /* FIXME!!! */ /** * same as above... * Also implement Url model * have a MainWindow.... */ void OPimNotifyManager::deregister( const OPimNotify& ) { } bool OPimNotifyManager::isEmpty()const { qWarning("is Empty called on OPimNotifyManager %d %d", m_rem.count(), m_al.count() ); if ( m_rem.isEmpty() && m_al.isEmpty() ) return true; else return false; } // Taken from otodoaccessxml.. QString OPimNotifyManager::alarmsToString() const { QString str; OPimNotifyManager::Alarms alarms = m_al; if ( !alarms.isEmpty() ) { QStringList als; OPimNotifyManager::Alarms::Iterator it = alarms.begin(); for ( ; it != alarms.end(); ++it ) { /* only if time is valid */ if ( (*it).dateTime().isValid() ) { als << OConversion::dateTimeToString( (*it).dateTime() ) + ":" + QString::number( (*it).duration() ) + ":" + QString::number( (*it).sound() ) + ":"; } } // now write the list qWarning("als: %s", als.join("____________").latin1() ); str = als.join(";"); } return str; } QString OPimNotifyManager::remindersToString() const { QString str; OPimNotifyManager::Reminders reminders = m_rem; if (!reminders.isEmpty() ) { OPimNotifyManager::Reminders::Iterator it = reminders.begin(); QStringList records; for ( ; it != reminders.end(); ++it ) { records << QString::number( (*it).recordUid() ); } str = records.join(";"); } return str; } void OPimNotifyManager::alarmsFromString( const QString& str ) { QStringList als = QStringList::split(";", str ); for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) { QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty qWarning("alarm: %s", alarm.join("___").latin1() ); qWarning("alarm[0]: %s %s", alarm[0].latin1(), OConversion::dateTimeFromString( alarm[0] ).toString().latin1() ); OPimAlarm al( alarm[2].toInt(), OConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() ); add( al ); } } void OPimNotifyManager::remindersFromString( const QString& str ) { QStringList rems = QStringList::split(";", str ); for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) { OPimReminder rem( (*it).toInt() ); add( rem ); } } +} diff --git a/libopie2/opiepim/core/opimnotifymanager.h b/libopie2/opiepim/core/opimnotifymanager.h index f3c22f9..0272e5d 100644 --- a/libopie2/opiepim/core/opimnotifymanager.h +++ b/libopie2/opiepim/core/opimnotifymanager.h @@ -1,91 +1,122 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_PIM_NOTIFY_MANAGER_H #define OPIE_PIM_NOTIFY_MANAGER_H #include <qvaluelist.h> -#include <opie/opimnotify.h> +#include <opie2/opimnotify.h> +namespace Opie { /** * The notify manager keeps track of the Notifiers.... */ class OPimNotifyManager { public: typedef QValueList<OPimReminder> Reminders; typedef QValueList<OPimAlarm> Alarms; OPimNotifyManager( const Reminders& rems = Reminders(), const Alarms& alarms = Alarms() ); ~OPimNotifyManager(); /* we will cast it for you ;) */ void add( const OPimNotify& ); void remove( const OPimNotify& ); /* replaces all with this one! */ void replace( const OPimNotify& ); Reminders reminders()const; /** * Return */ Alarms alarms()const; /** * Return alarm at DateTime "when". If more than one is registered at this * DateTime, the first one is returned. * If none was found, an empty Alarm is returned. * @param when The date and time of the returned alarm * @param found Returns true if anything was found. * @return Returns the found alarm at given DateTime. It is empty if found is false * (nothing could be found at given date and time) */ OPimAlarm alarmAtDateTime( const QDateTime& when, bool& found ) const; void setAlarms( const Alarms& ); void setReminders( const Reminders& ); /* register is a Ansi C keyword... */ /** * This function will register the Notify to the Alarm Server * or datebook depending on the type of the notify */ void registerNotify( const OPimNotify& ); /** * this will do the opposite.. */ void deregister( const OPimNotify& ); bool isEmpty()const; /** * Return all alarms as string */ QString alarmsToString() const; /** * Return all notifiers as string */ QString remindersToString() const; /** * Convert string to alarms * @param str String created by alarmsToString() */ void alarmsFromString( const QString& str ); /** * Convert string to reminders * @param str String created by remindersToString() */ void remindersFromString( const QString& str ); private: Reminders m_rem; Alarms m_al; class Private; Private *d; }; +} + #endif diff --git a/libopie2/opiepim/core/opimrecord.cpp b/libopie2/opiepim/core/opimrecord.cpp index 2365748..72bb372 100644 --- a/libopie2/opiepim/core/opimrecord.cpp +++ b/libopie2/opiepim/core/opimrecord.cpp @@ -1,182 +1,213 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <qarray.h> #include <qpe/categories.h> #include <qpe/categoryselect.h> -#include "opimrecord.h" +#include <opie2/opimrecord.h> +namespace Opie { Qtopia::UidGen OPimRecord::m_uidGen( Qtopia::UidGen::Qtopia ); OPimRecord::OPimRecord( int uid ) : Qtopia::Record() { m_lastHit = -1; setUid( uid ); } OPimRecord::~OPimRecord() { } OPimRecord::OPimRecord( const OPimRecord& rec ) : Qtopia::Record( rec ) { (*this) = rec; } OPimRecord &OPimRecord::operator=( const OPimRecord& rec) { if ( this == &rec ) return *this; Qtopia::Record::operator=( rec ); m_xrefman = rec.m_xrefman; m_lastHit = rec.m_lastHit; return *this; } /* * category names */ QStringList OPimRecord::categoryNames( const QString& appname ) const { QStringList list; QArray<int> cats = categories(); Categories catDB; catDB.load( categoryFileName() ); for (uint i = 0; i < cats.count(); i++ ) { list << catDB.label( appname, cats[i] ); } return list; } void OPimRecord::setCategoryNames( const QStringList& ) { } void OPimRecord::addCategoryName( const QString& ) { Categories catDB; catDB.load( categoryFileName() ); } bool OPimRecord::isEmpty()const { return ( uid() == 0 ); } /*QString OPimRecord::crossToString()const { QString str; QMap<QString, QArray<int> >::ConstIterator it; for (it = m_relations.begin(); it != m_relations.end(); ++it ) { QArray<int> id = it.data(); for ( uint i = 0; i < id.size(); ++i ) { str += it.key() + "," + QString::number( i ) + ";"; } } str = str.remove( str.length()-1, 1); // strip the ; //qWarning("IDS " + str ); return str; }*/ /* if uid = 1 assign a new one */ void OPimRecord::setUid( int uid ) { if ( uid == 1) uid = uidGen().generate(); Qtopia::Record::setUid( uid ); }; Qtopia::UidGen &OPimRecord::uidGen() { return m_uidGen; } OPimXRefManager &OPimRecord::xrefmanager() { return m_xrefman; } int OPimRecord::rtti(){ return 0; } /** * now let's put our data into the stream */ /* * First read UID * Categories * XRef */ bool OPimRecord::loadFromStream( QDataStream& stream ) { int Int; uint UInt; stream >> Int; setUid(Int); /** Categories */ stream >> UInt; QArray<int> array(UInt); for (uint i = 0; i < UInt; i++ ) { stream >> array[i]; } setCategories( array ); /* * now we do the X-Ref stuff */ OPimXRef xref; stream >> UInt; for ( uint i = 0; i < UInt; i++ ) { xref.setPartner( OPimXRef::One, partner( stream ) ); xref.setPartner( OPimXRef::Two, partner( stream ) ); m_xrefman.add( xref ); } return true; } bool OPimRecord::saveToStream( QDataStream& stream )const { /** UIDs */ stream << uid(); /** Categories */ stream << categories().count(); for ( uint i = 0; i < categories().count(); i++ ) { stream << categories()[i]; } /* * first the XRef count * then the xrefs */ stream << m_xrefman.list().count(); for ( OPimXRef::ValueList::ConstIterator it = m_xrefman.list().begin(); it != m_xrefman.list().end(); ++it ) { flush( (*it).partner( OPimXRef::One), stream ); flush( (*it).partner( OPimXRef::Two), stream ); } return true; } void OPimRecord::flush( const OPimXRefPartner& par, QDataStream& str ) const{ str << par.service(); str << par.uid(); str << par.field(); } OPimXRefPartner OPimRecord::partner( QDataStream& stream ) { OPimXRefPartner par; QString str; int i; stream >> str; par.setService( str ); stream >> i; par.setUid( i ); stream >> i ; par.setField( i ); return par; } void OPimRecord::setLastHitField( int lastHit )const { m_lastHit = lastHit; } int OPimRecord::lastHitField()const{ return m_lastHit; } QMap<QString, QString> OPimRecord::toExtraMap()const { return customMap; } void OPimRecord::setExtraMap( const QMap<QString, QString>& map) { customMap = map; } + +} diff --git a/libopie2/opiepim/core/opimrecord.h b/libopie2/opiepim/core/opimrecord.h index 3d774e2..63a3a98 100644 --- a/libopie2/opiepim/core/opimrecord.h +++ b/libopie2/opiepim/core/opimrecord.h @@ -1,158 +1,187 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_PIM_RECORD_H #define OPIE_PIM_RECORD_H #include <qdatastream.h> #include <qmap.h> #include <qstring.h> #include <qstringlist.h> /* * we need to get customMap which is private... */ #define private protected #include <qpe/palmtoprecord.h> #undef private -#include <opie/opimxrefmanager.h> +#include <opie2/opimxrefmanager.h> +namespace Opie { /** * This is the base class for * all PIM Records * */ class OPimRecord : public Qtopia::Record { public: /** * c'tor * uid of 0 isEmpty * uid of 1 will be assigned a new one */ OPimRecord(int uid = 0); ~OPimRecord(); /** * copy c'tor */ OPimRecord( const OPimRecord& rec ); /** * copy operator */ OPimRecord &operator=( const OPimRecord& ); /** * category names resolved */ QStringList categoryNames( const QString& appname )const; /** * set category names they will be resolved */ void setCategoryNames( const QStringList& ); /** * addCategoryName adds a name * to the internal category list */ void addCategoryName( const QString& ); /** * if a Record isEmpty * it's empty if it's 0 */ virtual bool isEmpty()const; /** * toRichText summary */ virtual QString toRichText()const = 0; /** * a small one line summary */ virtual QString toShortText()const = 0; /** * the name of the Record */ virtual QString type()const = 0; /** * matches the Records the regular expression? */ virtual bool match( const QString ®exp ) const {setLastHitField( -1 ); return Qtopia::Record::match(QRegExp(regexp));}; /** * if implemented this function returns which item has been * last hit by the match() function. * or -1 if not implemented or no hit has occured */ int lastHitField()const; /** * converts the internal structure to a map */ virtual QMap<int, QString> toMap()const = 0; // virtual fromMap( const <int, QString>& map ) = 0; // Should be added in the future (eilers) /** * key value representation of extra items */ QMap<QString, QString> toExtraMap()const; void setExtraMap( const QMap<QString, QString>& ); /** * the name for a recordField */ virtual QString recordField(int)const = 0; /** * returns a reference of the * Cross Reference Manager * Partner 'One' is THIS PIM RECORD! * 'Two' is the Partner where we link to */ OPimXRefManager& xrefmanager(); /** * set the uid */ virtual void setUid( int uid ); /* * used inside the Templates for casting * REIMPLEMENT in your .... */ static int rtti(); /** * some marshalling and de marshalling code * saves the OPimRecord * to and from a DataStream */ virtual bool loadFromStream(QDataStream& ); virtual bool saveToStream( QDataStream& stream )const; protected: // need to be const cause it is called from const methods mutable int m_lastHit; void setLastHitField( int lastHit )const; Qtopia::UidGen &uidGen(); // QString crossToString()const; private: class OPimRecordPrivate; OPimRecordPrivate *d; OPimXRefManager m_xrefman; static Qtopia::UidGen m_uidGen; private: void flush( const OPimXRefPartner&, QDataStream& stream )const; OPimXRefPartner partner( QDataStream& ); }; - +} #endif diff --git a/libopie2/opiepim/core/opimresolver.cpp b/libopie2/opiepim/core/opimresolver.cpp index 4ebbd6e..eceabcb 100644 --- a/libopie2/opiepim/core/opimresolver.cpp +++ b/libopie2/opiepim/core/opimresolver.cpp @@ -1,198 +1,230 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <qcopchannel_qws.h> #include <qpe/qcopenvelope_qws.h> -#include "otodoaccess.h" -#include "ocontactaccess.h" +#include <opie2/otodoaccess.h> +#include <opie2/ocontactaccess.h> //#include "opimfactory.h" -#include "opimresolver.h" +#include <opie2/opimresolver.h> + +namespace Opie { OPimResolver* OPimResolver::m_self = 0l; OPimResolver::OPimResolver() { /* the built in channels */ m_builtIns << "Todolist" << "Addressbook" << "Datebook"; } OPimResolver* OPimResolver::self() { if (!m_self) m_self = new OPimResolver(); return m_self; } /* * FIXME use a cache here too */ OPimRecord* OPimResolver::record( const QString& service, int uid ) { OPimRecord* rec = 0l; OPimBase* base = backend( service ); if ( base ) rec = base->record( uid ); delete base; return rec; } OPimRecord* OPimResolver::record( const QString& service ) { return record( serviceId( service ) ); } OPimRecord* OPimResolver::record( int rtti ) { OPimRecord* rec = 0l; switch( rtti ) { case 1: /* todolist */ rec = new OTodo(); case 2: /* contact */ rec = new OContact(); default: break; } /* * FIXME resolve externally */ if (!rec ) { ; } return 0l; } bool OPimResolver::isBuiltIn( const QString& str) const{ return m_builtIns.contains( str ); } QCString OPimResolver::qcopChannel( enum BuiltIn& built)const { QCString str("QPE/"); switch( built ) { case TodoList: str += "Todolist"; break; case DateBook: str += "Datebook"; break; case AddressBook: str += "Addressbook"; break; default: break; } return str; } QCString OPimResolver::qcopChannel( const QString& service )const { QCString str("QPE/"); str += service.latin1(); return str; } /* * Implement services!! * FIXME */ QCString OPimResolver::applicationChannel( enum BuiltIn& built)const { QCString str("QPE/Application/"); switch( built ) { case TodoList: str += "todolist"; break; case DateBook: str += "datebook"; break; case AddressBook: str += "addressbook"; break; } return str; } QCString OPimResolver::applicationChannel( const QString& service )const { QCString str("QPE/Application/"); if ( isBuiltIn( service ) ) { if ( service == "Todolist" ) str += "todolist"; else if ( service == "Datebook" ) str += "datebook"; else if ( service == "Addressbook" ) str += "addressbook"; }else ; // FIXME for additional stuff return str; } QStringList OPimResolver::services()const { return m_builtIns; } QString OPimResolver::serviceName( int rtti ) const{ QString str; switch ( rtti ) { case TodoList: str = "Todolist"; break; case DateBook: str = "Datebook"; break; case AddressBook: str = "Addressbook"; break; default: break; } return str; // FIXME me for 3rd party } int OPimResolver::serviceId( const QString& service ) { int rtti = 0; if ( service == "Todolist" ) rtti = TodoList; else if ( service == "Datebook" ) rtti = DateBook; else if ( service == "Addressbook" ) rtti = AddressBook; return rtti; } /** * check if the 'service' is registered and if so we'll */ bool OPimResolver::add( const QString& service, const OPimRecord& rec) { if ( QCopChannel::isRegistered( applicationChannel( service ) ) ) { QByteArray data; QDataStream arg(data, IO_WriteOnly ); if ( rec.saveToStream( arg ) ) { QCopEnvelope env( applicationChannel( service ), "add(int,QByteArray)" ); env << rec.rtti(); env << data; }else return false; }else{ OPimBase* base = backend( service ); if (!base ) return false; base->load(); base->add( rec ); base->save(); delete base; } return true; } OPimBase* OPimResolver::backend( const QString& service ) { return backend( serviceId( service ) ); } OPimBase* OPimResolver::backend( int rtti ) { OPimBase* base = 0l; switch( rtti ) { case TodoList: base = new OTodoAccess(); break; case DateBook: break; case AddressBook: base = new OContactAccess("Resolver"); break; default: break; } // FIXME for 3rd party if (!base ) ; return base; } + +} diff --git a/libopie2/opiepim/core/opimresolver.h b/libopie2/opiepim/core/opimresolver.h index 1ce1619..adc7c16 100644 --- a/libopie2/opiepim/core/opimresolver.h +++ b/libopie2/opiepim/core/opimresolver.h @@ -1,90 +1,121 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_PIM_RESOLVER #define OPIE_PIM_RESOLVER #include <qstring.h> #include <qvaluelist.h> -#include <opie/otemplatebase.h> +#include <opie2/otemplatebase.h> +namespace Opie { /** * OPimResolver is a MetaClass to access * available backends read only. * It will be used to resolve uids + app names * to full informations * to traverse through a list of alarms, reminders * to get access to built in PIM functionality * and to more stuff * THE PERFORMANCE will depend on THE BACKEND * USING XML is a waste of memory!!!!! */ class OPimResolver { public: enum BuiltIn { TodoList = 0, DateBook, AddressBook }; static OPimResolver* self(); /** * return a record for a uid * and an service * You've THE OWNERSHIP NOW! */ OPimRecord *record( const QString& service, int uid ); /** * return the QCopChannel for service * When we will use Qtopia Services it will be used here */ QCString qcopChannel( enum BuiltIn& )const; QCString qcopChannel( const QString& service )const; /** * The Application channel (QPE/Application/name) */ QCString applicationChannel( enum BuiltIn& )const; QCString applicationChannel( const QString& service )const; /** * return a list of available services */ QStringList services()const; inline QString serviceName(int rrti )const; int serviceId( const QString& Service); /** * add a record to a service... ;) */ bool add( const QString& service, const OPimRecord& ); /** * record returns an empty record for a given service. * Be sure to delete it!!! * */ OPimRecord* record( const QString& service ); OPimRecord* record( int rtti ); /** * you can cast to your */ OPimBase* backend( const QString& service ); OPimBase* backend( int rtti ); private: OPimResolver(); void loadData(); inline bool isBuiltIn( const QString& )const; OPimRecord* recordExtern( const QString&, int ); OPimRecord* recordExtern( const QString& ); static OPimResolver* m_self; struct Data; class Private; Data* data; Private* d; QStringList m_builtIns; }; +} + #endif diff --git a/libopie2/opiepim/core/opimstate.cpp b/libopie2/opiepim/core/opimstate.cpp index 6fb2feb..1013a1c 100644 --- a/libopie2/opiepim/core/opimstate.cpp +++ b/libopie2/opiepim/core/opimstate.cpp @@ -1,64 +1,95 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <qshared.h> #include "opimstate.h" +namespace Opie { /* * for one int this does not make * much sense but never the less * we will do it for the future */ struct OPimState::Data : public QShared { Data() : QShared(),state(Undefined) { } int state; }; OPimState::OPimState( int state ) { data = new Data; data->state = state; } OPimState::OPimState( const OPimState& st) : data( st.data ) { /* ref up */ data->ref(); } OPimState::~OPimState() { if ( data->deref() ) { delete data ; data = 0; } } bool OPimState::operator==( const OPimState& st) { if ( data->state == st.data->state ) return true; return false; } OPimState &OPimState::operator=( const OPimState& st) { st.data->ref(); deref(); data = st.data; return *this; } void OPimState::setState( int st) { copyInternally(); data->state = st; } int OPimState::state()const { return data->state; } void OPimState::deref() { if ( data->deref() ) { delete data; data = 0l; } } void OPimState::copyInternally() { /* we need to change it */ if ( data->count != 1 ) { data->deref(); Data* d2 = new Data; d2->state = data->state; data = d2; } } + +} diff --git a/libopie2/opiepim/core/opimstate.h b/libopie2/opiepim/core/opimstate.h index cf6af46..78e8cd0 100644 --- a/libopie2/opiepim/core/opimstate.h +++ b/libopie2/opiepim/core/opimstate.h @@ -1,46 +1,75 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_PIM_STATE_H #define OPIE_PIM_STATE_H #include <qstring.h> +namespace Opie { /** * The State of a Task * This class encapsules the state of a todo * and it's shared too */ /* * in c a simple struct would be enough ;) * g_new_state(); * g_do_some_thing( state_t* ); * ;) */ class OPimState { public: enum State { Started = 0, Postponed, Finished, NotStarted, Undefined }; OPimState( int state = Undefined ); OPimState( const OPimState& ); ~OPimState(); bool operator==( const OPimState& ); OPimState &operator=( const OPimState& ); void setState( int state); int state()const; private: void deref(); inline void copyInternally(); struct Data; Data* data; class Private; Private *d; }; - +} #endif diff --git a/libopie2/opiepim/core/opimxref.cpp b/libopie2/opiepim/core/opimxref.cpp index 8eefbd8..85d3345 100644 --- a/libopie2/opiepim/core/opimxref.cpp +++ b/libopie2/opiepim/core/opimxref.cpp @@ -1,47 +1,79 @@ -#include "opimxref.h" +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <opie2/opimxref.h> + +namespace Opie { OPimXRef::OPimXRef( const OPimXRefPartner& one, const OPimXRefPartner& two ) : m_partners(2) { m_partners[0] = one; m_partners[1] = two; } OPimXRef::OPimXRef() : m_partners(2) { } OPimXRef::OPimXRef( const OPimXRef& ref) { *this = ref; } OPimXRef::~OPimXRef() { } OPimXRef &OPimXRef::operator=( const OPimXRef& ref) { m_partners = ref.m_partners; m_partners.detach(); return* this; } bool OPimXRef::operator==( const OPimXRef& oper ) { if ( m_partners == oper.m_partners ) return true; return false; } OPimXRefPartner OPimXRef::partner( enum Partners par) const{ return m_partners[par]; } void OPimXRef::setPartner( enum Partners par, const OPimXRefPartner& part) { m_partners[par] = part; } bool OPimXRef::containsString( const QString& string ) const{ if ( m_partners[One].service() == string || m_partners[Two].service() == string ) return true; return false; } bool OPimXRef::containsUid( int uid ) const{ if ( m_partners[One].uid() == uid || m_partners[Two].uid() == uid ) return true; return false; } + +} diff --git a/libopie2/opiepim/core/opimxref.h b/libopie2/opiepim/core/opimxref.h index 6852651..820c9c4 100644 --- a/libopie2/opiepim/core/opimxref.h +++ b/libopie2/opiepim/core/opimxref.h @@ -1,39 +1,71 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + #ifndef OPIM_XREF_H #define OPIM_XREF_H #include <qarray.h> #include <qvaluelist.h> -#include <opie/opimxrefpartner.h> +#include <opie2/opimxrefpartner.h> +namespace Opie { /** * this is a Cross Referecne between * two Cross Reference Partners */ class OPimXRef { public: typedef QValueList<OPimXRef> ValueList; enum Partners { One, Two }; OPimXRef( const OPimXRefPartner& ONE, const OPimXRefPartner& ); OPimXRef(); OPimXRef( const OPimXRef& ); ~OPimXRef(); OPimXRef &operator=( const OPimXRef& ); bool operator==( const OPimXRef& ); OPimXRefPartner partner( enum Partners )const; void setPartner( enum Partners, const OPimXRefPartner& ); bool containsString( const QString& service)const; bool containsUid( int uid )const; private: QArray<OPimXRefPartner> m_partners; class Private; Private *d; }; +} + #endif diff --git a/libopie2/opiepim/core/opimxrefmanager.cpp b/libopie2/opiepim/core/opimxrefmanager.cpp index 58bfd24..bf6fed6 100644 --- a/libopie2/opiepim/core/opimxrefmanager.cpp +++ b/libopie2/opiepim/core/opimxrefmanager.cpp @@ -1,71 +1,102 @@ -#include "opimxrefmanager.h" +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <opie2/opimxrefmanager.h> +namespace Opie { OPimXRefManager::OPimXRefManager() { } OPimXRefManager::OPimXRefManager( const OPimXRefManager& ref) { m_list = ref.m_list; } OPimXRefManager::~OPimXRefManager() { } OPimXRefManager &OPimXRefManager::operator=( const OPimXRefManager& ref) { m_list = ref.m_list; return *this; } bool OPimXRefManager::operator==( const OPimXRefManager& /*ref*/) { // if ( m_list == ref.m_list ) return true; return false; } void OPimXRefManager::add( const OPimXRef& ref) { m_list.append( ref ); } void OPimXRefManager::remove( const OPimXRef& ref) { m_list.remove( ref ); } void OPimXRefManager::replace( const OPimXRef& ref) { m_list.remove( ref ); m_list.append( ref ); } void OPimXRefManager::clear() { m_list.clear(); } QStringList OPimXRefManager::apps()const { OPimXRef::ValueList::ConstIterator it; QStringList list; QString str; for ( it = m_list.begin(); it != m_list.end(); ++it ) { str = (*it).partner( OPimXRef::One ).service(); if ( !list.contains( str ) ) list << str; str = (*it).partner( OPimXRef::Two ).service(); if ( !list.contains( str ) ) list << str; } return list; } OPimXRef::ValueList OPimXRefManager::list()const { return m_list; } OPimXRef::ValueList OPimXRefManager::list( const QString& appName )const{ OPimXRef::ValueList list; OPimXRef::ValueList::ConstIterator it; for ( it = m_list.begin(); it != m_list.end(); ++it ) { if ( (*it).containsString( appName ) ) list.append( (*it) ); } return list; } OPimXRef::ValueList OPimXRefManager::list( int uid )const { OPimXRef::ValueList list; OPimXRef::ValueList::ConstIterator it; for ( it = m_list.begin(); it != m_list.end(); ++it ) { if ( (*it).containsUid( uid ) ) list.append( (*it) ); } return list; } + +} diff --git a/libopie2/opiepim/core/opimxrefmanager.h b/libopie2/opiepim/core/opimxrefmanager.h index c485e98..fa2d7f4 100644 --- a/libopie2/opiepim/core/opimxrefmanager.h +++ b/libopie2/opiepim/core/opimxrefmanager.h @@ -1,43 +1,74 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIM_XREF_MANAGER_H #define OPIM_XREF_MANAGER_H #include <qstringlist.h> -#include <opie/opimxref.h> +#include <opie2/opimxref.h> +namespace Opie { /** * This is a simple manager for * OPimXRefs. * It allows addition, removing, replacing * clearing and 'querying' the XRef... */ class OPimXRefManager { public: OPimXRefManager(); OPimXRefManager( const OPimXRefManager& ); ~OPimXRefManager(); OPimXRefManager& operator=( const OPimXRefManager& ); bool operator==( const OPimXRefManager& ); void add( const OPimXRef& ); void remove( const OPimXRef& ); void replace( const OPimXRef& ); void clear(); /** * apps participating */ QStringList apps()const; OPimXRef::ValueList list()const; OPimXRef::ValueList list( const QString& service )const; OPimXRef::ValueList list( int uid )const; private: OPimXRef::ValueList m_list; class Private; Private *d; }; +} + #endif diff --git a/libopie2/opiepim/core/opimxrefpartner.cpp b/libopie2/opiepim/core/opimxrefpartner.cpp index 6ef3efb..f6ccc7f 100644 --- a/libopie2/opiepim/core/opimxrefpartner.cpp +++ b/libopie2/opiepim/core/opimxrefpartner.cpp @@ -1,43 +1,75 @@ -#include "opimxrefpartner.h" +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <opie2/opimxrefpartner.h> + +namespace Opie { OPimXRefPartner::OPimXRefPartner( const QString& appName, int uid, int field ) : m_app(appName), m_uid(uid), m_field( field ) { } OPimXRefPartner::OPimXRefPartner( const OPimXRefPartner& ref ) { *this = ref; } OPimXRefPartner::~OPimXRefPartner() { } OPimXRefPartner &OPimXRefPartner::operator=( const OPimXRefPartner& par ) { m_app = par.m_app; m_uid = par.m_uid; m_field = par.m_field; return *this; } bool OPimXRefPartner::operator==( const OPimXRefPartner& par ) { if ( m_app != par.m_app ) return false; if ( m_uid != par.m_uid ) return false; if ( m_field != par.m_field ) return false; return true; } QString OPimXRefPartner::service()const { return m_app; } int OPimXRefPartner::uid()const { return m_uid; } int OPimXRefPartner::field()const { return m_field; } void OPimXRefPartner::setService( const QString& appName ) { m_app = appName; } void OPimXRefPartner::setUid( int uid ) { m_uid = uid; } void OPimXRefPartner::setField( int field ) { m_field = field; } + +} diff --git a/libopie2/opiepim/core/opimxrefpartner.h b/libopie2/opiepim/core/opimxrefpartner.h index d76e384..6853d5b 100644 --- a/libopie2/opiepim/core/opimxrefpartner.h +++ b/libopie2/opiepim/core/opimxrefpartner.h @@ -1,40 +1,70 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIM_XREF_PARTNER_H #define OPIM_XREF_PARTNER_H #include <qstring.h> +namespace Opie { /** * This class represents one partner * of a Cross Reference. * In Opie one application * can link one uid * with one tableId( fieldId ) to another. */ class OPimXRefPartner { public: OPimXRefPartner( const QString& service = QString::null, int uid = 0, int field = -1 ); OPimXRefPartner( const OPimXRefPartner& ); OPimXRefPartner& operator=( const OPimXRefPartner& ); ~OPimXRefPartner(); bool operator==(const OPimXRefPartner& ); QString service()const; int uid()const; int field()const; void setService( const QString& service ); void setUid( int uid ); void setField( int field ); private: QString m_app; int m_uid; int m_field; class Private; Private* d; }; +} #endif diff --git a/libopie2/opiepim/core/orecur.cpp b/libopie2/opiepim/core/orecur.cpp index f46f22e..033f264 100644 --- a/libopie2/opiepim/core/orecur.cpp +++ b/libopie2/opiepim/core/orecur.cpp @@ -1,593 +1,625 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + #include <time.h> #include <qshared.h> #include <qtopia/timeconversion.h> -#include "otimezone.h" -#include "orecur.h" +#include <opie2/otimezone.h> +#include <opie2/orecur.h> +namespace Opie { struct ORecur::Data : public QShared { Data() : QShared() { type = ORecur::NoRepeat; freq = -1; days = 0; pos = 0; create = QDateTime::currentDateTime(); hasEnd = FALSE; end = QDate::currentDate(); } char days; // Q_UINT8 for 8 seven days;) ORecur::RepeatType type; int freq; int pos; bool hasEnd : 1; QDate end; QDateTime create; int rep; QString app; ExceptionList list; QDate start; }; ORecur::ORecur() { data = new Data; } ORecur::ORecur( const QMap<int, QString>& map ) { ORecur(); fromMap( map ); } ORecur::ORecur( const ORecur& rec) : data( rec.data ) { data->ref(); } ORecur::~ORecur() { if ( data->deref() ) { delete data; data = 0l; } } void ORecur::deref() { if ( data->deref() ) { delete data; data = 0l; } } bool ORecur::operator==( const ORecur& )const { return false; } ORecur &ORecur::operator=( const ORecur& re) { if ( *this == re ) return *this; re.data->ref(); deref(); data = re.data; return *this; } bool ORecur::doesRecur()const { return !( type() == NoRepeat ); } /* * we try to be smart here * */ bool ORecur::doesRecur( const QDate& date ) { /* the day before the recurrance */ QDate da = date.addDays(-1); QDate recur; if (!nextOcurrence( da, recur ) ) return false; return (recur == date); } // FIXME unuglify! // GPL from Datebookdb.cpp // FIXME exception list! bool ORecur::nextOcurrence( const QDate& from, QDate& next ) { bool stillLooking; stillLooking = p_nextOccurrence( from, next ); while ( stillLooking && data->list.contains(next) ) stillLooking = p_nextOccurrence( next.addDays(1), next ); return stillLooking; } bool ORecur::p_nextOccurrence( const QDate& from, QDate& next ) { // easy checks, first are we too far in the future or too far in the past? QDate tmpDate; int freq = frequency(); int diff, diff2, a; int iday, imonth, iyear; int dayOfWeek = 0; int firstOfWeek = 0; int weekOfMonth; if (hasEndDate() && endDate() < from) return FALSE; if (start() >= from ) { next = start(); return TRUE; } switch ( type() ) { case Weekly: /* weekly is just daily by 7 */ /* first convert the repeatPattern.Days() mask to the next day of week valid after from */ dayOfWeek = from.dayOfWeek(); dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ /* this is done in case freq > 1 and from in week not for this round */ // firstOfWeek = 0; this is already done at decl. while(!((1 << firstOfWeek) & days() )) firstOfWeek++; /* there is at least one 'day', or there would be no event */ while(!((1 << (dayOfWeek % 7)) & days() )) dayOfWeek++; dayOfWeek = dayOfWeek % 7; /* the actual day of week */ dayOfWeek -= start().dayOfWeek() -1; firstOfWeek = firstOfWeek % 7; /* the actual first of week */ firstOfWeek -= start().dayOfWeek() -1; // dayOfWeek may be negitive now // day of week is number of days to add to start day freq *= 7; // FALL-THROUGH !!!!! case Daily: // the add is for the possible fall through from weekly */ if(start().addDays(dayOfWeek) > from) { /* first week exception */ next = QDate(start().addDays(dayOfWeek) ); if ((next > endDate()) && hasEndDate() ) return FALSE; return TRUE; } /* if from is middle of a non-week */ diff = start().addDays(dayOfWeek).daysTo(from) % freq; diff2 = start().addDays(firstOfWeek).daysTo(from) % freq; if(diff != 0) diff = freq - diff; if(diff2 != 0) diff2 = freq - diff2; diff = QMIN(diff, diff2); next = QDate(from.addDays(diff)); if ( (next > endDate()) && hasEndDate() ) return FALSE; return TRUE; case MonthlyDay: iday = from.day(); iyear = from.year(); imonth = from.month(); /* find equivelent day of month for this month */ dayOfWeek = start().dayOfWeek(); weekOfMonth = (start().day() - 1) / 7; /* work out when the next valid month is */ a = from.year() - start().year(); a *= 12; a = a + (imonth - start().month()); /* a is e.start()monthsFrom(from); */ if(a % freq) { a = freq - (a % freq); imonth = from.month() + a; if (imonth > 12) { imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; } } /* imonth is now the first month after or on from that matches the frequency given */ /* find for this month */ tmpDate = QDate( iyear, imonth, 1 ); iday = 1; iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; iday += 7 * weekOfMonth; while (iday > tmpDate.daysInMonth()) { imonth += freq; if (imonth > 12) { imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; } tmpDate = QDate( iyear, imonth, 1 ); /* these loops could go for a while, check end case now */ if ((tmpDate > endDate()) && hasEndDate() ) return FALSE; iday = 1; iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; iday += 7 * weekOfMonth; } tmpDate = QDate(iyear, imonth, iday); if (tmpDate >= from) { next = tmpDate; if ((next > endDate() ) && hasEndDate() ) return FALSE; return TRUE; } /* need to find the next iteration */ do { imonth += freq; if (imonth > 12) { imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; } tmpDate = QDate( iyear, imonth, 1 ); /* these loops could go for a while, check end case now */ if ((tmpDate > endDate()) && hasEndDate() ) return FALSE; iday = 1; iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; iday += 7 * weekOfMonth; } while (iday > tmpDate.daysInMonth()); tmpDate = QDate(iyear, imonth, iday); next = tmpDate; if ((next > endDate()) && hasEndDate() ) return FALSE; return TRUE; case MonthlyDate: iday = start().day(); iyear = from.year(); imonth = from.month(); a = from.year() - start().year(); a *= 12; a = a + (imonth - start().month()); /* a is e.start()monthsFrom(from); */ if(a % freq) { a = freq - (a % freq); imonth = from.month() + a; if (imonth > 12) { imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; } } /* imonth is now the first month after or on from that matches the frequencey given */ /* this could go for a while, worse case, 4*12 iterations, probably */ while(!QDate::isValid(iyear, imonth, iday) ) { imonth += freq; if (imonth > 12) { imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; } /* these loops could go for a while, check end case now */ if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) return FALSE; } if(QDate(iyear, imonth, iday) >= from) { /* done */ next = QDate(iyear, imonth, iday); if ((next > endDate()) && hasEndDate() ) return FALSE; return TRUE; } /* ok, need to cycle */ imonth += freq; imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; while(!QDate::isValid(iyear, imonth, iday) ) { imonth += freq; imonth--; iyear += imonth / 12; imonth = imonth % 12; imonth++; if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) return FALSE; } next = QDate(iyear, imonth, iday); if ((next > endDate()) && hasEndDate() ) return FALSE; return TRUE; case Yearly: iday = start().day(); imonth = start().month(); iyear = from.year(); // after all, we want to start in this year diff = 1; if(imonth == 2 && iday > 28) { /* leap year, and it counts, calculate actual frequency */ if(freq % 4) if (freq % 2) freq = freq * 4; else freq = freq * 2; /* else divides by 4 already, leave freq alone */ diff = 4; } a = from.year() - start().year(); if(a % freq) { a = freq - (a % freq); iyear = iyear + a; } /* under the assumption we won't hit one of the special not-leap years twice */ if(!QDate::isValid(iyear, imonth, iday)) { /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ iyear += freq; } if(QDate(iyear, imonth, iday) >= from) { next = QDate(iyear, imonth, iday); if ((next > endDate()) && hasEndDate() ) return FALSE; return TRUE; } /* iyear == from.year(), need to advance again */ iyear += freq; /* under the assumption we won't hit one of the special not-leap years twice */ if(!QDate::isValid(iyear, imonth, iday)) { /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ iyear += freq; } next = QDate(iyear, imonth, iday); if ((next > endDate()) && hasEndDate() ) return FALSE; return TRUE; default: return FALSE; } } ORecur::RepeatType ORecur::type()const{ return data->type; } int ORecur::frequency()const { return data->freq; } int ORecur::position()const { return data->pos; } char ORecur::days() const{ return data->days; } bool ORecur::hasEndDate()const { return data->hasEnd; } QDate ORecur::endDate()const { return data->end; } QDate ORecur::start()const{ return data->start; } QDateTime ORecur::createdDateTime()const { return data->create; } int ORecur::repetition()const { return data->rep; } QString ORecur::service()const { return data->app; } ORecur::ExceptionList& ORecur::exceptions() { return data->list; } void ORecur::setType( const RepeatType& z) { checkOrModify(); data->type = z; } void ORecur::setFrequency( int freq ) { checkOrModify(); data->freq = freq; } void ORecur::setPosition( int pos ) { checkOrModify(); data->pos = pos; } void ORecur::setDays( char c ) { checkOrModify(); data->days = c; } void ORecur::setEndDate( const QDate& dt) { checkOrModify(); data->end = dt; } void ORecur::setCreatedDateTime( const QDateTime& t) { checkOrModify(); data->create = t; } void ORecur::setHasEndDate( bool b) { checkOrModify(); data->hasEnd = b; } void ORecur::setRepitition( int rep ) { checkOrModify(); data->rep = rep; } void ORecur::setService( const QString& app ) { checkOrModify(); data->app = app; } void ORecur::setStart( const QDate& dt ) { checkOrModify(); data->start = dt; } void ORecur::checkOrModify() { if ( data->count != 1 ) { data->deref(); Data* d2 = new Data; d2->days = data->days; d2->type = data->type; d2->freq = data->freq; d2->pos = data->pos; d2->hasEnd = data->hasEnd; d2->end = data->end; d2->create = data->create; d2->rep = data->rep; d2->app = data->app; d2->list = data->list; d2->start = data->start; data = d2; } } QString ORecur::toString()const { QString buf; QMap<int, QString> recMap = toMap(); buf += " rtype=\""; buf += recMap[ORecur::RType]; buf += "\""; if (data->days > 0 ) buf += " rweekdays=\"" + recMap[ORecur::RWeekdays] + "\""; if ( data->pos != 0 ) buf += " rposition=\"" + recMap[ORecur::RPosition] + "\""; buf += " rfreq=\"" + recMap[ORecur::RFreq] + "\""; buf += " rhasenddate=\"" + recMap[ORecur::RHasEndDate]+ "\""; if ( data->hasEnd ) buf += " enddt=\"" + recMap[ORecur::EndDate] + "\""; buf += " created=\"" + recMap[ORecur::Created] + "\""; if ( data->list.isEmpty() ) return buf; buf += " exceptions=\""; buf += recMap[ORecur::Exceptions]; buf += "\" "; return buf; } QString ORecur::rTypeString() const { QString retString; switch ( data->type ) { case ORecur::Daily: retString = "Daily"; break; case ORecur::Weekly: retString = "Weekly"; break; case ORecur::MonthlyDay: retString = "MonthlyDay"; break; case ORecur::MonthlyDate: retString = "MonthlyDate"; break; case ORecur::Yearly: retString = "Yearly"; break; default: retString = "NoRepeat"; break; } return retString; } QMap<QString, ORecur::RepeatType> ORecur::rTypeValueConvertMap() const { QMap<QString, RepeatType> convertMap; convertMap.insert( QString( "Daily" ), ORecur::Daily ); convertMap.insert( QString( "Weekly" ), ORecur::Weekly ); convertMap.insert( QString( "MonthlyDay" ), ORecur::MonthlyDay ); convertMap.insert( QString( "MonthlyDate" ), ORecur::MonthlyDate ); convertMap.insert( QString( "Yearly" ), ORecur::Yearly ); convertMap.insert( QString( "NoRepeat" ), ORecur::NoRepeat ); return convertMap; } QMap<int, QString> ORecur::toMap() const { QMap<int, QString> retMap; retMap.insert( ORecur::RType, rTypeString() ); retMap.insert( ORecur::RWeekdays, QString::number( static_cast<int>( data->days ) ) ); retMap.insert( ORecur::RPosition, QString::number(data->pos ) ); retMap.insert( ORecur::RFreq, QString::number( data->freq ) ); retMap.insert( ORecur::RHasEndDate, QString::number( static_cast<int>( data->hasEnd ) ) ); if( data -> hasEnd ) retMap.insert( ORecur::EndDate, QString::number( OTimeZone::utc().fromUTCDateTime( QDateTime( data->end, QTime(12,0,0) ) ) ) ); retMap.insert( ORecur::Created, QString::number( OTimeZone::utc().fromUTCDateTime( data->create ) ) ); if ( data->list.isEmpty() ) return retMap; // save exceptions list here!! ExceptionList::ConstIterator it; ExceptionList list = data->list; QString exceptBuf; QDate date; for ( it = list.begin(); it != list.end(); ++it ) { date = (*it); if ( it != list.begin() ) exceptBuf += " "; exceptBuf += QCString().sprintf("%04d%02d%02d", date.year(), date.month(), date.day() ); } retMap.insert( ORecur::Exceptions, exceptBuf ); return retMap; } void ORecur::fromMap( const QMap<int, QString>& map ) { QMap<QString, RepeatType> repTypeMap = rTypeValueConvertMap(); data -> type = repTypeMap[ map [ORecur::RType] ]; data -> days = (char) map[ ORecur::RWeekdays ].toInt(); data -> pos = map[ ORecur::RPosition ].toInt(); data -> freq = map[ ORecur::RFreq ].toInt(); data -> hasEnd= map[ ORecur::RHasEndDate ].toInt() ? true : false; OTimeZone utc = OTimeZone::utc(); if ( data -> hasEnd ){ data -> end = utc.fromUTCDateTime( (time_t) map[ ORecur::EndDate ].toLong() ).date(); } data -> create = utc.fromUTCDateTime( (time_t) map[ ORecur::Created ].toLong() ).date(); #if 0 // FIXME: Exceptions currently not supported... // Convert the list of exceptions from QString into ExceptionList data -> list.clear(); QString exceptStr = map[ ORecur::Exceptions ]; QStringList exceptList = QStringList::split( " ", exceptStr ); ... #endif } + +}
\ No newline at end of file diff --git a/libopie2/opiepim/core/orecur.h b/libopie2/opiepim/core/orecur.h index d7ecd90..60508f5 100644 --- a/libopie2/opiepim/core/orecur.h +++ b/libopie2/opiepim/core/orecur.h @@ -1,107 +1,134 @@ /* - * GPL from TT + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #ifndef OPIE_RECUR_H #define OPIE_RECUR_H #include <sys/types.h> #include <qdatetime.h> #include <qvaluelist.h> #include <qmap.h> +namespace Opie { /** * Class to handle Recurrencies.. */ class ORecur { public: typedef QValueList<QDate> ExceptionList; enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, MonthlyDate, Yearly }; enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, FRI = 0x10, SAT = 0x20, SUN = 0x40 }; enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions }; ORecur(); ORecur( const QMap<int, QString>& map ); ORecur( const ORecur& ); ~ORecur(); ORecur &operator=( const ORecur& ); bool operator==(const ORecur& )const; bool doesRecur()const; /* if it recurrs on that day */ bool doesRecur( const QDate& ); RepeatType type()const; int frequency()const; int position()const; char days()const; bool hasEndDate()const; QDate start()const; QDate endDate()const; QDateTime createdDateTime()const; /** * starting on monday=0, sunday=6 * for convience */ bool repeatOnWeekDay( int day )const; /** * FromWhereToStart is not included!!! */ bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); /** * The module this ORecur belongs to */ QString service()const; /* * reference to the exception list */ ExceptionList &exceptions(); /** * the current repetition */ int repetition()const; void setType( const RepeatType& ); void setFrequency( int freq ); void setPosition( int pos ); void setDays( char c); void setEndDate( const QDate& dt ); void setStart( const QDate& dt ); void setCreatedDateTime( const QDateTime& ); void setHasEndDate( bool b ); void setRepitition(int ); void setService( const QString& ser ); QMap<int, QString> toMap() const; void fromMap( const QMap<int, QString>& map ); /* almost internal */ QString toString()const; private: bool p_nextOccurrence( const QDate& from, QDate& next ); void deref(); inline void checkOrModify(); /* Converts rType to String */ QString rTypeString() const; /* Returns a map to convert Stringname for RType to RepeatType */ QMap<QString, RepeatType> rTypeValueConvertMap() const; class Data; Data* data; class ORecurPrivate; ORecurPrivate *d; }; +} #endif diff --git a/libopie2/opiepim/core/otemplatebase.h b/libopie2/opiepim/core/otemplatebase.h index cadac74..17d9961 100644 --- a/libopie2/opiepim/core/otemplatebase.h +++ b/libopie2/opiepim/core/otemplatebase.h @@ -1,98 +1,129 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_TEMPLATE_BASE_H #define OPIE_TEMPLATE_BASE_H #include <qarray.h> -#include <opie/opimrecord.h> +#include <opie2/opimrecord.h> +namespace Opie { /** * Templates do not have a base class, This is why * we've this class * this is here to give us the possibility * to have a common base class * You may not want to use that interface internaly * POOR mans interface */ class OPimBasePrivate; struct OPimBase { /** * return the rtti */ virtual int rtti()= 0; virtual OPimRecord* record()const = 0; virtual OPimRecord* record(int uid)const = 0; virtual bool add( const OPimRecord& ) = 0; virtual bool remove( int uid ) = 0; virtual bool remove( const OPimRecord& ) = 0; virtual void clear() = 0; virtual bool load() = 0; virtual bool save() = 0; virtual QArray<int> records()const = 0; /* * ADD editing here? * -zecke */ private: OPimBasePrivate* d; }; /** * internal template base * T needs to implement the copy c'tor!!! */ class OTemplateBasePrivate; template <class T = OPimRecord> class OTemplateBase : public OPimBase { public: enum CacheDirection { Forward=0, Reverse }; OTemplateBase() { }; virtual ~OTemplateBase() { } virtual T find( int uid )const = 0; /** * read ahead find */ virtual T find( int uid, const QArray<int>& items, uint current, CacheDirection dir = Forward )const = 0; virtual void cache( const T& )const = 0; virtual void setSaneCacheSize( int ) = 0; /* reimplement of OPimBase */ int rtti(); OPimRecord* record()const; OPimRecord* record(int uid )const; static T* rec(); private: OTemplateBasePrivate *d; }; /* * implementation */ template <class T> int OTemplateBase<T>::rtti() { return T::rtti(); } template <class T> OPimRecord* OTemplateBase<T>::record()const { T* t = new T; return t; } template <class T> OPimRecord* OTemplateBase<T>::record(int uid )const { T t2 = find(uid ); T* t1 = new T(t2); return t1; }; template <class T> T* OTemplateBase<T>::rec() { return new T; } +} + #endif diff --git a/libopie2/opiepim/core/otimezone.cpp b/libopie2/opiepim/core/otimezone.cpp index 34659c3..dab68af 100644 --- a/libopie2/opiepim/core/otimezone.cpp +++ b/libopie2/opiepim/core/otimezone.cpp @@ -1,113 +1,146 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + #include <stdio.h> #include <stdlib.h> #include <sys/types.h> -#include "otimezone.h" +#include <opie2/otimezone.h> -namespace { +namespace Opie { QDateTime utcTime( time_t t) { tm* broken = ::gmtime( &t ); QDateTime ret; ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) ); ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) ); return ret; } QDateTime utcTime( time_t t, const QString& zone) { QCString org = ::getenv( "TZ" ); #ifndef Q_OS_MACX // Following line causes bus errors on Mac ::setenv( "TZ", zone.latin1(), true ); ::tzset(); tm* broken = ::localtime( &t ); ::setenv( "TZ", org, true ); #else #warning "Need a replacement for MacOSX!!" tm* broken = ::localtime( &t ); #endif QDateTime ret; ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) ); ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) ); return ret; } time_t to_Time_t( const QDateTime& utc, const QString& str ) { QDate d = utc.date(); QTime t = utc.time(); tm broken; broken.tm_year = d.year() - 1900; broken.tm_mon = d.month() - 1; broken.tm_mday = d.day(); broken.tm_hour = t.hour(); broken.tm_min = t.minute(); broken.tm_sec = t.second(); QCString org = ::getenv( "TZ" ); #ifndef Q_OS_MACX // Following line causes bus errors on Mac ::setenv( "TZ", str.latin1(), true ); ::tzset(); time_t ti = ::mktime( &broken ); ::setenv( "TZ", org, true ); #else #warning "Need a replacement for MacOSX!!" time_t ti = ::mktime( &broken ); #endif return ti; } } + +namespace Opie { OTimeZone::OTimeZone( const ZoneName& zone ) : m_name(zone) { } OTimeZone::~OTimeZone() { } bool OTimeZone::isValid()const { return !m_name.isEmpty(); } /* * we will get the current timezone * and ask it to convert to the timezone date */ QDateTime OTimeZone::toLocalDateTime( const QDateTime& dt) { return OTimeZone::current().toDateTime( dt, *this ); } QDateTime OTimeZone::toUTCDateTime( const QDateTime& dt ) { return OTimeZone::utc().toDateTime( dt, *this ); } QDateTime OTimeZone::fromUTCDateTime( time_t t) { return utcTime( t ); } QDateTime OTimeZone::toDateTime( time_t t) { return utcTime( t, m_name ); } /* * convert dt to utc using zone.m_name * convert utc -> timeZoneDT using this->m_name */ QDateTime OTimeZone::toDateTime( const QDateTime& dt, const OTimeZone& zone ) { time_t utc = to_Time_t( dt, zone.m_name ); qWarning("%d %s", utc, zone.m_name.latin1() ); return utcTime( utc, m_name ); } time_t OTimeZone::fromDateTime( const QDateTime& time ) { return to_Time_t( time, m_name ); } time_t OTimeZone::fromUTCDateTime( const QDateTime& time ) { return to_Time_t( time, "UTC" ); } OTimeZone OTimeZone::current() { QCString str = ::getenv("TZ"); OTimeZone zone( str ); return zone; } OTimeZone OTimeZone::utc() { return OTimeZone("UTC"); } QString OTimeZone::timeZone()const { return m_name; } + +} diff --git a/libopie2/opiepim/core/otimezone.h b/libopie2/opiepim/core/otimezone.h index bb08349..28ae6cb 100644 --- a/libopie2/opiepim/core/otimezone.h +++ b/libopie2/opiepim/core/otimezone.h @@ -1,71 +1,102 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + #ifndef OPIE_TIME_ZONE_H #define OPIE_TIME_ZONE_H #include <time.h> #include <qdatetime.h> +namespace Opie +{ /** * A very primitive class to convert time * from one timezone to another * and to localtime * and time_t */ class OTimeZone { public: typedef QString ZoneName; OTimeZone( const ZoneName& = ZoneName::null ); virtual ~OTimeZone(); // just in case. bool isValid()const; /** * converts the QDateTime to a DateTime * in the local timezone * if QDateTime is 25th Jan and takes place in Europe/Berlin at 12h * and the current timezone is Europe/London the returned * time will be 11h. */ QDateTime toLocalDateTime( const QDateTime& dt ); /** * converts the QDateTime to UTC time */ QDateTime toUTCDateTime( const QDateTime& dt ); /** * reads the time_t into a QDateTime using UTC as timezone! */ QDateTime fromUTCDateTime( time_t ); /** * converts the time_t to the time in the timezone */ QDateTime toDateTime( time_t ); /** * converts the QDateTime from one timezone to this timeZone */ QDateTime toDateTime( const QDateTime&, const OTimeZone& timeZone ); /** * converts the date time into a time_t. It takes the timezone into account */ time_t fromDateTime( const QDateTime& ); /** * converts the datetime with timezone UTC */ time_t fromUTCDateTime( const QDateTime& ); static OTimeZone current(); static OTimeZone utc(); QString timeZone()const; private: ZoneName m_name; class Private; Private* d; }; - +}; #endif diff --git a/libopie2/opiepim/core/otodoaccess.cpp b/libopie2/opiepim/core/otodoaccess.cpp index 37f6fbc..2a3695d 100644 --- a/libopie2/opiepim/core/otodoaccess.cpp +++ b/libopie2/opiepim/core/otodoaccess.cpp @@ -1,62 +1,93 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <qdatetime.h> #include <qpe/alarmserver.h> // #include "otodoaccesssql.h" -#include "otodoaccess.h" -#include "obackendfactory.h" +#include <opie2/otodoaccess.h> +#include <opie2/obackendfactory.h> +namespace Opie { OTodoAccess::OTodoAccess( OTodoAccessBackend* end, enum Access ) : QObject(), OPimAccessTemplate<OTodo>( end ), m_todoBackEnd( end ) { // if (end == 0l ) // m_todoBackEnd = new OTodoAccessBackendSQL( QString::null); - // Zecke: Du musst hier noch für das XML-Backend einen Appnamen übergeben ! + // Zecke: Du musst hier noch fr das XML-Backend einen Appnamen bergeben ! if (end == 0l ) m_todoBackEnd = OBackendFactory<OTodoAccessBackend>::Default ("todo", QString::null); setBackEnd( m_todoBackEnd ); } OTodoAccess::~OTodoAccess() { // qWarning("~OTodoAccess"); } void OTodoAccess::mergeWith( const QValueList<OTodo>& list ) { QValueList<OTodo>::ConstIterator it; for ( it = list.begin(); it != list.end(); ++it ) { replace( (*it) ); } } OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates ) { QArray<int> ints = m_todoBackEnd->effectiveToDos( start, end, includeNoDates ); List lis( ints, this ); return lis; } OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start, bool includeNoDates ) { return effectiveToDos( start, QDate::currentDate(), includeNoDates ); } OTodoAccess::List OTodoAccess::overDue() { List lis( m_todoBackEnd->overDue(), this ); return lis; } /* sort order */ OTodoAccess::List OTodoAccess::sorted( bool ascending, int sort,int filter, int cat ) { QArray<int> ints = m_todoBackEnd->sorted( ascending, sort, filter, cat ); OTodoAccess::List list( ints, this ); return list; } void OTodoAccess::removeAllCompleted() { m_todoBackEnd->removeAllCompleted(); } QBitArray OTodoAccess::backendSupport( const QString& ) const{ return m_todoBackEnd->supports(); } bool OTodoAccess::backendSupports( int attr, const QString& ar) const{ return backendSupport(ar).testBit( attr ); } + +} diff --git a/libopie2/opiepim/core/otodoaccess.h b/libopie2/opiepim/core/otodoaccess.h index 916923f..e13d277 100644 --- a/libopie2/opiepim/core/otodoaccess.h +++ b/libopie2/opiepim/core/otodoaccess.h @@ -1,105 +1,136 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_TODO_ACCESS_H #define OPIE_TODO_ACCESS_H #include <qobject.h> #include <qvaluelist.h> -#include "otodo.h" -#include "otodoaccessbackend.h" -#include "opimaccesstemplate.h" +#include <opie2/otodo.h> +#include <opie2/otodoaccessbackend.h> +#include <opie2/opimaccesstemplate.h> +namespace Opie { /** * OTodoAccess * the class to get access to * the todolist */ class OTodoAccess : public QObject, public OPimAccessTemplate<OTodo> { Q_OBJECT public: enum SortOrder { Completed = 0, Priority, Description, Deadline }; enum SortFilter{ Category =1, OnlyOverDue= 2, DoNotShowCompleted =4 }; /** * if you use 0l * the default resource will be * picked up */ OTodoAccess( OTodoAccessBackend* = 0l, enum Access acc = Random ); ~OTodoAccess(); /* our functions here */ /** * include todos from start to end * includeNoDates whether or not to include * events with no dates */ List effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates = true ); /** * start * end date taken from the currentDate() */ List effectiveToDos( const QDate& start, bool includeNoDates = true ); /** * return overdue OTodos */ List overDue(); /** * */ List sorted( bool ascending, int sortOrder, int sortFilter, int cat ); /** * merge a list of OTodos into * the resource */ void mergeWith( const QValueList<OTodo>& ); /** * delete all already completed items */ void removeAllCompleted(); /** * request information about what a backend supports. * Supports in the sense of beeing able to store. * This is related to the enum in OTodo * * @param backend Will be used in the future when we support multiple backend */ QBitArray backendSupport( const QString& backend = QString::null )const; /** * see above but for a specefic attribute. This method was added for convience * @param attr The attribute to be queried for * @param backend Will be used in the future when we support multiple backends */ bool backendSupports( int attr, const QString& backend = QString::null )const; signals: /** * if the OTodoAccess was changed */ void changed( const OTodoAccess* ); void changed( const OTodoAccess*, int uid ); void added( const OTodoAccess*, int uid ); void removed( const OTodoAccess*, int uid ); private: int m_cat; OTodoAccessBackend* m_todoBackEnd; class OTodoAccessPrivate; OTodoAccessPrivate* d; }; +} + #endif diff --git a/libopie2/opiepim/ocontact.cpp b/libopie2/opiepim/ocontact.cpp index fcf3b26..f1a22a7 100644 --- a/libopie2/opiepim/ocontact.cpp +++ b/libopie2/opiepim/ocontact.cpp @@ -1,1207 +1,1238 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** Copyright (C) 2002-2003 by Stefan Eilers (eilers.stefan@epost.de) ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #define QTOPIA_INTERNAL_CONTACT_MRE -#include "ocontact.h" -#include "opimresolver.h" -#include "oconversion.h" +#include <opie2/ocontact.h> +#include <opie2/opimresolver.h> +#include <opie2/oconversion.h> #include <qpe/stringutil.h> #include <qpe/timestring.h> #include <qpe/config.h> #include <qobject.h> #include <qregexp.h> #include <qstylesheet.h> #include <qfileinfo.h> #include <qmap.h> #include <stdio.h> /*! \class Contact contact.h \brief The Contact class holds the data of an address book entry. This data includes information the name of the person, contact information, and business information such as deparment and job title. \ingroup qtopiaemb \ingroup qtopiadesktop */ +namespace Opie { /*! Creates a new, empty contact. */ OContact::OContact() : OPimRecord(), mMap(), d( 0 ) { } /*! \internal Creates a new contact. The properties of the contact are set from \a fromMap. */ OContact::OContact( const QMap<int, QString> &fromMap ) : OPimRecord(), mMap( fromMap ), d( 0 ) { QString cats = mMap[ Qtopia::AddressCategory ]; if ( !cats.isEmpty() ) setCategories( idsFromString( cats ) ); QString uidStr = find( Qtopia::AddressUid ); if ( uidStr.isEmpty() || (uidStr.toInt() == 0) ){ qWarning( "Invalid UID found. Generate new one.." ); setUid( uidGen().generate() ); }else setUid( uidStr.toInt() ); // if ( !uidStr.isEmpty() ) // setUid( uidStr.toInt() ); } /*! Destroys a contact. */ OContact::~OContact() { } /*! \fn void OContact::setTitle( const QString &str ) Sets the title of the contact to \a str. */ /*! \fn void OContact::setFirstName( const QString &str ) Sets the first name of the contact to \a str. */ /*! \fn void OContact::setMiddleName( const QString &str ) Sets the middle name of the contact to \a str. */ /*! \fn void OContact::setLastName( const QString &str ) Sets the last name of the contact to \a str. */ /*! \fn void OContact::setSuffix( const QString &str ) Sets the suffix of the contact to \a str. */ /*! \fn void OContact::setFileAs( const QString &str ) Sets the contact to filed as \a str. */ /*! \fn void OContact::setDefaultEmail( const QString &str ) Sets the default email of the contact to \a str. */ /*! \fn void OContact::setHomeStreet( const QString &str ) Sets the home street address of the contact to \a str. */ /*! \fn void OContact::setHomeCity( const QString &str ) Sets the home city of the contact to \a str. */ /*! \fn void OContact::setHomeState( const QString &str ) Sets the home state of the contact to \a str. */ /*! \fn void OContact::setHomeZip( const QString &str ) Sets the home zip code of the contact to \a str. */ /*! \fn void OContact::setHomeCountry( const QString &str ) Sets the home country of the contact to \a str. */ /*! \fn void OContact::setHomePhone( const QString &str ) Sets the home phone number of the contact to \a str. */ /*! \fn void OContact::setHomeFax( const QString &str ) Sets the home fax number of the contact to \a str. */ /*! \fn void OContact::setHomeMobile( const QString &str ) Sets the home mobile phone number of the contact to \a str. */ /*! \fn void OContact::setHomeWebpage( const QString &str ) Sets the home webpage of the contact to \a str. */ /*! \fn void OContact::setCompany( const QString &str ) Sets the company for contact to \a str. */ /*! \fn void OContact::setJobTitle( const QString &str ) Sets the job title of the contact to \a str. */ /*! \fn void OContact::setDepartment( const QString &str ) Sets the department for contact to \a str. */ /*! \fn void OContact::setOffice( const QString &str ) Sets the office for contact to \a str. */ /*! \fn void OContact::setBusinessStreet( const QString &str ) Sets the business street address of the contact to \a str. */ /*! \fn void OContact::setBusinessCity( const QString &str ) Sets the business city of the contact to \a str. */ /*! \fn void OContact::setBusinessState( const QString &str ) Sets the business state of the contact to \a str. */ /*! \fn void OContact::setBusinessZip( const QString &str ) Sets the business zip code of the contact to \a str. */ /*! \fn void OContact::setBusinessCountry( const QString &str ) Sets the business country of the contact to \a str. */ /*! \fn void OContact::setBusinessPhone( const QString &str ) Sets the business phone number of the contact to \a str. */ /*! \fn void OContact::setBusinessFax( const QString &str ) Sets the business fax number of the contact to \a str. */ /*! \fn void OContact::setBusinessMobile( const QString &str ) Sets the business mobile phone number of the contact to \a str. */ /*! \fn void OContact::setBusinessPager( const QString &str ) Sets the business pager number of the contact to \a str. */ /*! \fn void OContact::setBusinessWebpage( const QString &str ) Sets the business webpage of the contact to \a str. */ /*! \fn void OContact::setProfession( const QString &str ) Sets the profession of the contact to \a str. */ /*! \fn void OContact::setAssistant( const QString &str ) Sets the assistant of the contact to \a str. */ /*! \fn void OContact::setManager( const QString &str ) Sets the manager of the contact to \a str. */ /*! \fn void OContact::setSpouse( const QString &str ) Sets the spouse of the contact to \a str. */ /*! \fn void OContact::setGender( const QString &str ) Sets the gender of the contact to \a str. */ /*! \fn void OContact::setNickname( const QString &str ) Sets the nickname of the contact to \a str. */ /*! \fn void OContact::setNotes( const QString &str ) Sets the notes about the contact to \a str. */ /*! \fn QString OContact::title() const Returns the title of the contact. */ /*! \fn QString OContact::firstName() const Returns the first name of the contact. */ /*! \fn QString OContact::middleName() const Returns the middle name of the contact. */ /*! \fn QString OContact::lastName() const Returns the last name of the contact. */ /*! \fn QString OContact::suffix() const Returns the suffix of the contact. */ /*! \fn QString OContact::fileAs() const Returns the string the contact is filed as. */ /*! \fn QString OContact::defaultEmail() const Returns the default email address of the contact. */ /*! \fn QString OContact::emails() const Returns the list of email address for a contact separated by ';'s in a single string. */ /*! \fn QString OContact::homeStreet() const Returns the home street address of the contact. */ /*! \fn QString OContact::homeCity() const Returns the home city of the contact. */ /*! \fn QString OContact::homeState() const Returns the home state of the contact. */ /*! \fn QString OContact::homeZip() const Returns the home zip of the contact. */ /*! \fn QString OContact::homeCountry() const Returns the home country of the contact. */ /*! \fn QString OContact::homePhone() const Returns the home phone number of the contact. */ /*! \fn QString OContact::homeFax() const Returns the home fax number of the contact. */ /*! \fn QString OContact::homeMobile() const Returns the home mobile number of the contact. */ /*! \fn QString OContact::homeWebpage() const Returns the home webpage of the contact. */ /*! \fn QString OContact::company() const Returns the company for the contact. */ /*! \fn QString OContact::department() const Returns the department for the contact. */ /*! \fn QString OContact::office() const Returns the office for the contact. */ /*! \fn QString OContact::jobTitle() const Returns the job title of the contact. */ /*! \fn QString OContact::profession() const Returns the profession of the contact. */ /*! \fn QString OContact::assistant() const Returns the assistant of the contact. */ /*! \fn QString OContact::manager() const Returns the manager of the contact. */ /*! \fn QString OContact::businessStreet() const Returns the business street address of the contact. */ /*! \fn QString OContact::businessCity() const Returns the business city of the contact. */ /*! \fn QString OContact::businessState() const Returns the business state of the contact. */ /*! \fn QString OContact::businessZip() const Returns the business zip of the contact. */ /*! \fn QString OContact::businessCountry() const Returns the business country of the contact. */ /*! \fn QString OContact::businessPhone() const Returns the business phone number of the contact. */ /*! \fn QString OContact::businessFax() const Returns the business fax number of the contact. */ /*! \fn QString OContact::businessMobile() const Returns the business mobile number of the contact. */ /*! \fn QString OContact::businessPager() const Returns the business pager number of the contact. */ /*! \fn QString OContact::businessWebpage() const Returns the business webpage of the contact. */ /*! \fn QString OContact::spouse() const Returns the spouse of the contact. */ /*! \fn QString OContact::gender() const Returns the gender of the contact. */ /*! \fn QString OContact::nickname() const Returns the nickname of the contact. */ /*! \fn QString OContact::children() const Returns the children of the contact. */ /*! \fn QString OContact::notes() const Returns the notes relating to the the contact. */ /*! \fn QString OContact::groups() const \internal Returns the groups for the contact. */ /*! \fn QStringList OContact::groupList() const \internal */ /*! \fn QString OContact::field(int) const \internal */ /*! \fn void OContact::saveJournal( journal_action, const QString & = QString::null ) \internal */ /*! \fn void OContact::setUid( int id ) \internal Sets the uid for this record to \a id. */ /*! \enum OContact::journal_action \internal */ /*! \internal */ QMap<int, QString> OContact::toMap() const { QMap<int, QString> map = mMap; QString cats = idsToString( categories() ); if ( !cats.isEmpty() ) map.insert( Qtopia::AddressCategory, cats ); return map; } /*! Returns a rich text formatted QString representing the contents the contact. */ QString OContact::toRichText() const { QString text; QString value, comp, state; QString str; bool marker = false; Config cfg("qpe"); cfg.setGroup("Appearance"); int addressformat = cfg.readNumEntry( "AddressFormat", Zip_City_State ); // name, jobtitle and company if ( !(value = fullName()).isEmpty() ) text += "<b><h3><img src=\"addressbook/AddressBook\"> " + Qtopia::escapeString(value) + "</h3></b>"; if ( !(value = jobTitle()).isEmpty() ) text += Qtopia::escapeString(value) + " "; comp = company(); if ( !(value = department()).isEmpty() ) { text += Qtopia::escapeString(value); if ( comp ) text += ", " + Qtopia::escapeString(comp); }else if ( comp ) text += "<br>" + Qtopia::escapeString(comp); text += "<br><hr>"; // defailt email QString defEmail = defaultEmail(); if ( !defEmail.isEmpty() ){ text += "<b><img src=\"addressbook/email\"> " + QObject::tr("Default Email: ") + "</b>" + Qtopia::escapeString(defEmail); marker = true; } // business address if ( !businessStreet().isEmpty() || !businessCity().isEmpty() || !businessZip().isEmpty() || !businessCountry().isEmpty() ) { text += QObject::tr( "<br><b>Work Address:</b>" ); marker = true; } if ( !(value = businessStreet()).isEmpty() ){ text += "<br>" + Qtopia::escapeString(value); marker = true; } switch( addressformat ){ case Zip_City_State:{ // Zip_Code City, State state = businessState(); if ( !(value = businessZip()).isEmpty() ){ text += "<br>" + Qtopia::escapeString(value) + " "; marker = true; } if ( !(value = businessCity()).isEmpty() ) { marker = true; if ( businessZip().isEmpty() && !businessStreet().isEmpty() ) text += "<br>"; text += Qtopia::escapeString(value); if ( state ) text += ", " + Qtopia::escapeString(state); } else if ( !state.isEmpty() ){ text += "<br>" + Qtopia::escapeString(state); marker = true; } break; } case City_State_Zip:{ // City, State Zip_Code state = businessState(); if ( !(value = businessCity()).isEmpty() ) { marker = true; text += "<br>" + Qtopia::escapeString(value); if ( state ) text += ", " + Qtopia::escapeString(state); } else if ( !state.isEmpty() ){ text += "<br>" + Qtopia::escapeString(state); marker = true; } if ( !(value = businessZip()).isEmpty() ){ text += " " + Qtopia::escapeString(value); marker = true; } break; } } if ( !(value = businessCountry()).isEmpty() ){ text += "<br>" + Qtopia::escapeString(value); marker = true; } // rest of Business data str = office(); if ( !str.isEmpty() ){ text += "<br><b>" + QObject::tr("Office: ") + "</b>" + Qtopia::escapeString(str); marker = true; } str = businessWebpage(); if ( !str.isEmpty() ){ text += "<br><b><img src=\"addressbook/webpagework\"> " + QObject::tr("Business Web Page: ") + "</b>" + Qtopia::escapeString(str); marker = true; } str = businessPhone(); if ( !str.isEmpty() ){ text += "<br><b><img src=\"addressbook/phonework\"> " + QObject::tr("Business Phone: ") + "</b>" + Qtopia::escapeString(str); marker = true; } str = businessFax(); if ( !str.isEmpty() ){ text += "<br><b><img src=\"addressbook/faxwork\"> " + QObject::tr("Business Fax: ") + "</b>" + Qtopia::escapeString(str); marker = true; } str = businessMobile(); if ( !str.isEmpty() ){ text += "<br><b><img src=\"addressbook/mobilework\"> " + QObject::tr("Business Mobile: ") + "</b>" + Qtopia::escapeString(str); marker = true; } str = businessPager(); if ( !str.isEmpty() ){ text += "<br><b>" + QObject::tr("Business Pager: ") + "</b>" + Qtopia::escapeString(str); marker = true; } // text += "<br>"; // home address if ( !homeStreet().isEmpty() || !homeCity().isEmpty() || !homeZip().isEmpty() || !homeCountry().isEmpty() ) { text += QObject::tr( "<br><b>Home Address:</b>" ); marker = true; } if ( !(value = homeStreet()).isEmpty() ){ text += "<br>" + Qtopia::escapeString(value); marker = true; } switch( addressformat ){ case Zip_City_State:{ // Zip_Code City, State state = homeState(); if ( !(value = homeZip()).isEmpty() ){ text += "<br>" + Qtopia::escapeString(value) + " "; marker = true; } if ( !(value = homeCity()).isEmpty() ) { marker = true; if ( homeZip().isEmpty() && !homeStreet().isEmpty() ) text += "<br>"; text += Qtopia::escapeString(value); if ( !state.isEmpty() ) text += ", " + Qtopia::escapeString(state); } else if (!state.isEmpty()) { text += "<br>" + Qtopia::escapeString(state); marker = true; } break; } case City_State_Zip:{ // City, State Zip_Code state = homeState(); if ( !(value = homeCity()).isEmpty() ) { marker = true; text += "<br>" + Qtopia::escapeString(value); if ( state ) text += ", " + Qtopia::escapeString(state); } else if ( !state.isEmpty() ){ text += "<br>" + Qtopia::escapeString(state); marker = true; } if ( !(value = homeZip()).isEmpty() ){ text += " " + Qtopia::escapeString(value); marker = true; } break; } } if ( !(value = homeCountry()).isEmpty() ){ text += "<br>" + Qtopia::escapeString(value); marker = true; } // rest of Home data str = homeWebpage(); if ( !str.isEmpty() ){ text += "<br><b><img src=\"addressbook/webpagehome\"> " + QObject::tr("Home Web Page: ") + "</b>" + Qtopia::escapeString(str); marker = true; } str = homePhone(); if ( !str.isEmpty() ){ text += "<br><b><img src=\"addressbook/phonehome\"> " + QObject::tr("Home Phone: ") + "</b>" + Qtopia::escapeString(str); marker = true; } str = homeFax(); if ( !str.isEmpty() ){ text += "<br><b><img src=\"addressbook/faxhome\"> " + QObject::tr("Home Fax: ") + "</b>" + Qtopia::escapeString(str); marker = true; } str = homeMobile(); if ( !str.isEmpty() ){ text += "<br><b><img src=\"addressbook/mobilehome\"> " + QObject::tr("Home Mobile: ") + "</b>" + Qtopia::escapeString(str); marker = true; } if ( marker ) text += "<br><hr>"; // the rest... str = emails(); if ( !str.isEmpty() && ( str != defEmail ) ) text += "<br><b>" + QObject::tr("All Emails: ") + "</b>" + Qtopia::escapeString(str); str = profession(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr("Profession: ") + "</b>" + Qtopia::escapeString(str); str = assistant(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr("Assistant: ") + "</b>" + Qtopia::escapeString(str); str = manager(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr("Manager: ") + "</b>" + Qtopia::escapeString(str); str = gender(); if ( !str.isEmpty() && str.toInt() != 0 ) { text += "<br>"; if ( str.toInt() == 1 ) str = QObject::tr( "Male" ); else if ( str.toInt() == 2 ) str = QObject::tr( "Female" ); text += "<b>" + QObject::tr("Gender: ") + "</b>" + str; } str = spouse(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr("Spouse: ") + "</b>" + Qtopia::escapeString(str); if ( birthday().isValid() ){ str = TimeString::numberDateString( birthday() ); text += "<br><b>" + QObject::tr("Birthday: ") + "</b>" + Qtopia::escapeString(str); } if ( anniversary().isValid() ){ str = TimeString::numberDateString( anniversary() ); text += "<br><b>" + QObject::tr("Anniversary: ") + "</b>" + Qtopia::escapeString(str); } str = children(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr("Children: ") + "</b>" + Qtopia::escapeString(str); str = nickname(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr("Nickname: ") + "</b>" + Qtopia::escapeString(str); // categories if ( categoryNames("Contacts").count() ){ text += "<br><b>" + QObject::tr( "Category:") + "</b> "; text += categoryNames("Contacts").join(", "); } // notes last if ( !(value = notes()).isEmpty() ) { text += "<br><hr><b>" + QObject::tr( "Notes:") + "</b> "; QRegExp reg("\n"); //QString tmp = Qtopia::escapeString(value); QString tmp = QStyleSheet::convertFromPlainText(value); //tmp.replace( reg, "<br>" ); text += "<br>" + tmp + "<br>"; } return text; } /*! \internal */ void OContact::insert( int key, const QString &v ) { QString value = v.stripWhiteSpace(); if ( value.isEmpty() ) mMap.remove( key ); else mMap.insert( key, value ); } /*! \internal */ void OContact::replace( int key, const QString & v ) { QString value = v.stripWhiteSpace(); if ( value.isEmpty() ) mMap.remove( key ); else mMap.replace( key, value ); } /*! \internal */ QString OContact::find( int key ) const { return mMap[key]; } /*! \internal */ QString OContact::displayAddress( const QString &street, const QString &city, const QString &state, const QString &zip, const QString &country ) const { QString s = street; if ( !street.isEmpty() ) s+= "\n"; s += city; if ( !city.isEmpty() && !state.isEmpty() ) s += ", "; s += state; if ( !state.isEmpty() && !zip.isEmpty() ) s += " "; s += zip; if ( !country.isEmpty() && !s.isEmpty() ) s += "\n"; s += country; return s; } /*! \internal */ QString OContact::displayBusinessAddress() const { return displayAddress( businessStreet(), businessCity(), businessState(), businessZip(), businessCountry() ); } /*! \internal */ QString OContact::displayHomeAddress() const { return displayAddress( homeStreet(), homeCity(), homeState(), homeZip(), homeCountry() ); } /*! Returns the full name of the contact */ QString OContact::fullName() const { QString title = find( Qtopia::Title ); QString firstName = find( Qtopia::FirstName ); QString middleName = find( Qtopia::MiddleName ); QString lastName = find( Qtopia::LastName ); QString suffix = find( Qtopia::Suffix ); QString name = title; if ( !firstName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += firstName; } if ( !middleName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += middleName; } if ( !lastName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += lastName; } if ( !suffix.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += suffix; } return name.simplifyWhiteSpace(); } /*! Returns a list of the names of the children of the contact. */ QStringList OContact::childrenList() const { return QStringList::split( " ", find( Qtopia::Children ) ); } /*! \fn void OContact::insertEmail( const QString &email ) Insert \a email into the email list. Ensures \a email can only be added once. If there is no default email address set, it sets it to the \a email. */ /*! \fn void OContact::removeEmail( const QString &email ) Removes the \a email from the email list. If the default email was \a email, then the default email address is assigned to the first email in the email list */ /*! \fn void OContact::clearEmails() Clears the email list. */ /*! \fn void OContact::insertEmails( const QStringList &emailList ) Appends the \a emailList to the exiting email list */ /*! Returns a list of email addresses belonging to the contact, including the default email address. */ QStringList OContact::emailList() const { QString emailStr = emails(); QStringList r; if ( !emailStr.isEmpty() ) { qDebug(" emailstr "); QStringList l = QStringList::split( emailSeparator(), emailStr ); for ( QStringList::ConstIterator it = l.begin();it != l.end();++it ) r += (*it).simplifyWhiteSpace(); } return r; } /*! \overload Generates the string for the contact to be filed as from the first, middle and last name of the contact. */ void OContact::setFileAs() { QString lastName, firstName, middleName, fileas; lastName = find( Qtopia::LastName ); firstName = find( Qtopia::FirstName ); middleName = find( Qtopia::MiddleName ); if ( !lastName.isEmpty() && !firstName.isEmpty() && !middleName.isEmpty() ) fileas = lastName + ", " + firstName + " " + middleName; else if ( !lastName.isEmpty() && !firstName.isEmpty() ) fileas = lastName + ", " + firstName; else if ( !lastName.isEmpty() || !firstName.isEmpty() || !middleName.isEmpty() ) fileas = firstName + ( firstName.isEmpty() ? "" : " " ) + middleName + ( middleName.isEmpty() ? "" : " " ) + lastName; replace( Qtopia::FileAs, fileas ); } /*! \internal Appends the contact information to \a buf. */ void OContact::save( QString &buf ) const { static const QStringList SLFIELDS = fields(); // I'm expecting "<Contact " in front of this... for ( QMap<int, QString>::ConstIterator it = mMap.begin(); it != mMap.end(); ++it ) { const QString &value = it.data(); int key = it.key(); if ( !value.isEmpty() ) { if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid) continue; key -= Qtopia::AddressCategory+1; buf += SLFIELDS[key]; buf += "=\"" + Qtopia::escapeString(value) + "\" "; } } buf += customToXml(); if ( categories().count() > 0 ) buf += "Categories=\"" + idsToString( categories() ) + "\" "; buf += "Uid=\"" + QString::number( uid() ) + "\" "; // You need to close this yourself } /*! \internal Returns the list of fields belonging to a contact Never change order of this list ! It has to be regarding enum AddressBookFields !! */ QStringList OContact::fields() { QStringList list; list.append( "Title" ); // Not Used! list.append( "FirstName" ); list.append( "MiddleName" ); list.append( "LastName" ); list.append( "Suffix" ); list.append( "FileAs" ); list.append( "JobTitle" ); list.append( "Department" ); list.append( "Company" ); list.append( "BusinessPhone" ); list.append( "BusinessFax" ); list.append( "BusinessMobile" ); list.append( "DefaultEmail" ); list.append( "Emails" ); list.append( "HomePhone" ); list.append( "HomeFax" ); list.append( "HomeMobile" ); list.append( "BusinessStreet" ); list.append( "BusinessCity" ); list.append( "BusinessState" ); list.append( "BusinessZip" ); list.append( "BusinessCountry" ); list.append( "BusinessPager" ); list.append( "BusinessWebPage" ); list.append( "Office" ); list.append( "Profession" ); list.append( "Assistant" ); list.append( "Manager" ); list.append( "HomeStreet" ); list.append( "HomeCity" ); list.append( "HomeState" ); list.append( "HomeZip" ); list.append( "HomeCountry" ); list.append( "HomeWebPage" ); list.append( "Spouse" ); list.append( "Gender" ); list.append( "Birthday" ); list.append( "Anniversary" ); list.append( "Nickname" ); list.append( "Children" ); list.append( "Notes" ); list.append( "Groups" ); return list; } /*! Sets the list of email address for contact to those contained in \a str. Email address should be separated by ';'s. */ void OContact::setEmails( const QString &str ) { replace( Qtopia::Emails, str ); if ( str.isEmpty() ) setDefaultEmail( QString::null ); } /*! Sets the list of children for the contact to those contained in \a str. */ void OContact::setChildren( const QString &str ) { replace( Qtopia::Children, str ); } /*! \overload Returns TRUE if the contact matches the regular expression \a regexp. Otherwise returns FALSE. */ bool OContact::match( const QRegExp &r ) const { setLastHitField( -1 ); bool match; match = false; QMap<int, QString>::ConstIterator it; for ( it = mMap.begin(); it != mMap.end(); ++it ) { if ( (*it).find( r ) > -1 ) { setLastHitField( it.key() ); match = true; break; } } return match; } QString OContact::toShortText() const { return ( fullName() ); } QString OContact::type() const { return QString::fromLatin1( "OContact" ); } class QString OContact::recordField( int pos ) const { QStringList SLFIELDS = fields(); // ?? why this ? (se) return SLFIELDS[pos]; } // In future releases, we should store birthday and anniversary // internally as QDate instead of QString ! // QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se) /*! \fn void OContact::setBirthday( const QDate& date ) Sets the birthday for the contact to \a date. If date is null the current stored date will be removed. */ void OContact::setBirthday( const QDate &v ) { if ( v.isNull() ){ qWarning( "Remove Birthday"); replace( Qtopia::Birthday, QString::null ); return; } if ( v.isValid() ) replace( Qtopia::Birthday, OConversion::dateToString( v ) ); } /*! \fn void OContact::setAnniversary( const QDate &date ) Sets the anniversary of the contact to \a date. If date is null, the current stored date will be removed. */ void OContact::setAnniversary( const QDate &v ) { if ( v.isNull() ){ qWarning( "Remove Anniversary"); replace( Qtopia::Anniversary, QString::null ); return; } if ( v.isValid() ) replace( Qtopia::Anniversary, OConversion::dateToString( v ) ); } /*! \fn QDate OContact::birthday() const Returns the birthday of the contact. */ QDate OContact::birthday() const { QString str = find( Qtopia::Birthday ); // qWarning ("Birthday %s", str.latin1() ); if ( !str.isEmpty() ) return OConversion::dateFromString ( str ); else return QDate(); } /*! \fn QDate OContact::anniversary() const Returns the anniversary of the contact. */ QDate OContact::anniversary() const { QDate empty; QString str = find( Qtopia::Anniversary ); // qWarning ("Anniversary %s", str.latin1() ); if ( !str.isEmpty() ) return OConversion::dateFromString ( str ); else return empty; } void OContact::insertEmail( const QString &v ) { //qDebug("insertEmail %s", v.latin1()); QString e = v.simplifyWhiteSpace(); QString def = defaultEmail(); // if no default, set it as the default email and don't insert if ( def.isEmpty() ) { setDefaultEmail( e ); // will insert into the list for us return; } // otherwise, insert assuming doesn't already exist QString emailsStr = find( Qtopia::Emails ); if ( emailsStr.contains( e )) return; if ( !emailsStr.isEmpty() ) emailsStr += emailSeparator(); emailsStr += e; replace( Qtopia::Emails, emailsStr ); } void OContact::removeEmail( const QString &v ) { QString e = v.simplifyWhiteSpace(); QString def = defaultEmail(); QString emailsStr = find( Qtopia::Emails ); QStringList emails = emailList(); // otherwise, must first contain it if ( !emailsStr.contains( e ) ) return; // remove it //qDebug(" removing email from list %s", e.latin1()); emails.remove( e ); // reset the string emailsStr = emails.join(emailSeparator()); // Sharp's brain dead separator replace( Qtopia::Emails, emailsStr ); // if default, then replace the default email with the first one if ( def == e ) { //qDebug("removeEmail is default; setting new default"); if ( !emails.count() ) clearEmails(); else // setDefaultEmail will remove e from the list setDefaultEmail( emails.first() ); } } void OContact::clearEmails() { mMap.remove( Qtopia::DefaultEmail ); mMap.remove( Qtopia::Emails ); } void OContact::setDefaultEmail( const QString &v ) { QString e = v.simplifyWhiteSpace(); //qDebug("OContact::setDefaultEmail %s", e.latin1()); replace( Qtopia::DefaultEmail, e ); if ( !e.isEmpty() ) insertEmail( e ); } void OContact::insertEmails( const QStringList &v ) { for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) insertEmail( *it ); } int OContact::rtti() { return OPimResolver::AddressBook; } void OContact::setUid( int i ) { OPimRecord::setUid(i); replace( Qtopia::AddressUid , QString::number(i)); } +} diff --git a/libopie2/opiepim/ocontact.h b/libopie2/opiepim/ocontact.h index 1d46b81..34888dc 100644 --- a/libopie2/opiepim/ocontact.h +++ b/libopie2/opiepim/ocontact.h @@ -1,240 +1,251 @@ -/********************************************************************** -** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. -** Copyright (C) 2002-2003 by Stefan Eilers (eilers.stefan@epost.de) -** -** This file may be distributed and/or modified under the terms of the -** GNU General Public License version 2 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -** See http://www.trolltech.com/gpl/ for GPL licensing information. -** -** Contact info@trolltech.com if any conditions of this licensing are -** not clear to you. -** -**********************************************************************/ - +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef __OCONTACT_H__ #define __OCONTACT_H__ -#include <opie/opimrecord.h> +#include <opie2/opimrecord.h> #include <qpe/recordfields.h> #include <qdatetime.h> #include <qstringlist.h> #if defined(QPC_TEMPLATEDLL) // MOC_SKIP_BEGIN QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>; // MOC_SKIP_END #endif +namespace Opie { class OContactPrivate; /** * OContact class represents a specialised PIM Record for contacts. * It does store all kind of persopn related information. * * @short Contact Container * @author TT, Stefan Eiler, Holger Freyther */ class QPC_EXPORT OContact : public OPimRecord { friend class DataSet; public: OContact(); OContact( const QMap<int, QString> &fromMap ); virtual ~OContact(); enum DateFormat{ Zip_City_State = 0, City_State_Zip }; /* * do we need to inline them * if yes do we need to inline them this way? * -zecke */ void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } void setFileAs(); // default email address void setDefaultEmail( const QString &v ); // inserts email to list and ensure's doesn't already exist void insertEmail( const QString &v ); void removeEmail( const QString &v ); void clearEmails(); void insertEmails( const QStringList &v ); // home void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); } void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); } void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); } void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); } void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); } void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); } void setHomeWebpage( const QString &v ) { replace( Qtopia::HomeWebPage, v ); } // business void setCompany( const QString &v ) { replace( Qtopia::Company, v ); } void setBusinessStreet( const QString &v ) { replace( Qtopia::BusinessStreet, v ); } void setBusinessCity( const QString &v ) { replace( Qtopia::BusinessCity, v ); } void setBusinessState( const QString &v ) { replace( Qtopia::BusinessState, v ); } void setBusinessZip( const QString &v ) { replace( Qtopia::BusinessZip, v ); } void setBusinessCountry( const QString &v ) { replace( Qtopia::BusinessCountry, v ); } void setBusinessWebpage( const QString &v ) { replace( Qtopia::BusinessWebPage, v ); } void setJobTitle( const QString &v ) { replace( Qtopia::JobTitle, v ); } void setDepartment( const QString &v ) { replace( Qtopia::Department, v ); } void setOffice( const QString &v ) { replace( Qtopia::Office, v ); } void setBusinessPhone( const QString &v ) { replace( Qtopia::BusinessPhone, v ); } void setBusinessFax( const QString &v ) { replace( Qtopia::BusinessFax, v ); } void setBusinessMobile( const QString &v ) { replace( Qtopia::BusinessMobile, v ); } void setBusinessPager( const QString &v ) { replace( Qtopia::BusinessPager, v ); } void setProfession( const QString &v ) { replace( Qtopia::Profession, v ); } void setAssistant( const QString &v ) { replace( Qtopia::Assistant, v ); } void setManager( const QString &v ) { replace( Qtopia::Manager, v ); } // personal void setSpouse( const QString &v ) { replace( Qtopia::Spouse, v ); } void setGender( const QString &v ) { replace( Qtopia::Gender, v ); } void setBirthday( const QDate &v ); void setAnniversary( const QDate &v ); void setNickname( const QString &v ) { replace( Qtopia::Nickname, v ); } void setChildren( const QString &v ); // other void setNotes( const QString &v ) { replace( Qtopia::Notes, v); } virtual bool match( const QRegExp ®exp ) const; // // custom // void setCustomField( const QString &key, const QString &v ) // { replace(Custom- + key, v ); } // name QString fullName() const; QString title() const { return find( Qtopia::Title ); } QString firstName() const { return find( Qtopia::FirstName ); } QString middleName() const { return find( Qtopia::MiddleName ); } QString lastName() const { return find( Qtopia::LastName ); } QString suffix() const { return find( Qtopia::Suffix ); } QString fileAs() const { return find( Qtopia::FileAs ); } // email QString defaultEmail() const { return find( Qtopia::DefaultEmail ); } QStringList emailList() const; // home /* * OPimAddress address(enum Location)const; * would be some how nicer... * -zecke */ QString homeStreet() const { return find( Qtopia::HomeStreet ); } QString homeCity() const { return find( Qtopia::HomeCity ); } QString homeState() const { return find( Qtopia::HomeState ); } QString homeZip() const { return find( Qtopia::HomeZip ); } QString homeCountry() const { return find( Qtopia::HomeCountry ); } QString homePhone() const { return find( Qtopia::HomePhone ); } QString homeFax() const { return find( Qtopia::HomeFax ); } QString homeMobile() const { return find( Qtopia::HomeMobile ); } QString homeWebpage() const { return find( Qtopia::HomeWebPage ); } /** Multi line string containing all non-empty address info in the form * Street * City, State Zip * Country */ QString displayHomeAddress() const; // business QString company() const { return find( Qtopia::Company ); } QString businessStreet() const { return find( Qtopia::BusinessStreet ); } QString businessCity() const { return find( Qtopia::BusinessCity ); } QString businessState() const { return find( Qtopia::BusinessState ); } QString businessZip() const { return find( Qtopia::BusinessZip ); } QString businessCountry() const { return find( Qtopia::BusinessCountry ); } QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); } QString jobTitle() const { return find( Qtopia::JobTitle ); } QString department() const { return find( Qtopia::Department ); } QString office() const { return find( Qtopia::Office ); } QString businessPhone() const { return find( Qtopia::BusinessPhone ); } QString businessFax() const { return find( Qtopia::BusinessFax ); } QString businessMobile() const { return find( Qtopia::BusinessMobile ); } QString businessPager() const { return find( Qtopia::BusinessPager ); } QString profession() const { return find( Qtopia::Profession ); } QString assistant() const { return find( Qtopia::Assistant ); } QString manager() const { return find( Qtopia::Manager ); } /** Multi line string containing all non-empty address info in the form * Street * City, State Zip * Country */ QString displayBusinessAddress() const; //personal QString spouse() const { return find( Qtopia::Spouse ); } QString gender() const { return find( Qtopia::Gender ); } QDate birthday() const; QDate anniversary() const; QString nickname() const { return find( Qtopia::Nickname ); } QString children() const { return find( Qtopia::Children ); } QStringList childrenList() const; // other QString notes() const { return find( Qtopia::Notes ); } QString groups() const { return find( Qtopia::Groups ); } QStringList groupList() const; QString toRichText() const; QMap<int, QString> toMap() const; QString field( int key ) const { return find( key ); } void setUid( int i ); QString toShortText()const; QString type()const; class QString recordField(int) const; // Why private ? (eilers,se) QString emailSeparator() const { return " "; } // the emails should be seperated by a comma void setEmails( const QString &v ); QString emails() const { return find( Qtopia::Emails ); } static int rtti(); private: // The XML Backend needs some access to the private functions friend class OContactAccessBackend_XML; void insert( int key, const QString &value ); void replace( int key, const QString &value ); QString find( int key ) const; static QStringList fields(); void save( QString &buf ) const; QString displayAddress( const QString &street, const QString &city, const QString &state, const QString &zip, const QString &country ) const; QMap<int, QString> mMap; OContactPrivate *d; }; +} #endif diff --git a/libopie2/opiepim/ocontactfields.cpp b/libopie2/opiepim/ocontactfields.cpp index 0f08a5a..deaa1e5 100644 --- a/libopie2/opiepim/ocontactfields.cpp +++ b/libopie2/opiepim/ocontactfields.cpp @@ -1,477 +1,508 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ -#include "ocontactfields.h" +#include <opie2/ocontactfields.h> #include <qstringlist.h> #include <qobject.h> // We should use our own enum in the future .. #include <qpe/recordfields.h> #include <qpe/config.h> -#include <opie/ocontact.h> +#include <opie2/ocontact.h> +namespace Opie { /*! \internal Returns a list of personal field names for a contact. */ QStringList OContactFields::personalfields( bool sorted, bool translated ) { QStringList list; QMap<int, QString> mapIdToStr; if ( translated ) mapIdToStr = idToTrFields(); else mapIdToStr = idToUntrFields(); list.append( mapIdToStr[ Qtopia::AddressUid ] ); list.append( mapIdToStr[ Qtopia::AddressCategory ] ); list.append( mapIdToStr[ Qtopia::Title ] ); list.append( mapIdToStr[ Qtopia::FirstName ] ); list.append( mapIdToStr[ Qtopia::MiddleName ] ); list.append( mapIdToStr[ Qtopia::LastName ] ); list.append( mapIdToStr[ Qtopia::Suffix ] ); list.append( mapIdToStr[ Qtopia::FileAs ] ); list.append( mapIdToStr[ Qtopia::JobTitle ] ); list.append( mapIdToStr[ Qtopia::Department ] ); list.append( mapIdToStr[ Qtopia::Company ] ); list.append( mapIdToStr[ Qtopia::Notes ] ); list.append( mapIdToStr[ Qtopia::Groups ] ); if (sorted) list.sort(); return list; } /*! \internal Returns a list of details field names for a contact. */ QStringList OContactFields::detailsfields( bool sorted, bool translated ) { QStringList list; QMap<int, QString> mapIdToStr; if ( translated ) mapIdToStr = idToTrFields(); else mapIdToStr = idToUntrFields(); list.append( mapIdToStr[ Qtopia::Office ] ); list.append( mapIdToStr[ Qtopia::Profession ] ); list.append( mapIdToStr[ Qtopia::Assistant ] ); list.append( mapIdToStr[ Qtopia::Manager ] ); list.append( mapIdToStr[ Qtopia::Spouse ] ); list.append( mapIdToStr[ Qtopia::Gender ] ); list.append( mapIdToStr[ Qtopia::Birthday ] ); list.append( mapIdToStr[ Qtopia::Anniversary ] ); list.append( mapIdToStr[ Qtopia::Nickname ] ); list.append( mapIdToStr[ Qtopia::Children ] ); if (sorted) list.sort(); return list; } /*! \internal Returns a list of phone field names for a contact. */ QStringList OContactFields::phonefields( bool sorted, bool translated ) { QStringList list; QMap<int, QString> mapIdToStr; if ( translated ) mapIdToStr = idToTrFields(); else mapIdToStr = idToUntrFields(); list.append( mapIdToStr[Qtopia::BusinessPhone] ); list.append( mapIdToStr[Qtopia::BusinessFax] ); list.append( mapIdToStr[Qtopia::BusinessMobile] ); list.append( mapIdToStr[Qtopia::BusinessPager] ); list.append( mapIdToStr[Qtopia::BusinessWebPage] ); list.append( mapIdToStr[Qtopia::DefaultEmail] ); list.append( mapIdToStr[Qtopia::Emails] ); list.append( mapIdToStr[Qtopia::HomePhone] ); list.append( mapIdToStr[Qtopia::HomeFax] ); list.append( mapIdToStr[Qtopia::HomeMobile] ); // list.append( mapIdToStr[Qtopia::HomePager] ); list.append( mapIdToStr[Qtopia::HomeWebPage] ); if (sorted) list.sort(); return list; } /*! \internal Returns a list of field names for a contact. */ QStringList OContactFields::fields( bool sorted, bool translated ) { QStringList list; QMap<int, QString> mapIdToStr; if ( translated ) mapIdToStr = idToTrFields(); else mapIdToStr = idToUntrFields(); list += personalfields( sorted, translated ); list += phonefields( sorted, translated ); list.append( mapIdToStr[Qtopia::BusinessStreet] ); list.append( mapIdToStr[Qtopia::BusinessCity] ); list.append( mapIdToStr[Qtopia::BusinessState] ); list.append( mapIdToStr[Qtopia::BusinessZip] ); list.append( mapIdToStr[Qtopia::BusinessCountry] ); list.append( mapIdToStr[Qtopia::HomeStreet] ); list.append( mapIdToStr[Qtopia::HomeCity] ); list.append( mapIdToStr[Qtopia::HomeState] ); list.append( mapIdToStr[Qtopia::HomeZip] ); list.append( mapIdToStr[Qtopia::HomeCountry] ); list += detailsfields( sorted, translated ); if (sorted) list.sort(); return list; } /*! \internal Returns an untranslated list of personal field names for a contact. */ QStringList OContactFields::untrpersonalfields( bool sorted ) { return personalfields( sorted, false ); } /*! \internal Returns a translated list of personal field names for a contact. */ QStringList OContactFields::trpersonalfields( bool sorted ) { return personalfields( sorted, true ); } /*! \internal Returns an untranslated list of details field names for a contact. */ QStringList OContactFields::untrdetailsfields( bool sorted ) { return detailsfields( sorted, false ); } /*! \internal Returns a translated list of details field names for a contact. */ QStringList OContactFields::trdetailsfields( bool sorted ) { return detailsfields( sorted, true ); } /*! \internal Returns a translated list of phone field names for a contact. */ QStringList OContactFields::trphonefields( bool sorted ) { return phonefields( sorted, true ); } /*! \internal Returns an untranslated list of phone field names for a contact. */ QStringList OContactFields::untrphonefields( bool sorted ) { return phonefields( sorted, false ); } /*! \internal Returns a translated list of field names for a contact. */ QStringList OContactFields::trfields( bool sorted ) { return fields( sorted, true ); } /*! \internal Returns an untranslated list of field names for a contact. */ QStringList OContactFields::untrfields( bool sorted ) { return fields( sorted, false ); } QMap<int, QString> OContactFields::idToTrFields() { QMap<int, QString> ret_map; ret_map.insert( Qtopia::AddressUid, QObject::tr( "User Id" ) ); ret_map.insert( Qtopia::AddressCategory, QObject::tr( "Categories" ) ); ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") ); ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) ); ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) ); ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) ); ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" )); ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) ); ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) ); ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) ); ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) ); ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) ); ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) ); ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" )); // email ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) ); ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) ); ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) ); ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) ); ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) ); // business ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) ); ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) ); ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) ); ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) ); ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) ); ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) ); ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) ); ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) ); ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) ); ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) ); ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) ); // home ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) ); ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) ); ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) ); ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) ); ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) ); ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) ); //personal ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) ); ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) ); ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) ); ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) ); ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) ); ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) ); // other ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) ); return ret_map; } QMap<int, QString> OContactFields::idToUntrFields() { QMap<int, QString> ret_map; ret_map.insert( Qtopia::AddressUid, "User Id" ); ret_map.insert( Qtopia::AddressCategory, "Categories" ); ret_map.insert( Qtopia::Title, "Name Title" ); ret_map.insert( Qtopia::FirstName, "First Name" ); ret_map.insert( Qtopia::MiddleName, "Middle Name" ); ret_map.insert( Qtopia::LastName, "Last Name" ); ret_map.insert( Qtopia::Suffix, "Suffix" ); ret_map.insert( Qtopia::FileAs, "File As" ); ret_map.insert( Qtopia::JobTitle, "Job Title" ); ret_map.insert( Qtopia::Department, "Department" ); ret_map.insert( Qtopia::Company, "Company" ); ret_map.insert( Qtopia::BusinessPhone, "Business Phone" ); ret_map.insert( Qtopia::BusinessFax, "Business Fax" ); ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" ); // email ret_map.insert( Qtopia::DefaultEmail, "Default Email" ); ret_map.insert( Qtopia::Emails, "Emails" ); ret_map.insert( Qtopia::HomePhone, "Home Phone" ); ret_map.insert( Qtopia::HomeFax, "Home Fax" ); ret_map.insert( Qtopia::HomeMobile, "Home Mobile" ); // business ret_map.insert( Qtopia::BusinessStreet, "Business Street" ); ret_map.insert( Qtopia::BusinessCity, "Business City" ); ret_map.insert( Qtopia::BusinessState, "Business State" ); ret_map.insert( Qtopia::BusinessZip, "Business Zip" ); ret_map.insert( Qtopia::BusinessCountry, "Business Country" ); ret_map.insert( Qtopia::BusinessPager, "Business Pager" ); ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" ); ret_map.insert( Qtopia::Office, "Office" ); ret_map.insert( Qtopia::Profession, "Profession" ); ret_map.insert( Qtopia::Assistant, "Assistant" ); ret_map.insert( Qtopia::Manager, "Manager" ); // home ret_map.insert( Qtopia::HomeStreet, "Home Street" ); ret_map.insert( Qtopia::HomeCity, "Home City" ); ret_map.insert( Qtopia::HomeState, "Home State" ); ret_map.insert( Qtopia::HomeZip, "Home Zip" ); ret_map.insert( Qtopia::HomeCountry, "Home Country" ); ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" ); //personal ret_map.insert( Qtopia::Spouse, "Spouse" ); ret_map.insert( Qtopia::Gender, "Gender" ); ret_map.insert( Qtopia::Birthday, "Birthday" ); ret_map.insert( Qtopia::Anniversary, "Anniversary" ); ret_map.insert( Qtopia::Nickname, "Nickname" ); ret_map.insert( Qtopia::Children, "Children" ); // other ret_map.insert( Qtopia::Notes, "Notes" ); ret_map.insert( Qtopia::Groups, "Groups" ); return ret_map; } QMap<QString, int> OContactFields::trFieldsToId() { QMap<int, QString> idtostr = idToTrFields(); QMap<QString, int> ret_map; QMap<int, QString>::Iterator it; for( it = idtostr.begin(); it != idtostr.end(); ++it ) ret_map.insert( *it, it.key() ); return ret_map; } /* ======================================================================= */ QMap<QString, int> OContactFields::untrFieldsToId() { QMap<int, QString> idtostr = idToUntrFields(); QMap<QString, int> ret_map; QMap<int, QString>::Iterator it; for( it = idtostr.begin(); it != idtostr.end(); ++it ) ret_map.insert( *it, it.key() ); return ret_map; } OContactFields::OContactFields(): fieldOrder( DEFAULT_FIELD_ORDER ), changedFieldOrder( false ) { // Get the global field order from the config file and // use it as a start pattern Config cfg ( "AddressBook" ); cfg.setGroup( "ContactFieldOrder" ); globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER ); } OContactFields::~OContactFields(){ // We will store the fieldorder into the config file // to reuse it for the future.. if ( changedFieldOrder ){ Config cfg ( "AddressBook" ); cfg.setGroup( "ContactFieldOrder" ); cfg.writeEntry( "General", globalFieldOrder ); } } void OContactFields::saveToRecord( OContact &cnt ){ qDebug("ocontactfields saveToRecord: >%s<",fieldOrder.latin1()); // Store fieldorder into this contact. cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder ); globalFieldOrder = fieldOrder; changedFieldOrder = true; } void OContactFields::loadFromRecord( const OContact &cnt ){ qDebug("ocontactfields loadFromRecord"); qDebug("loading >%s<",cnt.fullName().latin1()); // Get fieldorder for this contact. If none is defined, // we will use the global one from the config file.. fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME ); qDebug("fieldOrder from contact>%s<",fieldOrder.latin1()); if (fieldOrder.isEmpty()){ fieldOrder = globalFieldOrder; } qDebug("effective fieldOrder in loadFromRecord >%s<",fieldOrder.latin1()); } void OContactFields::setFieldOrder( int num, int index ){ qDebug("qcontactfields setfieldorder pos %i -> %i",num,index); fieldOrder[num] = QString::number( index, 16 )[0]; // We will store this new fieldorder globally to // remember it for contacts which have none globalFieldOrder = fieldOrder; changedFieldOrder = true; qDebug("fieldOrder >%s<",fieldOrder.latin1()); } int OContactFields::getFieldOrder( int num, int defIndex ){ qDebug("ocontactfields getFieldOrder"); qDebug("fieldOrder >%s<",fieldOrder.latin1()); // Get index of combo as char.. QChar poschar = fieldOrder[num]; bool ok; int ret = 0; // Convert char to number.. if ( !( poschar == QChar::null ) ) ret = QString( poschar ).toInt(&ok, 16); else ok = false; // Return default value if index for // num was not set or if anything else happened.. if ( !ok ) ret = defIndex; qDebug("returning >%i<",ret); return ret; } + +} diff --git a/libopie2/opiepim/ocontactfields.h b/libopie2/opiepim/ocontactfields.h index f105de7..993ce3b 100644 --- a/libopie2/opiepim/ocontactfields.h +++ b/libopie2/opiepim/ocontactfields.h @@ -1,67 +1,96 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_CONTACTS_FIELDS #define OPIE_CONTACTS_FIELDS class QStringList; #include <qmap.h> #include <qstring.h> -#include <opie/ocontact.h> +#include <opie2/ocontact.h> #define CONTACT_FIELD_ORDER_NAME "opie-contactfield-order" #define DEFAULT_FIELD_ORDER "__________" +namespace Opie { class OContactFields{ public: OContactFields(); ~OContactFields(); /** Set the index for combo boxes. * Sets the <b>index</b> of combo <b>num</b>. * @param num selects the number of the combo * @param index sets the index in the combo */ void setFieldOrder( int num, int index ); /** Get the index for combo boxes. * Returns the index of combo <b>num</b> or defindex * if none was defined.. * @param num Selects the number of the combo * @param defIndex will be returned if none was defined (either * globally in the config file, nor by the contact which was used * by loadFromRecord() ) */ int getFieldOrder( int num, int defIndex); /** Store fieldorder to contact. */ void saveToRecord( OContact& ); /** Get Fieldorder from contact. */ void loadFromRecord( const OContact& ); private: QString fieldOrder; QString globalFieldOrder; bool changedFieldOrder; public: static QStringList personalfields( bool sorted = true, bool translated = false ); static QStringList phonefields( bool sorted = true, bool translated = false ); static QStringList detailsfields( bool sorted = true, bool translated = false ); static QStringList fields( bool sorted = true, bool translated = false ); static QStringList trpersonalfields( bool sorted = true ); static QStringList untrpersonalfields( bool sorted = true ); static QStringList trphonefields( bool sorted = true ); static QStringList untrphonefields( bool sorted = true ); static QStringList trdetailsfields( bool sorted = true ); static QStringList untrdetailsfields( bool sorted = true ); static QStringList trfields( bool sorted = true ); static QStringList untrfields( bool sorted = true ); static QMap<int, QString> idToTrFields(); static QMap<QString, int> trFieldsToId(); static QMap<int, QString> idToUntrFields(); static QMap<QString, int> untrFieldsToId(); }; - +} #endif diff --git a/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp index 9b31957..de5e30b 100644 --- a/libopie2/opiepim/oevent.cpp +++ b/libopie2/opiepim/oevent.cpp @@ -1,717 +1,749 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <qshared.h> #include <qarray.h> #include <qpe/palmtopuidgen.h> #include <qpe/categories.h> #include <qpe/stringutil.h> -#include "orecur.h" -#include "opimresolver.h" -#include "opimnotifymanager.h" +#include <opie2/orecur.h> +#include <opie2/opimresolver.h> +#include <opie2/opimnotifymanager.h> + +#include <opie2/oevent.h> -#include "oevent.h" +namespace Opie { int OCalendarHelper::week( const QDate& date) { // Calculates the week this date is in within that // month. Equals the "row" is is in in the month view int week = 1; QDate tmp( date.year(), date.month(), 1 ); if ( date.dayOfWeek() < tmp.dayOfWeek() ) ++week; week += ( date.day() - 1 ) / 7; return week; } int OCalendarHelper::ocurrence( const QDate& date) { // calculates the number of occurrances of this day of the // week till the given date (e.g 3rd Wednesday of the month) return ( date.day() - 1 ) / 7 + 1; } int OCalendarHelper::dayOfWeek( char day ) { int dayOfWeek = 1; char i = ORecur::MON; while ( !( i & day ) && i <= ORecur::SUN ) { i <<= 1; ++dayOfWeek; } return dayOfWeek; } int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { return ( second.year() - first.year() ) * 12 + second.month() - first.month(); } struct OEvent::Data : public QShared { Data() : QShared() { child = 0; recur = 0; manager = 0; isAllDay = false; parent = 0; } ~Data() { delete manager; delete recur; } QString description; QString location; OPimNotifyManager* manager; ORecur* recur; QString note; QDateTime created; QDateTime start; QDateTime end; bool isAllDay : 1; QString timezone; QArray<int>* child; int parent; }; OEvent::OEvent( int uid ) : OPimRecord( uid ) { data = new Data; } OEvent::OEvent( const OEvent& ev) : OPimRecord( ev ), data( ev.data ) { data->ref(); } OEvent::OEvent( const QMap<int, QString> map ) : OPimRecord( 0 ) { data = new Data; fromMap( map ); } OEvent::~OEvent() { if ( data->deref() ) { delete data; data = 0; } } OEvent& OEvent::operator=( const OEvent& ev) { if ( this == &ev ) return *this; OPimRecord::operator=( ev ); ev.data->ref(); deref(); data = ev.data; return *this; } QString OEvent::description()const { return data->description; } void OEvent::setDescription( const QString& description ) { changeOrModify(); data->description = description; } void OEvent::setLocation( const QString& loc ) { changeOrModify(); data->location = loc; } QString OEvent::location()const { return data->location; } OPimNotifyManager &OEvent::notifiers()const { // I hope we can skip the changeOrModify here // the notifier should take care of it // and OPimNotify is shared too if (!data->manager ) data->manager = new OPimNotifyManager; return *data->manager; } bool OEvent::hasNotifiers()const { if (!data->manager ) return false; if (data->manager->reminders().isEmpty() && data->manager->alarms().isEmpty() ) return false; return true; } ORecur OEvent::recurrence()const { if (!data->recur) data->recur = new ORecur; return *data->recur; } void OEvent::setRecurrence( const ORecur& rec) { changeOrModify(); if (data->recur ) (*data->recur) = rec; else data->recur = new ORecur( rec ); } bool OEvent::hasRecurrence()const { if (!data->recur ) return false; return data->recur->doesRecur(); } QString OEvent::note()const { return data->note; } void OEvent::setNote( const QString& note ) { changeOrModify(); data->note = note; } QDateTime OEvent::createdDateTime()const { return data->created; } void OEvent::setCreatedDateTime( const QDateTime& time ) { changeOrModify(); data->created = time; } QDateTime OEvent::startDateTime()const { if ( data->isAllDay ) return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); return data->start; } QDateTime OEvent::startDateTimeInZone()const { /* if no timezone, or all day event or if the current and this timeZone match... */ if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); OTimeZone zone(data->timezone ); return zone.toDateTime( data->start, OTimeZone::current() ); } void OEvent::setStartDateTime( const QDateTime& dt ) { changeOrModify(); data->start = dt; } QDateTime OEvent::endDateTime()const { /* * if all Day event the end time needs * to be on the same day as the start */ if ( data->isAllDay ) return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); return data->end; } QDateTime OEvent::endDateTimeInZone()const { /* if no timezone, or all day event or if the current and this timeZone match... */ if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); OTimeZone zone(data->timezone ); return zone.toDateTime( data->end, OTimeZone::current() ); } void OEvent::setEndDateTime( const QDateTime& dt ) { changeOrModify(); data->end = dt; } bool OEvent::isMultipleDay()const { return data->end.date().day() - data->start.date().day(); } bool OEvent::isAllDay()const { return data->isAllDay; } void OEvent::setAllDay( bool allDay ) { changeOrModify(); data->isAllDay = allDay; if (allDay ) data->timezone = "UTC"; } void OEvent::setTimeZone( const QString& tz ) { changeOrModify(); data->timezone = tz; } QString OEvent::timeZone()const { if (data->isAllDay ) return QString::fromLatin1("UTC"); return data->timezone; } bool OEvent::match( const QRegExp& re )const { if ( re.match( data->description ) != -1 ){ setLastHitField( Qtopia::DatebookDescription ); return true; } if ( re.match( data->note ) != -1 ){ setLastHitField( Qtopia::Note ); return true; } if ( re.match( data->location ) != -1 ){ setLastHitField( Qtopia::Location ); return true; } if ( re.match( data->start.toString() ) != -1 ){ setLastHitField( Qtopia::StartDateTime ); return true; } if ( re.match( data->end.toString() ) != -1 ){ setLastHitField( Qtopia::EndDateTime ); return true; } return false; } QString OEvent::toRichText()const { QString text, value; // description text += "<b><h3><img src=\"datebook/DateBook\">"; if ( !description().isEmpty() ) { text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "" ); } text += "</h3></b><br><hr><br>"; // location if ( !(value = location()).isEmpty() ) { text += "<b>" + QObject::tr( "Location:" ) + "</b> "; text += Qtopia::escapeString(value) + "<br>"; } // all day event if ( isAllDay() ) { text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>"; } // multiple day event else if ( isMultipleDay () ) { text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>"; } // start & end times else { // start time if ( startDateTime().isValid() ) { text += "<b>" + QObject::tr( "Start:") + "</b> "; text += Qtopia::escapeString(startDateTime().toString() ). replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; } // end time if ( endDateTime().isValid() ) { text += "<b>" + QObject::tr( "End:") + "</b> "; text += Qtopia::escapeString(endDateTime().toString() ). replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; } } // categories if ( categoryNames("Calendar").count() ){ text += "<b>" + QObject::tr( "Category:") + "</b> "; text += categoryNames("Calendar").join(", "); text += "<br>"; } //notes if ( !note().isEmpty() ) { text += "<b>" + QObject::tr( "Note:") + "</b><br>"; text += note(); // text += Qtopia::escapeString(note() ). // replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; } return text; } QString OEvent::toShortText()const { QString text; text += QString::number( startDateTime().date().day() ); text += "."; text += QString::number( startDateTime().date().month() ); text += "."; text += QString::number( startDateTime().date().year() ); text += " "; text += QString::number( startDateTime().time().hour() ); text += ":"; text += QString::number( startDateTime().time().minute() ); text += " - "; text += description(); return text; } QString OEvent::type()const { return QString::fromLatin1("OEvent"); } QString OEvent::recordField( int /*id */ )const { return QString::null; } int OEvent::rtti() { return OPimResolver::DateBook; } bool OEvent::loadFromStream( QDataStream& ) { return true; } bool OEvent::saveToStream( QDataStream& )const { return true; } void OEvent::changeOrModify() { if ( data->count != 1 ) { data->deref(); Data* d2 = new Data; d2->description = data->description; d2->location = data->location; if (data->manager ) d2->manager = new OPimNotifyManager( *data->manager ); if ( data->recur ) d2->recur = new ORecur( *data->recur ); d2->note = data->note; d2->created = data->created; d2->start = data->start; d2->end = data->end; d2->isAllDay = data->isAllDay; d2->timezone = data->timezone; d2->parent = data->parent; if ( data->child ) { d2->child = new QArray<int>( *data->child ); d2->child->detach(); } data = d2; } } void OEvent::deref() { if ( data->deref() ) { delete data; data = 0; } } // Exporting Event data to map. Using the same // encoding as ODateBookAccessBackend_xml does.. // Thus, we could remove the stuff there and use this // for it and for all other places.. // Encoding should happen at one place, only ! (eilers) QMap<int, QString> OEvent::toMap()const { QMap<int, QString> retMap; retMap.insert( OEvent::FUid, QString::number( uid() ) ); retMap.insert( OEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) )); retMap.insert( OEvent::FDescription, Qtopia::escapeString( description() ) ); retMap.insert( OEvent::FLocation, Qtopia::escapeString( location() ) ); retMap.insert( OEvent::FType, isAllDay() ? "AllDay" : "" ); OPimAlarm alarm = notifiers().alarms()[0]; retMap.insert( OEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); retMap.insert( OEvent::FSound, (alarm.sound() == OPimAlarm::Loud) ? "loud" : "silent" ); OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); retMap.insert( OEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OTimeZone::utc() ) ) ) ); retMap.insert( OEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OTimeZone::utc() ) ) ) ); retMap.insert( OEvent::FNote, Qtopia::escapeString( note() ) ); retMap.insert( OEvent::FTimeZone, timeZone().isEmpty() ? QString( "None" ) : timeZone() ); if( parent() ) retMap.insert( OEvent::FRecParent, QString::number( parent() ) ); if( children().count() ){ QArray<int> childr = children(); QString buf; for ( uint i = 0; i < childr.count(); i++ ) { if ( i != 0 ) buf += " "; buf += QString::number( childr[i] ); } retMap.insert( OEvent::FRecChildren, buf ); } // Add recurrence stuff if( hasRecurrence() ){ ORecur recur = recurrence(); QMap<int, QString> recFields = recur.toMap(); retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); retMap.insert( OEvent::FRWeekdays, recFields[ORecur::RWeekdays] ); retMap.insert( OEvent::FRPosition, recFields[ORecur::RPosition] ); retMap.insert( OEvent::FRFreq, recFields[ORecur::RFreq] ); retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] ); retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] ); retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] ); retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] ); } else { ORecur recur = recurrence(); QMap<int, QString> recFields = recur.toMap(); retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); } return retMap; } void OEvent::fromMap( const QMap<int, QString>& map ) { // We just want to set the UID if it is really stored. if ( !map[OEvent::FUid].isEmpty() ) setUid( map[OEvent::FUid].toInt() ); setCategories( idsFromString( map[OEvent::FCategories] ) ); setDescription( map[OEvent::FDescription] ); setLocation( map[OEvent::FLocation] ); if ( map[OEvent::FType] == "AllDay" ) setAllDay( true ); else setAllDay( false ); int alarmTime = -1; if( !map[OEvent::FAlarm].isEmpty() ) alarmTime = map[OEvent::FAlarm].toInt(); int sound = ( ( map[OEvent::FSound] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent ); if ( ( alarmTime != -1 ) ){ QDateTime dt = startDateTime().addSecs( -1*alarmTime*60 ); OPimAlarm al( sound , dt ); notifiers().add( al ); } if ( !map[OEvent::FTimeZone].isEmpty() && ( map[OEvent::FTimeZone] != "None" ) ){ setTimeZone( map[OEvent::FTimeZone] ); } time_t start = (time_t) map[OEvent::FStart].toLong(); time_t end = (time_t) map[OEvent::FEnd].toLong(); /* AllDay is always in UTC */ if ( isAllDay() ) { OTimeZone utc = OTimeZone::utc(); setStartDateTime( utc.fromUTCDateTime( start ) ); setEndDateTime ( utc.fromUTCDateTime( end ) ); setTimeZone( "UTC"); // make sure it is really utc }else { /* to current date time */ // qWarning(" Start is %d", start ); OTimeZone zone( timeZone().isEmpty() ? OTimeZone::current() : timeZone() ); QDateTime date = zone.toDateTime( start ); qWarning(" Start is %s", date.toString().latin1() ); setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); date = zone.toDateTime( end ); setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); } if ( !map[OEvent::FRecParent].isEmpty() ) setParent( map[OEvent::FRecParent].toInt() ); if ( !map[OEvent::FRecChildren].isEmpty() ){ QStringList list = QStringList::split(' ', map[OEvent::FRecChildren] ); for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { addChild( (*it).toInt() ); } } // Fill recurrence stuff and put it directly into the ORecur-Object using fromMap.. if( !map[OEvent::FRType].isEmpty() ){ QMap<int, QString> recFields; recFields.insert( ORecur::RType, map[OEvent::FRType] ); recFields.insert( ORecur::RWeekdays, map[OEvent::FRWeekdays] ); recFields.insert( ORecur::RPosition, map[OEvent::FRPosition] ); recFields.insert( ORecur::RFreq, map[OEvent::FRFreq] ); recFields.insert( ORecur::RHasEndDate, map[OEvent::FRHasEndDate] ); recFields.insert( ORecur::EndDate, map[OEvent::FREndDate] ); recFields.insert( ORecur::Created, map[OEvent::FRCreated] ); recFields.insert( ORecur::Exceptions, map[OEvent::FRExceptions] ); ORecur recur( recFields ); setRecurrence( recur ); } } int OEvent::parent()const { return data->parent; } void OEvent::setParent( int uid ) { changeOrModify(); data->parent = uid; } QArray<int> OEvent::children() const{ if (!data->child) return QArray<int>(); else return data->child->copy(); } void OEvent::setChildren( const QArray<int>& arr ) { changeOrModify(); if (data->child) delete data->child; data->child = new QArray<int>( arr ); data->child->detach(); } void OEvent::addChild( int uid ) { changeOrModify(); if (!data->child ) { data->child = new QArray<int>(1); (*data->child)[0] = uid; }else{ int count = data->child->count(); data->child->resize( count + 1 ); (*data->child)[count] = uid; } } void OEvent::removeChild( int uid ) { if (!data->child || !data->child->contains( uid ) ) return; changeOrModify(); QArray<int> newAr( data->child->count() - 1 ); int j = 0; uint count = data->child->count(); for ( uint i = 0; i < count; i++ ) { if ( (*data->child)[i] != uid ) { newAr[j] = (*data->child)[i]; j++; } } (*data->child) = newAr; } struct OEffectiveEvent::Data : public QShared { Data() : QShared() { } OEvent event; QDate date; QTime start, end; QDate startDate, endDate; bool dates : 1; }; OEffectiveEvent::OEffectiveEvent() { data = new Data; data->date = QDate::currentDate(); data->start = data->end = QTime::currentTime(); data->dates = false; } OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, Position pos ) { data = new Data; data->event = ev; data->date = startDate; if ( pos & Start ) data->start = ev.startDateTime().time(); else data->start = QTime( 0, 0, 0 ); if ( pos & End ) data->end = ev.endDateTime().time(); else data->end = QTime( 23, 59, 59 ); data->dates = false; } OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { data = ev.data; data->ref(); } OEffectiveEvent::~OEffectiveEvent() { if ( data->deref() ) { delete data; data = 0; } } OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { if ( *this == ev ) return *this; ev.data->ref(); deref(); data = ev.data; return *this; } void OEffectiveEvent::setStartTime( const QTime& ti) { changeOrModify(); data->start = ti; } void OEffectiveEvent::setEndTime( const QTime& en) { changeOrModify(); data->end = en; } void OEffectiveEvent::setEvent( const OEvent& ev) { changeOrModify(); data->event = ev; } void OEffectiveEvent::setDate( const QDate& da) { changeOrModify(); data->date = da; } void OEffectiveEvent::setEffectiveDates( const QDate& from, const QDate& to ) { if (!from.isValid() ) { data->dates = false; return; } data->startDate = from; data->endDate = to; } QString OEffectiveEvent::description()const { return data->event.description(); } QString OEffectiveEvent::location()const { return data->event.location(); } QString OEffectiveEvent::note()const { return data->event.note(); } OEvent OEffectiveEvent::event()const { return data->event; } QTime OEffectiveEvent::startTime()const { return data->start; } QTime OEffectiveEvent::endTime()const { return data->end; } QDate OEffectiveEvent::date()const { return data->date; } int OEffectiveEvent::length()const { return (data->end.hour() * 60 - data->start.hour() * 60) + QABS(data->start.minute() - data->end.minute() ); } int OEffectiveEvent::size()const { return ( data->end.hour() - data->start.hour() ) * 3600 + (data->end.minute() - data->start.minute() * 60 + data->end.second() - data->start.second() ); } QDate OEffectiveEvent::startDate()const { if ( data->dates ) return data->startDate; else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer return data->date; else return data->event.startDateTime().date(); } QDate OEffectiveEvent::endDate()const { if ( data->dates ) return data->endDate; else if ( data->event.hasRecurrence() ) return data->date; else return data->event.endDateTime().date(); } void OEffectiveEvent::deref() { if ( data->deref() ) { delete data; data = 0; } } void OEffectiveEvent::changeOrModify() { if ( data->count != 1 ) { data->deref(); Data* d2 = new Data; d2->event = data->event; d2->date = data->date; d2->start = data->start; d2->end = data->end; d2->startDate = data->startDate; d2->endDate = data->endDate; d2->dates = data->dates; data = d2; } } bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{ if ( data->date < e.date() ) return TRUE; if ( data->date == e.date() ) return ( startTime() < e.startTime() ); else return FALSE; } bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const{ return (data->date <= e.date() ); } bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const { return ( date() == e.date() && startTime() == e.startTime() && endTime()== e.endTime() && event() == e.event() ); } bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const { return !(*this == e ); } bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const { return !(*this <= e ); } bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const { return !(*this < e); } + +} diff --git a/libopie2/opiepim/oevent.h b/libopie2/opiepim/oevent.h index 9eb948f..9502efa 100644 --- a/libopie2/opiepim/oevent.h +++ b/libopie2/opiepim/oevent.h @@ -1,236 +1,268 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ // CONTAINS GPLed code of TT #ifndef OPIE_PIM_EVENT_H #define OPIE_PIM_EVENT_H #include <qstring.h> #include <qdatetime.h> #include <qvaluelist.h> #include <qpe/recordfields.h> #include <qpe/palmtopuidgen.h> -#include "otimezone.h" -#include "opimrecord.h" +#include <opie2/otimezone.h> +#include <opie2/opimrecord.h> +namespace Opie { struct OCalendarHelper { /** calculate the week number of the date */ static int week( const QDate& ); /** calculate the occurence of week days since the start of the month */ static int ocurrence( const QDate& ); // returns the dayOfWeek for the *first* day it finds (ignores // any further days!). Returns 1 (Monday) if there isn't any day found static int dayOfWeek( char day ); /** returns the diff of month */ static int monthDiff( const QDate& first, const QDate& second ); }; class OPimNotifyManager; class ORecur; /** * This is the container for all Events. It encapsules all * available information for a single Event * @short container for events. */ class OEvent : public OPimRecord { public: typedef QValueList<OEvent> ValueList; /** * RecordFields contain possible attributes * used in the Results of toMap().. */ enum RecordFields { FUid = Qtopia::UID_ID, FCategories = Qtopia::CATEGORY_ID, FDescription = 0, FLocation, FType, FAlarm, FSound, FRType, FRWeekdays, FRPosition, FRFreq, FRHasEndDate, FREndDate, FRCreated, FRExceptions, FStart, FEnd, FNote, FTimeZone, FRecParent, FRecChildren, }; /** * Start with an Empty OEvent. UID == 0 means that it is empty */ OEvent(int uid = 0); /** * copy c'tor */ OEvent( const OEvent& ); /** * Create OEvent, initialized by map * @see enum RecordFields */ OEvent( const QMap<int, QString> map ); ~OEvent(); OEvent &operator=( const OEvent& ); QString description()const; void setDescription( const QString& description ); QString location()const; void setLocation( const QString& loc ); bool hasNotifiers()const; OPimNotifyManager ¬ifiers()const; ORecur recurrence()const; void setRecurrence( const ORecur& ); bool hasRecurrence()const; QString note()const; void setNote( const QString& note ); QDateTime createdDateTime()const; void setCreatedDateTime( const QDateTime& dt); /** set the date to dt. dt is the QDateTime in localtime */ void setStartDateTime( const QDateTime& ); /** returns the datetime in the local timeZone */ QDateTime startDateTime()const; /** returns the start datetime in the current zone */ QDateTime startDateTimeInZone()const; /** in current timezone */ void setEndDateTime( const QDateTime& ); /** in current timezone */ QDateTime endDateTime()const; QDateTime endDateTimeInZone()const; bool isMultipleDay()const; bool isAllDay()const; void setAllDay( bool isAllDay ); /* pin this event to a timezone! FIXME */ void setTimeZone( const QString& timeZone ); QString timeZone()const; virtual bool match( const QRegExp& )const; /** For exception to recurrence here is a list of children... */ QArray<int> children()const; void setChildren( const QArray<int>& ); void addChild( int uid ); void removeChild( int uid ); /** return the parent OEvent */ int parent()const; void setParent( int uid ); /* needed reimp */ QString toRichText()const; QString toShortText()const; QString type()const; QMap<int, QString> toMap()const; void fromMap( const QMap<int, QString>& map ); QString recordField(int )const; static int rtti(); bool loadFromStream( QDataStream& ); bool saveToStream( QDataStream& )const; /* bool operator==( const OEvent& ); bool operator!=( const OEvent& ); bool operator<( const OEvent& ); bool operator<=( const OEvent& ); bool operator>( const OEvent& ); bool operator>=(const OEvent& ); */ private: inline void changeOrModify(); void deref(); struct Data; Data* data; class Private; Private* priv; }; /** * AN Event can span through multiple days. We split up a multiday eve */ class OEffectiveEvent { public: typedef QValueList<OEffectiveEvent> ValueList; enum Position { MidWay, Start, End, StartEnd }; // If we calculate the effective event of a multi-day event // we have to figure out whether we are at the first day, // at the end, or anywhere else ("middle"). This is important // for the start/end times (00:00/23:59) // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- // day event // Start: start time -> 23:59 // End: 00:00 -> end time // Start | End == StartEnd: for single-day events (default) // here we draw start time -> end time OEffectiveEvent(); OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd ); OEffectiveEvent( const OEffectiveEvent& ); OEffectiveEvent &operator=(const OEffectiveEvent& ); ~OEffectiveEvent(); void setStartTime( const QTime& ); void setEndTime( const QTime& ); void setEvent( const OEvent& ); void setDate( const QDate& ); void setEffectiveDates( const QDate& from, const QDate& to ); QString description()const; QString location()const; QString note()const; OEvent event()const; QTime startTime()const; QTime endTime()const; QDate date()const; /* return the length in hours */ int length()const; int size()const; QDate startDate()const; QDate endDate()const; bool operator<( const OEffectiveEvent &e ) const; bool operator<=( const OEffectiveEvent &e ) const; bool operator==( const OEffectiveEvent &e ) const; bool operator!=( const OEffectiveEvent &e ) const; bool operator>( const OEffectiveEvent &e ) const; bool operator>= ( const OEffectiveEvent &e ) const; private: void deref(); inline void changeOrModify(); class Private; Private* priv; struct Data; Data* data; }; + +} + #endif diff --git a/libopie2/opiepim/opiepim.pro b/libopie2/opiepim/opiepim.pro index 3972c3f..82737f4 100644 --- a/libopie2/opiepim/opiepim.pro +++ b/libopie2/opiepim/opiepim.pro @@ -1,24 +1,30 @@ TEMPLATE = lib CONFIG += qt warn_on debug DESTDIR = $(OPIEDIR)/lib -HEADERS = +HEADERS = ocontact.h ocontactfields.h opimrecord.h otodo.h opimnotify.h opimnotifymanager.h oevent.h -SOURCES = +SOURCES = ocontact.cpp ocontactfields.cpp opimrecord.cpp otodo.cpp opimnotify.cpp \ + opimnotifymanager.cpp oevent.cpp INTERFACES = TARGET = opiepim2 VERSION = 1.8.2 INCLUDEPATH += $(OPIEDIR)/include DEPENDPATH += $(OPIEDIR)/include +include ( core/core.pro ) +include ( core/backends/backends.pro ) +include ( ui/ui.pro ) + MOC_DIR = moc OBJECTS_DIR = obj !contains( platform, x11 ) { include ( $(OPIEDIR)/include.pro ) } contains( platform, x11 ) { LIBS = -L$(OPIEDIR)/lib -Wl,-rpath,$(OPIEDIR)/lib } +LIBS += -lopiecore2 diff --git a/libopie2/opiepim/orecordlist.h b/libopie2/opiepim/orecordlist.h index 5211f57..8f0011b 100644 --- a/libopie2/opiepim/orecordlist.h +++ b/libopie2/opiepim/orecordlist.h @@ -1,306 +1,336 @@ +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_RECORD_LIST_H #define OPIE_RECORD_LIST_H #include <qarray.h> -#include "otemplatebase.h" -#include "opimrecord.h" +#include <opie2/otemplatebase.h> +#include <opie2/opimrecord.h> + +namespace Opie { class ORecordListIteratorPrivate; /** * Our List Iterator * it behaves like STL or Qt * * for(it = list.begin(); it != list.end(); ++it ) * doSomeCoolStuff( (*it) ); */ template <class T> class ORecordList; template <class T = OPimRecord> class ORecordListIterator { friend class ORecordList<T>; public: typedef OTemplateBase<T> Base; /** * The c'tor used internally from * ORecordList */ ORecordListIterator( const QArray<int>, const Base* ); /** * The standard c'tor */ ORecordListIterator(); ~ORecordListIterator(); ORecordListIterator( const ORecordListIterator& ); ORecordListIterator &operator=(const ORecordListIterator& ); /** * a * operator ;) * use it like this T = (*it); */ T operator*(); ORecordListIterator &operator++(); ORecordListIterator &operator--(); bool operator==( const ORecordListIterator& it ); bool operator!=( const ORecordListIterator& it ); /** * the current item */ uint current()const; /** * the number of items */ uint count()const; /** * sets the current item */ void setCurrent( uint cur ); private: QArray<int> m_uids; uint m_current; const Base* m_temp; bool m_end : 1; T m_record; bool m_direction :1; /* d pointer for future versions */ ORecordListIteratorPrivate *d; }; class ORecordListPrivate; /** * The recordlist used as a return type * from OPimAccessTemplate */ template <class T = OPimRecord > class ORecordList { public: typedef OTemplateBase<T> Base; typedef ORecordListIterator<T> Iterator; /** * c'tor */ ORecordList () { } ORecordList( const QArray<int>& ids, const Base* ); ~ORecordList(); /** * the first iterator */ Iterator begin(); /** * the end */ Iterator end(); /** * the number of items in the list */ uint count()const; T operator[]( uint i ); int uidAt(uint i ); /** * Remove the contact with given uid */ bool remove( int uid ); /* ConstIterator begin()const; ConstIterator end()const; */ private: QArray<int> m_ids; const Base* m_acc; ORecordListPrivate *d; }; /* ok now implement it */ template <class T> ORecordListIterator<T>::ORecordListIterator() { m_current = 0; m_temp = 0l; m_end = true; m_record = T(); /* forward */ m_direction = TRUE; } template <class T> ORecordListIterator<T>::~ORecordListIterator() { /* nothing to delete */ } template <class T> ORecordListIterator<T>::ORecordListIterator( const ORecordListIterator<T>& it) { // qWarning("ORecordListIterator copy c'tor"); m_uids = it.m_uids; m_current = it.m_current; m_temp = it.m_temp; m_end = it.m_end; m_record = it.m_record; m_direction = it.m_direction; } template <class T> ORecordListIterator<T> &ORecordListIterator<T>::operator=( const ORecordListIterator<T>& it) { m_uids = it.m_uids; m_current = it.m_current; m_temp = it.m_temp; m_end = it.m_end; m_record = it.m_record; return *this; } template <class T> T ORecordListIterator<T>::operator*() { //qWarning("operator* %d %d", m_current, m_uids[m_current] ); if (!m_end ) m_record = m_temp->find( m_uids[m_current], m_uids, m_current, m_direction ? Base::Forward : Base::Reverse ); else m_record = T(); return m_record; } template <class T> ORecordListIterator<T> &ORecordListIterator<T>::operator++() { m_direction = true; if (m_current < m_uids.count() ) { m_end = false; ++m_current; }else m_end = true; return *this; } template <class T> ORecordListIterator<T> &ORecordListIterator<T>::operator--() { m_direction = false; if ( m_current > 0 ) { --m_current; m_end = false; } else m_end = true; return *this; } template <class T> bool ORecordListIterator<T>::operator==( const ORecordListIterator<T>& it ) { /* if both are at we're the same.... */ if ( m_end == it.m_end ) return true; if ( m_uids != it.m_uids ) return false; if ( m_current != it.m_current ) return false; if ( m_temp != it.m_temp ) return false; return true; } template <class T> bool ORecordListIterator<T>::operator!=( const ORecordListIterator<T>& it ) { return !(*this == it ); } template <class T> ORecordListIterator<T>::ORecordListIterator( const QArray<int> uids, const Base* t ) : m_uids( uids ), m_current( 0 ), m_temp( t ), m_end( false ), m_direction( false ) { /* if the list is empty we're already at the end of the list */ if (uids.count() == 0 ) m_end = true; } template <class T> uint ORecordListIterator<T>::current()const { return m_current; } template <class T> void ORecordListIterator<T>::setCurrent( uint cur ) { if( cur < m_uids.count() ) { m_end = false; m_current= cur; } } template <class T> uint ORecordListIterator<T>::count()const { return m_uids.count(); } template <class T> ORecordList<T>::ORecordList( const QArray<int>& ids, const Base* acc ) : m_ids( ids ), m_acc( acc ) { } template <class T> ORecordList<T>::~ORecordList() { /* nothing to do here */ } template <class T> typename ORecordList<T>::Iterator ORecordList<T>::begin() { Iterator it( m_ids, m_acc ); return it; } template <class T> typename ORecordList<T>::Iterator ORecordList<T>::end() { Iterator it( m_ids, m_acc ); it.m_end = true; it.m_current = m_ids.count(); return it; } template <class T> uint ORecordList<T>::count()const { return m_ids.count(); } template <class T> T ORecordList<T>::operator[]( uint i ) { if ( i >= m_ids.count() ) return T(); /* forward */ return m_acc->find( m_ids[i], m_ids, i ); } template <class T> int ORecordList<T>::uidAt( uint i ) { return m_ids[i]; } template <class T> bool ORecordList<T>::remove( int uid ) { QArray<int> copy( m_ids.count() ); int counter = 0; bool ret_val = false; for (uint i = 0; i < m_ids.count(); i++){ if ( m_ids[i] != uid ){ copy[counter++] = m_ids[i]; }else ret_val = true; } copy.resize( counter ); m_ids = copy; return ret_val; } - +} #endif diff --git a/libopie2/opiepim/otodo.cpp b/libopie2/opiepim/otodo.cpp index 189bf94..3eb0026 100644 --- a/libopie2/opiepim/otodo.cpp +++ b/libopie2/opiepim/otodo.cpp @@ -1,520 +1,550 @@ - +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <qobject.h> #include <qshared.h> #include <qpe/palmtopuidgen.h> #include <qpe/stringutil.h> #include <qpe/palmtoprecord.h> #include <qpe/stringutil.h> #include <qpe/categories.h> #include <qpe/categoryselect.h> -#include "opimstate.h" -#include "orecur.h" -#include "opimmaintainer.h" -#include "opimnotifymanager.h" -#include "opimresolver.h" +#include <opie2/opimstate.h> +#include <opie2/orecur.h> +#include <opie2/opimmaintainer.h> +#include <opie2/opimnotifymanager.h> +#include <opie2/opimresolver.h> -#include "otodo.h" +#include <opie2/otodo.h> +namespace Opie { struct OTodo::OTodoData : public QShared { OTodoData() : QShared() { recur = 0; state = 0; maintainer = 0; notifiers = 0; }; ~OTodoData() { delete recur; delete maintainer; delete notifiers; } QDate date; bool isCompleted:1; bool hasDate:1; int priority; QString desc; QString sum; QMap<QString, QString> extra; ushort prog; OPimState *state; ORecur *recur; OPimMaintainer *maintainer; QDate start; QDate completed; OPimNotifyManager *notifiers; }; OTodo::OTodo(const OTodo &event ) : OPimRecord( event ), data( event.data ) { data->ref(); // qWarning("ref up"); } OTodo::~OTodo() { // qWarning("~OTodo " ); if ( data->deref() ) { // qWarning("OTodo::dereffing"); delete data; data = 0l; } } OTodo::OTodo(bool completed, int priority, const QArray<int> &category, const QString& summary, const QString &description, ushort progress, bool hasDate, QDate date, int uid ) : OPimRecord( uid ) { // qWarning("OTodoData " + summary); setCategories( category ); data = new OTodoData; data->date = date; data->isCompleted = completed; data->hasDate = hasDate; data->priority = priority; data->sum = summary; data->prog = progress; data->desc = Qtopia::simplifyMultiLineSpace(description ); } OTodo::OTodo(bool completed, int priority, const QStringList &category, const QString& summary, const QString &description, ushort progress, bool hasDate, QDate date, int uid ) : OPimRecord( uid ) { // qWarning("OTodoData" + summary); setCategories( idsFromString( category.join(";") ) ); data = new OTodoData; data->date = date; data->isCompleted = completed; data->hasDate = hasDate; data->priority = priority; data->sum = summary; data->prog = progress; data->desc = Qtopia::simplifyMultiLineSpace(description ); } bool OTodo::match( const QRegExp ®Exp )const { if( QString::number( data->priority ).find( regExp ) != -1 ){ setLastHitField( Priority ); return true; }else if( data->hasDate && data->date.toString().find( regExp) != -1 ){ setLastHitField( HasDate ); return true; }else if(data->desc.find( regExp ) != -1 ){ setLastHitField( Description ); return true; }else if(data->sum.find( regExp ) != -1 ) { setLastHitField( Summary ); return true; } return false; } bool OTodo::isCompleted() const { return data->isCompleted; } bool OTodo::hasDueDate() const { return data->hasDate; } bool OTodo::hasStartDate()const { return data->start.isValid(); } bool OTodo::hasCompletedDate()const { return data->completed.isValid(); } int OTodo::priority()const { return data->priority; } QString OTodo::summary() const { return data->sum; } ushort OTodo::progress() const { return data->prog; } QDate OTodo::dueDate()const { return data->date; } QDate OTodo::startDate()const { return data->start; } QDate OTodo::completedDate()const { return data->completed; } QString OTodo::description()const { return data->desc; } bool OTodo::hasState() const{ if (!data->state ) return false; return ( data->state->state() != OPimState::Undefined ); } OPimState OTodo::state()const { if (!data->state ) { OPimState state; return state; } return (*data->state); } bool OTodo::hasRecurrence()const { if (!data->recur) return false; return data->recur->doesRecur(); } ORecur OTodo::recurrence()const { if (!data->recur) return ORecur(); return (*data->recur); } bool OTodo::hasMaintainer()const { if (!data->maintainer) return false; return (data->maintainer->mode() != OPimMaintainer::Undefined ); } OPimMaintainer OTodo::maintainer()const { if (!data->maintainer) return OPimMaintainer(); return (*data->maintainer); } void OTodo::setCompleted( bool completed ) { changeOrModify(); data->isCompleted = completed; } void OTodo::setHasDueDate( bool hasDate ) { changeOrModify(); data->hasDate = hasDate; } void OTodo::setDescription(const QString &desc ) { // qWarning( "desc " + desc ); changeOrModify(); data->desc = Qtopia::simplifyMultiLineSpace(desc ); } void OTodo::setSummary( const QString& sum ) { changeOrModify(); data->sum = sum; } void OTodo::setPriority(int prio ) { changeOrModify(); data->priority = prio; } void OTodo::setDueDate( const QDate& date ) { changeOrModify(); data->date = date; } void OTodo::setStartDate( const QDate& date ) { changeOrModify(); data->start = date; } void OTodo::setCompletedDate( const QDate& date ) { changeOrModify(); data->completed = date; } void OTodo::setState( const OPimState& state ) { changeOrModify(); if (data->state ) (*data->state) = state; else data->state = new OPimState( state ); } void OTodo::setRecurrence( const ORecur& rec) { changeOrModify(); if (data->recur ) (*data->recur) = rec; else data->recur = new ORecur( rec ); } void OTodo::setMaintainer( const OPimMaintainer& pim ) { changeOrModify(); if (data->maintainer ) (*data->maintainer) = pim; else data->maintainer = new OPimMaintainer( pim ); } bool OTodo::isOverdue( ) { if( data->hasDate && !data->isCompleted) return QDate::currentDate() > data->date; return false; } void OTodo::setProgress(ushort progress ) { changeOrModify(); data->prog = progress; } QString OTodo::toShortText() const { return summary(); } /*! Returns a richt text string */ QString OTodo::toRichText() const { QString text; QStringList catlist; // summary text += "<b><h3><img src=\"todo/TodoList\"> "; if ( !summary().isEmpty() ) { text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "" ); } text += "</h3></b><br><hr><br>"; // description if( !description().isEmpty() ){ text += "<b>" + QObject::tr( "Description:" ) + "</b><br>"; text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; } // priority int priorityval = priority(); text += "<b>" + QObject::tr( "Priority:") +" </b><img src=\"todo/priority" + QString::number( priorityval ) + "\"> "; switch ( priorityval ) { case 1 : text += QObject::tr( "Very high" ); break; case 2 : text += QObject::tr( "High" ); break; case 3 : text += QObject::tr( "Normal" ); break; case 4 : text += QObject::tr( "Low" ); break; case 5 : text += QObject::tr( "Very low" ); break; }; text += "<br>"; // progress text += "<b>" + QObject::tr( "Progress:") + " </b>" + QString::number( progress() ) + " %<br>"; // due date if (hasDueDate() ){ QDate dd = dueDate(); int off = QDate::currentDate().daysTo( dd ); text += "<b>" + QObject::tr( "Deadline:" ) + " </b><font color=\""; if ( off < 0 ) text += "#FF0000"; else if ( off == 0 ) text += "#FFFF00"; else if ( off > 0 ) text += "#00FF00"; text += "\">" + dd.toString() + "</font><br>"; } // categories text += "<b>" + QObject::tr( "Category:") + "</b> "; text += categoryNames( "Todo List" ).join(", "); text += "<br>"; return text; } bool OTodo::hasNotifiers()const { if (!data->notifiers) return false; return !data->notifiers->isEmpty(); } OPimNotifyManager& OTodo::notifiers() { if (!data->notifiers ) data->notifiers = new OPimNotifyManager; return (*data->notifiers); } const OPimNotifyManager& OTodo::notifiers()const{ if (!data->notifiers ) data->notifiers = new OPimNotifyManager; return (*data->notifiers); } bool OTodo::operator<( const OTodo &toDoEvent )const{ if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true; if( !hasDueDate() && toDoEvent.hasDueDate() ) return false; if( hasDueDate() && toDoEvent.hasDueDate() ){ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide return priority() < toDoEvent.priority(); }else{ return dueDate() < toDoEvent.dueDate(); } } return false; } bool OTodo::operator<=(const OTodo &toDoEvent )const { if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true; if( !hasDueDate() && toDoEvent.hasDueDate() ) return true; if( hasDueDate() && toDoEvent.hasDueDate() ){ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide return priority() <= toDoEvent.priority(); }else{ return dueDate() <= toDoEvent.dueDate(); } } return true; } bool OTodo::operator>(const OTodo &toDoEvent )const { if( !hasDueDate() && !toDoEvent.hasDueDate() ) return false; if( !hasDueDate() && toDoEvent.hasDueDate() ) return false; if( hasDueDate() && toDoEvent.hasDueDate() ){ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide return priority() > toDoEvent.priority(); }else{ return dueDate() > toDoEvent.dueDate(); } } return false; } bool OTodo::operator>=(const OTodo &toDoEvent )const { if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true; if( !hasDueDate() && toDoEvent.hasDueDate() ) return false; if( hasDueDate() && toDoEvent.hasDueDate() ){ if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide return priority() > toDoEvent.priority(); }else{ return dueDate() > toDoEvent.dueDate(); } } return true; } bool OTodo::operator==(const OTodo &toDoEvent )const { if ( data->priority != toDoEvent.data->priority ) return false; if ( data->priority != toDoEvent.data->prog ) return false; if ( data->isCompleted != toDoEvent.data->isCompleted ) return false; if ( data->hasDate != toDoEvent.data->hasDate ) return false; if ( data->date != toDoEvent.data->date ) return false; if ( data->sum != toDoEvent.data->sum ) return false; if ( data->desc != toDoEvent.data->desc ) return false; if ( data->maintainer != toDoEvent.data->maintainer ) return false; return OPimRecord::operator==( toDoEvent ); } void OTodo::deref() { // qWarning("deref in ToDoEvent"); if ( data->deref() ) { // qWarning("deleting"); delete data; data= 0; } } OTodo &OTodo::operator=(const OTodo &item ) { if ( this == &item ) return *this; OPimRecord::operator=( item ); //qWarning("operator= ref "); item.data->ref(); deref(); data = item.data; return *this; } QMap<int, QString> OTodo::toMap() const { QMap<int, QString> map; map.insert( Uid, QString::number( uid() ) ); map.insert( Category, idsToString( categories() ) ); map.insert( HasDate, QString::number( data->hasDate ) ); map.insert( Completed, QString::number( data->isCompleted ) ); map.insert( Description, data->desc ); map.insert( Summary, data->sum ); map.insert( Priority, QString::number( data->priority ) ); map.insert( DateDay, QString::number( data->date.day() ) ); map.insert( DateMonth, QString::number( data->date.month() ) ); map.insert( DateYear, QString::number( data->date.year() ) ); map.insert( Progress, QString::number( data->prog ) ); // map.insert( CrossReference, crossToString() ); /* FIXME!!! map.insert( State, ); map.insert( Recurrence, ); map.insert( Reminders, ); map. */ return map; } /** * change or modify looks at the ref count and either * creates a new QShared Object or it can modify it * right in place */ void OTodo::changeOrModify() { if ( data->count != 1 ) { qWarning("changeOrModify"); data->deref(); OTodoData* d2 = new OTodoData(); copy(data, d2 ); data = d2; } } // WATCHOUT /* * if you add something to the Data struct * be sure to copy it here */ void OTodo::copy( OTodoData* src, OTodoData* dest ) { dest->date = src->date; dest->isCompleted = src->isCompleted; dest->hasDate = src->hasDate; dest->priority = src->priority; dest->desc = src->desc; dest->sum = src->sum; dest->extra = src->extra; dest->prog = src->prog; if (src->state ) dest->state = new OPimState( *src->state ); if (src->recur ) dest->recur = new ORecur( *src->recur ); if (src->maintainer ) dest->maintainer = new OPimMaintainer( *src->maintainer ) ; dest->start = src->start; dest->completed = src->completed; if (src->notifiers ) dest->notifiers = new OPimNotifyManager( *src->notifiers ); } QString OTodo::type() const { return QString::fromLatin1("OTodo"); } QString OTodo::recordField(int /*id*/ )const { return QString::null; } int OTodo::rtti(){ return OPimResolver::TodoList; } + +} diff --git a/libopie2/opiepim/otodo.h b/libopie2/opiepim/otodo.h index 6df98b9..61add04 100644 --- a/libopie2/opiepim/otodo.h +++ b/libopie2/opiepim/otodo.h @@ -1,285 +1,315 @@ - +/* + This file is part of the Opie Project + Copyright (C) The Main Author <main-author@whereever.org> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_TODO_EVENT_H #define OPIE_TODO_EVENT_H #include <qarray.h> #include <qmap.h> #include <qregexp.h> #include <qstringlist.h> #include <qdatetime.h> #include <qvaluelist.h> #include <qpe/recordfields.h> #include <qpe/palmtopuidgen.h> -#include <opie/opimrecord.h> +#include <opie2/opimrecord.h> +namespace Opie { + class OPimState; class ORecur; class OPimMaintainer; class OPimNotifyManager; class OTodo : public OPimRecord { public: typedef QValueList<OTodo> ValueList; enum RecordFields { Uid = Qtopia::UID_ID, Category = Qtopia::CATEGORY_ID, HasDate, Completed, Description, Summary, Priority, DateDay, DateMonth, DateYear, Progress, CrossReference, State, Recurrence, Alarms, Reminders, Notifiers, Maintainer, StartDate, CompletedDate }; public: // priorities from Very low to very high enum TaskPriority { VeryHigh=1, High, Normal, Low, VeryLow }; /* Constructs a new ToDoEvent @param completed Is the TodoEvent completed @param priority What is the priority of this ToDoEvent @param category Which category does it belong( uid ) @param summary A small summary of the todo @param description What is this ToDoEvent about @param hasDate Does this Event got a deadline @param date what is the deadline? @param uid what is the UUID of this Event **/ OTodo( bool completed = false, int priority = Normal, const QStringList &category = QStringList(), const QString &summary = QString::null , const QString &description = QString::null, ushort progress = 0, bool hasDate = false, QDate date = QDate::currentDate(), int uid = 0 /*empty*/ ); OTodo( bool completed, int priority, const QArray<int>& category, const QString& summary = QString::null, const QString& description = QString::null, ushort progress = 0, bool hasDate = false, QDate date = QDate::currentDate(), int uid = 0 /* empty */ ); /** Copy c'tor * */ OTodo(const OTodo & ); /** *destructor */ ~OTodo(); /** * Is this event completed? */ bool isCompleted() const; /** * Does this Event have a deadline */ bool hasDueDate() const; bool hasStartDate()const; bool hasCompletedDate()const; /** * What is the priority? */ int priority()const ; /** * progress as ushort 0, 20, 40, 60, 80 or 100% */ ushort progress() const; /** * The due Date */ QDate dueDate()const; /** * When did it start? */ QDate startDate()const; /** * When was it completed? */ QDate completedDate()const; /** * does it have a state? */ bool hasState()const; /** * What is the state of this OTodo? */ OPimState state()const; /** * has recurrence? */ bool hasRecurrence()const; /** * the recurrance of this */ ORecur recurrence()const; /** * does this OTodo have a maintainer? */ bool hasMaintainer()const; /** * the Maintainer of this OTodo */ OPimMaintainer maintainer()const; /** * The description of the todo */ QString description()const; /** * A small summary of the todo */ QString summary() const; /** * @reimplemented * Return this todoevent in a RichText formatted QString */ QString toRichText() const; bool hasNotifiers()const; /* * FIXME check if the sharing is still fine!! -zecke * ### CHECK If API is fine */ /** * return a reference to our notifiers... */ OPimNotifyManager ¬ifiers(); /** * */ const OPimNotifyManager ¬ifiers()const; /** * reimplementations */ QString type()const; QString toShortText()const; QString recordField(int id )const; /** * toMap puts all data into the map. int relates * to ToDoEvent RecordFields enum */ QMap<int, QString> toMap()const; /** * Set if this Todo is completed */ void setCompleted(bool completed ); /** * set if this todo got an end data */ void setHasDueDate( bool hasDate ); // FIXME we do not have these for start, completed // cause we'll use the isNull() of QDate for figuring // out if it's has a date... // decide what to do here? -zecke /** * Set the priority of the Todo */ void setPriority(int priority ); /** * Set the progress. */ void setProgress( ushort progress ); /** * set the end date */ void setDueDate( const QDate& date ); /** * set the start date */ void setStartDate( const QDate& date ); /** * set the completed date */ void setCompletedDate( const QDate& date ); void setRecurrence( const ORecur& ); void setDescription(const QString& ); void setSummary(const QString& ); /** * set the state of a Todo * @param state State what the todo should take */ void setState( const OPimState& state); /** * set the Maintainer Mode */ void setMaintainer( const OPimMaintainer& ); bool isOverdue(); virtual bool match( const QRegExp &r )const; bool operator<(const OTodo &toDoEvent )const; bool operator<=(const OTodo &toDoEvent )const; bool operator!=(const OTodo &toDoEvent )const; bool operator>(const OTodo &toDoEvent )const; bool operator>=(const OTodo &toDoEvent)const; bool operator==(const OTodo &toDoEvent )const; OTodo &operator=(const OTodo &toDoEvent ); static int rtti(); private: class OTodoPrivate; struct OTodoData; void deref(); inline void changeOrModify(); void copy( OTodoData* src, OTodoData* dest ); OTodoPrivate *d; OTodoData *data; }; inline bool OTodo::operator!=(const OTodo &toDoEvent )const { return !(*this == toDoEvent); } +} #endif diff --git a/libopie2/opiepim/ui/opimmainwindow.cpp b/libopie2/opiepim/ui/opimmainwindow.cpp index 2739e26..10ed743 100644 --- a/libopie2/opiepim/ui/opimmainwindow.cpp +++ b/libopie2/opiepim/ui/opimmainwindow.cpp @@ -1,150 +1,181 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #include <qapplication.h> #include <qdatetime.h> #include <qcopchannel_qws.h> #include <qpe/sound.h> #include <qpe/qcopenvelope_qws.h> #include <qpe/qpeapplication.h> -#include "opimresolver.h" +#include <opie2/opimresolver.h> #include "opimmainwindow.h" +namespace Opie { OPimMainWindow::OPimMainWindow( const QString& service, QWidget* parent, const char* name, WFlags flag ) : QMainWindow( parent, name, flag ), m_rtti(-1), m_service( service ), m_fallBack(0l) { /* * let's generate our QCopChannel */ m_str = QString("QPE/"+m_service).local8Bit(); m_channel= new QCopChannel(m_str, this ); connect(m_channel, SIGNAL(received(const QCString&, const QByteArray& ) ), this, SLOT( appMessage( const QCString&, const QByteArray& ) ) ); connect(qApp, SIGNAL(appMessage(const QCString&, const QByteArray& ) ), this, SLOT( appMessage( const QCString&, const QByteArray& ) ) ); /* connect flush and reload */ connect(qApp, SIGNAL(flush() ), this, SLOT(flush() ) ); connect(qApp, SIGNAL(reload() ), this, SLOT(reload() ) ); } OPimMainWindow::~OPimMainWindow() { delete m_channel; } QCopChannel* OPimMainWindow::channel() { return m_channel; } void OPimMainWindow::doSetDocument( const QString& ) { } void OPimMainWindow::appMessage( const QCString& cmd, const QByteArray& array ) { bool needShow = false; /* * create demands to create * a new record... */ QDataStream stream(array, IO_ReadOnly); if ( cmd == "create()" ) { raise(); int uid = create(); QCopEnvelope e(m_str, "created(int)" ); e << uid; needShow = true; }else if ( cmd == "remove(int)" ) { int uid; stream >> uid; bool rem = remove( uid ); QCopEnvelope e(m_str, "removed(bool)" ); e << rem; needShow = true; }else if ( cmd == "beam(int)" ) { int uid; stream >> uid; beam( uid); }else if ( cmd == "show(int)" ) { raise(); int uid; stream >> uid; show( uid ); needShow = true; }else if ( cmd == "edit(int)" ) { raise(); int uid; stream >> uid; edit( uid ); }else if ( cmd == "add(int,QByteArray)" ) { int rtti; QByteArray array; stream >> rtti; stream >> array; m_fallBack = record(rtti, array ); if (!m_fallBack) return; add( *m_fallBack ); delete m_fallBack; }else if ( cmd == "alarm(QDateTime,int)" ) { raise(); QDateTime dt; int uid; stream >> dt; stream >> uid; qWarning(" Date: %s Uid: %d", dt.toString().latin1(), uid ); QDateTime current = QDateTime::currentDateTime(); if ( current.time().hour() != dt.time().hour() && current.time().minute() != dt.time().minute() ) return; doAlarm( dt, uid ); needShow = true; } if (needShow ) QPEApplication::setKeepRunning(); } /* implement the url scripting here */ void OPimMainWindow::setDocument( const QString& str) { doSetDocument( str ); } /* * we now try to get the array demarshalled * check if the rtti matches this one */ OPimRecord* OPimMainWindow::record( int rtti, const QByteArray& array ) { if ( service() != rtti ) return 0l; OPimRecord* record = OPimResolver::self()->record( rtti ); QDataStream str(array, IO_ReadOnly ); if ( !record || !record->loadFromStream(str) ) { delete record; record = 0l; } return record; } /* * get the rtti for the service */ int OPimMainWindow::service() { if ( m_rtti == -1 ) m_rtti = OPimResolver::self()->serviceId( m_service ); return m_rtti; } void OPimMainWindow::doAlarm( const QDateTime&, int ) { } void OPimMainWindow::startAlarm(int count ) { m_alarmCount = count; m_playedCount = 0; Sound::soundAlarm(); m_timerId = startTimer( 5000 ); } void OPimMainWindow::killAlarm() { killTimer( m_timerId ); } void OPimMainWindow::timerEvent( QTimerEvent* e) { if ( m_playedCount <m_alarmCount ) { m_playedCount++; Sound::soundAlarm(); }else { killTimer( e->timerId() ); } } + +} diff --git a/libopie2/opiepim/ui/opimmainwindow.h b/libopie2/opiepim/ui/opimmainwindow.h index 855d364..abad630 100644 --- a/libopie2/opiepim/ui/opimmainwindow.h +++ b/libopie2/opiepim/ui/opimmainwindow.h @@ -1,99 +1,129 @@ +/* + This file is part of the Opie Project + Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ #ifndef OPIE_PIM_MAINWINDOW_H #define OPIE_PIM_MAINWINDOW_H #include <qmainwindow.h> -#include <opie/opimrecord.h> +#include <opie2/opimrecord.h> +class QCopChannel; +class QDateTime; +namespace Opie { /** * This is a common Opie PIM MainWindow * it takes care of the QCOP internals * and implements some functions * for the URL scripting schema */ /* * due Qt and Templates with signal and slots * do not work that good :( * (Ok how to moc a template ;) ) * We will have the mainwindow which calls a struct which * is normally reimplemented as a template ;) */ -class QCopChannel; -class QDateTime; class OPimMainWindow : public QMainWindow { Q_OBJECT public: enum TransPort { BlueTooth=0, IrDa }; OPimMainWindow( const QString& service, QWidget *parent = 0, const char* name = 0, WFlags f = WType_TopLevel); virtual ~OPimMainWindow(); protected slots: /* * called when a setDocument * couldn't be handled by this window */ virtual void doSetDocument( const QString& ); /* for syncing */ virtual void flush() = 0; virtual void reload() = 0; /** create a new Records and return the uid */ virtual int create() = 0; /** remove a record with UID == uid */ virtual bool remove( int uid ) = 0; /** beam the record with UID = uid */ virtual void beam( int uid ) = 0; /** show the record with UID == uid */ virtual void show( int uid ) = 0; /** edit the record */ virtual void edit( int uid ) = 0; /** make a copy of it! */ virtual void add( const OPimRecord& ) = 0; virtual void doAlarm( const QDateTime&, int uid ); QCopChannel* channel(); protected: /** * start to play soundAlarm() * @param count How many times the alarm is played */ void startAlarm(int count = 10); void killAlarm(); void timerEvent( QTimerEvent* ); private slots: void appMessage( const QCString&, const QByteArray& ); void setDocument( const QString& ); private: class Private; Private* d; int m_rtti; QCopChannel* m_channel; QString m_service; QCString m_str; OPimRecord* m_fallBack; int m_alarmCount; int m_playedCount; int m_timerId; /* I would love to do this as a template * but can't think of a right way * because I need signal and slots -zecke */ virtual OPimRecord* record( int rtti, const QByteArray& ) ; int service(); }; +} #endif diff --git a/libopie2/opiepim/ui/ui.pro b/libopie2/opiepim/ui/ui.pro new file mode 100644 index 0000000..db19bca --- a/dev/null +++ b/libopie2/opiepim/ui/ui.pro @@ -0,0 +1,3 @@ +HEADERS += ui/opimmainwindow.h + +SOURCES += ui/opimmainwindow.cpp |