summaryrefslogtreecommitdiffabout
path: root/kabc/plugins
Unidiff
Diffstat (limited to 'kabc/plugins') (more/less context) (ignore whitespace changes)
-rw-r--r--kabc/plugins/qtopia/qtopiaE.pro1
-rw-r--r--kabc/plugins/qtopia/qtopiaconverter.cpp839
-rw-r--r--kabc/plugins/qtopia/qtopiaconverter.h66
-rw-r--r--kabc/plugins/qtopia/resourceqtopia.cpp101
-rw-r--r--kabc/plugins/qtopia/resourceqtopia.h1
5 files changed, 707 insertions, 301 deletions
diff --git a/kabc/plugins/qtopia/qtopiaE.pro b/kabc/plugins/qtopia/qtopiaE.pro
index a15e9ba..d66c719 100644
--- a/kabc/plugins/qtopia/qtopiaE.pro
+++ b/kabc/plugins/qtopia/qtopiaE.pro
@@ -1,27 +1,26 @@
1 TEMPLATE= lib 1 TEMPLATE= lib
2CONFIG += qt warn_on 2CONFIG += qt warn_on
3 3
4TARGET = microkabc_qtopia 4TARGET = microkabc_qtopia
5 5
6INCLUDEPATH += $(KDEPIMDIR) $(KDEPIMDIR)/kabc $(KDEPIMDIR)/microkde $(KDEPIMDIR)/microkde/kdecore $(KDEPIMDIR)/microkde/kio/kfile $(KDEPIMDIR)/microkde/kio/kio $(KDEPIMDIR)/microkde/kresources $(KDEPIMDIR)/qtcompat $(QPEDIR)/include 6INCLUDEPATH += $(KDEPIMDIR) $(KDEPIMDIR)/kabc $(KDEPIMDIR)/microkde $(KDEPIMDIR)/microkde/kdecore $(KDEPIMDIR)/microkde/kio/kfile $(KDEPIMDIR)/microkde/kio/kio $(KDEPIMDIR)/microkde/kresources $(KDEPIMDIR)/qtcompat $(QPEDIR)/include
7 7
8OBJECTS_DIR = obj/$(PLATFORM) 8OBJECTS_DIR = obj/$(PLATFORM)
9MOC_DIR = moc/$(PLATFORM) 9MOC_DIR = moc/$(PLATFORM)
10DESTDIR = $(QPEDIR)/lib 10DESTDIR = $(QPEDIR)/lib
11LIBS += -lmicrokde 11LIBS += -lmicrokde
12LIBS += -lkamicrokabc 12LIBS += -lkamicrokabc
13LIBS += -L$(QPEDIR)/lib 13LIBS += -L$(QPEDIR)/lib
14LIBS += -lqpepim
15LIBS += -lqpe 14LIBS += -lqpe
16 15
17INTERFACES = \ 16INTERFACES = \
18 17
19HEADERS = \ 18HEADERS = \
20 resourceqtopia.h \ 19 resourceqtopia.h \
21 resourceqtopiaconfig.h \ 20 resourceqtopiaconfig.h \
22 qtopiaconverter.h 21 qtopiaconverter.h
23 22
24SOURCES = \ 23SOURCES = \
25 resourceqtopia.cpp \ 24 resourceqtopia.cpp \
26 resourceqtopiaconfig.cpp \ 25 resourceqtopiaconfig.cpp \
27 qtopiaconverter.cpp 26 qtopiaconverter.cpp
diff --git a/kabc/plugins/qtopia/qtopiaconverter.cpp b/kabc/plugins/qtopia/qtopiaconverter.cpp
index 5eab1be..040226c 100644
--- a/kabc/plugins/qtopia/qtopiaconverter.cpp
+++ b/kabc/plugins/qtopia/qtopiaconverter.cpp
@@ -1,376 +1,671 @@
1/* 1/*
2 This file is part of libkabc. 2 This file is part of libkabc.
3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org> 3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21/* 21/*
22Enhanced Version of the file for platform independent KDE tools. 22Enhanced Version of the file for platform independent KDE tools.
23Copyright (c) 2004 Ulf Schenk 23Copyright (c) 2004 Ulf Schenk
24 24
25$Id$ 25$Id$
26*/ 26*/
27 27
28//US 28//US
29#include "kglobal.h" 29#include "kglobal.h"
30#include "klocale.h"
30 31
31 32
32#include "qtopiaconverter.h" 33#include "qtopiaconverter.h"
33 34
34#include <qpe/categories.h> 35#include <qfile.h>
36#include <qdir.h>
37#include <qtextstream.h>
38//#include <.h>
39
40//#include <qpe/categories.h>
35#include <libkdepim/ksyncprofile.h> 41#include <libkdepim/ksyncprofile.h>
36//US #include <qpe/categoryselect.h> 42//US #include <qpe/categoryselect.h>
37 43
38 44
39using namespace KABC; 45using namespace KABC;
40 46
41QtopiaConverter::QtopiaConverter() : catDB(0) 47QtopiaConverter::QtopiaConverter()
42{ 48{
49 m_edit = 0;
43} 50}
44 51
45QtopiaConverter::~QtopiaConverter() 52QtopiaConverter::~QtopiaConverter()
46{ 53{
47 deinit(); 54 deinit();
48} 55}
49 56
50bool QtopiaConverter::init() 57bool QtopiaConverter::init()
51{ 58{
52 catDB = new Categories(); 59 QString fn = QDir::homeDirPath() +"/Settings/Categories.xml";
53 60 m_edit = new CategoryEdit( fn);
54 if (!catDB) 61 return true;
55 return false;
56
57 catDB->load( categoryFileName() );
58 return true;
59} 62}
60 63
61void QtopiaConverter::deinit() 64void QtopiaConverter::deinit()
62{ 65{
63 if (catDB) 66 if (m_edit)
64 { 67 {
65 delete catDB; 68 delete m_edit;
66 catDB = 0; 69 m_edit = 0;
67 } 70 }
68} 71}
69 72QString QtopiaConverter::categoriesToNumber( const QStringList &list, const QString &app )
70bool QtopiaConverter::qtopiaToAddressee( const PimContact &contact, Addressee &addr )
71{ 73{
72 // name 74 startover:
73 addr.setFormattedName(contact.fileAs()); 75 QStringList dummy;
74 addr.setFamilyName( contact.lastName() ); 76 QValueList<OpieCategories>::ConstIterator catIt;
75 addr.setGivenName( contact.firstName() ); 77 QValueList<OpieCategories> categories = m_edit->categories();
76 addr.setAdditionalName( contact.middleName() ); 78 bool found = false;
77 addr.setPrefix( contact.nameTitle() ); 79 for ( QStringList::ConstIterator listIt = list.begin(); listIt != list.end(); ++listIt ) {
78 addr.setSuffix( contact.suffix() ); 80 /* skip empty category name */
79 81 if ( (*listIt).isEmpty() ) continue;
80 addr.setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); 82
81 QString exuid = contact.uid().toString(); 83 found = false;
82 addr.setOriginalExternalUID( exuid ); 84 for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) {
83 int ente = exuid.find( "-0000"); 85 /*
84 if ( exuid.left(1) == "{" ) 86 * We currently do not take app into account
85 exuid = exuid.mid(1); 87 * if name matches and the id isn't already in dummy we'll add it
86 if ( ente > -1 ) 88 */
87 exuid = exuid.left( ente-1 ); 89 if ( (*catIt).name() == (*listIt) && !dummy.contains(( *catIt).id() ) ) { // the same name
88 addr.setExternalUID( exuid ); 90 found= true;
89 // qDebug("QtopiaConverter:set %s uid %s ",addr.originalExternalUID().latin1(),addr.externalUID().latin1() ); 91 dummy << (*catIt).id();
90 92 }
91 // email 93 }
92 QStringList emails = contact.emailList(); 94 /* if not found and the category is not empty
93 for ( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { 95 *
94 addr.insertEmail( *it, ((*it) == contact.defaultEmail()) ); 96 * generate a new category and start over again
97 * ugly goto to reiterate
98 */
99
100 if ( !found && !(*listIt).isEmpty() ){
101 m_edit->addCategory( app, (*listIt) ); // generate a new category
102 goto startover;
103 }
95 } 104 }
96 105
97 if (!contact.defaultEmail().isEmpty()) 106 return dummy.join(";");
98 addr.insertEmail(contact.defaultEmail(), true); 107}
99
100 // home
101 if ((!contact.homeStreet().isEmpty()) ||
102 (!contact.homeCity().isEmpty()) ||
103 (!contact.homeState().isEmpty()) ||
104 (!contact.homeZip().isEmpty()) ||
105 (!contact.homeCountry().isEmpty()))
106 {
107 Address homeaddress;
108 homeaddress.setType(Address::Home);
109//US homeaddress.setPostOfficeBox( "" );
110//US homeaddress.setExtended( "" );
111 homeaddress.setStreet( contact.homeStreet() );
112 homeaddress.setLocality( contact.homeCity() );
113 homeaddress.setRegion( contact.homeState() );
114 homeaddress.setPostalCode( contact.homeZip() );
115 homeaddress.setCountry( contact.homeCountry() );
116
117 addr.insertAddress( homeaddress );
118 }
119 108
120 if (!contact.homePhone().isEmpty())
121 {
122 PhoneNumber homephone;
123 homephone.setType( PhoneNumber::Home );
124 homephone.setNumber( contact.homePhone() );
125 addr.insertPhoneNumber( homephone );
126 }
127 109
128 if (!contact.homeFax().isEmpty()) 110// FROM TT timeconversion.cpp GPLed
129 { 111QDate QtopiaConverter::fromString( const QString &datestr )
130 PhoneNumber homefax; 112{
131 homefax.setType( PhoneNumber::Home | PhoneNumber::Fax ); 113 if (datestr.isEmpty() )
132 homefax.setNumber( contact.homeFax() ); 114 return QDate();
133 addr.insertPhoneNumber( homefax );
134 }
135 115
136 if (!contact.homeMobile().isEmpty()) 116 int monthPos = datestr.find('.');
137 { 117 int yearPos = datestr.find('.', monthPos+1 );
138 PhoneNumber homemobile; 118 if ( monthPos == -1 || yearPos == -1 ) {
139 homemobile.setType( PhoneNumber::Home | PhoneNumber::Cell ); 119 return QDate();
140 homemobile.setNumber( contact.homeMobile() );
141 addr.insertPhoneNumber( homemobile );
142 } 120 }
121 int d = datestr.left( monthPos ).toInt();
122 int m = datestr.mid( monthPos+1, yearPos - monthPos - 1 ).toInt();
123 int y = datestr.mid( yearPos+1 ).toInt();
124 QDate date ( y,m,d );
143 125
144 addr.setUrl( contact.homeWebpage() );
145
146
147 // business
148 if ((!contact.businessStreet().isEmpty()) ||
149 (!contact.businessCity().isEmpty()) ||
150 (!contact.businessState().isEmpty()) ||
151 (!contact.businessZip().isEmpty()) ||
152 (!contact.businessCountry().isEmpty()))
153 {
154 Address businessaddress;
155 businessaddress.setType(Address::Work);
156//US businessaddress.setPostOfficeBox( "" );
157//US businessaddress.setExtended( "" );
158 businessaddress.setStreet( contact.businessStreet() );
159 businessaddress.setLocality( contact.businessCity() );
160 businessaddress.setRegion( contact.businessState() );
161 businessaddress.setPostalCode( contact.businessZip() );
162 businessaddress.setCountry( contact.businessCountry() );
163
164 addr.insertAddress( businessaddress );
165 }
166 126
127 return date;
128}
167 129
168 if (!contact.businessPhone().isEmpty()) 130QDate QtopiaConverter::dateFromString( const QString& s )
169 { 131{
170 PhoneNumber businessphone; 132 QDate date;
171 businessphone.setType( PhoneNumber::Work );
172 businessphone.setNumber( contact.businessPhone() );
173 addr.insertPhoneNumber( businessphone );
174 }
175 133
176 if (!contact.businessFax().isEmpty()) 134 if ( s.isEmpty() )
177 { 135 return date;
178 PhoneNumber businessfax;
179 businessfax.setType( PhoneNumber::Work | PhoneNumber::Fax );
180 businessfax.setNumber( contact.businessFax() );
181 addr.insertPhoneNumber( businessfax );
182 }
183 136
184 if (!contact.businessMobile().isEmpty()) 137 // Be backward compatible to old Opie format:
185 { 138 // Try to load old format. If it fails, try new ISO-Format!
186 PhoneNumber businessmobile; 139 date = fromString ( s );
187 businessmobile.setType( PhoneNumber::Work | PhoneNumber::Cell ); 140 if ( date.isValid() )
188 businessmobile.setNumber( contact.businessMobile() ); 141 return date;
189 addr.insertPhoneNumber( businessmobile );
190 }
191 142
192 if (!contact.businessPager().isEmpty()) 143 // Read ISO-Format (YYYYMMDD)
193 { 144 int year = s.mid(0, 4).toInt();
194 PhoneNumber businesspager; 145 int month = s.mid(4,2).toInt();
195 businesspager.setType( PhoneNumber::Work | PhoneNumber::Pager ); 146 int day = s.mid(6,2).toInt();
196 businesspager.setNumber( contact.businessPager() );
197 addr.insertPhoneNumber( businesspager );
198 }
199 147
200 addr.setRole( contact.jobTitle() ); //? 148 // do some quick sanity checking
201 addr.setOrganization( contact.company() ); 149 if ( year < 1900 || year > 3000 )
202 addr.insertCustom( "KADDRESSBOOK", "X-Profession", contact.profession() ); 150 return date;
203 addr.insertCustom( "KADDRESSBOOK", "X-AssistantsName", contact.assistant() ); 151
204 addr.insertCustom( "KADDRESSBOOK", "X-Department", contact.department() ); 152 if ( month < 0 || month > 12 )
205 addr.insertCustom( "KADDRESSBOOK", "X-ManagersName", contact.manager() ); 153 return date;
206 addr.insertCustom( "KADDRESSBOOK", "X-Office", contact.office() );
207
208 //personal
209 addr.insertCustom( "KADDRESSBOOK", "X-SpousesName", contact.spouse() );
210 // qtopia uses this categorization:
211 // enum GenderType { UnspecifiedGender=0, Male, Female };
212 if (contact.gender() == PimContact::Male)
213 addr.insertCustom( "KADDRESSBOOK", "X-Gender", "male");
214 else if (contact.gender() == PimContact::Female)
215 addr.insertCustom( "KADDRESSBOOK", "X-Gender", "female");
216
217 if (contact.anniversary().isValid()) {
218 QString dt = KGlobal::locale()->formatDate(contact.anniversary(), true, KLocale::ISODate);
219//US
220// qDebug("QtopiaConverter::qtopiaToAddressee found:%s", dt.latin1());
221 addr.insertCustom( "KADDRESSBOOK", "X-Anniversary", dt);
222 }
223 154
224 addr.insertCustom( "KADDRESSBOOK", "X-Children", contact.children() ); 155 if ( day < 0 || day > 31 )
225 if (contact.birthday().isValid()) 156 return date;
226 addr.setBirthday( contact.birthday() );
227 157
228 addr.setNickName( contact.nickname() );
229 158
230 // others 159 date.setYMD( year, month, day );
231 //US I put opies BusinessWebPage into Ka/Pi's notes block, because no other native field is available.
232 QString notes = contact.notes();
233 notes += "\nBusinessWebPage: " + contact.businessWebpage() + "\n";
234 160
235 addr.setNote( contact.notes() ); 161 if ( !date.isValid() )
162 return QDate();
236 163
237 164
165 return date;
166}
167QString QtopiaConverter::dateToString( const QDate &d )
168{
169 if ( d.isNull() || !d.isValid() )
170 return QString::null;
238 171
239//US QString groups() const { return find( Qtopia::Groups ); } 172 // ISO format in year, month, day (YYYYMMDD); e.g. 20021231
240//US QStringList groupList() const; 173 QString year = QString::number( d.year() );
174 QString month = QString::number( d.month() );
175 month = month.rightJustify( 2, '0' );
176 QString day = QString::number( d.day() );
177 day = day.rightJustify( 2, '0' );
241 178
242 QArray<int> catArray = contact.categories(); 179 QString str = year + month + day;
243 QString cat;
244 180
245 for ( unsigned int i=0; i < catArray.size(); i++ ) { 181 return str;
246 cat = catDB->label("contact", catArray[i]); 182}
247 if ( cat.isEmpty() )
248 addr.insertCategory(QString::number(catArray[i]));
249 else
250 addr.insertCategory( cat );
251 }
252 183
184bool QtopiaConverter::qtopiaToAddressee( const QDomElement& el, Addressee &adr )
185{
186 { //LR
187
188 adr.setUid( el.attribute("Uid" ) );
189 adr.setFamilyName( el.attribute( "LastName" ) );
190 adr.setGivenName( el.attribute( "FirstName" ) );
191 adr.setAdditionalName( el.attribute( "MiddleName" ) );
192 adr.setSuffix( el.attribute( "Suffix" ) );
193 adr.setNickName( el.attribute( "Nickname" ) );
194
195 QDate date = dateFromString( el.attribute( "Birthday" ) );
196 if ( date.isValid() )
197 adr.setBirthday( date );
198
199 adr.setRole( el.attribute( "JobTitle" ) );
200 if ( !el.attribute( "FileAs" ).isEmpty() )
201 adr.setFormattedName( el.attribute( "FileAs" ) );
202
203 adr.setOrganization( el.attribute( "Company" ) );
204
205 KABC::PhoneNumber businessPhoneNum( el.attribute( "BusinessPhone" ),
206 KABC::PhoneNumber::Work );
207 KABC::PhoneNumber businessFaxNum( el.attribute( "BusinessFax" ),
208 KABC::PhoneNumber::Work | KABC::PhoneNumber::Fax );
209 KABC::PhoneNumber businessMobile( el.attribute( "BusinessMobile" ),
210 KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell );
211 KABC::PhoneNumber businessPager( el.attribute( "BusinessPager" ),
212 KABC::PhoneNumber::Work | KABC::PhoneNumber::Pager );
213 if ( !businessPhoneNum.number().isEmpty() )
214 adr.insertPhoneNumber( businessPhoneNum );
215 if ( !businessFaxNum.number().isEmpty() )
216 adr.insertPhoneNumber( businessFaxNum );
217 if ( !businessMobile.number().isEmpty() )
218 adr.insertPhoneNumber( businessMobile );
219 if ( !businessPager.number().isEmpty() )
220 adr.insertPhoneNumber( businessPager );
221
222 // Handle multiple mail addresses
223 QString DefaultEmail = el.attribute( "DefaultEmail" );
224 if ( !DefaultEmail.isEmpty() )
225 adr.insertEmail( DefaultEmail, true ); // preferred
226
227 QStringList Emails = QStringList::split(" ",el.attribute("Emails"));
228 int i;
229 for (i = 0;i < Emails.count();++i) {
230 if ( Emails[i] != DefaultEmail )
231 adr.insertEmail( Emails[i], false );
232 }
233
234 KABC::PhoneNumber homePhoneNum( el.attribute( "HomePhone" ),
235 KABC::PhoneNumber::Home );
236 KABC::PhoneNumber homeFax( el.attribute( "HomeFax" ),
237 KABC::PhoneNumber::Home | KABC::PhoneNumber::Fax );
238
239 KABC::PhoneNumber homeMobile( el.attribute( "HomeMobile" ),
240 KABC::PhoneNumber::Cell );
241
242 if ( !homePhoneNum.number().isEmpty() )
243 adr.insertPhoneNumber( homePhoneNum );
244 if ( !homeFax.number().isEmpty() )
245 adr.insertPhoneNumber( homeFax );
246 if ( !homeMobile.number().isEmpty() )
247 adr.insertPhoneNumber( homeMobile );
248
249 KABC::Address business( KABC::Address::Work );
250 business.setStreet( el.attribute( "BusinessStreet" ) );
251 business.setLocality( el.attribute( "BusinessCity" ) );
252 business.setRegion( el.attribute( "BusinessState" ) );
253 business.setPostalCode( el.attribute( "BusinessZip" ) );
254 business.setCountry( el.attribute( "BusinessCountry" ) );
255
256 if ( !business.isEmpty() )
257 adr.insertAddress( business );
258
259 KABC::Address home( KABC::Address::Home );
260 home.setStreet( el.attribute( "HomeStreet" ) );
261 home.setLocality( el.attribute( "HomeCity" ) );
262 home.setRegion( el.attribute( "HomeState" ) );
263 home.setPostalCode( el.attribute( "HomeZip" ) );
264 home.setCountry( el.attribute( "HomeCountry" ) );
265
266 if ( !home.isEmpty() )
267 adr.insertAddress( home );
268
269 adr.setNickName( el.attribute( "Nickname" ) );
270 adr.setNote( el.attribute( "Notes" ) );
271
272 {
273 QStringList categories = QStringList::split(";", el.attribute("Categories" ) );
274 QString cat;
275 QStringList added;
276 for ( uint i = 0; i < categories.count(); i++ ) {
277 cat = m_edit->categoryById( categories[ i ], "Contacts" );
278
279 // if name is not empty and we did not add the
280 // cat try to repair broken files
281 if ( !cat.isEmpty() && !added.contains( cat ) ) {
282 adr.insertCategory( cat );
283 added << cat;
284 }
285 }
286 }
287
288 if ( !el.attribute( "Department" ).isEmpty() )
289 adr.insertCustom( "KADDRESSBOOK", "X-Department", el.attribute( "Department" ) );
290 if ( !el.attribute( "HomeWebPage" ).isEmpty() )
291 adr.insertCustom( "opie", "HomeWebPage", el.attribute( "HomeWebPage" ) );
292 if ( !el.attribute( "Spouse" ).isEmpty() )
293 adr.insertCustom( "KADDRESSBOOK", "X-SpousesName", el.attribute( "Spouse" ) );
294 if ( !el.attribute( "Gender" ).isEmpty() )
295 adr.insertCustom( "opie", "Gender", el.attribute( "Gender" ) );
296
297 QDate ann = dateFromString( el.attribute( "Anniversary" ) );
298 if ( ann.isValid() ) {
299 QString dt = KGlobal::locale()->formatDate(ann, true, KLocale::ISODate);
300 adr.insertCustom( "KADDRESSBOOK", "X-Anniversary", dt );
301 }
302
303 if ( !el.attribute( "Children" ).isEmpty() )
304 adr.insertCustom("opie", "Children", el.attribute("Children") );
305 if ( !el.attribute( "Office" ).isEmpty() )
306 adr.insertCustom("KADDRESSBOOK", "X-Office", el.attribute("Office") );
307 if ( !el.attribute( "Profession" ).isEmpty() )
308 adr.insertCustom("KADDRESSBOOK", "X-Profession", el.attribute("Profession") );
309 if ( !el.attribute( "Assistant" ).isEmpty() )
310 adr.insertCustom("KADDRESSBOOK", "X-AssistantsName", el.attribute("Assistant") );
311 if ( !el.attribute( "Manager" ).isEmpty() )
312 adr.insertCustom("KADDRESSBOOK", "X-ManagersName", el.attribute("Manager") );
313
314
315 }
253 return true; 316 return true;
254} 317}
255 318
256bool QtopiaConverter::addresseeToQtopia( const Addressee &addr, PimContact &contact ) 319bool QtopiaConverter::addresseeToQtopia( const Addressee &ab, QTextStream *stream )
257{ 320{
321 *stream << "<Contact ";
322 *stream << "FirstName=\"" << escape(ab.givenName()) << "\" ";
323 *stream << "MiddleName=\"" << escape(ab.additionalName()) << "\" ";
324 *stream << "LastName=\"" << escape(ab.familyName()) << "\" ";
325 *stream << "Suffix=\"" << escape(ab.suffix()) << "\" ";
326
327 QString sortStr;
328 sortStr = ab.formattedName();
329 /* is formattedName is empty we use the assembled name as fallback */
330 if (sortStr.isEmpty() )
331 sortStr = ab.assembledName();
332 *stream << "FileAs=\"" << escape(sortStr) << "\" ";
333
334 *stream << "JobTitle=\"" << escape(ab.role()) << "\" ";
335 *stream << "Department=\"" << escape(ab.custom( "KADDRESSBOOK", "X-Department" )) << "\" ";
336 *stream << "Company=\"" << escape(ab.organization()) << "\" ";
337
338 KABC::PhoneNumber businessPhoneNum = ab.phoneNumber(KABC::PhoneNumber::Work );
339 *stream << "BusinessPhone=\"" << escape( businessPhoneNum.number() ) << "\" ";
340
341 KABC::PhoneNumber businessFaxNum = ab.phoneNumber(KABC::PhoneNumber::Work | KABC::PhoneNumber::Fax );
342 *stream << "BusinessFax=\"" << escape( businessFaxNum.number() )<< "\" ";
343
344 KABC::PhoneNumber businessMobile = ab.phoneNumber(KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell );
345 *stream << "BusinessMobile=\"" << escape( businessMobile.number() ) << "\" ";
346
347 *stream << "DefaultEmail=\"" << escape( ab.preferredEmail() ) << "\" ";
348 QStringList list = ab.emails();
349 if ( list.count() > 0 ) {
350 QStringList::Iterator it = list.begin();
351 *stream << "Emails=\"" << escape( *it );
352 while (++it != list.end())
353 *stream << ' ' << escape( *it );
354 *stream << "\" ";
355 }
356
357 KABC::PhoneNumber homePhoneNum = ab.phoneNumber(KABC::PhoneNumber::Home );
358 *stream << "HomePhone=\"" << escape( homePhoneNum.number() ) << "\" ";
359
360 KABC::PhoneNumber homeFax = ab.phoneNumber( KABC::PhoneNumber::Home | KABC::PhoneNumber::Fax );
361 *stream << "HomeFax=\"" << escape( homeFax.number() ) << "\" ";
362
363 KABC::PhoneNumber homeMobile = ab.phoneNumber( KABC::PhoneNumber::Cell );
364 *stream << "HomeMobile=\"" << escape( homeMobile.number() ) << "\" ";
365
366 KABC::Address business = ab.address(KABC::Address::Work );
367 *stream << "BusinessStreet=\"" << escape( business.street() ) << "\" ";
368 *stream << "BusinessCity=\"" << escape( business.locality() ) << "\" ";
369 *stream << "BusinessZip=\"" << escape( business.postalCode() ) << "\" ";
370 *stream << "BusinessCountry=\"" << escape( business.country() ) << "\" ";
371 *stream << "BusinessState=\"" << escape( business.region() ) << "\" ";
372 //stream << "BusinessPager=\"" << << "\" ";
373 *stream << "Office=\"" << escape( ab.custom( "KADDRESSBOOK", "X-Office" ) ) << "\" ";
374 *stream << "Profession=\"" << escape( ab.custom( "KADDRESSBOOK", "X-Profession" ) ) << "\" ";
375 *stream << "Assistant=\"" << escape( ab.custom( "KADDRESSBOOK", "X-AssistantsName") ) << "\" ";
376 *stream << "Manager=\"" << escape( ab.custom( "KADDRESSBOOK", "X-ManagersName" ) ) << "\" ";
377
378 KABC::Address home = ab.address( KABC::Address::Home );
379 *stream << "HomeStreet=\"" << escape( home.street() ) << "\" ";
380 *stream << "HomeCity=\"" << escape( home.locality() ) << "\" ";
381 *stream << "HomeState=\"" << escape( home.region() ) << "\" ";
382 *stream << "HomeZip=\"" << escape( home.postalCode() ) << "\" ";
383 *stream << "HomeCountry=\"" << escape( home.country() ) << "\" ";
384
385 *stream << "HomeWebPage=\"" << escape( ab.custom( "opie", "HomeWebPage" ) ) << "\" ";
386 *stream << "Spouse=\"" << escape( ab.custom( "KADDRESSBOOK", "X-SpousesName") ) << "\" ";
387 *stream << "Gender=\"" << escape( ab.custom( "opie", "Gender") ) << "\" ";
388
389 if ( ab.birthday().date().isValid() )
390 *stream << "Birthday=\"" << escape( dateToString(ab.birthday().date() ) ) << "\" ";
391
392 /*
393 * Anniversary block again
394 * Go from ISO -> QDate -> toString and then escape
395 */
396 {
397 QDate ann = KGlobal::locale()->readDate( ab.custom("KADDRESSBOOK", "X-Anniversary" ),
398 "%Y-%m-%d");
399 if (ann.isValid() ) {
400 *stream << "Anniversary=\"" << escape( dateToString( ann ) ) << "\" ";
401 }
402 }
403 *stream << "Nickname=\"" << escape( ab.nickName() ) << "\" ";
404 *stream << "Children=\"" << escape( ab.custom("opie", "Children" ) ) << "\" ";
405 *stream << "Notes=\"" << escape( ab.note() ) << "\" ";
406 *stream << "Categories=\"" << categoriesToNumber( ab.categories(), "Contacts") << "\" ";
407
408 QString uid = ab.uid();
409 *stream << "Uid=\"" << uid << "\" ";
410 //*stream << map.toString( "addressbook", uid );
411 *stream << " />" << "\n";
258 412
259 413 return true;
260 414}
261 // name
262 contact.setLastName(addr.familyName());
263 contact.setFirstName(addr.givenName());
264 contact.setMiddleName(addr.additionalName());
265 contact.setNameTitle(addr.prefix());
266 contact.setSuffix(addr.suffix());
267 contact.setFileAs();
268 415
269 416
270 // email 417#if 0
271 QStringList emails = addr.emails();
272 for ( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) {
273 contact.insertEmail(*it);
274 }
275 contact.setDefaultEmail( addr.preferredEmail() );
276 418
419KTempFile* AddressBook::fromKDE( KSync::AddressBookSyncee *syncee, ExtraMap& map )
420{
421
422}
277 423
278 // home 424QStringList AddressBook::attributes()const {
279 const Address homeaddress = addr.address(Address::Home); 425 QStringList lst;
280 if (!homeaddress.isEmpty()) { 426 lst << "FirstName";
281 contact.setHomeStreet(homeaddress.street()); 427 lst << "MiddleName";
282 contact.setHomeCity(homeaddress.locality()); 428 lst << "LastName";
283 contact.setHomeState(homeaddress.region()); 429 lst << "Suffix";
284 contact.setHomeZip(homeaddress.postalCode()); 430 lst << "FileAs";
285 contact.setHomeCountry(homeaddress.country()); 431 lst << "JobTitle";
286 } 432 lst << "Department";
287 433 lst << "Company";
288 PhoneNumber homephone = addr.phoneNumber( PhoneNumber::Home ); 434 lst << "BusinessPhone";
289 if (!homephone.number().isEmpty()) 435 lst << "BusinessFax";
290 contact.setHomePhone(homephone.number()); 436 lst << "BusinessMobile";
437 lst << "DefaultEmail";
438 lst << "Emails";
439 lst << "HomePhone";
440 lst << "HomeFax";
441 lst << "HomeMobile";
442 lst << "BusinessStreet";
443 lst << "BusinessCity";
444 lst << "BusinessZip";
445 lst << "BusinessCountry";
446 lst << "BusinessState";
447 lst << "Office";
448 lst << "Profession";
449 lst << "Assistant";
450 lst << "Manager";
451 lst << "HomeStreet";
452 lst << "HomeCity";
453 lst << "HomeState";
454 lst << "HomeZip";
455 lst << "HomeCountry";
456 lst << "HomeWebPage";
457 lst << "Spouse";
458 lst << "Gender";
459 lst << "Anniversary";
460 lst << "Nickname";
461 lst << "Children";
462 lst << "Notes";
463 lst << "Categories";
464 lst << "Uid";
465 lst << "Birthday";
466
467 return lst;
468}
291 469
292 PhoneNumber homefax = addr.phoneNumber( PhoneNumber::Home | PhoneNumber::Fax );
293 if (!homefax.number().isEmpty())
294 contact.setHomeFax(homefax.number());
295 470
296 PhoneNumber homemobile = addr.phoneNumber( PhoneNumber::Home | PhoneNumber::Cell );
297 if (!homemobile.number().isEmpty())
298 contact.setHomeMobile(homemobile.number());
299 471
300 contact.setHomeWebpage(addr.url().url()); 472#endif
301 473
302 474
303 // business 475CategoryEdit::CategoryEdit(){
304 const Address businessaddress = addr.address(Address::Work); 476}
305 if (!businessaddress.isEmpty()) { 477CategoryEdit::CategoryEdit(const QString &fileName){
306 contact.setBusinessStreet(businessaddress.street()); 478 parse( fileName );
307 contact.setBusinessCity(businessaddress.locality()); 479}
308 contact.setBusinessState(businessaddress.region()); 480CategoryEdit::~CategoryEdit(){
309 contact.setBusinessZip(businessaddress.postalCode()); 481}
310 contact.setBusinessCountry(businessaddress.country()); 482void CategoryEdit::save(const QString& fileName)const{
483 QFile file( fileName );
484 QString endl = "\n";
485 if ( file.open( IO_WriteOnly ) ) {
486 QTextStream stream( &file );
487 stream.setEncoding( QTextStream::UnicodeUTF8 );
488 stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
489 stream << "<!DOCTYPE CategoryList>" << endl;
490 stream << "<Categories>" << endl;
491 for ( QValueList<OpieCategories>::ConstIterator it = m_categories.begin();
492 it != m_categories.end(); ++it )
493 {
494 stream << "<Category id=\""<< ( (*it).id() ) << "\" ";
495
496 if ( !(*it).app().isEmpty() )
497 stream << " app=\""<< ( (*it).app() ) << "\" ";
498
499 stream << "name=\"" << ( (*it).name() ) << "\" ";
500 stream << " />" << endl;
501 }
502 stream << "</Categories>" << endl;
503 file.close();
311 } 504 }
505}
506int CategoryEdit::addCategory( const QString &name, int id ){
507 return addCategory( QString::null, name, id );
508}
509int CategoryEdit::addCategory( const QString &appName, const QString &name, int id ){
510 if ( id == 0 ) {
511 // code from tt
512 //generate uid
513 QDateTime dt = QDateTime::currentDateTime();
514 id = -1 * (int) dt.secsTo( QDateTime(QDate( 2000,1,1)) );
515 while ( ids.contains( id ) ){
516 id += -1;
517 if ( id > 0 )
518 id = -1;
519 }
520 }
521 ids.insert( id, TRUE );
522 OpieCategories categories(QString::number(id), name, appName);
523 //pending FIXME LR m_categories.remove( categories);
524 m_categories.append( categories);
525 return id;
526}
527/*
528 * we parse the simple Category File here
529 * We also keep track of global Cats
530 * and Of Organizer and Contact cats and then
531 * we will add them to the kde side...
532 */
533void CategoryEdit::parse( const QString &tempFile ){
534 clear();
535
536 QDomDocument doc( "mydocument" );
537 QFile f( tempFile );
538 if ( !f.open( IO_ReadOnly ) )
539 return;
540
541 if ( !doc.setContent( &f ) ) {
542 f.close();
543 return;
544 }
545 f.close();
546
547 QStringList global, contact, organizer;
548
549 // print out the element names of all elements that are a direct child
550 // of the outermost element.
551 QDomElement docElem = doc.documentElement();
552 QDomNode n = docElem.firstChild();
553 if( docElem.nodeName() == QString::fromLatin1("Categories") ){
554 while( !n.isNull() ) {
555 QDomElement e = n.toElement(); // try to convert the node to an element.
556 if( !e.isNull() ) { // the node was really an element.
557 QString id = e.attribute("id" );
558 QString app = e.attribute("app" );
559 QString name = e.attribute("name");
560
561 /*
562 * see where it belongs default to global
563 */
564 if (app == QString::fromLatin1("Calendar") || app == QString::fromLatin1("Todo List") )
565 organizer.append( name );
566 else if ( app == QString::fromLatin1("Contacts") )
567 contact.append( name );
568 else
569 global.append( name );
570
571 OpieCategories category( id, name, app );
572 m_categories.append( category ); // cheater
573 }
574 n = n.nextSibling();
575 }
576 }
577 updateKDE( "kaddressbookrc", global + contact );
578 updateKDE( "korganizerrc", global + organizer );
312 579
313 PhoneNumber businessphone = addr.phoneNumber( PhoneNumber::Work ); 580}
314 if (!businessphone.number().isEmpty()) 581void CategoryEdit::clear()
315 contact.setBusinessPhone(businessphone.number()); 582{
316 583 ids.clear();
317 PhoneNumber businessfax = addr.phoneNumber( PhoneNumber::Work | PhoneNumber::Fax ); 584 m_categories.clear();
318 if (!businessfax.number().isEmpty()) 585}
319 contact.setBusinessFax(businessfax.number()); 586QString CategoryEdit::categoryById( const QString &id, const QString &app )const
320 587{
321 PhoneNumber businessmobile = addr.phoneNumber( PhoneNumber::Work | PhoneNumber::Cell ); 588 QValueList<OpieCategories>::ConstIterator it;
322 if (!businessmobile.number().isEmpty()) 589 QString category;
323 contact.setBusinessMobile(businessmobile.number()); 590 QString fallback;
324 591 for( it = m_categories.begin(); it != m_categories.end(); ++it ){
325 PhoneNumber businesspager = addr.phoneNumber( PhoneNumber::Work | PhoneNumber::Pager ); 592 if( id.stripWhiteSpace() == (*it).id().stripWhiteSpace() ){
326 if (!businesspager.number().isEmpty()) 593 if( app == (*it).app() ){
327 contact.setBusinessPager(businesspager.number()); 594 category = (*it).name();
328 595 break;
329 contact.setJobTitle(addr.role()); 596 }else{
330 contact.setCompany(addr.organization()); 597 fallback = (*it).name();
331 598 }
332 contact.setProfession(addr.custom( "KADDRESSBOOK", "X-Profession" )); 599 }
333 contact.setAssistant(addr.custom( "KADDRESSBOOK", "X-AssistantsName" )); 600 }
334 contact.setDepartment(addr.custom( "KADDRESSBOOK", "X-Department" )); 601 return category.isEmpty() ? fallback : category;
335 contact.setManager(addr.custom( "KADDRESSBOOK", "X-ManagersName" )); 602}
336 contact.setOffice(addr.custom( "KADDRESSBOOK", "X-Office" )); 603QStringList CategoryEdit::categoriesByIds( const QStringList& ids,
337 604 const QString& app) {
338 //personal 605
339 contact.setSpouse(addr.custom( "KADDRESSBOOK", "X-Spouse" )); 606 QStringList list;
340 // qtopia uses this categorization: 607 QStringList::ConstIterator it;
341 // enum GenderType { UnspecifiedGender=0, Male, Female }; 608 QString temp;
342 QString gt = addr.custom( "KADDRESSBOOK", "X-Gender" ); 609 for ( it = ids.begin(); it != ids.end(); ++it ) {
343 if (gt = "male") 610 temp = categoryById( (*it), app );
344 contact.setGender(PimContact::Male); 611 if (!temp.isEmpty() )
345 else if (gt = "female") 612 list << temp;
346 contact.setGender(PimContact::Female); 613 }
347 else
348 contact.setGender(PimContact::UnspecifiedGender);
349
350
351 QDate dt = KGlobal::locale()->readDate(
352 addr.custom("KADDRESSBOOK", "X-Anniversary" ), "%Y-%m-%d"); // = Qt::ISODate
353 contact.setAnniversary( dt );
354
355 contact.setChildren(addr.custom( "KADDRESSBOOK", "X-Children" ));
356 614
357 contact.setBirthday(addr.birthday().date()); 615 return list;
358 contact.setNickname(addr.nickName()); 616}
617void CategoryEdit::updateKDE( const QString& configFile, const QStringList& cats ) {
618 KConfig conf(configFile);
619 conf.setGroup("General");
620 QStringList avail = conf.readListEntry("Custom Categories");
621 for (QStringList::ConstIterator it = cats.begin(); it != cats.end(); ++it ) {
622 if (!avail.contains( (*it) ) )
623 avail << (*it);
624 }
625 conf.writeEntry("Custom Categories", avail );
626}
359 627
360 // other
361 contact.setNotes(addr.note());
362 628
363//US QString groups() const { return find( Qtopia::Groups ); }
364//US QStringList groupList() const;
365 629
630OpieCategories::OpieCategories()
631{
366 632
367 QStringList cats = addr.categories(); 633}
634OpieCategories::OpieCategories(const QString &id, const QString &name, const QString &app )
635{
636 m_name = name;
637 m_id = id;
638 m_app = app;
639}
640OpieCategories::OpieCategories(const OpieCategories &op )
641{
642 (*this) = op;
643}
644QString OpieCategories::id() const
645{
646 return m_id;
647}
648QString OpieCategories::name() const
649{
650 return m_name;
651}
652QString OpieCategories::app() const
653{
654 return m_app;
655}
656OpieCategories &OpieCategories::operator=(const OpieCategories &op )
657{
658 m_name = op.m_name;
659 m_app = op.m_app;
660 m_id = op.m_id;
661 return (*this);
662}
368 663
369 QArray<int> iar;
370 if ( !cats.isEmpty() ) {
371 QArray<int> iar = catDB->ids("contact", cats);
372 contact.setCategories(iar);
373 }
374 664
375 return true; 665bool operator== (const OpieCategories& a, const OpieCategories &b )
666{
667 if ( a.id() == b.id() && a.name() == b.name() && a.app() == b.app() )
668 return true;
669 return false;
376} 670}
671
diff --git a/kabc/plugins/qtopia/qtopiaconverter.h b/kabc/plugins/qtopia/qtopiaconverter.h
index 012a6e2..d318ded 100644
--- a/kabc/plugins/qtopia/qtopiaconverter.h
+++ b/kabc/plugins/qtopia/qtopiaconverter.h
@@ -1,80 +1,132 @@
1/* 1/*
2 This file is part of libkabc. 2 This file is part of libkabc.
3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org> 3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21/* 21/*
22Enhanced Version of the file for platform independent KDE tools. 22Enhanced Version of the file for platform independent KDE tools.
23Copyright (c) 2004 Ulf Schenk 23Copyright (c) 2004 Ulf Schenk
24$Id$ 24$Id$
25*/ 25*/
26 26
27#ifndef KABC_QTOPIACONVERTER_H 27#ifndef KABC_QTOPIACONVERTER_H
28#define KABC_QTOPIACONVERTER_H 28#define KABC_QTOPIACONVERTER_H
29 29
30#include <qstring.h> 30#include <qstring.h>
31 31
32#include "addressee.h" 32#include "addressee.h"
33#include <qpe/pim/contact.h> 33//#include <qpe/pim/contact.h>
34#include <qpe/quuid.h> 34//#include <qpe/quuid.h>
35 35
36#include <xml/qdom.h>
36class Categories; 37class Categories;
37 38
38namespace KABC { 39namespace KABC {
39 40
41
42
43class OpieCategories {
44 public:
45 //friend class KSync::OpieSocket;
46 friend bool operator== ( const OpieCategories &a, const OpieCategories &b );
47 OpieCategories();
48 OpieCategories(const QString &id, const QString &name, const QString &app );
49 OpieCategories(const OpieCategories & );
50 ~OpieCategories() {};
51 OpieCategories &operator=(const OpieCategories & );
52 QString id()const;
53 QString name()const;
54 QString app()const;
55
56 private:
57 QString m_name;
58 QString m_app;
59 QString m_id;
60};
61
62
63 class CategoryEdit {
64 public:
65 CategoryEdit();
66 CategoryEdit(const QString &fileName);
67 ~CategoryEdit();
68
69 void save(const QString&) const;
70 int addCategory( const QString &name, int id = 0 );
71 int addCategory(const QString &appName, const QString &name, int id = 0);
72 void parse( const QString &fileName );
73
74 QString categoryById(const QString &id, const QString &app )const;
75 QStringList categoriesByIds( const QStringList& ids, const QString& app );
76
77 void clear();
78 QValueList<OpieCategories> categories()const { return m_categories; };
79 private:
80 /**
81 * this function will be used internally to update the kde categories...
82 */
83 void updateKDE( const QString& app, const QStringList& categories );
84 QMap<int, bool> ids; // from tt Qtopia::UidGen
85 QValueList<OpieCategories> m_categories;
86 };
87
88
40class QtopiaConverter 89class QtopiaConverter
41{ 90{
42public: 91public:
43 92
44 /** 93 /**
45 * Constructor. 94 * Constructor.
46 */ 95 */
47 QtopiaConverter(); 96 QtopiaConverter();
48 97
49 /** 98 /**
50 * Destructor. 99 * Destructor.
51 */ 100 */
52 virtual ~QtopiaConverter(); 101 virtual ~QtopiaConverter();
53 102
54 bool init(); 103 bool init();
55 void deinit(); 104 void deinit();
56 105
57 /** 106 /**
58 * Converts a vcard string to an addressee. 107 * Converts a vcard string to an addressee.
59 * 108 *
60 * @param contact The qtopia contact. 109 * @param contact The qtopia contact.
61 * @param addr The addressee. 110 * @param addr The addressee.
62 */ 111 */
63 bool qtopiaToAddressee( const PimContact &contact, Addressee &addr ); 112 bool qtopiaToAddressee( const QDomElement& el, Addressee &adr );
64
65 /** 113 /**
66 * Converts an addressee to a vcard string. 114 * Converts an addressee to a vcard string.
67 * 115 *
68 * @param addr The addressee. 116 * @param addr The addressee.
69 * @param contact The qtopia contact. 117 * @param contact The qtopia contact.
70 */ 118 */
71 bool addresseeToQtopia( const Addressee &addr, PimContact &contact ); 119 bool addresseeToQtopia( const Addressee &ab, QTextStream *stream );
72 120
73 private: 121 private:
74 Categories* catDB; 122 QString categoriesToNumber( const QStringList &list, const QString &app );
123 QString escape( const QString& s){ return s;};
124 CategoryEdit *m_edit;
125 QDate fromString( const QString& );
126 QDate dateFromString( const QString& );
127 QString dateToString( const QDate& );
75 128
76 129
77}; 130};
78
79} 131}
80#endif 132#endif
diff --git a/kabc/plugins/qtopia/resourceqtopia.cpp b/kabc/plugins/qtopia/resourceqtopia.cpp
index deb218b..b7263bb 100644
--- a/kabc/plugins/qtopia/resourceqtopia.cpp
+++ b/kabc/plugins/qtopia/resourceqtopia.cpp
@@ -1,285 +1,346 @@
1/* 1/*
2 This file is part of libkabc. 2 This file is part of libkabc.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21/* 21/*
22Enhanced Version of the file for platform independent KDE tools. 22Enhanced Version of the file for platform independent KDE tools.
23Copyright (c) 2004 Ulf Schenk 23Copyright (c) 2004 Ulf Schenk
24 24
25$Id$ 25$Id$
26*/ 26*/
27#include <sys/types.h> 27#include <sys/types.h>
28#include <sys/stat.h> 28#include <sys/stat.h>
29#include <unistd.h> 29#include <unistd.h>
30 30
31#include <qdir.h> 31#include <qdir.h>
32#include <qfile.h> 32#include <qfile.h>
33#include <qtextstream.h>
33#include <qfileinfo.h> 34#include <qfileinfo.h>
34#include <qregexp.h> 35#include <qregexp.h>
35//US #include <qtimer.h> 36//US #include <qtimer.h>
36 37
37#include <kapplication.h> 38#include <kapplication.h>
38#include <kconfig.h> 39#include <kconfig.h>
39#include <kdebug.h> 40#include <kdebug.h>
40#include <klocale.h> 41#include <klocale.h>
41//US #include <ksavefile.h> 42//US #include <ksavefile.h>
42#include <kstandarddirs.h> 43#include <kstandarddirs.h>
43#include <kmessagebox.h> 44#include <kmessagebox.h>
44 45
45#include <qpe/pim/addressbookaccess.h> 46#include <qpe/pim/addressbookaccess.h>
46 47
47 48
48#include "resourceqtopiaconfig.h" 49#include "resourceqtopiaconfig.h"
49#include "stdaddressbook.h" 50#include "stdaddressbook.h"
50 51
51#include "qtopiaconverter.h" 52#include "qtopiaconverter.h"
52 53
53#include "resourceqtopia.h" 54#include "resourceqtopia.h"
54 55
55using namespace KABC; 56using namespace KABC;
56extern "C" 57extern "C"
57{ 58{
58 void *init_microkabc_qtopia() 59 void *init_microkabc_qtopia()
59 { 60 {
60 return new KRES::PluginFactory<ResourceQtopia,ResourceQtopiaConfig>(); 61 return new KRES::PluginFactory<ResourceQtopia,ResourceQtopiaConfig>();
61 } 62 }
62} 63}
63 64
64ResourceQtopia::ResourceQtopia( const KConfig *config ) 65ResourceQtopia::ResourceQtopia( const KConfig *config )
65 : Resource( config ), mConverter (0) 66 : Resource( config ), mConverter (0)
66{ 67{
67 // we can not choose the filename. Therefore use the default to display 68 // we can not choose the filename. Therefore use the default to display
68 QString fileName = QDir::homeDirPath() + "/Applications/addressbook/addressbook.xml"; 69 QString fileName = QDir::homeDirPath() + "/Applications/addressbook/addressbook.xml";
69 init( fileName ); 70 init( fileName );
70} 71}
71 72
72ResourceQtopia::ResourceQtopia( const QString &fileName ) 73ResourceQtopia::ResourceQtopia( const QString &fileName )
73 : Resource( 0 ) 74 : Resource( 0 )
74{ 75{
75 init( fileName ); 76 init( fileName );
76} 77}
77 78
78void ResourceQtopia::init( const QString &fileName ) 79void ResourceQtopia::init( const QString &fileName )
79{ 80{
80 81
81 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) ); 82 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) );
82 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) ); 83 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) );
83 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) ); 84 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) );
84 85
85 setFileName( fileName ); 86 setFileName( fileName );
86} 87}
87 88
88ResourceQtopia::~ResourceQtopia() 89ResourceQtopia::~ResourceQtopia()
89{ 90{
90 if (mConverter != 0) 91 if (mConverter != 0)
91 delete mConverter; 92 delete mConverter;
92 93
93 if(mAccess != 0)
94 delete mAccess;
95} 94}
96 95
97void ResourceQtopia::writeConfig( KConfig *config ) 96void ResourceQtopia::writeConfig( KConfig *config )
98{ 97{
99 Resource::writeConfig( config ); 98 Resource::writeConfig( config );
100} 99}
101 100
102Ticket *ResourceQtopia::requestSaveTicket() 101Ticket *ResourceQtopia::requestSaveTicket()
103{ 102{
104 kdDebug(5700) << "ResourceQtopia::requestSaveTicket()" << endl; 103 kdDebug(5700) << "ResourceQtopia::requestSaveTicket()" << endl;
105 104
106 qDebug("ResourceQtopia::requestSaveTicket: %s", fileName().latin1()); 105 qDebug("ResourceQtopia::requestSaveTicket: %s", fileName().latin1());
107 106
108 if ( !addressBook() ) return 0; 107 if ( !addressBook() ) return 0;
109 108
110 if ( !lock( fileName() ) ) { 109 if ( !lock( fileName() ) ) {
111 kdDebug(5700) << "ResourceQtopia::requestSaveTicket(): Unable to lock file '" 110 kdDebug(5700) << "ResourceQtopia::requestSaveTicket(): Unable to lock file '"
112 << fileName() << "'" << endl; 111 << fileName() << "'" << endl;
113 return 0; 112 return 0;
114 } 113 }
115 return createTicket( this ); 114 return createTicket( this );
116} 115}
117 116
118 117
119bool ResourceQtopia::doOpen() 118bool ResourceQtopia::doOpen()
120{ 119{
121 qDebug("ResourceQtopia::doOpen(): %s", fileName().latin1()); 120 qDebug("ResourceQtopia::doOpen(): %s", fileName().latin1());
122 121
123 mAccess = new AddressBookAccess();
124
125 if ( !mAccess ) {
126 qDebug("Unable to load file() %s", fileName().latin1());
127 return false;
128 }
129
130 122
131 if (mConverter == 0) 123 if (mConverter == 0)
132 { 124 {
133 mConverter = new QtopiaConverter(); 125 mConverter = new QtopiaConverter();
134 bool res = mConverter->init(); 126 bool res = mConverter->init();
135 if ( !res ) 127 if ( !res )
136 { 128 {
137 QString msg("Unable to initialize qtopia converter. Most likely a problem with the category file"); 129 QString msg("Unable to initialize qtopia converter. Most likely a problem with the category file");
138 qDebug(msg); 130 qDebug(msg);
139 delete mAccess;
140 mAccess = 0;
141 return false; 131 return false;
142 } 132 }
143 } 133 }
144 134
145 return true; 135 return true;
146} 136}
147 137
148void ResourceQtopia::doClose() 138void ResourceQtopia::doClose()
149{ 139{
150 qDebug("ResourceQtopia::doClose: %s", fileName().latin1()); 140 qDebug("ResourceQtopia::doClose: %s", fileName().latin1());
151 141
152 if(mAccess) 142
153 {
154 delete mAccess;
155 mAccess = 0;
156 }
157 // it seems so, that deletion of access deletes backend as well 143 // it seems so, that deletion of access deletes backend as well
158 //delete backend; 144 //delete backend;
159 145
160 return; 146 return;
161} 147}
162 148
163bool ResourceQtopia::load() 149bool ResourceQtopia::load()
164{ 150{
151
152 QFile file( fileName() );
153 if ( !file.open(IO_ReadOnly ) ) {
154 return false;
155 }
156
157 QDomDocument doc("mydocument" );
158 if ( !doc.setContent( &file ) ) {
159 file.close();
160 return false;
161 }
162 bool res;
163 QDomElement docElem = doc.documentElement( );
164 QDomNode n = docElem.firstChild();
165 while ( !n.isNull() ) {
166 QDomElement e = n.toElement();
167 if ( !e.isNull() ) {
168 if ( e.tagName() == QString::fromLatin1( "Contacts" ) ) { // we're looking for them
169 QDomNode no = e.firstChild();
170 while ( !no.isNull() ) {
171 QDomElement el = no.toElement();
172 if ( !el.isNull() ) {
173 KABC::Addressee addressee;
174 res = mConverter->qtopiaToAddressee( el, addressee );
175 if ( !addressee.isEmpty() && res )
176 {
177 addressee.setResource( this );
178 addressBook()->insertAddressee( addressee );
179 }
180 }
181
182 no = no.nextSibling();
183 }
184 }
185 }
186
187 n = n.nextSibling();
188 }
189
190#if 0
191/ old code
165 qDebug("ResourceQtopia::load: %s", fileName().latin1()); 192 qDebug("ResourceQtopia::load: %s", fileName().latin1());
166 193
167 AddressBookIterator it(*mAccess); 194 AddressBookIterator it(*mAccess);
168 const PimContact* contact; 195 const PimContact* contact;
169 bool res; 196 bool res;
170 197
171 for (contact=it.toFirst(); it.current(); ++it) 198 for (contact=it.toFirst(); it.current(); ++it)
172 { 199 {
173 contact = it.current(); 200 contact = it.current();
174 201
175 KABC::Addressee addressee; 202 KABC::Addressee addressee;
176 203
177 res = mConverter->qtopiaToAddressee( (*contact), addressee ); 204 //LRres = mConverter->qtopiaToAddressee( (*contact), addressee );
178 205
179 if ( !addressee.isEmpty() && res ) 206 if ( !addressee.isEmpty() && res )
180 { 207 {
181 addressee.setResource( this ); 208 addressee.setResource( this );
182 addressBook()->insertAddressee( addressee ); 209 addressBook()->insertAddressee( addressee );
183 } 210 }
184 } 211 }
185 212#endif
186 return true; 213 return true;
187} 214}
188 215
189bool ResourceQtopia::save( Ticket *ticket ) 216bool ResourceQtopia::save( Ticket *ticket )
190{ 217{
218
219 mDirWatch.stopScan();
220 KABC::AddressBook::Iterator it;
221 bool res;
222 //pending open file for stream
223 QTextStream *stream;// = tempFile->textStream();
224 stream->setEncoding( QTextStream::UnicodeUTF8 );
225 *stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>" << endl;
226 *stream << " <Groups>" << endl;
227 *stream << " </Groups>" << endl;
228 *stream << " <Contacts> " << endl;
229 // for all entries
230 KABC::Addressee ab;
231 for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) {
232 KABC::Addressee addressee = (*it);
233 res = mConverter->addresseeToQtopia( addressee, stream );
234 if (!res == true)
235 {
236 qDebug("Unable to convert Addressee %s", addressee.formattedName().latin1());
237 }
238 }
239
240
241 *stream << "</Contacts>" << endl;
242 *stream << "</AddressBook>" << endl;
243 //pending close file
244 mDirWatch.startScan();
245
246 delete ticket;
247 unlock( fileName() );
248
249
250#if 0
251 //old code
191 qDebug("ResourceQtopia::save: %s", fileName().latin1()); 252 qDebug("ResourceQtopia::save: %s", fileName().latin1());
192 253
193 mDirWatch.stopScan(); 254 mDirWatch.stopScan();
194 255
195 KABC::AddressBook::Iterator it; 256 KABC::AddressBook::Iterator it;
196 bool res; 257 bool res;
197 258
198 for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) { 259 for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) {
199 PimContact c; 260 PimContact c;
200 KABC::Addressee addressee = (*it); 261 KABC::Addressee addressee = (*it);
201 262
202 res = mConverter->addresseeToQtopia( *it, c ); 263 //res = mConverter->addresseeToQtopia( *it, c );
203 if (res == true) 264 if (res == true)
204 { 265 {
205 mAccess->addContact(c); 266 mAccess->addContact(c);
206// if (res == false) 267// if (res == false)
207// qDebug("Unable to append Contact %s", c.fullName().latin1()); 268// qDebug("Unable to append Contact %s", c.fullName().latin1());
208 } 269 }
209 else 270 else
210 { 271 {
211 qDebug("Unable to convert Addressee %s", addressee.formattedName().latin1()); 272 qDebug("Unable to convert Addressee %s", addressee.formattedName().latin1());
212 } 273 }
213 } 274 }
214 275
215// mAccess->addressBookUpdated(); 276// mAccess->addressBookUpdated();
216 277
217 mDirWatch.startScan(); 278 mDirWatch.startScan();
218 279
219 delete ticket; 280 delete ticket;
220 unlock( fileName() ); 281 unlock( fileName() );
221 282#endif
222 return true; 283 return true;
223} 284}
224 285
225bool ResourceQtopia::lock( const QString &lockfileName ) 286bool ResourceQtopia::lock( const QString &lockfileName )
226{ 287{
227 qDebug("ResourceQtopia::lock: %s", fileName().latin1()); 288 qDebug("ResourceQtopia::lock: %s", fileName().latin1());
228 289
229 kdDebug(5700) << "ResourceQtopia::lock()" << endl; 290 kdDebug(5700) << "ResourceQtopia::lock()" << endl;
230 291
231 QString fn = lockfileName; 292 QString fn = lockfileName;
232 293
233 KURL url(fn); 294 KURL url(fn);
234 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); 295 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" );
235 296
236 kdDebug(5700) << "-- lock name: " << lockName << endl; 297 kdDebug(5700) << "-- lock name: " << lockName << endl;
237 298
238 if (QFile::exists( lockName )) 299 if (QFile::exists( lockName ))
239 { 300 {
240 qDebug("ResourceOpie::lock: lockfile %s already exists. (Delete it before continuing if nobody else is accessing the resourcefile %s)", lockName.latin1(), fileName().latin1()); 301 qDebug("ResourceOpie::lock: lockfile %s already exists. (Delete it before continuing if nobody else is accessing the resourcefile %s)", lockName.latin1(), fileName().latin1());
241 return false; 302 return false;
242 } 303 }
243 304
244 QString lockUniqueName; 305 QString lockUniqueName;
245 lockUniqueName = fn + KApplication::randomString( 8 ); 306 lockUniqueName = fn + KApplication::randomString( 8 );
246 307
247 url = lockUniqueName; 308 url = lockUniqueName;
248//US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName ); 309//US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName );
249 mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() ); 310 mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() );
250 kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl; 311 kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl;
251 312
252 // Create unique file 313 // Create unique file
253 QFile file( mLockUniqueName ); 314 QFile file( mLockUniqueName );
254 file.open( IO_WriteOnly ); 315 file.open( IO_WriteOnly );
255 file.close(); 316 file.close();
256 317
257 // Create lock file 318 // Create lock file
258 int result = 0; 319 int result = 0;
259#ifndef _WIN32_ 320#ifndef _WIN32_
260 result = ::link( QFile::encodeName( mLockUniqueName ), 321 result = ::link( QFile::encodeName( mLockUniqueName ),
261 QFile::encodeName( lockName ) ); 322 QFile::encodeName( lockName ) );
262#endif 323#endif
263 if ( result == 0 ) { 324 if ( result == 0 ) {
264 addressBook()->emitAddressBookLocked(); 325 addressBook()->emitAddressBookLocked();
265 return true; 326 return true;
266 } 327 }
267 328
268 // TODO: check stat 329 // TODO: check stat
269 330
270 return false; 331 return false;
271} 332}
272 333
273void ResourceQtopia::unlock( const QString &fileName ) 334void ResourceQtopia::unlock( const QString &fileName )
274{ 335{
275 qDebug("ResourceQtopia::unlock() %s", fileName.latin1()); 336 qDebug("ResourceQtopia::unlock() %s", fileName.latin1());
276 337
277 QString fn = fileName; 338 QString fn = fileName;
278 KURL url(fn); 339 KURL url(fn);
279 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); 340 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" );
280 341
281 QFile::remove( lockName ); 342 QFile::remove( lockName );
282 QFile::remove( mLockUniqueName ); 343 QFile::remove( mLockUniqueName );
283 addressBook()->emitAddressBookUnlocked(); 344 addressBook()->emitAddressBookUnlocked();
284} 345}
285 346
diff --git a/kabc/plugins/qtopia/resourceqtopia.h b/kabc/plugins/qtopia/resourceqtopia.h
index ff6350d..31b95f2 100644
--- a/kabc/plugins/qtopia/resourceqtopia.h
+++ b/kabc/plugins/qtopia/resourceqtopia.h
@@ -71,75 +71,74 @@ public:
71 ~ResourceQtopia(); 71 ~ResourceQtopia();
72 72
73 /** 73 /**
74 Writes the config back. 74 Writes the config back.
75 */ 75 */
76 virtual void writeConfig( KConfig *cfg ); 76 virtual void writeConfig( KConfig *cfg );
77 77
78 /** 78 /**
79 * Tries to open the file and checks for the proper format. 79 * Tries to open the file and checks for the proper format.
80 * This method should be called before @ref load(). 80 * This method should be called before @ref load().
81 */ 81 */
82 virtual bool doOpen(); 82 virtual bool doOpen();
83 83
84 /** 84 /**
85 * Closes the file again. 85 * Closes the file again.
86 */ 86 */
87 virtual void doClose(); 87 virtual void doClose();
88 88
89 /** 89 /**
90 * Requests a save ticket, that is used by @ref save() 90 * Requests a save ticket, that is used by @ref save()
91 */ 91 */
92 virtual Ticket *requestSaveTicket(); 92 virtual Ticket *requestSaveTicket();
93 93
94 /** 94 /**
95 * Loads all addressees from file to the address book. 95 * Loads all addressees from file to the address book.
96 * Returns true if all addressees could be loaded otherwise false. 96 * Returns true if all addressees could be loaded otherwise false.
97 */ 97 */
98 virtual bool load(); 98 virtual bool load();
99 99
100 /** 100 /**
101 * Saves all addresses from address book to file. 101 * Saves all addresses from address book to file.
102 * Returns true if all addressees could be saved otherwise false. 102 * Returns true if all addressees could be saved otherwise false.
103 * 103 *
104 * @param ticket The ticket returned by @ref requestSaveTicket() 104 * @param ticket The ticket returned by @ref requestSaveTicket()
105 */ 105 */
106 virtual bool save( Ticket *ticket ); 106 virtual bool save( Ticket *ticket );
107 107
108 /** 108 /**
109 * Remove a addressee from its source. 109 * Remove a addressee from its source.
110 * This method is mainly called by KABC::AddressBook. 110 * This method is mainly called by KABC::AddressBook.
111 */ 111 */
112 virtual void removeAddressee( const Addressee& addr ); 112 virtual void removeAddressee( const Addressee& addr );
113 113
114 /** 114 /**
115 * Set name of file to be used for saving. 115 * Set name of file to be used for saving.
116 */ 116 */
117 virtual void setFileName( const QString & ); 117 virtual void setFileName( const QString & );
118 118
119 /** 119 /**
120 * This method is called by an error handler if the application 120 * This method is called by an error handler if the application
121 * crashed 121 * crashed
122 */ 122 */
123 virtual void cleanUp(); 123 virtual void cleanUp();
124 124
125protected slots: 125protected slots:
126 void fileChanged(); 126 void fileChanged();
127 127
128protected: 128protected:
129 void init( const QString &fileName ); 129 void init( const QString &fileName );
130 130
131 bool lock( const QString &fileName ); 131 bool lock( const QString &fileName );
132 void unlock( const QString &fileName ); 132 void unlock( const QString &fileName );
133 133
134private: 134private:
135 AddressBookAccess* mAccess;
136 QtopiaConverter* mConverter; 135 QtopiaConverter* mConverter;
137 136
138 QString mLockUniqueName; 137 QString mLockUniqueName;
139 138
140 KDirWatch mDirWatch; 139 KDirWatch mDirWatch;
141}; 140};
142 141
143} 142}
144 143
145#endif 144#endif