libtdepim

addressesdialog.cpp
1 /*
2  *
3  * This file is part of libtdepim.
4  *
5  * Copyright (c) 2003 Zack Rusin <zack@kde.org>
6  * Copyright (c) 2003 Aaron J. Seigo <aseigo@kde.org>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB. If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24 
25 #include "addressesdialog.h"
26 #include "addresspicker.h"
27 #include "ldapsearchdialog.h"
28 
29 #include <config.h>
30 
31 #include <libemailfunctions/email.h>
32 
33 #ifdef TDEPIM_NEW_DISTRLISTS
34 #include "distributionlist.h"
35 #include <tderesources/selectdialog.h>
36 #include <tdeabc/resource.h>
37 #else
38 #include <tdeabc/distributionlist.h>
39 #endif
40 
41 #include <tdeabc/stdaddressbook.h>
42 #include <tdeapplication.h>
43 #include <kdebug.h>
44 #include <tdeglobal.h>
45 #include <kiconloader.h>
46 #include <kinputdialog.h>
47 #include <klineedit.h>
48 #include <tdelocale.h>
49 #include <tdemessagebox.h>
50 #include <tdeprocess.h>
51 #include <kpushbutton.h>
52 #include <krun.h>
53 #include <kstandarddirs.h>
54 
55 #include <tqdict.h>
56 #include <tqlayout.h>
57 #include <tqvbox.h>
58 #include <tqwidget.h>
59 
60 namespace KPIM {
61 
62 // private start :
63 struct AddresseeViewItem::AddresseeViewItemPrivate {
64  TDEABC::Addressee address;
65  AddresseeViewItem::Category category;
66  TDEABC::Addressee::List addresses;
67 };
68 
69 struct AddressesDialog::AddressesDialogPrivate {
70  AddressesDialogPrivate() :
71  ui(0), personal(0), recent(0),
72  toItem(0), ccItem(0), bccItem(0),
73  ldapSearchDialog(0)
74  {}
75 
76  AddressPickerUI *ui;
77 
78  AddresseeViewItem *personal;
79  AddresseeViewItem *recent;
80  AddresseeViewItem *topdist;
81  TQPtrList<AddresseeViewItem> dists;
82 
83  AddresseeViewItem *toItem;
84  AddresseeViewItem *ccItem;
85  AddresseeViewItem *bccItem;
86 
87  TQDict<AddresseeViewItem> groupDict;
88 
89  TDEABC::Addressee::List recentAddresses;
90  LDAPSearchDialog *ldapSearchDialog;
91 };
92 // privates end
93 
94 AddresseeViewItem::AddresseeViewItem( AddresseeViewItem *parent, const TDEABC::Addressee& addr,
95  int emailIndex )
96  : TQObject( 0 ), TDEListViewItem( parent, addr.realName(),
97  ( emailIndex == 0 ? addr.preferredEmail() : addr.emails()[ emailIndex ] ) )
98 {
99  d = new AddresseeViewItemPrivate;
100  d->address = addr;
101  d->category = Entry;
102 
103  if ( text( 0 ).stripWhiteSpace().isEmpty() )
104  setText( 0, addr.preferredEmail() );
105 
106  if ( addr.photo().url().isEmpty() ) {
107  if ( addr.photo().data().isNull() )
108  setPixmap( 0, TDEGlobal::iconLoader()->loadIcon( "preferences-desktop-personal", TDEIcon::Small ) );
109  else
110  setPixmap( 0, addr.photo().data().smoothScale( 16, 16 ) );
111  } else {
112  setPixmap( 0, TDEGlobal::iconLoader()->loadIcon( addr.photo().url(), TDEIcon::Small ) );
113  }
114 }
115 
116 AddresseeViewItem::AddresseeViewItem( TDEListView *lv, const TQString& name, Category cat )
117  : TQObject(0), TDEListViewItem( lv, name )
118 {
119  d = new AddresseeViewItemPrivate;
120  d->category = cat;
121 }
122 
123 AddresseeViewItem::AddresseeViewItem( AddresseeViewItem *parent, const TQString& name,
124  const TDEABC::Addressee::List &lst )
125  : TQObject(0), TDEListViewItem( parent, name, i18n("<group>") )
126 {
127  d = new AddresseeViewItemPrivate;
128  d->category = FilledGroup;
129  d->addresses = lst;
130 }
131 
132 AddresseeViewItem::AddresseeViewItem( AddresseeViewItem *parent, const TQString& name )
133  : TQObject(0), TDEListViewItem( parent, name, i18n("<group>") )
134 {
135  d = new AddresseeViewItemPrivate;
136  d->category = DistList;
137 
138  setPixmap( 0, TDEGlobal::iconLoader()->loadIcon( "tdmconfig", TDEIcon::Small ) );
139 }
140 
141 AddresseeViewItem::~AddresseeViewItem()
142 {
143  delete d;
144  d = 0;
145 }
146 
147 TDEABC::Addressee
148 AddresseeViewItem::addressee() const
149 {
150  return d->address;
151 }
152 
153 TDEABC::Addressee::List
154 AddresseeViewItem::addresses() const
155 {
156  return d->addresses;
157 }
158 
159 AddresseeViewItem::Category
160 AddresseeViewItem::category() const
161 {
162  return d->category;
163 }
164 
165 TQString
166 AddresseeViewItem::name() const
167 {
168  return text(0);
169 }
170 
171 TQString
172 AddresseeViewItem::email() const
173 {
174  return text(1);
175 }
176 
177 bool AddresseeViewItem::matches(const TQString& txt) const
178 {
179  return d->address.realName().contains(txt, false) || d->address.preferredEmail().contains(txt, false);
180 }
181 
182 void AddresseeViewItem::setSelected(bool selected)
183 {
184  if (selected == isSelected())
185  {
186  return;
187  }
188 
189  emit addressSelected( this, selected );
190  TQListViewItem::setSelected(selected);
191 }
192 
193 int
194 AddresseeViewItem::compare( TQListViewItem * i, int col, bool ascending ) const
195 {
196  if ( category() == Group || category() == Entry )
197  return TDEListViewItem::compare( i , col, ascending );
198 
199  AddresseeViewItem *item = static_cast<AddresseeViewItem*>( i );
200  int a = static_cast<int>( category() );
201  int b = static_cast<int>( item->category() );
202 
203  if ( ascending )
204  if ( a < b )
205  return -1;
206  else
207  return 1;
208  else
209  if ( a < b )
210  return 1;
211  else
212  return -1;
213 }
214 
215 AddressesDialog::AddressesDialog( TQWidget *widget, const char *name )
216  : KDialogBase( widget, name, true, i18n("Address Selection"),
217  Ok|Cancel, Ok, true )
218 {
219  TQVBox *page = makeVBoxMainWidget();
220  d = new AddressesDialogPrivate;
221  d->ui = new AddressPickerUI( page );
222 
223  TDEABC::StdAddressBook::self( true );
224  updateAvailableAddressees();
225  initConnections();
226 
227  d->ui->mAvailableView->setFocus();
228 
229  setMainWidget( page );
230  page->setMinimumSize( 750, 400 );
231 }
232 
233 AddressesDialog::~AddressesDialog()
234 {
235  delete d;
236  d = 0;
237 }
238 
239 AddresseeViewItem* AddressesDialog::selectedToItem()
240 {
241  if ( !d->toItem )
242  {
243  d->toItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("To"), AddresseeViewItem::To );
244  connect(d->toItem, TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
245  this, TQ_SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
246  }
247  return d->toItem;
248 }
249 
250 AddresseeViewItem* AddressesDialog::selectedCcItem()
251 {
252  if ( !d->ccItem )
253  {
254  d->ccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("CC"), AddresseeViewItem::CC );
255  connect(d->ccItem, TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
256  this, TQ_SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
257  }
258  return d->ccItem;
259 }
260 
261 AddresseeViewItem* AddressesDialog::selectedBccItem()
262 {
263  if ( !d->bccItem )
264  {
265  d->bccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("BCC"), AddresseeViewItem::BCC );
266  connect(d->bccItem, TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
267  this, TQ_SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
268  }
269  return d->bccItem;
270 }
271 
272 void
273 AddressesDialog::setSelectedTo( const TQStringList& l )
274 {
275  TQString name, email;
276  for ( TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) {
277  TDEABC::Addressee addr;
278  TDEABC::Addressee::parseEmailAddress( *it, name, email );
279  addr.setNameFromString( name );
280  addr.insertEmail( email );
281  addAddresseeToSelected( addr, selectedToItem() );
282  }
283 }
284 
285 void
286 AddressesDialog::setSelectedCC( const TQStringList& l )
287 {
288  TQString name, email;
289  for ( TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) {
290  TDEABC::Addressee addr;
291  TDEABC::Addressee::parseEmailAddress( *it, name, email );
292  addr.setNameFromString( name );
293  addr.insertEmail( email );
294  addAddresseeToSelected( addr, selectedCcItem() );
295  }
296 }
297 
298 void
299 AddressesDialog::setSelectedBCC( const TQStringList& l )
300 {
301  TQString name, email;
302  for ( TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) {
303  TDEABC::Addressee addr;
304  TDEABC::Addressee::parseEmailAddress( *it, name, email );
305  addr.setNameFromString( name );
306  addr.insertEmail( email );
307  addAddresseeToSelected( addr, selectedBccItem() );
308  }
309 }
310 
311 void
312 AddressesDialog::setRecentAddresses( const TDEABC::Addressee::List& list )
313 {
314  d->recentAddresses = list;
315 
316  updateRecentAddresses();
317 
318  checkForSingleAvailableGroup();
319 }
320 
321 void
322 AddressesDialog::updateRecentAddresses()
323 {
324  static const TQString &recentGroup = TDEGlobal::staticQString( i18n( "Recent Addresses" ) );
325 
326  if ( !d->recent ) {
327  d->recent = new AddresseeViewItem( d->ui->mAvailableView, recentGroup );
328  connect(d->recent, TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
329  this, TQ_SLOT(availableAddressSelected(AddresseeViewItem*, bool)));
330  d->recent->setVisible( false );
331  d->groupDict.insert( recentGroup, d->recent );
332  }
333 
334  TDEABC::Addressee::List::ConstIterator it;
335  for ( it = d->recentAddresses.begin(); it != d->recentAddresses.end(); ++it )
336  addAddresseeToAvailable( *it, d->recent );
337 
338  if ( d->recent->childCount() > 0 ) {
339  d->recent->setOpen( true );
340  d->recent->setVisible( true );
341  }
342 }
343 
344 void
345 AddressesDialog::setShowCC( bool b )
346 {
347  d->ui->mCCButton->setShown( b );
348 }
349 
350 void
351 AddressesDialog::setShowBCC( bool b )
352 {
353  d->ui->mBCCButton->setShown( b );
354 }
355 
356 TQStringList
357 AddressesDialog::to() const
358 {
359  TQStringList emails = allDistributionLists( d->toItem );
360  TDEABC::Addressee::List l = toAddresses();
361  emails += entryToString( l );
362 
363  return emails;
364 }
365 
366 TQStringList
367 AddressesDialog::cc() const
368 {
369  TQStringList emails = allDistributionLists( d->ccItem );
370  TDEABC::Addressee::List l = ccAddresses();
371  emails += entryToString( l );
372 
373  return emails;
374 }
375 
376 TQStringList
377 AddressesDialog::bcc() const
378 {
379  TQStringList emails = allDistributionLists( d->bccItem );
380 
381  TDEABC::Addressee::List l = bccAddresses();
382  emails += entryToString( l );
383 
384  return emails;
385 }
386 
387 TDEABC::Addressee::List
388 AddressesDialog::toAddresses() const
389 {
390  return allAddressee( d->toItem );
391 }
392 TDEABC::Addressee::List
393 AddressesDialog::allToAddressesNoDuplicates() const
394 {
395  TDEABC::Addressee::List aList = allAddressee( d->toItem );
396  const TQStringList dList = toDistributionLists();
397  TDEABC::AddressBook* abook = TDEABC::StdAddressBook::self( true );
398 #ifdef TDEPIM_NEW_DISTRLISTS
399  for ( TQStringList::ConstIterator it = dList.begin(); it != dList.end(); ++it ) {
400  const TQValueList<KPIM::DistributionList::Entry> eList
401  = KPIM::DistributionList::findByName(abook, *it).entries(abook);
402  TQValueList<KPIM::DistributionList::Entry>::ConstIterator eit;
403  for( eit = eList.begin(); eit != eList.end(); ++eit ) {
404  TDEABC::Addressee a = (*eit).addressee;
405  if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) {
406  aList.append( a ) ;
407  }
408  }
409  }
410 #else
411  TDEABC::DistributionListManager manager( abook );
412  manager.load();
413  for ( TQStringList::ConstIterator it = dList.begin(); it != dList.end(); ++it ) {
414  const TQValueList<TDEABC::DistributionList::Entry> eList = manager.list( *it )->entries();
415  TQValueList<TDEABC::DistributionList::Entry>::ConstIterator eit;
416  for( eit = eList.begin(); eit != eList.end(); ++eit ) {
417  TDEABC::Addressee a = (*eit).addressee;
418  if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) {
419  aList.append( a ) ;
420  }
421  }
422  }
423 #endif
424  return aList;
425 }
426 
427 TDEABC::Addressee::List
428 AddressesDialog::ccAddresses() const
429 {
430  return allAddressee( d->ccItem );
431 }
432 
433 TDEABC::Addressee::List
434 AddressesDialog::bccAddresses() const
435 {
436  return allAddressee( d->bccItem );
437 }
438 
439 
440 TQStringList
441 AddressesDialog::toDistributionLists() const
442 {
443  return allDistributionLists( d->toItem );
444 }
445 
446 TQStringList
447 AddressesDialog::ccDistributionLists() const
448 {
449  return allDistributionLists( d->ccItem );
450 }
451 
452 TQStringList
453 AddressesDialog::bccDistributionLists() const
454 {
455  return allDistributionLists( d->bccItem );
456 }
457 
458 void
459 AddressesDialog::updateAvailableAddressees()
460 {
461  d->ui->mAvailableView->clear();
462  d->groupDict.clear();
463 
464  static const TQString &personalGroup = TDEGlobal::staticQString( i18n( "Other Addresses" ) );
465  d->ui->mAvailableView->setRootIsDecorated( true );
466  d->personal = new AddresseeViewItem( d->ui->mAvailableView, personalGroup );
467  //connect(d->personal, TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
468  // this, TQ_SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
469  d->personal->setVisible( false );
470  d->groupDict.insert( personalGroup, d->personal );
471 
472  TDEABC::AddressBook *addressBook = TDEABC::StdAddressBook::self( true );
473  for( TDEABC::AddressBook::Iterator it = addressBook->begin();
474  it != addressBook->end(); ++it ) {
475  addAddresseeToAvailable( *it, d->personal );
476  }
477 
478  d->recent = 0;
479  updateRecentAddresses();
480 
481  d->topdist = 0;
482  addDistributionLists();
483  if ( d->personal->childCount() > 0 ) {
484  d->personal->setOpen( true );
485  d->personal->setVisible( true );
486  }
487 
488  checkForSingleAvailableGroup();
489 }
490 
491 void AddressesDialog::checkForSingleAvailableGroup()
492 {
493  TQListViewItem* item = d->ui->mAvailableView->firstChild();
494  TQListViewItem* firstGroup = 0;
495  int found = 0;
496  while (item)
497  {
498  if (item->isVisible())
499  {
500  if (!firstGroup && static_cast<AddresseeViewItem*>(item)->category() != AddresseeViewItem::Entry)
501  {
502  firstGroup = item;
503  }
504  ++found;
505  }
506  item = item->nextSibling();
507  }
508 
509  if (found == 1 && firstGroup)
510  {
511  firstGroup->setOpen(true);
512  }
513 }
514 
515 void
516 AddressesDialog::availableSelectionChanged()
517 {
518  bool selection = !selectedAvailableAddresses.isEmpty();
519  d->ui->mToButton->setEnabled(selection);
520  d->ui->mCCButton->setEnabled(selection);
521  d->ui->mBCCButton->setEnabled(selection);
522 }
523 
524 void
525 AddressesDialog::selectedSelectionChanged()
526 {
527  bool selection = !selectedSelectedAddresses.isEmpty();
528  d->ui->mRemoveButton->setEnabled(selection);
529 }
530 
531 void
532 AddressesDialog::availableAddressSelected( AddresseeViewItem* item, bool selected )
533 {
534  if (selected)
535  {
536  selectedAvailableAddresses.append(item);
537  }
538  else
539  {
540  selectedAvailableAddresses.remove(item);
541  }
542 }
543 
544 void
545 AddressesDialog::selectedAddressSelected( AddresseeViewItem* item, bool selected )
546 {
547  // we have to avoid that a parent and a child is selected together
548  // because in this case we get a double object deletion ( program crashes )
549  // when removing the selected items from list
550  AddresseeViewItem* parent = static_cast<AddresseeViewItem*>(((TQListViewItem*)item)->parent());
551  if ( parent && selected )
552  parent->setSelected( false );
553  if (selected)
554  {
555  selectedSelectedAddresses.append(item);
556  }
557  else
558  {
559  selectedSelectedAddresses.remove(item);
560  }
561  if ( selected ) {
562  AddresseeViewItem* child = static_cast<AddresseeViewItem*>(item->firstChild());
563  while (child) {
564  child->setSelected( false );
565  child = static_cast<AddresseeViewItem*>(child->nextSibling());
566  }
567  }
568 }
569 
570 void
571 AddressesDialog::initConnections()
572 {
573  connect( d->ui->mFilterEdit, TQ_SIGNAL(textChanged(const TQString &)),
574  TQ_SLOT(filterChanged(const TQString &)) );
575  connect( d->ui->mToButton, TQ_SIGNAL(clicked()),
576  TQ_SLOT(addSelectedTo()) );
577  connect( d->ui->mCCButton, TQ_SIGNAL(clicked()),
578  TQ_SLOT(addSelectedCC()) );
579  connect( d->ui->mBCCButton, TQ_SIGNAL(clicked()),
580  TQ_SLOT(addSelectedBCC()) );
581  connect( d->ui->mSaveAs, TQ_SIGNAL(clicked()),
582  TQ_SLOT(saveAs()) );
583  connect( d->ui->mLdapSearch, TQ_SIGNAL(clicked()),
584  TQ_SLOT(searchLdap()) );
585  connect( d->ui->mRemoveButton, TQ_SIGNAL(clicked()),
586  TQ_SLOT(removeEntry()) );
587  connect( d->ui->mAvailableView, TQ_SIGNAL(selectionChanged()),
588  TQ_SLOT(availableSelectionChanged()) );
589  connect( d->ui->mAvailableView, TQ_SIGNAL(doubleClicked(TQListViewItem*)),
590  TQ_SLOT(addSelectedTo()) );
591  connect( d->ui->mSelectedView, TQ_SIGNAL(selectionChanged()),
592  TQ_SLOT(selectedSelectionChanged()) );
593  connect( d->ui->mSelectedView, TQ_SIGNAL(doubleClicked(TQListViewItem*)),
594  TQ_SLOT(removeEntry()) );
595 
596 #ifndef TDEPIM_NEW_DISTRLISTS
597  connect( TDEABC::DistributionListWatcher::self(), TQ_SIGNAL( changed() ),
598  this, TQ_SLOT( updateAvailableAddressees() ) );
599 #endif
600 
601  connect( TDEABC::StdAddressBook::self( true ), TQ_SIGNAL( addressBookChanged(AddressBook*) ),
602  this, TQ_SLOT( updateAvailableAddressees() ) );
603 }
604 
605 void
606 AddressesDialog::addAddresseeToAvailable( const TDEABC::Addressee& addr, AddresseeViewItem* defaultParent, bool useCategory )
607 {
608  if ( addr.preferredEmail().isEmpty() )
609  return;
610 
611  if ( useCategory ) {
612  TQStringList categories = addr.categories();
613 
614  for ( TQStringList::Iterator it = categories.begin(); it != categories.end(); ++it ) {
615  if ( !d->groupDict[ *it ] ) { //we don't have the category yet
616  AddresseeViewItem* category = new AddresseeViewItem( d->ui->mAvailableView, *it );
617  d->groupDict.insert( *it, category );
618  }
619 
620  for ( uint i = 0; i < addr.emails().count(); ++i ) {
621  AddresseeViewItem* addressee = new AddresseeViewItem( d->groupDict[ *it ], addr, i );
622  connect(addressee, TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
623  this, TQ_SLOT(availableAddressSelected(AddresseeViewItem*, bool)));
624  }
625  }
626  }
627 
628  bool noCategory = false;
629  if ( useCategory ) {
630  if ( addr.categories().isEmpty() )
631  noCategory = true;
632  } else
633  noCategory = true;
634 
635  if ( defaultParent && noCategory ) { // only non-categorized items here
636  AddresseeViewItem* addressee = new AddresseeViewItem( defaultParent, addr );
637  connect(addressee, TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
638  this, TQ_SLOT(availableAddressSelected(AddresseeViewItem*, bool)));
639  }
640 }
641 
642 void
643 AddressesDialog::addAddresseeToSelected( const TDEABC::Addressee& addr, AddresseeViewItem* defaultParent )
644 {
645  if ( addr.preferredEmail().isEmpty() )
646  return;
647 
648  if ( defaultParent ) {
649  AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( defaultParent->firstChild() );
650  while( myChild ) {
651  if ( myChild->addressee().preferredEmail() == addr.preferredEmail() )
652  return;//already got it
653  myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() );
654  }
655  AddresseeViewItem* addressee = new AddresseeViewItem( defaultParent, addr );
656  connect(addressee, TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
657  this, TQ_SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
658  defaultParent->setOpen( true );
659  }
660 
661  d->ui->mSaveAs->setEnabled(true);
662 }
663 
664 void
665 AddressesDialog::addAddresseesToSelected( AddresseeViewItem *parent,
666  const TQPtrList<AddresseeViewItem>& addresses )
667 {
668  Q_ASSERT( parent );
669 
670  TQPtrListIterator<AddresseeViewItem> itr( addresses );
671 
672  if (itr.current())
673  {
674  d->ui->mSaveAs->setEnabled(true);
675  }
676 
677  while ( itr.current() ) {
678  AddresseeViewItem* address = itr.current();
679  ++itr;
680 
681  if (selectedToAvailableMapping.find(address) != 0)
682  {
683  continue;
684  }
685 
686  AddresseeViewItem* newItem = 0;
687  if (address->category() == AddresseeViewItem::Entry)
688  {
689  newItem = new AddresseeViewItem( parent, address->addressee() );
690  }
691  else if (address->category() == AddresseeViewItem::DistList)
692  {
693  newItem = new AddresseeViewItem( parent, address->name() );
694  }
695  else
696  {
697  newItem = new AddresseeViewItem( parent, address->name(), allAddressee( address ) );
698  }
699 
700  address->setSelected( false );
701  address->setVisible( false );
702  selectedToAvailableMapping.insert(address, newItem);
703  selectedToAvailableMapping.insert(newItem, address);
704  connect(newItem, TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
705  this, TQ_SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
706  }
707 
708  parent->setOpen( true );
709 }
710 
711 TQStringList
712 AddressesDialog::entryToString( const TDEABC::Addressee::List& l ) const
713 {
714  TQStringList entries;
715 
716  for( TDEABC::Addressee::List::ConstIterator it = l.begin(); it != l.end(); ++it ) {
717  entries += (*it).fullEmail();
718  }
719  return entries;
720 }
721 
722 void
723 AddressesDialog::addSelectedTo()
724 {
725  if ( !d->toItem )
726  {
727  d->toItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("To"), AddresseeViewItem::To );
728  connect(d->toItem, TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
729  this, TQ_SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
730  }
731 
732  addAddresseesToSelected( d->toItem, selectedAvailableAddresses );
733  selectedAvailableAddresses.clear();
734 
735  if ( d->toItem->childCount() > 0 ) {
736  d->toItem->setVisible( true );
737  } else {
738  delete d->toItem;
739  d->toItem = 0;
740  }
741 }
742 
743 void
744 AddressesDialog::addSelectedCC()
745 {
746  if ( !d->ccItem )
747  {
748  d->ccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("CC"), AddresseeViewItem::CC );
749  connect(d->ccItem , TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
750  this, TQ_SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
751  }
752 
753  addAddresseesToSelected( d->ccItem, selectedAvailableAddresses );
754  selectedAvailableAddresses.clear();
755 
756  if ( d->ccItem->childCount() > 0 ) {
757  d->ccItem->setVisible( true );
758  } else {
759  delete d->ccItem;
760  d->ccItem = 0;
761  }
762 }
763 
764 void
765 AddressesDialog::addSelectedBCC()
766 {
767  if ( !d->bccItem )
768  {
769  d->bccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("BCC"), AddresseeViewItem::BCC );
770  connect(d->bccItem , TQ_SIGNAL(addressSelected(AddresseeViewItem*, bool)),
771  this, TQ_SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
772  }
773 
774  addAddresseesToSelected( d->bccItem, selectedAvailableAddresses );
775  selectedAvailableAddresses.clear();
776 
777  if ( d->bccItem->childCount() > 0 ) {
778  d->bccItem->setVisible( true );
779  } else {
780  delete d->bccItem;
781  d->bccItem = 0;
782  }
783 }
784 
785 void AddressesDialog::unmapSelectedAddress(AddresseeViewItem* item)
786 {
787  AddresseeViewItem* correspondingItem = selectedToAvailableMapping[item];
788  if (correspondingItem)
789  {
790  correspondingItem->setVisible( true );
791  selectedToAvailableMapping.remove( item );
792  selectedToAvailableMapping.remove( correspondingItem );
793  }
794 
795  AddresseeViewItem* child = static_cast<AddresseeViewItem*>(item->firstChild());
796  while (child)
797  {
798  unmapSelectedAddress(child);
799  child = static_cast<AddresseeViewItem*>(child->nextSibling());
800  }
801 }
802 
803 void
804 AddressesDialog::removeEntry()
805 {
806  TQPtrList<AddresseeViewItem> lst;
807  bool resetTo = false;
808  bool resetCC = false;
809  bool resetBCC = false;
810 
811  lst.setAutoDelete( false );
812  TQPtrListIterator<AddresseeViewItem> it( selectedSelectedAddresses );
813  while ( it.current() ) {
814  AddresseeViewItem* item = it.current();
815  ++it;
816  if ( d->toItem == item )
817  resetTo = true;
818  else if ( d->ccItem == item )
819  resetCC = true;
820  else if( d->bccItem == item )
821  resetBCC = true;
822  // we may only append parent items
823  unmapSelectedAddress(item);
824  lst.append( item );
825  }
826  selectedSelectedAddresses.clear();
827  lst.setAutoDelete( true );
828  lst.clear();
829  if ( resetTo )
830  d->toItem = 0;
831  else if ( d->toItem && d->toItem->childCount() == 0 )
832  {
833  delete d->toItem;
834  d->toItem = 0;
835  }
836  if ( resetCC )
837  d->ccItem = 0;
838  else if ( d->ccItem && d->ccItem->childCount() == 0 )
839  {
840  delete d->ccItem;
841  d->ccItem = 0;
842  }
843  if ( resetBCC )
844  d->bccItem = 0;
845  else if ( d->bccItem && d->bccItem->childCount() == 0 )
846  {
847  delete d->bccItem;
848  d->bccItem = 0;
849  }
850  d->ui->mSaveAs->setEnabled(d->ui->mSelectedView->firstChild() != 0);
851 }
852 
853 #ifdef TDEPIM_NEW_DISTRLISTS
854 
855 // copied from tdeabcore.cpp :(
856 // KDE4: should be in libtdeabc I think
857 static TDEABC::Resource *requestResource( TDEABC::AddressBook* abook, TQWidget *parent )
858 {
859  TQPtrList<TDEABC::Resource> tdeabcResources = abook->resources();
860 
861  TQPtrList<KRES::Resource> kresResources;
862  TQPtrListIterator<TDEABC::Resource> resIt( tdeabcResources );
863  TDEABC::Resource *resource;
864  while ( ( resource = resIt.current() ) != 0 ) {
865  ++resIt;
866  if ( !resource->readOnly() ) {
867  KRES::Resource *res = static_cast<KRES::Resource*>( resource );
868  if ( res )
869  kresResources.append( res );
870  }
871  }
872 
873  KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, parent );
874  return static_cast<TDEABC::Resource*>( res );
875 }
876 #endif
877 
878 void
879 AddressesDialog::saveAs()
880 {
881 #ifndef TDEPIM_NEW_DISTRLISTS
882  TDEABC::DistributionListManager manager( TDEABC::StdAddressBook::self( true ) );
883  manager.load();
884 #endif
885 
886  if ( !d->ui->mSelectedView->firstChild() ) {
887  KMessageBox::information( 0,
888  i18n("There are no addresses in your list. "
889  "First add some addresses from your address book, "
890  "then try again.") );
891  return;
892  }
893 
894  bool ok = false;
895  TQString name = KInputDialog::getText( i18n("New Distribution List"),
896  i18n("Please enter name:"),
897  TQString(), &ok,
898  this );
899  if ( !ok || name.isEmpty() )
900  return;
901 
902  bool alreadyExists = false;
903 #ifdef TDEPIM_NEW_DISTRLISTS
904  TDEABC::AddressBook* abook = TDEABC::StdAddressBook::self( true );
905  KPIM::DistributionList dlist = KPIM::DistributionList::findByName( abook, name );
906  alreadyExists = !dlist.isEmpty();
907 #else
908  alreadyExists = manager.list( name );
909 #endif
910 
911  if ( alreadyExists ) {
912  KMessageBox::information( 0,
913  i18n( "<qt>Distribution list with the given name <b>%1</b> "
914  "already exists. Please select a different name.</qt>" )
915  .arg( name ) );
916  return;
917  }
918 
919 #ifdef TDEPIM_NEW_DISTRLISTS
920  TDEABC::Resource* resource = requestResource( abook, this );
921  if ( !resource )
922  return;
923 
924  dlist.setResource( resource );
925  dlist.setName( name );
926  TDEABC::Addressee::List addrl = allAddressee( d->ui->mSelectedView, false );
927  for ( TDEABC::Addressee::List::iterator itr = addrl.begin();
928  itr != addrl.end(); ++itr ) {
929  dlist.insertEntry( *itr );
930  }
931  abook->insertAddressee( dlist );
932 #else
933  TDEABC::DistributionList *dlist = new TDEABC::DistributionList( &manager, name );
934  TDEABC::Addressee::List addrl = allAddressee( d->ui->mSelectedView, false );
935  for ( TDEABC::Addressee::List::iterator itr = addrl.begin();
936  itr != addrl.end(); ++itr ) {
937  dlist->insertEntry( *itr );
938  }
939 
940  manager.save();
941 #endif
942 }
943 
944 void
945 AddressesDialog::searchLdap()
946 {
947  if ( !d->ldapSearchDialog ) {
948  d->ldapSearchDialog = new LDAPSearchDialog( this );
949  connect( d->ldapSearchDialog, TQ_SIGNAL( addresseesAdded() ),
950  TQ_SLOT(ldapSearchResult() ) );
951  }
952  d->ldapSearchDialog->show();
953 }
954 
955 void
956 AddressesDialog::ldapSearchResult()
957 {
958  TQStringList emails = KPIM::splitEmailAddrList( d->ldapSearchDialog->selectedEMails() );
959  TQStringList::iterator it( emails.begin() );
960  TQStringList::iterator end( emails.end() );
961  for ( ; it != end; ++it ){
962  TQString name;
963  TQString email;
964  KPIM::getNameAndMail( (*it), name, email );
965  TDEABC::Addressee ad;
966  ad.setNameFromString( name );
967  ad.insertEmail( email );
968  addAddresseeToSelected( ad, selectedToItem() );
969  }
970 }
971 
972 void
973 AddressesDialog::launchAddressBook()
974 {
975  kapp->startServiceByDesktopName( "kaddressbook", TQString() );
976 }
977 
978 void
979 AddressesDialog::filterChanged( const TQString& txt )
980 {
981  TQListViewItemIterator it( d->ui->mAvailableView );
982  bool showAll = false;
983 
984  if ( txt.isEmpty() )
985  showAll = true;
986 
987  int personalVisible = 0;
988  int recentVisible = 0;
989  while ( it.current() ) {
990  AddresseeViewItem* item = static_cast<AddresseeViewItem*>( it.current() );
991  ++it;
992 
993  if ( showAll ) {
994  item->setOpen( true );
995  item->setVisible( true );
996  // allen: I do not like the following behavior. comment out and see if anyone screams
997  //if ( item->category() == AddresseeViewItem::Group )
998  // item->setOpen( false );//close to not have too many entries
999  continue;
1000  }
1001 
1002  if ( item->category() == AddresseeViewItem::Entry ) {
1003  bool matches = item->matches( txt );
1004  item->setVisible( matches );
1005  TQListViewItem *parent = static_cast<TQListViewItem*>( item )->parent();
1006  if ( matches && parent ) {
1007  if ( parent == d->personal ) {
1008  personalVisible++;
1009  } else if ( parent == d->recent ) {
1010  recentVisible++;
1011  }
1012  }
1013  }
1014  if ( item->category() == AddresseeViewItem::Group ) {
1015  item->setOpen( true );
1016  item->setVisible( true );
1017  }
1018  }
1019 
1020  if ( !showAll && personalVisible == 0 ) {
1021  d->personal->setOpen( false );
1022  d->personal->setVisible( false );
1023  }
1024  if ( !showAll && recentVisible == 0 ) {
1025  d->recent->setOpen( false );
1026  d->recent->setVisible( false );
1027  }
1028 
1029  int distlistgroupVisible = 0;
1030  if ( !showAll ) {
1031  TQPtrListIterator<AddresseeViewItem> it( d->dists );
1032  for ( ; it.current(); ++it ) {
1033  TQListViewItem *p = *it;
1034  p->setVisible( true );
1035  AddresseeViewItem *p2 = static_cast<AddresseeViewItem*>( p->firstChild() );
1036  int pcount = 0;
1037  while ( p2 ) {
1038  if ( p2->matches( txt ) ) {
1039  p2->setVisible( true );
1040  pcount++;
1041  } else {
1042  p2->setVisible( false );
1043  }
1044  p2 = static_cast<AddresseeViewItem*>( p2->nextSibling() );
1045  }
1046  if ( !pcount && !p->text( 0 ).contains( txt, false ) ) {
1047  p->setVisible( false );
1048  }
1049  distlistgroupVisible += pcount;
1050  if ( p->text( 0 ).contains( txt, false ) ) {
1051  distlistgroupVisible++;
1052  }
1053  }
1054  }
1055  if ( d->topdist ) {
1056  if ( showAll || distlistgroupVisible > 0 ) {
1057  d->topdist->setOpen( true );
1058  } else {
1059  d->topdist->setOpen( false );
1060  d->topdist->setVisible( false );
1061  }
1062  }
1063 }
1064 
1065 TDEABC::Addressee::List
1066 AddressesDialog::allAddressee( TDEListView* view, bool onlySelected ) const
1067 {
1068  TDEABC::Addressee::List lst;
1069  TQListViewItemIterator it( view );
1070  while ( it.current() ) {
1071  AddresseeViewItem* item = static_cast<AddresseeViewItem*>( it.current() );
1072  if ( !onlySelected || item->isSelected() ) {
1073  if ( item->category() != AddresseeViewItem::Entry ) {
1074  AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( item->firstChild() );
1075  while( myChild ) {
1076  lst.append( myChild->addressee() );
1077  myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() );
1078  }
1079  } else {
1080  lst.append( item->addressee() );
1081  }
1082  }
1083  ++it;
1084  }
1085 
1086  return lst;
1087 }
1088 
1089 TDEABC::Addressee::List
1090 AddressesDialog::allAddressee( AddresseeViewItem* parent ) const
1091 {
1092  TDEABC::Addressee::List lst;
1093 
1094  if ( !parent ) return lst;
1095 
1096  if ( parent->category() == AddresseeViewItem::Entry )
1097  {
1098  lst.append( parent->addressee() );
1099  return lst;
1100  }
1101 
1102  AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( parent->firstChild() );
1103  while( myChild ) {
1104  if ( myChild->category() == AddresseeViewItem::FilledGroup )
1105  lst += myChild->addresses();
1106  else if ( !myChild->addressee().isEmpty() )
1107  lst.append( myChild->addressee() );
1108  myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() );
1109  }
1110 
1111  return lst;
1112 }
1113 
1114 TQStringList
1115 AddressesDialog::allDistributionLists( AddresseeViewItem* parent ) const
1116 {
1117  TQStringList lists;
1118 
1119  if ( !parent )
1120  return TQStringList();
1121 
1122  AddresseeViewItem *item = static_cast<AddresseeViewItem*>( parent->firstChild() );
1123  while ( item ) {
1124  if ( item->category() == AddresseeViewItem::DistList && !item->name().isEmpty() )
1125  lists.append( item->name() );
1126 
1127  item = static_cast<AddresseeViewItem*>( item->nextSibling() );
1128  }
1129 
1130  return lists;
1131 }
1132 
1133 void
1134 AddressesDialog::addDistributionLists()
1135 {
1136  TDEABC::AddressBook* abook = TDEABC::StdAddressBook::self( true );
1137 
1138 #ifdef TDEPIM_NEW_DISTRLISTS
1139  const TQValueList<KPIM::DistributionList> distLists =
1140  KPIM::DistributionList::allDistributionLists( abook );
1141 #else
1142  TDEABC::DistributionListManager manager( abook );
1143  manager.load();
1144 
1145  TQStringList distLists = manager.listNames();
1146 #endif
1147 
1148  if ( distLists.isEmpty() )
1149  return;
1150 
1151  if ( !d->topdist ) {
1152  d->topdist = new AddresseeViewItem( d->ui->mAvailableView, i18n( "Distribution Lists" ) );
1153  }
1154 
1155 #ifdef TDEPIM_NEW_DISTRLISTS
1156  TQValueList<KPIM::DistributionList>::ConstIterator listIt;
1157 #else
1158  TQStringList::Iterator listIt;
1159 #endif
1160  int total = 0;
1161  for ( listIt = distLists.begin(); listIt != distLists.end(); ++listIt ) {
1162 #ifdef TDEPIM_NEW_DISTRLISTS
1163  KPIM::DistributionList dlist = *listIt;
1164  KPIM::DistributionList::Entry::List entries = dlist.entries(abook);
1165 #else
1166  TDEABC::DistributionList& dlist = *manager.list( *listIt );
1167  TDEABC::DistributionList::Entry::List entries = dlist.entries();
1168 #endif
1169 
1170  AddresseeViewItem *item = new AddresseeViewItem( d->topdist, dlist.name() );
1171  d->dists.append( item );
1172  connect( item, TQ_SIGNAL( addressSelected( AddresseeViewItem*, bool ) ),
1173  this, TQ_SLOT( availableAddressSelected( AddresseeViewItem*, bool ) ) );
1174 
1175 #ifdef TDEPIM_NEW_DISTRLISTS
1176  KPIM::DistributionList::Entry::List::Iterator itemIt;
1177 #else
1178  TDEABC::DistributionList::Entry::List::Iterator itemIt;
1179 #endif
1180  for ( itemIt = entries.begin(); itemIt != entries.end(); ++itemIt ) {
1181  addAddresseeToAvailable( (*itemIt).addressee, item, false );
1182  }
1183  if ( item->childCount() > 0 ) {
1184  item->setOpen( true );
1185  item->setVisible( true );
1186  }
1187  total += item->childCount();
1188  }
1189  if ( total > 0 ) {
1190  d->topdist->setOpen( true );
1191  d->topdist->setVisible( true );
1192  }
1193 }
1194 
1195 } // namespace
1196 
1197 #include "addressesdialog.moc"
Distribution list of email addresses.
void insertEntry(const Addressee &, const TQString &email=TQString())
Insert an entry into this distribution list.
void setName(const TQString &name)
HACK: reimplemented from Addressee, but it's NOT virtual there.
Entry::List entries(TDEABC::AddressBook *book) const
Return list of entries belonging to this distribution list.
TDEPIM classes for drag and drop of mails.