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