22 #include "addresseditwidget.h"
24 #include "autoqpointer_p.h"
26 #include <QtCore/QEvent>
27 #include <QtCore/QList>
28 #include <QApplication>
29 #include <QButtonGroup>
32 #include <QGridLayout>
36 #include <QPushButton>
38 #include <kacceleratormanager.h>
39 #include <kcombobox.h>
42 #include <kinputdialog.h>
43 #include <klineedit.h>
45 #include <klocalizedstring.h>
47 #include <kmessagebox.h>
48 #include <kseparator.h>
49 #include <ktextedit.h>
53 struct LocaleAwareLessThan : std::binary_function<QString,QString,bool> {
54 bool operator()(
const QString &s1,
const QString &s2 )
const
56 return QString::localeAwareCompare( s1, s2 ) < 0 ;
60 class TabPressEater :
public QObject
63 TabPressEater( QObject *parent )
66 setObjectName( QLatin1String(
"TabPressEater" ) );
70 bool eventFilter( QObject*, QEvent *event )
72 if ( event->type() == QEvent::KeyPress ) {
73 QKeyEvent *keyEvent = (QKeyEvent*)event;
74 if ( keyEvent->key() == Qt::Key_Tab ) {
75 QApplication::sendEvent( parent(), event );
90 class AddressTypeDialog :
public KDialog
93 AddressTypeDialog( KABC::Address::Type type, QWidget *parent );
96 KABC::Address::Type type()
const;
101 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() ) );
152 : KComboBox( parent ),
153 mType( KABC::Address::Home ),
156 for (
int i = 0; i < KABC::Address::typeList().count(); ++i ) {
157 mTypeList.append( KABC::Address::typeList().at( i ) );
159 mTypeList.append( -1 );
163 connect(
this, SIGNAL(activated(
int)),
164 this, SLOT(selected(
int)) );
173 if ( !mTypeList.contains( (
int)type ) ) {
175 mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), (
int)
type );
187 void AddressTypeCombo::update()
189 bool blocked = signalsBlocked();
190 blockSignals(
true );
193 for (
int i = 0; i < mTypeList.count(); ++i ) {
194 if ( mTypeList.at( i ) == -1 ) {
195 addItem( i18nc(
"@item:inlistbox Category of contact info field",
"Other..." ) );
197 addItem( KABC::Address::typeLabel( KABC::Address::Type( mTypeList.at( i ) ) ) );
201 setCurrentIndex( mLastSelected = mTypeList.indexOf( mType ) );
203 blockSignals( blocked );
206 void AddressTypeCombo::selected(
int pos )
208 if ( mTypeList.at( pos ) == -1 ) {
211 mType = KABC::Address::Type( mTypeList.at( pos ) );
216 void AddressTypeCombo::otherSelected()
221 if ( !mTypeList.contains( mType ) ) {
222 mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), mType );
225 setType( KABC::Address::Type( mTypeList.at( mLastSelected ) ) );
231 AddressEditWidget::AddressEditWidget( QWidget *parent )
232 : QWidget( parent ), mReadOnly( false )
234 QGridLayout *layout =
new QGridLayout;
235 layout->setSpacing( KDialog::spacingHint() );
236 layout->setMargin( 0 );
238 QHBoxLayout *hboxLayout =
new QHBoxLayout;
239 QLabel *label =
new QLabel( i18nc(
"@label:listbox type of address",
"Address type:" ),
this );
240 hboxLayout->addWidget( label );
243 connect( mAddressSelectionWidget, SIGNAL(selectionChanged(KABC::Address)),
244 SLOT(updateAddressView()) );
245 label->setBuddy( mAddressSelectionWidget );
246 hboxLayout->addWidget( mAddressSelectionWidget, 1 );
247 layout->addLayout( hboxLayout, 0, 0, 1, 3 );
249 mAddressView =
new QLabel(
this );
250 mAddressView->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
251 mAddressView->setMinimumHeight( 20 );
252 mAddressView->setAlignment( Qt::AlignTop );
253 mAddressView->setTextFormat( Qt::PlainText );
254 mAddressView->setTextInteractionFlags( Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse );
255 layout->addWidget( mAddressView, 1, 0, 1, 3 );
257 mCreateButton =
new QPushButton( i18nc(
"@action:button street/postal",
"New..." ),
this );
258 connect( mCreateButton, SIGNAL(clicked()),
this, SLOT(createAddress()) );
259 mEditButton =
new QPushButton( i18nc(
"@action:button street/postal",
"Edit..." ),
this );
260 connect( mEditButton, SIGNAL(clicked()),
this, SLOT(editAddress()) );
261 mDeleteButton =
new QPushButton( i18nc(
"@action:button street/postal",
"Delete" ),
this );
262 connect( mDeleteButton, SIGNAL(clicked()),
this, SLOT(deleteAddress()) );
264 layout->addWidget( mCreateButton, 2, 0 );
265 layout->addWidget( mEditButton, 2, 1 );
266 layout->addWidget( mDeleteButton, 2, 2 );
271 AddressEditWidget::~AddressEditWidget()
275 void AddressEditWidget::setReadOnly(
bool readOnly )
277 if (mReadOnly != readOnly) {
278 mReadOnly = readOnly;
283 void AddressEditWidget::updateName(
const QString &name )
291 void AddressEditWidget::createAddress()
294 if ( dialog->exec() ) {
295 const KABC::Address address = dialog->address();
296 fixPreferredAddress( address );
297 mAddressList.append( address );
306 void AddressEditWidget::editAddress()
310 if ( dialog->exec() ) {
311 const KABC::Address address = dialog->address();
312 fixPreferredAddress( address );
313 mAddressList[ mAddressSelectionWidget->currentIndex() ] = address;
321 void AddressEditWidget::deleteAddress()
323 const int result = KMessageBox::questionYesNo(
this, i18n(
"Do you really want to delete this address?" ) );
325 if ( result != KMessageBox::Yes ) {
329 mAddressList.removeAt( mAddressSelectionWidget->currentIndex() );
335 void AddressEditWidget::fixPreferredAddress(
const KABC::Address &preferredAddress )
339 if ( preferredAddress.type() & KABC::Address::Pref ) {
340 for (
int i = 0; i < mAddressList.count(); ++i ) {
341 KABC::Address &address = mAddressList[ i ];
342 address.setType( address.type() & ~KABC::Address::Pref );
347 void AddressEditWidget::updateAddressView()
349 const KABC::Address address = mAddressSelectionWidget->
currentAddress();
351 if ( address.isEmpty() ) {
352 mAddressView->setText( QString() );
354 mAddressView->setText( address.formattedAddress( mName ) );
358 void AddressEditWidget::updateButtons()
360 mCreateButton->setEnabled( !mReadOnly );
361 mEditButton->setEnabled( !mReadOnly && ( mAddressList.count() > 0 ) );
362 mDeleteButton->setEnabled( !mReadOnly && ( mAddressList.count() > 0 ) );
365 void AddressEditWidget::loadContact(
const KABC::Addressee &contact )
367 mName = contact.realName();
368 mAddressList = contact.addresses();
373 for (
int i = 0; i < mAddressList.count(); ++i ) {
374 if ( mAddressList.at( i ).type() & KABC::Address::Pref ) {
384 void AddressEditWidget::storeContact( KABC::Addressee &contact )
const
387 const KABC::Address::List oldAddresses = contact.addresses();
388 for (
int i = 0; i < oldAddresses.count(); ++i ) {
389 contact.removeAddress( oldAddresses.at( i ) );
393 for (
int i = 0; i < mAddressList.count(); ++i ) {
394 const KABC::Address address( mAddressList.at( i ) );
395 if ( !address.isEmpty() ) {
396 contact.insertAddress( address );
401 AddressEditDialog::AddressEditDialog( QWidget *parent )
404 setCaption( i18nc(
"street/postal",
"Edit Address" ) );
405 setButtons( Ok | Cancel );
406 setDefaultButton( Ok );
407 showButtonSeparator(
true );
409 QWidget *page =
new QWidget(
this );
410 setMainWidget( page );
412 QGridLayout *topLayout =
new QGridLayout( page );
413 topLayout->setSpacing( spacingHint() );
414 topLayout->setMargin( 0 );
416 QLabel *label =
new QLabel( i18nc(
"@label:listbox type of address",
"Address type:" ),
this );
417 topLayout->addWidget( label, 0, 0 );
420 label->setBuddy( mTypeCombo );
421 topLayout->addWidget( mTypeCombo, 0, 1 );
423 label =
new QLabel( i18nc(
"<streetLabel>:",
"%1:", KABC::Address::streetLabel() ), page );
424 label->setAlignment( Qt::AlignTop | Qt::AlignLeft );
425 topLayout->addWidget( label, 1, 0 );
426 mStreetTextEdit =
new KTextEdit( page );
427 mStreetTextEdit->setAcceptRichText(
false );
428 label->setBuddy( mStreetTextEdit );
429 topLayout->addWidget( mStreetTextEdit, 1, 1 );
431 TabPressEater *eater =
new TabPressEater(
this );
432 mStreetTextEdit->installEventFilter( eater );
434 label =
new QLabel( i18nc(
"<postOfficeBoxLabel>:",
"%1:", KABC::Address::postOfficeBoxLabel() ), page );
435 topLayout->addWidget( label, 2 , 0 );
436 mPOBoxEdit =
new KLineEdit( page );
437 label->setBuddy( mPOBoxEdit );
438 topLayout->addWidget( mPOBoxEdit, 2, 1 );
440 label =
new QLabel( i18nc(
"<localityLabel>:",
"%1:", KABC::Address::localityLabel() ), page );
441 topLayout->addWidget( label, 3, 0 );
442 mLocalityEdit =
new KLineEdit( page );
443 label->setBuddy( mLocalityEdit );
444 topLayout->addWidget( mLocalityEdit, 3, 1 );
446 label =
new QLabel( i18nc(
"<regionLabel>:",
"%1:", KABC::Address::regionLabel() ), page );
447 topLayout->addWidget( label, 4, 0 );
448 mRegionEdit =
new KLineEdit( page );
449 label->setBuddy( mRegionEdit );
450 topLayout->addWidget( mRegionEdit, 4, 1 );
452 label =
new QLabel( i18nc(
"<postalCodeLabel>:",
"%1:", KABC::Address::postalCodeLabel() ), page );
453 topLayout->addWidget( label, 5, 0 );
454 mPostalCodeEdit =
new KLineEdit( page );
455 label->setBuddy( mPostalCodeEdit );
456 topLayout->addWidget( mPostalCodeEdit, 5, 1 );
458 label =
new QLabel( i18nc(
"<countryLabel>:",
"%1:", KABC::Address::countryLabel() ), page );
459 topLayout->addWidget( label, 6, 0 );
460 mCountryCombo =
new KComboBox( page );
461 mCountryCombo->setEditable(
true );
462 mCountryCombo->setDuplicatesEnabled(
false );
464 QPushButton *labelButton =
new QPushButton( i18n(
"Edit Label..." ), page );
465 topLayout->addWidget( labelButton, 7, 0, 1, 2 );
466 connect( labelButton, SIGNAL(clicked()), SLOT(editLabel()) );
469 label->setBuddy( mCountryCombo );
470 topLayout->addWidget( mCountryCombo, 6, 1 );
472 mPreferredCheckBox =
new QCheckBox( i18nc(
"street/postal",
"This is the preferred address" ), page );
473 topLayout->addWidget( mPreferredCheckBox, 8, 0, 1, 2 );
475 KHBox *buttonBox =
new KHBox( page );
476 buttonBox->setSpacing( spacingHint() );
477 topLayout->addWidget( buttonBox, 9, 0, 1, 2 );
479 KAcceleratorManager::manage(
this );
482 AddressEditDialog::~AddressEditDialog()
486 void AddressEditDialog::editLabel()
489 QString result = KInputDialog::getMultiLineText( KABC::Address::labelLabel(),
490 KABC::Address::labelLabel(),
497 void AddressEditDialog::setAddress(
const KABC::Address &address )
501 mTypeCombo->
setType( mAddress.type() );
502 mStreetTextEdit->setPlainText( mAddress.street() );
503 mRegionEdit->setText( mAddress.region() );
504 mLocalityEdit->setText( mAddress.locality() );
505 mPostalCodeEdit->setText( mAddress.postalCode() );
506 mPOBoxEdit->setText( mAddress.postOfficeBox() );
507 mLabel = mAddress.label();
508 mPreferredCheckBox->setChecked( mAddress.type() & KABC::Address::Pref );
510 if ( mAddress.isEmpty() ) {
511 mCountryCombo->setItemText( mCountryCombo->currentIndex(),
512 KGlobal::locale()->countryCodeToName( KGlobal::locale()->country() ) );
514 mCountryCombo->setItemText( mCountryCombo->currentIndex(), mAddress.country() );
517 mStreetTextEdit->setFocus();
520 KABC::Address AddressEditDialog::address()
const
522 KABC::Address address( mAddress );
524 address.setType( mTypeCombo->
type() );
525 address.setLocality( mLocalityEdit->text() );
526 address.setRegion( mRegionEdit->text() );
527 address.setPostalCode( mPostalCodeEdit->text() );
528 address.setCountry( mCountryCombo->currentText() );
529 address.setPostOfficeBox( mPOBoxEdit->text() );
530 address.setStreet( mStreetTextEdit->toPlainText() );
531 address.setLabel( mLabel );
533 if ( mPreferredCheckBox->isChecked() ) {
534 address.setType( address.type() | KABC::Address::Pref );
536 address.setType( address.type() & ~( KABC::Address::Pref ) );
542 void AddressEditDialog::fillCountryCombo()
544 QStringList countries;
546 foreach (
const QString &cc, KGlobal::locale()->allCountriesList() ) {
547 countries.append( KGlobal::locale()->countryCodeToName( cc ) );
550 qSort( countries.begin(), countries.end(), LocaleAwareLessThan() );
552 mCountryCombo->addItems( countries );
553 mCountryCombo->setAutoCompletion(
true );
554 mCountryCombo->completionObject()->setItems( countries );
555 mCountryCombo->completionObject()->setIgnoreCase(
true );
557 const QString currentCountry = KGlobal::locale()->countryCodeToName( KGlobal::locale()->country() );
558 mCountryCombo->setCurrentIndex( mCountryCombo->findText( currentCountry ) );
561 AddressTypeDialog::AddressTypeDialog( KABC::Address::Type type, QWidget *parent )
564 setCaption( i18nc(
"street/postal",
"Edit Address Type" ) );
565 setButtons( Ok | Cancel );
566 setDefaultButton( Ok );
568 QWidget *page =
new QWidget(
this );
569 setMainWidget( page );
570 QVBoxLayout *layout =
new QVBoxLayout( page );
571 layout->setSpacing( KDialog::spacingHint() );
572 layout->setMargin( 0 );
574 QGroupBox *box =
new QGroupBox( i18nc(
"street/postal",
"Address Types" ), page );
575 layout->addWidget( box );
576 mGroup =
new QButtonGroup( box );
577 mGroup->setExclusive (
false );
579 QGridLayout *buttonLayout =
new QGridLayout( box );
581 mTypeList = KABC::Address::typeList();
582 mTypeList.removeAll( KABC::Address::Pref );
584 KABC::Address::TypeList::ConstIterator it;
587 for ( it = mTypeList.constBegin(); it != mTypeList.constEnd(); ++it, ++i ) {
588 QCheckBox *cb =
new QCheckBox( KABC::Address::typeLabel( *it ), box );
589 cb->setChecked( type & mTypeList[ i ] );
590 buttonLayout->addWidget( cb, row, i%3 );
595 mGroup->addButton( cb );
599 AddressTypeDialog::~AddressTypeDialog()
603 KABC::Address::Type AddressTypeDialog::type()
const
605 KABC::Address::Type type;
606 for (
int i = 0; i < mGroup->buttons().count(); ++i ) {
607 QCheckBox *box =
dynamic_cast<QCheckBox*
>( mGroup->buttons().at( i ) );
608 if ( box && box->isChecked() ) {
609 type |= mTypeList[ i ];
void setType(KABC::Address::Type type)
Sets the type that shall be selected in the combobox.
AddressTypeCombo(QWidget *parent=0)
Creates a new address type combo.
~AddressTypeCombo()
Destroys the address type combo.
A QPointer which when destructed, deletes the object it points to.
KABC::Address::Type type() const
Returns the type that is currently selected.
Dialog for editing address details.