00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#include <qlabel.h>
00026
#include <qlistview.h>
00027
#include <qfile.h>
00028
#include <qtextstream.h>
00029
#include <qmessagebox.h>
00030
00031
#include <kdebug.h>
00032
#include <kfiledialog.h>
00033
#include <kmessagebox.h>
00034
#include <klocale.h>
00035
#include <kapplication.h>
00036
00037
#include <kabc/stdaddressbook.h>
00038
00039
#include "atcommand.h"
00040
#include "commandscheduler.h"
00041
00042
#include "mobilegui.h"
00043
#include "mobilegui.moc"
00044
00045
class SyncEntry {
00046
public:
00047 SyncEntry() { mOn =
true; }
00048
00049
bool mOn;
00050 };
00051
00052
class SyncEntryKab :
public SyncEntry {
00053
public:
00054 SyncEntryKab(
bool on,
const QString &index,
const QString &name,
00055
const QString &type,
const QString &phone,
const QString &phonetype)
00056 {
00057 mOn = on;
00058 mIndex = index;
00059 mName = name;
00060 mType = type;
00061 mPhone = phone;
00062 mPhonetype = phonetype;
00063 }
00064
00065
QString mIndex;
00066
QString mName;
00067
QString mType;
00068
QString mPhone;
00069
QString mPhonetype;
00070
00071 KABC::Addressee mAddressee;
00072 };
00073
00074
class SyncEntryMobile :
public SyncEntry {
00075
public:
00076 SyncEntryMobile(
bool on,
const QString &index,
const QString &phone,
00077
const QString &type,
const QString &name)
00078 {
00079 mOn = on;
00080 mIndex = index;
00081 mName = name;
00082 mType = type;
00083 mPhone = phone;
00084 }
00085
00086
QString mIndex;
00087
QString mName;
00088
QString mType;
00089
QString mPhone;
00090 };
00091
00092
class SyncEntryCommon :
public SyncEntry {
00093
public:
00094 SyncEntryCommon(
bool on,SyncEntryKab *kabEntry,SyncEntryMobile *mobileEntry)
00095 {
00096 mOn = on;
00097 mKabEntry = kabEntry;
00098 mMobileEntry = mobileEntry;
00099 }
00100
00101 SyncEntryKab *mKabEntry;
00102 SyncEntryMobile *mMobileEntry;
00103 };
00104
00105
class AddressSyncer {
00106
public:
00107 AddressSyncer()
00108 {
00109 mKabEntries.setAutoDelete(
true);
00110 mMobileEntries.setAutoDelete(
true);
00111 mCommonEntries.setAutoDelete(
true);
00112 }
00113
00114
QPtrList<SyncEntryKab> mKabEntries;
00115
QPtrList<SyncEntryMobile> mMobileEntries;
00116
QPtrList<SyncEntryCommon> mCommonEntries;
00117 };
00118
00119
00120
class PhoneBookItem :
public QCheckListItem {
00121
public:
00122 PhoneBookItem(
QListView *v) :
QCheckListItem(v,"",
QCheckListItem::CheckBox)
00123 {
00124 mSyncEntry = 0;
00125 }
00126 PhoneBookItem(
QListView *v,SyncEntry *syncEntry,
const QString &index,
00127
const QString &phone,
00128
const QString &type,
const QString &name) :
00129
QCheckListItem(v,index,
QCheckListItem::CheckBox)
00130 {
00131 mSyncEntry = syncEntry;
00132
00133 setText(1,phone);
00134 setText(2,type);
00135 setText(3,name);
00136 }
00137
00138
void setItem(
const QString &index,
const QString &phone,
00139
const QString &type,
const QString &name)
00140 {
00141 setText(0,index);
00142 setText(1,phone);
00143 setText(2,type);
00144 setText(3,name);
00145 }
00146
00147
void setIndex(
int i) { setText(0,QString::number(i)); }
00148
QString index() {
return text(0); }
00149
QString phone() {
return text(1); }
00150
QString type() {
return text(2); }
00151
QString name() {
return text(3); }
00152
00153 SyncEntry *syncEntry() {
return mSyncEntry; }
00154
00155
private:
00156 SyncEntry *mSyncEntry;
00157 };
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 MobileGui::MobileGui(CommandScheduler *scheduler,
QWidget* parent,
00168
const char* name,WFlags fl)
00169 : DCOPObject("KandyIface"),
00170 MobileGui_base(parent,name,fl)
00171 {
00172 mSyncing =
false;
00173 mScheduler = scheduler;
00174 mSyncer =
new AddressSyncer;
00175
00176 connect(mScheduler,SIGNAL(commandProcessed(
ATCommand *)),
00177 SLOT(processResult(
ATCommand *)));
00178 }
00179
00180 MobileGui::~MobileGui()
00181 {
00182
delete mSyncer;
00183 }
00184
00185
void MobileGui::exit()
00186 {
00187 kapp->quit();
00188 }
00189
00190
void MobileGui::readModelInformation()
00191 {
00192 mScheduler->executeId(
"+cgmi");
00193 mScheduler->executeId(
"+cgmm");
00194 mScheduler->executeId(
"+cgmr");
00195 mScheduler->executeId(
"+cgsn");
00196 }
00197
00198
void MobileGui::readPhonebook()
00199 {
00200 mScheduler->executeId(
"+cpbr=1,150");
00201
00202 emit statusMessage(i18n(
"Reading mobile phonebook..."));
00203 }
00204
00205
void MobileGui::writePhonebook()
00206 {
00207 kdDebug(5960) <<
"MobileGui::writePhonebook" << endl;
00208
00209
for(uint i=0;i<mSyncer->mMobileEntries.count();++i) {
00210 SyncEntryMobile *entry = mSyncer->mMobileEntries.at(i);
00211
00212
00213
00214
00215
QString id =
"+cpbw=" + entry->mIndex;
00216 mLastWriteId =
id;
00217
ATCommand *cmd =
new ATCommand(
id);
00218 cmd->
setAutoDelete(
true);
00219 cmd->
addParameter(
new ATParameter(quote(entry->mPhone)));
00220 cmd->
addParameter(
new ATParameter(entry->mType));
00221 cmd->
addParameter(
new ATParameter(quote(entry->mName)));
00222
00223 kdDebug(5960) <<
" " << cmd->
cmd() << endl;
00224 kdDebug(5960) <<
" id: " << cmd->
id() << endl;
00225
00226 mScheduler->execute(cmd);
00227 }
00228
00229 emit statusMessage(i18n(
"Writing mobile phonebook..."));
00230 }
00231
00232
void MobileGui::readKabc()
00233 {
00234 kdDebug(5960) <<
"MobileGui::readKabc()" << endl;
00235
00236 mSyncer->mKabEntries.clear();
00237
00238 KABC::AddressBook *addressBook = KABC::StdAddressBook::self();
00239
00240 KABC::AddressBook::Iterator it;
00241
for( it = addressBook->begin(); it != addressBook->end(); ++it ) {
00242
00243
QString index = (*it).custom(
"KANDY",
"Index");
00244
QString type = (*it).custom(
"KANDY",
"Type");
00245
QString name = (*it).custom(
"KANDY",
"Name");
00246
QString phonetype = (*it).custom(
"KANDY",
"Phonetype");
00247
00248
00249
00250 KABC::PhoneNumber phoneNumber;
00251
if ( phonetype.isEmpty() ) {
00252 KABC::PhoneNumber::List phoneNumbers = (*it).phoneNumbers();
00253 phoneNumber = phoneNumbers.first();
00254 }
else {
00255 phoneNumber = (*it).phoneNumber( phonetype.toInt() );
00256 }
00257
QString phone = phoneNumber.number();
00258
00259 SyncEntryKab *kabEntry;
00260
if (!index.isEmpty()) {
00261
00262 kabEntry =
new SyncEntryKab(
true,index,name,type,phone,phonetype);
00263 }
else {
00264
00265 index =
"";
00266 name = (*it).realName();
00267
if (phone.left(1) ==
"+") type =
"145";
00268
else type =
"129";
00269
00270 kabEntry =
new SyncEntryKab(
false,index,name,type,phone,phonetype);
00271 }
00272
00273 kabEntry->mAddressee = (*it);
00274
00275 mSyncer->mKabEntries.append(kabEntry);
00276 }
00277
00278
00279 updateKabBook();
00280
00281 emit transientStatusMessage(i18n(
"Read KDE address book."));
00282 }
00283
00284
void MobileGui::writeKabc()
00285 {
00286 kdDebug(5960) <<
"MobileGui::writeKabc()" << endl;
00287
00288 KABC::AddressBook *addressBook = KABC::StdAddressBook::self();
00289
00290 KABC::Ticket *ticket = addressBook->requestSaveTicket();
00291
00292
if ( !ticket ) {
00293 kdDebug(5960) <<
"Error! No ticket to save." << endl;
00294
return;
00295 }
00296
00297
for(uint i=0;i<mSyncer->mKabEntries.count();++i) {
00298 SyncEntryKab *kabEntry = mSyncer->mKabEntries.at(i);
00299
00300 KABC::Addressee entry = kabEntry->mAddressee;
00301
00302
QString name = kabEntry->mName;
00303
QString phonenumber = kabEntry->mPhone;
00304
QString index = kabEntry->mIndex;
00305
QString type = kabEntry->mType;
00306
00307 entry.insertCustom(
"KANDY",
"Index", index );
00308
00309 entry.setFormattedName( name );
00310
00311
00312
00313
int phoneType = 0;
00314
if (phonenumber.left(3) ==
"017" || phonenumber.left(6) ==
"+49017") {
00315 phoneType = KABC::PhoneNumber::Cell;
00316 }
00317 entry.insertPhoneNumber( KABC::PhoneNumber( phonenumber, phoneType ) );
00318 entry.insertCustom(
"KANDY",
"Phonetype", QString::number( phoneType ) );
00319
00320 entry.insertCustom(
"KANDY",
"Name", name );
00321 entry.insertCustom(
"KANDY",
"Type", type );
00322
00323 addressBook->insertAddressee( entry );
00324 }
00325
00326 addressBook->save( ticket );
00327
00328 emit transientStatusMessage(i18n(
"Wrote KDE address book"));
00329 }
00330
00331
void MobileGui::refreshStatus()
00332 {
00333 mScheduler->executeId(
"+cbc");
00334 mScheduler->executeId(
"+csq");
00335 }
00336
00337
void MobileGui::processResult(ATCommand *command)
00338 {
00339
if (command->
id() ==
"+cbc") {
00340 mBatteryChargeLabel->setText(command->
resultField(1) +
" %");
00341 }
else if (command->
id() ==
"+csq") {
00342 mSignalQualityLabel->setText(command->
resultField(0));
00343 }
else if (command->
id() ==
"+cgmi") {
00344 mManufacturerLabel->setText(command->
resultField(0));
00345 }
else if (command->
id() ==
"+cgmm") {
00346 mModelLabel->setText(command->
resultField(0));
00347 }
else if (command->
id() ==
"+cgmr") {
00348 mGSMVersionLabel->setText(command->
resultField(0));
00349 }
else if (command->
id() ==
"+cgsn") {
00350 mSerialNumberLabel->setText(command->
resultField(0));
00351 }
else if (command->
id() ==
"+cpbr=1,150") {
00352 fillPhonebook(command);
00353 }
else if (command->
id() == mLastWriteId) {
00354 mLastWriteId =
"";
00355 emit transientStatusMessage(i18n(
"Wrote mobile phonebook."));
00356 }
00357
if (command->
id() == mSyncReadId) {
00358 mSyncReadId =
"";
00359 mergePhonebooks();
00360 writeKabc();
00361 writePhonebook();
00362 mSyncWriteId = mLastWriteId;
00363 }
00364
if (command->
id() == mSyncWriteId) {
00365 mSyncWriteId =
"";
00366 emit transientStatusMessage(i18n(
"Synced phonebooks."));
00367 mSyncing =
false;
00368 }
00369 }
00370
00371
void MobileGui::fillPhonebook(ATCommand *cmd)
00372 {
00373 kdDebug(5960) <<
"MobileGui::fillPhonebook()" << endl;
00374
00375
00376
00377 mSyncer->mMobileEntries.clear();
00378
00379
QPtrList<QStringList> *list = cmd->
resultFields();
00380
00381
QStringList *fields = list->first();
00382
while(fields) {
00383
if (fields->count() != 4) {
00384 kdDebug(5960) <<
"Error! Unexpected number of address fields." << endl;
00385 }
else {
00386
QString index = (*fields)[0];
00387
QString phone = (*fields)[1];
00388
QString type = (*fields)[2];
00389
QString name = (*fields)[3];
00390 SyncEntryMobile *phoneEntry =
new SyncEntryMobile(
true,dequote(index),
00391 dequote(phone),dequote(type),dequote(name));
00392 mSyncer->mMobileEntries.append(phoneEntry);
00393 }
00394 fields = list->next();
00395 }
00396
00397
00398 updateMobileBook();
00399
00400 emit transientStatusMessage(i18n(
"Read mobile phonebook."));
00401
00402 emit phonebookRead();
00403 }
00404
00405
QString MobileGui::quote(
const QString &str)
00406 {
00407
if (str.left(1) ==
"\"" && str.right(1) ==
"\"")
return str;
00408
00409
return "\"" + str +
"\"";
00410 }
00411
00412
QString MobileGui::dequote(
const QString &str)
00413 {
00414
int pos = 0;
00415
int len = str.length();
00416
00417
if (str.left(1) ==
"\"") {
00418 ++pos;
00419 --len;
00420 }
00421
if (str.right(1) ==
"\"") {
00422 --len;
00423 }
00424
00425
return str.mid(pos,len);
00426 }
00427
00428
void MobileGui::savePhonebook()
00429 {
00430
QString fileName = KFileDialog::getSaveFileName(
"phonebook.csv");
00431
00432
QFile outFile(fileName);
00433
if ( outFile.open(IO_WriteOnly) ) {
00434
QTextStream t( &outFile );
00435
00436
for(uint i=0;i<mSyncer->mMobileEntries.count();++i) {
00437 SyncEntryMobile *e = mSyncer->mMobileEntries.at(i);
00438 t << e->mIndex <<
"," << e->mPhone <<
"," << e->mType <<
","
00439 << e->mName << endl;
00440 }
00441
00442 outFile.close();
00443 }
00444 }
00445
00446
void MobileGui::mergePhonebooks()
00447 {
00448 kdDebug(5960) <<
"MobileGui::mergePhonebooks()" << endl;
00449
00450
00451 PhoneBookItem *item = (PhoneBookItem *)mKabBook->firstChild();
00452
while(item) {
00453 item->syncEntry()->mOn = item->isOn();
00454 item = (PhoneBookItem *)item->nextSibling();
00455 }
00456 item = (PhoneBookItem *)mMobileBook->firstChild();
00457
while(item) {
00458 item->syncEntry()->mOn = item->isOn();
00459 item = (PhoneBookItem *)item->nextSibling();
00460 }
00461
00462 mSyncer->mCommonEntries.clear();
00463
00464
00465
00466
00467
for(uint i=0;i<mSyncer->mKabEntries.count();++i) {
00468
if (mSyncer->mKabEntries.at(i)->mOn) {
00469 mSyncer->mCommonEntries.append(
new SyncEntryCommon(
true,mSyncer->mKabEntries.at(i),0));
00470 }
00471 }
00472
00473
00474
00475
00476
for(uint i=0;i<mSyncer->mMobileEntries.count();++i) {
00477 SyncEntryMobile *mobileEntry = mSyncer->mMobileEntries.at(i);
00478
00479
00480 uint j=0;
00481
for(;j<mSyncer->mCommonEntries.count();++j) {
00482
if (mSyncer->mCommonEntries.at(j)->mKabEntry) {
00483
if (mSyncer->mCommonEntries.at(j)->mKabEntry->mIndex ==
00484 mobileEntry->mIndex) {
00485
00486 mSyncer->mCommonEntries.at(j)->mMobileEntry = mobileEntry;
00487
break;
00488 }
00489 }
00490 }
00491
if (j == mSyncer->mCommonEntries.count()) {
00492
if (mobileEntry->mOn) {
00493
00494 mSyncer->mCommonEntries.append(
new SyncEntryCommon(
true,0,mobileEntry));
00495 }
00496 }
00497 }
00498
00499
00500
00501
00502
bool kabUpdated =
false;
00503
bool mobileUpdated =
false;
00504
for(uint i=0;i<mSyncer->mCommonEntries.count();++i) {
00505 SyncEntryCommon *entry = mSyncer->mCommonEntries.at(i);
00506 SyncEntryKab *kabEntry = entry->mKabEntry;
00507 SyncEntryMobile *mobileEntry = entry->mMobileEntry;
00508
if (kabEntry && mobileEntry) {
00509
if (mobileEntry->mPhone == kabEntry->mPhone &&
00510 mobileEntry->mName == kabEntry->mName) {
00511
00512 }
else {
00513
00514
00515
QString text =
"<qt><b>" + i18n(
"Kab Entry:") +
"</b><br>";
00516 text +=
" " + kabEntry->mName +
" " + kabEntry->mPhone +
"<br>";
00517 text +=
"<b>" + i18n(
"Mobile Entry:") +
"</b><br>";
00518 text +=
" " + mobileEntry->mName +
" " + mobileEntry->mPhone;
00519 text +=
"</qt>";
00520
00521
QMessageBox *msg =
new QMessageBox(i18n(
"Conflicting Entries"),text,
00522 QMessageBox::Warning,1,2,0,
this);
00523 msg->setButtonText(1,i18n(
"Use Kab Entry"));
00524 msg->setButtonText(2,i18n(
"Use Mobile Entry"));
00525
switch (msg->exec()) {
00526
case 1:
00527 mobileEntry->mPhone = kabEntry->mPhone;
00528 mobileEntry->mName = kabEntry->mName;
00529 mobileUpdated =
true;
00530
break;
00531
case 2:
00532 kabEntry->mPhone = mobileEntry->mPhone;
00533 kabEntry->mName = mobileEntry->mName;
00534 kabUpdated =
true;
00535
break;
00536 }
00537 }
00538 }
00539 }
00540
00541
00542
00543
00544
for(uint i=0;i<mSyncer->mCommonEntries.count();++i) {
00545 SyncEntryCommon *entry = mSyncer->mCommonEntries.at(i);
00546 SyncEntryKab *kabEntry = entry->mKabEntry;
00547 SyncEntryMobile *mobileEntry = entry->mMobileEntry;
00548
00549
if (kabEntry && !mobileEntry) {
00550 kdDebug(5960) <<
"Creating mobile entry for " << kabEntry->mPhone << endl;
00551
00552
00553
00554 entry->mMobileEntry =
new SyncEntryMobile(
true,
"",kabEntry->mPhone,kabEntry->mType,
00555 kabEntry->mName);
00556 mSyncer->mMobileEntries.append(entry->mMobileEntry);
00557
00558
00559
QString index;
00560
for(uint j=1;j<150;++j) {
00561 uint k = 0;
00562
for(;k<mSyncer->mMobileEntries.count();++k) {
00563
if (mSyncer->mMobileEntries.at(k)->mIndex == QString::number(j)) {
00564
break;
00565 }
00566 }
00567
if (k == mSyncer->mMobileEntries.count()) {
00568 index = QString::number(j);
00569
break;
00570 }
00571 }
00572 entry->mMobileEntry->mIndex = index;
00573
00574 kabEntry->mIndex = index;
00575
00576 kabUpdated =
true;
00577 mobileUpdated =
true;
00578 }
else if (mobileEntry && !kabEntry) {
00579
00580
QString phonetype =
"0";
00581 entry->mKabEntry =
new SyncEntryKab(
true,mobileEntry->mIndex,mobileEntry->mName,
00582 mobileEntry->mType,mobileEntry->mPhone,
00583 phonetype);
00584 mSyncer->mKabEntries.append(entry->mKabEntry);
00585
00586 kabUpdated =
true;
00587 }
00588 }
00589
00590
00591
00592
00593
if (kabUpdated) updateKabBook();
00594
if (mobileUpdated) updateMobileBook();
00595
00596 kdDebug(5960) <<
"MobileGui::mergePhonebooks() done." << endl;
00597 }
00598
00599
void MobileGui::syncPhonebooks()
00600 {
00601
if (mSyncing)
return;
00602
00603 mSyncing =
true;
00604 readKabc();
00605 readPhonebook();
00606 mSyncReadId =
"+cpbr=1,150";
00607 }
00608
00609
void MobileGui::updateKabBook()
00610 {
00611 mKabBook->clear();
00612
for(uint i=0;i<mSyncer->mKabEntries.count();++i) {
00613 SyncEntryKab *kabEntry = mSyncer->mKabEntries.at(i);
00614 PhoneBookItem *item =
new PhoneBookItem(mKabBook,kabEntry,kabEntry->mIndex,
00615 kabEntry->mPhone,kabEntry->mType,kabEntry->mName);
00616 item->setOn(kabEntry->mOn);
00617 }
00618 }
00619
00620
void MobileGui::updateMobileBook()
00621 {
00622 mMobileBook->clear();
00623
for(uint i=0;i<mSyncer->mMobileEntries.count();++i) {
00624 SyncEntryMobile *entry = mSyncer->mMobileEntries.at(i);
00625 PhoneBookItem *item =
new PhoneBookItem(mMobileBook,entry,entry->mIndex,
00626 entry->mPhone,entry->mType,entry->mName);
00627 item->setOn(entry->mOn);
00628 }
00629 }