korganizer

koattendeeeditor.cpp
1 /*
2  Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
3  Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
4  Copyright (c) 2007 Volker Krause <vkrause@kde.org>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program 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
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20 
21 #include <config.h> // for TDEPIM_NEW_DISTRLISTS
22 
23 #include "koattendeeeditor.h"
24 #include "koprefs.h"
25 #include "koglobals.h"
26 
27 #ifndef KORG_NOKABC
28 #include <tdeabc/addresseedialog.h>
29 #include <libtdepim/addressesdialog.h>
30 #include <libtdepim/addresseelineedit.h>
31 #endif
32 
33 #include <libkcal/incidence.h>
34 
35 #include <libemailfunctions/email.h>
36 
37 #ifdef TDEPIM_NEW_DISTRLISTS
38 #include "distributionlist.h"
39 #else
40 #include <tdeabc/distributionlist.h>
41 #endif
42 #include <tdeabc/stdaddressbook.h>
43 
44 #include <kiconloader.h>
45 #include <tdelocale.h>
46 #include <tdemessagebox.h>
47 
48 #include <tqcheckbox.h>
49 #include <tqcombobox.h>
50 #include <tqhbox.h>
51 #include <tqlabel.h>
52 #include <tqlayout.h>
53 #include <tqpushbutton.h>
54 #include <tqwhatsthis.h>
55 
56 using namespace KCal;
57 
58 KOAttendeeEditor::KOAttendeeEditor( TQWidget * parent, const char *name ) :
59  TQWidget( parent, name ),
60  mDisableItemUpdate( true )
61 {
62 }
63 
64 void KOAttendeeEditor::initOrganizerWidgets(TQWidget * parent, TQBoxLayout * layout)
65 {
66  mOrganizerHBox = new TQHBox( parent );
67  layout->addWidget( mOrganizerHBox );
68  // If creating a new event, then the user is the organizer -> show the
69  // identity combo
70  // readEvent will delete it and set another label text instead, if the user
71  // isn't the organizer.
72  // Note that the i18n text below is duplicated in readEvent
73  TQString whatsThis = i18n("Sets the identity corresponding to "
74  "the organizer of this to-do or event. "
75  "Identities can be set in the 'Personal' "
76  "section of the KOrganizer configuration, or in the "
77  "'Security & Privacy'->'Password & User Account' "
78  "section of the Trinity Control Center. In addition, "
79  "identities are gathered from your KMail settings "
80  "and from your address book. If you choose "
81  "to set it globally for TDE in the Control Center, "
82  "be sure to check 'Use email settings from "
83  "Control Center' in the 'Personal' section of the "
84  "KOrganizer configuration.");
85  mOrganizerLabel = new TQLabel( i18n( "Identity as organizer:" ),
86  mOrganizerHBox );
87  mOrganizerCombo = new TQComboBox( mOrganizerHBox );
88  TQWhatsThis::add( mOrganizerLabel, whatsThis );
89  TQWhatsThis::add( mOrganizerCombo, whatsThis );
90  fillOrganizerCombo();
91  mOrganizerHBox->setStretchFactor( mOrganizerCombo, 100 );
92 }
93 
94 void KOAttendeeEditor::initEditWidgets(TQWidget * parent, TQBoxLayout * layout)
95 {
96  TQGridLayout *topLayout = new TQGridLayout();
97  layout->addLayout( topLayout );
98 
99  TQString whatsThis = i18n("Edits the name of the attendee selected in the list "
100  "above, or adds a new attendee if there are no attendees"
101  "in the list.");
102  TQLabel *attendeeLabel = new TQLabel( parent );
103  TQWhatsThis::add( attendeeLabel, whatsThis );
104  attendeeLabel->setText( i18n("Na&me:") );
105  topLayout->addWidget( attendeeLabel, 0, 0 );
106 
107  mNameEdit = new KPIM::AddresseeLineEdit( parent );
108  TQWhatsThis::add( mNameEdit, whatsThis );
109  mNameEdit->setClickMessage( i18n("Click to add a new attendee") );
110  attendeeLabel->setBuddy( mNameEdit );
111  mNameEdit->installEventFilter( this );
112  connect( mNameEdit, TQ_SIGNAL( textChanged( const TQString & ) ),
113  TQ_SLOT( updateAttendee() ) );
114  connect( mNameEdit, TQ_SIGNAL(returnPressed()), TQ_SLOT(expandAttendee()) );
115  topLayout->addMultiCellWidget( mNameEdit, 0, 0, 1, 2 );
116 
117  whatsThis = i18n("Edits the role of the attendee selected "
118  "in the list above.");
119  TQLabel *attendeeRoleLabel = new TQLabel( parent );
120  TQWhatsThis::add( attendeeRoleLabel, whatsThis );
121  attendeeRoleLabel->setText( i18n("Ro&le:") );
122  topLayout->addWidget( attendeeRoleLabel, 1, 0 );
123 
124  mRoleCombo = new TQComboBox( false, parent );
125  TQWhatsThis::add( mRoleCombo, whatsThis );
126  mRoleCombo->insertStringList( Attendee::roleList() );
127  attendeeRoleLabel->setBuddy( mRoleCombo );
128  connect( mRoleCombo, TQ_SIGNAL( activated( int ) ),
129  TQ_SLOT( updateAttendee() ) );
130  topLayout->addWidget( mRoleCombo, 1, 1 );
131 
132  mDelegateLabel = new TQLabel( parent );
133  topLayout->addWidget( mDelegateLabel, 1, 2 );
134 
135  whatsThis = i18n("Edits the current attendance status of the attendee "
136  "selected in the list above.");
137  TQLabel *statusLabel = new TQLabel( parent );
138  TQWhatsThis::add( statusLabel, whatsThis );
139  statusLabel->setText( i18n("Stat&us:") );
140  topLayout->addWidget( statusLabel, 2, 0 );
141 
142  mStatusCombo = new TQComboBox( false, parent );
143  TQWhatsThis::add( mStatusCombo, whatsThis );
144 // mStatusCombo->insertStringList( Attendee::statusList() );
145  mStatusCombo->insertItem( SmallIcon( "help" ), Attendee::statusName( Attendee::NeedsAction ) );
146  mStatusCombo->insertItem( KOGlobals::self()->smallIcon( "ok" ), Attendee::statusName( Attendee::Accepted ) );
147  mStatusCombo->insertItem( KOGlobals::self()->smallIcon( "no" ), Attendee::statusName( Attendee::Declined ) );
148  mStatusCombo->insertItem( KOGlobals::self()->smallIcon( "apply" ), Attendee::statusName( Attendee::Tentative ) );
149  mStatusCombo->insertItem( KOGlobals::self()->smallIcon( "mail-forward" ), Attendee::statusName( Attendee::Delegated ) );
150  mStatusCombo->insertItem( Attendee::statusName( Attendee::Completed ) );
151  mStatusCombo->insertItem( KOGlobals::self()->smallIcon( "help" ), Attendee::statusName( Attendee::InProcess ) );
152 
153  statusLabel->setBuddy( mStatusCombo );
154  connect( mStatusCombo, TQ_SIGNAL( activated( int ) ),
155  TQ_SLOT( updateAttendee() ) );
156  topLayout->addWidget( mStatusCombo, 2, 1 );
157 
158  topLayout->setColStretch( 2, 1 );
159 
160  mRsvpButton = new TQCheckBox( parent );
161  TQWhatsThis::add( mRsvpButton,
162  i18n("Edits whether to send an email to the attendee "
163  "selected in the list above to request "
164  "a response concerning attendance.") );
165  mRsvpButton->setText( i18n("Re&quest response") );
166  connect( mRsvpButton, TQ_SIGNAL( clicked() ), TQ_SLOT( updateAttendee() ) );
167  topLayout->addWidget( mRsvpButton, 2, 2 );
168 
169  TQWidget *buttonBox = new TQWidget( parent );
170  TQVBoxLayout *buttonLayout = new TQVBoxLayout( buttonBox );
171 
172  mAddButton = new TQPushButton( i18n("&New"), buttonBox );
173  TQWhatsThis::add( mAddButton,
174  i18n("Adds a new attendee to the list. Once the "
175  "attendee is added, you will be able to "
176  "edit the attendee's name, role, attendance "
177  "status, and whether or not the attendee is required "
178  "to respond to the invitation. To select an attendee "
179  "from your addressbook, click the 'Select Addressee' "
180  "button instead.") );
181  buttonLayout->addWidget( mAddButton );
182  connect( mAddButton, TQ_SIGNAL( clicked() ), TQ_SLOT( addNewAttendee() ) );
183 
184  mRemoveButton = new TQPushButton( i18n("&Remove"), buttonBox );
185  TQWhatsThis::add( mRemoveButton,
186  i18n("Removes the attendee selected in "
187  "the list above.") );
188  buttonLayout->addWidget( mRemoveButton );
189 
190  mAddressBookButton = new TQPushButton( i18n("Select Addressee..."),
191  buttonBox );
192  TQWhatsThis::add( mAddressBookButton,
193  i18n("Opens your address book, allowing you to select "
194  "new attendees from it.") );
195  buttonLayout->addWidget( mAddressBookButton );
196  connect( mAddressBookButton, TQ_SIGNAL( clicked() ), TQ_SLOT( openAddressBook() ) );
197 
198  topLayout->addMultiCellWidget( buttonBox, 0, 3, 3, 3 );
199 
200 #ifdef KORG_NOKABC
201  mAddressBookButton->hide();
202 #endif
203 }
204 
205 void KOAttendeeEditor::openAddressBook()
206 {
207 #ifndef KORG_NOKABC
208  KPIM::AddressesDialog *dia = new KPIM::AddressesDialog( this, "adddialog" );
209  dia->setShowCC( false );
210  dia->setShowBCC( false );
211  if ( dia->exec() ) {
212  TDEABC::Addressee::List aList = dia->allToAddressesNoDuplicates();
213  for ( TDEABC::Addressee::List::iterator itr = aList.begin();
214  itr != aList.end(); ++itr ) {
215  insertAttendeeFromAddressee( (*itr) );
216  }
217  }
218  delete dia;
219  return;
220 #endif
221 }
222 
223 void KOAttendeeEditor::insertAttendeeFromAddressee(const TDEABC::Addressee &a, const Attendee * at)
224 {
225  bool myself = KOPrefs::instance()->thatIsMe( a.preferredEmail() );
226  bool sameAsOrganizer = mOrganizerCombo &&
227  KPIM::compareEmail( a.preferredEmail(), mOrganizerCombo->currentText(), false );
228  KCal::Attendee::PartStat partStat = at? at->status() : KCal::Attendee::NeedsAction;
229  bool rsvp = at? at->RSVP() : true;
230 
231  if ( myself && sameAsOrganizer ) {
232  partStat = KCal::Attendee::Accepted;
233  rsvp = false;
234  }
235  Attendee *newAt = new Attendee( a.realName(),
236  a.preferredEmail(),
237  !myself, partStat,
238  at ? at->role() : Attendee::ReqParticipant,
239  a.uid() );
240  newAt->setRSVP( rsvp );
241  insertAttendee( newAt, true );
242  mnewAttendees.append( newAt );
243 }
244 
245 void KOAttendeeEditor::fillOrganizerCombo()
246 {
247  Q_ASSERT( mOrganizerCombo );
248  // Get all emails from KOPrefs (coming from various places),
249  // and insert them - removing duplicates
250  const TQStringList lst = KOPrefs::instance()->fullEmails();
251  TQStringList uniqueList;
252  for( TQStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
253  if ( uniqueList.find( *it ) == uniqueList.end() )
254  uniqueList << *it;
255  }
256  mOrganizerCombo->insertStringList( uniqueList );
257 }
258 
259 void KOAttendeeEditor::addNewAttendee()
260 {
261  // check if there's still an unchanged example entry, and if so
262  // suggest to edit that first
263  if ( TQListViewItem* item = hasExampleAttendee() ) {
264  KMessageBox::information( this,
265  i18n( "Please edit the example attendee, before adding more." ), TQString(),
266  "EditExistingExampleAttendeeFirst" );
267  // make sure the example attendee is selected
268  item->setSelected( true );
269  item->listView()->setCurrentItem( item );
270  return;
271  }
272  Attendee *a = new Attendee( i18n("Firstname Lastname"),
273  i18n("name") + "@example.net", true );
274  insertAttendee( a, false );
275  mnewAttendees.append( a );
276  updateAttendeeInput();
277  // We don't want the hint again
278  mNameEdit->setClickMessage( "" );
279  mNameEdit->setFocus();
280  TQTimer::singleShot( 0, mNameEdit, TQ_SLOT( selectAll() ) );
281 }
282 
283 void KOAttendeeEditor::readEvent(KCal::Incidence * incidence)
284 {
285  mdelAttendees.clear();
286  mnewAttendees.clear();
287  if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) || incidence->organizer().isEmpty() ) {
288  if ( !mOrganizerCombo ) {
289  mOrganizerCombo = new TQComboBox( mOrganizerHBox );
290  fillOrganizerCombo();
291  }
292  mOrganizerLabel->setText( i18n( "Identity as organizer:" ) );
293 
294  int found = -1;
295  TQString fullOrganizer = incidence->organizer().fullName();
296  for ( int i = 0 ; i < mOrganizerCombo->count(); ++i ) {
297  if ( mOrganizerCombo->text( i ) == fullOrganizer ) {
298  found = i;
299  mOrganizerCombo->setCurrentItem( i );
300  break;
301  }
302  }
303  if ( found < 0 ) {
304  mOrganizerCombo->insertItem( fullOrganizer, 0 );
305  mOrganizerCombo->setCurrentItem( 0 );
306  }
307  } else { // someone else is the organizer
308  if ( mOrganizerCombo ) {
309  delete mOrganizerCombo;
310  mOrganizerCombo = 0;
311  }
312  mOrganizerLabel->setText( i18n( "Organizer: %1" ).arg( incidence->organizer().fullName() ) );
313  }
314 
315  Attendee::List al = incidence->attendees();
316  Attendee::List::ConstIterator it;
317  Attendee *first = 0;
318  for( it = al.begin(); it != al.end(); ++it ) {
319  Attendee *a = new Attendee( **it );
320  if ( !first ) {
321  first = a;
322  }
323  insertAttendee( a, true );
324  }
325 
326  // Set the initial editing values to the first attendee in the list.
327  if ( first ) {
328  // Don't update the item here, the user didn't edit it, so it's not needed.
329  // Also, AttendeeEditor's subclasses didn't set the current Item at this point
330  // so if updateAttendee is called now what will happen is that a random item
331  // will get the text of "first".
332  mDisableItemUpdate = true;
333 
334  setSelected( 0 );
335  mNameEdit->setText( first->fullName() );
336  mUid = first->uid();
337  mRoleCombo->setCurrentItem( first->role() );
338  if ( first->status() != KCal::Attendee::None ) {
339  mStatusCombo->setCurrentItem( first->status() );
340  } else {
341  mStatusCombo->setCurrentItem( KCal::Attendee::NeedsAction );
342  }
343  mRsvpButton->setChecked( first->RSVP() );
344  mRsvpButton->setEnabled( true );
345  mDisableItemUpdate = false;
346  }
347 }
348 
349 void KOAttendeeEditor::writeEvent(KCal::Incidence * incidence)
350 {
351  if ( mOrganizerCombo ) {
352  // TODO: Don't take a string and split it up... Is there a better way?
353  incidence->setOrganizer( mOrganizerCombo->currentText() );
354  }
355 }
356 
357 void KOAttendeeEditor::setEnableAttendeeInput(bool enabled)
358 {
359  //mNameEdit->setEnabled( enabled );
360  mRoleCombo->setEnabled( enabled );
361  mStatusCombo->setEnabled( enabled );
362  mRsvpButton->setEnabled( enabled );
363 
364  mRemoveButton->setEnabled( enabled );
365 }
366 
367 void KOAttendeeEditor::clearAttendeeInput()
368 {
369  mNameEdit->setText("");
370  mUid = TQString();
371  mRoleCombo->setCurrentItem(0);
372  mStatusCombo->setCurrentItem(0);
373  mRsvpButton->setChecked(true);
374  setEnableAttendeeInput( false );
375  mDelegateLabel->setText( TQString() );
376 }
377 
378 void KOAttendeeEditor::expandAttendee()
379 {
380  TDEABC::Addressee::List aList = expandDistList( mNameEdit->text() );
381  if ( !aList.isEmpty() ) {
382  int index = selectedIndex();
383  for ( TDEABC::Addressee::List::iterator itr = aList.begin(); itr != aList.end(); ++itr ) {
384  insertAttendeeFromAddressee( (*itr) );
385  }
386  setSelected( index );
387  removeAttendee( currentAttendee() );
388  }
389 }
390 
391 void KOAttendeeEditor::updateAttendee()
392 {
393  Attendee *a = currentAttendee();
394  if ( !a || mDisableItemUpdate )
395  return;
396 
397  TQString text = mNameEdit->text();
398  if ( !mNameEdit->text().startsWith( "\"" ) ) {
399  // Quote the text as it might contain commas and other quotable chars.
400  text = KPIM::quoteNameIfNecessary( text );
401  }
402 
403  TQString name, email;
404  if ( KPIM::getNameAndMail( text, name, email ) ) {
405  name.remove( '"' );
406  email.remove( '"' ).remove( '>' );
407  } else {
408  name = TQString();
409  email = mNameEdit->text();
410  }
411 
412  bool iAmTheOrganizer = mOrganizerCombo &&
413  KOPrefs::instance()->thatIsMe( mOrganizerCombo->currentText() );
414  if ( iAmTheOrganizer ) {
415  bool myself =
416  KPIM::compareEmail( email, mOrganizerCombo->currentText(), false );
417  bool wasMyself =
418  KPIM::compareEmail( a->email(), mOrganizerCombo->currentText(), false );
419  if ( myself ) {
420  mRsvpButton->setChecked( false );
421  mRsvpButton->setEnabled( false );
422  } else if ( wasMyself ) {
423  // this was me, but is no longer, reset
424  mStatusCombo->setCurrentItem( KCal::Attendee::NeedsAction );
425  mRsvpButton->setChecked( true );
426  mRsvpButton->setEnabled( true );
427  }
428  }
429  a->setName( name );
430  a->setUid( mUid );
431  a->setEmail( email );
432  a->setRole( Attendee::Role( mRoleCombo->currentItem() ) );
433  a->setStatus( Attendee::PartStat( mStatusCombo->currentItem() ) );
434  a->setRSVP( mRsvpButton->isChecked() );
435 
436  updateCurrentItem();
437 }
438 
439 void KOAttendeeEditor::fillAttendeeInput( KCal::Attendee *a )
440 {
441  mDisableItemUpdate = true;
442 
443  TQString tname, temail;
444  TQString username = a->name();
445  if ( !a->email().isEmpty() ) {
446  username = KPIM::quoteNameIfNecessary( username );
447 
448  KPIM::getNameAndMail( username, tname, temail ); // ignore return value
449  // which is always false
450  tname += " <" + a->email() + '>';
451  }
452 
453  bool myself = KOPrefs::instance()->thatIsMe( a->email() );
454  bool sameAsOrganizer = mOrganizerCombo &&
455  KPIM::compareEmail( a->email(),
456  mOrganizerCombo->currentText(), false );
457  KCal::Attendee::PartStat partStat = a->status();
458  bool rsvp = a->RSVP();
459 
460  if ( myself && sameAsOrganizer && a->status() == KCal::Attendee::None ) {
461  partStat = KCal::Attendee::Accepted;
462  rsvp = false;
463  }
464 
465  mNameEdit->setText(tname);
466  mUid = a->uid();
467  mRoleCombo->setCurrentItem(a->role());
468  if ( partStat != KCal::Attendee::None ) {
469  mStatusCombo->setCurrentItem( partStat );
470  } else {
471  mStatusCombo->setCurrentItem( KCal::Attendee::NeedsAction );
472  }
473  mRsvpButton->setChecked( rsvp );
474 
475  mDisableItemUpdate = false;
476  setEnableAttendeeInput( true );
477 
478  if ( a->status() == Attendee::Delegated ) {
479  if ( !a->delegate().isEmpty() )
480  mDelegateLabel->setText( i18n( "Delegated to %1" ).arg( a->delegate() ) );
481  else if ( !a->delegator().isEmpty() )
482  mDelegateLabel->setText( i18n( "Delegated from %1" ).arg( a->delegator() ) );
483  else
484  mDelegateLabel->setText( i18n( "Not delegated" ) );
485  }
486  if( myself )
487  mRsvpButton->setEnabled( false );
488 
489 }
490 
491 void KOAttendeeEditor::updateAttendeeInput()
492 {
493  setEnableAttendeeInput(!mNameEdit->text().isEmpty());
494  Attendee* a = currentAttendee();
495  if ( a ) {
496  fillAttendeeInput( a );
497  } else {
498  clearAttendeeInput();
499  }
500 }
501 
503 {
504  incidence->clearAttendees();
505 
506  if ( mdelAttendees.isEmpty() ) {
507  return;
508  }
509 
510  Attendee *att;
511  for ( att = mdelAttendees.first(); att; att = mdelAttendees.next() ) {
512  bool isNewAttendee = false;
513  if ( !mnewAttendees.isEmpty() ) {
514  for ( Attendee *newAtt = mnewAttendees.first(); newAtt; newAtt = mnewAttendees.next() ) {
515  if ( *att == *newAtt ) {
516  isNewAttendee = true;
517  break;
518  }
519  }
520  }
521  if ( !isNewAttendee ) {
522  incidence->addAttendee( new Attendee( *att ) );
523  }
524  }
525  mdelAttendees.clear();
526 }
527 
528 void KOAttendeeEditor::acceptForMe()
529 {
530  changeStatusForMe( Attendee::Accepted );
531 }
532 
533 void KOAttendeeEditor::declineForMe()
534 {
535  changeStatusForMe( Attendee::Declined );
536 }
537 
538 bool KOAttendeeEditor::eventFilter(TQObject *watched, TQEvent *ev)
539 {
540  if ( watched && watched == mNameEdit && ev->type() == TQEvent::FocusIn &&
541  currentAttendee() == 0 ) {
542  addNewAttendee();
543  }
544 
545  return TQWidget::eventFilter( watched, ev );
546 }
547 
548 bool KOAttendeeEditor::isExampleAttendee( const KCal::Attendee* attendee ) const
549 {
550  if ( !attendee ) return false;
551  if ( attendee->name() == i18n( "Firstname Lastname" )
552  && attendee->email().endsWith( "example.net" ) ) {
553  return true;
554  }
555  return false;
556 }
557 
558 TDEABC::Addressee::List KOAttendeeEditor::expandDistList( const TQString &text ) const
559 {
560  TDEABC::Addressee::List aList;
561  TDEABC::AddressBook *abook = TDEABC::StdAddressBook::self( true );
562 
563 #ifdef TDEPIM_NEW_DISTRLISTS
564  const TQValueList<KPIM::DistributionList::Entry> eList =
565  KPIM::DistributionList::findByName( abook, text ).entries( abook );
566  TQValueList<KPIM::DistributionList::Entry>::ConstIterator eit;
567  for ( eit = eList.begin(); eit != eList.end(); ++eit ) {
568  TDEABC::Addressee a = (*eit).addressee;
569  if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) {
570  aList.append( a ) ;
571  }
572  }
573 
574 #else
575  TDEABC::DistributionListManager manager( abook );
576  manager.load();
577  const TQStringList dList = manager.listNames();
578  for ( TQStringList::ConstIterator it = dList.begin(); it != dList.end(); ++it ) {
579  if ( (*it) == text ) {
580  const TQValueList<TDEABC::DistributionList::Entry> eList = manager.list( *it )->entries();
581  TQValueList<TDEABC::DistributionList::Entry>::ConstIterator eit;
582  for ( eit = eList.begin(); eit != eList.end(); ++eit ) {
583  TDEABC::Addressee a = (*eit).addressee;
584  if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) {
585  aList.append( a ) ;
586  }
587  }
588  }
589  }
590 #endif
591  return aList;
592 }
593 
594 
595 #include "koattendeeeditor.moc"
void setRole(Role)
void setRSVP(bool r)
TQString uid() const
void setUid(const TQString &)
TQString delegate() const
Role role() const
TQString delegator() const
void setStatus(PartStat s)
bool RSVP() const
PartStat status() const
void setOrganizer(const Person &o)
const Attendee::List & attendees() const
void addAttendee(Attendee *attendee, bool doUpdate=true)
void insertAttendeeFromAddressee(const TDEABC::Addressee &a, const KCal::Attendee *at=0)
Reads values from a TDEABC::Addressee and inserts a new Attendee item into the listview with those it...
void cancelAttendeeEvent(KCal::Incidence *incidence)
return a clone of the event with attendees to be canceld