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