kaddressbook Library API Documentation

phoneeditwidget.cpp

00001 /*
00002     This file is part of KAddressBook.
00003     Copyright (c) 2002 Mike Pilone <mpilone@slac.com>
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 #include <qlayout.h>
00025 #include <qlabel.h>
00026 #include <qtooltip.h>
00027 #include <qpushbutton.h>
00028 #include <qcheckbox.h>
00029 #include <qstring.h>
00030 #include <qlistbox.h>
00031 #include <qlistview.h>
00032 #include <qbuttongroup.h>
00033 
00034 #include <kbuttonbox.h>
00035 #include <klistview.h>
00036 #include <kapplication.h>
00037 #include <kconfig.h>
00038 #include <klineedit.h>
00039 #include <kcombobox.h>
00040 #include <klocale.h>
00041 #include <kdebug.h>
00042 #include <kiconloader.h>
00043 
00044 #include <kabc/phonenumber.h>
00045 
00046 #include "typecombo.h"
00047 
00048 #include "phoneeditwidget.h"
00049 #include <qvaluevector.h>
00050 
00051 PhoneEditWidget::PhoneEditWidget( QWidget *parent, const char *name )
00052   : QWidget( parent, name ), mReadOnly(false)
00053 {
00054   QGridLayout *layout = new QGridLayout( this, 5, 2 );
00055   layout->setSpacing( KDialog::spacingHint() );
00056 
00057   mPrefCombo = new PhoneTypeCombo( mPhoneList, this );
00058   mPrefEdit = new KLineEdit( this );
00059   mPrefEdit->setMinimumWidth( int(mPrefEdit->sizeHint().width() * 1.5) );
00060   mPrefCombo->setLineEdit( mPrefEdit );
00061   layout->addWidget( mPrefCombo, 0, 0 );
00062   layout->addWidget( mPrefEdit, 0, 1 );
00063 
00064   mSecondCombo = new PhoneTypeCombo( mPhoneList, this );
00065   mSecondEdit = new KLineEdit( this );
00066   mSecondCombo->setLineEdit( mSecondEdit );
00067   layout->addWidget( mSecondCombo, 1, 0 );
00068   layout->addWidget( mSecondEdit, 1, 1 );
00069 
00070   mThirdCombo = new PhoneTypeCombo( mPhoneList, this );
00071   mThirdEdit = new KLineEdit( this );
00072   mThirdCombo->setLineEdit( mThirdEdit );
00073   layout->addWidget( mThirdCombo, 2, 0 );
00074   layout->addWidget( mThirdEdit, 2, 1 );
00075 
00076   mFourthCombo = new PhoneTypeCombo( mPhoneList, this );
00077   mFourthEdit = new KLineEdit( this );
00078   mFourthCombo->setLineEdit( mFourthEdit );
00079   layout->addWidget( mFourthCombo, 3, 0 );
00080   layout->addWidget( mFourthEdit, 3, 1 );
00081 
00082   // Four numbers don't fit in the current dialog
00083   mFourthCombo->hide();
00084   mFourthEdit->hide();
00085 
00086   mEditButton = new QPushButton( i18n( "Edit Phone Numbers..." ), this );
00087   layout->addMultiCellWidget( mEditButton, 4, 4, 0, 1 );
00088 
00089   connect( mPrefEdit, SIGNAL( textChanged( const QString& ) ),
00090            SLOT( slotPrefEditChanged() ) );
00091   connect( mSecondEdit, SIGNAL( textChanged( const QString& ) ),
00092            SLOT( slotSecondEditChanged() ) );
00093   connect( mThirdEdit, SIGNAL( textChanged( const QString& ) ),
00094            SLOT( slotThirdEditChanged() ) );
00095   connect( mFourthEdit, SIGNAL( textChanged( const QString& ) ),
00096            SLOT( slotFourthEditChanged() ) );
00097 
00098   connect( mEditButton, SIGNAL( clicked() ), SLOT( edit() ) );
00099 
00100   connect( mPrefCombo, SIGNAL( activated( int ) ),
00101            SLOT( updatePrefEdit() ) );
00102   connect( mSecondCombo, SIGNAL( activated( int ) ),
00103            SLOT( updateSecondEdit() ) );
00104   connect( mThirdCombo, SIGNAL( activated( int ) ),
00105            SLOT( updateThirdEdit() ) );
00106   connect( mFourthCombo, SIGNAL( activated( int ) ),
00107            SLOT( updateFourthEdit() ) );
00108 }
00109 
00110 PhoneEditWidget::~PhoneEditWidget()
00111 {
00112 }
00113 
00114 void PhoneEditWidget::setReadOnly( bool readOnly )
00115 {
00116   mReadOnly = readOnly;
00117 
00118   mPrefEdit->setReadOnly( mReadOnly );
00119   mSecondEdit->setReadOnly( mReadOnly );
00120   mThirdEdit->setReadOnly( mReadOnly );
00121   mFourthEdit->setReadOnly( mReadOnly );
00122   mEditButton->setEnabled( !mReadOnly );
00123 }
00124 
00125 void PhoneEditWidget::setPhoneNumbers( const KABC::PhoneNumber::List &list )
00126 {
00127   mPhoneList.clear();
00128 
00129   // Insert types for existing numbers.
00130   mPrefCombo->insertTypeList( list );
00131 
00132   QValueList<int> defaultTypes;
00133   defaultTypes << KABC::PhoneNumber::Home;
00134   defaultTypes << KABC::PhoneNumber::Work;
00135   defaultTypes << KABC::PhoneNumber::Cell;
00136   defaultTypes << ( KABC::PhoneNumber::Work | KABC::PhoneNumber::Fax );
00137   defaultTypes << ( KABC::PhoneNumber::Home | KABC::PhoneNumber::Fax );
00138 
00139   // Insert default types.
00140   // Doing this for mPrefCombo is enough because the list is shared by all
00141   // combos.
00142   QValueList<int>::ConstIterator it;
00143   for( it = defaultTypes.begin(); it != defaultTypes.end(); ++it ) {
00144     if ( !mPrefCombo->hasType( *it ) )
00145       mPrefCombo->insertType( list, *it, PhoneNumber( "", *it ) );
00146   }
00147 
00148   updateCombos();
00149 
00150   // Select combo items for which we have a phone number in the list
00151   // and then switch to the defaultTypes (but not those we showed already)
00152   const int nr = list.count();
00153   QValueVector<int> selectedTypes( 4 );
00154   for ( int i = 0; i < QMIN( nr, 4 ); ++i ) {
00155     const int type = list[i].type();
00156     defaultTypes.remove( type );
00157     selectedTypes[i] = type;
00158   }
00159   int def = 0;
00160   for ( int i = QMIN( nr, 4 ); i < 4; ++i )
00161     selectedTypes[i] = defaultTypes[def++];
00162 
00163   mPrefCombo->selectType( selectedTypes[ 0 ] );
00164   mSecondCombo->selectType( selectedTypes[ 1 ] );
00165   mThirdCombo->selectType( selectedTypes[ 2 ] );
00166   mFourthCombo->selectType( selectedTypes[ 3 ] );
00167 
00168   updateLineEdits();
00169 }
00170 
00171 void PhoneEditWidget::updateLineEdits()
00172 {
00173   updatePrefEdit();
00174   updateSecondEdit();
00175   updateThirdEdit();
00176   updateFourthEdit();
00177 }
00178 
00179 void PhoneEditWidget::updateCombos()
00180 {
00181   mPrefCombo->updateTypes();
00182   mSecondCombo->updateTypes();
00183   mThirdCombo->updateTypes();
00184   mFourthCombo->updateTypes();
00185 }
00186 
00187 KABC::PhoneNumber::List PhoneEditWidget::phoneNumbers()
00188 {
00189   KABC::PhoneNumber::List retList;
00190 
00191   KABC::PhoneNumber::List::Iterator it;
00192   for ( it = mPhoneList.begin(); it != mPhoneList.end(); ++it )
00193     if ( !(*it).number().isEmpty() )
00194       retList.append( *it );
00195 
00196   return retList;
00197 }
00198 
00199 void PhoneEditWidget::edit()
00200 {
00201   PhoneEditDialog dlg( mPhoneList, this );
00202 
00203   if ( dlg.exec() ) {
00204     if ( dlg.changed() ) {
00205       mPhoneList = dlg.phoneNumbers();
00206       updateCombos();
00207       emit modified();
00208     }
00209   }
00210 }
00211 
00212 void PhoneEditWidget::updatePrefEdit()
00213 {
00214   updateEdit( mPrefCombo );
00215 }
00216 
00217 void PhoneEditWidget::updateSecondEdit()
00218 {
00219   updateEdit( mSecondCombo );
00220 }
00221 
00222 void PhoneEditWidget::updateThirdEdit()
00223 {
00224   updateEdit( mThirdCombo );
00225 }
00226 
00227 void PhoneEditWidget::updateFourthEdit()
00228 {
00229   updateEdit( mFourthCombo );
00230 }
00231 
00232 void PhoneEditWidget::updateEdit( PhoneTypeCombo *combo )
00233 {
00234   QLineEdit *edit = combo->lineEdit();
00235   if ( !edit )
00236     return;
00237 
00238 #if 0
00239   if ( edit == mPrefEdit ) kdDebug(5720) << " prefEdit" << endl;
00240   if ( edit == mSecondEdit ) kdDebug(5720) << " secondEdit" << endl;
00241   if ( edit == mThirdEdit ) kdDebug(5720) << " thirdEdit" << endl;
00242   if ( edit == mFourthEdit ) kdDebug(5720) << " fourthEdit" << endl;
00243 #endif
00244 
00245   PhoneNumber::List::Iterator it = combo->selectedElement();
00246   if ( it != mPhoneList.end() ) {
00247     int pos = edit->cursorPosition();
00248     edit->setText( (*it).number() );
00249     edit->setCursorPosition( pos );
00250   } else {
00251     kdDebug(5720) << "PhoneEditWidget::updateEdit(): no selected element" << endl;
00252   }
00253 }
00254 
00255 void PhoneEditWidget::slotPrefEditChanged()
00256 {
00257   updatePhoneNumber( mPrefCombo );
00258 }
00259 
00260 void PhoneEditWidget::slotSecondEditChanged()
00261 {
00262   updatePhoneNumber( mSecondCombo );
00263 }
00264 
00265 void PhoneEditWidget::slotThirdEditChanged()
00266 {
00267   updatePhoneNumber( mThirdCombo );
00268 }
00269 
00270 void PhoneEditWidget::slotFourthEditChanged()
00271 {
00272   updatePhoneNumber( mFourthCombo );
00273 }
00274 
00275 void PhoneEditWidget::updatePhoneNumber( PhoneTypeCombo *combo )
00276 {
00277   QLineEdit *edit = combo->lineEdit();
00278   if ( !edit ) return;
00279 
00280   PhoneNumber::List::Iterator it = combo->selectedElement();
00281   if ( it != mPhoneList.end() ) {
00282     (*it).setNumber( edit->text() );
00283   } else {
00284     kdDebug(5720) << "PhoneEditWidget::updatePhoneNumber(): no selected element"
00285               << endl;
00286   }
00287 
00288   updateOtherEdit( combo, mPrefCombo );
00289   updateOtherEdit( combo, mSecondCombo );
00290   updateOtherEdit( combo, mThirdCombo );
00291   updateOtherEdit( combo, mFourthCombo );
00292 
00293   if ( !mReadOnly )
00294     emit modified();
00295 }
00296 
00297 void PhoneEditWidget::updateOtherEdit( PhoneTypeCombo *combo, PhoneTypeCombo *otherCombo )
00298 {
00299   if ( combo == otherCombo ) return;
00300 
00301   if ( combo->currentItem() == otherCombo->currentItem() ) {
00302     updateEdit( otherCombo );
00303   }
00304 }
00305 
00307 // PhoneEditDialog
00308 
00309 class PhoneViewItem : public QListViewItem
00310 {
00311 public:
00312   PhoneViewItem( QListView *parent, const KABC::PhoneNumber &number );
00313 
00314   void setPhoneNumber( const KABC::PhoneNumber &number )
00315   {
00316     mPhoneNumber = number;
00317     makeText();
00318   }
00319 
00320   QString key() { return mPhoneNumber.id(); }
00321   QString country() { return ""; }
00322   QString region() { return ""; }
00323   QString number() { return ""; }
00324 
00325   KABC::PhoneNumber phoneNumber() { return mPhoneNumber; }
00326 
00327 private:
00328   void makeText();
00329 
00330   KABC::PhoneNumber mPhoneNumber;
00331 };
00332 
00333 PhoneViewItem::PhoneViewItem( QListView *parent, const KABC::PhoneNumber &number )
00334   : QListViewItem( parent ), mPhoneNumber( number )
00335 {
00336   makeText();
00337 }
00338 
00339 void PhoneViewItem::makeText()
00340 {
00350   setText( 0, mPhoneNumber.number() );
00351   setText( 1, mPhoneNumber.typeLabel() );
00352 }
00353 
00354 PhoneEditDialog::PhoneEditDialog( const KABC::PhoneNumber::List &list, QWidget *parent, const char *name )
00355   : KDialogBase( KDialogBase::Plain, i18n( "Edit Phone Numbers" ),
00356                  KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00357                  parent, name, true)
00358 {
00359   mPhoneNumberList = list;
00360 
00361   QWidget *page = plainPage();
00362 
00363   QGridLayout *layout = new QGridLayout( page, 1, 2 );
00364   layout->setSpacing( spacingHint() );
00365 
00366   mListView = new KListView( page );
00367   mListView->setAllColumnsShowFocus( true );
00368   mListView->addColumn( i18n( "Number" ) );
00369   mListView->addColumn( i18n( "Type" ) );
00370 
00371   KButtonBox *buttonBox = new KButtonBox( page, Vertical );
00372 
00373   buttonBox->addButton( i18n( "&Add..." ), this, SLOT( slotAddPhoneNumber() ) );
00374   mEditButton = buttonBox->addButton( i18n( "&Edit..." ), this, SLOT( slotEditPhoneNumber() ) );
00375   mEditButton->setEnabled( false );
00376   mRemoveButton = buttonBox->addButton( i18n( "&Remove" ), this, SLOT( slotRemovePhoneNumber() ) );
00377   mRemoveButton->setEnabled( false );
00378   buttonBox->layout();
00379 
00380   layout->addWidget( mListView, 0, 0 );
00381   layout->addWidget( buttonBox, 0, 1 );
00382 
00383   connect( mListView, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()) );
00384   connect( mListView, SIGNAL(doubleClicked( QListViewItem *, const QPoint &, int  )), this, SLOT( slotEditPhoneNumber()));
00385 
00386   KABC::PhoneNumber::List::Iterator it;
00387   for ( it = mPhoneNumberList.begin(); it != mPhoneNumberList.end(); ++it )
00388     new PhoneViewItem( mListView, *it );
00389 
00390   mChanged = false;
00391 }
00392 
00393 PhoneEditDialog::~PhoneEditDialog()
00394 {
00395 }
00396 
00397 void PhoneEditDialog::slotAddPhoneNumber()
00398 {
00399   KABC::PhoneNumber tmp( "", 0 );
00400   PhoneTypeDialog dlg( tmp, this );
00401 
00402   if ( dlg.exec() ) {
00403     KABC::PhoneNumber phoneNumber = dlg.phoneNumber();
00404     mPhoneNumberList.append( phoneNumber );
00405     new PhoneViewItem( mListView, phoneNumber );
00406 
00407     mChanged = true;
00408   }
00409 }
00410 
00411 void PhoneEditDialog::slotRemovePhoneNumber()
00412 {
00413   PhoneViewItem *item = static_cast<PhoneViewItem*>( mListView->currentItem() );
00414   if ( !item )
00415     return;
00416 
00417   mPhoneNumberList.remove( item->phoneNumber() );
00418   QListViewItem *currItem = mListView->currentItem();
00419   mListView->takeItem( currItem );
00420   delete currItem;
00421 
00422   mChanged = true;
00423 }
00424 
00425 void PhoneEditDialog::slotEditPhoneNumber()
00426 {
00427   PhoneViewItem *item = static_cast<PhoneViewItem*>( mListView->currentItem() );
00428   if ( !item )
00429     return;
00430 
00431   PhoneTypeDialog dlg( item->phoneNumber(), this );
00432 
00433   if ( dlg.exec() ) {
00434     slotRemovePhoneNumber();
00435     KABC::PhoneNumber phoneNumber = dlg.phoneNumber();
00436     mPhoneNumberList.append( phoneNumber );
00437     new PhoneViewItem( mListView, phoneNumber );
00438 
00439     mChanged = true;
00440   }
00441 }
00442 
00443 void PhoneEditDialog::slotSelectionChanged()
00444 {
00445   bool state = ( mListView->currentItem() != 0 );
00446 
00447   mRemoveButton->setEnabled( state );
00448   mEditButton->setEnabled( state );
00449 }
00450 
00451 const KABC::PhoneNumber::List &PhoneEditDialog::phoneNumbers()
00452 {
00453   return mPhoneNumberList;
00454 }
00455 
00456 bool PhoneEditDialog::changed() const
00457 {
00458   return mChanged;
00459 }
00460 
00462 // PhoneTypeDialog
00463 PhoneTypeDialog::PhoneTypeDialog( const KABC::PhoneNumber &phoneNumber,
00464                                QWidget *parent, const char *name)
00465   : KDialogBase( KDialogBase::Plain, i18n( "Edit Phone Number" ),
00466                 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00467                 parent, name, true), mPhoneNumber( phoneNumber )
00468 {
00469   QWidget *page = plainPage();
00470   QLabel *label = 0;
00471   QGridLayout *layout = new QGridLayout( page, 3, 2, marginHint(), spacingHint() );
00472 
00473   label = new QLabel( i18n( "Number:" ), page );
00474   layout->addWidget( label, 0, 0 );
00475   mNumber = new KLineEdit( page );
00476   layout->addWidget( mNumber, 0, 1 );
00477 
00478   mPreferredBox = new QCheckBox( i18n( "This is the preferred phone number" ), page );
00479   layout->addMultiCellWidget( mPreferredBox, 1, 1, 0, 1 );
00480 
00481   mGroup = new QButtonGroup( 2, Horizontal, i18n( "Types" ), page );
00482   layout->addMultiCellWidget( mGroup, 2, 2, 0, 1 );
00483 
00484   // fill widgets
00485   mNumber->setText( mPhoneNumber.number() );
00486 
00487   mTypeList = KABC::PhoneNumber::typeList();
00488   mTypeList.remove( KABC::PhoneNumber::Pref );
00489 
00490   KABC::PhoneNumber::TypeList::Iterator it;
00491   for ( it = mTypeList.begin(); it != mTypeList.end(); ++it )
00492     new QCheckBox( KABC::PhoneNumber::typeLabel( *it ), mGroup );
00493 
00494   for ( int i = 0; i < mGroup->count(); ++i ) {
00495     int type = mPhoneNumber.type();
00496     QCheckBox *box = (QCheckBox*)mGroup->find( i );
00497     box->setChecked( type & mTypeList[ i ] );
00498   }
00499 
00500   mPreferredBox->setChecked( mPhoneNumber.type() & KABC::PhoneNumber::Pref );
00501 }
00502 
00503 KABC::PhoneNumber PhoneTypeDialog::phoneNumber()
00504 {
00505   mPhoneNumber.setNumber( mNumber->text() );
00506 
00507   int type = 0;
00508   for ( int i = 0; i < mGroup->count(); ++i ) {
00509     QCheckBox *box = (QCheckBox*)mGroup->find( i );
00510     if ( box->isChecked() )
00511       type += mTypeList[ i ];
00512   }
00513 
00514   if ( mPreferredBox->isChecked() )
00515     mPhoneNumber.setType( type | KABC::PhoneNumber::Pref );
00516   else
00517     mPhoneNumber.setType( type & ~KABC::PhoneNumber::Pref );
00518 
00519   return mPhoneNumber;
00520 }
00521 
00522 
00523 #include "phoneeditwidget.moc"
KDE Logo
This file is part of the documentation for kaddressbook Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Aug 2 09:54:31 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003