• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.9.4 API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • akonadi
  • contact
  • editor
addresseditwidget.cpp
1 /*
2  This file is part of Akonadi Contact.
3 
4  Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
5 
6  This library is free software; you can redistribute it and/or modify it
7  under the terms of the GNU Library General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or (at your
9  option) any later version.
10 
11  This library is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14  License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to the
18  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301, USA.
20 */
21 
22 #include "addresseditwidget.h"
23 
24 #include "autoqpointer_p.h"
25 
26 #include <QtCore/QEvent>
27 #include <QtCore/QList>
28 #include <QtGui/QApplication>
29 #include <QtGui/QBoxLayout>
30 #include <QtGui/QButtonGroup>
31 #include <QtGui/QCheckBox>
32 #include <QtGui/QFrame>
33 #include <QtGui/QGridLayout>
34 #include <QtGui/QGroupBox>
35 #include <QtGui/QKeyEvent>
36 #include <QtGui/QLabel>
37 #include <QtGui/QPushButton>
38 
39 #include <kacceleratormanager.h>
40 #include <kcombobox.h>
41 #include <kdebug.h>
42 #include <khbox.h>
43 #include <kinputdialog.h>
44 #include <klineedit.h>
45 #include <klocale.h>
46 #include <kmessagebox.h>
47 #include <kseparator.h>
48 #include <ktextedit.h>
49 
50 #include <functional>
51 
52 struct LocaleAwareLessThan : std::binary_function<QString,QString,bool> {
53  bool operator()( const QString &s1, const QString &s2 ) const
54  {
55  return QString::localeAwareCompare( s1, s2 ) < 0 ;
56  }
57 };
58 
59 class TabPressEater : public QObject
60 {
61  public:
62  TabPressEater( QObject *parent )
63  : QObject( parent )
64  {
65  setObjectName( QLatin1String( "TabPressEater" ) );
66  }
67 
68  protected:
69  bool eventFilter( QObject*, QEvent *event )
70  {
71  if ( event->type() == QEvent::KeyPress ) {
72  QKeyEvent *keyEvent = (QKeyEvent*)event;
73  if ( keyEvent->key() == Qt::Key_Tab ) {
74  QApplication::sendEvent( parent(), event );
75  return true;
76  } else
77  return false;
78  } else {
79  return false;
80  }
81  }
82 };
83 
89 class AddressTypeDialog : public KDialog
90 {
91  public:
92  AddressTypeDialog( KABC::Address::Type type, QWidget *parent );
93  ~AddressTypeDialog();
94 
95  KABC::Address::Type type() const;
96 
97  private:
98  QButtonGroup *mGroup;
99 
100  KABC::Address::TypeList mTypeList;
101 };
102 
103 
104 AddressSelectionWidget::AddressSelectionWidget( QWidget *parent )
105  : KComboBox( parent )
106 {
107  connect( this, SIGNAL(activated(int)), SLOT(selected(int)) );
108 }
109 
110 AddressSelectionWidget::~AddressSelectionWidget()
111 {
112 }
113 
114 void AddressSelectionWidget::setAddresses( const KABC::Address::List &addresses )
115 {
116  mAddresses = addresses;
117  updateView();
118 }
119 
120 void AddressSelectionWidget::setCurrentAddress( const KABC::Address &address )
121 {
122  const int index = mAddresses.indexOf( address );
123  if ( index != -1 )
124  setCurrentIndex( index );
125 }
126 
127 KABC::Address AddressSelectionWidget::currentAddress() const
128 {
129  if ( currentIndex() != -1 && currentIndex() < mAddresses.count() )
130  return mAddresses.at( currentIndex() );
131  else
132  return KABC::Address();
133 }
134 
135 void AddressSelectionWidget::selected( int index )
136 {
137  Q_ASSERT( index != -1 && index < mAddresses.count() );
138  emit selectionChanged( mAddresses.at( index ) );
139 }
140 
141 void AddressSelectionWidget::updateView()
142 {
143  clear();
144  for ( int i = 0; i < mAddresses.count(); ++i )
145  addItem( KABC::Address::typeLabel( mAddresses.at( i ).type() ) );
146 }
147 
148 
149 
150 AddressTypeCombo::AddressTypeCombo( QWidget *parent )
151  : KComboBox( parent ),
152  mType( KABC::Address::Home ),
153  mLastSelected( 0 )
154 {
155  for ( int i = 0; i < KABC::Address::typeList().count(); ++i )
156  mTypeList.append( KABC::Address::typeList().at( i ) );
157  mTypeList.append( -1 ); // Others...
158 
159  update();
160 
161  connect( this, SIGNAL(activated(int)),
162  this, SLOT(selected(int)) );
163 }
164 
165 AddressTypeCombo::~AddressTypeCombo()
166 {
167 }
168 
169 void AddressTypeCombo::setType( KABC::Address::Type type )
170 {
171  if ( !mTypeList.contains( (int)type ) ) {
172  // insert at the end, but before the 'Others...' entry
173  mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), (int)type );
174  }
175 
176  mType = type;
177  update();
178 }
179 
180 KABC::Address::Type AddressTypeCombo::type() const
181 {
182  return mType;
183 }
184 
185 void AddressTypeCombo::update()
186 {
187  bool blocked = signalsBlocked();
188  blockSignals( true );
189 
190  clear();
191  for ( int i = 0; i < mTypeList.count(); ++i ) {
192  if ( mTypeList.at( i ) == -1 ) // "Other..." entry
193  addItem( i18nc( "@item:inlistbox Category of contact info field", "Other..." ) );
194  else
195  addItem( KABC::Address::typeLabel( KABC::Address::Type( mTypeList.at( i ) ) ) );
196  }
197 
198  setCurrentIndex( mLastSelected = mTypeList.indexOf( mType ) );
199 
200  blockSignals( blocked );
201 }
202 
203 void AddressTypeCombo::selected( int pos )
204 {
205  if ( mTypeList.at( pos ) == -1 )
206  otherSelected();
207  else {
208  mType = KABC::Address::Type( mTypeList.at( pos ) );
209  mLastSelected = pos;
210  }
211 }
212 
213 void AddressTypeCombo::otherSelected()
214 {
215  AutoQPointer<AddressTypeDialog> dlg = new AddressTypeDialog( mType, this );
216  if ( dlg->exec() ) {
217  mType = dlg->type();
218  if ( !mTypeList.contains( mType ) )
219  mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), mType );
220  } else {
221  setType( KABC::Address::Type( mTypeList.at( mLastSelected ) ) );
222  }
223 
224  update();
225 }
226 
227 
228 AddressEditWidget::AddressEditWidget( QWidget *parent )
229  : QWidget( parent ), mReadOnly( false )
230 {
231  QGridLayout *layout = new QGridLayout( this );
232  layout->setSpacing( KDialog::spacingHint() );
233  layout->setMargin( 0 );
234 
235  mAddressSelectionWidget = new AddressSelectionWidget( this );
236  connect( mAddressSelectionWidget, SIGNAL(selectionChanged(KABC::Address)),
237  SLOT(updateAddressView()) );
238  layout->addWidget( mAddressSelectionWidget, 0, 0, 1, 3 );
239 
240  mAddressView = new QLabel( this );
241  mAddressView->setFrameStyle( QFrame::Panel | QFrame::Sunken );
242  mAddressView->setMinimumHeight( 20 );
243  mAddressView->setAlignment( Qt::AlignTop );
244  mAddressView->setTextFormat( Qt::PlainText );
245  mAddressView->setTextInteractionFlags( Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse );
246  layout->addWidget( mAddressView, 1, 0, 1, 3 );
247 
248  mCreateButton = new QPushButton( i18nc( "street/postal", "New..." ), this );
249  connect( mCreateButton, SIGNAL(clicked()), this, SLOT(createAddress()) );
250  mEditButton = new QPushButton( i18nc( "street/postal", "Edit..." ), this );
251  connect( mEditButton, SIGNAL(clicked()), this, SLOT(editAddress()) );
252  mDeleteButton = new QPushButton( i18nc( "street/postal", "Delete" ), this );
253  connect( mDeleteButton, SIGNAL(clicked()), this, SLOT(deleteAddress()) );
254 
255  layout->addWidget( mCreateButton, 2, 0 );
256  layout->addWidget( mEditButton, 2, 1 );
257  layout->addWidget( mDeleteButton, 2, 2 );
258 
259  updateButtons();
260 }
261 
262 AddressEditWidget::~AddressEditWidget()
263 {
264 }
265 
266 void AddressEditWidget::setReadOnly( bool readOnly )
267 {
268  mReadOnly = readOnly;
269  updateButtons();
270 }
271 
272 void AddressEditWidget::updateName( const QString &name )
273 {
274  mName = name;
275  updateAddressView();
276 }
277 
278 void AddressEditWidget::createAddress()
279 {
280  AutoQPointer<AddressEditDialog> dialog = new AddressEditDialog( this );
281  if ( dialog->exec() ) {
282  const KABC::Address address = dialog->address();
283  fixPreferredAddress( address );
284  mAddressList.append( address );
285  mAddressSelectionWidget->setAddresses( mAddressList );
286  mAddressSelectionWidget->setCurrentAddress( address );
287 
288  updateAddressView();
289  updateButtons();
290  }
291 }
292 
293 void AddressEditWidget::editAddress()
294 {
295  AutoQPointer<AddressEditDialog> dialog = new AddressEditDialog( this );
296  dialog->setAddress( mAddressSelectionWidget->currentAddress() );
297  if ( dialog->exec() ) {
298  const KABC::Address address = dialog->address();
299  fixPreferredAddress( address );
300  mAddressList[ mAddressSelectionWidget->currentIndex() ] = address;
301  mAddressSelectionWidget->setAddresses( mAddressList );
302  mAddressSelectionWidget->setCurrentAddress( address );
303 
304  updateAddressView();
305  }
306 }
307 
308 void AddressEditWidget::deleteAddress()
309 {
310  const int result = KMessageBox::questionYesNo( this, i18n( "Do you really want to delete this address?" ) );
311 
312  if ( result != KMessageBox::Yes )
313  return;
314 
315  mAddressList.removeAt( mAddressSelectionWidget->currentIndex() );
316  mAddressSelectionWidget->setAddresses( mAddressList );
317  updateAddressView();
318  updateButtons();
319 }
320 
321 void AddressEditWidget::fixPreferredAddress( const KABC::Address &preferredAddress )
322 {
323  // as the preferred address is mutual exclusive, we have to
324  // remove the flag from all other addresses
325  if ( preferredAddress.type() & KABC::Address::Pref ) {
326  for ( int i = 0; i < mAddressList.count(); ++i ) {
327  KABC::Address &address = mAddressList[ i ];
328  address.setType( address.type() & ~KABC::Address::Pref );
329  }
330  }
331 }
332 
333 void AddressEditWidget::updateAddressView()
334 {
335  const KABC::Address address = mAddressSelectionWidget->currentAddress();
336 
337  if ( address.isEmpty() )
338  mAddressView->setText( QString() );
339  else
340  mAddressView->setText( address.formattedAddress( mName ) );
341 }
342 
343 void AddressEditWidget::updateButtons()
344 {
345  mCreateButton->setEnabled( !mReadOnly );
346  mEditButton->setEnabled( !mReadOnly && (mAddressList.count() > 0) );
347  mDeleteButton->setEnabled( !mReadOnly && (mAddressList.count() > 0) );
348 }
349 
350 void AddressEditWidget::loadContact( const KABC::Addressee &contact )
351 {
352  mName = contact.realName();
353  mAddressList = contact.addresses();
354 
355  mAddressSelectionWidget->setAddresses( mAddressList );
356 
357  // set the preferred address as the visible one
358  for ( int i = 0; i < mAddressList.count(); ++i ) {
359  if ( mAddressList.at( i ).type() & KABC::Address::Pref ) {
360  mAddressSelectionWidget->setCurrentAddress( mAddressList.at( i ) );
361  break;
362  }
363  }
364 
365  updateAddressView();
366  updateButtons();
367 }
368 
369 void AddressEditWidget::storeContact( KABC::Addressee &contact ) const
370 {
371  // delete all previous addresses
372  const KABC::Address::List oldAddresses = contact.addresses();
373  for ( int i = 0; i < oldAddresses.count(); ++i )
374  contact.removeAddress( oldAddresses.at( i ) );
375 
376  // insert the new ones
377  for ( int i = 0; i < mAddressList.count(); ++i ) {
378  const KABC::Address address( mAddressList.at( i ) );
379  if ( !address.isEmpty() )
380  contact.insertAddress( address );
381  }
382 }
383 
384 
385 AddressEditDialog::AddressEditDialog( QWidget *parent )
386  : KDialog(parent)
387 {
388  setCaption( i18nc( "street/postal", "Edit Address" ) );
389  setButtons( Ok | Cancel );
390  setDefaultButton( Ok );
391  showButtonSeparator( true );
392 
393  QWidget *page = new QWidget( this );
394  setMainWidget( page );
395 
396  QGridLayout *topLayout = new QGridLayout( page );
397  topLayout->setSpacing( spacingHint() );
398  topLayout->setMargin( 0 );
399 
400  mTypeCombo = new AddressTypeCombo( page );
401  topLayout->addWidget( mTypeCombo, 0, 0, 1, 2 );
402 
403  QLabel *label = new QLabel( i18nc( "<streetLabel>:", "%1:", KABC::Address::streetLabel() ), page );
404  label->setAlignment( Qt::AlignTop | Qt::AlignLeft );
405  topLayout->addWidget( label, 1, 0 );
406  mStreetTextEdit = new KTextEdit( page );
407  mStreetTextEdit->setAcceptRichText( false );
408  label->setBuddy( mStreetTextEdit );
409  topLayout->addWidget( mStreetTextEdit, 1, 1 );
410 
411  TabPressEater *eater = new TabPressEater( this );
412  mStreetTextEdit->installEventFilter( eater );
413 
414  label = new QLabel( i18nc( "<postOfficeBoxLabel>:", "%1:", KABC::Address::postOfficeBoxLabel() ), page );
415  topLayout->addWidget( label, 2 , 0 );
416  mPOBoxEdit = new KLineEdit( page );
417  label->setBuddy( mPOBoxEdit );
418  topLayout->addWidget( mPOBoxEdit, 2, 1 );
419 
420  label = new QLabel( i18nc( "<localityLabel>:", "%1:", KABC::Address::localityLabel() ), page );
421  topLayout->addWidget( label, 3, 0 );
422  mLocalityEdit = new KLineEdit( page );
423  label->setBuddy( mLocalityEdit );
424  topLayout->addWidget( mLocalityEdit, 3, 1 );
425 
426  label = new QLabel( i18nc( "<regionLabel>:", "%1:", KABC::Address::regionLabel() ), page );
427  topLayout->addWidget( label, 4, 0 );
428  mRegionEdit = new KLineEdit( page );
429  label->setBuddy( mRegionEdit );
430  topLayout->addWidget( mRegionEdit, 4, 1 );
431 
432  label = new QLabel( i18nc( "<postalCodeLabel>:", "%1:", KABC::Address::postalCodeLabel() ), page );
433  topLayout->addWidget( label, 5, 0 );
434  mPostalCodeEdit = new KLineEdit( page );
435  label->setBuddy( mPostalCodeEdit );
436  topLayout->addWidget( mPostalCodeEdit, 5, 1 );
437 
438  label = new QLabel( i18nc( "<countryLabel>:", "%1:", KABC::Address::countryLabel() ), page );
439  topLayout->addWidget( label, 6, 0 );
440  mCountryCombo = new KComboBox( page );
441  mCountryCombo->setEditable( true );
442  mCountryCombo->setDuplicatesEnabled( false );
443 
444  QPushButton *labelButton = new QPushButton( i18n( "Edit Label..." ), page );
445  topLayout->addWidget( labelButton, 7, 0, 1, 2 );
446  connect( labelButton, SIGNAL(clicked()), SLOT(editLabel()) );
447 
448  fillCountryCombo();
449  label->setBuddy( mCountryCombo );
450  topLayout->addWidget( mCountryCombo, 6, 1 );
451 
452  mPreferredCheckBox = new QCheckBox( i18nc( "street/postal", "This is the preferred address" ), page );
453  topLayout->addWidget( mPreferredCheckBox, 8, 0, 1, 2 );
454 
455  KSeparator *sep = new KSeparator( Qt::Horizontal, page );
456  topLayout->addWidget( sep, 9, 0, 1, 2 );
457 
458  KHBox *buttonBox = new KHBox( page );
459  buttonBox->setSpacing( spacingHint() );
460  topLayout->addWidget( buttonBox, 10, 0, 1, 2 );
461 
462  KAcceleratorManager::manage( this );
463 }
464 
465 AddressEditDialog::~AddressEditDialog()
466 {
467 }
468 
469 void AddressEditDialog::editLabel()
470 {
471  bool ok = false;
472  QString result = KInputDialog::getMultiLineText( KABC::Address::labelLabel(),
473  KABC::Address::labelLabel(),
474  mLabel, &ok, this );
475  if ( ok )
476  mLabel = result;
477 }
478 
479 void AddressEditDialog::setAddress( const KABC::Address &address )
480 {
481  mAddress = address;
482 
483  mTypeCombo->setType( mAddress.type() );
484  mStreetTextEdit->setPlainText( mAddress.street() );
485  mRegionEdit->setText( mAddress.region() );
486  mLocalityEdit->setText( mAddress.locality() );
487  mPostalCodeEdit->setText( mAddress.postalCode() );
488  mPOBoxEdit->setText( mAddress.postOfficeBox() );
489  mLabel = mAddress.label();
490  mPreferredCheckBox->setChecked( mAddress.type() & KABC::Address::Pref );
491 
492  if ( mAddress.isEmpty() )
493  mCountryCombo->setItemText( mCountryCombo->currentIndex(),
494  KGlobal::locale()->countryCodeToName( KGlobal::locale()->country() ) );
495  else
496  mCountryCombo->setItemText( mCountryCombo->currentIndex(), mAddress.country() );
497 
498  mStreetTextEdit->setFocus();
499 }
500 
501 KABC::Address AddressEditDialog::address() const
502 {
503  KABC::Address address( mAddress );
504 
505  address.setType( mTypeCombo->type() );
506  address.setLocality( mLocalityEdit->text() );
507  address.setRegion( mRegionEdit->text() );
508  address.setPostalCode( mPostalCodeEdit->text() );
509  address.setCountry( mCountryCombo->currentText() );
510  address.setPostOfficeBox( mPOBoxEdit->text() );
511  address.setStreet( mStreetTextEdit->toPlainText() );
512  address.setLabel( mLabel );
513 
514  if ( mPreferredCheckBox->isChecked() ) {
515  address.setType( address.type() | KABC::Address::Pref );
516  } else
517  address.setType( address.type() & ~(KABC::Address::Pref) );
518 
519  return address;
520 }
521 
522 void AddressEditDialog::fillCountryCombo()
523 {
524  QStringList countries;
525 
526  foreach ( const QString &cc, KGlobal::locale()->allCountriesList() )
527  countries.append( KGlobal::locale()->countryCodeToName( cc ) );
528 
529  qSort( countries.begin(), countries.end(), LocaleAwareLessThan() );
530 
531  mCountryCombo->addItems( countries );
532  mCountryCombo->setAutoCompletion( true );
533  mCountryCombo->completionObject()->setItems( countries );
534  mCountryCombo->completionObject()->setIgnoreCase( true );
535 
536  const QString currentCountry = KGlobal::locale()->countryCodeToName( KGlobal::locale()->country() );
537  mCountryCombo->setCurrentIndex( mCountryCombo->findText( currentCountry ) );
538 }
539 
540 
541 AddressTypeDialog::AddressTypeDialog( KABC::Address::Type type, QWidget *parent )
542  : KDialog( parent)
543 {
544  setCaption( i18nc( "street/postal", "Edit Address Type" ) );
545  setButtons( Ok | Cancel );
546  setDefaultButton( Ok );
547 
548  QWidget *page = new QWidget(this);
549  setMainWidget( page );
550  QVBoxLayout *layout = new QVBoxLayout( page );
551  layout->setSpacing( KDialog::spacingHint() );
552  layout->setMargin( 0 );
553 
554  QGroupBox *box = new QGroupBox( i18nc( "street/postal", "Address Types" ), page );
555  layout->addWidget( box );
556  mGroup = new QButtonGroup( box );
557  mGroup->setExclusive ( false );
558 
559  QGridLayout *buttonLayout = new QGridLayout( box );
560 
561  mTypeList = KABC::Address::typeList();
562  mTypeList.removeAll( KABC::Address::Pref );
563 
564  KABC::Address::TypeList::ConstIterator it;
565  int i = 0;
566  int row = 0;
567  for ( it = mTypeList.constBegin(); it != mTypeList.constEnd(); ++it, ++i ) {
568  QCheckBox *cb = new QCheckBox( KABC::Address::typeLabel( *it ), box );
569  cb->setChecked( type & mTypeList[ i ] );
570  buttonLayout->addWidget( cb, row, i%3 );
571 
572  if( i%3 == 2 )
573  ++row;
574  mGroup->addButton( cb );
575  }
576 }
577 
578 AddressTypeDialog::~AddressTypeDialog()
579 {
580 }
581 
582 KABC::Address::Type AddressTypeDialog::type() const
583 {
584  KABC::Address::Type type;
585  for ( int i = 0; i < mGroup->buttons().count(); ++i ) {
586  QCheckBox *box = dynamic_cast<QCheckBox*>( mGroup->buttons().at( i ) );
587  if ( box && box->isChecked() )
588  type |= mTypeList[ i ];
589  }
590 
591  return type;
592 }
593 
594 #include "addresseditwidget.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Tue Dec 11 2012 12:14:29 by doxygen 1.8.1.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs-4.9.4 API Reference

Skip menu "kdepimlibs-4.9.4 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal