00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "koattendeeeditor.h"
00022 #include "koprefs.h"
00023 #include "koglobals.h"
00024
00025 #ifndef KORG_NOKABC
00026 #include <kabc/addresseedialog.h>
00027 #include <libkdepim/addressesdialog.h>
00028 #include <libkdepim/addresseelineedit.h>
00029 #endif
00030
00031 #include <libkcal/incidence.h>
00032
00033 #include <libemailfunctions/email.h>
00034
00035 #include <kiconloader.h>
00036 #include <klocale.h>
00037 #include <kmessagebox.h>
00038
00039 #include <qcheckbox.h>
00040 #include <qcombobox.h>
00041 #include <qhbox.h>
00042 #include <qlabel.h>
00043 #include <qlayout.h>
00044 #include <qpushbutton.h>
00045 #include <qwhatsthis.h>
00046
00047 using namespace KCal;
00048
00049 KOAttendeeEditor::KOAttendeeEditor( QWidget * parent, const char *name ) :
00050 QWidget( parent, name ),
00051 mDisableItemUpdate( true )
00052 {
00053 }
00054
00055 void KOAttendeeEditor::initOrganizerWidgets(QWidget * parent, QBoxLayout * layout)
00056 {
00057 mOrganizerHBox = new QHBox( parent );
00058 layout->addWidget( mOrganizerHBox );
00059
00060
00061
00062
00063
00064 QString whatsThis = i18n("Sets the identity corresponding to "
00065 "the organizer of this to-do or event. "
00066 "Identities can be set in the 'Personal' "
00067 "section of the KOrganizer configuration, or in the "
00068 "'Security & Privacy'->'Password & User Account' "
00069 "section of the KDE Control Center. In addition, "
00070 "identities are gathered from your KMail settings "
00071 "and from your address book. If you choose "
00072 "to set it globally for KDE in the Control Center, "
00073 "be sure to check 'Use email settings from "
00074 "Control Center' in the 'Personal' section of the "
00075 "KOrganizer configuration.");
00076 mOrganizerLabel = new QLabel( i18n( "Identity as organizer:" ),
00077 mOrganizerHBox );
00078 mOrganizerCombo = new QComboBox( mOrganizerHBox );
00079 QWhatsThis::add( mOrganizerLabel, whatsThis );
00080 QWhatsThis::add( mOrganizerCombo, whatsThis );
00081 fillOrganizerCombo();
00082 mOrganizerHBox->setStretchFactor( mOrganizerCombo, 100 );
00083 }
00084
00085 void KOAttendeeEditor::initEditWidgets(QWidget * parent, QBoxLayout * layout)
00086 {
00087 QGridLayout *topLayout = new QGridLayout();
00088 layout->addLayout( topLayout );
00089
00090 QString whatsThis = i18n("Edits the name of the attendee selected in the list "
00091 "above, or adds a new attendee if there are no attendees"
00092 "in the list.");
00093 QLabel *attendeeLabel = new QLabel( parent );
00094 QWhatsThis::add( attendeeLabel, whatsThis );
00095 attendeeLabel->setText( i18n("Na&me:") );
00096 topLayout->addWidget( attendeeLabel, 0, 0 );
00097
00098 mNameEdit = new KPIM::AddresseeLineEdit( parent );
00099 QWhatsThis::add( mNameEdit, whatsThis );
00100 mNameEdit->setClickMessage( i18n("Click to add a new attendee") );
00101 attendeeLabel->setBuddy( mNameEdit );
00102 mNameEdit->installEventFilter( this );
00103 connect( mNameEdit, SIGNAL( textChanged( const QString & ) ),
00104 SLOT( updateAttendee() ) );
00105 topLayout->addMultiCellWidget( mNameEdit, 0, 0, 1, 2 );
00106
00107 whatsThis = i18n("Edits the role of the attendee selected "
00108 "in the list above.");
00109 QLabel *attendeeRoleLabel = new QLabel( parent );
00110 QWhatsThis::add( attendeeRoleLabel, whatsThis );
00111 attendeeRoleLabel->setText( i18n("Ro&le:") );
00112 topLayout->addWidget( attendeeRoleLabel, 1, 0 );
00113
00114 mRoleCombo = new QComboBox( false, parent );
00115 QWhatsThis::add( mRoleCombo, whatsThis );
00116 mRoleCombo->insertStringList( Attendee::roleList() );
00117 attendeeRoleLabel->setBuddy( mRoleCombo );
00118 connect( mRoleCombo, SIGNAL( activated( int ) ),
00119 SLOT( updateAttendee() ) );
00120 topLayout->addWidget( mRoleCombo, 1, 1 );
00121
00122 mDelegateLabel = new QLabel( parent );
00123 topLayout->addWidget( mDelegateLabel, 1, 2 );
00124
00125 whatsThis = i18n("Edits the current attendance status of the attendee "
00126 "selected in the list above.");
00127 QLabel *statusLabel = new QLabel( parent );
00128 QWhatsThis::add( statusLabel, whatsThis );
00129 statusLabel->setText( i18n("Stat&us:") );
00130 topLayout->addWidget( statusLabel, 2, 0 );
00131
00132 mStatusCombo = new QComboBox( false, parent );
00133 QWhatsThis::add( mStatusCombo, whatsThis );
00134
00135 mStatusCombo->insertItem( SmallIcon( "help" ), Attendee::statusName( Attendee::NeedsAction ) );
00136 mStatusCombo->insertItem( KOGlobals::self()->smallIcon( "ok" ), Attendee::statusName( Attendee::Accepted ) );
00137 mStatusCombo->insertItem( KOGlobals::self()->smallIcon( "no" ), Attendee::statusName( Attendee::Declined ) );
00138 mStatusCombo->insertItem( KOGlobals::self()->smallIcon( "apply" ), Attendee::statusName( Attendee::Tentative ) );
00139 mStatusCombo->insertItem( KOGlobals::self()->smallIcon( "mail_forward" ), Attendee::statusName( Attendee::Delegated ) );
00140 mStatusCombo->insertItem( Attendee::statusName( Attendee::Completed ) );
00141 mStatusCombo->insertItem( KOGlobals::self()->smallIcon( "help" ), Attendee::statusName( Attendee::InProcess ) );
00142
00143 statusLabel->setBuddy( mStatusCombo );
00144 connect( mStatusCombo, SIGNAL( activated( int ) ),
00145 SLOT( updateAttendee() ) );
00146 topLayout->addWidget( mStatusCombo, 2, 1 );
00147
00148 topLayout->setColStretch( 2, 1 );
00149
00150 mRsvpButton = new QCheckBox( parent );
00151 QWhatsThis::add( mRsvpButton,
00152 i18n("Edits whether to send an email to the attendee "
00153 "selected in the list above to request "
00154 "a response concerning attendance.") );
00155 mRsvpButton->setText( i18n("Re&quest response") );
00156 connect( mRsvpButton, SIGNAL( clicked() ), SLOT( updateAttendee() ) );
00157 topLayout->addWidget( mRsvpButton, 2, 2 );
00158
00159 QWidget *buttonBox = new QWidget( parent );
00160 QVBoxLayout *buttonLayout = new QVBoxLayout( buttonBox );
00161
00162 mAddButton = new QPushButton( i18n("&New"), buttonBox );
00163 QWhatsThis::add( mAddButton,
00164 i18n("Adds a new attendee to the list. Once the "
00165 "attendee is added, you will be able to "
00166 "edit the attendee's name, role, attendance "
00167 "status, and whether or not the attendee is required "
00168 "to respond to the invitation. To select an attendee "
00169 "from your addressbook, click the 'Select Addressee' "
00170 "button instead.") );
00171 buttonLayout->addWidget( mAddButton );
00172 connect( mAddButton, SIGNAL( clicked() ), SLOT( addNewAttendee() ) );
00173
00174 mRemoveButton = new QPushButton( i18n("&Remove"), buttonBox );
00175 QWhatsThis::add( mRemoveButton,
00176 i18n("Removes the attendee selected in "
00177 "the list above.") );
00178 buttonLayout->addWidget( mRemoveButton );
00179
00180 mAddressBookButton = new QPushButton( i18n("Select Addressee..."),
00181 buttonBox );
00182 QWhatsThis::add( mAddressBookButton,
00183 i18n("Opens your address book, allowing you to select "
00184 "new attendees from it.") );
00185 buttonLayout->addWidget( mAddressBookButton );
00186 connect( mAddressBookButton, SIGNAL( clicked() ), SLOT( openAddressBook() ) );
00187
00188 topLayout->addMultiCellWidget( buttonBox, 0, 3, 3, 3 );
00189
00190 #ifdef KORG_NOKABC
00191 mAddressBookButton->hide();
00192 #endif
00193 }
00194
00195 void KOAttendeeEditor::openAddressBook()
00196 {
00197 #ifndef KORG_NOKABC
00198 KPIM::AddressesDialog *dia = new KPIM::AddressesDialog( this, "adddialog" );
00199 dia->setShowCC( false );
00200 dia->setShowBCC( false );
00201 if ( dia->exec() ) {
00202 KABC::Addressee::List aList = dia->allToAddressesNoDuplicates();
00203 for ( KABC::Addressee::List::iterator itr = aList.begin();
00204 itr != aList.end(); ++itr ) {
00205 insertAttendeeFromAddressee( (*itr) );
00206 }
00207 }
00208 delete dia;
00209 return;
00210 #if 0
00211
00212 KABC::Addressee a = KABC::AddresseeDialog::getAddressee(this);
00213 if (!a.isEmpty()) {
00214
00215
00216 bool myself = KOPrefs::instance()->thatIsMe( a.preferredEmail() );
00217 KCal::Attendee::PartStat partStat =
00218 myself ? KCal::Attendee::Accepted : KCal::Attendee::NeedsAction;
00219 insertAttendee( new Attendee( a.realName(), a.preferredEmail(),
00220 !myself, partStat,
00221 KCal::Attendee::ReqParticipant, a.uid() ) );
00222 }
00223 #endif
00224 #endif
00225 }
00226
00227 void KOAttendeeEditor::insertAttendeeFromAddressee(const KABC::Addressee &a, const Attendee * at)
00228 {
00229 bool myself = KOPrefs::instance()->thatIsMe( a.preferredEmail() );
00230 bool sameAsOrganizer = mOrganizerCombo &&
00231 KPIM::compareEmail( a.preferredEmail(), mOrganizerCombo->currentText(), false );
00232 KCal::Attendee::PartStat partStat = at? at->status() : KCal::Attendee::NeedsAction;
00233 bool rsvp = at? at->RSVP() : true;
00234
00235 if ( myself && sameAsOrganizer ) {
00236 partStat = KCal::Attendee::Accepted;
00237 rsvp = false;
00238 }
00239 Attendee *newAt = new Attendee( a.realName(),
00240 a.preferredEmail(),
00241 !myself, partStat,
00242 at ? at->role() : Attendee::ReqParticipant,
00243 a.uid() );
00244 newAt->setRSVP( rsvp );
00245 insertAttendee( newAt, true );
00246 }
00247
00248 void KOAttendeeEditor::fillOrganizerCombo()
00249 {
00250 Q_ASSERT( mOrganizerCombo );
00251
00252
00253 const QStringList lst = KOPrefs::instance()->fullEmails();
00254 QStringList uniqueList;
00255 for( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
00256 if ( uniqueList.find( *it ) == uniqueList.end() )
00257 uniqueList << *it;
00258 }
00259 mOrganizerCombo->insertStringList( uniqueList );
00260 }
00261
00262 void KOAttendeeEditor::addNewAttendee()
00263 {
00264
00265
00266 if ( QListViewItem* item = hasExampleAttendee() ) {
00267 KMessageBox::information( this,
00268 i18n( "Please edit the example attendee, before adding more." ), QString::null,
00269 "EditExistingExampleAttendeeFirst" );
00270
00271 item->setSelected( true );
00272 item->listView()->setCurrentItem( item );
00273 return;
00274 }
00275 Attendee *a = new Attendee( i18n("Firstname Lastname"),
00276 i18n("name") + "@example.net", true );
00277 insertAttendee( a, false );
00278 mnewAttendees.append(a);
00279 updateAttendeeInput();
00280
00281 mNameEdit->setClickMessage( "" );
00282 mNameEdit->setFocus();
00283 QTimer::singleShot( 0, mNameEdit, SLOT( selectAll() ) );
00284 }
00285
00286 void KOAttendeeEditor::readEvent(KCal::Incidence * incidence)
00287 {
00288 mdelAttendees.clear();
00289 mnewAttendees.clear();
00290 if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) ) {
00291 if ( !mOrganizerCombo ) {
00292 mOrganizerCombo = new QComboBox( mOrganizerHBox );
00293 fillOrganizerCombo();
00294 }
00295 mOrganizerLabel->setText( i18n( "Identity as organizer:" ) );
00296
00297 int found = -1;
00298 QString fullOrganizer = incidence->organizer().fullName();
00299 for ( int i = 0 ; i < mOrganizerCombo->count(); ++i ) {
00300 if ( mOrganizerCombo->text( i ) == fullOrganizer ) {
00301 found = i;
00302 mOrganizerCombo->setCurrentItem( i );
00303 break;
00304 }
00305 }
00306 if ( found < 0 ) {
00307 mOrganizerCombo->insertItem( fullOrganizer, 0 );
00308 mOrganizerCombo->setCurrentItem( 0 );
00309 }
00310 } else {
00311 if ( mOrganizerCombo ) {
00312 delete mOrganizerCombo;
00313 mOrganizerCombo = 0;
00314 }
00315 mOrganizerLabel->setText( i18n( "Organizer: %1" ).arg( incidence->organizer().fullName() ) );
00316 }
00317
00318 Attendee::List al = incidence->attendees();
00319 Attendee::List::ConstIterator it;
00320 for( it = al.begin(); it != al.end(); ++it )
00321 insertAttendee( new Attendee( **it ), true );
00322 }
00323
00324 void KOAttendeeEditor::writeEvent(KCal::Incidence * incidence)
00325 {
00326 if ( mOrganizerCombo ) {
00327
00328 incidence->setOrganizer( mOrganizerCombo->currentText() );
00329 }
00330 }
00331
00332 void KOAttendeeEditor::setEnableAttendeeInput(bool enabled)
00333 {
00334
00335 mRoleCombo->setEnabled( enabled );
00336 mStatusCombo->setEnabled( enabled );
00337 mRsvpButton->setEnabled( enabled );
00338
00339 mRemoveButton->setEnabled( enabled );
00340 }
00341
00342 void KOAttendeeEditor::clearAttendeeInput()
00343 {
00344 mNameEdit->setText("");
00345 mUid = QString::null;
00346 mRoleCombo->setCurrentItem(0);
00347 mStatusCombo->setCurrentItem(0);
00348 mRsvpButton->setChecked(true);
00349 setEnableAttendeeInput( false );
00350 mDelegateLabel->setText( QString() );
00351 }
00352
00353 void KOAttendeeEditor::updateAttendee()
00354 {
00355 Attendee *a = currentAttendee();
00356 if ( !a || mDisableItemUpdate )
00357 return;
00358
00359 QString name;
00360 QString email;
00361 KPIM::getNameAndMail(mNameEdit->text(), name, email);
00362
00363 bool iAmTheOrganizer = mOrganizerCombo &&
00364 KOPrefs::instance()->thatIsMe( mOrganizerCombo->currentText() );
00365 if ( iAmTheOrganizer ) {
00366 bool myself =
00367 KPIM::compareEmail( email, mOrganizerCombo->currentText(), false );
00368 bool wasMyself =
00369 KPIM::compareEmail( a->email(), mOrganizerCombo->currentText(), false );
00370 if ( myself ) {
00371 mStatusCombo->setCurrentItem( KCal::Attendee::Accepted );
00372 mRsvpButton->setChecked( false );
00373 mRsvpButton->setEnabled( false );
00374 } else if ( wasMyself ) {
00375
00376 mStatusCombo->setCurrentItem( KCal::Attendee::NeedsAction );
00377 mRsvpButton->setChecked( true );
00378 mRsvpButton->setEnabled( true );
00379 }
00380 }
00381 a->setName( name );
00382 a->setUid( mUid );
00383 a->setEmail( email );
00384 a->setRole( Attendee::Role( mRoleCombo->currentItem() ) );
00385 a->setStatus( Attendee::PartStat( mStatusCombo->currentItem() ) );
00386 a->setRSVP( mRsvpButton->isChecked() );
00387
00388 updateCurrentItem();
00389 }
00390
00391 void KOAttendeeEditor::fillAttendeeInput( KCal::Attendee *a )
00392 {
00393 mDisableItemUpdate = true;
00394
00395 QString name = a->name();
00396 if (!a->email().isEmpty()) {
00397 name = KPIM::quoteNameIfNecessary( name );
00398 name += " <" + a->email() + ">";
00399 }
00400 mNameEdit->setText(name);
00401 mUid = a->uid();
00402 mRoleCombo->setCurrentItem(a->role());
00403 mStatusCombo->setCurrentItem(a->status());
00404 mRsvpButton->setChecked(a->RSVP());
00405
00406 mDisableItemUpdate = false;
00407 setEnableAttendeeInput( true );
00408
00409 if ( a->status() == Attendee::Delegated ) {
00410 if ( !a->delegate().isEmpty() )
00411 mDelegateLabel->setText( i18n( "Delegated to %1" ).arg( a->delegate() ) );
00412 else if ( !a->delegator().isEmpty() )
00413 mDelegateLabel->setText( i18n( "Delegated from %1" ).arg( a->delegator() ) );
00414 else
00415 mDelegateLabel->setText( i18n( "Not delegated" ) );
00416 }
00417 }
00418
00419 void KOAttendeeEditor::updateAttendeeInput()
00420 {
00421 setEnableAttendeeInput(!mNameEdit->text().isEmpty());
00422 Attendee* a = currentAttendee();
00423 if ( a ) {
00424 fillAttendeeInput( a );
00425 } else {
00426 clearAttendeeInput();
00427 }
00428 }
00429
00430 void KOAttendeeEditor::cancelAttendeeEvent( KCal::Incidence *incidence )
00431 {
00432 incidence->clearAttendees();
00433 Attendee * att;
00434 for (att=mdelAttendees.first();att;att=mdelAttendees.next()) {
00435 bool isNewAttendee = false;
00436 for (Attendee *newAtt=mnewAttendees.first();newAtt;newAtt=mnewAttendees.next()) {
00437 if (*att==*newAtt) {
00438 isNewAttendee = true;
00439 break;
00440 }
00441 }
00442 if (!isNewAttendee) {
00443 incidence->addAttendee(new Attendee(*att));
00444 }
00445 }
00446 mdelAttendees.clear();
00447 }
00448
00449 void KOAttendeeEditor::acceptForMe()
00450 {
00451 changeStatusForMe( Attendee::Accepted );
00452 }
00453
00454 void KOAttendeeEditor::declineForMe()
00455 {
00456 changeStatusForMe( Attendee::Declined );
00457 }
00458
00459 bool KOAttendeeEditor::eventFilter(QObject *watched, QEvent *ev)
00460 {
00461 if ( watched && watched == mNameEdit && ev->type() == QEvent::FocusIn &&
00462 currentAttendee() == 0 ) {
00463 addNewAttendee();
00464 }
00465
00466 return QWidget::eventFilter( watched, ev );
00467 }
00468
00469 bool KOAttendeeEditor::isExampleAttendee( const KCal::Attendee* attendee ) const
00470 {
00471 if ( !attendee ) return false;
00472 if ( attendee->name() == i18n( "Firstname Lastname" )
00473 && attendee->email().endsWith( "example.net" ) ) {
00474 return true;
00475 }
00476 return false;
00477 }
00478
00479 #include "koattendeeeditor.moc"