kandy

mobilegui.cpp
1/*
2 This file is part of Kandy.
3
4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
20 As a special exception, permission is given to link this program
21 with any edition of TQt, and distribute the resulting executable,
22 without including the source code for TQt in the source distribution.
23*/
24
25#include <time.h>
26
27#include <tqlabel.h>
28#include <tqlistview.h>
29#include <tqfile.h>
30#include <tqtextstream.h>
31#include <tqmessagebox.h>
32
33#include <tqtextedit.h>
34#include <tqgroupbox.h>
35#include <tqpushbutton.h>
36
37#include <kdebug.h>
38#include <tdefiledialog.h>
39#include <tdemessagebox.h>
40#include <tdelocale.h>
41#include <tdeapplication.h>
42#include <kstatusbar.h>
43
44#include <tdeabc/stdaddressbook.h>
45
46#include "modem.h"
47#include "atcommand.h"
48#include "commandscheduler.h"
49
50#include "mobilegui.h"
51#include "mobilegui.moc"
52#include "mobilemain.h"
53
54
55class SyncEntry
56{
57 public:
58 SyncEntry()
59 {
60 mOn = true;
61 mToBeUpdated = false;
62 mToBeInserted = false;
63 }
64
65 bool mOn;
66 bool mToBeUpdated;
67 bool mToBeInserted;
68};
69
70
71class SyncEntryKab : public SyncEntry
72{
73 public:
74 SyncEntryKab( bool on, const TQString &index, const TQString &name,
75 const TQString &phone )
76 {
77 mOn = on;
78
79 mIndex = index;
80 mName = name;
81 mPhone = phone;
82
83 mKABindex = -1;
84 mPhoneNumberIndex = -1;
85 }
86
87 TQString mIndex;
88 TQString mName;
89 TQString mPhone;
90
91 TDEABC::Addressee mAddressee;
92 int mKABindex;
93 int mPhoneNumberIndex;
94};
95
96
97class SyncEntryMobile : public SyncEntry
98{
99 public:
100 SyncEntryMobile( bool on, const TQString &index, const TQString &phone,
101 const TQString &name )
102 {
103 mOn = on;
104 mToBeDeleted = false;
105
106 mIndex = index;
107 mName = name;
108 mPhone = phone;
109 }
110
111 TQString mIndex;
112 TQString mName;
113 TQString mPhone;
114
115 bool mToBeDeleted;
116};
117
118
119class SyncEntryCommon : public SyncEntry
120{
121 public:
122 SyncEntryCommon( bool on, SyncEntryKab *kabEntry,
123 SyncEntryMobile *mobileEntry )
124 {
125 mOn = on;
126 mKabEntry = kabEntry;
127 mMobileEntry = mobileEntry;
128 }
129
130 SyncEntryKab *mKabEntry;
131 SyncEntryMobile *mMobileEntry;
132};
133
134
135class AddressSyncer
136{
137 public:
138 AddressSyncer()
139 {
140 mKabEntries.setAutoDelete( true );
141 mMobileEntries.setAutoDelete( true );
142 mCommonEntries.setAutoDelete( true );
143 }
144
145 TQPtrList<SyncEntryKab> mKabEntries;
146 TQPtrList<SyncEntryMobile> mMobileEntries;
147 TQPtrList<SyncEntryCommon> mCommonEntries;
148};
149
150
151class PhoneBookItem : public TQCheckListItem
152{
153 public:
154 PhoneBookItem( TQListView *v ) :
155 TQCheckListItem( v, "", TQCheckListItem::CheckBox )
156 {
157 mSyncEntry = 0;
158 }
159
160 PhoneBookItem( TQListView *v, SyncEntry *syncEntry, const TQString &name,
161 const TQString &phone, const TQString &index ) :
162 TQCheckListItem( v, index, TQCheckListItem::CheckBox )
163 {
164 mSyncEntry = syncEntry;
165
166 setText( 0, name );
167 setText( 1, phone );
168 setText( 2, index );
169 }
170
171 SyncEntry *syncEntry() { return mSyncEntry; }
172
173 private:
174 SyncEntry *mSyncEntry;
175};
176
177
178/*
179 * Constructs a MobileGui which is a child of 'parent', with the
180 * name 'name' and widget flags set to 'f'
181 *
182 * The dialog will by default be modeless, unless you set 'modal' to
183 * TRUE to construct a modal dialog.
184 */
185MobileGui::MobileGui( CommandScheduler *scheduler, KandyPrefs *kprefs,
186 TQWidget* parent, const char* name, WFlags fl ) :
187 DCOPObject( "KandyIface" ), MobileGui_base( parent, name, fl )
188{
189 // Setup links to related classes
190 mScheduler = scheduler;
191 mSyncer = new AddressSyncer;
192 mPrefs = kprefs;
193 mparent = parent;
194
195 // Setup mobile phone specific data
196 mMobManufacturer = "";
197 mMobModel = "";
198 mPBStartIndex = 0;
199 mPBLength = 0;
200 mPBNameLength = 0;
201 mPBIndexOccupied.resize( 0, false );
202 mMobHasFD = false;
203 mMobHasLD = false;
204 mMobHasME = false;
205 mMobHasMT = false;
206 mMobHasTA = false;
207 mMobHasOW = false;
208 mMobHasMC = false;
209 mMobHasRC = false;
210
211 // Setup status for asynchronous control flow
212 mLastWriteId = "";
213 mComingFromToggleConnection = false;
214 mComingFromReadPhonebook = false;
215 mComingFromSyncPhonebooks = false;
216 mComingFromExit = false;
217
218 // Setup initial state of phone books
219 setKabState( UNLOADED );
220 setMobState( UNLOADED );
221
222 // Setup signal handlers
223 connect( mScheduler, TQ_SIGNAL( commandProcessed( ATCommand * ) ),
224 TQ_SLOT( processResult( ATCommand * ) ) );
225 connect( mScheduler->modem(), TQ_SIGNAL( gotLine( const char * ) ),
226 TQ_SLOT( termAddOutput( const char * ) ) );
227}
228
229
230MobileGui::~MobileGui()
231{
232 delete mSyncer;
233}
234
235
236void MobileGui::exit()
237{
238 warnKabState( UNLOADED );
239
240 mComingFromExit = true;
241 if ( !warnMobState( UNLOADED ) ) {
242 mComingFromExit = false;
243 tdeApp->quit();
244 }
245}
246
247
248void MobileGui::readModelInformation()
249{
250 // Read generic manufacturer and model information
251 mScheduler->executeId( "+cgmi" );
252 mScheduler->executeId( "+cgmm" );
253 mScheduler->executeId( "+cgmr" );
254 mScheduler->executeId( "+cgsn" );
255
256 // Read information about additional phonebook memories
257 ATCommand *cmd = new ATCommand( "+cpbs=?" );
258 cmd->setAutoDelete( true );
259 mScheduler->execute( cmd );
260
261 // Select SIM phonebook by default
262 cmd = new ATCommand( "+cpbs=" );
263 cmd->setAutoDelete( true );
264 cmd->addParameter( new ATParameter( "SM" ) );
265 mScheduler->execute( cmd );
266
267 // Read phonebook properties
268 mScheduler->executeId( "+cpbr=?" );
269 mScheduler->executeId( "+cpbs?" );
270
271 // Set clock
272 if ( (*mPrefs).autoSetClock() )
273 setClock();
274}
275
276
277void MobileGui::readPhonebook()
278{
279 if ( mMobState == LOADED )
280 return;
281
282 mComingFromReadPhonebook = true;
283 if ( !warnMobState( LOADED ) ) {
284 mComingFromReadPhonebook = false;
285 TQString tmp = "";
286
287 ATCommand *cmd = new ATCommand( "+cpbr=" );
288 cmd->setAutoDelete( true );
289 cmd->addParameter( new ATParameter( tmp.setNum( mPBStartIndex ) ) );
290 cmd->addParameter( new ATParameter( tmp.setNum( mPBStartIndex +
291 mPBLength - 1 ) ) );
292
293 mScheduler->execute( cmd );
294
295 emit statusMessage( i18n( "Reading mobile phonebook..." ) );
296 }
297}
298
299
300void MobileGui::writePhonebook()
301{
302 bool ModemCommandScheduled = false;
303
304
305 if ( mMobState != MODIFIED )
306 return;
307
308 PushButton12->setEnabled( false );
309
310
311 //
312 // Remove all entries from data structures which are marked as
313 // deleted but which are not found on the mobile phone
314 //
315
316 for ( uint i = 0; i < mSyncer->mMobileEntries.count(); i++ ) {
317 SyncEntryMobile *entry = mSyncer->mMobileEntries.at( i );
318
319
320 if ( entry->mToBeDeleted )
321 if ( entry->mIndex.isEmpty() ) {
322 // The current entry has to be deleted but doesn't come from
323 // the mobile phone. Hence, it was inserted during phonebook
324 // synchronisation or so.
325 // => It is sufficient to remove it from mMobileEntries, no
326 // ATCommand for deletion needs to be scheduled.
327 mSyncer->mMobileEntries.remove( i );
328 i--;
329 } else {
330 // The current entry has to be deleted and stems from the
331 // mobile phone. First thing to do is to free its associated
332 // index. This way, its index can be reused for entries which
333 // have be newly inserted to the mobile phone and we can save
334 // an explicit ATCommand for deletion and save time & battery
335 // energy.
336 uint theIndex = entry->mIndex.toUInt();
337 mPBIndexOccupied[ theIndex - mPBStartIndex ] = false;
338 }
339 }
340
341
342 //
343 // Write all elements which need an update to the mobile phone
344 //
345
346 for ( uint i = 0; i < mSyncer->mMobileEntries.count(); i++ ) {
347 SyncEntryMobile *entry = mSyncer->mMobileEntries.at( i );
348 TQString id;
349
350
351 // Only process changed items of the mobile phonebook in
352 // order to save time.
353 if ( entry->mToBeUpdated || entry->mToBeInserted ) {
354 TQString tmp = "";
355
356
357 if ( entry->mToBeUpdated ) {
358 id = "+cpbw=" + entry->mIndex;
359 } else {
360 int index = firstFreeIndex();
361
362
363 mPBIndexOccupied[ index ] = true;
364 id = "+cpbw=" + tmp.setNum( index + mPBStartIndex );
365 }
366 mLastWriteId = id;
367 entry->mToBeUpdated = false;
368 entry->mToBeInserted = false;
369
370 ATCommand *cmd = new ATCommand( id );
371 cmd->setAutoDelete( true );
372 cmd->addParameter( new ATParameter( quote( entry->mPhone ) ) );
373
374 if ( entry->mPhone.left( 1 ) == "+" )
375 cmd->addParameter( new ATParameter( "145" ) );
376 else
377 cmd->addParameter( new ATParameter( "129" ) );
378
379 cmd->addParameter( new ATParameter(
380 quote( string2GSM( entry->mName ) ) ) );
381
382 mScheduler->execute( cmd );
383 ModemCommandScheduled = true;
384 }
385 }
386
387
388 //
389 // As a final step, we need to check again all entries which should be
390 // deleted. If entries exist stemming from the mobile phone and whose
391 // index-position was not reused for updating or inserting other entries in
392 // the previous loop, we need to issue an explicit ATCommand for its deletion.
393 //
394
395 for ( uint i = 0; i < mSyncer->mMobileEntries.count(); i++ ) {
396 SyncEntryMobile *entry = mSyncer->mMobileEntries.at( i );
397
398
399 if ( entry->mToBeDeleted ) {
400 uint theIndex = entry->mIndex.toUInt();
401
402
403 if ( !mPBIndexOccupied[ theIndex - mPBStartIndex ] ) {
404 // Index of item to be deleted still is 0, so that index position
405 // wasn't reused. We must delete it explicitly.
406 TQString id = "+cpbw=" + entry->mIndex;
407
408
409 mLastWriteId = id;
410 ATCommand *cmd = new ATCommand( id );
411 cmd->setAutoDelete( true );
412
413 mScheduler->execute( cmd );
414 ModemCommandScheduled = true;
415 }
416
417 // Remove entry from internal data structures
418 mSyncer->mMobileEntries.remove( i );
419 i--;
420 }
421 }
422
423 if ( ModemCommandScheduled )
424 emit statusMessage( i18n( "Writing mobile phonebook..." ) );
425 else
426 writePhonebookPostProcessing();
427}
428
429
430void MobileGui::writePhonebookPostProcessing()
431{
432 mLastWriteId = "";
433 emit transienStatusMessage( i18n( "Wrote mobile phonebook." ) );
434 PushButton12->setEnabled( true );
435 setMobState( LOADED );
436 updateMobileBook();
437
438 if ( mComingFromToggleConnection ) {
439 mComingFromToggleConnection = false;
440 disconnectGUI();
441 } else
442 if ( mComingFromReadPhonebook ) {
443 mComingFromReadPhonebook = false;
444 TQString tmp = "";
445
446 ATCommand *cmd = new ATCommand( "+cpbr=" );
447 cmd->setAutoDelete( true );
448 cmd->addParameter( new ATParameter( tmp.setNum( mPBStartIndex ) ) );
449 cmd->addParameter( new ATParameter( tmp.setNum( mPBStartIndex +
450 mPBLength - 1 ) ) );
451
452 mScheduler->execute( cmd );
453
454 emit statusMessage( i18n( "Reading mobile phonebook..." ) );
455 } else
456 if ( mComingFromExit ) {
457 mComingFromExit = false;
458 tdeApp->quit();
459 }
460}
461
462
463void MobileGui::setClock()
464{
465 char *timeStr = new char[50];
466 TQString id = "+cclk=";
467 ATCommand *cmd = new ATCommand( id );
468
469
470 cmd->setAutoDelete( true );
471
472 time_t tloc;
473 time( &tloc );
474 struct tm *theTime = localtime( &tloc );
475 strftime( timeStr, 50, "%y/%m/%d,%T+00", theTime );
476
477 TQString Time = timeStr;
478 cmd->addParameter( new ATParameter( quote( Time ) ) );
479
480 mScheduler->execute( cmd );
481
482 delete[] timeStr;
483}
484
485
486void MobileGui::readKabc()
487{
488 if ( mKabState == LOADED )
489 return;
490
491 warnKabState( LOADED );
492
493 emit statusMessage( i18n( "Reading TDE address book..." ) );
494
495 mSyncer->mKabEntries.clear();
496
497 TDEABC::AddressBook *addressBook = TDEABC::StdAddressBook::self( true );
498 TDEABC::AddressBook::Iterator it;
499 int kabIndex = 0;
500
501 for ( it = addressBook->begin(); it != addressBook->end();
502 it++, kabIndex++ ) {
503 TQString index, name;
504 TDEABC::PhoneNumber phoneNumber;
505 TDEABC::PhoneNumber::List phoneNumbers = (*it).phoneNumbers();
506 TDEABC::PhoneNumber::List::Iterator it2;
507 int phoneNumberIndex = 0;
508
509
510 // Scan all numbers associated with a KAB entry
511 for ( it2 = phoneNumbers.begin(); it2 != phoneNumbers.end();
512 it2++, phoneNumberIndex++ ) {
513 bool excludeNumber = false;
514 phoneNumber = (*it2);
515 TQString phone = phoneNumber.number();
516
517
518 if ( (*mPrefs).excludeHome() &&
519 ( phoneNumber.type() & TDEABC::PhoneNumber::Home ) )
520 excludeNumber = true;
521 if ( (*mPrefs).excludeWork() &&
522 ( phoneNumber.type() & TDEABC::PhoneNumber::Work ) )
523 excludeNumber = true;
524 if ( (*mPrefs).excludeMessaging() &&
525 ( phoneNumber.type() & TDEABC::PhoneNumber::Msg ) )
526 excludeNumber = true;
527 if ( (*mPrefs).excludeFax() &&
528 ( phoneNumber.type() & TDEABC::PhoneNumber::Fax ) )
529 excludeNumber = true;
530 if ( (*mPrefs).excludeCell() &&
531 ( phoneNumber.type() & TDEABC::PhoneNumber::Cell ) )
532 excludeNumber = true;
533 if ( (*mPrefs).excludeVideo() &&
534 ( phoneNumber.type() & TDEABC::PhoneNumber::Video ) )
535 excludeNumber = true;
536 if ( (*mPrefs).excludeMailbox() &&
537 ( phoneNumber.type() & TDEABC::PhoneNumber::Bbs ) )
538 excludeNumber = true;
539 if ( (*mPrefs).excludeModem() &&
540 ( phoneNumber.type() & TDEABC::PhoneNumber::Modem ) )
541 excludeNumber = true;
542 if ( (*mPrefs).excludeCar() &&
543 ( phoneNumber.type() & TDEABC::PhoneNumber::Car ) )
544 excludeNumber = true;
545 if ( (*mPrefs).excludeISDN() &&
546 ( phoneNumber.type() & TDEABC::PhoneNumber::Isdn ) )
547 excludeNumber = true;
548 if ( (*mPrefs).excludePager() &&
549 ( phoneNumber.type() & TDEABC::PhoneNumber::Pager ) )
550 excludeNumber = true;
551
552 if ( excludeNumber == false ) {
553 SyncEntryKab *kabEntry;
554
555
556 index = "";
557 name = (*it).familyName();
558
559 TDEABC::AddressBook::Iterator it3;
560 TDEABC::Addressee::List tmp;
561 bool firstCharIsUnique = true;
562 for ( it3 = addressBook->begin(); it3 != addressBook->end(); ++it3 )
563 if ( ( (*it3).familyName() == name ) && ( it3 != it ) ) {
564 tmp.append( (*it3) );
565 if ( (*it3).givenName()[0] == (*it).givenName()[0] )
566 firstCharIsUnique = false;
567 }
568
569 // There are several KAB entries with the same family name.
570 // So, we need to append the given name in order to
571 // distinguish them.
572 if ( ( tmp.size() > 0 ) && !(*it).givenName().isEmpty() ) {
573 name += ", ";
574
575 if ( firstCharIsUnique )
576 name += (*it).givenName()[0] + ".";
577 else
578 name += (*it).givenName();
579 }
580
581 // Truncate name field if it's too long for mobile phone
582 if ( name.length() > mPBNameLength )
583 name = name.remove( mPBNameLength, name.length() - mPBNameLength );
584
585 // Append Suffix to name if specified in preferences
586 if ( (*mPrefs).useHomeSuff() &&
587 ( phoneNumber.type() & TDEABC::PhoneNumber::Home ) )
588 formatPBName( &name, (*mPrefs).homeSuff() );
589 else
590 if ( (*mPrefs).useWorkSuff() &&
591 ( phoneNumber.type() & TDEABC::PhoneNumber::Work ) )
592 formatPBName( &name, (*mPrefs).workSuff() );
593 else
594 if ( (*mPrefs).useMessagingSuff() &&
595 ( phoneNumber.type() & TDEABC::PhoneNumber::Msg ) )
596 formatPBName( &name, (*mPrefs).messagingSuff() );
597 else
598 if ( (*mPrefs).useFaxSuff() &&
599 ( phoneNumber.type() & TDEABC::PhoneNumber::Fax ) )
600 formatPBName( &name, (*mPrefs).faxSuff() );
601 else
602 if ( (*mPrefs).useCellSuff() &&
603 ( phoneNumber.type() & TDEABC::PhoneNumber::Cell ) )
604 formatPBName( &name, (*mPrefs).cellSuff() );
605 else
606 if ( (*mPrefs).useVideoSuff() &&
607 ( phoneNumber.type() & TDEABC::PhoneNumber::Video ) )
608 formatPBName( &name, (*mPrefs).videoSuff() );
609 else
610 if ( (*mPrefs).useMailboxSuff() &&
611 ( phoneNumber.type() & TDEABC::PhoneNumber::Bbs ) )
612 formatPBName( &name, (*mPrefs).mailboxSuff() );
613 else
614 if ( (*mPrefs).useModemSuff() &&
615 ( phoneNumber.type() & TDEABC::PhoneNumber::Modem ) )
616 formatPBName( &name, (*mPrefs).modemSuff() );
617 else
618 if ( (*mPrefs).useCarSuff() &&
619 ( phoneNumber.type() & TDEABC::PhoneNumber::Car ) )
620 formatPBName( &name, (*mPrefs).carSuff() );
621 else
622 if ( (*mPrefs).useISDNSuff() &&
623 ( phoneNumber.type() & TDEABC::PhoneNumber::Isdn ) )
624 formatPBName( &name, (*mPrefs).iSDNSuff() );
625 else
626 if ( (*mPrefs).usePagerSuff() &&
627 ( phoneNumber.type() & TDEABC::PhoneNumber::Pager ) )
628 formatPBName( &name, (*mPrefs).pagerSuff() );
629
630 kabEntry = new SyncEntryKab( true, index, name, phone );
631 kabEntry->mKABindex = kabIndex;
632 kabEntry->mPhoneNumberIndex = phoneNumberIndex;
633
634 kabEntry->mAddressee = (*it);
635 mSyncer->mKabEntries.append( kabEntry );
636 }
637 }
638 }
639
640 // Display KAB entries
641 updateKabBook();
642
643 emit transienStatusMessage( i18n( "Read TDE address book." ) );
644
645 setKabState( LOADED );
646}
647
648
649TQString MobileGui::decodeSuffix( const TQString &suffix )
650{
651 TQString theSuffix = suffix;
652
653
654 // Check whether suffix is quoted. If so, it should be interpreted
655 // as Hex-Number of a special GSM character.
656 if ( ( theSuffix.left( 1 ) == "\"" ) && ( theSuffix.right( 1 ) == "\"" ) ) {
657 TQString tmp = "";
658 char suffixNumber = (char) dequote( suffix ).toUInt( 0, 16 );
659 tmp += suffixNumber;
660
661 theSuffix = GSM2String( tmp );
662 }
663
664 return theSuffix;
665}
666
667
668void MobileGui::formatPBName( TQString *name, TQString suffix )
669{
670 TQString theSuffix = decodeSuffix( suffix );
671
672
673 if ( name->length() + theSuffix.length() > mPBNameLength ) {
674 // Truncate name field if it's too long for mobile phone
675 unsigned int toolong = name->length() + theSuffix.length() - mPBNameLength;
676 (*name) = name->remove( name->length() - toolong, toolong );
677 } else
678 if ( name->length() + theSuffix.length() < mPBNameLength )
679 // Add white spaces so that suffix is right justified
680 while ( name->length() + theSuffix.length() != mPBNameLength )
681 (*name) += ' ';
682
683 (*name) += theSuffix;
684}
685
686
687TQString MobileGui::stripWhiteSpaces( const TQString &theString )
688{
689 int pos = 0;
690 int len = theString.length();
691
692
693 for ( unsigned int i = 0; i < theString.length(); i++ )
694 if ( theString[ i ].latin1() == ' ' ) {
695 pos++;
696 len--;
697 } else
698 break;
699
700 if ( len == 0 )
701 return "";
702
703 for ( int i = theString.length() - 1; i >= 0; i-- )
704 if ( theString[ i ].latin1() == ' ' )
705 len--;
706 else
707 break;
708
709 return theString.mid( pos, len );
710}
711
712
713void MobileGui::writeKabc()
714{
715 if ( mKabState != MODIFIED )
716 return;
717
718 TDEABC::AddressBook *addressBook = TDEABC::StdAddressBook::self( true );
719 TDEABC::Ticket *ticket = addressBook->requestSaveTicket();
720
721 if ( !ticket ) {
722 kdDebug() << "Error! No ticket to save." << endl;
723 return;
724 }
725
726
727 for ( uint i = 0; i < mSyncer->mKabEntries.count(); i++ ) {
728 SyncEntryKab *kabEntry = mSyncer->mKabEntries.at( i );
729 TQString phoneNumber = kabEntry->mPhone;
730
731
732 if ( kabEntry->mToBeUpdated ) {
733 // Find the entry in the KAB which has to be updated
734 TDEABC::AddressBook::Iterator it = addressBook->begin();
735 for ( int KABindex = 0; KABindex != kabEntry->mKABindex;
736 it++, KABindex++ ) ;
737
738 // Find the correct phonenumber of the phonebook entry
739 TDEABC::PhoneNumber::List phoneNumbers = (*it).phoneNumbers();
740 TDEABC::PhoneNumber::List::Iterator it2 = phoneNumbers.begin();
741 for ( int phoneNumberIndex = 0;
742 phoneNumberIndex != kabEntry->mPhoneNumberIndex;
743 it2++, phoneNumberIndex++ ) ;
744
745 (*it2).setNumber( phoneNumber );
746 (*it).insertPhoneNumber( (*it2) );
747 } else
748
749 if ( kabEntry->mToBeInserted ) {
750 int phoneType = 0;
751 bool goon = true;
752 TDEABC::AddressBook::Iterator it;
753 bool equivalentEntryFound = false;
754 TQString name = kabEntry->mName;
755
756
757 //
758 // Identify Type of Phonenumber using possibly appended suffixes.
759 // If a suffix is found, remove it from the name.
760 //
761 if ( goon && (*mPrefs).useHomeSuff() ) {
762 TQString theSuffix = decodeSuffix( (*mPrefs).homeSuff() );
763 if ( name.right( theSuffix.length() ) == theSuffix ) {
764 phoneType = TDEABC::PhoneNumber::Home;
765 name = stripWhiteSpaces(
766 name.left( name.length() - theSuffix.length() ) );
767 goon = false;
768 }
769 }
770 if ( goon && (*mPrefs).useWorkSuff() ) {
771 TQString theSuffix = decodeSuffix( (*mPrefs).workSuff() );
772 if ( name.right( theSuffix.length() ) == theSuffix ) {
773 phoneType = TDEABC::PhoneNumber::Work;
774 name = stripWhiteSpaces(
775 name.left( name.length() - theSuffix.length() ) );
776 goon = false;
777 }
778 }
779 if ( goon && (*mPrefs).useMessagingSuff() ) {
780 TQString theSuffix = decodeSuffix( (*mPrefs).messagingSuff() );
781 if ( name.right( theSuffix.length() ) == theSuffix ) {
782 phoneType = TDEABC::PhoneNumber::Msg;
783 name = stripWhiteSpaces(
784 name.left( name.length() - theSuffix.length() ) );
785 goon = false;
786 }
787 }
788 if ( goon && (*mPrefs).useFaxSuff() ) {
789 TQString theSuffix = decodeSuffix( (*mPrefs).faxSuff() );
790 if ( name.right( theSuffix.length() ) == theSuffix ) {
791 phoneType = TDEABC::PhoneNumber::Fax;
792 name = stripWhiteSpaces(
793 name.left( name.length() - theSuffix.length() ) );
794 goon = false;
795 }
796 }
797 if ( goon && (*mPrefs).useCellSuff() ) {
798 TQString theSuffix = decodeSuffix( (*mPrefs).cellSuff() );
799 if ( name.right( theSuffix.length() ) == theSuffix ) {
800 phoneType = TDEABC::PhoneNumber::Cell;
801 name = stripWhiteSpaces(
802 name.left( name.length() - theSuffix.length() ) );
803 goon = false;
804 }
805 }
806 if ( goon && (*mPrefs).useVideoSuff() ) {
807 TQString theSuffix = decodeSuffix( (*mPrefs).videoSuff() );
808 if ( name.right( theSuffix.length() ) == theSuffix ) {
809 phoneType = TDEABC::PhoneNumber::Video;
810 name = stripWhiteSpaces(
811 name.left( name.length() - theSuffix.length() ) );
812 goon = false;
813 }
814 }
815 if ( goon && (*mPrefs).useMailboxSuff() ) {
816 TQString theSuffix = decodeSuffix( (*mPrefs).mailboxSuff() );
817 if ( name.right( theSuffix.length() ) == theSuffix ) {
818 phoneType = TDEABC::PhoneNumber::Bbs;
819 name = stripWhiteSpaces(
820 name.left( name.length() - theSuffix.length() ) );
821 goon = false;
822 }
823 }
824 if ( goon && (*mPrefs).useModemSuff() ) {
825 TQString theSuffix = decodeSuffix( (*mPrefs).modemSuff() );
826 if ( name.right( theSuffix.length() ) == theSuffix ) {
827 phoneType = TDEABC::PhoneNumber::Modem;
828 name = stripWhiteSpaces(
829 name.left( name.length() - theSuffix.length() ) );
830 goon = false;
831 }
832 }
833 if ( goon && (*mPrefs).useCarSuff() ) {
834 TQString theSuffix = decodeSuffix( (*mPrefs).carSuff() );
835 if ( name.right( theSuffix.length() ) == theSuffix ) {
836 phoneType = TDEABC::PhoneNumber::Car;
837 name = stripWhiteSpaces(
838 name.left( name.length() - theSuffix.length() ) );
839 goon = false;
840 }
841 }
842 if ( goon && (*mPrefs).useISDNSuff() ) {
843 TQString theSuffix = decodeSuffix( (*mPrefs).iSDNSuff() );
844 if ( name.right( theSuffix.length() ) == theSuffix ) {
845 phoneType = TDEABC::PhoneNumber::Isdn;
846 name = stripWhiteSpaces(
847 name.left( name.length() - theSuffix.length() ) );
848 goon = false;
849 }
850 }
851 if ( goon && (*mPrefs).usePagerSuff() ) {
852 TQString theSuffix = decodeSuffix( (*mPrefs).pagerSuff() );
853 if ( name.right( theSuffix.length() ) == theSuffix ) {
854 phoneType = TDEABC::PhoneNumber::Pager;
855 name = stripWhiteSpaces(
856 name.left( name.length() - theSuffix.length() ) );
857 goon = false;
858 }
859 }
860
861
862 //
863 // Search for a KAB entry whose name, if formatted in exactly the
864 // same way as was done in readKabc, is equal to the actual name.
865 //
866
867 for ( it = addressBook->begin(); it != addressBook->end(); it++ ) {
868 TQString kabName = (*it).familyName();
869 TDEABC::AddressBook::Iterator it3;
870 TDEABC::Addressee::List tmp;
871 bool firstCharIsUnique = true;
872 unsigned int minLength;
873
874
875 for ( it3 = addressBook->begin(); it3 != addressBook->end(); it3++ )
876 if ( ( (*it3).familyName() == kabName ) && ( it3 != it ) ) {
877 tmp.append( (*it3) );
878 if ( (*it3).givenName()[0] == (*it).givenName()[0] )
879 firstCharIsUnique = false;
880 }
881
882 // There are several KAB entries with the same family name.
883 // So, we need to append the given name in order to
884 // distinguish them.
885 if ( ( tmp.size() > 0 ) && !(*it).givenName().isEmpty() ) {
886 kabName += ", ";
887
888 if ( firstCharIsUnique )
889 kabName += (*it).givenName()[0] + ".";
890 else
891 kabName += (*it).givenName();
892 }
893
894 // Truncate name field if it's too long for mobile phone
895 if ( kabName.length() > mPBNameLength )
896 kabName = kabName.remove( mPBNameLength,
897 kabName.length() - mPBNameLength );
898
899 minLength = kabName.length();
900 if ( name.length() < minLength )
901 minLength = name.length();
902
903 if ( name.left( minLength ) == kabName.left( minLength ) ) {
904 (*it).insertPhoneNumber( TDEABC::PhoneNumber( phoneNumber,
905 phoneType ) );
906
907 equivalentEntryFound = true;
908 break;
909 }
910 }
911
912 //
913 // If no equivalent entry was found in KAB, we need to generate
914 // a complete new entry.
915 //
916
917 if ( !equivalentEntryFound ) {
918 TDEABC::Addressee entry;
919 TQStringList *fields = new TQStringList;
920
921
922 *fields = TQStringList::split( ',', name );
923
924 if ( fields->count() > 1 ) {
925 // Name string contains comma separated entry so that we
926 // need to build family and given names out of them.
927 TQString givenName = "";
928
929
930 entry.setFamilyName( stripWhiteSpaces( (*fields)[ 0 ] ) );
931
932 for ( unsigned int i = 1; i < fields->count(); i++ )
933 givenName += stripWhiteSpaces( (*fields)[ i ] ) + " ";
934 entry.setGivenName( stripWhiteSpaces( givenName ) );
935 } else
936 // Name string contains only one string without comma.
937 entry.setFamilyName( stripWhiteSpaces( name ) );
938
939 entry.insertPhoneNumber( TDEABC::PhoneNumber( phoneNumber, phoneType ) );
940
941 addressBook->insertAddressee( entry );
942 }
943 }
944
945 kabEntry->mToBeUpdated = false;
946 kabEntry->mToBeInserted = false;
947 }
948
949 addressBook->save( ticket );
950
951 emit transienStatusMessage( i18n( "Wrote TDE address book." ) );
952
953 setKabState( LOADED );
954}
955
956
957void MobileGui::refreshStatus()
958{
959 mScheduler->executeId( "+cbc" );
960 mScheduler->executeId( "+csq" );
961}
962
963
964void MobileGui::processResult( ATCommand *command )
965{
966 if ( command->id() == "+cbc" )
967 mBatteryChargeLabel->setText( command->resultField( 1 ) + " %" );
968 else
969 if ( command->id() == "+csq" )
970 mSignalQualityLabel->setText( command->resultField( 0 ) );
971 else
972 if ( command->id() == "+cgmi" ) {
973 mMobManufacturer = command->resultField( 0 );
974 mManufacturerLabel->setText( mMobManufacturer );
975 } else
976 if ( command->id() == "+cgmm" ) {
977 mMobModel = command->resultField( 0 );
978 mModelLabel->setText( mMobModel );
979 } else
980 if ( command->id() == "+cgmr" )
981 mGSMVersionLabel->setText( command->resultField( 0 ) );
982 else
983 if ( command->id() == "+cgsn" )
984 mSerialNumberLabel->setText( command->resultField( 0 ) );
985 else
986 if ( command->id() == "+cpbr=?" )
987 {
988 TQStringList tmpList = TQStringList::split( "-", command->resultField( 0 ) );
989 TQString tmpString = tmpList.first().right( tmpList.first().length() - 1 );
990 mPBStartIndex = tmpString.toUInt();
991 mPBNameLength = command->resultField( 2 ).toUInt();
992 } else
993 if ( command->id() == "+cpbs?" ) {
994 mPBLength = command->resultField( 2 ).toUInt();
995
996 // Allocate and initialize memory for the buckets of indices
997 mPBIndexOccupied.resize( mPBLength, false );
998 for ( unsigned int i = 0; i < mPBLength; i++ )
999 mPBIndexOccupied[ i ] = false;
1000 } else
1001 if ( command->id() == "+cpbr=" ) {
1002 fillPhonebook( command );
1003
1004 if ( mComingFromSyncPhonebooks ) {
1005 mComingFromSyncPhonebooks = false;
1006 mergePhonebooks();
1007 }
1008 } else
1009 if ( command->id() == mLastWriteId )
1010 writePhonebookPostProcessing();
1011 else
1012 if ( command->id() == "+cpbs=?" ) {
1013 TQPtrList<TQStringList> *list = command->resultFields();
1014 TQStringList *fields = list->first();
1015
1016
1017 while( fields ) {
1018 for ( unsigned int i = 0; i < fields->count(); i++ ) {
1019 TQString memory = dequote( (*fields)[ i ] );
1020
1021
1022 if ( memory == "FD" )
1023 mMobHasFD = true;
1024 else
1025 if ( memory == "LD" )
1026 mMobHasLD = true;
1027 else
1028 if ( memory == "ME" )
1029 mMobHasME = true;
1030 else
1031 if ( memory == "MT" )
1032 mMobHasMT = true;
1033 else
1034 if ( memory == "TA" )
1035 mMobHasTA = true;
1036 else
1037 if ( ( memory == "OW" ) ||
1038 ( ( memory == "ON" ) && ( mMobManufacturer == "SIEMENS" ) ) )
1039 mMobHasOW = true;
1040 else
1041 if ( ( mMobManufacturer == "SIEMENS" ) && ( memory == "MC" ) )
1042 mMobHasMC = true;
1043 else
1044 if ( ( mMobManufacturer == "SIEMENS" ) && ( memory == "RC" ) )
1045 mMobHasRC = true;
1046 }
1047
1048 fields = list->next();
1049 }
1050 }
1051}
1052
1053
1054TQString MobileGui::noSpaces( const TQString &theString )
1055{
1056 TQString result = "";
1057
1058
1059 for ( unsigned int i = 0; i < theString.length(); i++ )
1060 if ( theString[ i ].latin1() != ' ' )
1061 result += theString[ i ];
1062
1063 return result;
1064}
1065
1066
1067int MobileGui::firstFreeIndex()
1068{
1069 unsigned int i;
1070
1071
1072 if ( mPBIndexOccupied.capacity() == 0 )
1073 return 0;
1074
1075 for ( i = 1; i < mPBLength; i++ )
1076 if ( !mPBIndexOccupied[ i ] )
1077 break;
1078
1079 if ( i < mPBLength )
1080 return i;
1081
1082 return 0;
1083}
1084
1085
1086TQString MobileGui::string2GSM( const TQString &theString )
1087{
1088 TQString result = "";
1089
1090
1091 for ( unsigned int i = 0; i < theString.length(); i++ )
1092 switch ( theString[ i ].latin1() ) {
1093 case 'Ä': result += '['; break;
1094 case 'ä': result += '{'; break;
1095 case 'Ö': result += 92; break;
1096 case 'ö': result += '|'; break;
1097 case 'Ü': result += '^'; break;
1098 case 'ü': result += '~'; break;
1099 case 'ß': result += 30; break;
1100 case 'è': result += 4; break;
1101 case 'é': result += 5; break;
1102
1103 default: result += theString[ i ];
1104 }
1105
1106 return result;
1107}
1108
1109
1110TQString MobileGui::GSM2String( const TQString &theString )
1111{
1112 TQString result = "";
1113
1114
1115 for ( unsigned int i = 0; i < theString.length(); i++ )
1116 switch ( theString[ i ].latin1() ) {
1117 case '[': result += 'Ä'; break;
1118 case '{': result += 'ä'; break;
1119 case 92: result += 'Ö'; break;
1120 case '|': result += 'ö'; break;
1121 case '^': result += 'Ü'; break;
1122 case '~': result += 'ü'; break;
1123 case 30: result += 'ß'; break;
1124 case 4: result += 'è'; break;
1125 case 5: result += 'é'; break;
1126
1127 default: result += theString[ i ];
1128 }
1129
1130 return result;
1131}
1132
1133
1134void MobileGui::fillPhonebook( ATCommand *cmd )
1135{
1136 mSyncer->mMobileEntries.clear();
1137
1138 TQPtrList<TQStringList> *list = cmd->resultFields();
1139 TQStringList *fields = list->first();
1140
1141 while( fields ) {
1142 if ( fields->count() != 4 )
1143 kdDebug() << "Error! Unexpected number of address fields." << endl;
1144 else {
1145 TQString index = (*fields)[0];
1146 TQString phone = (*fields)[1];
1147 TQString type = (*fields)[2];
1148 TQString name = GSM2String( (*fields)[3] );
1149
1150 SyncEntryMobile *phoneEntry = new SyncEntryMobile( true, dequote( index ),
1151 dequote( phone ),
1152 dequote( name ) );
1153 mPBIndexOccupied[ index.toUInt() - mPBStartIndex ] = true;
1154 mSyncer->mMobileEntries.append( phoneEntry );
1155 }
1156 fields = list->next();
1157 }
1158
1159 // Display mobile entries
1160 updateMobileBook();
1161
1162 emit transienStatusMessage(i18n("Read mobile phonebook."));
1163 emit phonebookRead();
1164
1165 setMobState( LOADED );
1166}
1167
1168
1169TQString MobileGui::quote( const TQString &str )
1170{
1171 if ( ( str.left(1) == "\"" ) && ( str.right(1) == "\"" ) )
1172 return str;
1173
1174 return "\"" + str + "\"";
1175}
1176
1177
1178TQString MobileGui::dequote( const TQString &str )
1179{
1180 int pos = 0;
1181 int len = str.length();
1182
1183
1184 if ( str.left(1) == "\"" ) {
1185 pos = 1;
1186 len --;
1187 }
1188
1189 if ( str.right(1) == "\"" )
1190 len--;
1191
1192 return str.mid( pos, len );
1193}
1194
1195
1196void MobileGui::savePhonebook()
1197{
1198 if ( mMobState == UNLOADED )
1199 return;
1200
1201 TQString fileName = KFileDialog::getSaveFileName( "phonebook.csv" );
1202 TQFile outFile( fileName );
1203
1204 if ( outFile.open( IO_WriteOnly ) ) {
1205 TQTextStream t( &outFile ); // use a text stream
1206
1207 for( uint i = 0; i < mSyncer->mMobileEntries.count(); i++) {
1208 SyncEntryMobile *e = mSyncer->mMobileEntries.at( i );
1209
1210
1211 if ( !e->mToBeDeleted )
1212 t << e->mIndex << "," << e->mPhone << "," << e->mName << endl;
1213 }
1214
1215 outFile.close();
1216 }
1217}
1218
1219
1220void MobileGui::deleteMobPhonebook()
1221{
1222
1223 //
1224 // Process all elements selected in the GUI
1225 //
1226
1227 PhoneBookItem *item = (PhoneBookItem *) mMobileBook->firstChild();
1228 while ( item ) {
1229 if ( item->isOn() ) {
1230 SyncEntryMobile *mobileItem = (SyncEntryMobile *) item->syncEntry();
1231
1232
1233 // Deselect current item
1234 item->setOn( false );
1235 mobileItem->mOn = false;
1236
1237 // Mark current item as deleted
1238 mobileItem->mToBeDeleted = true;
1239 }
1240
1241 item = (PhoneBookItem *) item->nextSibling();
1242 }
1243
1244 // Update GUI
1245 updateMobileBook();
1246 setMobState( MODIFIED );
1247}
1248
1249
1250void MobileGui::mergePhonebooks()
1251{
1252 uint i;
1253
1254
1255 //
1256 // Transfer current Selection State from GUI to mSyncer
1257 //
1258
1259 PhoneBookItem *item = (PhoneBookItem *) mKabBook->firstChild();
1260 while ( item ) {
1261 item->syncEntry()->mOn = item->isOn();
1262 item = (PhoneBookItem *) item->nextSibling();
1263 }
1264
1265 item = (PhoneBookItem *) mMobileBook->firstChild();
1266 while ( item ) {
1267 item->syncEntry()->mOn = item->isOn();
1268 item = (PhoneBookItem *) item->nextSibling();
1269 }
1270
1271 mSyncer->mCommonEntries.clear();
1272
1273
1274 //
1275 // Put TDE Address Book list into Common List
1276 //
1277
1278 for ( i = 0; i < mSyncer->mKabEntries.count(); i++ )
1279 if ( mSyncer->mKabEntries.at( i )->mOn ) {
1280 mSyncer->mCommonEntries.append(
1281 new SyncEntryCommon( true, mSyncer->mKabEntries.at( i ), 0 ) );
1282 mSyncer->mKabEntries.at( i )->mOn = false;
1283 }
1284
1285
1286 //
1287 // Put Mobile Address Book list into Common List; Merge equivalent entries
1288 //
1289
1290 for ( i = 0; i < mSyncer->mMobileEntries.count(); i++ ) {
1291 SyncEntryMobile *mobileEntry = mSyncer->mMobileEntries.at( i );
1292 bool equivalentEntryFound = false;
1293 uint j;
1294
1295
1296 if( !mobileEntry->mToBeDeleted )
1297 for ( j = 0; j < mSyncer->mCommonEntries.count(); j++ ) {
1298 SyncEntryCommon *theCommonEntry = mSyncer->mCommonEntries.at( j );
1299
1300
1301 if ( theCommonEntry->mKabEntry &&
1302 ( theCommonEntry->mKabEntry->mName == mobileEntry->mName ) ) {
1303 theCommonEntry->mMobileEntry = mobileEntry;
1304 equivalentEntryFound = true;
1305
1306 if ( noSpaces( theCommonEntry->mKabEntry->mPhone ) ==
1307 mobileEntry->mPhone ) {
1308 mobileEntry->mOn = false;
1309 break;
1310 } else {
1311 // Conflict: 2 Entries have same name but different numbers.
1312 // Prompt user.
1313 TQString text = "<qt><b>" + i18n( "Kab Entry:" ) + "</b><br>";
1314 text += " " + theCommonEntry->mKabEntry->mName + " " +
1315 theCommonEntry->mKabEntry->mPhone + "<br>";
1316 text += "<b>" + i18n( "Mobile Entry:" ) + "</b><br>";
1317 text += " " + mobileEntry->mName + " " + mobileEntry->mPhone;
1318 text += "</qt>";
1319
1320 TQMessageBox *msg =
1321 new TQMessageBox( i18n( "Conflicting Entries" ), text,
1322 TQMessageBox::Warning, 1, 2, 0, this );
1323 msg->setButtonText( 1, i18n( "Use Kab Entry" ) );
1324 msg->setButtonText( 2, i18n( "Use Mobile Entry" ) );
1325
1326 switch ( msg->exec() ) {
1327 case 1:
1328 // Use TDE Address Book Entry
1329 mobileEntry->mPhone = theCommonEntry->mKabEntry->mPhone;
1330 mobileEntry->mName = theCommonEntry->mKabEntry->mName;
1331 mobileEntry->mOn = true;
1332 mobileEntry->mToBeUpdated = true;
1333
1334 setMobState( MODIFIED );
1335 break;
1336
1337 case 2:
1338 // Use Mobile Address Book Entry
1339 theCommonEntry->mKabEntry->mPhone = mobileEntry->mPhone;
1340 theCommonEntry->mKabEntry->mName = mobileEntry->mName;
1341 theCommonEntry->mKabEntry->mOn = true;
1342 theCommonEntry->mKabEntry->mToBeUpdated = true;
1343
1344 mobileEntry->mOn = false;
1345
1346 setKabState( MODIFIED );
1347 break;
1348 }
1349 }
1350 }
1351 }
1352
1353 if ( !equivalentEntryFound && mobileEntry->mOn ) {
1354 // No equivalent entry exists; generate a new one.
1355 mSyncer->mCommonEntries.append(
1356 new SyncEntryCommon( true, 0, mobileEntry ) );
1357 mobileEntry->mOn = false;
1358 }
1359 }
1360
1361
1362 //
1363 // Create new KAB and Mobile Entries
1364 //
1365
1366 for ( i = 0; i < mSyncer->mCommonEntries.count(); i++ ) {
1367 SyncEntryCommon *entry = mSyncer->mCommonEntries.at( i );
1368 SyncEntryKab *kabEntry = entry->mKabEntry;
1369 SyncEntryMobile *mobileEntry = entry->mMobileEntry;
1370
1371
1372 if ( kabEntry && !mobileEntry ) {
1373 // Create Mobile Entry
1374 entry->mMobileEntry = new SyncEntryMobile( true, "", kabEntry->mPhone,
1375 kabEntry->mName );
1376 entry->mMobileEntry->mToBeInserted = true;
1377 mSyncer->mMobileEntries.append( entry->mMobileEntry );
1378
1379 setMobState( MODIFIED );
1380 } else
1381 if ( mobileEntry && !kabEntry ) {
1382 // Create KAB Entry
1383 entry->mKabEntry = new SyncEntryKab( true, mobileEntry->mIndex,
1384 mobileEntry->mName,
1385 mobileEntry->mPhone );
1386 entry->mKabEntry->mToBeInserted = true;
1387 mSyncer->mKabEntries.append( entry->mKabEntry );
1388
1389 setKabState( MODIFIED );
1390 }
1391 }
1392
1393
1394 //
1395 // Update GUI
1396 //
1397
1398 updateKabBook();
1399 updateMobileBook();
1400
1401 emit transienStatusMessage( i18n( "Synced phonebooks." ) );
1402 PushButton8_3->setEnabled( true );
1403}
1404
1405
1406void MobileGui::syncPhonebooks()
1407{
1408 PushButton8_3->setEnabled( false );
1409
1410 if ( mKabState == UNLOADED )
1411 readKabc();
1412 if ( mMobState == UNLOADED ) {
1413 mComingFromSyncPhonebooks = true;
1414 readPhonebook();
1415 } else
1416 mergePhonebooks();
1417}
1418
1419
1420void MobileGui::updateKabBook()
1421{
1422 mKabBook->clear();
1423
1424 for ( uint i = 0; i < mSyncer->mKabEntries.count(); i++ ) {
1425 SyncEntryKab *kabEntry = mSyncer->mKabEntries.at( i );
1426 PhoneBookItem *item = new PhoneBookItem( mKabBook, kabEntry,
1427 kabEntry->mName, kabEntry->mPhone,
1428 kabEntry->mIndex );
1429 item->setOn( kabEntry->mOn );
1430 }
1431}
1432
1433
1434void MobileGui::updateMobileBook()
1435{
1436 mMobileBook->clear();
1437
1438 for ( uint i = 0; i < mSyncer->mMobileEntries.count(); i++ ) {
1439 SyncEntryMobile *entry = mSyncer->mMobileEntries.at( i );
1440
1441 if ( !entry->mToBeDeleted ) {
1442 PhoneBookItem *item = new PhoneBookItem( mMobileBook, entry, entry->mName,
1443 entry->mPhone, entry->mIndex );
1444 item->setOn( entry->mOn );
1445 }
1446 }
1447}
1448
1449
1450void MobileGui::toggleConnection()
1451{
1452 if ( mConnectButton->text() == i18n( "Connect" ) ) {
1453 emit connectModem();
1454
1455 readModelInformation();
1456 refreshStatus();
1457
1458 mConnectButton->setText( tr2i18n( "Disconnect" ) );
1459 PushButton1->setEnabled( true );
1460 PushButton5_3->setEnabled( true );
1461
1462 mABTab->setEnabled( true );
1463 setKabState( UNLOADED );
1464 setMobState( UNLOADED );
1465
1466 ((MobileMain *) mparent)->statusBar()->changeItem( i18n(" Connected "), 1 );
1467 } else {
1468 warnKabState( UNLOADED );
1469
1470 mComingFromToggleConnection = true;
1471 if ( !warnMobState( UNLOADED ) ) {
1472 mComingFromToggleConnection = false;
1473 disconnectGUI();
1474 }
1475 }
1476}
1477
1478
1479void MobileGui::disconnectGUI()
1480{
1481 emit disconnectModem();
1482
1483 mManufacturerLabel->setText( "x" );
1484 mModelLabel->setText( "x" );
1485 mGSMVersionLabel->setText( "x" );
1486 mSerialNumberLabel->setText( "x" );
1487
1488 mBatteryChargeLabel->setText( "xx %" );
1489 mSignalQualityLabel->setText( "x" );
1490
1491 mConnectButton->setText( tr2i18n( "Connect" ) );
1492 PushButton1->setEnabled( false );
1493 PushButton5_3->setEnabled( false );
1494
1495 mKabBook->clear();
1496 mMobileBook->clear();
1497 setKabState( UNLOADED );
1498 setMobState( UNLOADED );
1499
1500 mABTab->setEnabled( false );
1501
1502 mMobHasFD = false;
1503 mMobHasLD = false;
1504 mMobHasME = false;
1505 mMobHasMT = false;
1506 mMobHasTA = false;
1507 mMobHasOW = false;
1508 mMobHasMC = false;
1509 mMobHasRC = false;
1510
1511 mPBIndexOccupied.resize( 0, false );
1512
1513 ((MobileMain *) mparent)->statusBar()->changeItem( i18n(" Disconnected "),
1514 1 );
1515}
1516
1517
1518void MobileGui::termAddOutput( const char *line )
1519{
1520 mTermIO->append( line );
1521 mTermIO->setCursorPosition( mTermIO->paragraphs() - 1, 0 );
1522}
1523
1524
1525void MobileGui::setKabState( ABState newState )
1526{
1527 switch ( mKabState ) {
1528 case UNLOADED:
1529 groupBox3->setTitle( tr2i18n( "TDE Address Book" ) );
1530 mReadKabButton->setEnabled( true );
1531 PushButton8->setEnabled( false );
1532 break;
1533
1534 case LOADED:
1535 if ( newState == MODIFIED ) {
1536 groupBox3->setTitle( tr2i18n( "TDE Address Book (modified)" ) );
1537 mReadKabButton->setEnabled( true );
1538 PushButton8->setEnabled( true );
1539 } else
1540 if ( newState == UNLOADED ) {
1541 groupBox3->setTitle( tr2i18n( "TDE Address Book" ) );
1542 mReadKabButton->setEnabled( true );
1543 PushButton8->setEnabled( false );
1544 }
1545 break;
1546
1547 case MODIFIED:
1548 if ( newState != MODIFIED ) {
1549 groupBox3->setTitle( tr2i18n( "TDE Address Book" ) );
1550 mReadKabButton->setEnabled( true );
1551 PushButton8->setEnabled( false );
1552 }
1553 break;
1554 }
1555
1556 mKabState = newState;
1557}
1558
1559
1560void MobileGui::warnKabState( ABState newState )
1561{
1562 if ( ( mKabState == MODIFIED ) && ( newState != MODIFIED ) ) {
1563 TQString text = "<qt><b>" + i18n( "Warning" ) + "</b><br>";
1564 text += i18n( "The TDE address book contains unsaved changes." ) +
1565 "<br></qt>";
1566
1567 TQMessageBox *msg = new TQMessageBox( i18n( "Unsaved Changes" ), text,
1568 TQMessageBox::Critical, 1, 2, 0, this );
1569 msg->setButtonText( 1, i18n( "Save" ) );
1570 msg->setButtonText( 2, i18n( "Discard" ) );
1571
1572 switch ( msg->exec() ) {
1573 case 1:
1574 // Save Changes first
1575 writeKabc();
1576 break;
1577
1578 case 2:
1579 break;
1580 }
1581 }
1582}
1583
1584
1585void MobileGui::setMobState( ABState newState )
1586{
1587 switch ( mMobState ) {
1588 case UNLOADED:
1589 if ( newState == UNLOADED ) {
1590 groupBox4->setTitle( tr2i18n( "Mobile Phone Book" ) );
1591 PushButton3->setEnabled( true );
1592 PushButton12->setEnabled( false );
1593 PushButton4_2->setEnabled( false );
1594 MobDeleteButton->setEnabled( false );
1595 } else
1596 if ( newState == LOADED ) {
1597 groupBox4->setTitle( tr2i18n( "Mobile Phone Book" ) );
1598 PushButton3->setEnabled( true );
1599 PushButton12->setEnabled( false );
1600 PushButton4_2->setEnabled( true );
1601 MobDeleteButton->setEnabled( true );
1602 }
1603 break;
1604
1605 case LOADED:
1606 if ( newState == MODIFIED ) {
1607 groupBox4->setTitle( tr2i18n( "Mobile Phone Book (modified)" ) );
1608 PushButton3->setEnabled( true );
1609 PushButton12->setEnabled( true );
1610 PushButton4_2->setEnabled( true );
1611 MobDeleteButton->setEnabled( true );
1612 } else
1613 if ( newState == UNLOADED ) {
1614 groupBox4->setTitle( tr2i18n( "Mobile Phone Book" ) );
1615 PushButton3->setEnabled( true );
1616 PushButton12->setEnabled( false );
1617 PushButton4_2->setEnabled( false );
1618 MobDeleteButton->setEnabled( false );
1619 }
1620 break;
1621
1622 case MODIFIED:
1623 if ( newState == UNLOADED ) {
1624 groupBox4->setTitle( tr2i18n( "Mobile Phone Book" ) );
1625 PushButton3->setEnabled( true );
1626 PushButton12->setEnabled( false );
1627 PushButton4_2->setEnabled( false );
1628 MobDeleteButton->setEnabled( false );
1629 } else
1630 if ( newState == LOADED ) {
1631 groupBox4->setTitle( tr2i18n( "Mobile Phone Book" ) );
1632 PushButton3->setEnabled( true );
1633 PushButton12->setEnabled( false );
1634 PushButton4_2->setEnabled( true );
1635 MobDeleteButton->setEnabled( true );
1636 }
1637 break;
1638 }
1639
1640 mMobState = newState;
1641}
1642
1643
1644bool MobileGui::warnMobState( ABState newState )
1645{
1646 if ( ( mMobState == MODIFIED ) && ( newState != MODIFIED ) )
1647 {
1648 TQString text = "<qt><b>" + i18n( "Warning" ) + "</b><br>";
1649 text += i18n( "The mobile phone book contains unsaved changes." ) +
1650 "<br></qt>";
1651
1652 TQMessageBox *msg = new TQMessageBox( i18n( "Unsaved Changes" ), text,
1653 TQMessageBox::Critical, 1, 2, 0, this );
1654 msg->setButtonText( 1, i18n( "Save" ) );
1655 msg->setButtonText( 2, i18n( "Discard" ) );
1656
1657 switch ( msg->exec() ) {
1658 case 1:
1659 // Save Changes first
1660 writePhonebook();
1661 return true;
1662 break;
1663
1664 case 2:
1665 return false;
1666 break;
1667 }
1668 }
1669
1670 return false;
1671}
This class provides an abstraction of an AT command.
Definition: atcommand.h:54
This class serves as the main window for MobileMain.
Definition: mobilemain.h:47