kaddressbook Library API Documentation

gnokii_xxport.cpp

00001 /* 00002 This file is part of KAddressbook. 00003 Copyright (c) 2003 Helge Deller <deller@kde.org> 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 00019 As a special exception, permission is given to link this program 00020 with any edition of Qt, and distribute the resulting executable, 00021 without including the source code for Qt in the source distribution. 00022 */ 00023 00024 /* 00025 Description: 00026 This filter allows you to import and export the KDE addressbook entries 00027 to/from a mobile phone, which is accessible via gnokii. 00028 Gnokii homepage: http://www.gnokii.org 00029 00030 TODO: 00031 - modal mode (show dialog during up/download) 00032 - handle callergroup value (Friend, VIP, Family, ...) better 00033 - we do not yet write back to SIM memory (for security reasons) 00034 */ 00035 00036 #include "config.h" 00037 00038 #include <kdebug.h> 00039 #include <klocale.h> 00040 #include <kmessagebox.h> 00041 00042 #ifdef HAVE_GNOKII_H 00043 extern "C" { 00044 #include <gnokii.h> 00045 } 00046 #endif 00047 00048 #include "gnokii_xxport.h" 00049 00050 #define APP "GNOKII_XXPORT" 00051 00052 #if 1 // !defined(NDEBUG) 00053 #define GNOKII_DEBUG(x) do { kdWarning() << (x); } while (0) 00054 #else 00055 #define GNOKII_DEBUG(x) do { } while (0) 00056 #endif 00057 #define GNOKII_CHECK_ERROR(error) \ 00058 do { \ 00059 if (error) \ 00060 kdError() << QString("ERROR %1: %2\n").arg(error).arg(gn_error_print(error));\ 00061 } while (0) 00062 00063 00064 class GNOKIIXXPortFactory : public KAB::XXPortFactory 00065 { 00066 public: 00067 KAB::XXPort *xxportObject( KABC::AddressBook *ab, QWidget *parent, const char *name ) 00068 { 00069 return new GNOKIIXXPort( ab, parent, name ); 00070 } 00071 }; 00072 00073 extern "C" 00074 { 00075 void *init_libkaddrbk_gnokii_xxport() 00076 { 00077 return ( new GNOKIIXXPortFactory() ); 00078 } 00079 } 00080 00081 00082 GNOKIIXXPort::GNOKIIXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name ) 00083 : KAB::XXPort( ab, parent, name ) 00084 { 00085 createImportAction( i18n( "Import From Nokia Mobile Phone..." ) ); 00086 createExportAction( i18n( "Export to Nokia Mobile Phone..." ) ); 00087 } 00088 00089 /* import */ 00090 00091 #ifdef HAVE_GNOKII_H 00092 static char *BinDir; 00093 static char *lockfile = NULL; 00094 static char model[GN_MODEL_MAX_LENGTH+1], revision[GN_REVISION_MAX_LENGTH+1], imei[GN_IMEI_MAX_LENGTH+1]; 00095 static QString PhoneProductId; 00096 00097 static struct gn_statemachine state; 00098 static gn_data data; 00099 00100 static void busterminate(void) 00101 { 00102 gn_sm_functions(GN_OP_Terminate, NULL, &state); 00103 if (lockfile) gn_device_unlock(lockfile); 00104 } 00105 00106 static QString businit(void) 00107 { 00108 gn_error error; 00109 char *aux; 00110 00111 if (gn_cfg_read(&BinDir)<0 || !gn_cfg_phone_load("", &state)) 00112 return i18n("GNOKII isn't yet configured."); 00113 00114 gn_data_clear(&data); 00115 00116 aux = gn_cfg_get(gn_cfg_info, "global", "use_locking"); 00117 // Defaults to 'no' 00118 if (aux && !strcmp(aux, "yes")) { 00119 lockfile = gn_device_lock(state.config.port_device); 00120 if (lockfile == NULL) { 00121 return i18n("Lock file error.\n " 00122 "Please exit all other running instances of gnokii and try again."); 00123 } 00124 } 00125 00126 // Initialise the code for the GSM interface. 00127 int old_dcd = state.config.require_dcd; // work-around for older gnokii versions 00128 state.config.require_dcd = false; 00129 error = gn_gsm_initialise(&state); 00130 GNOKII_CHECK_ERROR(error); 00131 state.config.require_dcd = old_dcd; 00132 if (error != GN_ERR_NONE) { 00133 busterminate(); 00134 return i18n("Mobile phone interface initialization failed:\n%1").arg(gn_error_print(error)); 00135 } 00136 00137 // model 00138 gn_data_clear(&data); 00139 data.model = model; 00140 model[0] = 0; 00141 error = gn_sm_functions(GN_OP_GetModel, &data, &state); 00142 GNOKII_CHECK_ERROR(error); 00143 if (model[0] == 0) 00144 strcpy(model, i18n("unknown").utf8()); 00145 data.model = NULL; 00146 00147 // revision 00148 data.revision = revision; 00149 revision[0] = 0; 00150 error = gn_sm_functions(GN_OP_GetRevision, &data, &state); 00151 GNOKII_CHECK_ERROR(error); 00152 data.revision = NULL; 00153 00154 // imei 00155 data.imei = imei; 00156 imei[0] = 0; 00157 error = gn_sm_functions(GN_OP_GetImei, &data, &state); 00158 GNOKII_CHECK_ERROR(error); 00159 data.imei = NULL; 00160 00161 GNOKII_DEBUG( QString("Found mobile phone: Model: %1, Revision: %2, IMEI: %3\n") 00162 .arg(model).arg(revision).arg(imei) ); 00163 00164 PhoneProductId = QString("%1-%2-%3-%4").arg(APP).arg(model).arg(revision).arg(imei); 00165 00166 return QString::null; 00167 } 00168 00169 00170 // get number of entries in this phone memory type (internal/SIM-card) 00171 static gn_error read_phone_memstat( gn_memory_type memtype, gn_memory_status *memstat ) 00172 { 00173 gn_error error; 00174 00175 gn_data_clear(&data); 00176 memset(memstat, 0, sizeof(*memstat)); 00177 memstat->memory_type = memtype; 00178 data.memory_status = memstat; 00179 error = gn_sm_functions(GN_OP_GetMemoryStatus, &data, &state); 00180 GNOKII_CHECK_ERROR(error); 00181 if (error != GN_ERR_NONE) { 00182 switch (memtype) { 00183 case GN_MT_SM: 00184 // use at least 100 entries 00185 memstat->used = 0; 00186 memstat->free = 100; 00187 break; 00188 default: 00189 case GN_MT_ME: 00190 // Phone doesn't support ME (5110) 00191 memstat->used = memstat->free = 0; 00192 break; 00193 } 00194 } 00195 GNOKII_DEBUG( QString("\n\nMobile phone memory status: Type: %1, used=%2, free=%3, total=%4\n\n") 00196 .arg(memtype).arg(memstat->used).arg(memstat->free).arg(memstat->used+memstat->free) ); 00197 return error; 00198 } 00199 00200 00201 // read phone entry #index from memory #memtype 00202 static gn_error read_phone_entry( int index, gn_memory_type memtype, gn_phonebook_entry *entry ) 00203 { 00204 gn_error error; 00205 entry->memory_type = memtype; 00206 entry->location = index; 00207 data.phonebook_entry = entry; 00208 error = gn_sm_functions(GN_OP_ReadPhonebook, &data, &state); 00209 GNOKII_CHECK_ERROR(error); 00210 return error; 00211 } 00212 00213 static bool phone_entry_empty( int index, gn_memory_type memtype ) 00214 { 00215 gn_phonebook_entry entry; 00216 gn_error error; 00217 error = read_phone_entry( index, memtype, &entry ); 00218 if (error == GN_ERR_EMPTYLOCATION) 00219 return true; 00220 if (error == GN_ERR_NONE && entry.empty) 00221 return true; 00222 return false; 00223 } 00224 00225 // read and evaluate all phone entries 00226 static gn_error read_phone_entries( const char *memtypestr, gn_memory_type memtype, KABC::AddresseeList *addrList ) 00227 { 00228 gn_error error; 00229 00230 // get number of entries in this phone memory type (internal/SIM-card) 00231 gn_memory_status memstat; 00232 error = read_phone_memstat(memtype, &memstat); 00233 00234 gn_phonebook_entry entry; 00235 QStringList addrlist; 00236 KABC::Address *addr; 00237 QString s, country; 00238 00239 int num_read = 0; 00240 00241 for (int i = 1; i <= (memstat.used + memstat.free); i++) { 00242 error = read_phone_entry( i, memtype, &entry ); 00243 00244 if (error == GN_ERR_EMPTYLOCATION) 00245 continue; 00246 if (error == GN_ERR_INVALIDLOCATION) 00247 break; 00248 if (error == GN_ERR_INVALIDMEMORYTYPE) 00249 break; 00250 if (error == GN_ERR_NONE) { 00251 GNOKII_DEBUG(QString("%1: %2, num=%3, location=%4, group=%5, count=%6\n").arg(i).arg(entry.name) 00252 .arg(entry.number).arg(entry.location).arg(entry.caller_group).arg(entry.subentries_count)); 00253 KABC::Addressee *a = new KABC::Addressee(); 00254 00255 // try to split Name into FamilyName and GivenName 00256 s = QString(entry.name).simplifyWhiteSpace(); 00257 if (s.find(',')!=-1) { 00258 addrlist = QStringList::split(',', s); 00259 if (addrlist.count()==2) { 00260 a->setFamilyName(addrlist[0]); 00261 a->setGivenName(addrlist[1]); 00262 } else 00263 a->setGivenName(s); 00264 } else { 00265 addrlist = QStringList::split(' ', s); 00266 if (addrlist.count()>=2) { 00267 a->setFamilyName(addrlist[0]); 00268 addrlist.remove(addrlist.first()); 00269 a->setGivenName(addrlist.join(" ")); 00270 } else 00271 a->setGivenName(s); 00272 } 00273 00274 a->insertCustom(APP, "X_GSM_CALLERGROUP", s.setNum(entry.caller_group)); 00275 a->insertCustom(APP, "X_GSM_STORE_AT", QString("%1%2").arg(memtypestr).arg(entry.location)); 00276 00277 // set ProductId 00278 a->setProductId(PhoneProductId); 00279 00280 // evaluate timestamp (ignore timezone) 00281 QDateTime datetime; 00282 if (entry.date.year<1998) 00283 datetime = QDateTime::currentDateTime(); 00284 else 00285 datetime = QDateTime( QDate(entry.date.year, entry.date.month, entry.date.day), 00286 QTime(entry.date.hour, entry.date.minute, entry.date.second) ); 00287 GNOKII_DEBUG(QString(" date=%1\n").arg(datetime.toString())); 00288 a->setRevision(datetime); 00289 00290 if (!entry.subentries_count) 00291 a->insertPhoneNumber(KABC::PhoneNumber(entry.number, KABC::PhoneNumber::Work | KABC::PhoneNumber::Pref)); 00292 00293 /* scan sub-entries */ 00294 if (entry.subentries_count) 00295 for (int n=0; n<entry.subentries_count; n++) { 00296 QString s = QString(entry.subentries[n].data.number).simplifyWhiteSpace(); 00297 GNOKII_DEBUG(QString(" Subentry#%1, entry_type=%2, number_type=%3, number=%4\n") 00298 .arg(n).arg(entry.subentries[n].entry_type) 00299 .arg(entry.subentries[n].number_type).arg(s)); 00300 if (s.isEmpty()) 00301 continue; 00302 switch(entry.subentries[n].entry_type) { 00303 case GN_PHONEBOOK_ENTRY_Name: 00304 a->setName(s); 00305 break; 00306 case GN_PHONEBOOK_ENTRY_Email: 00307 a->insertEmail(s); 00308 break; 00309 case GN_PHONEBOOK_ENTRY_Postal: 00310 s = s.simplifyWhiteSpace(); 00311 addrlist = QStringList::split(';', s, true); 00312 addr = new KABC::Address(KABC::Address::Work); 00313 if (addrlist.count() <= 1 ) { 00314 addr->setExtended(s); 00315 } else { 00316 addr->setPostOfficeBox(addrlist[0]); 00317 addr->setExtended(addrlist[1]); 00318 addr->setStreet(addrlist[2]); 00319 addr->setLocality(addrlist[3]); 00320 addr->setRegion(addrlist[4]); 00321 addr->setPostalCode(addrlist[5]); 00322 country = addrlist[6]; 00323 if (!country.isEmpty()) 00324 addr->setCountry(i18n(country.utf8())); 00325 } 00326 a->insertAddress(*addr); 00327 delete addr; 00328 break; 00329 case GN_PHONEBOOK_ENTRY_Note: 00330 if (!a->note().isEmpty()) 00331 s = "\n" + s; 00332 a->setNote(a->note()+s); 00333 break; 00334 case GN_PHONEBOOK_ENTRY_Number: 00335 enum KABC::PhoneNumber::Types phonetype; 00336 switch (entry.subentries[n].number_type) { 00337 case GN_PHONEBOOK_NUMBER_Mobile: phonetype = KABC::PhoneNumber::Cell; break; 00338 case GN_PHONEBOOK_NUMBER_Fax: phonetype = KABC::PhoneNumber::Fax; break; 00339 case GN_PHONEBOOK_NUMBER_General: 00340 case GN_PHONEBOOK_NUMBER_Work: phonetype = KABC::PhoneNumber::Work; break; 00341 default: 00342 case GN_PHONEBOOK_NUMBER_Home: phonetype = KABC::PhoneNumber::Home; break; 00343 } 00344 //if (s == entry.number) 00345 // type = (KABC::PhoneNumber::Types) (phonetype | KABC::PhoneNumber::Pref); 00346 a->insertPhoneNumber(KABC::PhoneNumber(s, phonetype)); 00347 break; 00348 case GN_PHONEBOOK_ENTRY_URL: 00349 a->setUrl(s); 00350 break; 00351 case GN_PHONEBOOK_ENTRY_Group: 00352 a->insertCategory(s); 00353 break; 00354 default: 00355 GNOKII_DEBUG(QString(" Not handled id=%1, entry=%2\n") 00356 .arg(entry.subentries[n].entry_type).arg(s)); 00357 break; 00358 } // switch() 00359 } // if(subentry) 00360 00361 // add only if entry was valid 00362 if (strlen(entry.name) || strlen(entry.number) || entry.subentries_count) 00363 addrList->append(*a); 00364 00365 // did we read all valid phonebook-entries ? 00366 num_read++; 00367 delete a; 00368 if (num_read >= memstat.used) 00369 break; // yes, all were read 00370 else 00371 continue; // no, we are still missing some. 00372 } 00373 GNOKII_CHECK_ERROR(error); 00374 } 00375 00376 return GN_ERR_NONE; 00377 } 00378 #endif 00379 00380 00381 00382 KABC::AddresseeList GNOKIIXXPort::importContacts( const QString& ) const 00383 { 00384 KABC::AddresseeList addrList; 00385 00386 #ifndef HAVE_GNOKII_H 00387 00388 KMessageBox::error(parentWidget(), i18n("Gnokii interface is not available.\n" 00389 "Please ask your distributor to add gnokii during compile time.")); 00390 00391 #else 00392 00393 QString errStr = businit(); 00394 if (!errStr.isEmpty()) { 00395 KMessageBox::error(parentWidget(), errStr); 00396 return addrList; 00397 } 00398 00399 GNOKII_DEBUG("GNOKII import filter started.\n"); 00400 00401 read_phone_entries("ME", GN_MT_ME, &addrList); // internal phone memory 00402 read_phone_entries("SM", GN_MT_SM, &addrList); // SIM card 00403 00404 GNOKII_DEBUG("GNOKII import filter finished.\n"); 00405 00406 busterminate(); 00407 00408 #endif 00409 00410 return addrList; 00411 } 00412 00413 00414 // export to phone 00415 00416 #ifdef HAVE_GNOKII_H 00417 00418 static QString makeValidPhone( const QString &number ) 00419 { 00420 // allowed chars: 0-9, *, #, p, w, + 00421 QString num = number.simplifyWhiteSpace(); 00422 QString allowed("+0123456789*#pw"); 00423 for (unsigned int i=num.length(); i>=1; i--) 00424 if (allowed.find(num[i-1])==-1) 00425 num.remove(i-1,1); 00426 if (num.isEmpty()) 00427 num = "0"; 00428 return num; 00429 } 00430 00431 static gn_error xxport_phone_write_entry( int phone_location, gn_memory_type memtype, 00432 const KABC::Addressee *addr) 00433 { 00434 gn_phonebook_entry entry; 00435 QString s; 00436 00437 memset(&entry, 0, sizeof(entry)); 00438 strncpy(entry.name, addr->realName().latin1(), sizeof(entry.name)-1); 00439 s = addr->phoneNumber(KABC::PhoneNumber::Pref).number(); 00440 if (s.isEmpty()) 00441 s = addr->phoneNumber(KABC::PhoneNumber::Work).number(); 00442 if (s.isEmpty()) 00443 s = addr->phoneNumber(KABC::PhoneNumber::Home).number(); 00444 if (s.isEmpty()) 00445 s = addr->phoneNumber(KABC::PhoneNumber::Cell).number(); 00446 if (s.isEmpty() && addr->phoneNumbers().count()>0) 00447 s = (*addr->phoneNumbers().at(0)).number(); 00448 s = makeValidPhone(s); 00449 strncpy(entry.number, s.latin1(), sizeof(entry.number)-1); 00450 entry.memory_type = memtype; 00451 QString cg = addr->custom(APP, "X_GSM_CALLERGROUP"); 00452 if (cg.isEmpty()) 00453 entry.caller_group = 5; // default group 00454 else 00455 entry.caller_group = cg.toInt(); 00456 entry.location = phone_location; 00457 00458 // set date/revision 00459 QDateTime datetime = addr->revision(); 00460 QDate date(datetime.date()); 00461 QTime time(datetime.time()); 00462 entry.date.year = date.year(); 00463 entry.date.month = date.month(); 00464 entry.date.day = date.day(); 00465 entry.date.hour = time.hour(); 00466 entry.date.minute = time.minute(); 00467 entry.date.second = time.second(); 00468 00469 GNOKII_DEBUG(QString("Write #%1: name=%2, number=%3\n").arg(phone_location) 00470 .arg(entry.name).arg(entry.number)); 00471 00472 const KABC::Address homeAddr = addr->address(KABC::Address::Home); 00473 const KABC::Address workAddr = addr->address(KABC::Address::Work); 00474 00475 entry.subentries_count = 0; 00476 gn_phonebook_subentry *subentry = &entry.subentries[0]; 00477 // add all phone numbers 00478 const KABC::PhoneNumber::List phoneList = addr->phoneNumbers(); 00479 KABC::PhoneNumber::List::ConstIterator it; 00480 for ( it = phoneList.begin(); it != phoneList.end(); ++it ) { 00481 const KABC::PhoneNumber *phonenumber = &(*it); 00482 s = phonenumber->number(); 00483 if (s.isEmpty()) continue; 00484 subentry->entry_type = GN_PHONEBOOK_ENTRY_Number; 00485 gn_phonebook_number_type type; 00486 switch (phonenumber->type() & ~KABC::PhoneNumber::Pref) { 00487 case KABC::PhoneNumber::Home: type = GN_PHONEBOOK_NUMBER_Home; break; 00488 case KABC::PhoneNumber::Voice: 00489 case KABC::PhoneNumber::Work: type = GN_PHONEBOOK_NUMBER_Work; break; 00490 case KABC::PhoneNumber::Pager: 00491 case KABC::PhoneNumber::Cell: type = GN_PHONEBOOK_NUMBER_Mobile; break; 00492 case KABC::PhoneNumber::Fax: type = GN_PHONEBOOK_NUMBER_Fax; break; 00493 default: type = GN_PHONEBOOK_NUMBER_General; break; 00494 } 00495 subentry->number_type = type; 00496 strncpy(subentry->data.number, makeValidPhone(s).latin1(), sizeof(subentry->data.number)-1); 00497 subentry->id = phone_location<<8+entry.subentries_count; 00498 entry.subentries_count++; 00499 subentry++; 00500 if (entry.subentries_count >= GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER) 00501 break; // Phonebook full 00502 } 00503 // add URL 00504 s = addr->url().prettyURL(); 00505 if (!s.isEmpty() && (entry.subentries_count<GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER)) { 00506 subentry->entry_type = GN_PHONEBOOK_ENTRY_URL; 00507 strncpy(subentry->data.number, s.latin1(), sizeof(subentry->data.number)-1); 00508 entry.subentries_count++; 00509 subentry++; 00510 } 00511 // add E-Mails 00512 QStringList emails = addr->emails(); 00513 for (unsigned int n=0; n<emails.count(); n++) { 00514 if (entry.subentries_count >= GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER) 00515 break; // Phonebook full 00516 s = emails[n].simplifyWhiteSpace(); 00517 if (s.isEmpty()) continue; 00518 subentry->entry_type = GN_PHONEBOOK_ENTRY_Email; 00519 strncpy(subentry->data.number, s.latin1(), sizeof(subentry->data.number)-1); 00520 entry.subentries_count++; 00521 subentry++; 00522 } 00523 // add Adresses 00524 const KABC::Address::List addresses = addr->addresses(); 00525 KABC::Address::List::ConstIterator it2; 00526 for ( it2 = addresses.begin(); it2 != addresses.end(); ++it2 ) { 00527 if (entry.subentries_count >= GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER) 00528 break; // Phonebook full 00529 const KABC::Address *Addr = &(*it2); 00530 if (Addr->isEmpty()) continue; 00531 subentry->entry_type = GN_PHONEBOOK_ENTRY_Postal; 00532 QStringList a; 00533 QChar sem(';'); 00534 QString sem_repl(QString::fromLatin1(",")); 00535 a.append( Addr->postOfficeBox().replace( sem, sem_repl ) ); 00536 a.append( Addr->extended() .replace( sem, sem_repl ) ); 00537 a.append( Addr->street() .replace( sem, sem_repl ) ); 00538 a.append( Addr->locality() .replace( sem, sem_repl ) ); 00539 a.append( Addr->region() .replace( sem, sem_repl ) ); 00540 a.append( Addr->postalCode() .replace( sem, sem_repl ) ); 00541 a.append( Addr->country() .replace( sem, sem_repl ) ); 00542 s = a.join(sem); 00543 strncpy(subentry->data.number, s.latin1(), sizeof(subentry->data.number)-1); 00544 entry.subentries_count++; 00545 subentry++; 00546 } 00547 // add Note 00548 s = addr->note().simplifyWhiteSpace(); 00549 if (!s.isEmpty() && (entry.subentries_count<GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER)) { 00550 subentry->entry_type = GN_PHONEBOOK_ENTRY_Note; 00551 strncpy(subentry->data.number, s.latin1(), sizeof(subentry->data.number)-1); 00552 entry.subentries_count++; 00553 subentry++; 00554 } 00555 00556 // debug output 00557 for (int st=0; st<entry.subentries_count; st++) { 00558 gn_phonebook_subentry *subentry = &entry.subentries[st]; 00559 GNOKII_DEBUG(QString(" SubTel #%1: entry_type=%2, number_type=%3, number=%4\n") 00560 .arg(st).arg(subentry->entry_type) 00561 .arg(subentry->number_type).arg(subentry->data.number)); 00562 } 00563 00564 data.phonebook_entry = &entry; 00565 gn_error error = gn_sm_functions(GN_OP_WritePhonebook, &data, &state); 00566 GNOKII_CHECK_ERROR(error); 00567 00568 return error; 00569 } 00570 00571 00572 static gn_error xxport_phone_delete_entry( int phone_location, gn_memory_type memtype ) 00573 { 00574 gn_phonebook_entry entry; 00575 memset(&entry, 0, sizeof(entry)); 00576 entry.empty = 1; 00577 entry.memory_type = memtype; 00578 entry.location = phone_location; 00579 data.phonebook_entry = &entry; 00580 GNOKII_DEBUG(QString("Deleting entry %1\n").arg(phone_location)); 00581 gn_error error = gn_sm_functions(GN_OP_WritePhonebook, &data, &state); 00582 GNOKII_CHECK_ERROR(error); 00583 return error; 00584 } 00585 00586 #endif 00587 00588 bool GNOKIIXXPort::exportContacts( const KABC::AddresseeList &list, const QString & ) 00589 { 00590 #ifndef HAVE_GNOKII_H 00591 00592 Q_UNUSED(list); 00593 KMessageBox::error(parentWidget(), i18n("Gnokii interface is not available.\n" 00594 "Please ask your distributor to add gnokii during compile time.")); 00595 00596 #else 00597 00598 KABC::AddresseeList::ConstIterator it; 00599 00600 gn_error error; 00601 00602 QString errStr = businit(); 00603 if (!errStr.isEmpty()) { 00604 KMessageBox::error(parentWidget(), errStr); 00605 return false; 00606 } 00607 00608 GNOKII_DEBUG("GNOKII export filter started.\n"); 00609 00610 gn_memory_type memtype = GN_MT_ME; // internal phone memory 00611 00612 int phone_count; // num entries in phone 00613 bool overwrite_phone_entries = false; 00614 int phone_entry_no; 00615 bool entry_empty; 00616 00617 // get number of entries in this phone memory 00618 gn_memory_status memstat; 00619 error = read_phone_memstat(memtype, &memstat); 00620 if (error == GN_ERR_NONE) { 00621 GNOKII_DEBUG("Writing to internal phone memory.\n"); 00622 } else { 00623 memtype = GN_MT_SM; // try SIM card instead 00624 error = read_phone_memstat(memtype, &memstat); 00625 if (error != GN_ERR_NONE) 00626 goto finish; 00627 GNOKII_DEBUG("Writing to SIM card memory.\n"); 00628 } 00629 phone_count = memstat.used; 00630 00631 if (memstat.free >= (int) list.count()) { 00632 if (KMessageBox::No == KMessageBox::questionYesNo(parentWidget(), 00633 i18n("The selected phonebook entries can either be added to the mobile phonebook or they " 00634 "can replace existing phonebook entries.\n\n" 00635 "Do you want to just add the new entries ?"), 00636 i18n("Export to mobile phone") ) ) 00637 overwrite_phone_entries = true; 00638 } 00639 00640 if (overwrite_phone_entries) { 00641 if (KMessageBox::Continue != KMessageBox::warningContinueCancel(parentWidget(), 00642 i18n("During the export now all your existing phonebook entries in the mobile phone " 00643 "will be deleted and replaced with the new entries.\n" 00644 "Do you really want to continue ?"), 00645 i18n("Export to mobile phone") ) ) 00646 goto finish; 00647 } 00648 00649 // Now run the loop... 00650 phone_entry_no = 1; 00651 for ( it = list.begin(); it != list.end(); ++it ) { 00652 const KABC::Addressee *addr = &(*it); 00653 if (addr->isEmpty()) 00654 continue; 00655 // don't write back SIM-card entries ! 00656 if (addr->custom(APP, "X_GSM_STORE_AT").startsWith("SM")) 00657 continue; 00658 00659 try_next_phone_entry: 00660 // End of phone memory reached ? 00661 if (phone_entry_no > (memstat.used + memstat.free)) 00662 break; 00663 00664 GNOKII_DEBUG(QString("Try to write entry '%1' at phone_entry_no=%2, phone_count=%3\n") 00665 .arg(addr->realName()).arg(phone_entry_no).arg(phone_count)); 00666 00667 error = GN_ERR_NONE; 00668 00669 // is this phone entry empty ? 00670 entry_empty = phone_entry_empty(phone_entry_no, memtype); 00671 if (overwrite_phone_entries) { 00672 // overwrite this phonebook entry ... 00673 if (!entry_empty) 00674 phone_count--; 00675 error = xxport_phone_write_entry( phone_entry_no, memtype, addr); 00676 phone_entry_no++; 00677 } else { 00678 // add this phonebook entry if possible ... 00679 if (entry_empty) { 00680 error = xxport_phone_write_entry( phone_entry_no, memtype, addr); 00681 phone_entry_no++; 00682 } else { 00683 phone_entry_no++; 00684 goto try_next_phone_entry; 00685 } 00686 } 00687 00688 // break if we got an error on the first entry 00689 if (error != GN_ERR_NONE && it==list.begin()) 00690 break; 00691 00692 } // for() 00693 00694 // if we wanted to overwrite all entries, make sure, that we also 00695 // delete all remaining entries in the mobile phone. 00696 while (overwrite_phone_entries && error==GN_ERR_NONE && phone_count>0) { 00697 if (phone_entry_no > (memstat.used + memstat.free)) 00698 break; 00699 entry_empty = phone_entry_empty(phone_entry_no, memtype); 00700 if (!entry_empty) { 00701 error = xxport_phone_delete_entry(phone_entry_no, memtype); 00702 phone_count--; 00703 } 00704 phone_entry_no++; 00705 } 00706 00707 finish: 00708 GNOKII_DEBUG("GNOKII export filter finished.\n"); 00709 00710 busterminate(); 00711 00712 #endif 00713 00714 return true; 00715 } 00716 00717 #include "gnokii_xxport.moc" 00718 /* vim: set sts=4 ts=4 sw=4: */ 00719
KDE Logo
This file is part of the documentation for kaddressbook Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:58:08 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003