00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "phoneeditwidget.h"
00023
00024 #include <QtCore/QSignalMapper>
00025 #include <QtCore/QString>
00026 #include <QtGui/QButtonGroup>
00027 #include <QtGui/QCheckBox>
00028 #include <QtGui/QGridLayout>
00029 #include <QtGui/QGroupBox>
00030 #include <QtGui/QHBoxLayout>
00031 #include <QtGui/QPushButton>
00032 #include <QtGui/QScrollArea>
00033 #include <QtGui/QScrollBar>
00034 #include <QtGui/QVBoxLayout>
00035
00036 #include <kabc/phonenumber.h>
00037 #include <kcombobox.h>
00038 #include <kdebug.h>
00039 #include <klineedit.h>
00040 #include <klocale.h>
00041
00042 PhoneTypeCombo::PhoneTypeCombo( QWidget *parent )
00043 : KComboBox( parent ),
00044 mType( KABC::PhoneNumber::Home ),
00045 mLastSelected( 0 )
00046 {
00047 for ( int i = 0; i < KABC::PhoneNumber::typeList().count(); ++i )
00048 mTypeList.append( KABC::PhoneNumber::typeList().at( i ) );
00049
00050 mTypeList.append( -1 );
00051
00052 update();
00053
00054 connect( this, SIGNAL( activated( int ) ),
00055 this, SLOT( selected( int ) ) );
00056 }
00057
00058 PhoneTypeCombo::~PhoneTypeCombo()
00059 {
00060 }
00061
00062 void PhoneTypeCombo::setType( KABC::PhoneNumber::Type type )
00063 {
00064 if ( !mTypeList.contains( type ) )
00065 mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), type );
00066
00067 mType = type;
00068 update();
00069 }
00070
00071 KABC::PhoneNumber::Type PhoneTypeCombo::type() const
00072 {
00073 return mType;
00074 }
00075
00076 void PhoneTypeCombo::update()
00077 {
00078 clear();
00079
00080 for ( int i = 0; i < mTypeList.count(); ++i ) {
00081 if ( mTypeList.at( i ) == -1 )
00082 addItem( i18nc( "@item:inlistbox Category of contact info field", "Other..." ) );
00083 else
00084 addItem( KABC::PhoneNumber::typeLabel( KABC::PhoneNumber::Type( mTypeList.at( i ) ) ) );
00085 }
00086
00087 setCurrentIndex( mLastSelected = mTypeList.indexOf( mType ) );
00088 }
00089
00090 void PhoneTypeCombo::selected( int pos )
00091 {
00092 if ( mTypeList.at( pos ) == -1 )
00093 otherSelected();
00094 else {
00095 mType = KABC::PhoneNumber::Type( mTypeList.at( pos ) );
00096 mLastSelected = pos;
00097 }
00098 }
00099
00100 void PhoneTypeCombo::otherSelected()
00101 {
00102 PhoneTypeDialog dlg( mType, this );
00103 if ( dlg.exec() ) {
00104 mType = dlg.type();
00105 if ( !mTypeList.contains( mType ) )
00106 mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), mType );
00107 } else {
00108 setType( KABC::PhoneNumber::Type( mTypeList.at( mLastSelected ) ) );
00109 }
00110
00111 update();
00112 }
00113
00114 PhoneNumberWidget::PhoneNumberWidget( QWidget *parent )
00115 : QWidget( parent )
00116 {
00117 QHBoxLayout *layout = new QHBoxLayout( this );
00118 layout->setSpacing( 11 );
00119 layout->setMargin( 0 );
00120
00121 mTypeCombo = new PhoneTypeCombo( this );
00122 mNumberEdit = new KLineEdit( this );
00123
00124 layout->addWidget( mTypeCombo );
00125 layout->addWidget( mNumberEdit );
00126
00127 connect( mTypeCombo, SIGNAL( activated( int ) ), SIGNAL( modified() ) );
00128 connect( mNumberEdit, SIGNAL( textChanged( const QString& ) ), SIGNAL( modified() ) );
00129 }
00130
00131 void PhoneNumberWidget::setNumber( const KABC::PhoneNumber &number )
00132 {
00133 mNumber = number;
00134
00135 disconnect( mTypeCombo, SIGNAL( activated( int ) ), this, SIGNAL( modified() ) );
00136 mTypeCombo->setType( number.type() );
00137 connect( mTypeCombo, SIGNAL( activated( int ) ), SIGNAL( modified() ) );
00138
00139 mNumberEdit->setText( number.number() );
00140 }
00141
00142 KABC::PhoneNumber PhoneNumberWidget::number() const
00143 {
00144 KABC::PhoneNumber number( mNumber );
00145
00146 number.setType( mTypeCombo->type() );
00147 number.setNumber( mNumberEdit->text() );
00148
00149 return number;
00150 }
00151
00152 void PhoneNumberWidget::setReadOnly( bool readOnly )
00153 {
00154 mTypeCombo->setEnabled( !readOnly );
00155 mNumberEdit->setReadOnly( readOnly );
00156 }
00157
00158 PhoneNumberListWidget::PhoneNumberListWidget( QWidget *parent )
00159 : QWidget( parent ), mReadOnly( false )
00160 {
00161 mWidgetLayout = new QVBoxLayout( this );
00162
00163 mMapper = new QSignalMapper( this );
00164 connect( mMapper, SIGNAL( mapped( int ) ), SLOT( changed( int ) ) );
00165
00166 setPhoneNumbers( KABC::PhoneNumber::List() );
00167 }
00168
00169 PhoneNumberListWidget::~PhoneNumberListWidget()
00170 {
00171 }
00172
00173 void PhoneNumberListWidget::setReadOnly( bool readOnly )
00174 {
00175 mReadOnly = readOnly;
00176
00177 foreach ( PhoneNumberWidget *const widget, mWidgets )
00178 widget->setReadOnly( readOnly );
00179 }
00180
00181 int PhoneNumberListWidget::phoneNumberCount() const
00182 {
00183 return mPhoneNumberList.count();
00184 }
00185
00186 void PhoneNumberListWidget::setPhoneNumbers( const KABC::PhoneNumber::List &list )
00187 {
00188 mPhoneNumberList = list;
00189
00190 KABC::PhoneNumber::TypeList types;
00191 types << KABC::PhoneNumber::Home;
00192 types << KABC::PhoneNumber::Work;
00193 types << KABC::PhoneNumber::Cell;
00194
00195
00196 if ( mPhoneNumberList.count() < 3 )
00197 for ( int i = mPhoneNumberList.count(); i < 3; ++i )
00198 mPhoneNumberList.append( KABC::PhoneNumber( QString(), types[ i ] ) );
00199
00200 recreateNumberWidgets();
00201 }
00202
00203 KABC::PhoneNumber::List PhoneNumberListWidget::phoneNumbers() const
00204 {
00205 KABC::PhoneNumber::List list;
00206
00207 KABC::PhoneNumber::List::ConstIterator it;
00208 for ( it = mPhoneNumberList.constBegin(); it != mPhoneNumberList.constEnd(); ++it )
00209 if ( !(*it).number().isEmpty() )
00210 list.append( *it );
00211
00212 return list;
00213 }
00214
00215 void PhoneNumberListWidget::add()
00216 {
00217 mPhoneNumberList.append( KABC::PhoneNumber() );
00218
00219 recreateNumberWidgets();
00220 }
00221
00222 void PhoneNumberListWidget::remove()
00223 {
00224 mPhoneNumberList.removeLast();
00225
00226 recreateNumberWidgets();
00227 }
00228
00229 void PhoneNumberListWidget::recreateNumberWidgets()
00230 {
00231 foreach ( QWidget *const widget, mWidgets ) {
00232 mWidgetLayout->removeWidget( widget );
00233 delete widget;
00234 }
00235 mWidgets.clear();
00236
00237 KABC::PhoneNumber::List::ConstIterator it;
00238 int counter = 0;
00239 for ( it = mPhoneNumberList.constBegin(); it != mPhoneNumberList.constEnd(); ++it ) {
00240 PhoneNumberWidget *wdg = new PhoneNumberWidget( this );
00241 wdg->setNumber( *it );
00242
00243 mMapper->setMapping( wdg, counter );
00244 connect( wdg, SIGNAL( modified() ), mMapper, SLOT( map() ) );
00245
00246 mWidgetLayout->addWidget( wdg );
00247 mWidgets.append( wdg );
00248 wdg->show();
00249
00250 ++counter;
00251 }
00252
00253 setReadOnly( mReadOnly );
00254 }
00255
00256 void PhoneNumberListWidget::changed( int pos )
00257 {
00258 mPhoneNumberList[ pos ] = mWidgets.at( pos )->number();
00259 }
00260
00261 PhoneEditWidget::PhoneEditWidget( QWidget *parent )
00262 : QWidget( parent ), mReadOnly( false )
00263 {
00264 QGridLayout *layout = new QGridLayout( this );
00265 layout->setSpacing( KDialog::spacingHint() );
00266
00267 mListScrollArea = new QScrollArea( this );
00268 mPhoneNumberListWidget = new PhoneNumberListWidget;
00269 mListScrollArea->setWidget( mPhoneNumberListWidget );
00270 mListScrollArea->setWidgetResizable( true );
00271
00272
00273 const int scrollAreaMinHeight = mPhoneNumberListWidget->sizeHint().height() +
00274 mListScrollArea->horizontalScrollBar()->sizeHint().height();
00275 mListScrollArea->setMinimumHeight( scrollAreaMinHeight );
00276 layout->addWidget( mListScrollArea, 0, 0, 1, 2 );
00277
00278 mAddButton = new QPushButton( i18n( "Add" ), this );
00279 mAddButton->setMaximumSize( mAddButton->sizeHint() );
00280 layout->addWidget( mAddButton, 1, 0, Qt::AlignRight );
00281
00282 mRemoveButton = new QPushButton( i18n( "Remove" ), this );
00283 mRemoveButton->setMaximumSize( mRemoveButton->sizeHint() );
00284 layout->addWidget( mRemoveButton, 1, 1 );
00285
00286 connect( mAddButton, SIGNAL( clicked() ), mPhoneNumberListWidget, SLOT( add() ) );
00287 connect( mRemoveButton, SIGNAL( clicked() ), mPhoneNumberListWidget, SLOT( remove() ) );
00288 connect( mAddButton, SIGNAL( clicked() ), SLOT( changed() ) );
00289 connect( mRemoveButton, SIGNAL( clicked() ), SLOT( changed() ) );
00290 }
00291
00292 PhoneEditWidget::~PhoneEditWidget()
00293 {
00294 }
00295
00296 void PhoneEditWidget::setReadOnly( bool readOnly )
00297 {
00298 mReadOnly = readOnly;
00299 mAddButton->setEnabled( !readOnly );
00300 mRemoveButton->setEnabled( !readOnly && mPhoneNumberListWidget->phoneNumberCount() > 3 );
00301
00302 mPhoneNumberListWidget->setReadOnly( readOnly );
00303 }
00304
00305 void PhoneEditWidget::changed()
00306 {
00307 mRemoveButton->setEnabled( !mReadOnly && mPhoneNumberListWidget->phoneNumberCount() > 3 );
00308 }
00309
00310 void PhoneEditWidget::loadContact( const KABC::Addressee &contact )
00311 {
00312 mPhoneNumberListWidget->setPhoneNumbers( contact.phoneNumbers() );
00313 changed();
00314 }
00315
00316 void PhoneEditWidget::storeContact( KABC::Addressee &contact ) const
00317 {
00318 const KABC::PhoneNumber::List oldNumbers = contact.phoneNumbers();
00319 for ( int i = 0; i < oldNumbers.count(); ++i )
00320 contact.removePhoneNumber( oldNumbers.at( i ) );
00321
00322 const KABC::PhoneNumber::List newNumbers = mPhoneNumberListWidget->phoneNumbers();
00323 for ( int i = 0; i < newNumbers.count(); ++i )
00324 contact.insertPhoneNumber( newNumbers.at( i ) );
00325 }
00326
00328
00329 PhoneTypeDialog::PhoneTypeDialog( KABC::PhoneNumber::Type type, QWidget *parent )
00330 : KDialog( parent),
00331 mType( type )
00332 {
00333 setCaption( i18n( "Edit Phone Number" ) );
00334 setButtons( Ok | Cancel );
00335 setDefaultButton( Ok );
00336 showButtonSeparator( true );
00337
00338 QWidget *page = new QWidget( this );
00339 setMainWidget( page );
00340
00341 QVBoxLayout *layout = new QVBoxLayout( page );
00342 layout->setSpacing( spacingHint() );
00343 layout->setMargin( 0 );
00344
00345 mPreferredBox = new QCheckBox( i18n( "This is the preferred phone number" ), page );
00346 layout->addWidget( mPreferredBox );
00347
00348 QGroupBox *box = new QGroupBox( i18n( "Types" ), page );
00349 layout->addWidget( box );
00350
00351 QGridLayout *buttonLayout = new QGridLayout( box );
00352
00353
00354 mTypeList = KABC::PhoneNumber::typeList();
00355 mTypeList.removeAll( KABC::PhoneNumber::Pref );
00356
00357 KABC::PhoneNumber::TypeList::ConstIterator it;
00358 mGroup = new QButtonGroup( box );
00359 mGroup->setExclusive( false );
00360 int row, column, counter;
00361 row = column = counter = 0;
00362 for ( it = mTypeList.constBegin(); it != mTypeList.constEnd(); ++it, ++counter ) {
00363 QCheckBox *cb = new QCheckBox( KABC::PhoneNumber::typeLabel( *it ), box );
00364 cb->setChecked( type & mTypeList[ counter ] );
00365 buttonLayout->addWidget( cb, row, column );
00366 mGroup->addButton( cb );
00367
00368 column++;
00369 if ( column == 5 ) {
00370 column = 0;
00371 ++row;
00372 }
00373 }
00374
00375 mPreferredBox->setChecked( mType & KABC::PhoneNumber::Pref );
00376 }
00377
00378 KABC::PhoneNumber::Type PhoneTypeDialog::type() const
00379 {
00380 KABC::PhoneNumber::Type type = 0;
00381
00382 for ( int i = 0; i < mGroup->buttons().count(); ++i ) {
00383 QCheckBox *box = dynamic_cast<QCheckBox*>( mGroup->buttons().at( i ) ) ;
00384 if ( box && box->isChecked() )
00385 type |= mTypeList[ i ];
00386 }
00387
00388 if ( mPreferredBox->isChecked() )
00389 type = type | KABC::PhoneNumber::Pref;
00390 else
00391 type = type & ~KABC::PhoneNumber::Pref;
00392
00393 return type;
00394 }
00395
00396 #include "phoneeditwidget.moc"