korganizer

koattendeeeditor.cpp

00001 /*
00002     Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
00003     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00004     Copyright (c) 2007 Volker Krause <vkrause@kde.org>
00005 
00006         This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
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   // If creating a new event, then the user is the organizer -> show the
00059   // identity combo
00060   // readEvent will delete it and set another label text instead, if the user
00061   // isn't the organizer.
00062   // Note that the i18n text below is duplicated in readEvent
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 //   mStatusCombo->insertStringList( Attendee::statusList() );
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     // old code
00211     KABC::Addressee a = KABC::AddresseeDialog::getAddressee(this);
00212     if (!a.isEmpty()) {
00213         // If this is myself, I don't want to get a response but instead
00214         // assume I will be available
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   // Get all emails from KOPrefs (coming from various places),
00251   // and insert them - removing duplicates
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   updateAttendeeInput();
00267   // We don't want the hint again
00268   mNameEdit->setClickMessage( "" );
00269   mNameEdit->setFocus();
00270   QTimer::singleShot( 0, mNameEdit, SLOT( selectAll() ) );
00271 }
00272 
00273 void KOAttendeeEditor::readEvent(KCal::Incidence * incidence)
00274 {
00275   mdelAttendees.clear();
00276   if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) ) {
00277     if ( !mOrganizerCombo ) {
00278       mOrganizerCombo = new QComboBox( mOrganizerHBox );
00279       fillOrganizerCombo();
00280     }
00281     mOrganizerLabel->setText( i18n( "Identity as organizer:" ) );
00282 
00283     int found = -1;
00284     QString fullOrganizer = incidence->organizer().fullName();
00285     for ( int i = 0 ; i < mOrganizerCombo->count(); ++i ) {
00286       if ( mOrganizerCombo->text( i ) == fullOrganizer ) {
00287         found = i;
00288         mOrganizerCombo->setCurrentItem( i );
00289         break;
00290       }
00291     }
00292     if ( found < 0 ) {
00293       mOrganizerCombo->insertItem( fullOrganizer, 0 );
00294       mOrganizerCombo->setCurrentItem( 0 );
00295     }
00296   } else { // someone else is the organizer
00297     if ( mOrganizerCombo ) {
00298       delete mOrganizerCombo;
00299       mOrganizerCombo = 0;
00300     }
00301     mOrganizerLabel->setText( i18n( "Organizer: %1" ).arg( incidence->organizer().fullName() ) );
00302   }
00303 
00304   Attendee::List al = incidence->attendees();
00305   Attendee::List::ConstIterator it;
00306   for( it = al.begin(); it != al.end(); ++it )
00307     insertAttendee( new Attendee( **it ), true );
00308 }
00309 
00310 void KOAttendeeEditor::writeEvent(KCal::Incidence * incidence)
00311 {
00312   if ( mOrganizerCombo ) {
00313     // TODO: Don't take a string and split it up... Is there a better way?
00314     incidence->setOrganizer( mOrganizerCombo->currentText() );
00315   }
00316 }
00317 
00318 void KOAttendeeEditor::setEnableAttendeeInput(bool enabled)
00319 {
00320   //mNameEdit->setEnabled( enabled );
00321   mRoleCombo->setEnabled( enabled );
00322   mStatusCombo->setEnabled( enabled );
00323   mRsvpButton->setEnabled( enabled );
00324 
00325   mRemoveButton->setEnabled( enabled );
00326 }
00327 
00328 void KOAttendeeEditor::clearAttendeeInput()
00329 {
00330   mNameEdit->setText("");
00331   mUid = QString::null;
00332   mRoleCombo->setCurrentItem(0);
00333   mStatusCombo->setCurrentItem(0);
00334   mRsvpButton->setChecked(true);
00335   setEnableAttendeeInput( false );
00336   mDelegateLabel->setText( QString() );
00337 }
00338 
00339 void KOAttendeeEditor::updateAttendee()
00340 {
00341   Attendee *a = currentAttendee();
00342   if ( !a || mDisableItemUpdate )
00343     return;
00344 
00345   QString name;
00346   QString email;
00347   KPIM::getNameAndMail(mNameEdit->text(), name, email);
00348 
00349   bool iAmTheOrganizer = mOrganizerCombo &&
00350     KOPrefs::instance()->thatIsMe( mOrganizerCombo->currentText() );
00351   if ( iAmTheOrganizer ) {
00352     bool myself =
00353       KPIM::compareEmail( email, mOrganizerCombo->currentText(), false );
00354     bool wasMyself =
00355       KPIM::compareEmail( a->email(), mOrganizerCombo->currentText(), false );
00356     if ( myself ) {
00357       mStatusCombo->setCurrentItem( KCal::Attendee::Accepted );
00358       mRsvpButton->setChecked( false );
00359       mRsvpButton->setEnabled( false );
00360     } else if ( wasMyself ) {
00361       // this was me, but is no longer, reset
00362       mStatusCombo->setCurrentItem( KCal::Attendee::NeedsAction );
00363       mRsvpButton->setChecked( true );
00364       mRsvpButton->setEnabled( true );
00365     }
00366   }
00367   a->setName( name );
00368   a->setUid( mUid );
00369   a->setEmail( email );
00370   a->setRole( Attendee::Role( mRoleCombo->currentItem() ) );
00371   a->setStatus( Attendee::PartStat( mStatusCombo->currentItem() ) );
00372   a->setRSVP( mRsvpButton->isChecked() );
00373 
00374   updateCurrentItem();
00375 }
00376 
00377 void KOAttendeeEditor::fillAttendeeInput( KCal::Attendee *a )
00378 {
00379   mDisableItemUpdate = true;
00380 
00381   QString name = a->name();
00382   if (!a->email().isEmpty()) {
00383     name = KPIM::quoteNameIfNecessary( name );
00384     name += " <" + a->email() + ">";
00385   }
00386   mNameEdit->setText(name);
00387   mUid = a->uid();
00388   mRoleCombo->setCurrentItem(a->role());
00389   mStatusCombo->setCurrentItem(a->status());
00390   mRsvpButton->setChecked(a->RSVP());
00391 
00392   mDisableItemUpdate = false;
00393   setEnableAttendeeInput( true );
00394 
00395   if ( a->status() == Attendee::Delegated ) {
00396     if ( !a->delegate().isEmpty() )
00397       mDelegateLabel->setText( i18n( "Delegated to %1" ).arg( a->delegate() ) );
00398     else if ( !a->delegator().isEmpty() )
00399       mDelegateLabel->setText( i18n( "Delegated from %1" ).arg( a->delegator() ) );
00400     else
00401       mDelegateLabel->setText( i18n( "Not delegated" ) );
00402   }
00403 }
00404 
00405 void KOAttendeeEditor::updateAttendeeInput()
00406 {
00407   setEnableAttendeeInput(!mNameEdit->text().isEmpty());
00408   Attendee* a = currentAttendee();
00409   if ( a ) {
00410     fillAttendeeInput( a );
00411   } else {
00412     clearAttendeeInput();
00413   }
00414 }
00415 
00416 void KOAttendeeEditor::cancelAttendeeEvent( KCal::Incidence *incidence )
00417 {
00418   incidence->clearAttendees();
00419   Attendee * att;
00420   for (att=mdelAttendees.first();att;att=mdelAttendees.next()) {
00421     incidence->addAttendee(new Attendee(*att));
00422   }
00423   mdelAttendees.clear();
00424 }
00425 
00426 void KOAttendeeEditor::acceptForMe()
00427 {
00428   changeStatusForMe( Attendee::Accepted );
00429 }
00430 
00431 void KOAttendeeEditor::declineForMe()
00432 {
00433   changeStatusForMe( Attendee::Declined );
00434 }
00435 
00436 bool KOAttendeeEditor::eventFilter(QObject *watched, QEvent *ev)
00437 {
00438   if ( watched && watched == mNameEdit && ev->type() == QEvent::FocusIn &&
00439        currentAttendee() == 0 ) {
00440     addNewAttendee();
00441   }
00442 
00443   return QWidget::eventFilter( watched, ev );
00444 }
00445 
00446 #include "koattendeeeditor.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys