summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--kabc/plugins/qtopia/qtopiaE.pro1
-rw-r--r--kabc/plugins/qtopia/qtopiaconverter.cpp791
-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, 683 insertions, 277 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,8 +58,4 @@ 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)
55 return false;
56
57 catDB->load( categoryFileName() );
58 return true; 61 return true;
@@ -62,315 +65,607 @@ 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{
72 // name
73 addr.setFormattedName(contact.fileAs());
74 addr.setFamilyName( contact.lastName() );
75 addr.setGivenName( contact.firstName() );
76 addr.setAdditionalName( contact.middleName() );
77 addr.setPrefix( contact.nameTitle() );
78 addr.setSuffix( contact.suffix() );
79
80 addr.setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL );
81 QString exuid = contact.uid().toString();
82 addr.setOriginalExternalUID( exuid );
83 int ente = exuid.find( "-0000");
84 if ( exuid.left(1) == "{" )
85 exuid = exuid.mid(1);
86 if ( ente > -1 )
87 exuid = exuid.left( ente-1 );
88 addr.setExternalUID( exuid );
89 // qDebug("QtopiaConverter:set %s uid %s ",addr.originalExternalUID().latin1(),addr.externalUID().latin1() );
90
91 // email
92 QStringList emails = contact.emailList();
93 for ( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) {
94 addr.insertEmail( *it, ((*it) == contact.defaultEmail()) );
95 }
96
97 if (!contact.defaultEmail().isEmpty())
98 addr.insertEmail(contact.defaultEmail(), true);
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 { 73 {
107 Address homeaddress; 74 startover:
108 homeaddress.setType(Address::Home); 75 QStringList dummy;
109//US homeaddress.setPostOfficeBox( "" ); 76 QValueList<OpieCategories>::ConstIterator catIt;
110//US homeaddress.setExtended( "" ); 77 QValueList<OpieCategories> categories = m_edit->categories();
111 homeaddress.setStreet( contact.homeStreet() ); 78 bool found = false;
112 homeaddress.setLocality( contact.homeCity() ); 79 for ( QStringList::ConstIterator listIt = list.begin(); listIt != list.end(); ++listIt ) {
113 homeaddress.setRegion( contact.homeState() ); 80 /* skip empty category name */
114 homeaddress.setPostalCode( contact.homeZip() ); 81 if ( (*listIt).isEmpty() ) continue;
115 homeaddress.setCountry( contact.homeCountry() ); 82
116 83 found = false;
117 addr.insertAddress( homeaddress ); 84 for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) {
85 /*
86 * We currently do not take app into account
87 * if name matches and the id isn't already in dummy we'll add it
88 */
89 if ( (*catIt).name() == (*listIt) && !dummy.contains(( *catIt).id() ) ) { // the same name
90 found= true;
91 dummy << (*catIt).id();
118 } 92 }
119
120 if (!contact.homePhone().isEmpty())
121 {
122 PhoneNumber homephone;
123 homephone.setType( PhoneNumber::Home );
124 homephone.setNumber( contact.homePhone() );
125 addr.insertPhoneNumber( homephone );
126 } 93 }
94 /* if not found and the category is not empty
95 *
96 * generate a new category and start over again
97 * ugly goto to reiterate
98 */
127 99
128 if (!contact.homeFax().isEmpty()) 100 if ( !found && !(*listIt).isEmpty() ){
129 { 101 m_edit->addCategory( app, (*listIt) ); // generate a new category
130 PhoneNumber homefax; 102 goto startover;
131 homefax.setType( PhoneNumber::Home | PhoneNumber::Fax );
132 homefax.setNumber( contact.homeFax() );
133 addr.insertPhoneNumber( homefax );
134 } 103 }
135
136 if (!contact.homeMobile().isEmpty())
137 {
138 PhoneNumber homemobile;
139 homemobile.setType( PhoneNumber::Home | PhoneNumber::Cell );
140 homemobile.setNumber( contact.homeMobile() );
141 addr.insertPhoneNumber( homemobile );
142 } 104 }
143 105
144 addr.setUrl( contact.homeWebpage() ); 106 return dummy.join(";");
107}
145 108
146 109
147 // business 110// FROM TT timeconversion.cpp GPLed
148 if ((!contact.businessStreet().isEmpty()) || 111QDate QtopiaConverter::fromString( const QString &datestr )
149 (!contact.businessCity().isEmpty()) ||
150 (!contact.businessState().isEmpty()) ||
151 (!contact.businessZip().isEmpty()) ||
152 (!contact.businessCountry().isEmpty()))
153 { 112 {
154 Address businessaddress; 113 if (datestr.isEmpty() )
155 businessaddress.setType(Address::Work); 114 return QDate();
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 115
164 addr.insertAddress( businessaddress ); 116 int monthPos = datestr.find('.');
117 int yearPos = datestr.find('.', monthPos+1 );
118 if ( monthPos == -1 || yearPos == -1 ) {
119 return QDate();
165 } 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 );
166 125
167 126
168 if (!contact.businessPhone().isEmpty()) 127 return date;
169 {
170 PhoneNumber businessphone;
171 businessphone.setType( PhoneNumber::Work );
172 businessphone.setNumber( contact.businessPhone() );
173 addr.insertPhoneNumber( businessphone );
174 } 128 }
175 129
176 if (!contact.businessFax().isEmpty()) 130QDate QtopiaConverter::dateFromString( const QString& s )
177 { 131 {
178 PhoneNumber businessfax; 132 QDate date;
179 businessfax.setType( PhoneNumber::Work | PhoneNumber::Fax ); 133
180 businessfax.setNumber( contact.businessFax() ); 134 if ( s.isEmpty() )
181 addr.insertPhoneNumber( businessfax ); 135 return date;
182 } 136
137 // Be backward compatible to old Opie format:
138 // Try to load old format. If it fails, try new ISO-Format!
139 date = fromString ( s );
140 if ( date.isValid() )
141 return date;
142
143 // Read ISO-Format (YYYYMMDD)
144 int year = s.mid(0, 4).toInt();
145 int month = s.mid(4,2).toInt();
146 int day = s.mid(6,2).toInt();
147
148 // do some quick sanity checking
149 if ( year < 1900 || year > 3000 )
150 return date;
151
152 if ( month < 0 || month > 12 )
153 return date;
154
155 if ( day < 0 || day > 31 )
156 return date;
157
158
159 date.setYMD( year, month, day );
160
161 if ( !date.isValid() )
162 return QDate();
183 163
184 if (!contact.businessMobile().isEmpty()) 164
165 return date;
166}
167QString QtopiaConverter::dateToString( const QDate &d )
185 { 168 {
186 PhoneNumber businessmobile; 169 if ( d.isNull() || !d.isValid() )
187 businessmobile.setType( PhoneNumber::Work | PhoneNumber::Cell ); 170 return QString::null;
188 businessmobile.setNumber( contact.businessMobile() ); 171
189 addr.insertPhoneNumber( businessmobile ); 172 // ISO format in year, month, day (YYYYMMDD); e.g. 20021231
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' );
178
179 QString str = year + month + day;
180
181 return str;
190 } 182 }
191 183
192 if (!contact.businessPager().isEmpty()) 184bool QtopiaConverter::qtopiaToAddressee( const QDomElement& el, Addressee &adr )
193 { 185 {
194 PhoneNumber businesspager; 186 { //LR
195 businesspager.setType( PhoneNumber::Work | PhoneNumber::Pager ); 187
196 businesspager.setNumber( contact.businessPager() ); 188 adr.setUid( el.attribute("Uid" ) );
197 addr.insertPhoneNumber( businesspager ); 189 adr.setFamilyName( el.attribute( "LastName" ) );
198 } 190 adr.setGivenName( el.attribute( "FirstName" ) );
199 191 adr.setAdditionalName( el.attribute( "MiddleName" ) );
200 addr.setRole( contact.jobTitle() ); //? 192 adr.setSuffix( el.attribute( "Suffix" ) );
201 addr.setOrganization( contact.company() ); 193 adr.setNickName( el.attribute( "Nickname" ) );
202 addr.insertCustom( "KADDRESSBOOK", "X-Profession", contact.profession() ); 194
203 addr.insertCustom( "KADDRESSBOOK", "X-AssistantsName", contact.assistant() ); 195 QDate date = dateFromString( el.attribute( "Birthday" ) );
204 addr.insertCustom( "KADDRESSBOOK", "X-Department", contact.department() ); 196 if ( date.isValid() )
205 addr.insertCustom( "KADDRESSBOOK", "X-ManagersName", contact.manager() ); 197 adr.setBirthday( date );
206 addr.insertCustom( "KADDRESSBOOK", "X-Office", contact.office() ); 198
207 199 adr.setRole( el.attribute( "JobTitle" ) );
208 //personal 200 if ( !el.attribute( "FileAs" ).isEmpty() )
209 addr.insertCustom( "KADDRESSBOOK", "X-SpousesName", contact.spouse() ); 201 adr.setFormattedName( el.attribute( "FileAs" ) );
210 // qtopia uses this categorization: 202
211 // enum GenderType { UnspecifiedGender=0, Male, Female }; 203 adr.setOrganization( el.attribute( "Company" ) );
212 if (contact.gender() == PimContact::Male) 204
213 addr.insertCustom( "KADDRESSBOOK", "X-Gender", "male"); 205 KABC::PhoneNumber businessPhoneNum( el.attribute( "BusinessPhone" ),
214 else if (contact.gender() == PimContact::Female) 206 KABC::PhoneNumber::Work );
215 addr.insertCustom( "KADDRESSBOOK", "X-Gender", "female"); 207 KABC::PhoneNumber businessFaxNum( el.attribute( "BusinessFax" ),
216 208 KABC::PhoneNumber::Work | KABC::PhoneNumber::Fax );
217 if (contact.anniversary().isValid()) { 209 KABC::PhoneNumber businessMobile( el.attribute( "BusinessMobile" ),
218 QString dt = KGlobal::locale()->formatDate(contact.anniversary(), true, KLocale::ISODate); 210 KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell );
219//US 211 KABC::PhoneNumber businessPager( el.attribute( "BusinessPager" ),
220// qDebug("QtopiaConverter::qtopiaToAddressee found:%s", dt.latin1()); 212 KABC::PhoneNumber::Work | KABC::PhoneNumber::Pager );
221 addr.insertCustom( "KADDRESSBOOK", "X-Anniversary", dt); 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 );
222 } 232 }
223 233
224 addr.insertCustom( "KADDRESSBOOK", "X-Children", contact.children() ); 234 KABC::PhoneNumber homePhoneNum( el.attribute( "HomePhone" ),
225 if (contact.birthday().isValid()) 235 KABC::PhoneNumber::Home );
226 addr.setBirthday( contact.birthday() ); 236 KABC::PhoneNumber homeFax( el.attribute( "HomeFax" ),
237 KABC::PhoneNumber::Home | KABC::PhoneNumber::Fax );
227 238
228 addr.setNickName( contact.nickname() ); 239 KABC::PhoneNumber homeMobile( el.attribute( "HomeMobile" ),
240 KABC::PhoneNumber::Cell );
229 241
230 // others 242 if ( !homePhoneNum.number().isEmpty() )
231 //US I put opies BusinessWebPage into Ka/Pi's notes block, because no other native field is available. 243 adr.insertPhoneNumber( homePhoneNum );
232 QString notes = contact.notes(); 244 if ( !homeFax.number().isEmpty() )
233 notes += "\nBusinessWebPage: " + contact.businessWebpage() + "\n"; 245 adr.insertPhoneNumber( homeFax );
246 if ( !homeMobile.number().isEmpty() )
247 adr.insertPhoneNumber( homeMobile );
234 248
235 addr.setNote( contact.notes() ); 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" ) );
236 255
256 if ( !business.isEmpty() )
257 adr.insertAddress( business );
237 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" ) );
238 265
239//US QString groups() const { return find( Qtopia::Groups ); } 266 if ( !home.isEmpty() )
240//US QStringList groupList() const; 267 adr.insertAddress( home );
241 268
242 QArray<int> catArray = contact.categories(); 269 adr.setNickName( el.attribute( "Nickname" ) );
243 QString cat; 270 adr.setNote( el.attribute( "Notes" ) );
244 271
245 for ( unsigned int i=0; i < catArray.size(); i++ ) { 272 {
246 cat = catDB->label("contact", catArray[i]); 273 QStringList categories = QStringList::split(";", el.attribute("Categories" ) );
247 if ( cat.isEmpty() ) 274 QString cat;
248 addr.insertCategory(QString::number(catArray[i])); 275 QStringList added;
249 else 276 for ( uint i = 0; i < categories.count(); i++ ) {
250 addr.insertCategory( cat ); 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 }
251 } 286 }
252 287
253 return true; 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 );
254} 301}
255 302
256bool QtopiaConverter::addresseeToQtopia( const Addressee &addr, PimContact &contact ) 303 if ( !el.attribute( "Children" ).isEmpty() )
257{ 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") );
258 313
259 314
315 }
316 return true;
317}
260 318
261 // name 319bool QtopiaConverter::addresseeToQtopia( const Addressee &ab, QTextStream *stream )
262 contact.setLastName(addr.familyName()); 320{
263 contact.setFirstName(addr.givenName()); 321 *stream << "<Contact ";
264 contact.setMiddleName(addr.additionalName()); 322 *stream << "FirstName=\"" << escape(ab.givenName()) << "\" ";
265 contact.setNameTitle(addr.prefix()); 323 *stream << "MiddleName=\"" << escape(ab.additionalName()) << "\" ";
266 contact.setSuffix(addr.suffix()); 324 *stream << "LastName=\"" << escape(ab.familyName()) << "\" ";
267 contact.setFileAs(); 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 }
268 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() ) ) << "\" ";
269 391
270 // email 392 /*
271 QStringList emails = addr.emails(); 393 * Anniversary block again
272 for ( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { 394 * Go from ISO -> QDate -> toString and then escape
273 contact.insertEmail(*it); 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 }
274 } 402 }
275 contact.setDefaultEmail( addr.preferredEmail() ); 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") << "\" ";
276 407
408 QString uid = ab.uid();
409 *stream << "Uid=\"" << uid << "\" ";
410 //*stream << map.toString( "addressbook", uid );
411 *stream << " />" << "\n";
277 412
278 // home 413 return true;
279 const Address homeaddress = addr.address(Address::Home);
280 if (!homeaddress.isEmpty()) {
281 contact.setHomeStreet(homeaddress.street());
282 contact.setHomeCity(homeaddress.locality());
283 contact.setHomeState(homeaddress.region());
284 contact.setHomeZip(homeaddress.postalCode());
285 contact.setHomeCountry(homeaddress.country());
286 } 414 }
287 415
288 PhoneNumber homephone = addr.phoneNumber( PhoneNumber::Home );
289 if (!homephone.number().isEmpty())
290 contact.setHomePhone(homephone.number());
291
292 PhoneNumber homefax = addr.phoneNumber( PhoneNumber::Home | PhoneNumber::Fax );
293 if (!homefax.number().isEmpty())
294 contact.setHomeFax(homefax.number());
295 416
296 PhoneNumber homemobile = addr.phoneNumber( PhoneNumber::Home | PhoneNumber::Cell ); 417#if 0
297 if (!homemobile.number().isEmpty())
298 contact.setHomeMobile(homemobile.number());
299 418
300 contact.setHomeWebpage(addr.url().url()); 419KTempFile* AddressBook::fromKDE( KSync::AddressBookSyncee *syncee, ExtraMap& map )
420{
301 421
422}
302 423
303 // business 424QStringList AddressBook::attributes()const {
304 const Address businessaddress = addr.address(Address::Work); 425 QStringList lst;
305 if (!businessaddress.isEmpty()) { 426 lst << "FirstName";
306 contact.setBusinessStreet(businessaddress.street()); 427 lst << "MiddleName";
307 contact.setBusinessCity(businessaddress.locality()); 428 lst << "LastName";
308 contact.setBusinessState(businessaddress.region()); 429 lst << "Suffix";
309 contact.setBusinessZip(businessaddress.postalCode()); 430 lst << "FileAs";
310 contact.setBusinessCountry(businessaddress.country()); 431 lst << "JobTitle";
432 lst << "Department";
433 lst << "Company";
434 lst << "BusinessPhone";
435 lst << "BusinessFax";
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;
311 } 468 }
312 469
313 PhoneNumber businessphone = addr.phoneNumber( PhoneNumber::Work );
314 if (!businessphone.number().isEmpty())
315 contact.setBusinessPhone(businessphone.number());
316 470
317 PhoneNumber businessfax = addr.phoneNumber( PhoneNumber::Work | PhoneNumber::Fax );
318 if (!businessfax.number().isEmpty())
319 contact.setBusinessFax(businessfax.number());
320 471
321 PhoneNumber businessmobile = addr.phoneNumber( PhoneNumber::Work | PhoneNumber::Cell ); 472#endif
322 if (!businessmobile.number().isEmpty())
323 contact.setBusinessMobile(businessmobile.number());
324 473
325 PhoneNumber businesspager = addr.phoneNumber( PhoneNumber::Work | PhoneNumber::Pager );
326 if (!businesspager.number().isEmpty())
327 contact.setBusinessPager(businesspager.number());
328 474
329 contact.setJobTitle(addr.role()); 475CategoryEdit::CategoryEdit(){
330 contact.setCompany(addr.organization()); 476}
477CategoryEdit::CategoryEdit(const QString &fileName){
478 parse( fileName );
479}
480CategoryEdit::~CategoryEdit(){
481}
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() ) << "\" ";
331 495
332 contact.setProfession(addr.custom( "KADDRESSBOOK", "X-Profession" )); 496 if ( !(*it).app().isEmpty() )
333 contact.setAssistant(addr.custom( "KADDRESSBOOK", "X-AssistantsName" )); 497 stream << " app=\""<< ( (*it).app() ) << "\" ";
334 contact.setDepartment(addr.custom( "KADDRESSBOOK", "X-Department" ));
335 contact.setManager(addr.custom( "KADDRESSBOOK", "X-ManagersName" ));
336 contact.setOffice(addr.custom( "KADDRESSBOOK", "X-Office" ));
337 498
338 //personal 499 stream << "name=\"" << ( (*it).name() ) << "\" ";
339 contact.setSpouse(addr.custom( "KADDRESSBOOK", "X-Spouse" )); 500 stream << " />" << endl;
340 // qtopia uses this categorization: 501 }
341 // enum GenderType { UnspecifiedGender=0, Male, Female }; 502 stream << "</Categories>" << endl;
342 QString gt = addr.custom( "KADDRESSBOOK", "X-Gender" ); 503 file.close();
343 if (gt = "male") 504 }
344 contact.setGender(PimContact::Male); 505}
345 else if (gt = "female") 506int CategoryEdit::addCategory( const QString &name, int id ){
346 contact.setGender(PimContact::Female); 507 return addCategory( QString::null, name, id );
347 else 508}
348 contact.setGender(PimContact::UnspecifiedGender); 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();
349 535
536 QDomDocument doc( "mydocument" );
537 QFile f( tempFile );
538 if ( !f.open( IO_ReadOnly ) )
539 return;
350 540
351 QDate dt = KGlobal::locale()->readDate( 541 if ( !doc.setContent( &f ) ) {
352 addr.custom("KADDRESSBOOK", "X-Anniversary" ), "%Y-%m-%d"); // = Qt::ISODate 542 f.close();
353 contact.setAnniversary( dt ); 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");
354 560
355 contact.setChildren(addr.custom( "KADDRESSBOOK", "X-Children" )); 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 );
356 570
357 contact.setBirthday(addr.birthday().date()); 571 OpieCategories category( id, name, app );
358 contact.setNickname(addr.nickName()); 572 m_categories.append( category ); // cheater
573 }
574 n = n.nextSibling();
575 }
576 }
577 updateKDE( "kaddressbookrc", global + contact );
578 updateKDE( "korganizerrc", global + organizer );
579
580}
581void CategoryEdit::clear()
582{
583 ids.clear();
584 m_categories.clear();
585}
586QString CategoryEdit::categoryById( const QString &id, const QString &app )const
587{
588 QValueList<OpieCategories>::ConstIterator it;
589 QString category;
590 QString fallback;
591 for( it = m_categories.begin(); it != m_categories.end(); ++it ){
592 if( id.stripWhiteSpace() == (*it).id().stripWhiteSpace() ){
593 if( app == (*it).app() ){
594 category = (*it).name();
595 break;
596 }else{
597 fallback = (*it).name();
598 }
599 }
600 }
601 return category.isEmpty() ? fallback : category;
602}
603QStringList CategoryEdit::categoriesByIds( const QStringList& ids,
604 const QString& app) {
605
606 QStringList list;
607 QStringList::ConstIterator it;
608 QString temp;
609 for ( it = ids.begin(); it != ids.end(); ++it ) {
610 temp = categoryById( (*it), app );
611 if (!temp.isEmpty() )
612 list << temp;
613 }
359 614
360 // other 615 return list;
361 contact.setNotes(addr.note()); 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}
362 627
363//US QString groups() const { return find( Qtopia::Groups ); }
364//US QStringList groupList() const;
365 628
366 629
367 QStringList cats = addr.categories(); 630OpieCategories::OpieCategories()
631{
368 632
369 QArray<int> iar;
370 if ( !cats.isEmpty() ) {
371 QArray<int> iar = catDB->ids("contact", cats);
372 contact.setCategories(iar);
373 } 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}
663
374 664
665bool operator== (const OpieCategories& a, const OpieCategories &b )
666{
667 if ( a.id() == b.id() && a.name() == b.name() && a.app() == b.app() )
375 return true; 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;