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
39using namespace KPIM;
40
41class 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
62TQStringList 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
80void AddresseeSelector::AddressBookManager::addResource( TDEABC::Resource *resource )
81{
82 if ( mResources.find( resource ) == mResources.end() )
83 mResources.append( resource );
84}
85
86void 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
98void AddresseeSelector::AddressBookManager::clear()
99{
100 mResources.clear();
101 mAddressBooks.clear();
102}
103
104bool 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
138SelectionItem::SelectionItem( const TDEABC::Addressee &addressee, uint index )
139 : mAddressee( addressee ), mDistributionList( 0 ), mIndex( index )
140{
141 mField.fill( false, 10 );
142}
143
144SelectionItem::SelectionItem( TDEABC::DistributionList *list, uint index )
145 : mDistributionList( list ), mIndex( index )
146{
147 mField.fill( false, 10 );
148}
149
150SelectionItem::SelectionItem()
151 : mDistributionList( 0 ), mIndex( 0 )
152{
153 mField.fill( false, 10 );
154}
155
156void SelectionItem::addToField( int index )
157{
158 mField.setBit( index );
159}
160
161void SelectionItem::removeFromField( int index )
162{
163 mField.clearBit( index );
164}
165
166bool SelectionItem::isInField( int index )
167{
168 return mField.testBit( index );
169}
170
171TDEABC::Addressee SelectionItem::addressee() const
172{
173 return mAddressee;
174}
175
176TDEABC::DistributionList* SelectionItem::distributionList() const
177{
178 return mDistributionList;
179}
180
181uint SelectionItem::index() const
182{
183 return mIndex;
184}
185
186
187class 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
227AddresseeSelector::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
242AddresseeSelector::~AddresseeSelector()
243{
244 delete mManager;
245 mManager = 0;
246
247 delete mAddressBookManager;
248 mAddressBookManager = 0;
249}
250
251void 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
268void 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
341void 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
357void 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
383void 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
392void 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
403void 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
425void 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
448void 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
460void AddresseeSelector::updateSelectionViews()
461{
462 for ( uint i = 0; i < mSelection->fieldCount(); ++i )
463 updateSelectionView( i );
464}
465
466void 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
563AddresseeSelectorDialog::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
575void 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.