kaddressbook

distributionlisteditor.cpp
1/*
2 This file is part of KAddressBook.
3 Copyright (c) 2007 Klaralvdalens Datakonsult AB <frank@kdab.net>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program 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
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 As a special exception, permission is given to link this program
19 with any edition of TQt, and distribute the resulting executable,
20 without including the source code for TQt in the source distribution.
21*/
22
23#include "distributionlisteditor.h"
24#include "distributionlisteditor_p.h"
25
26#include <libtdepim/addresseelineedit.h>
27#include <libtdepim/distributionlist.h>
28#include <libemailfunctions/email.h>
29
30#include <tdeabc/addressbook.h>
31#include <tdeabc/resource.h>
32
33#include <tdeapplication.h>
34#include <kdialogbase.h>
35#include <tdeglobal.h>
36#include <kiconloader.h>
37#include <klineedit.h>
38#include <tdelocale.h>
39#include <tdemessagebox.h>
40
41#include <tqlabel.h>
42#include <tqlayout.h>
43#include <tqsignalmapper.h>
44#include <tqtoolbutton.h>
45#include <tqguardedptr.h>
46
47class KPIM::DistributionListEditor::EditorWidgetPrivate
48{
49public:
50 TQScrollView* scrollView;
51 TQSignalMapper* mapper;
52 TDEABC::AddressBook* addressBook;
53 TQString distListUid;
54 TQLabel* nameLabel;
55 TQLabel* memberListLabel;
56 KLineEdit* nameLineEdit;
57 TQWidget* memberListWidget;
58 TQVBoxLayout* addresseeLayout;
59 TQValueList<KPIM::DistributionListEditor::Line*> addressees;
60 TQGuardedPtr<TDEABC::Resource> resource;
61 KPIM::DistributionList distributionList;
62 KPIM::DistributionListEditor::Line* addLineForEntry( const KPIM::DistributionList::Entry& entry );
63 int lastLineId;
64};
65
66
67KPIM::DistributionListEditor::Line::Line( TDEABC::AddressBook* book, TQWidget* parent ) : TQWidget( parent ), m_addressBook( book )
68{
69 Q_ASSERT( m_addressBook );
70 TQBoxLayout* layout = new TQHBoxLayout( this );
71 layout->setSpacing( KDialog::spacingHint() );
72 m_lineEdit = new KPIM::DistributionListEditor::LineEdit( this );
73 connect( m_lineEdit, TQT_SIGNAL( textChanged( const TQString& ) ),
74 this, TQT_SLOT( textChanged( const TQString& ) ) );
75 layout->addWidget( m_lineEdit );
76 m_clearButton = new TQToolButton( this );
77 m_clearButton->setIconSet( TDEApplication::reverseLayout() ? SmallIconSet("locationbar_erase") : SmallIconSet( "clear_left" ) );
78 m_clearButton->setEnabled( false );
79 layout->addWidget( m_clearButton );
80 connect( m_clearButton, TQT_SIGNAL( clicked() ), m_lineEdit, TQT_SLOT( clear() ) );
81}
82
83void KPIM::DistributionListEditor::Line::textChanged( const TQString& text )
84{
85 m_clearButton->setEnabled( !text.isEmpty() );
86 if ( text.isEmpty() )
87 emit cleared();
88 emit textChanged();
89}
90
91void KPIM::DistributionListEditor::Line::setFocusToLineEdit()
92{
93 m_lineEdit->setFocus();
94}
95
96void KPIM::DistributionListEditor::Line::setEntry( const KPIM::DistributionList::Entry& entry )
97{
98 m_uid = entry.addressee.uid();
99 m_initialText = entry.addressee.fullEmail( entry.email );
100 m_lineEdit->setText( m_initialText );
101}
102
103TDEABC::Addressee KPIM::DistributionListEditor::Line::findAddressee( const TQString& name, const TQString& email ) const
104{
105 if ( name.isEmpty() && email.isEmpty() )
106 return TDEABC::Addressee();
107
108 typedef TDEABC::Addressee::List List;
109 const List byEmail = m_addressBook->findByEmail( email );
110 if ( !byEmail.isEmpty() )
111 {
112 const List::ConstIterator end = byEmail.end();
113 for ( List::ConstIterator it = byEmail.begin(); it != end; ++it )
114 {
115 if ( (*it).formattedName() == name )
116 return *it;
117 }
118 return byEmail.first();
119 }
120 // no entry found, create new addressee:
121 TDEABC::Addressee addressee;
122 addressee.setUid( TDEApplication::randomString( 10 ) );
123 addressee.setFormattedName( name );
124 addressee.setEmails( email );
125 m_addressBook->insertAddressee( addressee );
126 return addressee;
127}
128
129KPIM::DistributionList::Entry KPIM::DistributionListEditor::Line::entry() const
130{
131 const TQString text = m_lineEdit->text();
132 TQString name;
133 TQString email;
134 KPIM::getNameAndMail(m_lineEdit->text(), name, email );
135
136 KPIM::DistributionList::Entry res;
137 if ( !m_uid.isNull() )
138 {
139 const TDEABC::Addressee addr = m_addressBook->findByUid( m_uid );
140 if ( m_initialText == text || addr.formattedName() == name )
141 res.addressee = addr;
142 }
143 if ( res.addressee.isEmpty() )
144 res.addressee = findAddressee( name, email );
145 res.email = res.addressee.preferredEmail() != email ? email : TQString();
146 return res;
147}
148
149
150KPIM::DistributionListEditor::LineEdit::LineEdit( TQWidget* parent ) : KPIM::AddresseeLineEdit( parent )
151{
152 allowDistributionLists( false );
153}
154
155
156KPIM::DistributionListEditor::EditorWidget::EditorWidget( TDEABC::AddressBook* book, TQWidget* parent )
157 : KDialogBase( parent, /*name=*/0, /*modal=*/ true, /*caption=*/TQString(), KDialogBase::Ok|KDialogBase::Cancel ), d( new DistributionListEditor::EditorWidgetPrivate )
158{
159 d->addressBook = book;
160 Q_ASSERT( d->addressBook );
161 d->lastLineId = 0;
162 d->mapper = new TQSignalMapper( TQT_TQOBJECT(this) );
163 connect( d->mapper, TQT_SIGNAL( mapped( int ) ),
164 this, TQT_SLOT( lineTextChanged( int ) ) );
165 setCaption( i18n( "Edit Distribution List" ) );
166 TQWidget* main = new TQWidget( this );
167 TQVBoxLayout* mainLayout = new TQVBoxLayout( main );
168 mainLayout->setMargin( KDialog::marginHint() );
169 mainLayout->setSpacing( KDialog::spacingHint() );
170
171 TQHBoxLayout* nameLayout = new TQHBoxLayout;
172 nameLayout->setSpacing( KDialog::spacingHint() );
173 d->nameLabel = new TQLabel( main );
174 d->nameLabel->setText( i18n( "Name:" ) );
175 nameLayout->addWidget( d->nameLabel );
176
177 d->nameLineEdit = new KLineEdit( main );
178 nameLayout->addWidget( d->nameLineEdit );
179
180 mainLayout->addLayout( nameLayout );
181 mainLayout->addSpacing( 30 );
182
183 d->memberListLabel = new TQLabel( main );
184 d->memberListLabel->setText( i18n( "Distribution list members:" ) );
185 mainLayout->addWidget( d->memberListLabel );
186
187 d->scrollView = new TQScrollView( main );
188 d->scrollView->setFrameShape( TQFrame::NoFrame );
189 mainLayout->addWidget( d->scrollView );
190 d->memberListWidget = new TQWidget( d->scrollView->viewport() );
191 d->memberListWidget->setSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding );
192 TQVBoxLayout* memberLayout = new TQVBoxLayout( d->memberListWidget );
193 d->addresseeLayout = new TQVBoxLayout;
194 d->addresseeLayout->setSpacing( KDialog::spacingHint() );
195 memberLayout->addItem( d->addresseeLayout );
196 memberLayout->addStretch();
197 d->scrollView->addChild( d->memberListWidget );
198 d->scrollView->setResizePolicy( TQScrollView::AutoOneFit );
199
200 setMainWidget( main );
201
202 KPIM::DistributionListEditor::Line* const last = d->addLineForEntry( KPIM::DistributionList::Entry() );
203 const TQSize hint = sizeHint();
204 resize( hint.width() * 3L/2, hint.height() );
205}
206
207KPIM::DistributionListEditor::EditorWidget::~EditorWidget()
208{
209 delete d;
210}
211
212void KPIM::DistributionListEditor::EditorWidget::lineTextChanged( int id )
213{
214 if ( id != d->lastLineId )
215 return;
216 d->addLineForEntry( KPIM::DistributionList::Entry() );
217 d->scrollView->updateContents();
218}
219
220void KPIM::DistributionListEditor::EditorWidget::setDistributionList( const KPIM::DistributionList& list )
221{
222 d->distListUid = list.uid();
223 d->nameLineEdit->setText( list.name() );
224 d->resource = list.resource();
225
226 using KPIM::DistributionListEditor::Line;
227 typedef TQValueList<Line*>::ConstIterator ListIterator;
228 for ( ListIterator it = d->addressees.begin(), end = d->addressees.end(); it != end; ++it )
229 {
230 delete *it;
231 }
232 d->addressees.clear();
233
234 typedef KPIM::DistributionList::Entry Entry;
235 const Entry::List entries = list.entries( d->addressBook );
236
237 for ( Entry::List::ConstIterator it = entries.begin(), end = entries.end(); it != end; ++it )
238 {
239 d->addLineForEntry( *it );
240 }
241 KPIM::DistributionListEditor::Line* const last = d->addLineForEntry( Entry() );
242 last->setFocusToLineEdit();
243}
244
245KPIM::DistributionListEditor::Line* KPIM::DistributionListEditor::EditorWidgetPrivate::addLineForEntry( const KPIM::DistributionList::Entry& entry )
246{
247 KPIM::DistributionListEditor::Line* line = new KPIM::DistributionListEditor::Line( addressBook, memberListWidget );
248 line->setEntry( entry );
249 addresseeLayout->addWidget( line );
250 addressees.append( line );
251 TQObject::connect( line, TQT_SIGNAL( textChanged() ),
252 mapper, TQT_SLOT( map() ) );
253 mapper->setMapping( TQT_TQOBJECT(line), ++lastLineId );
254 line->setShown( true );
255 return line;
256}
257
258void KPIM::DistributionListEditor::EditorWidget::slotOk()
259{
260 const TQString name = d->nameLineEdit->text();
261 const KPIM::DistributionList existing = KPIM::DistributionList::findByName( d->addressBook, name );
262 if ( !existing.isEmpty() && existing.uid() != d->distListUid )
263 {
264 KMessageBox::error( this, i18n( "A distribution list with the name %1 already exists. Please choose another name." ).arg( name ), i18n( "Name in Use" ) );
265 return;
266 }
267
268 TDEABC::Ticket *ticket = d->resource->requestSaveTicket();
269 if ( !ticket ) {
270 kdWarning(5720) << "Unable to get save ticket!" << endl;
271 return;
272 }
273
274 KPIM::DistributionList list;
275 list.setUid( d->distListUid.isNull() ? TDEApplication::randomString( 10 ) :d->distListUid );
276 list.setName( name );
277 list.setResource( d->resource );
278 typedef TQValueList<KPIM::DistributionListEditor::Line*>::ConstIterator ListIterator;
279 for ( ListIterator it = d->addressees.begin(), end = d->addressees.end(); it != end; ++it )
280 {
281 const KPIM::DistributionList::Entry entry = (*it)->entry();
282 if ( entry.addressee.isEmpty() )
283 continue;
284 list.insertEntry( entry.addressee, entry.email );
285 }
286 d->distributionList = list;
287
288 d->addressBook->insertAddressee( d->distributionList );
289 if ( !d->resource->save( ticket ) ) {
290 kdWarning(5720) << "Unable to save dist list!" << endl;
291 }
292 d->resource->releaseSaveTicket( ticket );
293
294 if ( !KPIM::DistributionList::findByName( d->addressBook, name ).isEmpty() ) {
295 accept();
296 }
297}
298
299KPIM::DistributionList KPIM::DistributionListEditor::EditorWidget::distributionList() const
300{
301 return d->distributionList;
302}
303
304#include "distributionlisteditor.moc"
305#include "distributionlisteditor_p.moc"