00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "koeditordetails.h"
00027 #include "koprefs.h"
00028 #include "koglobals.h"
00029 #include "koeditorfreebusy.h"
00030 #include "kocore.h"
00031
00032 #include <kcal/incidence.h>
00033 #include <kpimutils/email.h>
00034
00035 #ifndef KORG_NOKABC
00036 #include <kabc/addresseedialog.h>
00037 #include <kabc/stdaddressbook.h>
00038 #include <libkdepim/addressesdialog.h>
00039 #include <libkdepim/addresseelineedit.h>
00040 #include <libkdepim/distributionlist.h>
00041 #endif
00042 #include <libkdepim/kvcarddrag.h>
00043
00044 #include <KComboBox>
00045 #include <kdebug.h>
00046 #include <klocale.h>
00047 #include <kiconloader.h>
00048 #include <kmessagebox.h>
00049 #include <kvbox.h>
00050
00051 #include <QCheckBox>
00052 #include <QDateTime>
00053 #include <QLabel>
00054 #include <QLayout>
00055 #include <QLineEdit>
00056 #include <QPushButton>
00057 #include <QRadioButton>
00058 #include <QRegExp>
00059 #include <QGridLayout>
00060 #include <QDragMoveEvent>
00061 #include <QEvent>
00062 #include <QDropEvent>
00063 #include <QVBoxLayout>
00064 #include <QDragEnterEvent>
00065
00066 template <>
00067 CustomListViewItem<KCal::Attendee *>::~CustomListViewItem()
00068 {
00069 delete mData;
00070 }
00071
00072 template <>
00073 void CustomListViewItem<KCal::Attendee *>::updateItem()
00074 {
00075 setText( 0, mData->name() );
00076 setText( 1, mData->email() );
00077 setText( 2, mData->roleStr() );
00078 setText( 3, mData->statusStr() );
00079 if ( mData->RSVP() && !mData->email().isEmpty() ) {
00080 setPixmap( 4, KOGlobals::self()->smallIcon( "mail-flag" ) );
00081 } else {
00082 setPixmap( 4, KOGlobals::self()->smallIcon( "mail-queue" ) );
00083 }
00084 setText( 5, mData->delegate() );
00085 setText( 6, mData->delegator() );
00086 }
00087
00088 KOAttendeeListView::KOAttendeeListView ( QWidget *parent )
00089 : K3ListView( parent )
00090 {
00091 setAcceptDrops( true );
00092 setAllColumnsShowFocus( true );
00093 setSorting( -1 );
00094 }
00095
00100 KOAttendeeListView::~KOAttendeeListView()
00101 {
00102 }
00103
00104 void KOAttendeeListView::contentsDragEnterEvent( QDragEnterEvent *e )
00105 {
00106 dragEnterEvent(e);
00107 }
00108
00109 void KOAttendeeListView::contentsDragMoveEvent( QDragMoveEvent *e )
00110 {
00111 #ifndef KORG_NODND
00112 const QMimeData *md = e->mimeData();
00113 if ( KPIM::KVCardDrag::canDecode( md ) || md->hasText() ) {
00114 e->accept();
00115 } else {
00116 e->ignore();
00117 }
00118 #endif
00119 }
00120
00121 void KOAttendeeListView::dragEnterEvent( QDragEnterEvent *e )
00122 {
00123 #ifndef KORG_NODND
00124 const QMimeData *md = e->mimeData();
00125 if ( KPIM::KVCardDrag::canDecode( md ) || md->hasText() ) {
00126 e->accept();
00127 } else {
00128 e->ignore();
00129 }
00130 #endif
00131 }
00132
00133 void KOAttendeeListView::addAttendee( const QString &newAttendee )
00134 {
00135 kDebug() << " Email:" << newAttendee;
00136 QString name;
00137 QString email;
00138 KPIMUtils::extractEmailAddressAndName( newAttendee, email, name );
00139 emit dropped( new Attendee( name, email, true ) );
00140 }
00141
00142 void KOAttendeeListView::contentsDropEvent( QDropEvent *e )
00143 {
00144 dropEvent( e );
00145 }
00146
00147 void KOAttendeeListView::dropEvent( QDropEvent *e )
00148 {
00149 #ifndef KORG_NODND
00150 const QMimeData *md = e->mimeData();
00151
00152 #ifndef KORG_NOKABC
00153 if ( KPIM::KVCardDrag::canDecode( md ) ) {
00154 KABC::Addressee::List list;
00155 KPIM::KVCardDrag::fromMimeData( md, list );
00156
00157 KABC::Addressee::List::Iterator it;
00158 for ( it = list.begin(); it != list.end(); ++it ) {
00159 QString em( (*it).fullEmail() );
00160 if ( em.isEmpty() ) {
00161 em = (*it).realName();
00162 }
00163 addAttendee( em );
00164 }
00165 }
00166 #endif // KORG_NOKABC
00167 if ( md->hasText() ) {
00168 QString text = md->text();
00169 kDebug() << "Dropped :" << text;
00170 QStringList emails = text.split( ',', QString::SkipEmptyParts );
00171 for ( QStringList::ConstIterator it = emails.begin(); it != emails.end(); ++it ) {
00172 addAttendee( *it );
00173 }
00174 }
00175 #endif //KORG_NODND
00176 }
00177
00178 KOEditorDetails::KOEditorDetails( int spacing, QWidget *parent )
00179 : KOAttendeeEditor( parent ), mDisableItemUpdate( false )
00180 {
00181 QBoxLayout *topLayout = new QVBoxLayout( this );
00182 topLayout->setSpacing( spacing );
00183
00184 initOrganizerWidgets( this, topLayout );
00185
00186 mListView = new KOAttendeeListView( this );
00187 mListView->setObjectName( "mListView" );
00188 mListView->setWhatsThis( i18nc( "@info:whatsthis",
00189 "Displays information about current attendees. "
00190 "To edit an attendee, select it in this list "
00191 "and modify the values in the area below. "
00192 "Clicking on a column title will sort the list "
00193 "according to that column. The RSVP column "
00194 "indicates whether or not a response is "
00195 "requested from the attendee." ) );
00196 mListView->addColumn( i18nc( "@title:column attendee name", "Name" ), 200 );
00197 mListView->addColumn( i18nc( "@title:column attendee email", "Email" ), 200 );
00198 mListView->addColumn( i18nc( "@title:column attendee role", "Role" ), 80 );
00199 mListView->addColumn( i18nc( "@title:column attendee status", "Status" ), 100 );
00200 mListView->addColumn( i18nc( "@title:column attendee has RSVPed?", "RSVP" ), 55 );
00201 mListView->addColumn( i18nc( "@title:column attendee delegated to", "Delegated To" ), 120 );
00202 mListView->addColumn( i18nc( "@title:column attendee delegated from", "Delegated From" ), 120 );
00203 mListView->setResizeMode( Q3ListView::LastColumn );
00204 if ( KOPrefs::instance()->mCompactDialogs ) {
00205 mListView->setFixedHeight( 78 );
00206 }
00207
00208 connect( mListView, SIGNAL(selectionChanged(Q3ListViewItem*)),
00209 SLOT(updateAttendeeInput()) );
00210 #ifndef KORG_NODND
00211 connect( mListView, SIGNAL( dropped( Attendee * ) ),
00212 SLOT( slotInsertAttendee( Attendee * ) ) );
00213 #endif
00214 topLayout->addWidget( mListView );
00215
00216 initEditWidgets( this, topLayout );
00217
00218 connect( mRemoveButton, SIGNAL(clicked()), SLOT(removeAttendee()) );
00219
00220 updateAttendeeInput();
00221 }
00222
00223 KOEditorDetails::~KOEditorDetails()
00224 {
00225 }
00226
00227 bool KOEditorDetails::hasAttendees()
00228 {
00229 return mListView->childCount() > 0;
00230 }
00231
00232 void KOEditorDetails::removeAttendee()
00233 {
00234 AttendeeListItem *aItem = static_cast<AttendeeListItem *>( mListView->selectedItem() );
00235 if ( !aItem ) {
00236 return;
00237 }
00238
00239 Attendee *delA = new Attendee( aItem->data()->name(), aItem->data()->email(),
00240 aItem->data()->RSVP(), aItem->data()->status(),
00241 aItem->data()->role(), aItem->data()->uid() );
00242 mdelAttendees.append( delA );
00243
00244 delete aItem;
00245
00246 updateAttendeeInput();
00247 emit updateAttendeeSummary( mListView->childCount() );
00248 }
00249
00250 void KOEditorDetails::insertAttendee( Attendee *a, bool goodEmailAddress )
00251 {
00252 Q_UNUSED( goodEmailAddress );
00253
00254
00255 AttendeeListItem *item = new AttendeeListItem( a, mListView,
00256 static_cast<K3ListViewItem*>( mListView->lastItem() ) );
00257 mListView->setSelected( item, true );
00258 emit updateAttendeeSummary( mListView->childCount() );
00259 }
00260
00261 void KOEditorDetails::setDefaults()
00262 {
00263 mRsvpButton->setChecked( true );
00264 }
00265
00266 void KOEditorDetails::readIncidence( Incidence *event )
00267 {
00268 mListView->clear();
00269 KOAttendeeEditor::readIncidence( event );
00270
00271 mListView->setSelected( mListView->firstChild(), true );
00272
00273 emit updateAttendeeSummary( mListView->childCount() );
00274 }
00275
00276 void KOEditorDetails::writeIncidence( Incidence *incidence )
00277 {
00278 incidence->clearAttendees();
00279 QVector<Q3ListViewItem*> toBeDeleted;
00280 Q3ListViewItem *item;
00281 AttendeeListItem *a;
00282 for ( item = mListView->firstChild(); item; item = item->nextSibling() ) {
00283 a = (AttendeeListItem *)item;
00284 Attendee *attendee = a->data();
00285 Q_ASSERT( attendee );
00286
00287 if ( attendee->email().isEmpty() ) {
00288 KPIM::DistributionList list =
00289 KPIM::DistributionList::findByName( KABC::StdAddressBook::self(), attendee->name() );
00290 if ( !list.isEmpty() ) {
00291 toBeDeleted.push_back( item );
00292 KPIM::DistributionList::Entry::List entries = list.entries( KABC::StdAddressBook::self() );
00293 KPIM::DistributionList::Entry::List::Iterator it( entries.begin() );
00294 while ( it != entries.end() ) {
00295 KPIM::DistributionList::Entry &e = ( *it );
00296 ++it;
00297
00298 insertAttendeeFromAddressee( e.addressee, attendee );
00299
00300 }
00301 }
00302 } else {
00303 bool skip = false;
00304 if ( attendee->email().endsWith( "example.net" ) ) {
00305 if ( KMessageBox::warningYesNo(
00306 this,
00307 i18nc( "@info",
00308 "%1 does not look like a valid email address. "
00309 "Are you sure you want to invite this participant?",
00310 attendee->email() ),
00311 i18nc( "@title", "Invalid Email Address" ) ) != KMessageBox::Yes ) {
00312 skip = true;
00313 }
00314 }
00315 if ( !skip ) {
00316 incidence->addAttendee( new Attendee( *attendee ) );
00317 }
00318 }
00319 }
00320
00321 KOAttendeeEditor::writeIncidence( incidence );
00322
00323
00324 qDeleteAll( toBeDeleted );
00325 toBeDeleted.clear();
00326 }
00327
00328 bool KOEditorDetails::validateInput()
00329 {
00330 return true;
00331 }
00332
00333 KCal::Attendee *KOEditorDetails::currentAttendee() const
00334 {
00335 Q3ListViewItem *item = mListView->selectedItem();
00336 AttendeeListItem *aItem = static_cast<AttendeeListItem *>( item );
00337 if ( !aItem ) {
00338 return 0;
00339 }
00340 return aItem->data();
00341 }
00342
00343 void KOEditorDetails::updateCurrentItem()
00344 {
00345 AttendeeListItem *item = static_cast<AttendeeListItem*>( mListView->selectedItem() );
00346 if ( item ) {
00347 item->updateItem();
00348 }
00349 }
00350
00351 void KOEditorDetails::slotInsertAttendee( Attendee *a )
00352 {
00353 insertAttendee( a );
00354 }
00355
00356 void KOEditorDetails::changeStatusForMe( Attendee::PartStat status )
00357 {
00358 const QStringList myEmails = KOPrefs::instance()->allEmails();
00359 for ( Q3ListViewItemIterator it( mListView ); it.current(); ++it ) {
00360 AttendeeListItem *item = static_cast<AttendeeListItem*>( it.current() );
00361 for ( QStringList::ConstIterator it2( myEmails.begin() ), end( myEmails.end() );
00362 it2 != end; ++it2 ) {
00363 if ( item->data()->email() == *it2 ) {
00364 item->data()->setStatus( status );
00365 item->updateItem();
00366 }
00367 }
00368 }
00369 }
00370
00371 Q3ListViewItem* KOEditorDetails::hasExampleAttendee() const
00372 {
00373 for ( Q3ListViewItemIterator it( mListView ); it.current(); ++it ) {
00374 AttendeeListItem *item = static_cast<AttendeeListItem*>( it.current() );
00375 Attendee *attendee = item->data();
00376 Q_ASSERT( attendee );
00377 if ( isExampleAttendee( attendee ) )
00378 return item;
00379 }
00380 return 0;
00381 }
00382
00383 #include "koeditordetails.moc"