00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "distributionlistwidget.h"
00024
00025 #include <qbuttongroup.h>
00026 #include <qcombobox.h>
00027 #include <qlabel.h>
00028 #include <qlayout.h>
00029 #include <qlistview.h>
00030 #include <qpushbutton.h>
00031 #include <qradiobutton.h>
00032
00033 #include <kaccelmanager.h>
00034 #include <kconfig.h>
00035 #include <kdebug.h>
00036 #include <kglobal.h>
00037 #include <kinputdialog.h>
00038 #include <klocale.h>
00039 #include <kmessagebox.h>
00040
00041 #include <kabc/addresseedialog.h>
00042 #ifdef KDEPIM_NEW_DISTRLISTS
00043 #include <libkdepim/distributionlist.h>
00044 typedef KPIM::DistributionList DistributionList;
00045 #else
00046 #include <kabc/distributionlist.h>
00047 typedef KABC::DistributionList DistributionList;
00048 #endif
00049 #include <kabc/stdaddressbook.h>
00050 #include <kabc/vcardconverter.h>
00051 #include <libkdepim/kvcarddrag.h>
00052
00053 #include "core.h"
00054
00055 class DistributionListFactory : public KAB::ExtensionFactory
00056 {
00057 public:
00058 KAB::ExtensionWidget *extension( KAB::Core *core, QWidget *parent, const char *name )
00059 {
00060 return new DistributionListWidget( core, parent, name );
00061 }
00062
00063 QString identifier() const
00064 {
00065 return "distribution_list_editor";
00066 }
00067 };
00068
00069 extern "C" {
00070 void *init_libkaddrbk_distributionlist()
00071 {
00072 return ( new DistributionListFactory );
00073 }
00074 }
00075
00081 class DeletePressedCatcher : public QObject
00082 {
00083 public:
00084 DeletePressedCatcher( DistributionListWidget *parent )
00085 : QObject( parent, "DeletePressedCatcher" ), mWidget( parent )
00086 {
00087 }
00088
00089 protected:
00090 bool eventFilter( QObject*, QEvent *event )
00091 {
00092 if ( event->type() == QEvent::AccelOverride ) {
00093 QKeyEvent *keyEvent = (QKeyEvent*)event;
00094 if ( keyEvent->key() == Qt::Key_Delete ) {
00095 keyEvent->accept();
00096 mWidget->removeContact();
00097 return true;
00098 } else
00099 return false;
00100 } else {
00101 return false;
00102 }
00103 }
00104
00105 private:
00106 DistributionListWidget *mWidget;
00107 };
00108
00109 class ContactItem : public QListViewItem
00110 {
00111 public:
00112 ContactItem( DistributionListView *parent, const KABC::Addressee &addressee,
00113 const QString &email = QString::null ) :
00114 QListViewItem( parent ),
00115 mAddressee( addressee ),
00116 mEmail( email )
00117 {
00118 setText( 0, addressee.realName() );
00119 if ( email.isEmpty() ) {
00120 setText( 1, addressee.preferredEmail() );
00121 setText( 2, i18n( "Yes" ) );
00122 } else {
00123 setText( 1, email );
00124 setText( 2, i18n( "No" ) );
00125 }
00126 }
00127
00128 KABC::Addressee addressee() const
00129 {
00130 return mAddressee;
00131 }
00132
00133 QString email() const
00134 {
00135 return mEmail;
00136 }
00137
00138 protected:
00139 bool acceptDrop( const QMimeSource* )
00140 {
00141 return true;
00142 }
00143
00144 private:
00145 KABC::Addressee mAddressee;
00146 QString mEmail;
00147 };
00148
00149 DistributionListWidget::DistributionListWidget( KAB::Core *core, QWidget *parent,
00150 const char *name )
00151 : KAB::ExtensionWidget( core, parent, name )
00152 #ifndef KDEPIM_NEW_DISTRLISTS
00153 , mManager( 0 )
00154 #endif
00155 {
00156 QGridLayout *topLayout = new QGridLayout( this, 3, 4, KDialog::marginHint(),
00157 KDialog::spacingHint() );
00158
00159 mNameCombo = new QComboBox( this );
00160 topLayout->addWidget( mNameCombo, 0, 0 );
00161 connect( mNameCombo, SIGNAL( activated( int ) ), SLOT( updateContactView() ) );
00162
00163 mCreateListButton = new QPushButton( i18n( "New List..." ), this );
00164 topLayout->addWidget( mCreateListButton, 0, 1 );
00165 connect( mCreateListButton, SIGNAL( clicked() ), SLOT( createList() ) );
00166
00167 mEditListButton = new QPushButton( i18n( "Rename List..." ), this );
00168 topLayout->addWidget( mEditListButton, 0, 2 );
00169 connect( mEditListButton, SIGNAL( clicked() ), SLOT( editList() ) );
00170
00171 mRemoveListButton = new QPushButton( i18n( "Remove List" ), this );
00172 topLayout->addWidget( mRemoveListButton, 0, 3 );
00173 connect( mRemoveListButton, SIGNAL( clicked() ), SLOT( removeList() ) );
00174
00175 mContactView = new DistributionListView( this );
00176 mContactView->addColumn( i18n( "Name" ) );
00177 mContactView->addColumn( i18n( "Email" ) );
00178 mContactView->addColumn( i18n( "Use Preferred" ) );
00179 mContactView->setEnabled( false );
00180 mContactView->setAllColumnsShowFocus( true );
00181 mContactView->setFullWidth( true );
00182 topLayout->addMultiCellWidget( mContactView, 1, 1, 0, 3 );
00183 connect( mContactView, SIGNAL( selectionChanged() ),
00184 SLOT( selectionContactViewChanged() ) );
00185 connect( mContactView, SIGNAL( dropped( QDropEvent*, QListViewItem* ) ),
00186 SLOT( dropped( QDropEvent*, QListViewItem* ) ) );
00187
00188 mAddContactButton = new QPushButton( i18n( "Add Contact" ), this );
00189 mAddContactButton->setEnabled( false );
00190 topLayout->addWidget( mAddContactButton, 2, 0 );
00191 connect( mAddContactButton, SIGNAL( clicked() ), SLOT( addContact() ) );
00192
00193 mEntryCountLabel = new QLabel( this );
00194 topLayout->addWidget( mEntryCountLabel, 2, 1 );
00195
00196 mChangeEmailButton = new QPushButton( i18n( "Change Email..." ), this );
00197 topLayout->addWidget( mChangeEmailButton, 2, 2 );
00198 connect( mChangeEmailButton, SIGNAL( clicked() ), SLOT( changeEmail() ) );
00199
00200 mRemoveContactButton = new QPushButton( i18n( "Remove Contact" ), this );
00201 topLayout->addWidget( mRemoveContactButton, 2, 3 );
00202 connect( mRemoveContactButton, SIGNAL( clicked() ), SLOT( removeContact() ) );
00203
00204 #ifdef KDEPIM_NEW_DISTRLISTS
00205
00206 connect( core, SIGNAL( contactsUpdated() ),
00207 this, SLOT( updateNameCombo() ) );
00208 #else
00209 mManager = new KABC::DistributionListManager( core->addressBook() );
00210
00211 connect( KABC::DistributionListWatcher::self(), SIGNAL( changed() ),
00212 this, SLOT( updateNameCombo() ) );
00213 #endif
00214
00215 connect( core->addressBook(), SIGNAL( addressBookChanged( AddressBook* ) ),
00216 this, SLOT( updateNameCombo() ) );
00217
00218 updateNameCombo();
00219
00220 QObject *catcher = new DeletePressedCatcher( this );
00221 installEventFilter( catcher );
00222 mContactView->installEventFilter( catcher );
00223
00224 mContactView->restoreLayout( KGlobal::config(), "DistributionListViewColumns" );
00225
00226 KAcceleratorManager::manage( this );
00227 }
00228
00229 DistributionListWidget::~DistributionListWidget()
00230 {
00231 #ifndef KDEPIM_NEW_DISTRLISTS
00232 delete mManager;
00233 #endif
00234
00235 mContactView->saveLayout( KGlobal::config(), "DistributionListViewColumns" );
00236 }
00237
00238 void DistributionListWidget::save()
00239 {
00240 #ifndef KDEPIM_NEW_DISTRLISTS
00241 mManager->save();
00242 #endif
00243 }
00244
00245 void DistributionListWidget::selectionContactViewChanged()
00246 {
00247 ContactItem *contactItem =
00248 static_cast<ContactItem *>( mContactView->selectedItem() );
00249 bool state = contactItem;
00250
00251 mChangeEmailButton->setEnabled( state );
00252 mRemoveContactButton->setEnabled( state );
00253 }
00254
00255 bool DistributionListWidget::alreadyExists( const QString& distrListName ) const
00256 {
00257 #ifdef KDEPIM_NEW_DISTRLISTS
00258 return core()->distributionListNames().contains( distrListName );
00259 #else
00260 return mManager->listNames().contains( distrListName );
00261 #endif
00262 }
00263
00264 void DistributionListWidget::createList()
00265 {
00266 QString newName = KInputDialog::getText( i18n( "New Distribution List" ),
00267 i18n( "Please enter name:" ),
00268 QString::null, 0, this );
00269
00270 if ( newName.isEmpty() ) return;
00271
00272 if ( alreadyExists( newName ) ) {
00273 KMessageBox::sorry( this, i18n( "The name already exists" ) );
00274 return;
00275 }
00276 #ifdef KDEPIM_NEW_DISTRLISTS
00277 KABC::Resource* resource = core()->requestResource( this );
00278 if ( !resource )
00279 return;
00280
00281 KPIM::DistributionList dist;
00282 dist.setResource( resource );
00283 dist.setName( newName );
00284 core()->addressBook()->insertAddressee( dist );
00285
00286
00287
00288 changed( dist );
00289
00290 #else
00291 new KABC::DistributionList( mManager, newName );
00292 changed();
00293
00294 updateNameCombo();
00295 #endif
00296
00297
00298 mNameCombo->setCurrentText( newName );
00299
00300 updateContactView();
00301 }
00302
00303 void DistributionListWidget::editList()
00304 {
00305 const QString oldName = mNameCombo->currentText();
00306
00307 const QString newName = KInputDialog::getText( i18n( "Rename Distribution List" ),
00308 i18n( "Please enter name:" ),
00309 oldName, 0, this );
00310
00311 if ( newName.isEmpty() ) return;
00312
00313 if ( alreadyExists( newName ) ) {
00314 KMessageBox::sorry( this, i18n( "The name already exists." ) );
00315 return;
00316 }
00317 #ifdef KDEPIM_NEW_DISTRLISTS
00318 KPIM::DistributionList dist = KPIM::DistributionList::findByName(
00319 core()->addressBook(), mNameCombo->currentText() );
00320 if ( dist.isEmpty() )
00321 return;
00322
00323 dist.setFormattedName( newName );
00324 core()->addressBook()->insertAddressee( dist );
00325
00326 changed( dist );
00327 #else
00328 KABC::DistributionList *list = mManager->list( oldName );
00329 list->setName( newName );
00330 mManager->save();
00331 updateNameCombo();
00332 #endif
00333
00334
00335 mNameCombo->setCurrentText( newName );
00336
00337 updateContactView();
00338
00339 #ifndef KDEPIM_NEW_DISTRLISTS
00340 changed();
00341 #endif
00342 }
00343
00344 void DistributionListWidget::removeList()
00345 {
00346 int result = KMessageBox::warningContinueCancel( this,
00347 i18n( "<qt>Delete distribution list <b>%1</b>?</qt>" ) .arg( mNameCombo->currentText() ),
00348 QString::null, KGuiItem( i18n("Delete"), "editdelete") );
00349
00350 if ( result != KMessageBox::Continue )
00351 return;
00352
00353 #ifdef KDEPIM_NEW_DISTRLISTS
00354 KPIM::DistributionList dist = KPIM::DistributionList::findByName(
00355 core()->addressBook(), mNameCombo->currentText() );
00356 if ( dist.isEmpty() )
00357 return;
00358
00359 core()->addressBook()->removeAddressee( dist );
00360
00361 emit deleted( dist.uid() );
00362 #else
00363 mManager->remove( mManager->list( mNameCombo->currentText() ) );
00364 mNameCombo->removeItem( mNameCombo->currentItem() );
00365
00366 updateContactView();
00367
00368 changed();
00369 #endif
00370 }
00371
00372 void DistributionListWidget::addContact()
00373 {
00374 #ifdef KDEPIM_NEW_DISTRLISTS
00375 KPIM::DistributionList dist = KPIM::DistributionList::findByName(
00376 core()->addressBook(), mNameCombo->currentText() );
00377 if ( dist.isEmpty() ) {
00378 kdDebug(5720) << k_funcinfo << mNameCombo->currentText() << " not found" << endl;
00379 return;
00380 }
00381 #else
00382 KABC::DistributionList *list = mManager->list( mNameCombo->currentText() );
00383 if ( !list )
00384 return;
00385 KABC::DistributionList& dist = *list;
00386 #endif
00387
00388 const KABC::Addressee::List addrList = selectedContacts();
00389 KABC::Addressee::List::ConstIterator it;
00390 for ( it = addrList.begin(); it != addrList.end(); ++it )
00391 dist.insertEntry( *it );
00392
00393 #ifdef KDEPIM_NEW_DISTRLISTS
00394 core()->addressBook()->insertAddressee( dist );
00395 changed( dist );
00396 #else
00397 updateContactView();
00398 changed();
00399 #endif
00400 }
00401
00402 void DistributionListWidget::removeContact()
00403 {
00404 #ifdef KDEPIM_NEW_DISTRLISTS
00405 KPIM::DistributionList dist = KPIM::DistributionList::findByName(
00406 core()->addressBook(), mNameCombo->currentText() );
00407 if ( dist.isEmpty() )
00408 return;
00409 #else
00410 KABC::DistributionList *list = mManager->list( mNameCombo->currentText() );
00411 if ( !list )
00412 return;
00413 KABC::DistributionList& dist = *list;
00414 #endif
00415
00416 ContactItem *contactItem =
00417 static_cast<ContactItem *>( mContactView->selectedItem() );
00418 if ( !contactItem )
00419 return;
00420
00421 dist.removeEntry( contactItem->addressee(), contactItem->email() );
00422 delete contactItem;
00423
00424 #ifdef KDEPIM_NEW_DISTRLISTS
00425 core()->addressBook()->insertAddressee( dist );
00426 changed( dist );
00427 #else
00428 changed();
00429 #endif
00430 }
00431
00432 void DistributionListWidget::changeEmail()
00433 {
00434 #ifdef KDEPIM_NEW_DISTRLISTS
00435 KPIM::DistributionList dist = KPIM::DistributionList::findByName(
00436 core()->addressBook(), mNameCombo->currentText() );
00437 if ( dist.isEmpty() )
00438 return;
00439 #else
00440 KABC::DistributionList *list = mManager->list( mNameCombo->currentText() );
00441 if ( !list )
00442 return;
00443 KABC::DistributionList& dist = *list;
00444 #endif
00445
00446 ContactItem *contactItem =
00447 static_cast<ContactItem *>( mContactView->selectedItem() );
00448 if ( !contactItem )
00449 return;
00450
00451 const QString email = EmailSelector::getEmail( contactItem->addressee().emails(),
00452 contactItem->email(), this );
00453 dist.removeEntry( contactItem->addressee(), contactItem->email() );
00454 dist.insertEntry( contactItem->addressee(), email );
00455
00456 #ifdef KDEPIM_NEW_DISTRLISTS
00457 core()->addressBook()->insertAddressee( dist );
00458 changed( dist );
00459 #else
00460 updateContactView();
00461 changed();
00462 #endif
00463 }
00464
00465 void DistributionListWidget::updateContactView()
00466 {
00467 mContactView->clear();
00468
00469 bool isListSelected = false;
00470 #ifdef KDEPIM_NEW_DISTRLISTS
00471 KPIM::DistributionList dist;
00472 if ( mNameCombo->count() != 0 )
00473 dist = KPIM::DistributionList::findByName(
00474 core()->addressBook(), mNameCombo->currentText() );
00475 isListSelected = !dist.isEmpty();
00476 #else
00477 KABC::DistributionList *list = mManager->list( mNameCombo->currentText() );
00478 isListSelected = list != 0;
00479 #endif
00480 if ( !isListSelected ) {
00481 mEditListButton->setEnabled( false );
00482 mRemoveListButton->setEnabled( false );
00483 mChangeEmailButton->setEnabled( false );
00484 mRemoveContactButton->setEnabled( false );
00485 mContactView->setEnabled( false );
00486 return;
00487 }
00488 mEditListButton->setEnabled( true );
00489 mRemoveListButton->setEnabled( true );
00490 mContactView->setEnabled( true );
00491
00492 uint entryCount = 0;
00493 #ifdef KDEPIM_NEW_DISTRLISTS
00494 const KPIM::DistributionList::Entry::List entries = dist.entries( core()->addressBook() );
00495 KPIM::DistributionList::Entry::List::ConstIterator it;
00496 #else
00497 const KABC::DistributionList::Entry::List entries = list->entries();
00498 KABC::DistributionList::Entry::List::ConstIterator it;
00499 #endif
00500 for ( it = entries.begin(); it != entries.end(); ++it, ++entryCount )
00501 new ContactItem( mContactView, (*it).addressee, (*it).email );
00502
00503 bool state = mContactView->selectedItem() != 0;
00504 mChangeEmailButton->setEnabled( state );
00505 mRemoveContactButton->setEnabled( state );
00506
00507 mEntryCountLabel->setText( i18n( "Count: %n contact", "Count: %n contacts", entryCount ) );
00508 }
00509
00510 void DistributionListWidget::updateNameCombo()
00511 {
00512 int pos = mNameCombo->currentItem();
00513 mNameCombo->clear();
00514 #ifdef KDEPIM_NEW_DISTRLISTS
00515 const QStringList names = core()->distributionListNames();
00516 #else
00517 mManager->load();
00518 const QStringList names = mManager->listNames();
00519 #endif
00520 mNameCombo->insertStringList( names );
00521 mNameCombo->setCurrentItem( QMIN( pos, (int)names.count() - 1 ) );
00522
00523 updateContactView();
00524 }
00525
00526 void DistributionListWidget::dropEvent( QDropEvent *e )
00527 {
00528 if ( mNameCombo->count() == 0 )
00529 return;
00530
00531 #ifdef KDEPIM_NEW_DISTRLISTS
00532 KPIM::DistributionList dist = KPIM::DistributionList::findByName(
00533 core()->addressBook(), mNameCombo->currentText() );
00534 if ( dist.isEmpty() )
00535 return;
00536 #else
00537 KABC::DistributionList *list = mManager->list( mNameCombo->currentText() );
00538 if ( !list )
00539 return;
00540 KABC::DistributionList& dist = *list;
00541 #endif
00542
00543 QString vcards;
00544 if ( KVCardDrag::decode( e, vcards ) ) {
00545 KABC::VCardConverter converter;
00546 const KABC::Addressee::List lst = converter.parseVCards( vcards );
00547 for ( KABC::Addressee::List::ConstIterator it = lst.begin(); it != lst.end(); ++it )
00548 dist.insertEntry( *it );
00549
00550 #ifdef KDEPIM_NEW_DISTRLISTS
00551 core()->addressBook()->insertAddressee( dist );
00552 changed( dist );
00553 #else
00554 changed();
00555 updateContactView();
00556 #endif
00557 }
00558 }
00559
00560 void DistributionListWidget::contactsSelectionChanged()
00561 {
00562 mAddContactButton->setEnabled( contactsSelected() && mNameCombo->count() > 0 );
00563 }
00564
00565 QString DistributionListWidget::title() const
00566 {
00567 return i18n( "Distribution List Editor" );
00568 }
00569
00570 QString DistributionListWidget::identifier() const
00571 {
00572 return "distribution_list_editor";
00573 }
00574
00575 void DistributionListWidget::dropped( QDropEvent *e, QListViewItem* )
00576 {
00577 dropEvent( e );
00578 }
00579
00580 #ifdef KDEPIM_NEW_DISTRLISTS
00581 void DistributionListWidget::changed( const KABC::Addressee& dist )
00582 {
00583 emit modified( KABC::Addressee::List() << dist );
00584 }
00585 #else
00586 void DistributionListWidget::changed()
00587 {
00588 save();
00589 }
00590 #endif
00591
00592 DistributionListView::DistributionListView( QWidget *parent, const char* name )
00593 : KListView( parent, name )
00594 {
00595 setDragEnabled( true );
00596 setAcceptDrops( true );
00597 setAllColumnsShowFocus( true );
00598 }
00599
00600 void DistributionListView::dragEnterEvent( QDragEnterEvent* e )
00601 {
00602 bool canDecode = QTextDrag::canDecode( e );
00603 e->accept( canDecode );
00604 }
00605
00606 void DistributionListView::viewportDragMoveEvent( QDragMoveEvent *e )
00607 {
00608 bool canDecode = QTextDrag::canDecode( e );
00609 e->accept( canDecode );
00610 }
00611
00612 void DistributionListView::viewportDropEvent( QDropEvent *e )
00613 {
00614 emit dropped( e, 0 );
00615 }
00616
00617 void DistributionListView::dropEvent( QDropEvent *e )
00618 {
00619 emit dropped( e, 0 );
00620 }
00621
00622
00623 EmailSelector::EmailSelector( const QStringList &emails,
00624 const QString ¤t, QWidget *parent )
00625 : KDialogBase( KDialogBase::Plain, i18n("Select Email Address"), Ok, Ok,
00626 parent )
00627 {
00628 QFrame *topFrame = plainPage();
00629 QBoxLayout *topLayout = new QVBoxLayout( topFrame );
00630
00631 mButtonGroup = new QButtonGroup( 1, Horizontal, i18n("Email Addresses"),
00632 topFrame );
00633 mButtonGroup->setRadioButtonExclusive( true );
00634 topLayout->addWidget( mButtonGroup );
00635
00636 QRadioButton *button = new QRadioButton( i18n("Preferred address"), mButtonGroup );
00637 button->setDown( true );
00638 mEmailMap.insert( mButtonGroup->id( button ), "" );
00639
00640 QStringList::ConstIterator it;
00641 for ( it = emails.begin(); it != emails.end(); ++it ) {
00642 button = new QRadioButton( *it, mButtonGroup );
00643 mEmailMap.insert( mButtonGroup->id( button ), *it );
00644 if ( (*it) == current )
00645 button->setDown( true );
00646 }
00647 }
00648
00649 QString EmailSelector::selected() const
00650 {
00651 QButton *button = mButtonGroup->selected();
00652 if ( button )
00653 return mEmailMap[ mButtonGroup->id( button ) ];
00654
00655 return QString::null;
00656 }
00657
00658 QString EmailSelector::getEmail( const QStringList &emails,
00659 const QString ¤t, QWidget *parent )
00660 {
00661 EmailSelector dlg( emails, current, parent );
00662 dlg.exec();
00663
00664 return dlg.selected();
00665 }
00666
00667
00668 #include "distributionlistwidget.moc"