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 
47 class KPIM::DistributionListEditor::EditorWidgetPrivate
48 {
49 public:
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 
67 KPIM::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, TQ_SIGNAL( textChanged( const TQString& ) ),
74  this, TQ_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, TQ_SIGNAL( clicked() ), m_lineEdit, TQ_SLOT( clear() ) );
81 }
82 
83 void 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 
91 void KPIM::DistributionListEditor::Line::setFocusToLineEdit()
92 {
93  m_lineEdit->setFocus();
94 }
95 
96 void 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 
103 TDEABC::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 
129 KPIM::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 
150 KPIM::DistributionListEditor::LineEdit::LineEdit( TQWidget* parent ) : KPIM::AddresseeLineEdit( parent )
151 {
152  allowDistributionLists( false );
153 }
154 
155 
156 KPIM::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( this );
163  connect( d->mapper, TQ_SIGNAL( mapped( int ) ),
164  this, TQ_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 
207 KPIM::DistributionListEditor::EditorWidget::~EditorWidget()
208 {
209  delete d;
210 }
211 
212 void 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 
220 void 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 
245 KPIM::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, TQ_SIGNAL( textChanged() ),
252  mapper, TQ_SLOT( map() ) );
253  mapper->setMapping( line, ++lastLineId );
254  line->setShown( true );
255  return line;
256 }
257 
258 void 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 
299 KPIM::DistributionList KPIM::DistributionListEditor::EditorWidget::distributionList() const
300 {
301  return d->distributionList;
302 }
303 
304 #include "distributionlisteditor.moc"
305 #include "distributionlisteditor_p.moc"