22 #include "addresseditwidget.h"
24 #include "autoqpointer_p.h"
26 #include <QtCore/QEvent>
27 #include <QtCore/QList>
28 #include <QApplication>
30 #include <QButtonGroup>
33 #include <QGridLayout>
37 #include <QPushButton>
39 #include <kacceleratormanager.h>
40 #include <kcombobox.h>
43 #include <kinputdialog.h>
44 #include <klineedit.h>
46 #include <kmessagebox.h>
47 #include <kseparator.h>
48 #include <ktextedit.h>
52 struct LocaleAwareLessThan : std::binary_function<QString,QString,bool> {
53 bool operator()(
const QString &s1,
const QString &s2 )
const
55 return QString::localeAwareCompare( s1, s2 ) < 0 ;
59 class TabPressEater :
public QObject
62 TabPressEater( QObject *parent )
65 setObjectName( QLatin1String(
"TabPressEater" ) );
69 bool eventFilter( QObject*, QEvent *event )
71 if ( event->type() == QEvent::KeyPress ) {
72 QKeyEvent *keyEvent = (QKeyEvent*)event;
73 if ( keyEvent->key() == Qt::Key_Tab ) {
74 QApplication::sendEvent( parent(), event );
89 class AddressTypeDialog :
public KDialog
92 AddressTypeDialog( KABC::Address::Type type, QWidget *parent );
95 KABC::Address::Type type()
const;
100 KABC::Address::TypeList mTypeList;
105 : KComboBox( parent )
107 connect(
this, SIGNAL(activated(
int)), SLOT(selected(
int)) );
116 mAddresses = addresses;
122 const int index = mAddresses.indexOf( address );
124 setCurrentIndex( index );
130 if ( currentIndex() != -1 && currentIndex() < mAddresses.count() ) {
131 return mAddresses.at( currentIndex() );
133 return KABC::Address();
137 void AddressSelectionWidget::selected(
int index )
139 Q_ASSERT( index != -1 && index < mAddresses.count() );
143 void AddressSelectionWidget::updateView()
146 for (
int i = 0; i < mAddresses.count(); ++i ) {
147 addItem( KABC::Address::typeLabel( mAddresses.at( i ).type() ) );
154 : KComboBox( parent ),
155 mType( KABC::Address::Home ),
158 for (
int i = 0; i < KABC::Address::typeList().count(); ++i ) {
159 mTypeList.append( KABC::Address::typeList().at( i ) );
161 mTypeList.append( -1 );
165 connect(
this, SIGNAL(activated(
int)),
166 this, SLOT(selected(
int)) );
175 if ( !mTypeList.contains( (
int)type ) ) {
177 mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), (
int)
type );
189 void AddressTypeCombo::update()
191 bool blocked = signalsBlocked();
192 blockSignals(
true );
195 for (
int i = 0; i < mTypeList.count(); ++i ) {
196 if ( mTypeList.at( i ) == -1 ) {
197 addItem( i18nc(
"@item:inlistbox Category of contact info field",
"Other..." ) );
199 addItem( KABC::Address::typeLabel( KABC::Address::Type( mTypeList.at( i ) ) ) );
203 setCurrentIndex( mLastSelected = mTypeList.indexOf( mType ) );
205 blockSignals( blocked );
208 void AddressTypeCombo::selected(
int pos )
210 if ( mTypeList.at( pos ) == -1 ) {
213 mType = KABC::Address::Type( mTypeList.at( pos ) );
218 void AddressTypeCombo::otherSelected()
223 if ( !mTypeList.contains( mType ) ) {
224 mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), mType );
227 setType( KABC::Address::Type( mTypeList.at( mLastSelected ) ) );
234 AddressEditWidget::AddressEditWidget( QWidget *parent )
235 : QWidget( parent ), mReadOnly( false )
237 QGridLayout *layout =
new QGridLayout(
this );
238 layout->setSpacing( KDialog::spacingHint() );
239 layout->setMargin( 0 );
242 connect( mAddressSelectionWidget, SIGNAL(selectionChanged(KABC::Address)),
243 SLOT(updateAddressView()) );
244 layout->addWidget( mAddressSelectionWidget, 0, 0, 1, 3 );
246 mAddressView =
new QLabel(
this );
247 mAddressView->setFrameStyle( QFrame::Panel | QFrame::Sunken );
248 mAddressView->setMinimumHeight( 20 );
249 mAddressView->setAlignment( Qt::AlignTop );
250 mAddressView->setTextFormat( Qt::PlainText );
251 mAddressView->setTextInteractionFlags( Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse );
252 layout->addWidget( mAddressView, 1, 0, 1, 3 );
254 mCreateButton =
new QPushButton( i18nc(
"street/postal",
"New..." ),
this );
255 connect( mCreateButton, SIGNAL(clicked()),
this, SLOT(createAddress()) );
256 mEditButton =
new QPushButton( i18nc(
"street/postal",
"Edit..." ),
this );
257 connect( mEditButton, SIGNAL(clicked()),
this, SLOT(editAddress()) );
258 mDeleteButton =
new QPushButton( i18nc(
"street/postal",
"Delete" ),
this );
259 connect( mDeleteButton, SIGNAL(clicked()),
this, SLOT(deleteAddress()) );
261 layout->addWidget( mCreateButton, 2, 0 );
262 layout->addWidget( mEditButton, 2, 1 );
263 layout->addWidget( mDeleteButton, 2, 2 );
268 AddressEditWidget::~AddressEditWidget()
272 void AddressEditWidget::setReadOnly(
bool readOnly )
274 mReadOnly = readOnly;
278 void AddressEditWidget::updateName(
const QString &name )
284 void AddressEditWidget::createAddress()
287 if ( dialog->exec() ) {
288 const KABC::Address address = dialog->address();
289 fixPreferredAddress( address );
290 mAddressList.append( address );
299 void AddressEditWidget::editAddress()
303 if ( dialog->exec() ) {
304 const KABC::Address address = dialog->address();
305 fixPreferredAddress( address );
306 mAddressList[ mAddressSelectionWidget->currentIndex() ] = address;
314 void AddressEditWidget::deleteAddress()
316 const int result = KMessageBox::questionYesNo(
this, i18n(
"Do you really want to delete this address?" ) );
318 if ( result != KMessageBox::Yes ) {
322 mAddressList.removeAt( mAddressSelectionWidget->currentIndex() );
328 void AddressEditWidget::fixPreferredAddress(
const KABC::Address &preferredAddress )
332 if ( preferredAddress.type() & KABC::Address::Pref ) {
333 for (
int i = 0; i < mAddressList.count(); ++i ) {
334 KABC::Address &address = mAddressList[ i ];
335 address.setType( address.type() & ~KABC::Address::Pref );
340 void AddressEditWidget::updateAddressView()
342 const KABC::Address address = mAddressSelectionWidget->
currentAddress();
344 if ( address.isEmpty() ) {
345 mAddressView->setText( QString() );
347 mAddressView->setText( address.formattedAddress( mName ) );
351 void AddressEditWidget::updateButtons()
353 mCreateButton->setEnabled( !mReadOnly );
354 mEditButton->setEnabled( !mReadOnly && ( mAddressList.count() > 0 ) );
355 mDeleteButton->setEnabled( !mReadOnly && ( mAddressList.count() > 0 ) );
358 void AddressEditWidget::loadContact(
const KABC::Addressee &contact )
360 mName = contact.realName();
361 mAddressList = contact.addresses();
366 for (
int i = 0; i < mAddressList.count(); ++i ) {
367 if ( mAddressList.at( i ).type() & KABC::Address::Pref ) {
377 void AddressEditWidget::storeContact( KABC::Addressee &contact )
const
380 const KABC::Address::List oldAddresses = contact.addresses();
381 for (
int i = 0; i < oldAddresses.count(); ++i ) {
382 contact.removeAddress( oldAddresses.at( i ) );
386 for (
int i = 0; i < mAddressList.count(); ++i ) {
387 const KABC::Address address( mAddressList.at( i ) );
388 if ( !address.isEmpty() ) {
389 contact.insertAddress( address );
395 AddressEditDialog::AddressEditDialog( QWidget *parent )
398 setCaption( i18nc(
"street/postal",
"Edit Address" ) );
399 setButtons( Ok | Cancel );
400 setDefaultButton( Ok );
401 showButtonSeparator(
true );
403 QWidget *page =
new QWidget(
this );
404 setMainWidget( page );
406 QGridLayout *topLayout =
new QGridLayout( page );
407 topLayout->setSpacing( spacingHint() );
408 topLayout->setMargin( 0 );
411 topLayout->addWidget( mTypeCombo, 0, 0, 1, 2 );
413 QLabel *label =
new QLabel( i18nc(
"<streetLabel>:",
"%1:", KABC::Address::streetLabel() ), page );
414 label->setAlignment( Qt::AlignTop | Qt::AlignLeft );
415 topLayout->addWidget( label, 1, 0 );
416 mStreetTextEdit =
new KTextEdit( page );
417 mStreetTextEdit->setAcceptRichText(
false );
418 label->setBuddy( mStreetTextEdit );
419 topLayout->addWidget( mStreetTextEdit, 1, 1 );
421 TabPressEater *eater =
new TabPressEater(
this );
422 mStreetTextEdit->installEventFilter( eater );
424 label =
new QLabel( i18nc(
"<postOfficeBoxLabel>:",
"%1:", KABC::Address::postOfficeBoxLabel() ), page );
425 topLayout->addWidget( label, 2 , 0 );
426 mPOBoxEdit =
new KLineEdit( page );
427 label->setBuddy( mPOBoxEdit );
428 topLayout->addWidget( mPOBoxEdit, 2, 1 );
430 label =
new QLabel( i18nc(
"<localityLabel>:",
"%1:", KABC::Address::localityLabel() ), page );
431 topLayout->addWidget( label, 3, 0 );
432 mLocalityEdit =
new KLineEdit( page );
433 label->setBuddy( mLocalityEdit );
434 topLayout->addWidget( mLocalityEdit, 3, 1 );
436 label =
new QLabel( i18nc(
"<regionLabel>:",
"%1:", KABC::Address::regionLabel() ), page );
437 topLayout->addWidget( label, 4, 0 );
438 mRegionEdit =
new KLineEdit( page );
439 label->setBuddy( mRegionEdit );
440 topLayout->addWidget( mRegionEdit, 4, 1 );
442 label =
new QLabel( i18nc(
"<postalCodeLabel>:",
"%1:", KABC::Address::postalCodeLabel() ), page );
443 topLayout->addWidget( label, 5, 0 );
444 mPostalCodeEdit =
new KLineEdit( page );
445 label->setBuddy( mPostalCodeEdit );
446 topLayout->addWidget( mPostalCodeEdit, 5, 1 );
448 label =
new QLabel( i18nc(
"<countryLabel>:",
"%1:", KABC::Address::countryLabel() ), page );
449 topLayout->addWidget( label, 6, 0 );
450 mCountryCombo =
new KComboBox( page );
451 mCountryCombo->setEditable(
true );
452 mCountryCombo->setDuplicatesEnabled(
false );
454 QPushButton *labelButton =
new QPushButton( i18n(
"Edit Label..." ), page );
455 topLayout->addWidget( labelButton, 7, 0, 1, 2 );
456 connect( labelButton, SIGNAL(clicked()), SLOT(editLabel()) );
459 label->setBuddy( mCountryCombo );
460 topLayout->addWidget( mCountryCombo, 6, 1 );
462 mPreferredCheckBox =
new QCheckBox( i18nc(
"street/postal",
"This is the preferred address" ), page );
463 topLayout->addWidget( mPreferredCheckBox, 8, 0, 1, 2 );
465 KSeparator *sep =
new KSeparator( Qt::Horizontal, page );
466 topLayout->addWidget( sep, 9, 0, 1, 2 );
468 KHBox *buttonBox =
new KHBox( page );
469 buttonBox->setSpacing( spacingHint() );
470 topLayout->addWidget( buttonBox, 10, 0, 1, 2 );
472 KAcceleratorManager::manage(
this );
475 AddressEditDialog::~AddressEditDialog()
479 void AddressEditDialog::editLabel()
482 QString result = KInputDialog::getMultiLineText( KABC::Address::labelLabel(),
483 KABC::Address::labelLabel(),
490 void AddressEditDialog::setAddress(
const KABC::Address &address )
494 mTypeCombo->
setType( mAddress.type() );
495 mStreetTextEdit->setPlainText( mAddress.street() );
496 mRegionEdit->setText( mAddress.region() );
497 mLocalityEdit->setText( mAddress.locality() );
498 mPostalCodeEdit->setText( mAddress.postalCode() );
499 mPOBoxEdit->setText( mAddress.postOfficeBox() );
500 mLabel = mAddress.label();
501 mPreferredCheckBox->setChecked( mAddress.type() & KABC::Address::Pref );
503 if ( mAddress.isEmpty() ) {
504 mCountryCombo->setItemText( mCountryCombo->currentIndex(),
505 KGlobal::locale()->countryCodeToName( KGlobal::locale()->country() ) );
507 mCountryCombo->setItemText( mCountryCombo->currentIndex(), mAddress.country() );
510 mStreetTextEdit->setFocus();
513 KABC::Address AddressEditDialog::address()
const
515 KABC::Address address( mAddress );
517 address.setType( mTypeCombo->
type() );
518 address.setLocality( mLocalityEdit->text() );
519 address.setRegion( mRegionEdit->text() );
520 address.setPostalCode( mPostalCodeEdit->text() );
521 address.setCountry( mCountryCombo->currentText() );
522 address.setPostOfficeBox( mPOBoxEdit->text() );
523 address.setStreet( mStreetTextEdit->toPlainText() );
524 address.setLabel( mLabel );
526 if ( mPreferredCheckBox->isChecked() ) {
527 address.setType( address.type() | KABC::Address::Pref );
529 address.setType( address.type() & ~( KABC::Address::Pref ) );
535 void AddressEditDialog::fillCountryCombo()
537 QStringList countries;
539 foreach (
const QString &cc, KGlobal::locale()->allCountriesList() ) {
540 countries.append( KGlobal::locale()->countryCodeToName( cc ) );
543 qSort( countries.begin(), countries.end(), LocaleAwareLessThan() );
545 mCountryCombo->addItems( countries );
546 mCountryCombo->setAutoCompletion(
true );
547 mCountryCombo->completionObject()->setItems( countries );
548 mCountryCombo->completionObject()->setIgnoreCase(
true );
550 const QString currentCountry = KGlobal::locale()->countryCodeToName( KGlobal::locale()->country() );
551 mCountryCombo->setCurrentIndex( mCountryCombo->findText( currentCountry ) );
555 AddressTypeDialog::AddressTypeDialog( KABC::Address::Type type, QWidget *parent )
558 setCaption( i18nc(
"street/postal",
"Edit Address Type" ) );
559 setButtons( Ok | Cancel );
560 setDefaultButton( Ok );
562 QWidget *page =
new QWidget(
this );
563 setMainWidget( page );
564 QVBoxLayout *layout =
new QVBoxLayout( page );
565 layout->setSpacing( KDialog::spacingHint() );
566 layout->setMargin( 0 );
568 QGroupBox *box =
new QGroupBox( i18nc(
"street/postal",
"Address Types" ), page );
569 layout->addWidget( box );
570 mGroup =
new QButtonGroup( box );
571 mGroup->setExclusive (
false );
573 QGridLayout *buttonLayout =
new QGridLayout( box );
575 mTypeList = KABC::Address::typeList();
576 mTypeList.removeAll( KABC::Address::Pref );
578 KABC::Address::TypeList::ConstIterator it;
581 for ( it = mTypeList.constBegin(); it != mTypeList.constEnd(); ++it, ++i ) {
582 QCheckBox *cb =
new QCheckBox( KABC::Address::typeLabel( *it ), box );
583 cb->setChecked( type & mTypeList[ i ] );
584 buttonLayout->addWidget( cb, row, i%3 );
589 mGroup->addButton( cb );
593 AddressTypeDialog::~AddressTypeDialog()
597 KABC::Address::Type AddressTypeDialog::type()
const
599 KABC::Address::Type type;
600 for (
int i = 0; i < mGroup->buttons().count(); ++i ) {
601 QCheckBox *box =
dynamic_cast<QCheckBox*
>( mGroup->buttons().at( i ) );
602 if ( box && box->isChecked() ) {
603 type |= mTypeList[ i ];