TDE personal information management applications
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

674 lines
19KB

  1. /*
  2. This file is part of KAddressBook.
  3. Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  15. As a special exception, permission is given to link this program
  16. with any edition of TQt, and distribute the resulting executable,
  17. without including the source code for TQt in the source distribution.
  18. */
  19. #include "distributionlistwidget.h"
  20. #include <tqbuttongroup.h>
  21. #include <tqcombobox.h>
  22. #include <tqlabel.h>
  23. #include <tqlayout.h>
  24. #include <tqlistview.h>
  25. #include <tqpushbutton.h>
  26. #include <tqradiobutton.h>
  27. #include <kaccelmanager.h>
  28. #include <kconfig.h>
  29. #include <kdebug.h>
  30. #include <kglobal.h>
  31. #include <kinputdialog.h>
  32. #include <klocale.h>
  33. #include <kmessagebox.h>
  34. #include <kabc/addresseedialog.h>
  35. #ifdef KDEPIM_NEW_DISTRLISTS
  36. #include <libtdepim/distributionlist.h>
  37. typedef KPIM::DistributionList DistributionList;
  38. #else
  39. #include <kabc/distributionlist.h>
  40. typedef KABC::DistributionList DistributionList;
  41. #endif
  42. #include <kabc/stdaddressbook.h>
  43. #include <kabc/vcardconverter.h>
  44. #include <libtdepim/kvcarddrag.h>
  45. #include "core.h"
  46. class DistributionListFactory : public KAB::ExtensionFactory
  47. {
  48. public:
  49. KAB::ExtensionWidget *extension( KAB::Core *core, TQWidget *parent, const char *name )
  50. {
  51. return new DistributionListWidget( core, parent, name );
  52. }
  53. TQString identifier() const
  54. {
  55. return "distribution_list_editor";
  56. }
  57. };
  58. extern "C" {
  59. void *init_libkaddrbk_distributionlist()
  60. {
  61. return ( new DistributionListFactory );
  62. }
  63. }
  64. /**
  65. We have to catch when the 'Del' key is pressed, otherwise
  66. the event is forwarded to the ViewManager and it tries to
  67. remove a contact instead of the distribution list.
  68. */
  69. class DeletePressedCatcher : public TQObject
  70. {
  71. public:
  72. DeletePressedCatcher( DistributionListWidget *parent )
  73. : TQObject( parent, "DeletePressedCatcher" ), mWidget( parent )
  74. {
  75. }
  76. protected:
  77. bool eventFilter( TQObject*, TQEvent *event )
  78. {
  79. if ( event->type() == TQEvent::AccelOverride ) {
  80. TQKeyEvent *keyEvent = (TQKeyEvent*)event;
  81. if ( keyEvent->key() == TQt::Key_Delete ) {
  82. keyEvent->accept();
  83. mWidget->removeContact();
  84. return true;
  85. } else
  86. return false;
  87. } else {
  88. return false;
  89. }
  90. }
  91. private:
  92. DistributionListWidget *mWidget;
  93. };
  94. class ContactItem : public TQListViewItem
  95. {
  96. public:
  97. ContactItem( DistributionListView *parent, const KABC::Addressee &addressee,
  98. const TQString &email = TQString() ) :
  99. TQListViewItem( parent ),
  100. mAddressee( addressee ),
  101. mEmail( email )
  102. {
  103. setText( 0, addressee.realName() );
  104. if ( email.isEmpty() ) {
  105. setText( 1, addressee.preferredEmail() );
  106. setText( 2, i18n( "Yes" ) );
  107. } else {
  108. setText( 1, email );
  109. setText( 2, i18n( "No" ) );
  110. }
  111. }
  112. KABC::Addressee addressee() const
  113. {
  114. return mAddressee;
  115. }
  116. TQString email() const
  117. {
  118. return mEmail;
  119. }
  120. protected:
  121. bool acceptDrop( const TQMimeSource* )
  122. {
  123. return true;
  124. }
  125. private:
  126. KABC::Addressee mAddressee;
  127. TQString mEmail;
  128. };
  129. DistributionListWidget::DistributionListWidget( KAB::Core *core, TQWidget *parent,
  130. const char *name )
  131. : KAB::ExtensionWidget( core, parent, name )
  132. #ifndef KDEPIM_NEW_DISTRLISTS
  133. , mManager( 0 )
  134. #endif
  135. {
  136. TQGridLayout *topLayout = new TQGridLayout( this, 3, 4, KDialog::marginHint(),
  137. KDialog::spacingHint() );
  138. mNameCombo = new TQComboBox( this );
  139. topLayout->addWidget( mNameCombo, 0, 0 );
  140. connect( mNameCombo, TQT_SIGNAL( activated( int ) ), TQT_SLOT( updateContactView() ) );
  141. mCreateListButton = new TQPushButton( i18n( "New List..." ), this );
  142. topLayout->addWidget( mCreateListButton, 0, 1 );
  143. connect( mCreateListButton, TQT_SIGNAL( clicked() ), TQT_SLOT( createList() ) );
  144. mEditListButton = new TQPushButton( i18n( "Rename List..." ), this );
  145. topLayout->addWidget( mEditListButton, 0, 2 );
  146. connect( mEditListButton, TQT_SIGNAL( clicked() ), TQT_SLOT( editList() ) );
  147. mRemoveListButton = new TQPushButton( i18n( "Remove List" ), this );
  148. topLayout->addWidget( mRemoveListButton, 0, 3 );
  149. connect( mRemoveListButton, TQT_SIGNAL( clicked() ), TQT_SLOT( removeList() ) );
  150. mContactView = new DistributionListView( this );
  151. mContactView->addColumn( i18n( "Name" ) );
  152. mContactView->addColumn( i18n( "Email" ) );
  153. mContactView->addColumn( i18n( "Use Preferred" ) );
  154. mContactView->setEnabled( false );
  155. mContactView->setAllColumnsShowFocus( true );
  156. mContactView->setFullWidth( true );
  157. topLayout->addMultiCellWidget( mContactView, 1, 1, 0, 3 );
  158. connect( mContactView, TQT_SIGNAL( selectionChanged() ),
  159. TQT_SLOT( selectionContactViewChanged() ) );
  160. connect( mContactView, TQT_SIGNAL( dropped( TQDropEvent*, TQListViewItem* ) ),
  161. TQT_SLOT( dropped( TQDropEvent*, TQListViewItem* ) ) );
  162. mAddContactButton = new TQPushButton( i18n( "Add Contact" ), this );
  163. mAddContactButton->setEnabled( false );
  164. topLayout->addWidget( mAddContactButton, 2, 0 );
  165. connect( mAddContactButton, TQT_SIGNAL( clicked() ), TQT_SLOT( addContact() ) );
  166. mEntryCountLabel = new TQLabel( this );
  167. topLayout->addWidget( mEntryCountLabel, 2, 1 );
  168. mChangeEmailButton = new TQPushButton( i18n( "Change Email..." ), this );
  169. topLayout->addWidget( mChangeEmailButton, 2, 2 );
  170. connect( mChangeEmailButton, TQT_SIGNAL( clicked() ), TQT_SLOT( changeEmail() ) );
  171. mRemoveContactButton = new TQPushButton( i18n( "Remove Contact" ), this );
  172. topLayout->addWidget( mRemoveContactButton, 2, 3 );
  173. connect( mRemoveContactButton, TQT_SIGNAL( clicked() ), TQT_SLOT( removeContact() ) );
  174. #ifdef KDEPIM_NEW_DISTRLISTS
  175. // When contacts are changed, update both distr list combo and contents of displayed distr list
  176. connect( core, TQT_SIGNAL( contactsUpdated() ),
  177. this, TQT_SLOT( updateNameCombo() ) );
  178. #else
  179. mManager = new KABC::DistributionListManager( core->addressBook() );
  180. connect( KABC::DistributionListWatcher::self(), TQT_SIGNAL( changed() ),
  181. this, TQT_SLOT( updateNameCombo() ) );
  182. #endif
  183. connect( core->addressBook(), TQT_SIGNAL( addressBookChanged( AddressBook* ) ),
  184. this, TQT_SLOT( updateNameCombo() ) );
  185. updateNameCombo();
  186. TQObject *catcher = new DeletePressedCatcher( this );
  187. installEventFilter( catcher );
  188. mContactView->installEventFilter( catcher );
  189. mContactView->restoreLayout( KGlobal::config(), "DistributionListViewColumns" );
  190. KAcceleratorManager::manage( this );
  191. }
  192. DistributionListWidget::~DistributionListWidget()
  193. {
  194. #ifndef KDEPIM_NEW_DISTRLISTS
  195. delete mManager;
  196. #endif
  197. mContactView->saveLayout( KGlobal::config(), "DistributionListViewColumns" );
  198. }
  199. void DistributionListWidget::save()
  200. {
  201. #ifndef KDEPIM_NEW_DISTRLISTS
  202. mManager->save();
  203. #endif
  204. }
  205. void DistributionListWidget::selectionContactViewChanged()
  206. {
  207. ContactItem *contactItem =
  208. static_cast<ContactItem *>( mContactView->selectedItem() );
  209. bool state = contactItem;
  210. mChangeEmailButton->setEnabled( state );
  211. mRemoveContactButton->setEnabled( state );
  212. }
  213. bool DistributionListWidget::alreadyExists( const TQString& distrListName ) const
  214. {
  215. #ifdef KDEPIM_NEW_DISTRLISTS
  216. return core()->distributionListNames().contains( distrListName );
  217. #else
  218. return mManager->listNames().contains( distrListName );
  219. #endif
  220. }
  221. void DistributionListWidget::createList()
  222. {
  223. TQString newName = KInputDialog::getText( i18n( "New Distribution List" ),
  224. i18n( "Please enter name:" ),
  225. TQString(), 0, this );
  226. if ( newName.isEmpty() ) return;
  227. if ( alreadyExists( newName ) ) {
  228. KMessageBox::sorry( this, i18n( "The name already exists" ) );
  229. return;
  230. }
  231. #ifdef KDEPIM_NEW_DISTRLISTS
  232. KABC::Resource* resource = core()->requestResource( this );
  233. if ( !resource )
  234. return;
  235. KPIM::DistributionList dist;
  236. dist.setResource( resource );
  237. dist.setName( newName );
  238. // Creates undo-redo command, calls setModified, also triggers contactsUpdated,
  239. // which triggers updateNameCombo, so the new name appears
  240. changed( dist );
  241. core()->addressBook()->insertAddressee( dist );
  242. #else
  243. new KABC::DistributionList( mManager, newName );
  244. changed();
  245. updateNameCombo();
  246. #endif
  247. // Select the new one in the list
  248. mNameCombo->setCurrentText( newName );
  249. // Display the contents of the list we just selected (well, it's empty)
  250. updateContactView();
  251. }
  252. void DistributionListWidget::editList()
  253. {
  254. const TQString oldName = mNameCombo->currentText();
  255. const TQString newName = KInputDialog::getText( i18n( "Rename Distribution List" ),
  256. i18n( "Please enter name:" ),
  257. oldName, 0, this );
  258. if ( newName.isEmpty() ) return;
  259. if ( alreadyExists( newName ) ) {
  260. KMessageBox::sorry( this, i18n( "The name already exists." ) );
  261. return;
  262. }
  263. #ifdef KDEPIM_NEW_DISTRLISTS
  264. KPIM::DistributionList dist = KPIM::DistributionList::findByName(
  265. core()->addressBook(), mNameCombo->currentText() );
  266. if ( dist.isEmpty() ) // not found [should be impossible]
  267. return;
  268. dist.setFormattedName( newName );
  269. core()->addressBook()->insertAddressee( dist );
  270. changed( dist );
  271. #else
  272. KABC::DistributionList *list = mManager->list( oldName );
  273. list->setName( newName );
  274. mManager->save();
  275. updateNameCombo();
  276. #endif
  277. // Select the new name in the list (updateNameCombo couldn't know we wanted that one)
  278. mNameCombo->setCurrentText( newName );
  279. // Display the contents of the list we just selected
  280. updateContactView();
  281. #ifndef KDEPIM_NEW_DISTRLISTS
  282. changed();
  283. #endif
  284. }
  285. void DistributionListWidget::removeList()
  286. {
  287. int result = KMessageBox::warningContinueCancel( this,
  288. i18n( "<qt>Delete distribution list <b>%1</b>?</qt>" ) .tqarg( mNameCombo->currentText() ),
  289. TQString(), KGuiItem( i18n("Delete"), "editdelete") );
  290. if ( result != KMessageBox::Continue )
  291. return;
  292. #ifdef KDEPIM_NEW_DISTRLISTS
  293. KPIM::DistributionList dist = KPIM::DistributionList::findByName(
  294. core()->addressBook(), mNameCombo->currentText() );
  295. if ( dist.isEmpty() ) // not found [should be impossible]
  296. return;
  297. emit deleted( dist.uid() );
  298. core()->addressBook()->removeAddressee( dist );
  299. #else
  300. mManager->remove( mManager->list( mNameCombo->currentText() ) );
  301. mNameCombo->removeItem( mNameCombo->currentItem() );
  302. updateContactView();
  303. changed();
  304. #endif
  305. }
  306. void DistributionListWidget::addContact()
  307. {
  308. #ifdef KDEPIM_NEW_DISTRLISTS
  309. KPIM::DistributionList dist = KPIM::DistributionList::findByName(
  310. core()->addressBook(), mNameCombo->currentText() );
  311. if ( dist.isEmpty() ) { // not found
  312. kdDebug(5720) << k_funcinfo << mNameCombo->currentText() << " not found" << endl;
  313. return;
  314. }
  315. #else
  316. KABC::DistributionList *list = mManager->list( mNameCombo->currentText() );
  317. if ( !list )
  318. return;
  319. KABC::DistributionList& dist = *list;
  320. #endif
  321. const KABC::Addressee::List addrList = selectedContacts();
  322. KABC::Addressee::List::ConstIterator it;
  323. for ( it = addrList.begin(); it != addrList.end(); ++it )
  324. dist.insertEntry( *it );
  325. #ifdef KDEPIM_NEW_DISTRLISTS
  326. core()->addressBook()->insertAddressee( dist );
  327. changed( dist );
  328. #else
  329. updateContactView();
  330. changed();
  331. #endif
  332. }
  333. void DistributionListWidget::removeContact()
  334. {
  335. #ifdef KDEPIM_NEW_DISTRLISTS
  336. KPIM::DistributionList dist = KPIM::DistributionList::findByName(
  337. core()->addressBook(), mNameCombo->currentText() );
  338. if ( dist.isEmpty() ) // not found
  339. return;
  340. #else
  341. KABC::DistributionList *list = mManager->list( mNameCombo->currentText() );
  342. if ( !list )
  343. return;
  344. KABC::DistributionList& dist = *list;
  345. #endif
  346. ContactItem *contactItem =
  347. static_cast<ContactItem *>( mContactView->selectedItem() );
  348. if ( !contactItem )
  349. return;
  350. dist.removeEntry( contactItem->addressee(), contactItem->email() );
  351. delete contactItem;
  352. #ifdef KDEPIM_NEW_DISTRLISTS
  353. core()->addressBook()->insertAddressee( dist );
  354. changed( dist );
  355. #else
  356. changed();
  357. #endif
  358. }
  359. void DistributionListWidget::changeEmail()
  360. {
  361. #ifdef KDEPIM_NEW_DISTRLISTS
  362. KPIM::DistributionList dist = KPIM::DistributionList::findByName(
  363. core()->addressBook(), mNameCombo->currentText() );
  364. if ( dist.isEmpty() ) // not found
  365. return;
  366. #else
  367. KABC::DistributionList *list = mManager->list( mNameCombo->currentText() );
  368. if ( !list )
  369. return;
  370. KABC::DistributionList& dist = *list;
  371. #endif
  372. ContactItem *contactItem =
  373. static_cast<ContactItem *>( mContactView->selectedItem() );
  374. if ( !contactItem )
  375. return;
  376. bool canceled = false;
  377. const TQString email = EmailSelector::getEmail( contactItem->addressee().emails(),
  378. contactItem->email(), this, canceled);
  379. if( canceled)
  380. return;
  381. dist.removeEntry( contactItem->addressee(), contactItem->email() );
  382. dist.insertEntry( contactItem->addressee(), email );
  383. #ifdef KDEPIM_NEW_DISTRLISTS
  384. core()->addressBook()->insertAddressee( dist );
  385. changed( dist );
  386. #else
  387. updateContactView();
  388. changed();
  389. #endif
  390. }
  391. void DistributionListWidget::updateContactView()
  392. {
  393. mContactView->clear();
  394. bool isListSelected = false;
  395. #ifdef KDEPIM_NEW_DISTRLISTS
  396. KPIM::DistributionList dist;
  397. if ( mNameCombo->count() != 0 )
  398. dist = KPIM::DistributionList::findByName(
  399. core()->addressBook(), mNameCombo->currentText() );
  400. isListSelected = !dist.isEmpty();
  401. #else
  402. KABC::DistributionList *list = mManager->list( mNameCombo->currentText() );
  403. isListSelected = list != 0;
  404. #endif
  405. if ( !isListSelected ) {
  406. mEditListButton->setEnabled( false );
  407. mRemoveListButton->setEnabled( false );
  408. mChangeEmailButton->setEnabled( false );
  409. mRemoveContactButton->setEnabled( false );
  410. mContactView->setEnabled( false );
  411. return;
  412. }
  413. mEditListButton->setEnabled( true );
  414. mRemoveListButton->setEnabled( true );
  415. mContactView->setEnabled( true );
  416. uint entryCount = 0;
  417. #ifdef KDEPIM_NEW_DISTRLISTS
  418. const KPIM::DistributionList::Entry::List entries = dist.entries( core()->addressBook() );
  419. KPIM::DistributionList::Entry::List::ConstIterator it;
  420. #else
  421. const KABC::DistributionList::Entry::List entries = list->entries();
  422. KABC::DistributionList::Entry::List::ConstIterator it;
  423. #endif
  424. for ( it = entries.begin(); it != entries.end(); ++it, ++entryCount )
  425. new ContactItem( mContactView, (*it).addressee, (*it).email );
  426. bool state = mContactView->selectedItem() != 0;
  427. mChangeEmailButton->setEnabled( state );
  428. mRemoveContactButton->setEnabled( state );
  429. mEntryCountLabel->setText( i18n( "Count: %n contact", "Count: %n contacts", entryCount ) );
  430. }
  431. void DistributionListWidget::updateNameCombo()
  432. {
  433. int pos = mNameCombo->currentItem();
  434. mNameCombo->clear();
  435. #ifdef KDEPIM_NEW_DISTRLISTS
  436. const TQStringList names = core()->distributionListNames();
  437. #else
  438. mManager->load();
  439. const TQStringList names = mManager->listNames();
  440. #endif
  441. mNameCombo->insertStringList( names );
  442. mNameCombo->setCurrentItem( TQMIN( pos, (int)names.count() - 1 ) );
  443. updateContactView();
  444. }
  445. void DistributionListWidget::dropEvent( TQDropEvent *e )
  446. {
  447. if ( mNameCombo->count() == 0 )
  448. return;
  449. #ifdef KDEPIM_NEW_DISTRLISTS
  450. KPIM::DistributionList dist = KPIM::DistributionList::findByName(
  451. core()->addressBook(), mNameCombo->currentText() );
  452. if ( dist.isEmpty() )
  453. return;
  454. #else
  455. KABC::DistributionList *list = mManager->list( mNameCombo->currentText() );
  456. if ( !list )
  457. return;
  458. KABC::DistributionList& dist = *list;
  459. #endif
  460. TQString vcards;
  461. if ( KVCardDrag::decode( e, vcards ) ) {
  462. KABC::VCardConverter converter;
  463. const KABC::Addressee::List lst = converter.parseVCards( vcards );
  464. for ( KABC::Addressee::List::ConstIterator it = lst.begin(); it != lst.end(); ++it )
  465. dist.insertEntry( *it );
  466. #ifdef KDEPIM_NEW_DISTRLISTS
  467. core()->addressBook()->insertAddressee( dist );
  468. changed( dist );
  469. #else
  470. changed();
  471. updateContactView();
  472. #endif
  473. }
  474. }
  475. void DistributionListWidget::contactsSelectionChanged()
  476. {
  477. mAddContactButton->setEnabled( contactsSelected() && mNameCombo->count() > 0 );
  478. }
  479. TQString DistributionListWidget::title() const
  480. {
  481. return i18n( "Distribution List Editor" );
  482. }
  483. TQString DistributionListWidget::identifier() const
  484. {
  485. return "distribution_list_editor";
  486. }
  487. void DistributionListWidget::dropped( TQDropEvent *e, TQListViewItem* )
  488. {
  489. dropEvent( e );
  490. }
  491. #ifdef KDEPIM_NEW_DISTRLISTS
  492. void DistributionListWidget::changed( const KABC::Addressee& dist )
  493. {
  494. emit modified( KABC::Addressee::List() << dist );
  495. }
  496. #else
  497. void DistributionListWidget::changed()
  498. {
  499. save();
  500. }
  501. #endif
  502. DistributionListView::DistributionListView( TQWidget *parent, const char* name )
  503. : KListView( parent, name )
  504. {
  505. setDragEnabled( true );
  506. setAcceptDrops( true );
  507. setAllColumnsShowFocus( true );
  508. }
  509. void DistributionListView::dragEnterEvent( TQDragEnterEvent* e )
  510. {
  511. bool canDecode = TQTextDrag::canDecode( e );
  512. e->accept( canDecode );
  513. }
  514. void DistributionListView::viewportDragMoveEvent( TQDragMoveEvent *e )
  515. {
  516. bool canDecode = TQTextDrag::canDecode( e );
  517. e->accept( canDecode );
  518. }
  519. void DistributionListView::viewportDropEvent( TQDropEvent *e )
  520. {
  521. emit dropped( e, 0 );
  522. }
  523. void DistributionListView::dropEvent( TQDropEvent *e )
  524. {
  525. emit dropped( e, 0 );
  526. }
  527. EmailSelector::EmailSelector( const TQStringList &emails,
  528. const TQString &current, TQWidget *parent )
  529. : KDialogBase( KDialogBase::Plain, i18n("Select Email Address"), Ok|Cancel, Ok,
  530. parent )
  531. {
  532. TQFrame *topFrame = plainPage();
  533. TQBoxLayout *topLayout = new TQVBoxLayout( topFrame );
  534. mButtonGroup = new TQButtonGroup( 1, Horizontal, i18n("Email Addresses"),
  535. topFrame );
  536. mButtonGroup->setRadioButtonExclusive( true );
  537. topLayout->addWidget( mButtonGroup );
  538. TQRadioButton *button = new TQRadioButton( i18n("Preferred address"), mButtonGroup );
  539. button->setDown( true );
  540. mEmailMap.insert( mButtonGroup->id( button ), "" );
  541. TQStringList::ConstIterator it;
  542. for ( it = emails.begin(); it != emails.end(); ++it ) {
  543. button = new TQRadioButton( *it, mButtonGroup );
  544. mEmailMap.insert( mButtonGroup->id( button ), *it );
  545. if ( (*it) == current )
  546. button->setDown( true );
  547. }
  548. }
  549. TQString EmailSelector::selected() const
  550. {
  551. TQButton *button = mButtonGroup->selected();
  552. if ( button )
  553. return mEmailMap[ mButtonGroup->id( button ) ];
  554. return TQString();
  555. }
  556. TQString EmailSelector::getEmail( const TQStringList &emails,
  557. const TQString &current, TQWidget *parent, bool &canceled )
  558. {
  559. EmailSelector dlg( emails, current, parent );
  560. if(dlg.exec())
  561. {
  562. canceled = false;
  563. return dlg.selected();
  564. }
  565. canceled = true;
  566. return TQString();
  567. }
  568. #include "distributionlistwidget.moc"