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.