libtdepim

addresseeselector.cpp
1 /*
2  This file is part of libtdepim.
3 
4  Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public 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
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include <tqheader.h>
23 #include <tqlabel.h>
24 #include <tqlayout.h>
25 #include <tqsignalmapper.h>
26 #include <tqtoolbutton.h>
27 
28 #include <tdeabc/stdaddressbook.h>
29 #include <kcombobox.h>
30 #include <kdialog.h>
31 #include <tdeglobal.h>
32 #include <kiconloader.h>
33 #include <klineedit.h>
34 #include <tdelistview.h>
35 #include <tdelocale.h>
36 
37 #include "addresseeselector.h"
38 
39 using namespace KPIM;
40 
41 class AddresseeSelector::AddressBookManager
42 {
43  public:
44  TQStringList titles() const;
45 
46  void addResource( TDEABC::Resource* );
47  void addAddressBook( const TQString &title, SelectionItem::List &list );
48 
49  void clear();
50  bool contains( uint index, const SelectionItem& );
51 
52  private:
53  struct AddressBookEntry {
54  TQString title;
55  SelectionItem::List list;
56  };
57 
58  TQValueList<TDEABC::Resource*> mResources;
59  TQValueList<AddressBookEntry> mAddressBooks;
60 };
61 
62 TQStringList AddresseeSelector::AddressBookManager::titles() const
63 {
64  TQStringList titles;
65 
66  // we've always an 'all' entry
67  titles.append( i18n( "All" ) );
68 
69  TQValueList<TDEABC::Resource*>::ConstIterator resIt;
70  for ( resIt = mResources.begin(); resIt != mResources.end(); ++resIt )
71  titles.append( (*resIt)->resourceName() );
72 
73  TQValueList<AddressBookEntry>::ConstIterator abIt;
74  for ( abIt = mAddressBooks.begin(); abIt != mAddressBooks.end(); ++abIt )
75  titles.append( (*abIt).title );
76 
77  return titles;
78 }
79 
80 void AddresseeSelector::AddressBookManager::addResource( TDEABC::Resource *resource )
81 {
82  if ( mResources.find( resource ) == mResources.end() )
83  mResources.append( resource );
84 }
85 
86 void AddresseeSelector::AddressBookManager::addAddressBook( const TQString &title,
87  SelectionItem::List &list )
88 {
89  AddressBookEntry entry;
90  entry.title = title;
91  entry.list = list;
92 
93 
94  // TODO: check for duplicates
95  mAddressBooks.append( entry );
96 }
97 
98 void AddresseeSelector::AddressBookManager::clear()
99 {
100  mResources.clear();
101  mAddressBooks.clear();
102 }
103 
104 bool AddresseeSelector::AddressBookManager::contains( uint index, const SelectionItem &item )
105 {
106  if ( index == 0 ) // the 'all' entry
107  return true;
108 
109  if ( mResources.count() > 0 ) {
110  if ( index <= mResources.count() ) {
111  index--;
112  if ( item.addressee().resource() == mResources[ index ] )
113  return true;
114  else
115  return false;
116  }
117  }
118 
119  index = index - mResources.count();
120 
121  if ( mAddressBooks.count() > 0 ) {
122  if ( index <= mAddressBooks.count() ) {
123  index--;
124  AddressBookEntry entry = mAddressBooks[ index ];
125  SelectionItem::List::ConstIterator it;
126  for ( it = entry.list.begin(); it != entry.list.end(); ++it )
127  if ( (*it).addressee() == item.addressee() )
128  return true;
129 
130  return false;
131  }
132  }
133 
134  return false;
135 }
136 
137 
138 SelectionItem::SelectionItem( const TDEABC::Addressee &addressee, uint index )
139  : mAddressee( addressee ), mDistributionList( 0 ), mIndex( index )
140 {
141  mField.fill( false, 10 );
142 }
143 
144 SelectionItem::SelectionItem( TDEABC::DistributionList *list, uint index )
145  : mDistributionList( list ), mIndex( index )
146 {
147  mField.fill( false, 10 );
148 }
149 
150 SelectionItem::SelectionItem()
151  : mDistributionList( 0 ), mIndex( 0 )
152 {
153  mField.fill( false, 10 );
154 }
155 
156 void SelectionItem::addToField( int index )
157 {
158  mField.setBit( index );
159 }
160 
161 void SelectionItem::removeFromField( int index )
162 {
163  mField.clearBit( index );
164 }
165 
166 bool SelectionItem::isInField( int index )
167 {
168  return mField.testBit( index );
169 }
170 
171 TDEABC::Addressee SelectionItem::addressee() const
172 {
173  return mAddressee;
174 }
175 
176 TDEABC::DistributionList* SelectionItem::distributionList() const
177 {
178  return mDistributionList;
179 }
180 
181 uint SelectionItem::index() const
182 {
183  return mIndex;
184 }
185 
186 
187 class SelectionViewItem : public TQListViewItem
188 {
189  public:
190  SelectionViewItem( TQListView *parent, Selection *selection,
191  SelectionItem *item )
192  : TQListViewItem( parent, "" ), mSelection( selection ), mItem( item )
193  {
194  if ( mItem->distributionList() == 0 )
195  mIcon = mSelection->itemIcon( mItem->addressee(), mItem->index() );
196  else
197  mIcon = mSelection->distributionListIcon( mItem->distributionList() );
198  }
199 
200  TQString text( int column ) const
201  {
202  if ( column == 0 ) {
203  if ( mItem->distributionList() == 0 )
204  return mSelection->itemText( mItem->addressee(), mItem->index() );
205  else
206  return mSelection->distributionListText( mItem->distributionList() );
207  } else
208  return TQString();
209  }
210 
211  const TQPixmap* pixmap( int column ) const
212  {
213  if ( column == 0 ) {
214  return &mIcon;
215  } else
216  return 0;
217  }
218 
219  SelectionItem* item() const { return mItem; }
220 
221  private:
222  Selection *mSelection;
223  SelectionItem *mItem;
224  TQPixmap mIcon;
225 };
226 
227 AddresseeSelector::AddresseeSelector( Selection *selection, TQWidget *parent, const char *name )
228  : TQWidget( parent, name ), mSelection( selection ), mManager( 0 )
229 {
230  mMoveMapper = new TQSignalMapper( this );
231  mRemoveMapper = new TQSignalMapper( this );
232 
233  mAddressBookManager = new AddressBookManager();
234 
235  initGUI();
236 
237  init();
238 
239  mSelection->setSelector( this );
240 }
241 
242 AddresseeSelector::~AddresseeSelector()
243 {
244  delete mManager;
245  mManager = 0;
246 
247  delete mAddressBookManager;
248  mAddressBookManager = 0;
249 }
250 
251 void AddresseeSelector::init()
252 {
253  connect( TDEABC::StdAddressBook::self( true ), TQ_SIGNAL( addressBookChanged( AddressBook* ) ),
254  this, TQ_SLOT( reloadAddressBook() ) );
255  connect( mAddresseeFilter, TQ_SIGNAL( textChanged( const TQString& ) ),
256  this, TQ_SLOT( updateAddresseeView() ) );
257  connect( mAddressBookCombo, TQ_SIGNAL( activated( int ) ),
258  this, TQ_SLOT( updateAddresseeView() ) );
259 
260  connect( mMoveMapper, TQ_SIGNAL( mapped( int ) ),
261  this, TQ_SLOT( move( int ) ) );
262  connect( mRemoveMapper, TQ_SIGNAL( mapped( int ) ),
263  this, TQ_SLOT( remove( int ) ) );
264 
265  reloadAddressBook();
266 }
267 
268 void AddresseeSelector::initGUI()
269 {
270  TQGridLayout *layout = new TQGridLayout( this, 2, 3, KDialog::marginHint(), KDialog::spacingHint() );
271  TQGridLayout *topLayout = new TQGridLayout( this, 2, 2, KDialog::marginHint() );
272 
273  TQLabel *label = new TQLabel( i18n( "Address book:" ), this );
274  mAddressBookCombo = new KComboBox( false, this );
275 
276  topLayout->addWidget( label, 0, 0 );
277  topLayout->addWidget( mAddressBookCombo, 0, 1 );
278 
279  label = new TQLabel( i18n( "Search:" ), this );
280  mAddresseeFilter = new KLineEdit( this );
281 
282  topLayout->addWidget( label, 1, 0 );
283  topLayout->addWidget( mAddresseeFilter, 1, 1 );
284 
285  topLayout->setColStretch( 1, 1 );
286 
287  layout->addMultiCellLayout( topLayout, 0, 0, 0, 2 );
288 
289  int row = 1;
290 
291  TQIconSet moveSet = TDEGlobal::iconLoader()->loadIconSet( "go-next", TDEIcon::Small );
292  TQIconSet removeSet = TDEGlobal::iconLoader()->loadIconSet( "go-previous", TDEIcon::Small );
293 
294  uint count = mSelection->fieldCount();
295  for ( uint i = 0; i < count; ++i, ++row ) {
296  TDEListView *listView = new TDEListView( this );
297  listView->addColumn( mSelection->fieldTitle( i ) );
298  listView->setFullWidth( true );
299  mSelectionViews.append( listView );
300 
301  connect( listView, TQ_SIGNAL( doubleClicked( TQListViewItem*, const TQPoint&, int ) ),
302  mRemoveMapper, TQ_SLOT( map() ) );
303  mRemoveMapper->setMapping( listView, i );
304 
305  TQVBoxLayout *buttonLayout = new TQVBoxLayout( this );
306  buttonLayout->setAlignment( TQt::AlignBottom );
307  layout->addLayout( buttonLayout, row, 1 );
308 
309  // move button
310  TQToolButton *moveButton = new TQToolButton( this );
311  moveButton->setIconSet( moveSet );
312  moveButton->setFixedSize( 30, 30 );
313 
314  connect( moveButton, TQ_SIGNAL( clicked() ),
315  mMoveMapper, TQ_SLOT( map() ) );
316  mMoveMapper->setMapping( moveButton, i );
317 
318  // remove button
319  TQToolButton *removeButton = new TQToolButton( this );
320  removeButton->setIconSet( removeSet );
321  removeButton->setFixedSize( 30, 30 );
322 
323  connect( removeButton, TQ_SIGNAL( clicked() ),
324  mRemoveMapper, TQ_SLOT( map() ) );
325  mRemoveMapper->setMapping( removeButton, i );
326 
327  buttonLayout->addWidget( moveButton );
328  buttonLayout->addWidget( removeButton );
329 
330  layout->addWidget( listView, row, 2 );
331  }
332 
333  mAddresseeView = new TDEListView( this );
334  mAddresseeView->addColumn( "" );
335  mAddresseeView->header()->hide();
336  mAddresseeView->setFullWidth( true );
337 
338  layout->addMultiCellWidget( mAddresseeView, 1, row, 0, 0 );
339 }
340 
341 void AddresseeSelector::finish()
342 {
343  SelectionItem::List::Iterator it;
344 
345  for ( uint field = 0; field < mSelection->fieldCount(); ++field ) {
346  for ( it = mSelectionItems.begin(); it != mSelectionItems.end(); ++it ) {
347  if ( (*it).isInField( field ) ) {
348  if ( (*it).distributionList() == 0 )
349  mSelection->addSelectedAddressees( field, (*it).addressee(), (*it).index() );
350  else
351  mSelection->addSelectedDistributionList( field, (*it).distributionList() );
352  }
353  }
354  }
355 }
356 
357 void AddresseeSelector::updateAddresseeView()
358 {
359  mAddresseeView->clear();
360 
361  int addressBookIndex = mAddressBookCombo->currentItem();
362 
363  SelectionItem::List::Iterator it;
364  for ( it = mSelectionItems.begin(); it != mSelectionItems.end(); ++it ) {
365  if ( mAddressBookManager->contains( addressBookIndex, *it ) ) {
366  if ( (*it).distributionList() == 0 ) {
367  if ( mAddresseeFilter->text().isEmpty() ||
368  mSelection->itemMatches( (*it).addressee(), (*it).index(),
369  mAddresseeFilter->text() ) )
370  new SelectionViewItem( mAddresseeView, mSelection, &(*it) );
371  } else {
372  if ( mAddresseeFilter->text().isEmpty() ||
373  mSelection->distributionListMatches( (*it).distributionList(),
374  mAddresseeFilter->text() ) )
375  new SelectionViewItem( mAddresseeView, mSelection, &(*it) );
376  }
377  }
378  }
379 
380  updateSelectionViews();
381 }
382 
383 void AddresseeSelector::move( int index )
384 {
385  SelectionViewItem *item = dynamic_cast<SelectionViewItem*>( mAddresseeView->selectedItem() );
386  if ( item ) {
387  item->item()->addToField( index );
388  updateSelectionView( index );
389  }
390 }
391 
392 void AddresseeSelector::remove( int index )
393 {
394  TDEListView *view = mSelectionViews[ index ];
395 
396  SelectionViewItem *item = dynamic_cast<SelectionViewItem*>( view->selectedItem() );
397  if ( item ) {
398  item->item()->removeFromField( index );
399  updateSelectionView( index );
400  }
401 }
402 
403 void AddresseeSelector::setItemSelected( uint fieldIndex, const TDEABC::Addressee &addr, uint itemIndex )
404 {
405  bool found = false;
406 
407  SelectionItem::List::Iterator it;
408  for ( it = mSelectionItems.begin(); it != mSelectionItems.end(); ++it ) {
409  if ( (*it).addressee() == addr && (*it).index() == itemIndex ) {
410  (*it).addToField( fieldIndex );
411  found = true;
412  }
413  }
414 
415  if ( !found ) {
416  SelectionItem item( addr, itemIndex );
417  item.addToField( fieldIndex );
418 
419  mSelectionItems.append( item );
420  }
421 
422  updateSelectionView( fieldIndex );
423 }
424 
425 void AddresseeSelector::setItemSelected( uint fieldIndex, const TDEABC::Addressee &addr,
426  uint itemIndex, const TQString &text )
427 {
428  bool found = false;
429 
430  SelectionItem::List::Iterator it;
431  for ( it = mSelectionItems.begin(); it != mSelectionItems.end(); ++it ) {
432  if ( mSelection->itemEquals( (*it).addressee(), (*it).index(), text ) ) {
433  (*it).addToField( fieldIndex );
434  found = true;
435  }
436  }
437 
438  if ( !found ) {
439  SelectionItem item( addr, itemIndex );
440  item.addToField( fieldIndex );
441 
442  mSelectionItems.append( item );
443  }
444 
445  updateSelectionView( fieldIndex );
446 }
447 
448 void AddresseeSelector::updateSelectionView( int index )
449 {
450  TDEListView *view = mSelectionViews[ index ];
451  view->clear();
452 
453  SelectionItem::List::Iterator it;
454  for ( it = mSelectionItems.begin(); it != mSelectionItems.end(); ++it ) {
455  if ( (*it).isInField( index ) )
456  new SelectionViewItem( view, mSelection, &(*it) );
457  }
458 }
459 
460 void AddresseeSelector::updateSelectionViews()
461 {
462  for ( uint i = 0; i < mSelection->fieldCount(); ++i )
463  updateSelectionView( i );
464 }
465 
466 void AddresseeSelector::reloadAddressBook()
467 {
468  // load contacts
469  TDEABC::Addressee::List list = TDEABC::StdAddressBook::self( true )->allAddressees();
470  TDEABC::Addressee::List::Iterator it;
471 
472  SelectionItem::List selectedItems;
473 
474  SelectionItem::List::Iterator itemIt;
475  for ( itemIt = mSelectionItems.begin(); itemIt != mSelectionItems.end(); ++itemIt ) {
476  bool isSelected = false;
477  for ( uint i = 0; i < mSelection->fieldCount(); ++i ) {
478  if ( (*itemIt).isInField( i ) ) {
479  isSelected = true;
480  break;
481  }
482  }
483 
484  // we don't save distribution lists, since this leads to crashes
485  if ( isSelected && (*itemIt).distributionList() == 0 ) {
486  selectedItems.append( *itemIt );
487  }
488  }
489 
490  mSelectionItems.clear();
491  mSelectionItems = selectedItems;
492 
493  for ( it = list.begin(); it != list.end(); ++it ) {
494  uint itemCount = mSelection->itemCount( *it );
495  for ( uint index = 0; index < itemCount; ++index ) {
496  bool available = false;
497  for ( itemIt = mSelectionItems.begin(); itemIt != mSelectionItems.end(); ++itemIt ) {
498  if ( (*itemIt).addressee() == (*it) && (*itemIt).index() == index ) {
499  available = true;
500  break;
501  }
502  }
503 
504  if ( !available ) {
505  SelectionItem item( *it, index );
506  mSelectionItems.append( item );
507  }
508  }
509  }
510 
511  // load distribution lists
512  delete mManager;
513  mManager = new TDEABC::DistributionListManager( TDEABC::StdAddressBook::self( true ) );
514 
515  mManager->load();
516 
517  TQStringList lists = mManager->listNames();
518 
519  TQStringList::Iterator listIt;
520  for ( listIt = lists.begin(); listIt != lists.end(); ++listIt ) {
521  TDEABC::DistributionList *list = mManager->list( *listIt );
522  SelectionItem item( list, 0 );
523  mSelectionItems.append( item );
524  }
525 
526  mAddressBookManager->clear();
527 
528  // update address book combo
529  mAddressBookCombo->clear();
530 
531  TQPtrList<TDEABC::Resource> resources = TDEABC::StdAddressBook::self( true )->resources();
532  TQPtrListIterator<TDEABC::Resource> resIt( resources );
533  while ( resIt.current() ) {
534  if ( resIt.current()->isActive() )
535  mAddressBookManager->addResource( resIt );
536 
537  ++resIt;
538  }
539 
540  for ( uint i = 0; i < mSelection->addressBookCount(); ++i ) {
541  SelectionItem::List itemList;
542 
543  TDEABC::Addressee::List addrList = mSelection->addressBookContent( i );
544  for ( it = addrList.begin(); it != addrList.end(); ++it ) {
545  uint itemCount = mSelection->itemCount( *it );
546  for ( uint index = 0; index < itemCount; ++index ) {
547  SelectionItem item( *it, index );
548  mSelectionItems.append( item );
549  itemList.append( item );
550  }
551  }
552 
553  mAddressBookManager->addAddressBook( mSelection->addressBookTitle( i ),
554  itemList );
555  }
556 
557  mAddressBookCombo->insertStringList( mAddressBookManager->titles() );
558 
559  updateAddresseeView();
560 }
561 
562 
563 AddresseeSelectorDialog::AddresseeSelectorDialog( Selection *selection,
564  TQWidget *parent, const char *name )
565  : KDialogBase( Plain, "", Ok | Cancel, Ok, parent, name, true )
566 {
567  TQFrame *frame = plainPage();
568  TQVBoxLayout *layout = new TQVBoxLayout( frame );
569  mSelector = new KPIM::AddresseeSelector( selection, frame );
570  layout->addWidget( mSelector );
571 
572  resize( 500, 490 );
573 }
574 
575 void AddresseeSelectorDialog::accept()
576 {
577  mSelector->finish();
578  TQDialog::accept();
579 }
580 
581 #include "addresseeselector.moc"
Internal helper class.
TDEPIM classes for drag and drop of mails.