1/*
2 This file is part of libkabc.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "distributionlistdialog.h"
22#include "distributionlist.h"
23#include "addressbook.h"
24#include "addresseedialog.h"
25
26#include <kinputdialog.h>
27#include <klocalizedstring.h>
28#include <kdebug.h>
29#include <kmessagebox.h>
30#include <kcombobox.h>
31
32#include <QtCore/QPointer>
33#include <QTreeWidget>
34#include <QLayout>
35#include <QLabel>
36#include <QPushButton>
37#include <QGroupBox>
38#include <QButtonGroup>
39#include <QRadioButton>
40
41using namespace KABC;
42
43DistributionListDialog::DistributionListDialog( AddressBook *addressBook, QWidget *parent )
44 : KDialog( parent ), d( 0 )
45{
46 setModal( true );
47 setCaption( i18n( "Configure Distribution Lists" ) );
48 setButtons( Ok );
49 setDefaultButton( Ok );
50 showButtonSeparator( true );
51
52 DistributionListEditorWidget *editor = new DistributionListEditorWidget( addressBook, this );
53 setMainWidget( editor );
54
55 connect( this, SIGNAL(okClicked()), editor, SLOT(save()) );
56}
57
58DistributionListDialog::~DistributionListDialog()
59{
60}
61
62class EmailSelector::Private
63{
64 public:
65 QButtonGroup *mButtonGroup;
66 QMap<QWidget *, QString> mEmailMap;
67};
68
69EmailSelector::EmailSelector( const QStringList &emails, const QString &current, QWidget *parent )
70 : KDialog( parent ), d( new Private )
71{
72 setCaption( i18n( "Select Email Address" ) );
73 setButtons( Ok );
74 setDefaultButton( Ok );
75
76 QFrame *topFrame = new QFrame( this );
77 setMainWidget( topFrame );
78
79 QBoxLayout *topLayout = new QVBoxLayout( topFrame );
80
81 QGroupBox *box = new QGroupBox( i18n( "Email Addresses" ) );
82 d->mButtonGroup = new QButtonGroup( box );
83 topLayout->addWidget( box );
84
85 QVBoxLayout *layout = new QVBoxLayout;
86
87 QStringList::ConstIterator it;
88 QStringList::ConstIterator end( emails.end() );
89 for ( it = emails.begin(); it != end; ++it ) {
90 QRadioButton *button = new QRadioButton( *it, box );
91 d->mButtonGroup->addButton( button );
92 d->mEmailMap.insert( button, *it );
93 layout->addWidget( button );
94 if ( ( *it ) == current ) {
95 button->setChecked( true );
96 }
97 }
98 layout->addStretch( 1 );
99 box->setLayout( layout );
100}
101
102EmailSelector::~EmailSelector()
103{
104 delete d;
105}
106
107QString EmailSelector::selected() const
108{
109 QAbstractButton *button = d->mButtonGroup->checkedButton();
110 if ( !button ) {
111 return QString();
112 }
113
114 return d->mEmailMap[button];
115}
116
117QString EmailSelector::getEmail( const QStringList &emails, const QString &current,
118 QWidget *parent )
119{
120 QString email;
121
122 QPointer<EmailSelector> dlg = new EmailSelector( emails, current, parent );
123 if ( dlg->exec() && dlg ) {
124 email = dlg->selected();
125 }
126
127 delete dlg;
128
129 return email;
130}
131
132class EntryItem : public QTreeWidgetItem
133{
134 public:
135 EntryItem( QTreeWidget *parent, const Addressee &addressee,
136 const QString &email=QString() ) :
137 QTreeWidgetItem( parent ),
138 mAddressee( addressee ),
139 mEmail( email )
140 {
141 setText( 0, addressee.realName() );
142 if ( email.isEmpty() ) {
143 setText( 1, addressee.preferredEmail() );
144 setText( 2, i18nc( "this the preferred email address", "Yes" ) );
145 } else {
146 setText( 1, email );
147 setText( 2, i18nc( "this is not the preferred email address", "No" ) );
148 }
149 }
150
151 Addressee addressee() const
152 {
153 return mAddressee;
154 }
155
156 QString email() const
157 {
158 return mEmail;
159 }
160
161 private:
162 Addressee mAddressee;
163 QString mEmail;
164};
165
166class DistributionListEditorWidget::Private
167{
168 public:
169 Private( AddressBook *addressBook, DistributionListEditorWidget *parent )
170 : mParent( parent ), mAddressBook( addressBook )
171 {
172 }
173
174 ~Private()
175 {
176 }
177
178 void newList();
179 void editList();
180 void removeList();
181 void addEntry();
182 void removeEntry();
183 void changeEmail();
184 void updateEntryView();
185 void updateAddresseeView();
186 void updateNameCombo();
187 void slotSelectionEntryViewChanged();
188 void slotSelectionAddresseeViewChanged();
189 void save();
190
191 DistributionListEditorWidget *mParent;
192 KComboBox *mNameCombo;
193 QLabel *mListLabel;
194 QTreeWidget *mEntryView;
195 QTreeWidget *mAddresseeView;
196
197 AddressBook *mAddressBook;
198 QPushButton *mNewButton, *mEditButton, *mRemoveButton;
199 QPushButton *mChangeEmailButton, *mRemoveEntryButton, *mAddEntryButton;
200};
201
202DistributionListEditorWidget::DistributionListEditorWidget( AddressBook *addressBook,
203 QWidget *parent )
204 : QWidget( parent ), d( new Private( addressBook, this ) )
205{
206 kDebug();
207
208 QBoxLayout *topLayout = new QVBoxLayout( this );
209
210 QBoxLayout *nameLayout = new QHBoxLayout();
211 topLayout->addLayout( topLayout );
212
213 d->mNameCombo = new KComboBox( this );
214 nameLayout->addWidget( d->mNameCombo );
215 connect( d->mNameCombo, SIGNAL(activated(int)), SLOT(updateEntryView()) );
216
217 d->mNewButton = new QPushButton( i18n( "New List..." ), this );
218 nameLayout->addWidget( d->mNewButton );
219 connect( d->mNewButton, SIGNAL(clicked()), SLOT(newList()) );
220
221 d->mEditButton = new QPushButton( i18n( "Rename List..." ), this );
222 nameLayout->addWidget( d->mEditButton );
223 connect( d->mEditButton, SIGNAL(clicked()), SLOT(editList()) );
224
225 d->mRemoveButton = new QPushButton( i18n( "Remove List" ), this );
226 nameLayout->addWidget( d->mRemoveButton );
227 connect( d->mRemoveButton, SIGNAL(clicked()), SLOT(removeList()) );
228
229 QGridLayout *gridLayout = new QGridLayout();
230 topLayout->addLayout( gridLayout );
231 gridLayout->setColumnStretch( 1, 1 );
232
233 QLabel *listLabel = new QLabel( i18n( "Available addresses:" ), this );
234 gridLayout->addWidget( listLabel, 0, 0 );
235
236 d->mListLabel = new QLabel( this );
237 gridLayout->addWidget( d->mListLabel, 0, 0, 1, 2 );
238
239 d->mAddresseeView = new QTreeWidget( this );
240 d->mAddresseeView->setColumnCount( 2 );
241 QStringList labels;
242 labels << i18nc( "@title:column addressee name", "Name" )
243 << i18nc( "@title:column addressee preferred email", "Preferred Email" );
244 d->mAddresseeView->setHeaderLabels( labels );
245 gridLayout->addWidget( d->mAddresseeView, 1, 0 );
246 connect( d->mAddresseeView, SIGNAL(itemSelectionChanged()),
247 SLOT(slotSelectionAddresseeViewChanged()) );
248 connect( d->mAddresseeView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
249 SLOT(addEntry()) );
250
251 d->mAddEntryButton = new QPushButton( i18n( "Add Entry" ), this );
252 d->mAddEntryButton->setEnabled( false );
253 gridLayout->addWidget( d->mAddEntryButton, 2, 0 );
254 connect( d->mAddEntryButton, SIGNAL(clicked()), SLOT(addEntry()) );
255
256 d->mEntryView = new QTreeWidget( this );
257 QStringList entryLabels;
258 entryLabels << i18nc( "@title:column addressee name", "Name" )
259 << i18nc( "@title:column addressee preferred email", "Email" )
260 << i18nc( "@title:column use preferred email", "Use Preferred" );
261 d->mEntryView->setEnabled( false );
262 gridLayout->addWidget( d->mEntryView, 1, 1, 1, 2 );
263 connect( d->mEntryView, SIGNAL(itemSelectionChanged()),
264 SLOT(slotSelectionEntryViewChanged()) );
265
266 d->mChangeEmailButton = new QPushButton( i18n( "Change Email..." ), this );
267 gridLayout->addWidget( d->mChangeEmailButton, 2, 1 );
268 connect( d->mChangeEmailButton, SIGNAL(clicked()), SLOT(changeEmail()) );
269
270 d->mRemoveEntryButton = new QPushButton( i18n( "Remove Entry" ), this );
271 gridLayout->addWidget( d->mRemoveEntryButton, 2, 2 );
272 connect( d->mRemoveEntryButton, SIGNAL(clicked()), SLOT(removeEntry()) );
273
274 d->updateAddresseeView();
275 d->updateNameCombo();
276}
277
278DistributionListEditorWidget::~DistributionListEditorWidget()
279{
280 delete d;
281}
282
283void DistributionListEditorWidget::Private::save()
284{
285 // FIXME new distribution list handling
286 // do we need extra save?
287 //mManager->save();
288}
289
290void DistributionListEditorWidget::Private::slotSelectionEntryViewChanged()
291{
292 QList<QTreeWidgetItem*> selected = mEntryView->selectedItems();
293 bool state = selected.count() > 0;
294 mChangeEmailButton->setEnabled( state );
295 mRemoveEntryButton->setEnabled( state );
296}
297
298void DistributionListEditorWidget::Private::newList()
299{
300 bool ok;
301 QString name = KInputDialog::getText( i18n( "New Distribution List" ),
302 i18n( "Please enter &name:" ), QString(), &ok );
303 if ( !ok ) {
304 return;
305 }
306
307 mAddressBook->createDistributionList( name );
308
309 mNameCombo->clear();
310 mNameCombo->addItems( mAddressBook->allDistributionListNames() );
311 mNameCombo->setCurrentIndex( mNameCombo->count() - 1 );
312
313 updateEntryView();
314 slotSelectionAddresseeViewChanged();
315}
316
317void DistributionListEditorWidget::Private::editList()
318{
319 QString oldName = mNameCombo->currentText();
320 bool ok;
321 QString name = KInputDialog::getText( i18n( "Distribution List" ),
322 i18n( "Please change &name:" ), oldName, &ok );
323 if ( !ok ) {
324 return;
325 }
326
327 DistributionList *list = mAddressBook->findDistributionListByName( oldName );
328 if ( list ) {
329 list->setName( name );
330 }
331
332 mNameCombo->clear();
333 mNameCombo->addItems( mAddressBook->allDistributionListNames() );
334 mNameCombo->setCurrentIndex( mNameCombo->count() - 1 );
335
336 updateEntryView();
337 slotSelectionAddresseeViewChanged();
338}
339
340void DistributionListEditorWidget::Private::removeList()
341{
342 int result = KMessageBox::warningContinueCancel( mParent,
343 i18n( "Delete distribution list '%1'?", mNameCombo->currentText() ),
344 QString(), KStandardGuiItem::del() );
345
346 if ( result != KMessageBox::Continue ) {
347 return;
348 }
349
350 DistributionList *list = mAddressBook->findDistributionListByName( mNameCombo->currentText() );
351 if ( list ) {
352 // FIXME new distribution list handling
353 // list should be deleted, no?
354 mAddressBook->removeDistributionList( list );
355 mNameCombo->removeItem( mNameCombo->currentIndex() );
356 }
357
358 updateEntryView();
359 slotSelectionAddresseeViewChanged();
360}
361
362void DistributionListEditorWidget::Private::addEntry()
363{
364 QList<QTreeWidgetItem*> selected = mAddresseeView->selectedItems();
365 if ( selected.count() == 0 ) {
366 kDebug() << "No addressee selected.";
367 return;
368 }
369 AddresseeItem *addresseeItem =
370 static_cast<AddresseeItem *>( selected.at( 0 ) );
371
372 DistributionList *list = mAddressBook->findDistributionListByName( mNameCombo->currentText() );
373 if ( !list ) {
374 kDebug() << "No dist list '" << mNameCombo->currentText() << "'";
375 return;
376 }
377
378 list->insertEntry( addresseeItem->addressee() );
379 updateEntryView();
380 slotSelectionAddresseeViewChanged();
381}
382
383void DistributionListEditorWidget::Private::removeEntry()
384{
385 DistributionList *list = mAddressBook->findDistributionListByName( mNameCombo->currentText() );
386 if ( !list ) {
387 return;
388 }
389
390 QList<QTreeWidgetItem*> selected = mEntryView->selectedItems();
391 if ( selected.count() == 0 ) {
392 return;
393 }
394
395 EntryItem *entryItem =
396 static_cast<EntryItem *>( selected.at( 0 ) );
397
398 list->removeEntry( entryItem->addressee(), entryItem->email() );
399 delete entryItem;
400}
401
402void DistributionListEditorWidget::Private::changeEmail()
403{
404 DistributionList *list = mAddressBook->findDistributionListByName( mNameCombo->currentText() );
405 if ( !list ) {
406 return;
407 }
408
409 QList<QTreeWidgetItem*> selected = mEntryView->selectedItems();
410 if ( selected.count() == 0 ) {
411 return;
412 }
413
414 EntryItem *entryItem =
415 static_cast<EntryItem *>( selected.at( 0 ) );
416
417 const QString email = EmailSelector::getEmail( entryItem->addressee().emails(),
418 entryItem->email(), mParent );
419 list->removeEntry( entryItem->addressee(), entryItem->email() );
420 list->insertEntry( entryItem->addressee(), email );
421
422 updateEntryView();
423}
424
425void DistributionListEditorWidget::Private::updateEntryView()
426{
427 if ( mNameCombo->currentText().isEmpty() ) {
428 mListLabel->setText( i18n( "Selected addressees:" ) );
429 } else {
430 mListLabel->setText( i18n( "Selected addresses in '%1':",
431 mNameCombo->currentText() ) );
432 }
433
434 mEntryView->clear();
435
436 DistributionList *list = mAddressBook->findDistributionListByName( mNameCombo->currentText() );
437 if ( !list ) {
438 mEditButton->setEnabled( false );
439 mRemoveButton->setEnabled( false );
440 mChangeEmailButton->setEnabled( false );
441 mRemoveEntryButton->setEnabled( false );
442 mAddresseeView->setEnabled( false );
443 mEntryView->setEnabled( false );
444 return;
445 } else {
446 mEditButton->setEnabled( true );
447 mRemoveButton->setEnabled( true );
448 mAddresseeView->setEnabled( true );
449 mEntryView->setEnabled( true );
450 }
451
452 DistributionList::Entry::List entries = list->entries();
453 DistributionList::Entry::List::ConstIterator it;
454 DistributionList::Entry::List::ConstIterator end( entries.constEnd() );
455 for ( it = entries.constBegin(); it != end; ++it ) {
456 new EntryItem( mEntryView, ( *it ).addressee(), ( *it ).email() );
457 }
458
459 QList<QTreeWidgetItem*> selected = mEntryView->selectedItems();
460 bool state = ( selected.count() != 0 );
461
462 mChangeEmailButton->setEnabled( state );
463 mRemoveEntryButton->setEnabled( state );
464}
465
466void DistributionListEditorWidget::Private::updateAddresseeView()
467{
468 mAddresseeView->clear();
469
470 AddressBook::ConstIterator it;
471 AddressBook::ConstIterator end( mAddressBook->constEnd() );
472 for ( it = mAddressBook->constBegin(); it != end; ++it ) {
473 new AddresseeItem( mAddresseeView, *it );
474 }
475}
476
477void DistributionListEditorWidget::Private::updateNameCombo()
478{
479 mNameCombo->addItems( mAddressBook->allDistributionListNames() );
480
481 updateEntryView();
482}
483
484void DistributionListEditorWidget::Private::slotSelectionAddresseeViewChanged()
485{
486 QList<QTreeWidgetItem*> selected = mAddresseeView->selectedItems();
487 bool state = ( selected.count() != 0 );
488 mAddEntryButton->setEnabled( state && !mNameCombo->currentText().isEmpty() );
489}
490
491#include "moc_distributionlistdialog.cpp"
492