summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (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
@@ -13,3 +13,2 @@ LIBS += -lkamicrokabc
13LIBS += -L$(QPEDIR)/lib 13LIBS += -L$(QPEDIR)/lib
14LIBS += -lqpepim
15LIBS += -lqpe 14LIBS += -lqpe
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
@@ -29,2 +29,3 @@ $Id$
29#include "kglobal.h" 29#include "kglobal.h"
30#include "klocale.h"
30 31
@@ -33,3 +34,8 @@ $Id$
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>
@@ -40,4 +46,5 @@ using namespace KABC;
40 46
41QtopiaConverter::QtopiaConverter() : catDB(0) 47QtopiaConverter::QtopiaConverter()
42{ 48{
49 m_edit = 0;
43} 50}
@@ -51,9 +58,5 @@ bool 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}
@@ -62,192 +65,252 @@ void 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;
@@ -255,122 +318,354 @@ bool QtopiaConverter::qtopiaToAddressee( const PimContact &contact, Addressee &a
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
@@ -32,5 +32,6 @@ $Id$
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;
@@ -39,2 +40,50 @@ namespace 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
@@ -62,4 +111,3 @@ public:
62 */ 111 */
63 bool qtopiaToAddressee( const PimContact &contact, Addressee &addr ); 112 bool qtopiaToAddressee( const QDomElement& el, Addressee &adr );
64
65 /** 113 /**
@@ -70,6 +118,11 @@ public:
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
@@ -77,3 +130,2 @@ public:
77}; 130};
78
79} 131}
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
@@ -32,2 +32,3 @@ $Id$
32#include <qfile.h> 32#include <qfile.h>
33#include <qtextstream.h>
33#include <qfileinfo.h> 34#include <qfileinfo.h>
@@ -92,4 +93,2 @@ ResourceQtopia::~ResourceQtopia()
92 93
93 if(mAccess != 0)
94 delete mAccess;
95} 94}
@@ -122,9 +121,2 @@ bool ResourceQtopia::doOpen()
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
@@ -138,4 +130,2 @@ bool ResourceQtopia::doOpen()
138 qDebug(msg); 130 qDebug(msg);
139 delete mAccess;
140 mAccess = 0;
141 return false; 131 return false;
@@ -151,7 +141,3 @@ void ResourceQtopia::doClose()
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
@@ -164,2 +150,43 @@ bool 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());
@@ -176,3 +203,3 @@ bool ResourceQtopia::load()
176 203
177 res = mConverter->qtopiaToAddressee( (*contact), addressee ); 204 //LRres = mConverter->qtopiaToAddressee( (*contact), addressee );
178 205
@@ -184,3 +211,3 @@ bool ResourceQtopia::load()
184 } 211 }
185 212#endif
186 return true; 213 return true;
@@ -190,2 +217,36 @@ bool 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());
@@ -201,3 +262,3 @@ bool ResourceQtopia::save( Ticket *ticket )
201 262
202 res = mConverter->addresseeToQtopia( *it, c ); 263 //res = mConverter->addresseeToQtopia( *it, c );
203 if (res == true) 264 if (res == true)
@@ -220,3 +281,3 @@ bool ResourceQtopia::save( Ticket *ticket )
220 unlock( fileName() ); 281 unlock( fileName() );
221 282#endif
222 return true; 283 return true;
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
@@ -134,3 +134,2 @@ protected:
134private: 134private:
135 AddressBookAccess* mAccess;
136 QtopiaConverter* mConverter; 135 QtopiaConverter* mConverter;