summaryrefslogtreecommitdiff
authoreilers <eilers>2003-09-22 14:31:15 (UTC)
committer eilers <eilers>2003-09-22 14:31:15 (UTC)
commit34e86ddf4f9b1045a5b730beab2d8d72e2dd4d56 (patch) (unidiff)
treecee19bfcf7c8d6a24cd4aaf578bd64b38b2d0ee4
parentfd500184450e37c239e573adf1c12a6ff62b65f6 (diff)
downloadopie-34e86ddf4f9b1045a5b730beab2d8d72e2dd4d56.zip
opie-34e86ddf4f9b1045a5b730beab2d8d72e2dd4d56.tar.gz
opie-34e86ddf4f9b1045a5b730beab2d8d72e2dd4d56.tar.bz2
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...
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/libopie.pro17
-rw-r--r--libopie/pim/obackendfactory.h16
-rw-r--r--libopie/pim/ocontact.h13
-rw-r--r--libopie/pim/ocontactaccessbackend_sql.cpp664
-rw-r--r--libopie/pim/ocontactaccessbackend_sql.h96
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.cpp7
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.h6
-rw-r--r--libopie/pim/ocontactfields.cpp456
-rw-r--r--libopie/pim/ocontactfields.h60
-rw-r--r--libopie/pim/otodoaccesssql.cpp73
-rw-r--r--libopie/pim/otodoaccesssql.h6
-rw-r--r--libopie/pim/test/converter.cpp64
-rw-r--r--libopie/pim/test/converter.pro12
-rw-r--r--libopie/pim/test/converter_base.ui43
-rw-r--r--libopie2/opiepim/backend/obackendfactory.h16
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp664
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.h96
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp7
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.h6
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.cpp73
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.h6
-rw-r--r--libopie2/opiepim/ocontact.h13
-rw-r--r--libopie2/opiepim/ocontactfields.cpp456
-rw-r--r--libopie2/opiepim/ocontactfields.h60
24 files changed, 2881 insertions, 49 deletions
diff --git a/libopie/libopie.pro b/libopie/libopie.pro
index 2148233..0398775 100644
--- a/libopie/libopie.pro
+++ b/libopie/libopie.pro
@@ -1,121 +1,136 @@
1TEMPLATE = lib 1TEMPLATE = lib
2CONFIG += qte warn_on release 2CONFIG += qte warn_on release
3HEADERS = ofontmenu.h \ 3HEADERS = ofontmenu.h \
4 ocolorbutton.h \ 4 ocolorbutton.h \
5 ofiledialog.h ofileselector.h \ 5 ofiledialog.h ofileselector.h \
6 ofileselector_p.h \ 6 ofileselector_p.h \
7 ocheckitem.h \ 7 ocheckitem.h \
8 xmltree.h \ 8 xmltree.h \
9 colordialog.h colorpopupmenu.h \ 9 colordialog.h colorpopupmenu.h \
10 oclickablelabel.h oprocctrl.h \ 10 oclickablelabel.h oprocctrl.h \
11 oprocess.h odevice.h odevicebutton.h \ 11 oprocess.h odevice.h odevicebutton.h \
12 otimepicker.h otabwidget.h \ 12 otimepicker.h otabwidget.h \
13 otabbar.h otabinfo.h \ 13 otabbar.h otabinfo.h \
14 ofontselector.h \ 14 ofontselector.h \
15 pim/opimrecord.h \ 15 pim/opimrecord.h \
16 pim/otodo.h \ 16 pim/otodo.h \
17 pim/orecordlist.h \ 17 pim/orecordlist.h \
18 pim/opimaccesstemplate.h \ 18 pim/opimaccesstemplate.h \
19 pim/opimaccessbackend.h \ 19 pim/opimaccessbackend.h \
20 pim/otodoaccess.h \ 20 pim/otodoaccess.h \
21 pim/otodoaccessbackend.h \ 21 pim/otodoaccessbackend.h \
22 pim/oconversion.h \ 22 pim/oconversion.h \
23 pim/ocontact.h \ 23 pim/ocontact.h \
24 pim/ocontactfields.h \
24 pim/ocontactaccess.h \ 25 pim/ocontactaccess.h \
25 pim/ocontactaccessbackend.h \ 26 pim/ocontactaccessbackend.h \
26 pim/ocontactaccessbackend_xml.h \ 27 pim/ocontactaccessbackend_xml.h \
27 pim/ocontactaccessbackend_vcard.h \ 28 pim/ocontactaccessbackend_vcard.h \
28 pim/obackendfactory.h \ 29 pim/obackendfactory.h \
29 pim/opimcache.h \ 30 pim/opimcache.h \
30 pim/otodoaccessvcal.h \ 31 pim/otodoaccessvcal.h \
31 pim/orecur.h \ 32 pim/orecur.h \
32 pim/opimstate.h \ 33 pim/opimstate.h \
33 pim/opimxrefpartner.h \ 34 pim/opimxrefpartner.h \
34 pim/opimxref.h \ 35 pim/opimxref.h \
35 pim/opimxrefmanager.h \ 36 pim/opimxrefmanager.h \
36 pim/opimmaintainer.h \ 37 pim/opimmaintainer.h \
37 pim/opimnotify.h \ 38 pim/opimnotify.h \
38 pim/opimnotifymanager.h \ 39 pim/opimnotifymanager.h \
39 pim/opimmainwindow.h \ 40 pim/opimmainwindow.h \
40 pim/opimresolver.h \ 41 pim/opimresolver.h \
41 pim/oevent.h \ 42 pim/oevent.h \
42 pim/otimezone.h \ 43 pim/otimezone.h \
43 pim/odatebookaccess.h \ 44 pim/odatebookaccess.h \
44 pim/odatebookaccessbackend.h \ 45 pim/odatebookaccessbackend.h \
45 pim/odatebookaccessbackend_xml.h \ 46 pim/odatebookaccessbackend_xml.h \
46 orecurrancewidget.h \ 47 orecurrancewidget.h \
47 oticker.h owait.h 48 oticker.h owait.h
48 49
49SOURCES = ofontmenu.cc \ 50SOURCES = ofontmenu.cc \
50 ocolorbutton.cpp \ 51 ocolorbutton.cpp \
51 sharp_compat.cpp \ 52 sharp_compat.cpp \
52 xmltree.cc \ 53 xmltree.cc \
53 ofiledialog.cc ofileselector.cpp \ 54 ofiledialog.cc ofileselector.cpp \
54 ocheckitem.cpp \ 55 ocheckitem.cpp \
55 colordialog.cpp \ 56 colordialog.cpp \
56 colorpopupmenu.cpp oclickablelabel.cpp \ 57 colorpopupmenu.cpp oclickablelabel.cpp \
57 oprocctrl.cpp oprocess.cpp \ 58 oprocctrl.cpp oprocess.cpp \
58 odevice.cpp odevicebutton.cpp otimepicker.cpp \ 59 odevice.cpp odevicebutton.cpp otimepicker.cpp \
59 otabwidget.cpp otabbar.cpp \ 60 otabwidget.cpp otabbar.cpp \
60 ofontselector.cpp \ 61 ofontselector.cpp \
61 pim/otodo.cpp \ 62 pim/otodo.cpp \
62 pim/opimrecord.cpp \ 63 pim/opimrecord.cpp \
63 pim/otodoaccess.cpp \ 64 pim/otodoaccess.cpp \
64 pim/otodoaccessbackend.cpp \ 65 pim/otodoaccessbackend.cpp \
65 pim/otodoaccessxml.cpp \ 66 pim/otodoaccessxml.cpp \
66 pim/oconversion.cpp \ 67 pim/oconversion.cpp \
67 pim/ocontact.cpp \ 68 pim/ocontact.cpp \
69 pim/ocontactfields.cpp \
68 pim/ocontactaccess.cpp \ 70 pim/ocontactaccess.cpp \
69 pim/ocontactaccessbackend_vcard.cpp \ 71 pim/ocontactaccessbackend_vcard.cpp \
70 pim/ocontactaccessbackend_xml.cpp \ 72 pim/ocontactaccessbackend_xml.cpp \
71 pim/otodoaccessvcal.cpp \ 73 pim/otodoaccessvcal.cpp \
72 pim/orecur.cpp \ 74 pim/orecur.cpp \
73 pim/opimstate.cpp \ 75 pim/opimstate.cpp \
74 pim/opimxrefpartner.cpp \ 76 pim/opimxrefpartner.cpp \
75 pim/opimxref.cpp \ 77 pim/opimxref.cpp \
76 pim/opimxrefmanager.cpp \ 78 pim/opimxrefmanager.cpp \
77 pim/opimmaintainer.cpp \ 79 pim/opimmaintainer.cpp \
78 pim/opimnotify.cpp \ 80 pim/opimnotify.cpp \
79 pim/opimnotifymanager.cpp \ 81 pim/opimnotifymanager.cpp \
80 pim/opimmainwindow.cpp \ 82 pim/opimmainwindow.cpp \
81 pim/opimresolver.cpp \ 83 pim/opimresolver.cpp \
82 pim/oevent.cpp \ 84 pim/oevent.cpp \
83 pim/otimezone.cpp \ 85 pim/otimezone.cpp \
84 pim/odatebookaccess.cpp \ 86 pim/odatebookaccess.cpp \
85 pim/odatebookaccessbackend.cpp \ 87 pim/odatebookaccessbackend.cpp \
86 pim/odatebookaccessbackend_xml.cpp \ 88 pim/odatebookaccessbackend_xml.cpp \
87 orecurrancewidget.cpp \ 89 orecurrancewidget.cpp \
88 oticker.cpp owait.cpp 90 oticker.cpp owait.cpp
89 91
90TARGET = opie 92TARGET = opie
91INCLUDEPATH += $(OPIEDIR)/include 93INCLUDEPATH += $(OPIEDIR)/include
92DESTDIR = $(OPIEDIR)/lib$(PROJMAK) 94DESTDIR = $(OPIEDIR)/lib$(PROJMAK)
93 95
96# The following is just for my Notebook !
97# It should never be committed !! (eilers)
98# QMAKE_CXXFLAGS += -DQT_NO_SOUND
99
94LIBS += -lqpe 100LIBS += -lqpe
95 101
96# LIBS += -lopiesql 102# Add SQL-Support if selected by config (eilers)
103CONFTEST = $$system( echo $CONFIG_SQL_PIM_BACKEND )
104contains( CONFTEST, y ){
105
106DEFINES += __USE_SQL
107LIBS += -lopiedb2 -lsqlite
108HEADERS += pim/otodoaccesssql.h pim/ocontactaccessbackend_sql.h
109SOURCES += pim/otodoaccesssql.cpp pim/ocontactaccessbackend_sql.cpp
110
111}
97 112
98INTERFACES = otimepickerbase.ui orecurrancebase.ui 113INTERFACES = otimepickerbase.ui orecurrancebase.ui
99TARGET = opie 114TARGET = opie
100 115
101TRANSLATIONS = ../i18n/de/libopie.ts \ 116TRANSLATIONS = ../i18n/de/libopie.ts \
102 ../i18n/nl/libopie.ts \ 117 ../i18n/nl/libopie.ts \
103 ../i18n/xx/libopie.ts \ 118 ../i18n/xx/libopie.ts \
104 ../i18n/en/libopie.ts \ 119 ../i18n/en/libopie.ts \
105 ../i18n/es/libopie.ts \ 120 ../i18n/es/libopie.ts \
106 ../i18n/fr/libopie.ts \ 121 ../i18n/fr/libopie.ts \
107 ../i18n/hu/libopie.ts \ 122 ../i18n/hu/libopie.ts \
108 ../i18n/ja/libopie.ts \ 123 ../i18n/ja/libopie.ts \
109 ../i18n/ko/libopie.ts \ 124 ../i18n/ko/libopie.ts \
110 ../i18n/no/libopie.ts \ 125 ../i18n/no/libopie.ts \
111 ../i18n/pl/libopie.ts \ 126 ../i18n/pl/libopie.ts \
112 ../i18n/pt/libopie.ts \ 127 ../i18n/pt/libopie.ts \
113 ../i18n/pt_BR/libopie.ts \ 128 ../i18n/pt_BR/libopie.ts \
114 ../i18n/sl/libopie.ts \ 129 ../i18n/sl/libopie.ts \
115 ../i18n/zh_CN/libopie.ts \ 130 ../i18n/zh_CN/libopie.ts \
116 ../i18n/zh_TW/libopie.ts \ 131 ../i18n/zh_TW/libopie.ts \
117 ../i18n/da/libopie.ts 132 ../i18n/da/libopie.ts
118 133
119include ( big-screen/big-screen.pro ) 134include ( big-screen/big-screen.pro )
120 135
121include ( $(OPIEDIR)/include.pro ) 136include ( $(OPIEDIR)/include.pro )
diff --git a/libopie/pim/obackendfactory.h b/libopie/pim/obackendfactory.h
index f3c339d..3567687 100644
--- a/libopie/pim/obackendfactory.h
+++ b/libopie/pim/obackendfactory.h
@@ -1,166 +1,176 @@
1/* 1/*
2 * Class to manage Backends. 2 * Class to manage Backends.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; 9 * License as published by the Free Software Foundation;
10 * either version 2 of the License, or (at your option) any later 10 * either version 2 of the License, or (at your option) any later
11 * version. 11 * version.
12 * ===================================================================== 12 * =====================================================================
13 * ToDo: Use plugins 13 * ToDo: Use plugins
14 * ===================================================================== 14 * =====================================================================
15 * Version: $Id$ 15 * Version: $Id$
16 * ===================================================================== 16 * =====================================================================
17 * History: 17 * History:
18 * $Log$ 18 * $Log$
19 * Revision 1.8 2003/09/22 14:31:16 eilers
20 * Added first experimental incarnation of sql-backend for addressbook.
21 * Some modifications to be able to compile the todo sql-backend.
22 * A lot of changes fill follow...
23 *
19 * Revision 1.7 2003/08/01 12:30:16 eilers 24 * Revision 1.7 2003/08/01 12:30:16 eilers
20 * Merging changes from BRANCH_1_0 to HEAD 25 * Merging changes from BRANCH_1_0 to HEAD
21 * 26 *
22 * Revision 1.6.4.1 2003/06/30 14:34:19 eilers 27 * Revision 1.6.4.1 2003/06/30 14:34:19 eilers
23 * Patches from Zecke: 28 * Patches from Zecke:
24 * Fixing and cleaning up extraMap handling 29 * Fixing and cleaning up extraMap handling
25 * Adding d_ptr for binary compatibility in the future 30 * Adding d_ptr for binary compatibility in the future
26 * 31 *
27 * Revision 1.6 2003/04/13 18:07:10 zecke 32 * Revision 1.6 2003/04/13 18:07:10 zecke
28 * More API doc 33 * More API doc
29 * QString -> const QString& 34 * QString -> const QString&
30 * QString = 0l -> QString::null 35 * QString = 0l -> QString::null
31 * 36 *
32 * Revision 1.5 2003/02/21 23:31:52 zecke 37 * Revision 1.5 2003/02/21 23:31:52 zecke
33 * Add XML datebookresource 38 * Add XML datebookresource
34 * -clean up todoaccessxml header 39 * -clean up todoaccessxml header
35 * -implement some more stuff in the oeven tester 40 * -implement some more stuff in the oeven tester
36 * -extend DefaultFactory to not crash and to use datebook 41 * -extend DefaultFactory to not crash and to use datebook
37 * 42 *
38 * -reading of OEvents is working nicely.. saving will be added 43 * -reading of OEvents is working nicely.. saving will be added
39 * tomorrow 44 * tomorrow
40 * -fix spelling in ODateBookAcces 45 * -fix spelling in ODateBookAcces
41 * 46 *
42 * Revision 1.4 2002/10/14 15:55:18 eilers 47 * Revision 1.4 2002/10/14 15:55:18 eilers
43 * Redeactivate SQL.. ;) 48 * Redeactivate SQL.. ;)
44 * 49 *
45 * Revision 1.3 2002/10/10 17:08:58 zecke 50 * Revision 1.3 2002/10/10 17:08:58 zecke
46 * The Cache is finally in place 51 * The Cache is finally in place
47 * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;) 52 * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;)
48 * 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.... 53 * 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....
49 * I still have to fully implement read ahead 54 * I still have to fully implement read ahead
50 * This change is bic but sc 55 * This change is bic but sc
51 * 56 *
52 * Revision 1.2 2002/10/08 09:27:36 eilers 57 * Revision 1.2 2002/10/08 09:27:36 eilers
53 * Fixed libopie.pro to include the new pim-API. 58 * Fixed libopie.pro to include the new pim-API.
54 * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to 59 * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to
55 * compile itself would need to install libsqlite, libopiesql... 60 * compile itself would need to install libsqlite, libopiesql...
56 * Therefore, the backend currently uses XML only.. 61 * Therefore, the backend currently uses XML only..
57 * 62 *
58 * Revision 1.1 2002/10/07 17:35:01 eilers 63 * Revision 1.1 2002/10/07 17:35:01 eilers
59 * added OBackendFactory for advanced backend access 64 * added OBackendFactory for advanced backend access
60 * 65 *
61 * 66 *
62 * ===================================================================== 67 * =====================================================================
63 */ 68 */
64#ifndef OPIE_BACKENDFACTORY_H_ 69#ifndef OPIE_BACKENDFACTORY_H_
65#define OPIE_BACKENDFACTORY_H_ 70#define OPIE_BACKENDFACTORY_H_
66 71
67#include <qstring.h> 72#include <qstring.h>
68#include <qasciidict.h> 73#include <qasciidict.h>
69#include <qpe/config.h> 74#include <qpe/config.h>
70 75
71#include "otodoaccessxml.h" 76#include "otodoaccessxml.h"
72#include "ocontactaccessbackend_xml.h" 77#include "ocontactaccessbackend_xml.h"
73#include "odatebookaccessbackend_xml.h" 78#include "odatebookaccessbackend_xml.h"
74 79
75#ifdef __USE_SQL 80#ifdef __USE_SQL
76#include "otodoaccesssql.h" 81#include "otodoaccesssql.h"
82#include "ocontactaccessbackend_sql.h"
77#endif 83#endif
78 84
79class OBackendPrivate; 85class OBackendPrivate;
80 86
81/** 87/**
82 * This class is our factory. It will give us the default implementations 88 * This class is our factory. It will give us the default implementations
83 * of at least Todolist, Contacts and Datebook. In the future this class will 89 * of at least Todolist, Contacts and Datebook. In the future this class will
84 * allow users to switch the backend with ( XML->SQLite ) without the need 90 * allow users to switch the backend with ( XML->SQLite ) without the need
85 * to recompile.# 91 * to recompile.#
86 * This class as the whole PIM Api is making use of templates 92 * This class as the whole PIM Api is making use of templates
87 * 93 *
88 * <pre> 94 * <pre>
89 * OTodoAccessBackend* backend = OBackEndFactory<OTodoAccessBackend>::Default("todo", QString::null ); 95 * OTodoAccessBackend* backend = OBackEndFactory<OTodoAccessBackend>::Default("todo", QString::null );
90 * backend->load(); 96 * backend->load();
91 * </pre> 97 * </pre>
92 * 98 *
93 * @author Stefan Eilers 99 * @author Stefan Eilers
94 * @version 0.1 100 * @version 0.1
95 */ 101 */
96template<class T> 102template<class T>
97class OBackendFactory 103class OBackendFactory
98{ 104{
99 public: 105 public:
100 OBackendFactory() {}; 106 OBackendFactory() {};
101 107
102 enum BACKENDS { 108 enum BACKENDS {
103 TODO, 109 TODO,
104 CONTACT, 110 CONTACT,
105 DATE 111 DATE
106 }; 112 };
107 113
108 /** 114 /**
109 * Returns a backend implementation for backendName 115 * Returns a backend implementation for backendName
110 * @param backendName the type of the backend 116 * @param backendName the type of the backend
111 * @param appName will be passed on to the backend 117 * @param appName will be passed on to the backend
112 */ 118 */
113 static T* Default( const QString backendName, const QString& appName ){ 119 static T* Default( const QString backendName, const QString& appName ){
114 120
115 // __asm__("int3"); 121 // __asm__("int3");
116 122
117 Config config( "pimaccess" ); 123 Config config( "pimaccess" );
118 config.setGroup ( backendName ); 124 config.setGroup ( backendName );
119 QString backend = config.readEntry( "usebackend" ); 125 QString backend = config.readEntry( "usebackend" );
120 126
127 qWarning("Selected backend for %s is: %s", backendName.latin1(), backend.latin1() );
128
121 QAsciiDict<int> dict ( 3 ); 129 QAsciiDict<int> dict ( 3 );
122 dict.setAutoDelete ( TRUE ); 130 dict.setAutoDelete ( TRUE );
123 131
124 dict.insert( "todo", new int (TODO) ); 132 dict.insert( "todo", new int (TODO) );
125 dict.insert( "contact", new int (CONTACT) ); 133 dict.insert( "contact", new int (CONTACT) );
126 dict.insert( "datebook", new int(DATE) ); 134 dict.insert( "datebook", new int(DATE) );
127 135
128 qWarning ("TODO is: %d", TODO);
129 qWarning ("CONTACT is: %d", CONTACT);
130
131 int *find = dict[ backendName ]; 136 int *find = dict[ backendName ];
132 if (!find ) return 0; 137 if (!find ) return 0;
133 138
134 switch ( *find ){ 139 switch ( *find ){
135 case TODO: 140 case TODO:
136#ifdef __USE_SQL 141#ifdef __USE_SQL
137 if ( backend == "sql" ) 142 if ( backend == "sql" )
138 return (T*) new OTodoAccessBackendSQL(""); 143 return (T*) new OTodoAccessBackendSQL("");
139#else 144#else
140 if ( backend == "sql" ) 145 if ( backend == "sql" )
141 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 146 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
142#endif 147#endif
143 148
144 return (T*) new OTodoAccessXML( appName ); 149 return (T*) new OTodoAccessXML( appName );
145 case CONTACT: 150 case CONTACT:
151#ifdef __USE_SQL
152 if ( backend == "sql" )
153 return (T*) new OContactAccessBackend_SQL("");
154#else
146 if ( backend == "sql" ) 155 if ( backend == "sql" )
147 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 156 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
157#endif
148 158
149 return (T*) new OContactAccessBackend_XML( appName ); 159 return (T*) new OContactAccessBackend_XML( appName );
150 case DATE: 160 case DATE:
151 if ( backend == "sql" ) 161 if ( backend == "sql" )
152 qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 162 qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!");
153 163
154 return (T*) new ODateBookAccessBackend_XML( appName ); 164 return (T*) new ODateBookAccessBackend_XML( appName );
155 default: 165 default:
156 return NULL; 166 return NULL;
157 } 167 }
158 168
159 169
160 } 170 }
161 private: 171 private:
162 OBackendPrivate* d; 172 OBackendPrivate* d;
163}; 173};
164 174
165 175
166#endif 176#endif
diff --git a/libopie/pim/ocontact.h b/libopie/pim/ocontact.h
index 9a1a8dc..1d46b81 100644
--- a/libopie/pim/ocontact.h
+++ b/libopie/pim/ocontact.h
@@ -135,111 +135,106 @@ public:
135 QString defaultEmail() const { return find( Qtopia::DefaultEmail ); } 135 QString defaultEmail() const { return find( Qtopia::DefaultEmail ); }
136 QStringList emailList() const; 136 QStringList emailList() const;
137 137
138 // home 138 // home
139 /* 139 /*
140 * OPimAddress address(enum Location)const; 140 * OPimAddress address(enum Location)const;
141 * would be some how nicer... 141 * would be some how nicer...
142 * -zecke 142 * -zecke
143 */ 143 */
144 QString homeStreet() const { return find( Qtopia::HomeStreet ); } 144 QString homeStreet() const { return find( Qtopia::HomeStreet ); }
145 QString homeCity() const { return find( Qtopia::HomeCity ); } 145 QString homeCity() const { return find( Qtopia::HomeCity ); }
146 QString homeState() const { return find( Qtopia::HomeState ); } 146 QString homeState() const { return find( Qtopia::HomeState ); }
147 QString homeZip() const { return find( Qtopia::HomeZip ); } 147 QString homeZip() const { return find( Qtopia::HomeZip ); }
148 QString homeCountry() const { return find( Qtopia::HomeCountry ); } 148 QString homeCountry() const { return find( Qtopia::HomeCountry ); }
149 QString homePhone() const { return find( Qtopia::HomePhone ); } 149 QString homePhone() const { return find( Qtopia::HomePhone ); }
150 QString homeFax() const { return find( Qtopia::HomeFax ); } 150 QString homeFax() const { return find( Qtopia::HomeFax ); }
151 QString homeMobile() const { return find( Qtopia::HomeMobile ); } 151 QString homeMobile() const { return find( Qtopia::HomeMobile ); }
152 QString homeWebpage() const { return find( Qtopia::HomeWebPage ); } 152 QString homeWebpage() const { return find( Qtopia::HomeWebPage ); }
153 /** Multi line string containing all non-empty address info in the form 153 /** Multi line string containing all non-empty address info in the form
154 * Street 154 * Street
155 * City, State Zip 155 * City, State Zip
156 * Country 156 * Country
157 */ 157 */
158 QString displayHomeAddress() const; 158 QString displayHomeAddress() const;
159 159
160 // business 160 // business
161 QString company() const { return find( Qtopia::Company ); } 161 QString company() const { return find( Qtopia::Company ); }
162 QString businessStreet() const { return find( Qtopia::BusinessStreet ); } 162 QString businessStreet() const { return find( Qtopia::BusinessStreet ); }
163 QString businessCity() const { return find( Qtopia::BusinessCity ); } 163 QString businessCity() const { return find( Qtopia::BusinessCity ); }
164 QString businessState() const { return find( Qtopia::BusinessState ); } 164 QString businessState() const { return find( Qtopia::BusinessState ); }
165 QString businessZip() const { return find( Qtopia::BusinessZip ); } 165 QString businessZip() const { return find( Qtopia::BusinessZip ); }
166 QString businessCountry() const { return find( Qtopia::BusinessCountry ); } 166 QString businessCountry() const { return find( Qtopia::BusinessCountry ); }
167 QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); } 167 QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); }
168 QString jobTitle() const { return find( Qtopia::JobTitle ); } 168 QString jobTitle() const { return find( Qtopia::JobTitle ); }
169 QString department() const { return find( Qtopia::Department ); } 169 QString department() const { return find( Qtopia::Department ); }
170 QString office() const { return find( Qtopia::Office ); } 170 QString office() const { return find( Qtopia::Office ); }
171 QString businessPhone() const { return find( Qtopia::BusinessPhone ); } 171 QString businessPhone() const { return find( Qtopia::BusinessPhone ); }
172 QString businessFax() const { return find( Qtopia::BusinessFax ); } 172 QString businessFax() const { return find( Qtopia::BusinessFax ); }
173 QString businessMobile() const { return find( Qtopia::BusinessMobile ); } 173 QString businessMobile() const { return find( Qtopia::BusinessMobile ); }
174 QString businessPager() const { return find( Qtopia::BusinessPager ); } 174 QString businessPager() const { return find( Qtopia::BusinessPager ); }
175 QString profession() const { return find( Qtopia::Profession ); } 175 QString profession() const { return find( Qtopia::Profession ); }
176 QString assistant() const { return find( Qtopia::Assistant ); } 176 QString assistant() const { return find( Qtopia::Assistant ); }
177 QString manager() const { return find( Qtopia::Manager ); } 177 QString manager() const { return find( Qtopia::Manager ); }
178 /** Multi line string containing all non-empty address info in the form 178 /** Multi line string containing all non-empty address info in the form
179 * Street 179 * Street
180 * City, State Zip 180 * City, State Zip
181 * Country 181 * Country
182 */ 182 */
183 QString displayBusinessAddress() const; 183 QString displayBusinessAddress() const;
184 184
185 //personal 185 //personal
186 QString spouse() const { return find( Qtopia::Spouse ); } 186 QString spouse() const { return find( Qtopia::Spouse ); }
187 QString gender() const { return find( Qtopia::Gender ); } 187 QString gender() const { return find( Qtopia::Gender ); }
188 QDate birthday() const; 188 QDate birthday() const;
189 QDate anniversary() const; 189 QDate anniversary() const;
190 QString nickname() const { return find( Qtopia::Nickname ); } 190 QString nickname() const { return find( Qtopia::Nickname ); }
191 QString children() const { return find( Qtopia::Children ); } 191 QString children() const { return find( Qtopia::Children ); }
192 QStringList childrenList() const; 192 QStringList childrenList() const;
193 193
194 // other 194 // other
195 QString notes() const { return find( Qtopia::Notes ); } 195 QString notes() const { return find( Qtopia::Notes ); }
196 QString groups() const { return find( Qtopia::Groups ); } 196 QString groups() const { return find( Qtopia::Groups ); }
197 QStringList groupList() const; 197 QStringList groupList() const;
198 198
199// // custom
200// const QString &customField( const QString &key )
201// { return find( Custom- + key ); }
202
203
204 QString toRichText() const; 199 QString toRichText() const;
205 QMap<int, QString> toMap() const; 200 QMap<int, QString> toMap() const;
206 QString field( int key ) const { return find( key ); } 201 QString field( int key ) const { return find( key ); }
207 202
208 203
209 void setUid( int i ); 204 void setUid( int i );
210 205
211 QString toShortText()const; 206 QString toShortText()const;
212 QString OContact::type()const; 207 QString type()const;
213 QMap<QString,QString> OContact::toExtraMap() const; 208 class QString recordField(int) const;
214 class QString OContact::recordField(int) const;
215 209
216 // Why private ? (eilers,se) 210 // Why private ? (eilers,se)
217 QString emailSeparator() const { return " "; } 211 QString emailSeparator() const { return " "; }
212
218 // the emails should be seperated by a comma 213 // the emails should be seperated by a comma
219 void setEmails( const QString &v ); 214 void setEmails( const QString &v );
220 QString emails() const { return find( Qtopia::Emails ); } 215 QString emails() const { return find( Qtopia::Emails ); }
221 static int rtti(); 216 static int rtti();
222 217
223private: 218private:
224 // The XML-Backend needs some access to the private functions 219 // The XML Backend needs some access to the private functions
225 friend class OContactAccessBackend_XML; 220 friend class OContactAccessBackend_XML;
226 221
227 void insert( int key, const QString &value ); 222 void insert( int key, const QString &value );
228 void replace( int key, const QString &value ); 223 void replace( int key, const QString &value );
229 QString find( int key ) const; 224 QString find( int key ) const;
230 static QStringList fields(); 225 static QStringList fields();
231 226
232 void save( QString &buf ) const; 227 void save( QString &buf ) const;
233 228
234 QString displayAddress( const QString &street, 229 QString displayAddress( const QString &street,
235 const QString &city, 230 const QString &city,
236 const QString &state, 231 const QString &state,
237 const QString &zip, 232 const QString &zip,
238 const QString &country ) const; 233 const QString &country ) const;
239 234
240 QMap<int, QString> mMap; 235 QMap<int, QString> mMap;
241 OContactPrivate *d; 236 OContactPrivate *d;
242}; 237};
243 238
244 239
245#endif 240#endif
diff --git a/libopie/pim/ocontactaccessbackend_sql.cpp b/libopie/pim/ocontactaccessbackend_sql.cpp
new file mode 100644
index 0000000..4afa5f3
--- a/dev/null
+++ b/libopie/pim/ocontactaccessbackend_sql.cpp
@@ -0,0 +1,664 @@
1/*
2 * SQL Backend for the OPIE-Contact Database.
3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 *
6 * =====================================================================
7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * =====================================================================
12 * =====================================================================
13 * Version: $Id$
14 * =====================================================================
15 * History:
16 * $Log$
17 * Revision 1.1 2003/09/22 14:31:16 eilers
18 * Added first experimental incarnation of sql-backend for addressbook.
19 * Some modifications to be able to compile the todo sql-backend.
20 * A lot of changes fill follow...
21 *
22 */
23
24#include "ocontactaccessbackend_sql.h"
25
26#include <qarray.h>
27#include <qdatetime.h>
28#include <qstringlist.h>
29
30#include <qpe/global.h>
31#include <qpe/recordfields.h>
32
33#include <opie/ocontactfields.h>
34#include <opie/oconversion.h>
35#include <opie2/osqldriver.h>
36#include <opie2/osqlresult.h>
37#include <opie2/osqlmanager.h>
38#include <opie2/osqlquery.h>
39
40/*
41 * Implementation of used query types
42 * CREATE query
43 * LOAD query
44 * INSERT
45 * REMOVE
46 * CLEAR
47 */
48namespace {
49 /**
50 * CreateQuery for the Todolist Table
51 */
52 class CreateQuery : public OSQLQuery {
53 public:
54 CreateQuery();
55 ~CreateQuery();
56 QString query()const;
57 };
58
59 /**
60 * Clears (delete) a Table
61 */
62 class ClearQuery : public OSQLQuery {
63 public:
64 ClearQuery();
65 ~ClearQuery();
66 QString query()const;
67
68 };
69
70
71 /**
72 * LoadQuery
73 * this one queries for all uids
74 */
75 class LoadQuery : public OSQLQuery {
76 public:
77 LoadQuery();
78 ~LoadQuery();
79 QString query()const;
80 };
81
82 /**
83 * inserts/adds a OContact to the table
84 */
85 class InsertQuery : public OSQLQuery {
86 public:
87 InsertQuery(const OContact& );
88 ~InsertQuery();
89 QString query()const;
90 private:
91 OContact m_contact;
92 };
93
94
95 /**
96 * removes one from the table
97 */
98 class RemoveQuery : public OSQLQuery {
99 public:
100 RemoveQuery(int uid );
101 ~RemoveQuery();
102 QString query()const;
103 private:
104 int m_uid;
105 };
106
107 /**
108 * a find query for noncustom elements
109 */
110 class FindQuery : public OSQLQuery {
111 public:
112 FindQuery(int uid);
113 FindQuery(const QArray<int>& );
114 ~FindQuery();
115 QString query()const;
116 private:
117 QString single()const;
118 QString multi()const;
119 QArray<int> m_uids;
120 int m_uid;
121 };
122
123 /**
124 * a find query for custom elements
125 */
126 class FindCustomQuery : public OSQLQuery {
127 public:
128 FindCustomQuery(int uid);
129 FindCustomQuery(const QArray<int>& );
130 ~FindCustomQuery();
131 QString query()const;
132 private:
133 QString single()const;
134 QString multi()const;
135 QArray<int> m_uids;
136 int m_uid;
137 };
138
139
140
141 // We using three tables to store the information:
142 // 1. addressbook : It contains General information about the contact (non custom)
143 // 2. dates : Stuff like birthdays, anniversaries, etc.
144 // 3. custom_data : Not official supported entries
145 // All tables are connected by the uid of the contact.
146 // Maybe I should add a table for meta-information ?
147 CreateQuery::CreateQuery() : OSQLQuery() {}
148 CreateQuery::~CreateQuery() {}
149 QString CreateQuery::query()const {
150 QString qu;
151 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));";
152 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
153 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );";
154 return qu;
155 }
156
157 ClearQuery::ClearQuery()
158 : OSQLQuery() {}
159 ClearQuery::~ClearQuery() {}
160 QString ClearQuery::query()const {
161 QString qu = "drop table addressbook;";
162 qu += "drop table custom_data;";
163 qu += "drop table dates;";
164 return qu;
165 }
166
167// Distinct loading is not very fast. If I expect that every person has just
168// one (and always one) 'Last Name', I can request all uid's for existing lastnames,
169// which is faster..
170// But this may not be true for all entries, like company contacts..
171// The current AddressBook application handles this problem, but other may not.. (eilers)
172#define __USE_SUPERFAST_LOADQUERY
173
174 LoadQuery::LoadQuery() : OSQLQuery() {}
175 LoadQuery::~LoadQuery() {}
176 QString LoadQuery::query()const {
177 QString qu;
178#ifndef __USE_SUPERFAST_LOADQUERY
179 qu += "select distinct uid from addressbook";
180#else
181 qu += "select uid from addressbook where type = 'Last Name'";
182#endif
183
184 return qu;
185 }
186
187
188 InsertQuery::InsertQuery( const OContact& contact )
189 : OSQLQuery(), m_contact( contact ) {
190 }
191
192 InsertQuery::~InsertQuery() {
193 }
194
195 /*
196 * converts from a OContact to a query
197 */
198 QString InsertQuery::query()const{
199
200 // Get all information out of the contact-class
201 // Remember: The category is stored in contactMap, too !
202 QMap<int, QString> contactMap = m_contact.toMap();
203 QMap<QString, QString> customMap = m_contact.toExtraMap();
204
205 QMap<QString, QString> addressbook_db;
206
207 // Get the translation from the ID to the String
208 QMap<int, QString> transMap = OContactFields::idToUntrFields();
209
210 for( QMap<int, QString>::Iterator it = contactMap.begin();
211 it != contactMap.end(); ++it ){
212 switch ( it.key() ){
213 case Qtopia::Birthday:{
214 // These entries should stored in a special format
215 // year-month-day
216 QDate day = m_contact.birthday();
217 addressbook_db.insert( transMap[it.key()],
218 QString("%1-%2-%3")
219 .arg( day.year() )
220 .arg( day.month() )
221 .arg( day.day() ) );
222 }
223 break;
224 case Qtopia::Anniversary:{
225 // These entries should stored in a special format
226 // year-month-day
227 QDate day = m_contact.anniversary();
228 addressbook_db.insert( transMap[it.key()],
229 QString("%1-%2-%3")
230 .arg( day.year() )
231 .arg( day.month() )
232 .arg( day.day() ) );
233 }
234 break;
235 case Qtopia::AddressUid: // Ignore UID
236 break;
237 default: // Translate id to String
238 addressbook_db.insert( transMap[it.key()], it.data() );
239 break;
240 }
241
242 }
243
244 // Now convert this whole stuff into a SQL String, beginning with
245 // the addressbook table..
246 QString qu;
247 // qu += "begin transaction;";
248 int id = 0;
249 for( QMap<QString, QString>::Iterator it = addressbook_db.begin();
250 it != addressbook_db.end(); ++it ){
251 qu += "insert into addressbook VALUES("
252 + QString::number( m_contact.uid() )
253 + ","
254 + QString::number( id++ )
255 + ",'"
256 + it.key() //.latin1()
257 + "',"
258 + "0" // Priority for future enhancements
259 + ",'"
260 + it.data() //.latin1()
261 + "');";
262 }
263
264 // Now add custom data..
265 id = 0;
266 for( QMap<QString, QString>::Iterator it = customMap.begin();
267 it != customMap.end(); ++it ){
268 qu += "insert into custom_data VALUES("
269 + QString::number( m_contact.uid() )
270 + ","
271 + QString::number( id++ )
272 + ",'"
273 + it.key() //.latin1()
274 + "',"
275 + "0" // Priority for future enhancements
276 + ",'"
277 + it.data() //.latin1()
278 + "');";
279 }
280
281 // qu += "commit;";
282 qWarning("add %s", qu.latin1() );
283 return qu;
284 }
285
286
287 RemoveQuery::RemoveQuery(int uid )
288 : OSQLQuery(), m_uid( uid ) {}
289 RemoveQuery::~RemoveQuery() {}
290 QString RemoveQuery::query()const {
291 QString qu = "DELETE from addressbook where uid = "
292 + QString::number(m_uid) + ";";
293 qu += "DELETE from dates where uid = "
294 + QString::number(m_uid) + ";";
295 qu += "DELETE from custom_data where uid = "
296 + QString::number(m_uid) + ";";
297 return qu;
298 }
299
300
301
302
303 FindQuery::FindQuery(int uid)
304 : OSQLQuery(), m_uid( uid ) {
305 }
306 FindQuery::FindQuery(const QArray<int>& ints)
307 : OSQLQuery(), m_uids( ints ){
308 }
309 FindQuery::~FindQuery() {
310 }
311 QString FindQuery::query()const{
312 // if ( m_uids.count() == 0 )
313 return single();
314 }
315 /*
316 else
317 return multi();
318 }
319 QString FindQuery::multi()const {
320 QString qu = "select uid, type, value from addressbook where";
321 for (uint i = 0; i < m_uids.count(); i++ ) {
322 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
323 }
324 qu.remove( qu.length()-2, 2 ); // Hmmmm..
325 return qu;
326 }
327 */
328 QString FindQuery::single()const{
329 QString qu = "select uid, type, value from addressbook where uid = ";
330 qu += QString::number(m_uid);
331 return qu;
332 }
333
334
335 FindCustomQuery::FindCustomQuery(int uid)
336 : OSQLQuery(), m_uid( uid ) {
337 }
338 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
339 : OSQLQuery(), m_uids( ints ){
340 }
341 FindCustomQuery::~FindCustomQuery() {
342 }
343 QString FindCustomQuery::query()const{
344 // if ( m_uids.count() == 0 )
345 return single();
346 }
347 QString FindCustomQuery::single()const{
348 QString qu = "select uid, type, value from custom_data where uid = ";
349 qu += QString::number(m_uid);
350 return qu;
351 }
352
353};
354
355
356/* --------------------------------------------------------------------------- */
357
358OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */,
359 const QString& filename ): m_changed(false)
360{
361 qWarning("C'tor OContactAccessBackend_SQL starts");
362 QTime t;
363 t.start();
364
365 /* Expecting to access the default filename if nothing else is set */
366 if ( filename.isEmpty() ){
367 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
368 } else
369 m_fileName = filename;
370
371 // Get the standart sql-driver from the OSQLManager..
372 OSQLManager man;
373 m_driver = man.standard();
374 m_driver->setUrl( m_fileName );
375
376 load();
377
378 qWarning("C'tor OContactAccessBackend_SQL ends: %d", t.elapsed() );
379}
380
381
382bool OContactAccessBackend_SQL::load ()
383{
384 if (!m_driver->open() )
385 return false;
386
387 // Don't expect that the database exists.
388 // It is save here to create the table, even if it
389 // do exist. ( Is that correct for all databases ?? )
390 CreateQuery creat;
391 OSQLResult res = m_driver->query( &creat );
392
393 update();
394
395 return true;
396
397}
398
399bool OContactAccessBackend_SQL::reload()
400{
401 return load();
402}
403
404bool OContactAccessBackend_SQL::save()
405{
406 return m_driver->close();
407}
408
409
410void OContactAccessBackend_SQL::clear ()
411{
412 ClearQuery cle;
413 OSQLResult res = m_driver->query( &cle );
414 CreateQuery qu;
415 res = m_driver->query(&qu);
416}
417
418bool OContactAccessBackend_SQL::wasChangedExternally()
419{
420 return false;
421}
422
423QArray<int> OContactAccessBackend_SQL::allRecords() const
424{
425
426 // FIXME: Think about cute handling of changed tables..
427 // Thus, we don't have to call update here...
428 if ( m_changed )
429 ((OContactAccessBackend_SQL*)this)->update();
430
431 return m_uids;
432}
433
434bool OContactAccessBackend_SQL::add ( const OContact &newcontact )
435{
436 InsertQuery ins( newcontact );
437 OSQLResult res = m_driver->query( &ins );
438
439 if ( res.state() == OSQLResult::Failure )
440 return false;
441
442 int c = m_uids.count();
443 m_uids.resize( c+1 );
444 m_uids[c] = newcontact.uid();
445
446 return true;
447}
448
449
450bool OContactAccessBackend_SQL::remove ( int uid )
451{
452 RemoveQuery rem( uid );
453 OSQLResult res = m_driver->query(&rem );
454
455 if ( res.state() == OSQLResult::Failure )
456 return false;
457
458 m_changed = true;
459
460 return true;
461}
462
463bool OContactAccessBackend_SQL::replace ( const OContact &contact )
464{
465 if ( !remove( contact.uid() ) )
466 return false;
467
468 return add( contact );
469}
470
471
472OContact OContactAccessBackend_SQL::find ( int uid ) const
473{
474 qWarning("OContactAccessBackend_SQL::find()");
475 QTime t;
476 t.start();
477
478 OContact retContact( requestNonCustom( uid ) );
479 retContact.setExtraMap( requestCustom( uid ) );
480
481 qWarning("OContactAccessBackend_SQL::find() needed: %d", t.elapsed() );
482 return retContact;
483}
484
485
486
487QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() )
488{
489 QArray<int> nix(0);
490 return nix;
491}
492
493QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
494{
495 QArray<int> nix(0);
496 return nix;
497}
498
499const uint OContactAccessBackend_SQL::querySettings()
500{
501 return 0;
502}
503
504bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
505{
506 return false;
507}
508
509QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int )
510{
511 QTime t;
512 t.start();
513
514 // Not implemented..
515 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' ";
516
517 query += "ORDER BY value ";
518 if ( !asc )
519 query += "DESC";
520
521 qWarning("sorted query is: %s", query.latin1() );
522
523 OSQLRawQuery raw( query );
524 OSQLResult res = m_driver->query( &raw );
525 if ( res.state() != OSQLResult::Success ){
526 QArray<int> empty;
527 return empty;
528 }
529
530 QArray<int> list = extractUids( res );
531
532 qWarning("sorted needed %d ms!", t.elapsed() );
533 return list;
534}
535
536
537void OContactAccessBackend_SQL::update()
538{
539 qWarning("Update starts");
540 QTime t;
541 t.start();
542
543 // Now load the database set and extract the uid's
544 // which will be held locally
545
546 LoadQuery lo;
547 OSQLResult res = m_driver->query(&lo);
548 if ( res.state() != OSQLResult::Success )
549 return;
550
551 m_uids = extractUids( res );
552
553 m_changed = false;
554
555 qWarning("Update ends %d", t.elapsed() );
556}
557
558QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
559{
560 qWarning("extractUids");
561 QTime t;
562 t.start();
563 OSQLResultItem::ValueList list = res.results();
564 OSQLResultItem::ValueList::Iterator it;
565 QArray<int> ints(list.count() );
566 qWarning(" count = %d", list.count() );
567
568 int i = 0;
569 for (it = list.begin(); it != list.end(); ++it ) {
570 ints[i] = (*it).data("uid").toInt();
571 i++;
572 }
573 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
574
575 return ints;
576
577}
578
579QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
580{
581 QTime t;
582 t.start();
583
584 QMap<int, QString> nonCustomMap;
585
586 int t2needed = 0;
587 QTime t2;
588 t2.start();
589 FindQuery query( uid );
590 OSQLResult res_noncustom = m_driver->query( &query );
591 t2needed = t2.elapsed();
592
593 if ( res_noncustom.state() == OSQLResult::Failure ) {
594 qWarning("OSQLResult::Failure in find query !!");
595 QMap<int, QString> empty;
596 return empty;
597 }
598
599 int t3needed = 0;
600 QTime t3;
601 t3.start();
602 QMap<QString, int> translateMap = OContactFields::untrFieldsToId();
603
604 OSQLResultItem::ValueList list = res_noncustom.results();
605 OSQLResultItem::ValueList::Iterator it = list.begin();
606 for ( ; it != list.end(); ++it ) {
607 if ( (*it).data("type") != "" ){
608 int typeId = translateMap[(*it).data( "type" )];
609 switch( typeId ){
610 case Qtopia::Birthday:
611 case Qtopia::Anniversary:{
612 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
613 QStringList list = QStringList::split( '-', (*it).data( "value" ) );
614 QStringList::Iterator lit = list.begin();
615 int year = (*lit).toInt();
616 qWarning("1. %s", (*lit).latin1());
617 int month = (*(++lit)).toInt();
618 qWarning("2. %s", (*lit).latin1());
619 int day = (*(++lit)).toInt();
620 qWarning("3. %s", (*lit).latin1());
621 qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day );
622 QDate date( year, month, day );
623 nonCustomMap.insert( typeId, OConversion::dateToString( date ) );
624 }
625 break;
626 default:
627 nonCustomMap.insert( typeId,
628 (*it).data( "value" ) );
629 }
630 }
631 }
632 // Add UID to Map..
633 nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) );
634 t3needed = t3.elapsed();
635
636 qWarning("RequestNonCustom needed: ins:%d, query: %d, mapping: %d", t.elapsed(), t2needed, t3needed );
637 return nonCustomMap;
638}
639
640QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const
641{
642 QTime t;
643 t.start();
644
645 QMap<QString, QString> customMap;
646
647 FindCustomQuery query( uid );
648 OSQLResult res_custom = m_driver->query( &query );
649
650 if ( res_custom.state() == OSQLResult::Failure ) {
651 qWarning("OSQLResult::Failure in find query !!");
652 QMap<QString, QString> empty;
653 return empty;
654 }
655
656 OSQLResultItem::ValueList list = res_custom.results();
657 OSQLResultItem::ValueList::Iterator it = list.begin();
658 for ( ; it != list.end(); ++it ) {
659 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
660 }
661
662 qWarning("RequestCustom needed: %d", t.elapsed() );
663 return customMap;
664}
diff --git a/libopie/pim/ocontactaccessbackend_sql.h b/libopie/pim/ocontactaccessbackend_sql.h
new file mode 100644
index 0000000..bb22551
--- a/dev/null
+++ b/libopie/pim/ocontactaccessbackend_sql.h
@@ -0,0 +1,96 @@
1/*
2 * SQL Backend for the OPIE-Contact Database.
3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 *
6 * =====================================================================
7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * =====================================================================
12 *
13 *
14 * =====================================================================
15 * Version: $Id$
16 * =====================================================================
17 * History:
18 * $Log$
19 * Revision 1.1 2003/09/22 14:31:16 eilers
20 * Added first experimental incarnation of sql-backend for addressbook.
21 * Some modifications to be able to compile the todo sql-backend.
22 * A lot of changes fill follow...
23 *
24 *
25 */
26
27#ifndef _OContactAccessBackend_SQL_
28#define _OContactAccessBackend_SQL_
29
30#include "ocontactaccessbackend.h"
31#include "ocontactaccess.h"
32
33#include <qlist.h>
34#include <qdict.h>
35
36class OSQLDriver;
37class OSQLResult;
38class OSQLResultItem;
39
40/* the default xml implementation */
41/**
42 * This class is the SQL implementation of a Contact backend
43 * it does implement everything available for OContact.
44 * @see OPimAccessBackend for more information of available methods
45 */
46class OContactAccessBackend_SQL : public OContactAccessBackend {
47 public:
48 OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null );
49
50 bool save();
51
52 bool load ();
53
54 void clear ();
55
56 bool wasChangedExternally();
57
58 QArray<int> allRecords() const;
59
60 OContact find ( int uid ) const;
61 // FIXME: Add lookahead-cache support !
62 //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
63
64 QArray<int> queryByExample ( const OContact &query, int settings,
65 const QDateTime& d );
66
67 QArray<int> matchRegexp( const QRegExp &r ) const;
68
69 const uint querySettings();
70
71 bool hasQuerySettings (uint querySettings) const;
72
73 // Currently only asc implemented..
74 QArray<int> sorted( bool asc, int , int , int );
75 bool add ( const OContact &newcontact );
76
77 bool replace ( const OContact &contact );
78
79 bool remove ( int uid );
80 bool reload();
81
82 private:
83 QArray<int> extractUids( OSQLResult& res ) const;
84 QMap<int, QString> requestNonCustom( int uid ) const;
85 QMap<QString, QString> requestCustom( int uid ) const;
86 void update();
87
88 protected:
89 bool m_changed;
90 QString m_fileName;
91 QArray<int> m_uids;
92
93 OSQLDriver* m_driver;
94};
95
96#endif
diff --git a/libopie/pim/ocontactaccessbackend_xml.cpp b/libopie/pim/ocontactaccessbackend_xml.cpp
index 1b5af2f..aae7fca 100644
--- a/libopie/pim/ocontactaccessbackend_xml.cpp
+++ b/libopie/pim/ocontactaccessbackend_xml.cpp
@@ -1,83 +1,86 @@
1/* 1/*
2 * XML Backend for the OPIE-Contact Database. 2 * XML Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 *
14 * 12 *
15 * ===================================================================== 13 * =====================================================================
16 * Version: $Id$ 14 * Version: $Id$
17 * ===================================================================== 15 * =====================================================================
18 * History: 16 * History:
19 * $Log$ 17 * $Log$
18 * Revision 1.9 2003/09/22 14:31:16 eilers
19 * Added first experimental incarnation of sql-backend for addressbook.
20 * Some modifications to be able to compile the todo sql-backend.
21 * A lot of changes fill follow...
22 *
20 * Revision 1.8 2003/08/30 15:28:26 eilers 23 * Revision 1.8 2003/08/30 15:28:26 eilers
21 * Removed some unimportant debug output which causes slow down.. 24 * Removed some unimportant debug output which causes slow down..
22 * 25 *
23 * Revision 1.7 2003/08/01 12:30:16 eilers 26 * Revision 1.7 2003/08/01 12:30:16 eilers
24 * Merging changes from BRANCH_1_0 to HEAD 27 * Merging changes from BRANCH_1_0 to HEAD
25 * 28 *
26 * Revision 1.6 2003/07/07 16:19:47 eilers 29 * Revision 1.6 2003/07/07 16:19:47 eilers
27 * Fixing serious bug in hasQuerySettings() 30 * Fixing serious bug in hasQuerySettings()
28 * 31 *
29 * Revision 1.5 2003/04/13 18:07:10 zecke 32 * Revision 1.5 2003/04/13 18:07:10 zecke
30 * More API doc 33 * More API doc
31 * QString -> const QString& 34 * QString -> const QString&
32 * QString = 0l -> QString::null 35 * QString = 0l -> QString::null
33 * 36 *
34 * Revision 1.4 2003/03/21 14:32:54 mickeyl 37 * Revision 1.4 2003/03/21 14:32:54 mickeyl
35 * g++ compliance fix: default arguments belong into the declaration, but not the definition 38 * g++ compliance fix: default arguments belong into the declaration, but not the definition
36 * 39 *
37 * Revision 1.3 2003/03/21 12:26:28 eilers 40 * Revision 1.3 2003/03/21 12:26:28 eilers
38 * Fixing small bug: If we search a birthday from today to today, it returned 41 * Fixing small bug: If we search a birthday from today to today, it returned
39 * every contact .. 42 * every contact ..
40 * 43 *
41 * Revision 1.2 2003/03/21 10:33:09 eilers 44 * Revision 1.2 2003/03/21 10:33:09 eilers
42 * Merged speed optimized xml backend for contacts to main. 45 * Merged speed optimized xml backend for contacts to main.
43 * Added QDateTime to querybyexample. For instance, it is now possible to get 46 * Added QDateTime to querybyexample. For instance, it is now possible to get
44 * all Birthdays/Anniversaries between two dates. This should be used 47 * all Birthdays/Anniversaries between two dates. This should be used
45 * to show all birthdays in the datebook.. 48 * to show all birthdays in the datebook..
46 * This change is sourcecode backward compatible but you have to upgrade 49 * This change is sourcecode backward compatible but you have to upgrade
47 * the binaries for today-addressbook. 50 * the binaries for today-addressbook.
48 * 51 *
49 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers 52 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers
50 * Speed optimization. Removed the sequential search loops. 53 * Speed optimization. Removed the sequential search loops.
51 * 54 *
52 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers 55 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers
53 * Writing offsets to debug output.. 56 * Writing offsets to debug output..
54 * 57 *
55 * Revision 1.1 2003/02/09 15:05:01 eilers 58 * Revision 1.1 2003/02/09 15:05:01 eilers
56 * Nothing happened.. Just some cleanup before I will start.. 59 * Nothing happened.. Just some cleanup before I will start..
57 * 60 *
58 * Revision 1.12 2003/01/03 16:58:03 eilers 61 * Revision 1.12 2003/01/03 16:58:03 eilers
59 * Reenable debug output 62 * Reenable debug output
60 * 63 *
61 * Revision 1.11 2003/01/03 12:31:28 eilers 64 * Revision 1.11 2003/01/03 12:31:28 eilers
62 * Bugfix for calculating data diffs.. 65 * Bugfix for calculating data diffs..
63 * 66 *
64 * Revision 1.10 2003/01/02 14:27:12 eilers 67 * Revision 1.10 2003/01/02 14:27:12 eilers
65 * Improved query by example: Search by date is possible.. First step 68 * Improved query by example: Search by date is possible.. First step
66 * for a today plugin for birthdays.. 69 * for a today plugin for birthdays..
67 * 70 *
68 * Revision 1.9 2002/12/08 12:48:57 eilers 71 * Revision 1.9 2002/12/08 12:48:57 eilers
69 * Moved journal-enum from ocontact into i the xml-backend.. 72 * Moved journal-enum from ocontact into i the xml-backend..
70 * 73 *
71 * Revision 1.8 2002/11/14 17:04:24 eilers 74 * Revision 1.8 2002/11/14 17:04:24 eilers
72 * Sorting will now work if fullname is identical on some entries 75 * Sorting will now work if fullname is identical on some entries
73 * 76 *
74 * Revision 1.7 2002/11/13 15:02:46 eilers 77 * Revision 1.7 2002/11/13 15:02:46 eilers
75 * Small Bug in sorted fixed 78 * Small Bug in sorted fixed
76 * 79 *
77 * Revision 1.6 2002/11/13 14:14:51 eilers 80 * Revision 1.6 2002/11/13 14:14:51 eilers
78 * Added sorted for Contacts.. 81 * Added sorted for Contacts..
79 * 82 *
80 * Revision 1.5 2002/11/01 15:10:42 eilers 83 * Revision 1.5 2002/11/01 15:10:42 eilers
81 * Added regExp-search in database for all fields in a contact. 84 * Added regExp-search in database for all fields in a contact.
82 * 85 *
83 * Revision 1.4 2002/10/16 10:52:40 eilers 86 * Revision 1.4 2002/10/16 10:52:40 eilers
diff --git a/libopie/pim/ocontactaccessbackend_xml.h b/libopie/pim/ocontactaccessbackend_xml.h
index 7b5365b..a0cae4d 100644
--- a/libopie/pim/ocontactaccessbackend_xml.h
+++ b/libopie/pim/ocontactaccessbackend_xml.h
@@ -1,83 +1,89 @@
1/* 1/*
2 * XML Backend for the OPIE-Contact Database. 2 * XML Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed... 12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 * File Locking to protect against concurrent access
13 * 14 *
14 * 15 *
15 * ===================================================================== 16 * =====================================================================
16 * Version: $Id$ 17 * Version: $Id$
17 * ===================================================================== 18 * =====================================================================
18 * History: 19 * History:
19 * $Log$ 20 * $Log$
21 * Revision 1.15 2003/09/22 14:31:16 eilers
22 * Added first experimental incarnation of sql-backend for addressbook.
23 * Some modifications to be able to compile the todo sql-backend.
24 * A lot of changes fill follow...
25 *
20 * Revision 1.14 2003/04/13 18:07:10 zecke 26 * Revision 1.14 2003/04/13 18:07:10 zecke
21 * More API doc 27 * More API doc
22 * QString -> const QString& 28 * QString -> const QString&
23 * QString = 0l -> QString::null 29 * QString = 0l -> QString::null
24 * 30 *
25 * Revision 1.13 2003/03/21 10:33:09 eilers 31 * Revision 1.13 2003/03/21 10:33:09 eilers
26 * Merged speed optimized xml backend for contacts to main. 32 * Merged speed optimized xml backend for contacts to main.
27 * Added QDateTime to querybyexample. For instance, it is now possible to get 33 * Added QDateTime to querybyexample. For instance, it is now possible to get
28 * all Birthdays/Anniversaries between two dates. This should be used 34 * all Birthdays/Anniversaries between two dates. This should be used
29 * to show all birthdays in the datebook.. 35 * to show all birthdays in the datebook..
30 * This change is sourcecode backward compatible but you have to upgrade 36 * This change is sourcecode backward compatible but you have to upgrade
31 * the binaries for today-addressbook. 37 * the binaries for today-addressbook.
32 * 38 *
33 * Revision 1.12.2.2 2003/02/11 12:17:28 eilers 39 * Revision 1.12.2.2 2003/02/11 12:17:28 eilers
34 * Speed optimization. Removed the sequential search loops. 40 * Speed optimization. Removed the sequential search loops.
35 * 41 *
36 * Revision 1.12.2.1 2003/02/09 15:05:01 eilers 42 * Revision 1.12.2.1 2003/02/09 15:05:01 eilers
37 * Nothing happened.. Just some cleanup before I will start.. 43 * Nothing happened.. Just some cleanup before I will start..
38 * 44 *
39 * Revision 1.12 2003/01/03 16:58:03 eilers 45 * Revision 1.12 2003/01/03 16:58:03 eilers
40 * Reenable debug output 46 * Reenable debug output
41 * 47 *
42 * Revision 1.11 2003/01/03 12:31:28 eilers 48 * Revision 1.11 2003/01/03 12:31:28 eilers
43 * Bugfix for calculating data diffs.. 49 * Bugfix for calculating data diffs..
44 * 50 *
45 * Revision 1.10 2003/01/02 14:27:12 eilers 51 * Revision 1.10 2003/01/02 14:27:12 eilers
46 * Improved query by example: Search by date is possible.. First step 52 * Improved query by example: Search by date is possible.. First step
47 * for a today plugin for birthdays.. 53 * for a today plugin for birthdays..
48 * 54 *
49 * Revision 1.9 2002/12/08 12:48:57 eilers 55 * Revision 1.9 2002/12/08 12:48:57 eilers
50 * Moved journal-enum from ocontact into i the xml-backend.. 56 * Moved journal-enum from ocontact into i the xml-backend..
51 * 57 *
52 * Revision 1.8 2002/11/14 17:04:24 eilers 58 * Revision 1.8 2002/11/14 17:04:24 eilers
53 * Sorting will now work if fullname is identical on some entries 59 * Sorting will now work if fullname is identical on some entries
54 * 60 *
55 * Revision 1.7 2002/11/13 15:02:46 eilers 61 * Revision 1.7 2002/11/13 15:02:46 eilers
56 * Small Bug in sorted fixed 62 * Small Bug in sorted fixed
57 * 63 *
58 * Revision 1.6 2002/11/13 14:14:51 eilers 64 * Revision 1.6 2002/11/13 14:14:51 eilers
59 * Added sorted for Contacts.. 65 * Added sorted for Contacts..
60 * 66 *
61 * Revision 1.5 2002/11/01 15:10:42 eilers 67 * Revision 1.5 2002/11/01 15:10:42 eilers
62 * Added regExp-search in database for all fields in a contact. 68 * Added regExp-search in database for all fields in a contact.
63 * 69 *
64 * Revision 1.4 2002/10/16 10:52:40 eilers 70 * Revision 1.4 2002/10/16 10:52:40 eilers
65 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 71 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
66 * 72 *
67 * Revision 1.3 2002/10/14 16:21:54 eilers 73 * Revision 1.3 2002/10/14 16:21:54 eilers
68 * Some minor interface updates 74 * Some minor interface updates
69 * 75 *
70 * Revision 1.2 2002/10/07 17:34:24 eilers 76 * Revision 1.2 2002/10/07 17:34:24 eilers
71 * added OBackendFactory for advanced backend access 77 * added OBackendFactory for advanced backend access
72 * 78 *
73 * Revision 1.1 2002/09/27 17:11:44 eilers 79 * Revision 1.1 2002/09/27 17:11:44 eilers
74 * Added API for accessing the Contact-Database ! It is compiling, but 80 * Added API for accessing the Contact-Database ! It is compiling, but
75 * please do not expect that anything is working ! 81 * please do not expect that anything is working !
76 * I will debug that stuff in the next time .. 82 * I will debug that stuff in the next time ..
77 * Please read README_COMPILE for compiling ! 83 * Please read README_COMPILE for compiling !
78 * 84 *
79 * 85 *
80 */ 86 */
81 87
82#ifndef _OContactAccessBackend_XML_ 88#ifndef _OContactAccessBackend_XML_
83#define _OContactAccessBackend_XML_ 89#define _OContactAccessBackend_XML_
diff --git a/libopie/pim/ocontactfields.cpp b/libopie/pim/ocontactfields.cpp
new file mode 100644
index 0000000..831a596
--- a/dev/null
+++ b/libopie/pim/ocontactfields.cpp
@@ -0,0 +1,456 @@
1
2#include "ocontactfields.h"
3
4#include <qstringlist.h>
5#include <qobject.h>
6
7// We should use our own enum in the future ..
8#include <qpe/recordfields.h>
9#include <qpe/config.h>
10#include <opie/ocontact.h>
11
12/*!
13 \internal
14 Returns a list of details field names for a contact.
15*/
16QStringList OContactFields::untrdetailsfields( bool sorted )
17{
18 QStringList list;
19 QMap<int, QString> mapIdToStr = idToUntrFields();
20
21 list.append( mapIdToStr[ Qtopia::Office ] );
22 list.append( mapIdToStr[ Qtopia::Profession ] );
23 list.append( mapIdToStr[ Qtopia::Assistant ] );
24 list.append( mapIdToStr[ Qtopia::Manager ] );
25
26 list.append( mapIdToStr[ Qtopia::Spouse ] );
27 list.append( mapIdToStr[ Qtopia::Gender ] );
28 list.append( mapIdToStr[ Qtopia::Birthday ] );
29 list.append( mapIdToStr[ Qtopia::Anniversary ] );
30 list.append( mapIdToStr[ Qtopia::Nickname ] );
31 list.append( mapIdToStr[ Qtopia::Children ] );
32
33 if (sorted) list.sort();
34 return list;
35}
36
37/*!
38 \internal
39 Returns a translated list of details field names for a contact.
40*/
41QStringList OContactFields::trdetailsfields( bool sorted )
42{
43 QStringList list;
44 QMap<int, QString> mapIdToStr = idToTrFields();
45
46 list.append( mapIdToStr[Qtopia::Office] );
47 list.append( mapIdToStr[Qtopia::Profession] );
48 list.append( mapIdToStr[Qtopia::Assistant] );
49 list.append( mapIdToStr[Qtopia::Manager] );
50
51 list.append( mapIdToStr[Qtopia::Spouse] );
52 list.append( mapIdToStr[Qtopia::Gender] );
53 list.append( mapIdToStr[Qtopia::Birthday] );
54 list.append( mapIdToStr[Qtopia::Anniversary] );
55 list.append( mapIdToStr[Qtopia::Nickname] );
56 list.append( mapIdToStr[Qtopia::Children] );
57
58 if (sorted) list.sort();
59 return list;
60}
61
62
63/*!
64 \internal
65 Returns a translated list of phone field names for a contact.
66*/
67QStringList OContactFields::trphonefields( bool sorted )
68{
69 QStringList list;
70 QMap<int, QString> mapIdToStr = idToTrFields();
71
72 list.append( mapIdToStr[Qtopia::BusinessPhone] );
73 list.append( mapIdToStr[Qtopia::BusinessFax] );
74 list.append( mapIdToStr[Qtopia::BusinessMobile] );
75 list.append( mapIdToStr[Qtopia::BusinessPager] );
76 list.append( mapIdToStr[Qtopia::BusinessWebPage] );
77
78 list.append( mapIdToStr[Qtopia::DefaultEmail] );
79 list.append( mapIdToStr[Qtopia::Emails] );
80
81 list.append( mapIdToStr[Qtopia::HomePhone] );
82 list.append( mapIdToStr[Qtopia::HomeFax] );
83 list.append( mapIdToStr[Qtopia::HomeMobile] );
84 // list.append( mapIdToStr[Qtopia::HomePager] );
85 list.append( mapIdToStr[Qtopia::HomeWebPage] );
86
87 if (sorted) list.sort();
88
89 return list;
90}
91
92
93/*!
94 \internal
95 Returns a list of phone field names for a contact.
96*/
97QStringList OContactFields::untrphonefields( bool sorted )
98{
99 QStringList list;
100 QMap<int, QString> mapIdToStr = idToUntrFields();
101
102 list.append( mapIdToStr[ Qtopia::BusinessPhone ] );
103 list.append( mapIdToStr[ Qtopia::BusinessFax ] );
104 list.append( mapIdToStr[ Qtopia::BusinessMobile ] );
105 list.append( mapIdToStr[ Qtopia::BusinessPager ] );
106 list.append( mapIdToStr[ Qtopia::BusinessWebPage ] );
107
108 list.append( mapIdToStr[ Qtopia::DefaultEmail ] );
109 list.append( mapIdToStr[ Qtopia::Emails ] );
110
111 list.append( mapIdToStr[ Qtopia::HomePhone ] );
112 list.append( mapIdToStr[ Qtopia::HomeFax ] );
113 list.append( mapIdToStr[ Qtopia::HomeMobile ] );
114 //list.append( mapIdToStr[Qtopia::HomePager] );
115 list.append( mapIdToStr[Qtopia::HomeWebPage] );
116
117 if (sorted) list.sort();
118
119 return list;
120}
121
122
123/*!
124 \internal
125 Returns a translated list of field names for a contact.
126*/
127QStringList OContactFields::trfields( bool sorted )
128{
129 QStringList list;
130 QMap<int, QString> mapIdToStr = idToTrFields();
131
132 list.append( mapIdToStr[Qtopia::Title]);
133 list.append( mapIdToStr[Qtopia::FirstName] );
134 list.append( mapIdToStr[Qtopia::MiddleName] );
135 list.append( mapIdToStr[Qtopia::LastName] );
136 list.append( mapIdToStr[Qtopia::Suffix] );
137 list.append( mapIdToStr[Qtopia::FileAs] );
138
139 list.append( mapIdToStr[Qtopia::JobTitle] );
140 list.append( mapIdToStr[Qtopia::Department] );
141 list.append( mapIdToStr[Qtopia::Company] );
142
143 list += trphonefields( sorted );
144
145 list.append( mapIdToStr[Qtopia::BusinessStreet] );
146 list.append( mapIdToStr[Qtopia::BusinessCity] );
147 list.append( mapIdToStr[Qtopia::BusinessState] );
148 list.append( mapIdToStr[Qtopia::BusinessZip] );
149 list.append( mapIdToStr[Qtopia::BusinessCountry] );
150
151 list.append( mapIdToStr[Qtopia::HomeStreet] );
152 list.append( mapIdToStr[Qtopia::HomeCity] );
153 list.append( mapIdToStr[Qtopia::HomeState] );
154 list.append( mapIdToStr[Qtopia::HomeZip] );
155 list.append( mapIdToStr[Qtopia::HomeCountry] );
156
157 list += trdetailsfields( sorted );
158
159 list.append( mapIdToStr[Qtopia::Notes] );
160 list.append( mapIdToStr[Qtopia::Groups] );
161
162 if (sorted) list.sort();
163
164 return list;
165}
166
167/*!
168 \internal
169 Returns an untranslated list of field names for a contact.
170*/
171QStringList OContactFields::untrfields( bool sorted )
172{
173 QStringList list;
174 QMap<int, QString> mapIdToStr = idToUntrFields();
175
176 list.append( mapIdToStr[ Qtopia::Title ] );
177 list.append( mapIdToStr[ Qtopia::FirstName ] );
178 list.append( mapIdToStr[ Qtopia::MiddleName ] );
179 list.append( mapIdToStr[ Qtopia::LastName ] );
180 list.append( mapIdToStr[ Qtopia::Suffix ] );
181 list.append( mapIdToStr[ Qtopia::FileAs ] );
182
183 list.append( mapIdToStr[ Qtopia::JobTitle ] );
184 list.append( mapIdToStr[ Qtopia::Department ] );
185 list.append( mapIdToStr[ Qtopia::Company ] );
186
187 list += untrphonefields( sorted );
188
189 list.append( mapIdToStr[ Qtopia::BusinessStreet ] );
190 list.append( mapIdToStr[ Qtopia::BusinessCity ] );
191 list.append( mapIdToStr[ Qtopia::BusinessState ] );
192 list.append( mapIdToStr[ Qtopia::BusinessZip ] );
193 list.append( mapIdToStr[ Qtopia::BusinessCountry ] );
194
195 list.append( mapIdToStr[ Qtopia::HomeStreet ] );
196 list.append( mapIdToStr[ Qtopia::HomeCity ] );
197 list.append( mapIdToStr[ Qtopia::HomeState ] );
198 list.append( mapIdToStr[ Qtopia::HomeZip ] );
199 list.append( mapIdToStr[ Qtopia::HomeCountry ] );
200
201 list += untrdetailsfields( sorted );
202
203 list.append( mapIdToStr[ Qtopia::Notes ] );
204 list.append( mapIdToStr[ Qtopia::Groups ] );
205
206 if (sorted) list.sort();
207
208 return list;
209}
210QMap<int, QString> OContactFields::idToTrFields()
211{
212 QMap<int, QString> ret_map;
213
214 ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") );
215 ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) );
216 ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) );
217 ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) );
218 ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" ));
219 ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) );
220
221 ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) );
222 ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) );
223 ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) );
224 ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) );
225 ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) );
226 ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" ));
227
228 // email
229 ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) );
230 ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) );
231
232 ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) );
233 ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) );
234 ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) );
235
236 // business
237 ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) );
238 ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) );
239 ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) );
240 ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) );
241 ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) );
242 ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) );
243 ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) );
244
245 ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) );
246 ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) );
247 ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) );
248 ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) );
249
250 // home
251 ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) );
252 ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) );
253 ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) );
254 ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) );
255 ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) );
256 ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) );
257
258 //personal
259 ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) );
260 ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) );
261 ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) );
262 ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) );
263 ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) );
264 ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) );
265
266 // other
267 ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) );
268
269
270 return ret_map;
271}
272
273QMap<int, QString> OContactFields::idToUntrFields()
274{
275 QMap<int, QString> ret_map;
276
277 ret_map.insert( Qtopia::Title, "Name Title" );
278 ret_map.insert( Qtopia::FirstName, "First Name" );
279 ret_map.insert( Qtopia::MiddleName, "Middle Name" );
280 ret_map.insert( Qtopia::LastName, "Last Name" );
281 ret_map.insert( Qtopia::Suffix, "Suffix" );
282 ret_map.insert( Qtopia::FileAs, "File As" );
283
284 ret_map.insert( Qtopia::JobTitle, "Job Title" );
285 ret_map.insert( Qtopia::Department, "Department" );
286 ret_map.insert( Qtopia::Company, "Company" );
287 ret_map.insert( Qtopia::BusinessPhone, "Business Phone" );
288 ret_map.insert( Qtopia::BusinessFax, "Business Fax" );
289 ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" );
290
291 // email
292 ret_map.insert( Qtopia::DefaultEmail, "Default Email" );
293 ret_map.insert( Qtopia::Emails, "Emails" );
294
295 ret_map.insert( Qtopia::HomePhone, "Home Phone" );
296 ret_map.insert( Qtopia::HomeFax, "Home Fax" );
297 ret_map.insert( Qtopia::HomeMobile, "Home Mobile" );
298
299 // business
300 ret_map.insert( Qtopia::BusinessStreet, "Business Street" );
301 ret_map.insert( Qtopia::BusinessCity, "Business City" );
302 ret_map.insert( Qtopia::BusinessState, "Business State" );
303 ret_map.insert( Qtopia::BusinessZip, "Business Zip" );
304 ret_map.insert( Qtopia::BusinessCountry, "Business Country" );
305 ret_map.insert( Qtopia::BusinessPager, "Business Pager" );
306 ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" );
307
308 ret_map.insert( Qtopia::Office, "Office" );
309 ret_map.insert( Qtopia::Profession, "Profession" );
310 ret_map.insert( Qtopia::Assistant, "Assistant" );
311 ret_map.insert( Qtopia::Manager, "Manager" );
312
313 // home
314 ret_map.insert( Qtopia::HomeStreet, "Home Street" );
315 ret_map.insert( Qtopia::HomeCity, "Home City" );
316 ret_map.insert( Qtopia::HomeState, "Home State" );
317 ret_map.insert( Qtopia::HomeZip, "Home Zip" );
318 ret_map.insert( Qtopia::HomeCountry, "Home Country" );
319 ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" );
320
321 //personal
322 ret_map.insert( Qtopia::Spouse, "Spouse" );
323 ret_map.insert( Qtopia::Gender, "Gender" );
324 ret_map.insert( Qtopia::Birthday, "Birthday" );
325 ret_map.insert( Qtopia::Anniversary, "Anniversary" );
326 ret_map.insert( Qtopia::Nickname, "Nickname" );
327 ret_map.insert( Qtopia::Children, "Children" );
328
329 // other
330 ret_map.insert( Qtopia::Notes, "Notes" );
331
332
333 return ret_map;
334}
335
336QMap<QString, int> OContactFields::trFieldsToId()
337{
338 QMap<int, QString> idtostr = idToTrFields();
339 QMap<QString, int> ret_map;
340
341
342 QMap<int, QString>::Iterator it;
343 for( it = idtostr.begin(); it != idtostr.end(); ++it )
344 ret_map.insert( *it, it.key() );
345
346
347 return ret_map;
348}
349
350QMap<QString, int> OContactFields::untrFieldsToId()
351{
352 QMap<int, QString> idtostr = idToUntrFields();
353 QMap<QString, int> ret_map;
354
355
356 QMap<int, QString>::Iterator it;
357 for( it = idtostr.begin(); it != idtostr.end(); ++it )
358 ret_map.insert( *it, it.key() );
359
360
361 return ret_map;
362}
363
364
365OContactFields::OContactFields():
366 fieldOrder( DEFAULT_FIELD_ORDER ),
367 changedFieldOrder( false )
368{
369 // Get the global field order from the config file and
370 // use it as a start pattern
371 Config cfg ( "AddressBook" );
372 cfg.setGroup( "ContactFieldOrder" );
373 globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER );
374}
375
376OContactFields::~OContactFields(){
377
378 // We will store the fieldorder into the config file
379 // to reuse it for the future..
380 if ( changedFieldOrder ){
381 Config cfg ( "AddressBook" );
382 cfg.setGroup( "ContactFieldOrder" );
383 cfg.writeEntry( "General", globalFieldOrder );
384 }
385}
386
387
388
389void OContactFields::saveToRecord( OContact &cnt ){
390
391 qDebug("ocontactfields saveToRecord: >%s<",fieldOrder.latin1());
392
393 // Store fieldorder into this contact.
394 cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder );
395
396 globalFieldOrder = fieldOrder;
397 changedFieldOrder = true;
398
399}
400
401void OContactFields::loadFromRecord( const OContact &cnt ){
402 qDebug("ocontactfields loadFromRecord");
403 qDebug("loading >%s<",cnt.fullName().latin1());
404
405 // Get fieldorder for this contact. If none is defined,
406 // we will use the global one from the config file..
407
408 fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME );
409
410 qDebug("fieldOrder from contact>%s<",fieldOrder.latin1());
411
412 if (fieldOrder.isEmpty()){
413 fieldOrder = globalFieldOrder;
414 }
415
416
417 qDebug("effective fieldOrder in loadFromRecord >%s<",fieldOrder.latin1());
418}
419
420void OContactFields::setFieldOrder( int num, int index ){
421 qDebug("qcontactfields setfieldorder pos %i -> %i",num,index);
422
423 fieldOrder[num] = QString::number( index, 16 )[0];
424
425 // We will store this new fieldorder globally to
426 // remember it for contacts which have none
427 globalFieldOrder = fieldOrder;
428 changedFieldOrder = true;
429
430 qDebug("fieldOrder >%s<",fieldOrder.latin1());
431}
432
433int OContactFields::getFieldOrder( int num, int defIndex ){
434 qDebug("ocontactfields getFieldOrder");
435 qDebug("fieldOrder >%s<",fieldOrder.latin1());
436
437 // Get index of combo as char..
438 QChar poschar = fieldOrder[num];
439
440 bool ok;
441 int ret = 0;
442 // Convert char to number..
443 if ( !( poschar == QChar::null ) )
444 ret = QString( poschar ).toInt(&ok, 16);
445 else
446 ok = false;
447
448 // Return default value if index for
449 // num was not set or if anything else happened..
450 if ( !ok ) ret = defIndex;
451
452 qDebug("returning >%i<",ret);
453
454 return ret;
455
456}
diff --git a/libopie/pim/ocontactfields.h b/libopie/pim/ocontactfields.h
new file mode 100644
index 0000000..9f6171b
--- a/dev/null
+++ b/libopie/pim/ocontactfields.h
@@ -0,0 +1,60 @@
1#ifndef OPIE_CONTACTS_FIELDS
2#define OPIE_CONTACTS_FIELDS
3
4class QStringList;
5
6#include <qmap.h>
7#include <qstring.h>
8#include <opie/ocontact.h>
9
10#define CONTACT_FIELD_ORDER_NAME "opie-contactfield-order"
11#define DEFAULT_FIELD_ORDER "__________"
12
13class OContactFields{
14
15 public:
16 OContactFields();
17 ~OContactFields();
18 /** Set the index for combo boxes.
19 * Sets the <b>index</b> of combo <b>num</b>.
20 * @param num selects the number of the combo
21 * @param index sets the index in the combo
22 */
23 void setFieldOrder( int num, int index );
24
25 /** Get the index for combo boxes.
26 * Returns the index of combo <b>num</b> or defindex
27 * if none was defined..
28 * @param num Selects the number of the combo
29 * @param defIndex will be returned if none was defined (either
30 * globally in the config file, nor by the contact which was used
31 * by loadFromRecord() )
32 */
33 int getFieldOrder( int num, int defIndex);
34
35 /** Store fieldorder to contact. */
36 void saveToRecord( OContact& );
37 /** Get Fieldorder from contact. */
38 void loadFromRecord( const OContact& );
39
40 private:
41 QString fieldOrder;
42 QString globalFieldOrder;
43 bool changedFieldOrder;
44
45 public:
46 static QStringList trphonefields( bool sorted = true );
47 static QStringList untrphonefields( bool sorted = true );
48 static QStringList trdetailsfields( bool sorted = true );
49 static QStringList untrdetailsfields( bool sorted = true );
50 static QStringList trfields( bool sorted = true );
51 static QStringList untrfields( bool sorted = true );
52
53 static QMap<int, QString> idToTrFields();
54 static QMap<QString, int> trFieldsToId();
55 static QMap<int, QString> idToUntrFields();
56 static QMap<QString, int> untrFieldsToId();
57
58};
59
60#endif
diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp
index ec9c14c..23e0c3e 100644
--- a/libopie/pim/otodoaccesssql.cpp
+++ b/libopie/pim/otodoaccesssql.cpp
@@ -1,73 +1,73 @@
1 1
2#include <qdatetime.h> 2#include <qdatetime.h>
3 3
4#include <qpe/global.h> 4#include <qpe/global.h>
5 5
6#include <opie/osqldriver.h> 6#include <opie2/osqldriver.h>
7#include <opie/osqlresult.h> 7#include <opie2/osqlresult.h>
8#include <opie/osqlmanager.h> 8#include <opie2/osqlmanager.h>
9#include <opie/osqlquery.h> 9#include <opie2/osqlquery.h>
10 10
11#include "otodoaccesssql.h" 11#include "otodoaccesssql.h"
12 12
13/* 13/*
14 * first some query 14 * first some query
15 * CREATE query 15 * CREATE query
16 * LOAD query 16 * LOAD query
17 * INSERT 17 * INSERT
18 * REMOVE 18 * REMOVE
19 * CLEAR 19 * CLEAR
20 */ 20 */
21namespace { 21namespace {
22 /** 22 /**
23 * CreateQuery for the Todolist Table 23 * CreateQuery for the Todolist Table
24 */ 24 */
25 class CreateQuery : public OSQLQuery { 25 class CreateQuery : public OSQLQuery {
26 public: 26 public:
27 CreateQuery(); 27 CreateQuery();
28 ~CreateQuery(); 28 ~CreateQuery();
29 QString query()const; 29 QString query()const;
30 }; 30 };
31 31
32 /** 32 /**
33 * LoadQuery 33 * LoadQuery
34 * this one queries for all uids 34 * this one queries for all uids
35 */ 35 */
36 class LoadQuery : public OSQLQuery { 36 class LoadQuery : public OSQLQuery {
37 public: 37 public:
38 LoadQuery(); 38 LoadQuery();
39 ~LoadQuery(); 39 ~LoadQuery();
40 QString query()const; 40 QString query()const;
41 }; 41 };
42 42
43 /** 43 /**
44 * inserts/adds a OTodo to the table 44 * inserts/adds a OTodo to the table
45 */ 45 */
46 class InsertQuery : public OSQLQuery { 46 class InsertQuery : public OSQLQuery {
47 public: 47 public:
48 InsertQuery(const OTodo& ); 48 InsertQuery(const OTodo& );
49 ~InsertQuery(); 49 ~InsertQuery();
50 QString query()const; 50 QString query()const;
51 private: 51 private:
52 OTodo m_todo; 52 OTodo m_todo;
53 }; 53 };
54 54
55 /** 55 /**
56 * removes one from the table 56 * removes one from the table
57 */ 57 */
58 class RemoveQuery : public OSQLQuery { 58 class RemoveQuery : public OSQLQuery {
59 public: 59 public:
60 RemoveQuery(int uid ); 60 RemoveQuery(int uid );
61 ~RemoveQuery(); 61 ~RemoveQuery();
62 QString query()const; 62 QString query()const;
63 private: 63 private:
64 int m_uid; 64 int m_uid;
65 }; 65 };
66 66
67 /** 67 /**
68 * Clears (delete) a Table 68 * Clears (delete) a Table
69 */ 69 */
70 class ClearQuery : public OSQLQuery { 70 class ClearQuery : public OSQLQuery {
71 public: 71 public:
72 ClearQuery(); 72 ClearQuery();
73 ~ClearQuery(); 73 ~ClearQuery();
@@ -188,353 +188,406 @@ namespace {
188 QString FindQuery::query()const{ 188 QString FindQuery::query()const{
189 if (m_uids.count() == 0 ) 189 if (m_uids.count() == 0 )
190 return single(); 190 return single();
191 else 191 else
192 return multi(); 192 return multi();
193 } 193 }
194 QString FindQuery::single()const{ 194 QString FindQuery::single()const{
195 QString qu = "select uid, categories, completed, progress, summary, "; 195 QString qu = "select uid, categories, completed, progress, summary, ";
196 qu += "DueDate, priority, description from todolist where uid = " + QString::number(m_uid); 196 qu += "DueDate, priority, description from todolist where uid = " + QString::number(m_uid);
197 return qu; 197 return qu;
198 } 198 }
199 QString FindQuery::multi()const { 199 QString FindQuery::multi()const {
200 QString qu = "select uid, categories, completed, progress, summary, "; 200 QString qu = "select uid, categories, completed, progress, summary, ";
201 qu += "DueDate, priority, description from todolist where "; 201 qu += "DueDate, priority, description from todolist where ";
202 for (uint i = 0; i < m_uids.count(); i++ ) { 202 for (uint i = 0; i < m_uids.count(); i++ ) {
203 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 203 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
204 } 204 }
205 qu.remove( qu.length()-2, 2 ); 205 qu.remove( qu.length()-2, 2 );
206 return qu; 206 return qu;
207 } 207 }
208 208
209 OverDueQuery::OverDueQuery(): OSQLQuery() {} 209 OverDueQuery::OverDueQuery(): OSQLQuery() {}
210 OverDueQuery::~OverDueQuery() {} 210 OverDueQuery::~OverDueQuery() {}
211 QString OverDueQuery::query()const { 211 QString OverDueQuery::query()const {
212 QDate date = QDate::currentDate(); 212 QDate date = QDate::currentDate();
213 QString str; 213 QString str;
214 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); 214 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() );
215 215
216 return str; 216 return str;
217 } 217 }
218 218
219 219
220 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) 220 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc )
221 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} 221 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {}
222 EffQuery::~EffQuery() {} 222 EffQuery::~EffQuery() {}
223 QString EffQuery::query()const { 223 QString EffQuery::query()const {
224 return m_inc ? with() : out(); 224 return m_inc ? with() : out();
225 } 225 }
226 QString EffQuery::with()const { 226 QString EffQuery::with()const {
227 QString str; 227 QString str;
228 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") 228 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ")
229 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) 229 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() )
230 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); 230 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() );
231 return str; 231 return str;
232 } 232 }
233 QString EffQuery::out()const { 233 QString EffQuery::out()const {
234 QString str; 234 QString str;
235 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") 235 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'")
236 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) 236 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() )
237 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); 237 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() );
238 238
239 return str; 239 return str;
240 } 240 }
241}; 241};
242 242
243OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) 243OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file )
244 : OTodoAccessBackend(), m_dict(15), m_dirty(true) 244 : OTodoAccessBackend(), m_dict(15), m_dirty(true)
245{ 245{
246 QString fi = file; 246 QString fi = file;
247 if ( fi.isEmpty() ) 247 if ( fi.isEmpty() )
248 fi = Global::applicationFileName( "todolist", "todolist.db" ); 248 fi = Global::applicationFileName( "todolist", "todolist.db" );
249 OSQLManager man; 249 OSQLManager man;
250 m_driver = man.standard(); 250 m_driver = man.standard();
251 m_driver->setUrl(fi); 251 m_driver->setUrl(fi);
252 fillDict(); 252 // fillDict();
253} 253}
254 254
255OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ 255OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){
256} 256}
257bool OTodoAccessBackendSQL::load(){ 257bool OTodoAccessBackendSQL::load(){
258 if (!m_driver->open() ) 258 if (!m_driver->open() )
259 return false; 259 return false;
260 260
261 CreateQuery creat; 261 CreateQuery creat;
262 OSQLResult res = m_driver->query(&creat ); 262 OSQLResult res = m_driver->query(&creat );
263 263
264 m_dirty = true; 264 m_dirty = true;
265 return true; 265 return true;
266} 266}
267bool OTodoAccessBackendSQL::reload(){ 267bool OTodoAccessBackendSQL::reload(){
268 return load(); 268 return load();
269} 269}
270 270
271bool OTodoAccessBackendSQL::save(){ 271bool OTodoAccessBackendSQL::save(){
272 return m_driver->close(); 272 return m_driver->close();
273} 273}
274QArray<int> OTodoAccessBackendSQL::allRecords()const { 274QArray<int> OTodoAccessBackendSQL::allRecords()const {
275 if (m_dirty ) 275 if (m_dirty )
276 update(); 276 update();
277 277
278 return m_uids; 278 return m_uids;
279} 279}
280QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ 280QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){
281 QArray<int> ints(0); 281 QArray<int> ints(0);
282 return ints; 282 return ints;
283} 283}
284OTodo OTodoAccessBackendSQL::find(int uid ) const{ 284OTodo OTodoAccessBackendSQL::find(int uid ) const{
285 FindQuery query( uid ); 285 FindQuery query( uid );
286 return todo( m_driver->query(&query) ); 286 return todo( m_driver->query(&query) );
287 287
288} 288}
289OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, 289OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
290 uint cur, Frontend::CacheDirection dir ) const{ 290 uint cur, Frontend::CacheDirection dir ) const{
291 int CACHE = readAhead(); 291 int CACHE = readAhead();
292 qWarning("searching for %d", uid ); 292 qWarning("searching for %d", uid );
293 QArray<int> search( CACHE ); 293 QArray<int> search( CACHE );
294 uint size =0; 294 uint size =0;
295 OTodo to; 295 OTodo to;
296 296
297 // we try to cache CACHE items 297 // we try to cache CACHE items
298 switch( dir ) { 298 switch( dir ) {
299 /* forward */ 299 /* forward */
300 case 0: 300 case 0: // FIXME: Not a good style to use magic numbers here (eilers)
301 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { 301 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
302 qWarning("size %d %d", size, ints[i] ); 302 qWarning("size %d %d", size, ints[i] );
303 search[size] = ints[i]; 303 search[size] = ints[i];
304 size++; 304 size++;
305 } 305 }
306 break; 306 break;
307 /* reverse */ 307 /* reverse */
308 case 1: 308 case 1: // FIXME: Not a good style to use magic numbers here (eilers)
309 for (uint i = cur; i != 0 && size < CACHE; i-- ) { 309 for (uint i = cur; i != 0 && size < CACHE; i-- ) {
310 search[size] = ints[i]; 310 search[size] = ints[i];
311 size++; 311 size++;
312 } 312 }
313 break; 313 break;
314 } 314 }
315 search.resize( size ); 315 search.resize( size );
316 FindQuery query( search ); 316 FindQuery query( search );
317 OSQLResult res = m_driver->query( &query ); 317 OSQLResult res = m_driver->query( &query );
318 if ( res.state() != OSQLResult::Success ) 318 if ( res.state() != OSQLResult::Success )
319 return to; 319 return to;
320 320
321 return todo( res ); 321 return todo( res );
322} 322}
323void OTodoAccessBackendSQL::clear() { 323void OTodoAccessBackendSQL::clear() {
324 ClearQuery cle; 324 ClearQuery cle;
325 OSQLResult res = m_driver->query( &cle ); 325 OSQLResult res = m_driver->query( &cle );
326 CreateQuery qu; 326 CreateQuery qu;
327 res = m_driver->query(&qu); 327 res = m_driver->query(&qu);
328} 328}
329bool OTodoAccessBackendSQL::add( const OTodo& t) { 329bool OTodoAccessBackendSQL::add( const OTodo& t) {
330 InsertQuery ins( t ); 330 InsertQuery ins( t );
331 OSQLResult res = m_driver->query( &ins ); 331 OSQLResult res = m_driver->query( &ins );
332 332
333 if ( res.state() == OSQLResult::Failure ) 333 if ( res.state() == OSQLResult::Failure )
334 return false; 334 return false;
335 int c = m_uids.count(); 335 int c = m_uids.count();
336 m_uids.resize( c+1 ); 336 m_uids.resize( c+1 );
337 m_uids[c] = t.uid(); 337 m_uids[c] = t.uid();
338 338
339 return true; 339 return true;
340} 340}
341bool OTodoAccessBackendSQL::remove( int uid ) { 341bool OTodoAccessBackendSQL::remove( int uid ) {
342 RemoveQuery rem( uid ); 342 RemoveQuery rem( uid );
343 OSQLResult res = m_driver->query(&rem ); 343 OSQLResult res = m_driver->query(&rem );
344 344
345 if ( res.state() == OSQLResult::Failure ) 345 if ( res.state() == OSQLResult::Failure )
346 return false; 346 return false;
347 347
348 m_dirty = true; 348 m_dirty = true;
349 return true; 349 return true;
350} 350}
351/* 351/*
352 * FIXME better set query 352 * FIXME better set query
353 * but we need the cache for that 353 * but we need the cache for that
354 * now we remove 354 * now we remove
355 */ 355 */
356bool OTodoAccessBackendSQL::replace( const OTodo& t) { 356bool OTodoAccessBackendSQL::replace( const OTodo& t) {
357 remove( t.uid() ); 357 remove( t.uid() );
358 bool b= add(t); 358 bool b= add(t);
359 m_dirty = false; // we changed some stuff but the UID stayed the same 359 m_dirty = false; // we changed some stuff but the UID stayed the same
360 return b; 360 return b;
361} 361}
362QArray<int> OTodoAccessBackendSQL::overDue() { 362QArray<int> OTodoAccessBackendSQL::overDue() {
363 OverDueQuery qu; 363 OverDueQuery qu;
364 return uids( m_driver->query(&qu ) ); 364 return uids( m_driver->query(&qu ) );
365} 365}
366QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, 366QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s,
367 const QDate& t, 367 const QDate& t,
368 bool u) { 368 bool u) {
369 EffQuery ef(s, t, u ); 369 EffQuery ef(s, t, u );
370 return uids (m_driver->query(&ef) ); 370 return uids (m_driver->query(&ef) );
371} 371}
372/* 372/*
373 * 373 *
374 */ 374 */
375QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, 375QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
376 int sortFilter, int cat ) { 376 int sortFilter, int cat ) {
377 qWarning("sorted %d, %d", asc, sortOrder ); 377 qWarning("sorted %d, %d", asc, sortOrder );
378 QString query; 378 QString query;
379 query = "select uid from todolist WHERE "; 379 query = "select uid from todolist WHERE ";
380 380
381 /* 381 /*
382 * Sort Filter stuff 382 * Sort Filter stuff
383 * not that straight forward 383 * not that straight forward
384 * FIXME: Replace magic numbers
384 * 385 *
385 */ 386 */
386 /* Category */ 387 /* Category */
387 if ( sortFilter & 1 ) { 388 if ( sortFilter & 1 ) {
388 QString str; 389 QString str;
389 if (cat != 0 ) str = QString::number( cat ); 390 if (cat != 0 ) str = QString::number( cat );
390 query += " categories like '%" +str+"%' AND"; 391 query += " categories like '%" +str+"%' AND";
391 } 392 }
392 /* Show only overdue */ 393 /* Show only overdue */
393 if ( sortFilter & 2 ) { 394 if ( sortFilter & 2 ) {
394 QDate date = QDate::currentDate(); 395 QDate date = QDate::currentDate();
395 QString due; 396 QString due;
396 QString base; 397 QString base;
397 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); 398 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() );
398 query += " " + base + " AND"; 399 query += " " + base + " AND";
399 } 400 }
400 /* not show completed */ 401 /* not show completed */
401 if ( sortFilter & 4 ) { 402 if ( sortFilter & 4 ) {
402 query += " completed = 0 AND"; 403 query += " completed = 0 AND";
403 }else{ 404 }else{
404 query += " ( completed = 1 OR completed = 0) AND"; 405 query += " ( completed = 1 OR completed = 0) AND";
405 } 406 }
406 /* srtip the end */ 407 /* srtip the end */
407 query = query.remove( query.length()-3, 3 ); 408 query = query.remove( query.length()-3, 3 );
408 409
409 410
410 /* 411 /*
411 * sort order stuff 412 * sort order stuff
412 * quite straight forward 413 * quite straight forward
413 */ 414 */
414 query += "ORDER BY "; 415 query += "ORDER BY ";
415 switch( sortOrder ) { 416 switch( sortOrder ) {
416 /* completed */ 417 /* completed */
417 case 0: 418 case 0:
418 query += "completed"; 419 query += "completed";
419 break; 420 break;
420 case 1: 421 case 1:
421 query += "priority"; 422 query += "priority";
422 break; 423 break;
423 case 2: 424 case 2:
424 query += "summary"; 425 query += "summary";
425 break; 426 break;
426 case 3: 427 case 3:
427 query += "DueDate"; 428 query += "DueDate";
428 break; 429 break;
429 } 430 }
430 431
431 if ( !asc ) { 432 if ( !asc ) {
432 qWarning("not ascending!"); 433 qWarning("not ascending!");
433 query += " DESC"; 434 query += " DESC";
434 } 435 }
435 436
436 qWarning( query ); 437 qWarning( query );
437 OSQLRawQuery raw(query ); 438 OSQLRawQuery raw(query );
438 return uids( m_driver->query(&raw) ); 439 return uids( m_driver->query(&raw) );
439} 440}
440bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ 441bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{
441 if ( str == "0-0-0" ) 442 if ( str == "0-0-0" )
442 return false; 443 return false;
443 else{ 444 else{
444 int day, year, month; 445 int day, year, month;
445 QStringList list = QStringList::split("-", str ); 446 QStringList list = QStringList::split("-", str );
446 year = list[0].toInt(); 447 year = list[0].toInt();
447 month = list[1].toInt(); 448 month = list[1].toInt();
448 day = list[2].toInt(); 449 day = list[2].toInt();
449 da.setYMD( year, month, day ); 450 da.setYMD( year, month, day );
450 return true; 451 return true;
451 } 452 }
452} 453}
453OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ 454OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{
454 if ( res.state() == OSQLResult::Failure ) { 455 if ( res.state() == OSQLResult::Failure ) {
455 OTodo to; 456 OTodo to;
456 return to; 457 return to;
457 } 458 }
458 459
459 OSQLResultItem::ValueList list = res.results(); 460 OSQLResultItem::ValueList list = res.results();
460 OSQLResultItem::ValueList::Iterator it = list.begin(); 461 OSQLResultItem::ValueList::Iterator it = list.begin();
461 qWarning("todo1"); 462 qWarning("todo1");
462 OTodo to = todo( (*it) ); 463 OTodo to = todo( (*it) );
463 cache( to ); 464 cache( to );
464 ++it; 465 ++it;
465 466
466 for ( ; it != list.end(); ++it ) { 467 for ( ; it != list.end(); ++it ) {
467 qWarning("caching"); 468 qWarning("caching");
468 cache( todo( (*it) ) ); 469 cache( todo( (*it) ) );
469 } 470 }
470 return to; 471 return to;
471} 472}
472OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const { 473OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const {
473 qWarning("todo"); 474 qWarning("todo");
474 bool has = false; QDate da = QDate::currentDate(); 475 bool has = false; QDate da = QDate::currentDate();
475 has = date( da, item.data("DueDate") ); 476 has = date( da, item.data("DueDate") );
476 QStringList cats = QStringList::split(";", item.data("categories") ); 477 QStringList cats = QStringList::split(";", item.data("categories") );
477 478
478 OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), 479 OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(),
479 cats, item.data("summary"), item.data("description"), 480 cats, item.data("summary"), item.data("description"),
480 item.data("progress").toUShort(), has, da, 481 item.data("progress").toUShort(), has, da,
481 item.data("uid").toInt() ); 482 item.data("uid").toInt() );
482 return to; 483 return to;
483} 484}
484OTodo OTodoAccessBackendSQL::todo( int uid )const { 485OTodo OTodoAccessBackendSQL::todo( int uid )const {
485 FindQuery find( uid ); 486 FindQuery find( uid );
486 return todo( m_driver->query(&find) ); 487 return todo( m_driver->query(&find) );
487} 488}
488/* 489/*
489 * update the dict 490 * update the dict
490 */ 491 */
491void OTodoAccessBackendSQL::fillDict() { 492void OTodoAccessBackendSQL::fillDict() {
492 /* initialize dict */ 493 /* initialize dict */
493 /* 494 /*
494 * UPDATE dict if you change anything!!! 495 * UPDATE dict if you change anything!!!
496 * FIXME: Isn't this dict obsolete ? (eilers)
495 */ 497 */
496 m_dict.setAutoDelete( TRUE ); 498 m_dict.setAutoDelete( TRUE );
497 m_dict.insert("Categories" , new int(OTodo::Category) ); 499 m_dict.insert("Categories" , new int(OTodo::Category) );
498 m_dict.insert("Uid" , new int(OTodo::Uid) ); 500 m_dict.insert("Uid" , new int(OTodo::Uid) );
499 m_dict.insert("HasDate" , new int(OTodo::HasDate) ); 501 m_dict.insert("HasDate" , new int(OTodo::HasDate) );
500 m_dict.insert("Completed" , new int(OTodo::Completed) ); 502 m_dict.insert("Completed" , new int(OTodo::Completed) );
501 m_dict.insert("Description" , new int(OTodo::Description) ); 503 m_dict.insert("Description" , new int(OTodo::Description) );
502 m_dict.insert("Summary" , new int(OTodo::Summary) ); 504 m_dict.insert("Summary" , new int(OTodo::Summary) );
503 m_dict.insert("Priority" , new int(OTodo::Priority) ); 505 m_dict.insert("Priority" , new int(OTodo::Priority) );
504 m_dict.insert("DateDay" , new int(OTodo::DateDay) ); 506 m_dict.insert("DateDay" , new int(OTodo::DateDay) );
505 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 507 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) );
506 m_dict.insert("DateYear" , new int(OTodo::DateYear) ); 508 m_dict.insert("DateYear" , new int(OTodo::DateYear) );
507 m_dict.insert("Progress" , new int(OTodo::Progress) ); 509 m_dict.insert("Progress" , new int(OTodo::Progress) );
508 m_dict.insert("Completed", new int(OTodo::Completed) ); 510 m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers)
509 m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); 511 m_dict.insert("CrossReference", new int(OTodo::CrossReference) );
510 m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); 512// m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers)
511 m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); 513// m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers)
512} 514}
513/* 515/*
514 * need to be const so let's fool the 516 * need to be const so let's fool the
515 * compiler :( 517 * compiler :(
516 */ 518 */
517void OTodoAccessBackendSQL::update()const { 519void OTodoAccessBackendSQL::update()const {
518 ((OTodoAccessBackendSQL*)this)->m_dirty = false; 520 ((OTodoAccessBackendSQL*)this)->m_dirty = false;
519 LoadQuery lo; 521 LoadQuery lo;
520 OSQLResult res = m_driver->query(&lo); 522 OSQLResult res = m_driver->query(&lo);
521 if ( res.state() != OSQLResult::Success ) 523 if ( res.state() != OSQLResult::Success )
522 return; 524 return;
523 525
524 ((OTodoAccessBackendSQL*)this)->m_uids = uids( res ); 526 ((OTodoAccessBackendSQL*)this)->m_uids = uids( res );
525} 527}
526QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{ 528QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{
527 529
528 OSQLResultItem::ValueList list = res.results(); 530 OSQLResultItem::ValueList list = res.results();
529 OSQLResultItem::ValueList::Iterator it; 531 OSQLResultItem::ValueList::Iterator it;
530 QArray<int> ints(list.count() ); 532 QArray<int> ints(list.count() );
531 qWarning(" count = %d", list.count() ); 533 qWarning(" count = %d", list.count() );
532 534
533 int i = 0; 535 int i = 0;
534 for (it = list.begin(); it != list.end(); ++it ) { 536 for (it = list.begin(); it != list.end(); ++it ) {
535 ints[i] = (*it).data("uid").toInt(); 537 ints[i] = (*it).data("uid").toInt();
536 i++; 538 i++;
537 } 539 }
538 return ints; 540 return ints;
539} 541}
540 542
543QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
544{
545
546#warning OTodoAccessBackendSQL::matchRegexp() not implemented !!
547
548#if 0
549
550 Copied from xml-backend by not adapted to sql (eilers)
551
552 QArray<int> m_currentQuery( m_events.count() );
553 uint arraycounter = 0;
554
555
556
557 QMap<int, OTodo>::ConstIterator it;
558 for (it = m_events.begin(); it != m_events.end(); ++it ) {
559 if ( it.data().match( r ) )
560 m_currentQuery[arraycounter++] = it.data().uid();
561
562 }
563 // Shrink to fit..
564 m_currentQuery.resize(arraycounter);
565
566 return m_currentQuery;
567#endif
568 QArray<int> empty;
569 return empty;
570}
571QBitArray OTodoAccessBackendSQL::supports()const {
572
573 static QBitArray ar = sup();
574 return ar;
575}
576
577QBitArray OTodoAccessBackendSQL::sup() {
578
579 QBitArray ar( OTodo::CompletedDate + 1 );
580 ar.fill( true );
581 ar[OTodo::CrossReference] = false;
582 ar[OTodo::State ] = false;
583 ar[OTodo::Reminders] = false;
584 ar[OTodo::Notifiers] = false;
585 ar[OTodo::Maintainer] = false;
586
587 return ar;
588}
589
590void OTodoAccessBackendSQL::removeAllCompleted(){
591#warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !!
592
593}
diff --git a/libopie/pim/otodoaccesssql.h b/libopie/pim/otodoaccesssql.h
index 6a4257c..77d8b77 100644
--- a/libopie/pim/otodoaccesssql.h
+++ b/libopie/pim/otodoaccesssql.h
@@ -1,50 +1,56 @@
1#ifndef OPIE_PIM_ACCESS_SQL_H 1#ifndef OPIE_PIM_ACCESS_SQL_H
2#define OPIE_PIM_ACCESS_SQL_H 2#define OPIE_PIM_ACCESS_SQL_H
3 3
4#include <qasciidict.h> 4#include <qasciidict.h>
5 5
6#include "otodoaccessbackend.h" 6#include "otodoaccessbackend.h"
7 7
8class OSQLDriver; 8class OSQLDriver;
9class OSQLResult; 9class OSQLResult;
10class OSQLResultItem; 10class OSQLResultItem;
11class OTodoAccessBackendSQL : public OTodoAccessBackend { 11class OTodoAccessBackendSQL : public OTodoAccessBackend {
12public: 12public:
13 OTodoAccessBackendSQL( const QString& file ); 13 OTodoAccessBackendSQL( const QString& file );
14 ~OTodoAccessBackendSQL(); 14 ~OTodoAccessBackendSQL();
15 15
16 bool load(); 16 bool load();
17 bool reload(); 17 bool reload();
18 bool save(); 18 bool save();
19 QArray<int> allRecords()const; 19 QArray<int> allRecords()const;
20 20
21 QArray<int> queryByExample( const OTodo& t, int settings, const QDateTime& d = QDateTime() ); 21 QArray<int> queryByExample( const OTodo& t, int settings, const QDateTime& d = QDateTime() );
22 OTodo find(int uid)const; 22 OTodo find(int uid)const;
23 OTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; 23 OTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
24 void clear(); 24 void clear();
25 bool add( const OTodo& t ); 25 bool add( const OTodo& t );
26 bool remove( int uid ); 26 bool remove( int uid );
27 bool replace( const OTodo& t ); 27 bool replace( const OTodo& t );
28 28
29 QArray<int> overDue(); 29 QArray<int> overDue();
30 QArray<int> effectiveToDos( const QDate& start, 30 QArray<int> effectiveToDos( const QDate& start,
31 const QDate& end, bool includeNoDates ); 31 const QDate& end, bool includeNoDates );
32 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat ); 32 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat );
33 33
34 QBitArray supports()const;
35 QArray<int> matchRegexp( const QRegExp &r ) const;
36 void removeAllCompleted();
37
38
34private: 39private:
35 void update()const; 40 void update()const;
36 void fillDict(); 41 void fillDict();
37 inline bool date( QDate& date, const QString& )const; 42 inline bool date( QDate& date, const QString& )const;
38 inline OTodo todo( const OSQLResult& )const; 43 inline OTodo todo( const OSQLResult& )const;
39 inline OTodo todo( OSQLResultItem& )const; 44 inline OTodo todo( OSQLResultItem& )const;
40 inline QArray<int> uids( const OSQLResult& )const; 45 inline QArray<int> uids( const OSQLResult& )const;
41 OTodo todo( int uid )const; 46 OTodo todo( int uid )const;
47 QBitArray sup();
42 48
43 QAsciiDict<int> m_dict; 49 QAsciiDict<int> m_dict;
44 OSQLDriver* m_driver; 50 OSQLDriver* m_driver;
45 QArray<int> m_uids; 51 QArray<int> m_uids;
46 bool m_dirty : 1; 52 bool m_dirty : 1;
47}; 53};
48 54
49 55
50#endif 56#endif
diff --git a/libopie/pim/test/converter.cpp b/libopie/pim/test/converter.cpp
new file mode 100644
index 0000000..0a488f2
--- a/dev/null
+++ b/libopie/pim/test/converter.cpp
@@ -0,0 +1,64 @@
1#include <qpe/qpeapplication.h>
2
3#include <opie/ocontactaccess.h>
4#include <opie/ocontactaccessbackend_xml.h>
5#include <opie/ocontactaccessbackend_sql.h>
6
7#include "converter_base.h"
8
9class ConvertXMLToSQL: public converter_base {
10public:
11 ConvertXMLToSQL()
12 {
13 convertContact();
14 }
15private:
16 void convertContact();
17
18};
19
20
21void ConvertXMLToSQL::convertContact(){
22 qWarning("Converting Contacts from XML to SQL..");
23
24 // Creating backends to the requested databases..
25 OContactAccessBackend* xmlBackend = new OContactAccessBackend_XML( "Converter",
26 QString::null );
27
28 OContactAccessBackend* sqlBackend = new OContactAccessBackend_SQL( QString::null,
29 QString::null );
30 // Put the created backends into frontends to access them
31 OContactAccess* xmlAccess = new OContactAccess ( "addressbook_xml",
32 QString::null , xmlBackend, true );
33
34 OContactAccess* sqlAccess = new OContactAccess ( "addressbook_sql",
35 QString::null , sqlBackend, true );
36
37 // Clean the sql-database..
38 sqlAccess->clear();
39
40 // Now trasmit every contact from the xml database to the sql-database
41 OContactAccess::List contactList = xmlAccess->allRecords();
42 if ( sqlAccess && xmlAccess ){
43 OContactAccess::List::Iterator it;
44 for ( it = contactList.begin(); it != contactList.end(); ++it )
45 sqlAccess->add( *it );
46 }
47
48 // Delete the frontends. Backends will be deleted automatically, too !
49 delete sqlAccess;
50 delete xmlAccess;
51}
52
53int main( int argc, char** argv ) {
54
55 QPEApplication a( argc, argv );
56
57 ConvertXMLToSQL dlg;
58
59 a.showMainWidget( &dlg );
60 // dlg. showMaximized ( );
61
62 return a.exec();
63
64}
diff --git a/libopie/pim/test/converter.pro b/libopie/pim/test/converter.pro
new file mode 100644
index 0000000..aa74bff
--- a/dev/null
+++ b/libopie/pim/test/converter.pro
@@ -0,0 +1,12 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on debug
3 # CONFIG = qt warn_on release
4 #HEADERS =
5 SOURCES = converter.cpp
6INTERFACES = converter_base.ui
7 INCLUDEPATH+= $(OPIEDIR)/include
8 DEPENDPATH+= $(OPIEDIR)/include
9LIBS += -lqpe -lopie
10 TARGET = converter
11
12include ( $(OPIEDIR)/include.pro )
diff --git a/libopie/pim/test/converter_base.ui b/libopie/pim/test/converter_base.ui
new file mode 100644
index 0000000..f680550
--- a/dev/null
+++ b/libopie/pim/test/converter_base.ui
@@ -0,0 +1,43 @@
1<!DOCTYPE UI><UI>
2<class>converter_base</class>
3<widget>
4 <class>QDialog</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>converter_base</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>579</width>
15 <height>211</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Form2</string>
21 </property>
22 <widget>
23 <class>QLabel</class>
24 <property stdset="1">
25 <name>name</name>
26 <cstring>TextLabel1</cstring>
27 </property>
28 <property stdset="1">
29 <name>geometry</name>
30 <rect>
31 <x>340</x>
32 <y>40</y>
33 <width>210</width>
34 <height>20</height>
35 </rect>
36 </property>
37 <property stdset="1">
38 <name>text</name>
39 <string>Converter from XML-&gt;SQL</string>
40 </property>
41 </widget>
42</widget>
43</UI>
diff --git a/libopie2/opiepim/backend/obackendfactory.h b/libopie2/opiepim/backend/obackendfactory.h
index f3c339d..3567687 100644
--- a/libopie2/opiepim/backend/obackendfactory.h
+++ b/libopie2/opiepim/backend/obackendfactory.h
@@ -1,166 +1,176 @@
1/* 1/*
2 * Class to manage Backends. 2 * Class to manage Backends.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; 9 * License as published by the Free Software Foundation;
10 * either version 2 of the License, or (at your option) any later 10 * either version 2 of the License, or (at your option) any later
11 * version. 11 * version.
12 * ===================================================================== 12 * =====================================================================
13 * ToDo: Use plugins 13 * ToDo: Use plugins
14 * ===================================================================== 14 * =====================================================================
15 * Version: $Id$ 15 * Version: $Id$
16 * ===================================================================== 16 * =====================================================================
17 * History: 17 * History:
18 * $Log$ 18 * $Log$
19 * Revision 1.8 2003/09/22 14:31:16 eilers
20 * Added first experimental incarnation of sql-backend for addressbook.
21 * Some modifications to be able to compile the todo sql-backend.
22 * A lot of changes fill follow...
23 *
19 * Revision 1.7 2003/08/01 12:30:16 eilers 24 * Revision 1.7 2003/08/01 12:30:16 eilers
20 * Merging changes from BRANCH_1_0 to HEAD 25 * Merging changes from BRANCH_1_0 to HEAD
21 * 26 *
22 * Revision 1.6.4.1 2003/06/30 14:34:19 eilers 27 * Revision 1.6.4.1 2003/06/30 14:34:19 eilers
23 * Patches from Zecke: 28 * Patches from Zecke:
24 * Fixing and cleaning up extraMap handling 29 * Fixing and cleaning up extraMap handling
25 * Adding d_ptr for binary compatibility in the future 30 * Adding d_ptr for binary compatibility in the future
26 * 31 *
27 * Revision 1.6 2003/04/13 18:07:10 zecke 32 * Revision 1.6 2003/04/13 18:07:10 zecke
28 * More API doc 33 * More API doc
29 * QString -> const QString& 34 * QString -> const QString&
30 * QString = 0l -> QString::null 35 * QString = 0l -> QString::null
31 * 36 *
32 * Revision 1.5 2003/02/21 23:31:52 zecke 37 * Revision 1.5 2003/02/21 23:31:52 zecke
33 * Add XML datebookresource 38 * Add XML datebookresource
34 * -clean up todoaccessxml header 39 * -clean up todoaccessxml header
35 * -implement some more stuff in the oeven tester 40 * -implement some more stuff in the oeven tester
36 * -extend DefaultFactory to not crash and to use datebook 41 * -extend DefaultFactory to not crash and to use datebook
37 * 42 *
38 * -reading of OEvents is working nicely.. saving will be added 43 * -reading of OEvents is working nicely.. saving will be added
39 * tomorrow 44 * tomorrow
40 * -fix spelling in ODateBookAcces 45 * -fix spelling in ODateBookAcces
41 * 46 *
42 * Revision 1.4 2002/10/14 15:55:18 eilers 47 * Revision 1.4 2002/10/14 15:55:18 eilers
43 * Redeactivate SQL.. ;) 48 * Redeactivate SQL.. ;)
44 * 49 *
45 * Revision 1.3 2002/10/10 17:08:58 zecke 50 * Revision 1.3 2002/10/10 17:08:58 zecke
46 * The Cache is finally in place 51 * The Cache is finally in place
47 * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;) 52 * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;)
48 * 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.... 53 * 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....
49 * I still have to fully implement read ahead 54 * I still have to fully implement read ahead
50 * This change is bic but sc 55 * This change is bic but sc
51 * 56 *
52 * Revision 1.2 2002/10/08 09:27:36 eilers 57 * Revision 1.2 2002/10/08 09:27:36 eilers
53 * Fixed libopie.pro to include the new pim-API. 58 * Fixed libopie.pro to include the new pim-API.
54 * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to 59 * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to
55 * compile itself would need to install libsqlite, libopiesql... 60 * compile itself would need to install libsqlite, libopiesql...
56 * Therefore, the backend currently uses XML only.. 61 * Therefore, the backend currently uses XML only..
57 * 62 *
58 * Revision 1.1 2002/10/07 17:35:01 eilers 63 * Revision 1.1 2002/10/07 17:35:01 eilers
59 * added OBackendFactory for advanced backend access 64 * added OBackendFactory for advanced backend access
60 * 65 *
61 * 66 *
62 * ===================================================================== 67 * =====================================================================
63 */ 68 */
64#ifndef OPIE_BACKENDFACTORY_H_ 69#ifndef OPIE_BACKENDFACTORY_H_
65#define OPIE_BACKENDFACTORY_H_ 70#define OPIE_BACKENDFACTORY_H_
66 71
67#include <qstring.h> 72#include <qstring.h>
68#include <qasciidict.h> 73#include <qasciidict.h>
69#include <qpe/config.h> 74#include <qpe/config.h>
70 75
71#include "otodoaccessxml.h" 76#include "otodoaccessxml.h"
72#include "ocontactaccessbackend_xml.h" 77#include "ocontactaccessbackend_xml.h"
73#include "odatebookaccessbackend_xml.h" 78#include "odatebookaccessbackend_xml.h"
74 79
75#ifdef __USE_SQL 80#ifdef __USE_SQL
76#include "otodoaccesssql.h" 81#include "otodoaccesssql.h"
82#include "ocontactaccessbackend_sql.h"
77#endif 83#endif
78 84
79class OBackendPrivate; 85class OBackendPrivate;
80 86
81/** 87/**
82 * This class is our factory. It will give us the default implementations 88 * This class is our factory. It will give us the default implementations
83 * of at least Todolist, Contacts and Datebook. In the future this class will 89 * of at least Todolist, Contacts and Datebook. In the future this class will
84 * allow users to switch the backend with ( XML->SQLite ) without the need 90 * allow users to switch the backend with ( XML->SQLite ) without the need
85 * to recompile.# 91 * to recompile.#
86 * This class as the whole PIM Api is making use of templates 92 * This class as the whole PIM Api is making use of templates
87 * 93 *
88 * <pre> 94 * <pre>
89 * OTodoAccessBackend* backend = OBackEndFactory<OTodoAccessBackend>::Default("todo", QString::null ); 95 * OTodoAccessBackend* backend = OBackEndFactory<OTodoAccessBackend>::Default("todo", QString::null );
90 * backend->load(); 96 * backend->load();
91 * </pre> 97 * </pre>
92 * 98 *
93 * @author Stefan Eilers 99 * @author Stefan Eilers
94 * @version 0.1 100 * @version 0.1
95 */ 101 */
96template<class T> 102template<class T>
97class OBackendFactory 103class OBackendFactory
98{ 104{
99 public: 105 public:
100 OBackendFactory() {}; 106 OBackendFactory() {};
101 107
102 enum BACKENDS { 108 enum BACKENDS {
103 TODO, 109 TODO,
104 CONTACT, 110 CONTACT,
105 DATE 111 DATE
106 }; 112 };
107 113
108 /** 114 /**
109 * Returns a backend implementation for backendName 115 * Returns a backend implementation for backendName
110 * @param backendName the type of the backend 116 * @param backendName the type of the backend
111 * @param appName will be passed on to the backend 117 * @param appName will be passed on to the backend
112 */ 118 */
113 static T* Default( const QString backendName, const QString& appName ){ 119 static T* Default( const QString backendName, const QString& appName ){
114 120
115 // __asm__("int3"); 121 // __asm__("int3");
116 122
117 Config config( "pimaccess" ); 123 Config config( "pimaccess" );
118 config.setGroup ( backendName ); 124 config.setGroup ( backendName );
119 QString backend = config.readEntry( "usebackend" ); 125 QString backend = config.readEntry( "usebackend" );
120 126
127 qWarning("Selected backend for %s is: %s", backendName.latin1(), backend.latin1() );
128
121 QAsciiDict<int> dict ( 3 ); 129 QAsciiDict<int> dict ( 3 );
122 dict.setAutoDelete ( TRUE ); 130 dict.setAutoDelete ( TRUE );
123 131
124 dict.insert( "todo", new int (TODO) ); 132 dict.insert( "todo", new int (TODO) );
125 dict.insert( "contact", new int (CONTACT) ); 133 dict.insert( "contact", new int (CONTACT) );
126 dict.insert( "datebook", new int(DATE) ); 134 dict.insert( "datebook", new int(DATE) );
127 135
128 qWarning ("TODO is: %d", TODO);
129 qWarning ("CONTACT is: %d", CONTACT);
130
131 int *find = dict[ backendName ]; 136 int *find = dict[ backendName ];
132 if (!find ) return 0; 137 if (!find ) return 0;
133 138
134 switch ( *find ){ 139 switch ( *find ){
135 case TODO: 140 case TODO:
136#ifdef __USE_SQL 141#ifdef __USE_SQL
137 if ( backend == "sql" ) 142 if ( backend == "sql" )
138 return (T*) new OTodoAccessBackendSQL(""); 143 return (T*) new OTodoAccessBackendSQL("");
139#else 144#else
140 if ( backend == "sql" ) 145 if ( backend == "sql" )
141 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 146 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
142#endif 147#endif
143 148
144 return (T*) new OTodoAccessXML( appName ); 149 return (T*) new OTodoAccessXML( appName );
145 case CONTACT: 150 case CONTACT:
151#ifdef __USE_SQL
152 if ( backend == "sql" )
153 return (T*) new OContactAccessBackend_SQL("");
154#else
146 if ( backend == "sql" ) 155 if ( backend == "sql" )
147 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 156 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
157#endif
148 158
149 return (T*) new OContactAccessBackend_XML( appName ); 159 return (T*) new OContactAccessBackend_XML( appName );
150 case DATE: 160 case DATE:
151 if ( backend == "sql" ) 161 if ( backend == "sql" )
152 qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 162 qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!");
153 163
154 return (T*) new ODateBookAccessBackend_XML( appName ); 164 return (T*) new ODateBookAccessBackend_XML( appName );
155 default: 165 default:
156 return NULL; 166 return NULL;
157 } 167 }
158 168
159 169
160 } 170 }
161 private: 171 private:
162 OBackendPrivate* d; 172 OBackendPrivate* d;
163}; 173};
164 174
165 175
166#endif 176#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
new file mode 100644
index 0000000..4afa5f3
--- a/dev/null
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
@@ -0,0 +1,664 @@
1/*
2 * SQL Backend for the OPIE-Contact Database.
3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 *
6 * =====================================================================
7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * =====================================================================
12 * =====================================================================
13 * Version: $Id$
14 * =====================================================================
15 * History:
16 * $Log$
17 * Revision 1.1 2003/09/22 14:31:16 eilers
18 * Added first experimental incarnation of sql-backend for addressbook.
19 * Some modifications to be able to compile the todo sql-backend.
20 * A lot of changes fill follow...
21 *
22 */
23
24#include "ocontactaccessbackend_sql.h"
25
26#include <qarray.h>
27#include <qdatetime.h>
28#include <qstringlist.h>
29
30#include <qpe/global.h>
31#include <qpe/recordfields.h>
32
33#include <opie/ocontactfields.h>
34#include <opie/oconversion.h>
35#include <opie2/osqldriver.h>
36#include <opie2/osqlresult.h>
37#include <opie2/osqlmanager.h>
38#include <opie2/osqlquery.h>
39
40/*
41 * Implementation of used query types
42 * CREATE query
43 * LOAD query
44 * INSERT
45 * REMOVE
46 * CLEAR
47 */
48namespace {
49 /**
50 * CreateQuery for the Todolist Table
51 */
52 class CreateQuery : public OSQLQuery {
53 public:
54 CreateQuery();
55 ~CreateQuery();
56 QString query()const;
57 };
58
59 /**
60 * Clears (delete) a Table
61 */
62 class ClearQuery : public OSQLQuery {
63 public:
64 ClearQuery();
65 ~ClearQuery();
66 QString query()const;
67
68 };
69
70
71 /**
72 * LoadQuery
73 * this one queries for all uids
74 */
75 class LoadQuery : public OSQLQuery {
76 public:
77 LoadQuery();
78 ~LoadQuery();
79 QString query()const;
80 };
81
82 /**
83 * inserts/adds a OContact to the table
84 */
85 class InsertQuery : public OSQLQuery {
86 public:
87 InsertQuery(const OContact& );
88 ~InsertQuery();
89 QString query()const;
90 private:
91 OContact m_contact;
92 };
93
94
95 /**
96 * removes one from the table
97 */
98 class RemoveQuery : public OSQLQuery {
99 public:
100 RemoveQuery(int uid );
101 ~RemoveQuery();
102 QString query()const;
103 private:
104 int m_uid;
105 };
106
107 /**
108 * a find query for noncustom elements
109 */
110 class FindQuery : public OSQLQuery {
111 public:
112 FindQuery(int uid);
113 FindQuery(const QArray<int>& );
114 ~FindQuery();
115 QString query()const;
116 private:
117 QString single()const;
118 QString multi()const;
119 QArray<int> m_uids;
120 int m_uid;
121 };
122
123 /**
124 * a find query for custom elements
125 */
126 class FindCustomQuery : public OSQLQuery {
127 public:
128 FindCustomQuery(int uid);
129 FindCustomQuery(const QArray<int>& );
130 ~FindCustomQuery();
131 QString query()const;
132 private:
133 QString single()const;
134 QString multi()const;
135 QArray<int> m_uids;
136 int m_uid;
137 };
138
139
140
141 // We using three tables to store the information:
142 // 1. addressbook : It contains General information about the contact (non custom)
143 // 2. dates : Stuff like birthdays, anniversaries, etc.
144 // 3. custom_data : Not official supported entries
145 // All tables are connected by the uid of the contact.
146 // Maybe I should add a table for meta-information ?
147 CreateQuery::CreateQuery() : OSQLQuery() {}
148 CreateQuery::~CreateQuery() {}
149 QString CreateQuery::query()const {
150 QString qu;
151 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));";
152 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
153 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );";
154 return qu;
155 }
156
157 ClearQuery::ClearQuery()
158 : OSQLQuery() {}
159 ClearQuery::~ClearQuery() {}
160 QString ClearQuery::query()const {
161 QString qu = "drop table addressbook;";
162 qu += "drop table custom_data;";
163 qu += "drop table dates;";
164 return qu;
165 }
166
167// Distinct loading is not very fast. If I expect that every person has just
168// one (and always one) 'Last Name', I can request all uid's for existing lastnames,
169// which is faster..
170// But this may not be true for all entries, like company contacts..
171// The current AddressBook application handles this problem, but other may not.. (eilers)
172#define __USE_SUPERFAST_LOADQUERY
173
174 LoadQuery::LoadQuery() : OSQLQuery() {}
175 LoadQuery::~LoadQuery() {}
176 QString LoadQuery::query()const {
177 QString qu;
178#ifndef __USE_SUPERFAST_LOADQUERY
179 qu += "select distinct uid from addressbook";
180#else
181 qu += "select uid from addressbook where type = 'Last Name'";
182#endif
183
184 return qu;
185 }
186
187
188 InsertQuery::InsertQuery( const OContact& contact )
189 : OSQLQuery(), m_contact( contact ) {
190 }
191
192 InsertQuery::~InsertQuery() {
193 }
194
195 /*
196 * converts from a OContact to a query
197 */
198 QString InsertQuery::query()const{
199
200 // Get all information out of the contact-class
201 // Remember: The category is stored in contactMap, too !
202 QMap<int, QString> contactMap = m_contact.toMap();
203 QMap<QString, QString> customMap = m_contact.toExtraMap();
204
205 QMap<QString, QString> addressbook_db;
206
207 // Get the translation from the ID to the String
208 QMap<int, QString> transMap = OContactFields::idToUntrFields();
209
210 for( QMap<int, QString>::Iterator it = contactMap.begin();
211 it != contactMap.end(); ++it ){
212 switch ( it.key() ){
213 case Qtopia::Birthday:{
214 // These entries should stored in a special format
215 // year-month-day
216 QDate day = m_contact.birthday();
217 addressbook_db.insert( transMap[it.key()],
218 QString("%1-%2-%3")
219 .arg( day.year() )
220 .arg( day.month() )
221 .arg( day.day() ) );
222 }
223 break;
224 case Qtopia::Anniversary:{
225 // These entries should stored in a special format
226 // year-month-day
227 QDate day = m_contact.anniversary();
228 addressbook_db.insert( transMap[it.key()],
229 QString("%1-%2-%3")
230 .arg( day.year() )
231 .arg( day.month() )
232 .arg( day.day() ) );
233 }
234 break;
235 case Qtopia::AddressUid: // Ignore UID
236 break;
237 default: // Translate id to String
238 addressbook_db.insert( transMap[it.key()], it.data() );
239 break;
240 }
241
242 }
243
244 // Now convert this whole stuff into a SQL String, beginning with
245 // the addressbook table..
246 QString qu;
247 // qu += "begin transaction;";
248 int id = 0;
249 for( QMap<QString, QString>::Iterator it = addressbook_db.begin();
250 it != addressbook_db.end(); ++it ){
251 qu += "insert into addressbook VALUES("
252 + QString::number( m_contact.uid() )
253 + ","
254 + QString::number( id++ )
255 + ",'"
256 + it.key() //.latin1()
257 + "',"
258 + "0" // Priority for future enhancements
259 + ",'"
260 + it.data() //.latin1()
261 + "');";
262 }
263
264 // Now add custom data..
265 id = 0;
266 for( QMap<QString, QString>::Iterator it = customMap.begin();
267 it != customMap.end(); ++it ){
268 qu += "insert into custom_data VALUES("
269 + QString::number( m_contact.uid() )
270 + ","
271 + QString::number( id++ )
272 + ",'"
273 + it.key() //.latin1()
274 + "',"
275 + "0" // Priority for future enhancements
276 + ",'"
277 + it.data() //.latin1()
278 + "');";
279 }
280
281 // qu += "commit;";
282 qWarning("add %s", qu.latin1() );
283 return qu;
284 }
285
286
287 RemoveQuery::RemoveQuery(int uid )
288 : OSQLQuery(), m_uid( uid ) {}
289 RemoveQuery::~RemoveQuery() {}
290 QString RemoveQuery::query()const {
291 QString qu = "DELETE from addressbook where uid = "
292 + QString::number(m_uid) + ";";
293 qu += "DELETE from dates where uid = "
294 + QString::number(m_uid) + ";";
295 qu += "DELETE from custom_data where uid = "
296 + QString::number(m_uid) + ";";
297 return qu;
298 }
299
300
301
302
303 FindQuery::FindQuery(int uid)
304 : OSQLQuery(), m_uid( uid ) {
305 }
306 FindQuery::FindQuery(const QArray<int>& ints)
307 : OSQLQuery(), m_uids( ints ){
308 }
309 FindQuery::~FindQuery() {
310 }
311 QString FindQuery::query()const{
312 // if ( m_uids.count() == 0 )
313 return single();
314 }
315 /*
316 else
317 return multi();
318 }
319 QString FindQuery::multi()const {
320 QString qu = "select uid, type, value from addressbook where";
321 for (uint i = 0; i < m_uids.count(); i++ ) {
322 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
323 }
324 qu.remove( qu.length()-2, 2 ); // Hmmmm..
325 return qu;
326 }
327 */
328 QString FindQuery::single()const{
329 QString qu = "select uid, type, value from addressbook where uid = ";
330 qu += QString::number(m_uid);
331 return qu;
332 }
333
334
335 FindCustomQuery::FindCustomQuery(int uid)
336 : OSQLQuery(), m_uid( uid ) {
337 }
338 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
339 : OSQLQuery(), m_uids( ints ){
340 }
341 FindCustomQuery::~FindCustomQuery() {
342 }
343 QString FindCustomQuery::query()const{
344 // if ( m_uids.count() == 0 )
345 return single();
346 }
347 QString FindCustomQuery::single()const{
348 QString qu = "select uid, type, value from custom_data where uid = ";
349 qu += QString::number(m_uid);
350 return qu;
351 }
352
353};
354
355
356/* --------------------------------------------------------------------------- */
357
358OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */,
359 const QString& filename ): m_changed(false)
360{
361 qWarning("C'tor OContactAccessBackend_SQL starts");
362 QTime t;
363 t.start();
364
365 /* Expecting to access the default filename if nothing else is set */
366 if ( filename.isEmpty() ){
367 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
368 } else
369 m_fileName = filename;
370
371 // Get the standart sql-driver from the OSQLManager..
372 OSQLManager man;
373 m_driver = man.standard();
374 m_driver->setUrl( m_fileName );
375
376 load();
377
378 qWarning("C'tor OContactAccessBackend_SQL ends: %d", t.elapsed() );
379}
380
381
382bool OContactAccessBackend_SQL::load ()
383{
384 if (!m_driver->open() )
385 return false;
386
387 // Don't expect that the database exists.
388 // It is save here to create the table, even if it
389 // do exist. ( Is that correct for all databases ?? )
390 CreateQuery creat;
391 OSQLResult res = m_driver->query( &creat );
392
393 update();
394
395 return true;
396
397}
398
399bool OContactAccessBackend_SQL::reload()
400{
401 return load();
402}
403
404bool OContactAccessBackend_SQL::save()
405{
406 return m_driver->close();
407}
408
409
410void OContactAccessBackend_SQL::clear ()
411{
412 ClearQuery cle;
413 OSQLResult res = m_driver->query( &cle );
414 CreateQuery qu;
415 res = m_driver->query(&qu);
416}
417
418bool OContactAccessBackend_SQL::wasChangedExternally()
419{
420 return false;
421}
422
423QArray<int> OContactAccessBackend_SQL::allRecords() const
424{
425
426 // FIXME: Think about cute handling of changed tables..
427 // Thus, we don't have to call update here...
428 if ( m_changed )
429 ((OContactAccessBackend_SQL*)this)->update();
430
431 return m_uids;
432}
433
434bool OContactAccessBackend_SQL::add ( const OContact &newcontact )
435{
436 InsertQuery ins( newcontact );
437 OSQLResult res = m_driver->query( &ins );
438
439 if ( res.state() == OSQLResult::Failure )
440 return false;
441
442 int c = m_uids.count();
443 m_uids.resize( c+1 );
444 m_uids[c] = newcontact.uid();
445
446 return true;
447}
448
449
450bool OContactAccessBackend_SQL::remove ( int uid )
451{
452 RemoveQuery rem( uid );
453 OSQLResult res = m_driver->query(&rem );
454
455 if ( res.state() == OSQLResult::Failure )
456 return false;
457
458 m_changed = true;
459
460 return true;
461}
462
463bool OContactAccessBackend_SQL::replace ( const OContact &contact )
464{
465 if ( !remove( contact.uid() ) )
466 return false;
467
468 return add( contact );
469}
470
471
472OContact OContactAccessBackend_SQL::find ( int uid ) const
473{
474 qWarning("OContactAccessBackend_SQL::find()");
475 QTime t;
476 t.start();
477
478 OContact retContact( requestNonCustom( uid ) );
479 retContact.setExtraMap( requestCustom( uid ) );
480
481 qWarning("OContactAccessBackend_SQL::find() needed: %d", t.elapsed() );
482 return retContact;
483}
484
485
486
487QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() )
488{
489 QArray<int> nix(0);
490 return nix;
491}
492
493QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
494{
495 QArray<int> nix(0);
496 return nix;
497}
498
499const uint OContactAccessBackend_SQL::querySettings()
500{
501 return 0;
502}
503
504bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
505{
506 return false;
507}
508
509QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int )
510{
511 QTime t;
512 t.start();
513
514 // Not implemented..
515 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' ";
516
517 query += "ORDER BY value ";
518 if ( !asc )
519 query += "DESC";
520
521 qWarning("sorted query is: %s", query.latin1() );
522
523 OSQLRawQuery raw( query );
524 OSQLResult res = m_driver->query( &raw );
525 if ( res.state() != OSQLResult::Success ){
526 QArray<int> empty;
527 return empty;
528 }
529
530 QArray<int> list = extractUids( res );
531
532 qWarning("sorted needed %d ms!", t.elapsed() );
533 return list;
534}
535
536
537void OContactAccessBackend_SQL::update()
538{
539 qWarning("Update starts");
540 QTime t;
541 t.start();
542
543 // Now load the database set and extract the uid's
544 // which will be held locally
545
546 LoadQuery lo;
547 OSQLResult res = m_driver->query(&lo);
548 if ( res.state() != OSQLResult::Success )
549 return;
550
551 m_uids = extractUids( res );
552
553 m_changed = false;
554
555 qWarning("Update ends %d", t.elapsed() );
556}
557
558QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
559{
560 qWarning("extractUids");
561 QTime t;
562 t.start();
563 OSQLResultItem::ValueList list = res.results();
564 OSQLResultItem::ValueList::Iterator it;
565 QArray<int> ints(list.count() );
566 qWarning(" count = %d", list.count() );
567
568 int i = 0;
569 for (it = list.begin(); it != list.end(); ++it ) {
570 ints[i] = (*it).data("uid").toInt();
571 i++;
572 }
573 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
574
575 return ints;
576
577}
578
579QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
580{
581 QTime t;
582 t.start();
583
584 QMap<int, QString> nonCustomMap;
585
586 int t2needed = 0;
587 QTime t2;
588 t2.start();
589 FindQuery query( uid );
590 OSQLResult res_noncustom = m_driver->query( &query );
591 t2needed = t2.elapsed();
592
593 if ( res_noncustom.state() == OSQLResult::Failure ) {
594 qWarning("OSQLResult::Failure in find query !!");
595 QMap<int, QString> empty;
596 return empty;
597 }
598
599 int t3needed = 0;
600 QTime t3;
601 t3.start();
602 QMap<QString, int> translateMap = OContactFields::untrFieldsToId();
603
604 OSQLResultItem::ValueList list = res_noncustom.results();
605 OSQLResultItem::ValueList::Iterator it = list.begin();
606 for ( ; it != list.end(); ++it ) {
607 if ( (*it).data("type") != "" ){
608 int typeId = translateMap[(*it).data( "type" )];
609 switch( typeId ){
610 case Qtopia::Birthday:
611 case Qtopia::Anniversary:{
612 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
613 QStringList list = QStringList::split( '-', (*it).data( "value" ) );
614 QStringList::Iterator lit = list.begin();
615 int year = (*lit).toInt();
616 qWarning("1. %s", (*lit).latin1());
617 int month = (*(++lit)).toInt();
618 qWarning("2. %s", (*lit).latin1());
619 int day = (*(++lit)).toInt();
620 qWarning("3. %s", (*lit).latin1());
621 qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day );
622 QDate date( year, month, day );
623 nonCustomMap.insert( typeId, OConversion::dateToString( date ) );
624 }
625 break;
626 default:
627 nonCustomMap.insert( typeId,
628 (*it).data( "value" ) );
629 }
630 }
631 }
632 // Add UID to Map..
633 nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) );
634 t3needed = t3.elapsed();
635
636 qWarning("RequestNonCustom needed: ins:%d, query: %d, mapping: %d", t.elapsed(), t2needed, t3needed );
637 return nonCustomMap;
638}
639
640QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const
641{
642 QTime t;
643 t.start();
644
645 QMap<QString, QString> customMap;
646
647 FindCustomQuery query( uid );
648 OSQLResult res_custom = m_driver->query( &query );
649
650 if ( res_custom.state() == OSQLResult::Failure ) {
651 qWarning("OSQLResult::Failure in find query !!");
652 QMap<QString, QString> empty;
653 return empty;
654 }
655
656 OSQLResultItem::ValueList list = res_custom.results();
657 OSQLResultItem::ValueList::Iterator it = list.begin();
658 for ( ; it != list.end(); ++it ) {
659 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
660 }
661
662 qWarning("RequestCustom needed: %d", t.elapsed() );
663 return customMap;
664}
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
new file mode 100644
index 0000000..bb22551
--- a/dev/null
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
@@ -0,0 +1,96 @@
1/*
2 * SQL Backend for the OPIE-Contact Database.
3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 *
6 * =====================================================================
7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * =====================================================================
12 *
13 *
14 * =====================================================================
15 * Version: $Id$
16 * =====================================================================
17 * History:
18 * $Log$
19 * Revision 1.1 2003/09/22 14:31:16 eilers
20 * Added first experimental incarnation of sql-backend for addressbook.
21 * Some modifications to be able to compile the todo sql-backend.
22 * A lot of changes fill follow...
23 *
24 *
25 */
26
27#ifndef _OContactAccessBackend_SQL_
28#define _OContactAccessBackend_SQL_
29
30#include "ocontactaccessbackend.h"
31#include "ocontactaccess.h"
32
33#include <qlist.h>
34#include <qdict.h>
35
36class OSQLDriver;
37class OSQLResult;
38class OSQLResultItem;
39
40/* the default xml implementation */
41/**
42 * This class is the SQL implementation of a Contact backend
43 * it does implement everything available for OContact.
44 * @see OPimAccessBackend for more information of available methods
45 */
46class OContactAccessBackend_SQL : public OContactAccessBackend {
47 public:
48 OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null );
49
50 bool save();
51
52 bool load ();
53
54 void clear ();
55
56 bool wasChangedExternally();
57
58 QArray<int> allRecords() const;
59
60 OContact find ( int uid ) const;
61 // FIXME: Add lookahead-cache support !
62 //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
63
64 QArray<int> queryByExample ( const OContact &query, int settings,
65 const QDateTime& d );
66
67 QArray<int> matchRegexp( const QRegExp &r ) const;
68
69 const uint querySettings();
70
71 bool hasQuerySettings (uint querySettings) const;
72
73 // Currently only asc implemented..
74 QArray<int> sorted( bool asc, int , int , int );
75 bool add ( const OContact &newcontact );
76
77 bool replace ( const OContact &contact );
78
79 bool remove ( int uid );
80 bool reload();
81
82 private:
83 QArray<int> extractUids( OSQLResult& res ) const;
84 QMap<int, QString> requestNonCustom( int uid ) const;
85 QMap<QString, QString> requestCustom( int uid ) const;
86 void update();
87
88 protected:
89 bool m_changed;
90 QString m_fileName;
91 QArray<int> m_uids;
92
93 OSQLDriver* m_driver;
94};
95
96#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
index 1b5af2f..aae7fca 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
@@ -1,83 +1,86 @@
1/* 1/*
2 * XML Backend for the OPIE-Contact Database. 2 * XML Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 *
14 * 12 *
15 * ===================================================================== 13 * =====================================================================
16 * Version: $Id$ 14 * Version: $Id$
17 * ===================================================================== 15 * =====================================================================
18 * History: 16 * History:
19 * $Log$ 17 * $Log$
18 * Revision 1.9 2003/09/22 14:31:16 eilers
19 * Added first experimental incarnation of sql-backend for addressbook.
20 * Some modifications to be able to compile the todo sql-backend.
21 * A lot of changes fill follow...
22 *
20 * Revision 1.8 2003/08/30 15:28:26 eilers 23 * Revision 1.8 2003/08/30 15:28:26 eilers
21 * Removed some unimportant debug output which causes slow down.. 24 * Removed some unimportant debug output which causes slow down..
22 * 25 *
23 * Revision 1.7 2003/08/01 12:30:16 eilers 26 * Revision 1.7 2003/08/01 12:30:16 eilers
24 * Merging changes from BRANCH_1_0 to HEAD 27 * Merging changes from BRANCH_1_0 to HEAD
25 * 28 *
26 * Revision 1.6 2003/07/07 16:19:47 eilers 29 * Revision 1.6 2003/07/07 16:19:47 eilers
27 * Fixing serious bug in hasQuerySettings() 30 * Fixing serious bug in hasQuerySettings()
28 * 31 *
29 * Revision 1.5 2003/04/13 18:07:10 zecke 32 * Revision 1.5 2003/04/13 18:07:10 zecke
30 * More API doc 33 * More API doc
31 * QString -> const QString& 34 * QString -> const QString&
32 * QString = 0l -> QString::null 35 * QString = 0l -> QString::null
33 * 36 *
34 * Revision 1.4 2003/03/21 14:32:54 mickeyl 37 * Revision 1.4 2003/03/21 14:32:54 mickeyl
35 * g++ compliance fix: default arguments belong into the declaration, but not the definition 38 * g++ compliance fix: default arguments belong into the declaration, but not the definition
36 * 39 *
37 * Revision 1.3 2003/03/21 12:26:28 eilers 40 * Revision 1.3 2003/03/21 12:26:28 eilers
38 * Fixing small bug: If we search a birthday from today to today, it returned 41 * Fixing small bug: If we search a birthday from today to today, it returned
39 * every contact .. 42 * every contact ..
40 * 43 *
41 * Revision 1.2 2003/03/21 10:33:09 eilers 44 * Revision 1.2 2003/03/21 10:33:09 eilers
42 * Merged speed optimized xml backend for contacts to main. 45 * Merged speed optimized xml backend for contacts to main.
43 * Added QDateTime to querybyexample. For instance, it is now possible to get 46 * Added QDateTime to querybyexample. For instance, it is now possible to get
44 * all Birthdays/Anniversaries between two dates. This should be used 47 * all Birthdays/Anniversaries between two dates. This should be used
45 * to show all birthdays in the datebook.. 48 * to show all birthdays in the datebook..
46 * This change is sourcecode backward compatible but you have to upgrade 49 * This change is sourcecode backward compatible but you have to upgrade
47 * the binaries for today-addressbook. 50 * the binaries for today-addressbook.
48 * 51 *
49 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers 52 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers
50 * Speed optimization. Removed the sequential search loops. 53 * Speed optimization. Removed the sequential search loops.
51 * 54 *
52 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers 55 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers
53 * Writing offsets to debug output.. 56 * Writing offsets to debug output..
54 * 57 *
55 * Revision 1.1 2003/02/09 15:05:01 eilers 58 * Revision 1.1 2003/02/09 15:05:01 eilers
56 * Nothing happened.. Just some cleanup before I will start.. 59 * Nothing happened.. Just some cleanup before I will start..
57 * 60 *
58 * Revision 1.12 2003/01/03 16:58:03 eilers 61 * Revision 1.12 2003/01/03 16:58:03 eilers
59 * Reenable debug output 62 * Reenable debug output
60 * 63 *
61 * Revision 1.11 2003/01/03 12:31:28 eilers 64 * Revision 1.11 2003/01/03 12:31:28 eilers
62 * Bugfix for calculating data diffs.. 65 * Bugfix for calculating data diffs..
63 * 66 *
64 * Revision 1.10 2003/01/02 14:27:12 eilers 67 * Revision 1.10 2003/01/02 14:27:12 eilers
65 * Improved query by example: Search by date is possible.. First step 68 * Improved query by example: Search by date is possible.. First step
66 * for a today plugin for birthdays.. 69 * for a today plugin for birthdays..
67 * 70 *
68 * Revision 1.9 2002/12/08 12:48:57 eilers 71 * Revision 1.9 2002/12/08 12:48:57 eilers
69 * Moved journal-enum from ocontact into i the xml-backend.. 72 * Moved journal-enum from ocontact into i the xml-backend..
70 * 73 *
71 * Revision 1.8 2002/11/14 17:04:24 eilers 74 * Revision 1.8 2002/11/14 17:04:24 eilers
72 * Sorting will now work if fullname is identical on some entries 75 * Sorting will now work if fullname is identical on some entries
73 * 76 *
74 * Revision 1.7 2002/11/13 15:02:46 eilers 77 * Revision 1.7 2002/11/13 15:02:46 eilers
75 * Small Bug in sorted fixed 78 * Small Bug in sorted fixed
76 * 79 *
77 * Revision 1.6 2002/11/13 14:14:51 eilers 80 * Revision 1.6 2002/11/13 14:14:51 eilers
78 * Added sorted for Contacts.. 81 * Added sorted for Contacts..
79 * 82 *
80 * Revision 1.5 2002/11/01 15:10:42 eilers 83 * Revision 1.5 2002/11/01 15:10:42 eilers
81 * Added regExp-search in database for all fields in a contact. 84 * Added regExp-search in database for all fields in a contact.
82 * 85 *
83 * Revision 1.4 2002/10/16 10:52:40 eilers 86 * Revision 1.4 2002/10/16 10:52:40 eilers
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
index 7b5365b..a0cae4d 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
@@ -1,83 +1,89 @@
1/* 1/*
2 * XML Backend for the OPIE-Contact Database. 2 * XML Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed... 12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 * File Locking to protect against concurrent access
13 * 14 *
14 * 15 *
15 * ===================================================================== 16 * =====================================================================
16 * Version: $Id$ 17 * Version: $Id$
17 * ===================================================================== 18 * =====================================================================
18 * History: 19 * History:
19 * $Log$ 20 * $Log$
21 * Revision 1.15 2003/09/22 14:31:16 eilers
22 * Added first experimental incarnation of sql-backend for addressbook.
23 * Some modifications to be able to compile the todo sql-backend.
24 * A lot of changes fill follow...
25 *
20 * Revision 1.14 2003/04/13 18:07:10 zecke 26 * Revision 1.14 2003/04/13 18:07:10 zecke
21 * More API doc 27 * More API doc
22 * QString -> const QString& 28 * QString -> const QString&
23 * QString = 0l -> QString::null 29 * QString = 0l -> QString::null
24 * 30 *
25 * Revision 1.13 2003/03/21 10:33:09 eilers 31 * Revision 1.13 2003/03/21 10:33:09 eilers
26 * Merged speed optimized xml backend for contacts to main. 32 * Merged speed optimized xml backend for contacts to main.
27 * Added QDateTime to querybyexample. For instance, it is now possible to get 33 * Added QDateTime to querybyexample. For instance, it is now possible to get
28 * all Birthdays/Anniversaries between two dates. This should be used 34 * all Birthdays/Anniversaries between two dates. This should be used
29 * to show all birthdays in the datebook.. 35 * to show all birthdays in the datebook..
30 * This change is sourcecode backward compatible but you have to upgrade 36 * This change is sourcecode backward compatible but you have to upgrade
31 * the binaries for today-addressbook. 37 * the binaries for today-addressbook.
32 * 38 *
33 * Revision 1.12.2.2 2003/02/11 12:17:28 eilers 39 * Revision 1.12.2.2 2003/02/11 12:17:28 eilers
34 * Speed optimization. Removed the sequential search loops. 40 * Speed optimization. Removed the sequential search loops.
35 * 41 *
36 * Revision 1.12.2.1 2003/02/09 15:05:01 eilers 42 * Revision 1.12.2.1 2003/02/09 15:05:01 eilers
37 * Nothing happened.. Just some cleanup before I will start.. 43 * Nothing happened.. Just some cleanup before I will start..
38 * 44 *
39 * Revision 1.12 2003/01/03 16:58:03 eilers 45 * Revision 1.12 2003/01/03 16:58:03 eilers
40 * Reenable debug output 46 * Reenable debug output
41 * 47 *
42 * Revision 1.11 2003/01/03 12:31:28 eilers 48 * Revision 1.11 2003/01/03 12:31:28 eilers
43 * Bugfix for calculating data diffs.. 49 * Bugfix for calculating data diffs..
44 * 50 *
45 * Revision 1.10 2003/01/02 14:27:12 eilers 51 * Revision 1.10 2003/01/02 14:27:12 eilers
46 * Improved query by example: Search by date is possible.. First step 52 * Improved query by example: Search by date is possible.. First step
47 * for a today plugin for birthdays.. 53 * for a today plugin for birthdays..
48 * 54 *
49 * Revision 1.9 2002/12/08 12:48:57 eilers 55 * Revision 1.9 2002/12/08 12:48:57 eilers
50 * Moved journal-enum from ocontact into i the xml-backend.. 56 * Moved journal-enum from ocontact into i the xml-backend..
51 * 57 *
52 * Revision 1.8 2002/11/14 17:04:24 eilers 58 * Revision 1.8 2002/11/14 17:04:24 eilers
53 * Sorting will now work if fullname is identical on some entries 59 * Sorting will now work if fullname is identical on some entries
54 * 60 *
55 * Revision 1.7 2002/11/13 15:02:46 eilers 61 * Revision 1.7 2002/11/13 15:02:46 eilers
56 * Small Bug in sorted fixed 62 * Small Bug in sorted fixed
57 * 63 *
58 * Revision 1.6 2002/11/13 14:14:51 eilers 64 * Revision 1.6 2002/11/13 14:14:51 eilers
59 * Added sorted for Contacts.. 65 * Added sorted for Contacts..
60 * 66 *
61 * Revision 1.5 2002/11/01 15:10:42 eilers 67 * Revision 1.5 2002/11/01 15:10:42 eilers
62 * Added regExp-search in database for all fields in a contact. 68 * Added regExp-search in database for all fields in a contact.
63 * 69 *
64 * Revision 1.4 2002/10/16 10:52:40 eilers 70 * Revision 1.4 2002/10/16 10:52:40 eilers
65 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 71 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
66 * 72 *
67 * Revision 1.3 2002/10/14 16:21:54 eilers 73 * Revision 1.3 2002/10/14 16:21:54 eilers
68 * Some minor interface updates 74 * Some minor interface updates
69 * 75 *
70 * Revision 1.2 2002/10/07 17:34:24 eilers 76 * Revision 1.2 2002/10/07 17:34:24 eilers
71 * added OBackendFactory for advanced backend access 77 * added OBackendFactory for advanced backend access
72 * 78 *
73 * Revision 1.1 2002/09/27 17:11:44 eilers 79 * Revision 1.1 2002/09/27 17:11:44 eilers
74 * Added API for accessing the Contact-Database ! It is compiling, but 80 * Added API for accessing the Contact-Database ! It is compiling, but
75 * please do not expect that anything is working ! 81 * please do not expect that anything is working !
76 * I will debug that stuff in the next time .. 82 * I will debug that stuff in the next time ..
77 * Please read README_COMPILE for compiling ! 83 * Please read README_COMPILE for compiling !
78 * 84 *
79 * 85 *
80 */ 86 */
81 87
82#ifndef _OContactAccessBackend_XML_ 88#ifndef _OContactAccessBackend_XML_
83#define _OContactAccessBackend_XML_ 89#define _OContactAccessBackend_XML_
diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp
index ec9c14c..23e0c3e 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.cpp
+++ b/libopie2/opiepim/backend/otodoaccesssql.cpp
@@ -1,73 +1,73 @@
1 1
2#include <qdatetime.h> 2#include <qdatetime.h>
3 3
4#include <qpe/global.h> 4#include <qpe/global.h>
5 5
6#include <opie/osqldriver.h> 6#include <opie2/osqldriver.h>
7#include <opie/osqlresult.h> 7#include <opie2/osqlresult.h>
8#include <opie/osqlmanager.h> 8#include <opie2/osqlmanager.h>
9#include <opie/osqlquery.h> 9#include <opie2/osqlquery.h>
10 10
11#include "otodoaccesssql.h" 11#include "otodoaccesssql.h"
12 12
13/* 13/*
14 * first some query 14 * first some query
15 * CREATE query 15 * CREATE query
16 * LOAD query 16 * LOAD query
17 * INSERT 17 * INSERT
18 * REMOVE 18 * REMOVE
19 * CLEAR 19 * CLEAR
20 */ 20 */
21namespace { 21namespace {
22 /** 22 /**
23 * CreateQuery for the Todolist Table 23 * CreateQuery for the Todolist Table
24 */ 24 */
25 class CreateQuery : public OSQLQuery { 25 class CreateQuery : public OSQLQuery {
26 public: 26 public:
27 CreateQuery(); 27 CreateQuery();
28 ~CreateQuery(); 28 ~CreateQuery();
29 QString query()const; 29 QString query()const;
30 }; 30 };
31 31
32 /** 32 /**
33 * LoadQuery 33 * LoadQuery
34 * this one queries for all uids 34 * this one queries for all uids
35 */ 35 */
36 class LoadQuery : public OSQLQuery { 36 class LoadQuery : public OSQLQuery {
37 public: 37 public:
38 LoadQuery(); 38 LoadQuery();
39 ~LoadQuery(); 39 ~LoadQuery();
40 QString query()const; 40 QString query()const;
41 }; 41 };
42 42
43 /** 43 /**
44 * inserts/adds a OTodo to the table 44 * inserts/adds a OTodo to the table
45 */ 45 */
46 class InsertQuery : public OSQLQuery { 46 class InsertQuery : public OSQLQuery {
47 public: 47 public:
48 InsertQuery(const OTodo& ); 48 InsertQuery(const OTodo& );
49 ~InsertQuery(); 49 ~InsertQuery();
50 QString query()const; 50 QString query()const;
51 private: 51 private:
52 OTodo m_todo; 52 OTodo m_todo;
53 }; 53 };
54 54
55 /** 55 /**
56 * removes one from the table 56 * removes one from the table
57 */ 57 */
58 class RemoveQuery : public OSQLQuery { 58 class RemoveQuery : public OSQLQuery {
59 public: 59 public:
60 RemoveQuery(int uid ); 60 RemoveQuery(int uid );
61 ~RemoveQuery(); 61 ~RemoveQuery();
62 QString query()const; 62 QString query()const;
63 private: 63 private:
64 int m_uid; 64 int m_uid;
65 }; 65 };
66 66
67 /** 67 /**
68 * Clears (delete) a Table 68 * Clears (delete) a Table
69 */ 69 */
70 class ClearQuery : public OSQLQuery { 70 class ClearQuery : public OSQLQuery {
71 public: 71 public:
72 ClearQuery(); 72 ClearQuery();
73 ~ClearQuery(); 73 ~ClearQuery();
@@ -188,353 +188,406 @@ namespace {
188 QString FindQuery::query()const{ 188 QString FindQuery::query()const{
189 if (m_uids.count() == 0 ) 189 if (m_uids.count() == 0 )
190 return single(); 190 return single();
191 else 191 else
192 return multi(); 192 return multi();
193 } 193 }
194 QString FindQuery::single()const{ 194 QString FindQuery::single()const{
195 QString qu = "select uid, categories, completed, progress, summary, "; 195 QString qu = "select uid, categories, completed, progress, summary, ";
196 qu += "DueDate, priority, description from todolist where uid = " + QString::number(m_uid); 196 qu += "DueDate, priority, description from todolist where uid = " + QString::number(m_uid);
197 return qu; 197 return qu;
198 } 198 }
199 QString FindQuery::multi()const { 199 QString FindQuery::multi()const {
200 QString qu = "select uid, categories, completed, progress, summary, "; 200 QString qu = "select uid, categories, completed, progress, summary, ";
201 qu += "DueDate, priority, description from todolist where "; 201 qu += "DueDate, priority, description from todolist where ";
202 for (uint i = 0; i < m_uids.count(); i++ ) { 202 for (uint i = 0; i < m_uids.count(); i++ ) {
203 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 203 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
204 } 204 }
205 qu.remove( qu.length()-2, 2 ); 205 qu.remove( qu.length()-2, 2 );
206 return qu; 206 return qu;
207 } 207 }
208 208
209 OverDueQuery::OverDueQuery(): OSQLQuery() {} 209 OverDueQuery::OverDueQuery(): OSQLQuery() {}
210 OverDueQuery::~OverDueQuery() {} 210 OverDueQuery::~OverDueQuery() {}
211 QString OverDueQuery::query()const { 211 QString OverDueQuery::query()const {
212 QDate date = QDate::currentDate(); 212 QDate date = QDate::currentDate();
213 QString str; 213 QString str;
214 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); 214 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() );
215 215
216 return str; 216 return str;
217 } 217 }
218 218
219 219
220 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) 220 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc )
221 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} 221 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {}
222 EffQuery::~EffQuery() {} 222 EffQuery::~EffQuery() {}
223 QString EffQuery::query()const { 223 QString EffQuery::query()const {
224 return m_inc ? with() : out(); 224 return m_inc ? with() : out();
225 } 225 }
226 QString EffQuery::with()const { 226 QString EffQuery::with()const {
227 QString str; 227 QString str;
228 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") 228 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ")
229 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) 229 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() )
230 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); 230 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() );
231 return str; 231 return str;
232 } 232 }
233 QString EffQuery::out()const { 233 QString EffQuery::out()const {
234 QString str; 234 QString str;
235 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") 235 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'")
236 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) 236 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() )
237 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); 237 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() );
238 238
239 return str; 239 return str;
240 } 240 }
241}; 241};
242 242
243OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) 243OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file )
244 : OTodoAccessBackend(), m_dict(15), m_dirty(true) 244 : OTodoAccessBackend(), m_dict(15), m_dirty(true)
245{ 245{
246 QString fi = file; 246 QString fi = file;
247 if ( fi.isEmpty() ) 247 if ( fi.isEmpty() )
248 fi = Global::applicationFileName( "todolist", "todolist.db" ); 248 fi = Global::applicationFileName( "todolist", "todolist.db" );
249 OSQLManager man; 249 OSQLManager man;
250 m_driver = man.standard(); 250 m_driver = man.standard();
251 m_driver->setUrl(fi); 251 m_driver->setUrl(fi);
252 fillDict(); 252 // fillDict();
253} 253}
254 254
255OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ 255OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){
256} 256}
257bool OTodoAccessBackendSQL::load(){ 257bool OTodoAccessBackendSQL::load(){
258 if (!m_driver->open() ) 258 if (!m_driver->open() )
259 return false; 259 return false;
260 260
261 CreateQuery creat; 261 CreateQuery creat;
262 OSQLResult res = m_driver->query(&creat ); 262 OSQLResult res = m_driver->query(&creat );
263 263
264 m_dirty = true; 264 m_dirty = true;
265 return true; 265 return true;
266} 266}
267bool OTodoAccessBackendSQL::reload(){ 267bool OTodoAccessBackendSQL::reload(){
268 return load(); 268 return load();
269} 269}
270 270
271bool OTodoAccessBackendSQL::save(){ 271bool OTodoAccessBackendSQL::save(){
272 return m_driver->close(); 272 return m_driver->close();
273} 273}
274QArray<int> OTodoAccessBackendSQL::allRecords()const { 274QArray<int> OTodoAccessBackendSQL::allRecords()const {
275 if (m_dirty ) 275 if (m_dirty )
276 update(); 276 update();
277 277
278 return m_uids; 278 return m_uids;
279} 279}
280QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ 280QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){
281 QArray<int> ints(0); 281 QArray<int> ints(0);
282 return ints; 282 return ints;
283} 283}
284OTodo OTodoAccessBackendSQL::find(int uid ) const{ 284OTodo OTodoAccessBackendSQL::find(int uid ) const{
285 FindQuery query( uid ); 285 FindQuery query( uid );
286 return todo( m_driver->query(&query) ); 286 return todo( m_driver->query(&query) );
287 287
288} 288}
289OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, 289OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
290 uint cur, Frontend::CacheDirection dir ) const{ 290 uint cur, Frontend::CacheDirection dir ) const{
291 int CACHE = readAhead(); 291 int CACHE = readAhead();
292 qWarning("searching for %d", uid ); 292 qWarning("searching for %d", uid );
293 QArray<int> search( CACHE ); 293 QArray<int> search( CACHE );
294 uint size =0; 294 uint size =0;
295 OTodo to; 295 OTodo to;
296 296
297 // we try to cache CACHE items 297 // we try to cache CACHE items
298 switch( dir ) { 298 switch( dir ) {
299 /* forward */ 299 /* forward */
300 case 0: 300 case 0: // FIXME: Not a good style to use magic numbers here (eilers)
301 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { 301 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
302 qWarning("size %d %d", size, ints[i] ); 302 qWarning("size %d %d", size, ints[i] );
303 search[size] = ints[i]; 303 search[size] = ints[i];
304 size++; 304 size++;
305 } 305 }
306 break; 306 break;
307 /* reverse */ 307 /* reverse */
308 case 1: 308 case 1: // FIXME: Not a good style to use magic numbers here (eilers)
309 for (uint i = cur; i != 0 && size < CACHE; i-- ) { 309 for (uint i = cur; i != 0 && size < CACHE; i-- ) {
310 search[size] = ints[i]; 310 search[size] = ints[i];
311 size++; 311 size++;
312 } 312 }
313 break; 313 break;
314 } 314 }
315 search.resize( size ); 315 search.resize( size );
316 FindQuery query( search ); 316 FindQuery query( search );
317 OSQLResult res = m_driver->query( &query ); 317 OSQLResult res = m_driver->query( &query );
318 if ( res.state() != OSQLResult::Success ) 318 if ( res.state() != OSQLResult::Success )
319 return to; 319 return to;
320 320
321 return todo( res ); 321 return todo( res );
322} 322}
323void OTodoAccessBackendSQL::clear() { 323void OTodoAccessBackendSQL::clear() {
324 ClearQuery cle; 324 ClearQuery cle;
325 OSQLResult res = m_driver->query( &cle ); 325 OSQLResult res = m_driver->query( &cle );
326 CreateQuery qu; 326 CreateQuery qu;
327 res = m_driver->query(&qu); 327 res = m_driver->query(&qu);
328} 328}
329bool OTodoAccessBackendSQL::add( const OTodo& t) { 329bool OTodoAccessBackendSQL::add( const OTodo& t) {
330 InsertQuery ins( t ); 330 InsertQuery ins( t );
331 OSQLResult res = m_driver->query( &ins ); 331 OSQLResult res = m_driver->query( &ins );
332 332
333 if ( res.state() == OSQLResult::Failure ) 333 if ( res.state() == OSQLResult::Failure )
334 return false; 334 return false;
335 int c = m_uids.count(); 335 int c = m_uids.count();
336 m_uids.resize( c+1 ); 336 m_uids.resize( c+1 );
337 m_uids[c] = t.uid(); 337 m_uids[c] = t.uid();
338 338
339 return true; 339 return true;
340} 340}
341bool OTodoAccessBackendSQL::remove( int uid ) { 341bool OTodoAccessBackendSQL::remove( int uid ) {
342 RemoveQuery rem( uid ); 342 RemoveQuery rem( uid );
343 OSQLResult res = m_driver->query(&rem ); 343 OSQLResult res = m_driver->query(&rem );
344 344
345 if ( res.state() == OSQLResult::Failure ) 345 if ( res.state() == OSQLResult::Failure )
346 return false; 346 return false;
347 347
348 m_dirty = true; 348 m_dirty = true;
349 return true; 349 return true;
350} 350}
351/* 351/*
352 * FIXME better set query 352 * FIXME better set query
353 * but we need the cache for that 353 * but we need the cache for that
354 * now we remove 354 * now we remove
355 */ 355 */
356bool OTodoAccessBackendSQL::replace( const OTodo& t) { 356bool OTodoAccessBackendSQL::replace( const OTodo& t) {
357 remove( t.uid() ); 357 remove( t.uid() );
358 bool b= add(t); 358 bool b= add(t);
359 m_dirty = false; // we changed some stuff but the UID stayed the same 359 m_dirty = false; // we changed some stuff but the UID stayed the same
360 return b; 360 return b;
361} 361}
362QArray<int> OTodoAccessBackendSQL::overDue() { 362QArray<int> OTodoAccessBackendSQL::overDue() {
363 OverDueQuery qu; 363 OverDueQuery qu;
364 return uids( m_driver->query(&qu ) ); 364 return uids( m_driver->query(&qu ) );
365} 365}
366QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, 366QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s,
367 const QDate& t, 367 const QDate& t,
368 bool u) { 368 bool u) {
369 EffQuery ef(s, t, u ); 369 EffQuery ef(s, t, u );
370 return uids (m_driver->query(&ef) ); 370 return uids (m_driver->query(&ef) );
371} 371}
372/* 372/*
373 * 373 *
374 */ 374 */
375QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, 375QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
376 int sortFilter, int cat ) { 376 int sortFilter, int cat ) {
377 qWarning("sorted %d, %d", asc, sortOrder ); 377 qWarning("sorted %d, %d", asc, sortOrder );
378 QString query; 378 QString query;
379 query = "select uid from todolist WHERE "; 379 query = "select uid from todolist WHERE ";
380 380
381 /* 381 /*
382 * Sort Filter stuff 382 * Sort Filter stuff
383 * not that straight forward 383 * not that straight forward
384 * FIXME: Replace magic numbers
384 * 385 *
385 */ 386 */
386 /* Category */ 387 /* Category */
387 if ( sortFilter & 1 ) { 388 if ( sortFilter & 1 ) {
388 QString str; 389 QString str;
389 if (cat != 0 ) str = QString::number( cat ); 390 if (cat != 0 ) str = QString::number( cat );
390 query += " categories like '%" +str+"%' AND"; 391 query += " categories like '%" +str+"%' AND";
391 } 392 }
392 /* Show only overdue */ 393 /* Show only overdue */
393 if ( sortFilter & 2 ) { 394 if ( sortFilter & 2 ) {
394 QDate date = QDate::currentDate(); 395 QDate date = QDate::currentDate();
395 QString due; 396 QString due;
396 QString base; 397 QString base;
397 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); 398 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() );
398 query += " " + base + " AND"; 399 query += " " + base + " AND";
399 } 400 }
400 /* not show completed */ 401 /* not show completed */
401 if ( sortFilter & 4 ) { 402 if ( sortFilter & 4 ) {
402 query += " completed = 0 AND"; 403 query += " completed = 0 AND";
403 }else{ 404 }else{
404 query += " ( completed = 1 OR completed = 0) AND"; 405 query += " ( completed = 1 OR completed = 0) AND";
405 } 406 }
406 /* srtip the end */ 407 /* srtip the end */
407 query = query.remove( query.length()-3, 3 ); 408 query = query.remove( query.length()-3, 3 );
408 409
409 410
410 /* 411 /*
411 * sort order stuff 412 * sort order stuff
412 * quite straight forward 413 * quite straight forward
413 */ 414 */
414 query += "ORDER BY "; 415 query += "ORDER BY ";
415 switch( sortOrder ) { 416 switch( sortOrder ) {
416 /* completed */ 417 /* completed */
417 case 0: 418 case 0:
418 query += "completed"; 419 query += "completed";
419 break; 420 break;
420 case 1: 421 case 1:
421 query += "priority"; 422 query += "priority";
422 break; 423 break;
423 case 2: 424 case 2:
424 query += "summary"; 425 query += "summary";
425 break; 426 break;
426 case 3: 427 case 3:
427 query += "DueDate"; 428 query += "DueDate";
428 break; 429 break;
429 } 430 }
430 431
431 if ( !asc ) { 432 if ( !asc ) {
432 qWarning("not ascending!"); 433 qWarning("not ascending!");
433 query += " DESC"; 434 query += " DESC";
434 } 435 }
435 436
436 qWarning( query ); 437 qWarning( query );
437 OSQLRawQuery raw(query ); 438 OSQLRawQuery raw(query );
438 return uids( m_driver->query(&raw) ); 439 return uids( m_driver->query(&raw) );
439} 440}
440bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ 441bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{
441 if ( str == "0-0-0" ) 442 if ( str == "0-0-0" )
442 return false; 443 return false;
443 else{ 444 else{
444 int day, year, month; 445 int day, year, month;
445 QStringList list = QStringList::split("-", str ); 446 QStringList list = QStringList::split("-", str );
446 year = list[0].toInt(); 447 year = list[0].toInt();
447 month = list[1].toInt(); 448 month = list[1].toInt();
448 day = list[2].toInt(); 449 day = list[2].toInt();
449 da.setYMD( year, month, day ); 450 da.setYMD( year, month, day );
450 return true; 451 return true;
451 } 452 }
452} 453}
453OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ 454OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{
454 if ( res.state() == OSQLResult::Failure ) { 455 if ( res.state() == OSQLResult::Failure ) {
455 OTodo to; 456 OTodo to;
456 return to; 457 return to;
457 } 458 }
458 459
459 OSQLResultItem::ValueList list = res.results(); 460 OSQLResultItem::ValueList list = res.results();
460 OSQLResultItem::ValueList::Iterator it = list.begin(); 461 OSQLResultItem::ValueList::Iterator it = list.begin();
461 qWarning("todo1"); 462 qWarning("todo1");
462 OTodo to = todo( (*it) ); 463 OTodo to = todo( (*it) );
463 cache( to ); 464 cache( to );
464 ++it; 465 ++it;
465 466
466 for ( ; it != list.end(); ++it ) { 467 for ( ; it != list.end(); ++it ) {
467 qWarning("caching"); 468 qWarning("caching");
468 cache( todo( (*it) ) ); 469 cache( todo( (*it) ) );
469 } 470 }
470 return to; 471 return to;
471} 472}
472OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const { 473OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const {
473 qWarning("todo"); 474 qWarning("todo");
474 bool has = false; QDate da = QDate::currentDate(); 475 bool has = false; QDate da = QDate::currentDate();
475 has = date( da, item.data("DueDate") ); 476 has = date( da, item.data("DueDate") );
476 QStringList cats = QStringList::split(";", item.data("categories") ); 477 QStringList cats = QStringList::split(";", item.data("categories") );
477 478
478 OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), 479 OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(),
479 cats, item.data("summary"), item.data("description"), 480 cats, item.data("summary"), item.data("description"),
480 item.data("progress").toUShort(), has, da, 481 item.data("progress").toUShort(), has, da,
481 item.data("uid").toInt() ); 482 item.data("uid").toInt() );
482 return to; 483 return to;
483} 484}
484OTodo OTodoAccessBackendSQL::todo( int uid )const { 485OTodo OTodoAccessBackendSQL::todo( int uid )const {
485 FindQuery find( uid ); 486 FindQuery find( uid );
486 return todo( m_driver->query(&find) ); 487 return todo( m_driver->query(&find) );
487} 488}
488/* 489/*
489 * update the dict 490 * update the dict
490 */ 491 */
491void OTodoAccessBackendSQL::fillDict() { 492void OTodoAccessBackendSQL::fillDict() {
492 /* initialize dict */ 493 /* initialize dict */
493 /* 494 /*
494 * UPDATE dict if you change anything!!! 495 * UPDATE dict if you change anything!!!
496 * FIXME: Isn't this dict obsolete ? (eilers)
495 */ 497 */
496 m_dict.setAutoDelete( TRUE ); 498 m_dict.setAutoDelete( TRUE );
497 m_dict.insert("Categories" , new int(OTodo::Category) ); 499 m_dict.insert("Categories" , new int(OTodo::Category) );
498 m_dict.insert("Uid" , new int(OTodo::Uid) ); 500 m_dict.insert("Uid" , new int(OTodo::Uid) );
499 m_dict.insert("HasDate" , new int(OTodo::HasDate) ); 501 m_dict.insert("HasDate" , new int(OTodo::HasDate) );
500 m_dict.insert("Completed" , new int(OTodo::Completed) ); 502 m_dict.insert("Completed" , new int(OTodo::Completed) );
501 m_dict.insert("Description" , new int(OTodo::Description) ); 503 m_dict.insert("Description" , new int(OTodo::Description) );
502 m_dict.insert("Summary" , new int(OTodo::Summary) ); 504 m_dict.insert("Summary" , new int(OTodo::Summary) );
503 m_dict.insert("Priority" , new int(OTodo::Priority) ); 505 m_dict.insert("Priority" , new int(OTodo::Priority) );
504 m_dict.insert("DateDay" , new int(OTodo::DateDay) ); 506 m_dict.insert("DateDay" , new int(OTodo::DateDay) );
505 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 507 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) );
506 m_dict.insert("DateYear" , new int(OTodo::DateYear) ); 508 m_dict.insert("DateYear" , new int(OTodo::DateYear) );
507 m_dict.insert("Progress" , new int(OTodo::Progress) ); 509 m_dict.insert("Progress" , new int(OTodo::Progress) );
508 m_dict.insert("Completed", new int(OTodo::Completed) ); 510 m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers)
509 m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); 511 m_dict.insert("CrossReference", new int(OTodo::CrossReference) );
510 m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); 512// m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers)
511 m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); 513// m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers)
512} 514}
513/* 515/*
514 * need to be const so let's fool the 516 * need to be const so let's fool the
515 * compiler :( 517 * compiler :(
516 */ 518 */
517void OTodoAccessBackendSQL::update()const { 519void OTodoAccessBackendSQL::update()const {
518 ((OTodoAccessBackendSQL*)this)->m_dirty = false; 520 ((OTodoAccessBackendSQL*)this)->m_dirty = false;
519 LoadQuery lo; 521 LoadQuery lo;
520 OSQLResult res = m_driver->query(&lo); 522 OSQLResult res = m_driver->query(&lo);
521 if ( res.state() != OSQLResult::Success ) 523 if ( res.state() != OSQLResult::Success )
522 return; 524 return;
523 525
524 ((OTodoAccessBackendSQL*)this)->m_uids = uids( res ); 526 ((OTodoAccessBackendSQL*)this)->m_uids = uids( res );
525} 527}
526QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{ 528QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{
527 529
528 OSQLResultItem::ValueList list = res.results(); 530 OSQLResultItem::ValueList list = res.results();
529 OSQLResultItem::ValueList::Iterator it; 531 OSQLResultItem::ValueList::Iterator it;
530 QArray<int> ints(list.count() ); 532 QArray<int> ints(list.count() );
531 qWarning(" count = %d", list.count() ); 533 qWarning(" count = %d", list.count() );
532 534
533 int i = 0; 535 int i = 0;
534 for (it = list.begin(); it != list.end(); ++it ) { 536 for (it = list.begin(); it != list.end(); ++it ) {
535 ints[i] = (*it).data("uid").toInt(); 537 ints[i] = (*it).data("uid").toInt();
536 i++; 538 i++;
537 } 539 }
538 return ints; 540 return ints;
539} 541}
540 542
543QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
544{
545
546#warning OTodoAccessBackendSQL::matchRegexp() not implemented !!
547
548#if 0
549
550 Copied from xml-backend by not adapted to sql (eilers)
551
552 QArray<int> m_currentQuery( m_events.count() );
553 uint arraycounter = 0;
554
555
556
557 QMap<int, OTodo>::ConstIterator it;
558 for (it = m_events.begin(); it != m_events.end(); ++it ) {
559 if ( it.data().match( r ) )
560 m_currentQuery[arraycounter++] = it.data().uid();
561
562 }
563 // Shrink to fit..
564 m_currentQuery.resize(arraycounter);
565
566 return m_currentQuery;
567#endif
568 QArray<int> empty;
569 return empty;
570}
571QBitArray OTodoAccessBackendSQL::supports()const {
572
573 static QBitArray ar = sup();
574 return ar;
575}
576
577QBitArray OTodoAccessBackendSQL::sup() {
578
579 QBitArray ar( OTodo::CompletedDate + 1 );
580 ar.fill( true );
581 ar[OTodo::CrossReference] = false;
582 ar[OTodo::State ] = false;
583 ar[OTodo::Reminders] = false;
584 ar[OTodo::Notifiers] = false;
585 ar[OTodo::Maintainer] = false;
586
587 return ar;
588}
589
590void OTodoAccessBackendSQL::removeAllCompleted(){
591#warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !!
592
593}
diff --git a/libopie2/opiepim/backend/otodoaccesssql.h b/libopie2/opiepim/backend/otodoaccesssql.h
index 6a4257c..77d8b77 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.h
+++ b/libopie2/opiepim/backend/otodoaccesssql.h
@@ -1,50 +1,56 @@
1#ifndef OPIE_PIM_ACCESS_SQL_H 1#ifndef OPIE_PIM_ACCESS_SQL_H
2#define OPIE_PIM_ACCESS_SQL_H 2#define OPIE_PIM_ACCESS_SQL_H
3 3
4#include <qasciidict.h> 4#include <qasciidict.h>
5 5
6#include "otodoaccessbackend.h" 6#include "otodoaccessbackend.h"
7 7
8class OSQLDriver; 8class OSQLDriver;
9class OSQLResult; 9class OSQLResult;
10class OSQLResultItem; 10class OSQLResultItem;
11class OTodoAccessBackendSQL : public OTodoAccessBackend { 11class OTodoAccessBackendSQL : public OTodoAccessBackend {
12public: 12public:
13 OTodoAccessBackendSQL( const QString& file ); 13 OTodoAccessBackendSQL( const QString& file );
14 ~OTodoAccessBackendSQL(); 14 ~OTodoAccessBackendSQL();
15 15
16 bool load(); 16 bool load();
17 bool reload(); 17 bool reload();
18 bool save(); 18 bool save();
19 QArray<int> allRecords()const; 19 QArray<int> allRecords()const;
20 20
21 QArray<int> queryByExample( const OTodo& t, int settings, const QDateTime& d = QDateTime() ); 21 QArray<int> queryByExample( const OTodo& t, int settings, const QDateTime& d = QDateTime() );
22 OTodo find(int uid)const; 22 OTodo find(int uid)const;
23 OTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; 23 OTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
24 void clear(); 24 void clear();
25 bool add( const OTodo& t ); 25 bool add( const OTodo& t );
26 bool remove( int uid ); 26 bool remove( int uid );
27 bool replace( const OTodo& t ); 27 bool replace( const OTodo& t );
28 28
29 QArray<int> overDue(); 29 QArray<int> overDue();
30 QArray<int> effectiveToDos( const QDate& start, 30 QArray<int> effectiveToDos( const QDate& start,
31 const QDate& end, bool includeNoDates ); 31 const QDate& end, bool includeNoDates );
32 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat ); 32 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat );
33 33
34 QBitArray supports()const;
35 QArray<int> matchRegexp( const QRegExp &r ) const;
36 void removeAllCompleted();
37
38
34private: 39private:
35 void update()const; 40 void update()const;
36 void fillDict(); 41 void fillDict();
37 inline bool date( QDate& date, const QString& )const; 42 inline bool date( QDate& date, const QString& )const;
38 inline OTodo todo( const OSQLResult& )const; 43 inline OTodo todo( const OSQLResult& )const;
39 inline OTodo todo( OSQLResultItem& )const; 44 inline OTodo todo( OSQLResultItem& )const;
40 inline QArray<int> uids( const OSQLResult& )const; 45 inline QArray<int> uids( const OSQLResult& )const;
41 OTodo todo( int uid )const; 46 OTodo todo( int uid )const;
47 QBitArray sup();
42 48
43 QAsciiDict<int> m_dict; 49 QAsciiDict<int> m_dict;
44 OSQLDriver* m_driver; 50 OSQLDriver* m_driver;
45 QArray<int> m_uids; 51 QArray<int> m_uids;
46 bool m_dirty : 1; 52 bool m_dirty : 1;
47}; 53};
48 54
49 55
50#endif 56#endif
diff --git a/libopie2/opiepim/ocontact.h b/libopie2/opiepim/ocontact.h
index 9a1a8dc..1d46b81 100644
--- a/libopie2/opiepim/ocontact.h
+++ b/libopie2/opiepim/ocontact.h
@@ -135,111 +135,106 @@ public:
135 QString defaultEmail() const { return find( Qtopia::DefaultEmail ); } 135 QString defaultEmail() const { return find( Qtopia::DefaultEmail ); }
136 QStringList emailList() const; 136 QStringList emailList() const;
137 137
138 // home 138 // home
139 /* 139 /*
140 * OPimAddress address(enum Location)const; 140 * OPimAddress address(enum Location)const;
141 * would be some how nicer... 141 * would be some how nicer...
142 * -zecke 142 * -zecke
143 */ 143 */
144 QString homeStreet() const { return find( Qtopia::HomeStreet ); } 144 QString homeStreet() const { return find( Qtopia::HomeStreet ); }
145 QString homeCity() const { return find( Qtopia::HomeCity ); } 145 QString homeCity() const { return find( Qtopia::HomeCity ); }
146 QString homeState() const { return find( Qtopia::HomeState ); } 146 QString homeState() const { return find( Qtopia::HomeState ); }
147 QString homeZip() const { return find( Qtopia::HomeZip ); } 147 QString homeZip() const { return find( Qtopia::HomeZip ); }
148 QString homeCountry() const { return find( Qtopia::HomeCountry ); } 148 QString homeCountry() const { return find( Qtopia::HomeCountry ); }
149 QString homePhone() const { return find( Qtopia::HomePhone ); } 149 QString homePhone() const { return find( Qtopia::HomePhone ); }
150 QString homeFax() const { return find( Qtopia::HomeFax ); } 150 QString homeFax() const { return find( Qtopia::HomeFax ); }
151 QString homeMobile() const { return find( Qtopia::HomeMobile ); } 151 QString homeMobile() const { return find( Qtopia::HomeMobile ); }
152 QString homeWebpage() const { return find( Qtopia::HomeWebPage ); } 152 QString homeWebpage() const { return find( Qtopia::HomeWebPage ); }
153 /** Multi line string containing all non-empty address info in the form 153 /** Multi line string containing all non-empty address info in the form
154 * Street 154 * Street
155 * City, State Zip 155 * City, State Zip
156 * Country 156 * Country
157 */ 157 */
158 QString displayHomeAddress() const; 158 QString displayHomeAddress() const;
159 159
160 // business 160 // business
161 QString company() const { return find( Qtopia::Company ); } 161 QString company() const { return find( Qtopia::Company ); }
162 QString businessStreet() const { return find( Qtopia::BusinessStreet ); } 162 QString businessStreet() const { return find( Qtopia::BusinessStreet ); }
163 QString businessCity() const { return find( Qtopia::BusinessCity ); } 163 QString businessCity() const { return find( Qtopia::BusinessCity ); }
164 QString businessState() const { return find( Qtopia::BusinessState ); } 164 QString businessState() const { return find( Qtopia::BusinessState ); }
165 QString businessZip() const { return find( Qtopia::BusinessZip ); } 165 QString businessZip() const { return find( Qtopia::BusinessZip ); }
166 QString businessCountry() const { return find( Qtopia::BusinessCountry ); } 166 QString businessCountry() const { return find( Qtopia::BusinessCountry ); }
167 QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); } 167 QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); }
168 QString jobTitle() const { return find( Qtopia::JobTitle ); } 168 QString jobTitle() const { return find( Qtopia::JobTitle ); }
169 QString department() const { return find( Qtopia::Department ); } 169 QString department() const { return find( Qtopia::Department ); }
170 QString office() const { return find( Qtopia::Office ); } 170 QString office() const { return find( Qtopia::Office ); }
171 QString businessPhone() const { return find( Qtopia::BusinessPhone ); } 171 QString businessPhone() const { return find( Qtopia::BusinessPhone ); }
172 QString businessFax() const { return find( Qtopia::BusinessFax ); } 172 QString businessFax() const { return find( Qtopia::BusinessFax ); }
173 QString businessMobile() const { return find( Qtopia::BusinessMobile ); } 173 QString businessMobile() const { return find( Qtopia::BusinessMobile ); }
174 QString businessPager() const { return find( Qtopia::BusinessPager ); } 174 QString businessPager() const { return find( Qtopia::BusinessPager ); }
175 QString profession() const { return find( Qtopia::Profession ); } 175 QString profession() const { return find( Qtopia::Profession ); }
176 QString assistant() const { return find( Qtopia::Assistant ); } 176 QString assistant() const { return find( Qtopia::Assistant ); }
177 QString manager() const { return find( Qtopia::Manager ); } 177 QString manager() const { return find( Qtopia::Manager ); }
178 /** Multi line string containing all non-empty address info in the form 178 /** Multi line string containing all non-empty address info in the form
179 * Street 179 * Street
180 * City, State Zip 180 * City, State Zip
181 * Country 181 * Country
182 */ 182 */
183 QString displayBusinessAddress() const; 183 QString displayBusinessAddress() const;
184 184
185 //personal 185 //personal
186 QString spouse() const { return find( Qtopia::Spouse ); } 186 QString spouse() const { return find( Qtopia::Spouse ); }
187 QString gender() const { return find( Qtopia::Gender ); } 187 QString gender() const { return find( Qtopia::Gender ); }
188 QDate birthday() const; 188 QDate birthday() const;
189 QDate anniversary() const; 189 QDate anniversary() const;
190 QString nickname() const { return find( Qtopia::Nickname ); } 190 QString nickname() const { return find( Qtopia::Nickname ); }
191 QString children() const { return find( Qtopia::Children ); } 191 QString children() const { return find( Qtopia::Children ); }
192 QStringList childrenList() const; 192 QStringList childrenList() const;
193 193
194 // other 194 // other
195 QString notes() const { return find( Qtopia::Notes ); } 195 QString notes() const { return find( Qtopia::Notes ); }
196 QString groups() const { return find( Qtopia::Groups ); } 196 QString groups() const { return find( Qtopia::Groups ); }
197 QStringList groupList() const; 197 QStringList groupList() const;
198 198
199// // custom
200// const QString &customField( const QString &key )
201// { return find( Custom- + key ); }
202
203
204 QString toRichText() const; 199 QString toRichText() const;
205 QMap<int, QString> toMap() const; 200 QMap<int, QString> toMap() const;
206 QString field( int key ) const { return find( key ); } 201 QString field( int key ) const { return find( key ); }
207 202
208 203
209 void setUid( int i ); 204 void setUid( int i );
210 205
211 QString toShortText()const; 206 QString toShortText()const;
212 QString OContact::type()const; 207 QString type()const;
213 QMap<QString,QString> OContact::toExtraMap() const; 208 class QString recordField(int) const;
214 class QString OContact::recordField(int) const;
215 209
216 // Why private ? (eilers,se) 210 // Why private ? (eilers,se)
217 QString emailSeparator() const { return " "; } 211 QString emailSeparator() const { return " "; }
212
218 // the emails should be seperated by a comma 213 // the emails should be seperated by a comma
219 void setEmails( const QString &v ); 214 void setEmails( const QString &v );
220 QString emails() const { return find( Qtopia::Emails ); } 215 QString emails() const { return find( Qtopia::Emails ); }
221 static int rtti(); 216 static int rtti();
222 217
223private: 218private:
224 // The XML-Backend needs some access to the private functions 219 // The XML Backend needs some access to the private functions
225 friend class OContactAccessBackend_XML; 220 friend class OContactAccessBackend_XML;
226 221
227 void insert( int key, const QString &value ); 222 void insert( int key, const QString &value );
228 void replace( int key, const QString &value ); 223 void replace( int key, const QString &value );
229 QString find( int key ) const; 224 QString find( int key ) const;
230 static QStringList fields(); 225 static QStringList fields();
231 226
232 void save( QString &buf ) const; 227 void save( QString &buf ) const;
233 228
234 QString displayAddress( const QString &street, 229 QString displayAddress( const QString &street,
235 const QString &city, 230 const QString &city,
236 const QString &state, 231 const QString &state,
237 const QString &zip, 232 const QString &zip,
238 const QString &country ) const; 233 const QString &country ) const;
239 234
240 QMap<int, QString> mMap; 235 QMap<int, QString> mMap;
241 OContactPrivate *d; 236 OContactPrivate *d;
242}; 237};
243 238
244 239
245#endif 240#endif
diff --git a/libopie2/opiepim/ocontactfields.cpp b/libopie2/opiepim/ocontactfields.cpp
new file mode 100644
index 0000000..831a596
--- a/dev/null
+++ b/libopie2/opiepim/ocontactfields.cpp
@@ -0,0 +1,456 @@
1
2#include "ocontactfields.h"
3
4#include <qstringlist.h>
5#include <qobject.h>
6
7// We should use our own enum in the future ..
8#include <qpe/recordfields.h>
9#include <qpe/config.h>
10#include <opie/ocontact.h>
11
12/*!
13 \internal
14 Returns a list of details field names for a contact.
15*/
16QStringList OContactFields::untrdetailsfields( bool sorted )
17{
18 QStringList list;
19 QMap<int, QString> mapIdToStr = idToUntrFields();
20
21 list.append( mapIdToStr[ Qtopia::Office ] );
22 list.append( mapIdToStr[ Qtopia::Profession ] );
23 list.append( mapIdToStr[ Qtopia::Assistant ] );
24 list.append( mapIdToStr[ Qtopia::Manager ] );
25
26 list.append( mapIdToStr[ Qtopia::Spouse ] );
27 list.append( mapIdToStr[ Qtopia::Gender ] );
28 list.append( mapIdToStr[ Qtopia::Birthday ] );
29 list.append( mapIdToStr[ Qtopia::Anniversary ] );
30 list.append( mapIdToStr[ Qtopia::Nickname ] );
31 list.append( mapIdToStr[ Qtopia::Children ] );
32
33 if (sorted) list.sort();
34 return list;
35}
36
37/*!
38 \internal
39 Returns a translated list of details field names for a contact.
40*/
41QStringList OContactFields::trdetailsfields( bool sorted )
42{
43 QStringList list;
44 QMap<int, QString> mapIdToStr = idToTrFields();
45
46 list.append( mapIdToStr[Qtopia::Office] );
47 list.append( mapIdToStr[Qtopia::Profession] );
48 list.append( mapIdToStr[Qtopia::Assistant] );
49 list.append( mapIdToStr[Qtopia::Manager] );
50
51 list.append( mapIdToStr[Qtopia::Spouse] );
52 list.append( mapIdToStr[Qtopia::Gender] );
53 list.append( mapIdToStr[Qtopia::Birthday] );
54 list.append( mapIdToStr[Qtopia::Anniversary] );
55 list.append( mapIdToStr[Qtopia::Nickname] );
56 list.append( mapIdToStr[Qtopia::Children] );
57
58 if (sorted) list.sort();
59 return list;
60}
61
62
63/*!
64 \internal
65 Returns a translated list of phone field names for a contact.
66*/
67QStringList OContactFields::trphonefields( bool sorted )
68{
69 QStringList list;
70 QMap<int, QString> mapIdToStr = idToTrFields();
71
72 list.append( mapIdToStr[Qtopia::BusinessPhone] );
73 list.append( mapIdToStr[Qtopia::BusinessFax] );
74 list.append( mapIdToStr[Qtopia::BusinessMobile] );
75 list.append( mapIdToStr[Qtopia::BusinessPager] );
76 list.append( mapIdToStr[Qtopia::BusinessWebPage] );
77
78 list.append( mapIdToStr[Qtopia::DefaultEmail] );
79 list.append( mapIdToStr[Qtopia::Emails] );
80
81 list.append( mapIdToStr[Qtopia::HomePhone] );
82 list.append( mapIdToStr[Qtopia::HomeFax] );
83 list.append( mapIdToStr[Qtopia::HomeMobile] );
84 // list.append( mapIdToStr[Qtopia::HomePager] );
85 list.append( mapIdToStr[Qtopia::HomeWebPage] );
86
87 if (sorted) list.sort();
88
89 return list;
90}
91
92
93/*!
94 \internal
95 Returns a list of phone field names for a contact.
96*/
97QStringList OContactFields::untrphonefields( bool sorted )
98{
99 QStringList list;
100 QMap<int, QString> mapIdToStr = idToUntrFields();
101
102 list.append( mapIdToStr[ Qtopia::BusinessPhone ] );
103 list.append( mapIdToStr[ Qtopia::BusinessFax ] );
104 list.append( mapIdToStr[ Qtopia::BusinessMobile ] );
105 list.append( mapIdToStr[ Qtopia::BusinessPager ] );
106 list.append( mapIdToStr[ Qtopia::BusinessWebPage ] );
107
108 list.append( mapIdToStr[ Qtopia::DefaultEmail ] );
109 list.append( mapIdToStr[ Qtopia::Emails ] );
110
111 list.append( mapIdToStr[ Qtopia::HomePhone ] );
112 list.append( mapIdToStr[ Qtopia::HomeFax ] );
113 list.append( mapIdToStr[ Qtopia::HomeMobile ] );
114 //list.append( mapIdToStr[Qtopia::HomePager] );
115 list.append( mapIdToStr[Qtopia::HomeWebPage] );
116
117 if (sorted) list.sort();
118
119 return list;
120}
121
122
123/*!
124 \internal
125 Returns a translated list of field names for a contact.
126*/
127QStringList OContactFields::trfields( bool sorted )
128{
129 QStringList list;
130 QMap<int, QString> mapIdToStr = idToTrFields();
131
132 list.append( mapIdToStr[Qtopia::Title]);
133 list.append( mapIdToStr[Qtopia::FirstName] );
134 list.append( mapIdToStr[Qtopia::MiddleName] );
135 list.append( mapIdToStr[Qtopia::LastName] );
136 list.append( mapIdToStr[Qtopia::Suffix] );
137 list.append( mapIdToStr[Qtopia::FileAs] );
138
139 list.append( mapIdToStr[Qtopia::JobTitle] );
140 list.append( mapIdToStr[Qtopia::Department] );
141 list.append( mapIdToStr[Qtopia::Company] );
142
143 list += trphonefields( sorted );
144
145 list.append( mapIdToStr[Qtopia::BusinessStreet] );
146 list.append( mapIdToStr[Qtopia::BusinessCity] );
147 list.append( mapIdToStr[Qtopia::BusinessState] );
148 list.append( mapIdToStr[Qtopia::BusinessZip] );
149 list.append( mapIdToStr[Qtopia::BusinessCountry] );
150
151 list.append( mapIdToStr[Qtopia::HomeStreet] );
152 list.append( mapIdToStr[Qtopia::HomeCity] );
153 list.append( mapIdToStr[Qtopia::HomeState] );
154 list.append( mapIdToStr[Qtopia::HomeZip] );
155 list.append( mapIdToStr[Qtopia::HomeCountry] );
156
157 list += trdetailsfields( sorted );
158
159 list.append( mapIdToStr[Qtopia::Notes] );
160 list.append( mapIdToStr[Qtopia::Groups] );
161
162 if (sorted) list.sort();
163
164 return list;
165}
166
167/*!
168 \internal
169 Returns an untranslated list of field names for a contact.
170*/
171QStringList OContactFields::untrfields( bool sorted )
172{
173 QStringList list;
174 QMap<int, QString> mapIdToStr = idToUntrFields();
175
176 list.append( mapIdToStr[ Qtopia::Title ] );
177 list.append( mapIdToStr[ Qtopia::FirstName ] );
178 list.append( mapIdToStr[ Qtopia::MiddleName ] );
179 list.append( mapIdToStr[ Qtopia::LastName ] );
180 list.append( mapIdToStr[ Qtopia::Suffix ] );
181 list.append( mapIdToStr[ Qtopia::FileAs ] );
182
183 list.append( mapIdToStr[ Qtopia::JobTitle ] );
184 list.append( mapIdToStr[ Qtopia::Department ] );
185 list.append( mapIdToStr[ Qtopia::Company ] );
186
187 list += untrphonefields( sorted );
188
189 list.append( mapIdToStr[ Qtopia::BusinessStreet ] );
190 list.append( mapIdToStr[ Qtopia::BusinessCity ] );
191 list.append( mapIdToStr[ Qtopia::BusinessState ] );
192 list.append( mapIdToStr[ Qtopia::BusinessZip ] );
193 list.append( mapIdToStr[ Qtopia::BusinessCountry ] );
194
195 list.append( mapIdToStr[ Qtopia::HomeStreet ] );
196 list.append( mapIdToStr[ Qtopia::HomeCity ] );
197 list.append( mapIdToStr[ Qtopia::HomeState ] );
198 list.append( mapIdToStr[ Qtopia::HomeZip ] );
199 list.append( mapIdToStr[ Qtopia::HomeCountry ] );
200
201 list += untrdetailsfields( sorted );
202
203 list.append( mapIdToStr[ Qtopia::Notes ] );
204 list.append( mapIdToStr[ Qtopia::Groups ] );
205
206 if (sorted) list.sort();
207
208 return list;
209}
210QMap<int, QString> OContactFields::idToTrFields()
211{
212 QMap<int, QString> ret_map;
213
214 ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") );
215 ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) );
216 ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) );
217 ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) );
218 ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" ));
219 ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) );
220
221 ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) );
222 ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) );
223 ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) );
224 ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) );
225 ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) );
226 ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" ));
227
228 // email
229 ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) );
230 ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) );
231
232 ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) );
233 ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) );
234 ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) );
235
236 // business
237 ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) );
238 ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) );
239 ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) );
240 ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) );
241 ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) );
242 ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) );
243 ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) );
244
245 ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) );
246 ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) );
247 ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) );
248 ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) );
249
250 // home
251 ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) );
252 ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) );
253 ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) );
254 ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) );
255 ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) );
256 ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) );
257
258 //personal
259 ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) );
260 ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) );
261 ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) );
262 ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) );
263 ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) );
264 ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) );
265
266 // other
267 ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) );
268
269
270 return ret_map;
271}
272
273QMap<int, QString> OContactFields::idToUntrFields()
274{
275 QMap<int, QString> ret_map;
276
277 ret_map.insert( Qtopia::Title, "Name Title" );
278 ret_map.insert( Qtopia::FirstName, "First Name" );
279 ret_map.insert( Qtopia::MiddleName, "Middle Name" );
280 ret_map.insert( Qtopia::LastName, "Last Name" );
281 ret_map.insert( Qtopia::Suffix, "Suffix" );
282 ret_map.insert( Qtopia::FileAs, "File As" );
283
284 ret_map.insert( Qtopia::JobTitle, "Job Title" );
285 ret_map.insert( Qtopia::Department, "Department" );
286 ret_map.insert( Qtopia::Company, "Company" );
287 ret_map.insert( Qtopia::BusinessPhone, "Business Phone" );
288 ret_map.insert( Qtopia::BusinessFax, "Business Fax" );
289 ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" );
290
291 // email
292 ret_map.insert( Qtopia::DefaultEmail, "Default Email" );
293 ret_map.insert( Qtopia::Emails, "Emails" );
294
295 ret_map.insert( Qtopia::HomePhone, "Home Phone" );
296 ret_map.insert( Qtopia::HomeFax, "Home Fax" );
297 ret_map.insert( Qtopia::HomeMobile, "Home Mobile" );
298
299 // business
300 ret_map.insert( Qtopia::BusinessStreet, "Business Street" );
301 ret_map.insert( Qtopia::BusinessCity, "Business City" );
302 ret_map.insert( Qtopia::BusinessState, "Business State" );
303 ret_map.insert( Qtopia::BusinessZip, "Business Zip" );
304 ret_map.insert( Qtopia::BusinessCountry, "Business Country" );
305 ret_map.insert( Qtopia::BusinessPager, "Business Pager" );
306 ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" );
307
308 ret_map.insert( Qtopia::Office, "Office" );
309 ret_map.insert( Qtopia::Profession, "Profession" );
310 ret_map.insert( Qtopia::Assistant, "Assistant" );
311 ret_map.insert( Qtopia::Manager, "Manager" );
312
313 // home
314 ret_map.insert( Qtopia::HomeStreet, "Home Street" );
315 ret_map.insert( Qtopia::HomeCity, "Home City" );
316 ret_map.insert( Qtopia::HomeState, "Home State" );
317 ret_map.insert( Qtopia::HomeZip, "Home Zip" );
318 ret_map.insert( Qtopia::HomeCountry, "Home Country" );
319 ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" );
320
321 //personal
322 ret_map.insert( Qtopia::Spouse, "Spouse" );
323 ret_map.insert( Qtopia::Gender, "Gender" );
324 ret_map.insert( Qtopia::Birthday, "Birthday" );
325 ret_map.insert( Qtopia::Anniversary, "Anniversary" );
326 ret_map.insert( Qtopia::Nickname, "Nickname" );
327 ret_map.insert( Qtopia::Children, "Children" );
328
329 // other
330 ret_map.insert( Qtopia::Notes, "Notes" );
331
332
333 return ret_map;
334}
335
336QMap<QString, int> OContactFields::trFieldsToId()
337{
338 QMap<int, QString> idtostr = idToTrFields();
339 QMap<QString, int> ret_map;
340
341
342 QMap<int, QString>::Iterator it;
343 for( it = idtostr.begin(); it != idtostr.end(); ++it )
344 ret_map.insert( *it, it.key() );
345
346
347 return ret_map;
348}
349
350QMap<QString, int> OContactFields::untrFieldsToId()
351{
352 QMap<int, QString> idtostr = idToUntrFields();
353 QMap<QString, int> ret_map;
354
355
356 QMap<int, QString>::Iterator it;
357 for( it = idtostr.begin(); it != idtostr.end(); ++it )
358 ret_map.insert( *it, it.key() );
359
360
361 return ret_map;
362}
363
364
365OContactFields::OContactFields():
366 fieldOrder( DEFAULT_FIELD_ORDER ),
367 changedFieldOrder( false )
368{
369 // Get the global field order from the config file and
370 // use it as a start pattern
371 Config cfg ( "AddressBook" );
372 cfg.setGroup( "ContactFieldOrder" );
373 globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER );
374}
375
376OContactFields::~OContactFields(){
377
378 // We will store the fieldorder into the config file
379 // to reuse it for the future..
380 if ( changedFieldOrder ){
381 Config cfg ( "AddressBook" );
382 cfg.setGroup( "ContactFieldOrder" );
383 cfg.writeEntry( "General", globalFieldOrder );
384 }
385}
386
387
388
389void OContactFields::saveToRecord( OContact &cnt ){
390
391 qDebug("ocontactfields saveToRecord: >%s<",fieldOrder.latin1());
392
393 // Store fieldorder into this contact.
394 cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder );
395
396 globalFieldOrder = fieldOrder;
397 changedFieldOrder = true;
398
399}
400
401void OContactFields::loadFromRecord( const OContact &cnt ){
402 qDebug("ocontactfields loadFromRecord");
403 qDebug("loading >%s<",cnt.fullName().latin1());
404
405 // Get fieldorder for this contact. If none is defined,
406 // we will use the global one from the config file..
407
408 fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME );
409
410 qDebug("fieldOrder from contact>%s<",fieldOrder.latin1());
411
412 if (fieldOrder.isEmpty()){
413 fieldOrder = globalFieldOrder;
414 }
415
416
417 qDebug("effective fieldOrder in loadFromRecord >%s<",fieldOrder.latin1());
418}
419
420void OContactFields::setFieldOrder( int num, int index ){
421 qDebug("qcontactfields setfieldorder pos %i -> %i",num,index);
422
423 fieldOrder[num] = QString::number( index, 16 )[0];
424
425 // We will store this new fieldorder globally to
426 // remember it for contacts which have none
427 globalFieldOrder = fieldOrder;
428 changedFieldOrder = true;
429
430 qDebug("fieldOrder >%s<",fieldOrder.latin1());
431}
432
433int OContactFields::getFieldOrder( int num, int defIndex ){
434 qDebug("ocontactfields getFieldOrder");
435 qDebug("fieldOrder >%s<",fieldOrder.latin1());
436
437 // Get index of combo as char..
438 QChar poschar = fieldOrder[num];
439
440 bool ok;
441 int ret = 0;
442 // Convert char to number..
443 if ( !( poschar == QChar::null ) )
444 ret = QString( poschar ).toInt(&ok, 16);
445 else
446 ok = false;
447
448 // Return default value if index for
449 // num was not set or if anything else happened..
450 if ( !ok ) ret = defIndex;
451
452 qDebug("returning >%i<",ret);
453
454 return ret;
455
456}
diff --git a/libopie2/opiepim/ocontactfields.h b/libopie2/opiepim/ocontactfields.h
new file mode 100644
index 0000000..9f6171b
--- a/dev/null
+++ b/libopie2/opiepim/ocontactfields.h
@@ -0,0 +1,60 @@
1#ifndef OPIE_CONTACTS_FIELDS
2#define OPIE_CONTACTS_FIELDS
3
4class QStringList;
5
6#include <qmap.h>
7#include <qstring.h>
8#include <opie/ocontact.h>
9
10#define CONTACT_FIELD_ORDER_NAME "opie-contactfield-order"
11#define DEFAULT_FIELD_ORDER "__________"
12
13class OContactFields{
14
15 public:
16 OContactFields();
17 ~OContactFields();
18 /** Set the index for combo boxes.
19 * Sets the <b>index</b> of combo <b>num</b>.
20 * @param num selects the number of the combo
21 * @param index sets the index in the combo
22 */
23 void setFieldOrder( int num, int index );
24
25 /** Get the index for combo boxes.
26 * Returns the index of combo <b>num</b> or defindex
27 * if none was defined..
28 * @param num Selects the number of the combo
29 * @param defIndex will be returned if none was defined (either
30 * globally in the config file, nor by the contact which was used
31 * by loadFromRecord() )
32 */
33 int getFieldOrder( int num, int defIndex);
34
35 /** Store fieldorder to contact. */
36 void saveToRecord( OContact& );
37 /** Get Fieldorder from contact. */
38 void loadFromRecord( const OContact& );
39
40 private:
41 QString fieldOrder;
42 QString globalFieldOrder;
43 bool changedFieldOrder;
44
45 public:
46 static QStringList trphonefields( bool sorted = true );
47 static QStringList untrphonefields( bool sorted = true );
48 static QStringList trdetailsfields( bool sorted = true );
49 static QStringList untrdetailsfields( bool sorted = true );
50 static QStringList trfields( bool sorted = true );
51 static QStringList untrfields( bool sorted = true );
52
53 static QMap<int, QString> idToTrFields();
54 static QMap<QString, int> trFieldsToId();
55 static QMap<int, QString> idToUntrFields();
56 static QMap<QString, int> untrFieldsToId();
57
58};
59
60#endif