korganizer

koeditordetails.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
00005     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020 
00021     As a special exception, permission is given to link this program
00022     with any edition of Qt, and distribute the resulting executable,
00023     without including the source code for Qt in the source distribution.
00024 */
00025 
00026 #include "koeditordetails.h"
00027 
00028 #include <qbuttongroup.h>
00029 #include <qcheckbox.h>
00030 #include <qcombobox.h>
00031 #include <qdatetime.h>
00032 #include <qdragobject.h>
00033 #include <qfiledialog.h>
00034 #include <qgroupbox.h>
00035 #include <qlabel.h>
00036 #include <qlayout.h>
00037 #include <qlineedit.h>
00038 #include <qpushbutton.h>
00039 #include <qradiobutton.h>
00040 #include <qregexp.h>
00041 #include <qtooltip.h>
00042 #include <qvbox.h>
00043 #include <qvgroupbox.h>
00044 #include <qwhatsthis.h>
00045 #include <qwidgetstack.h>
00046 #include <qvaluevector.h>
00047 
00048 #include <kdebug.h>
00049 #include <klocale.h>
00050 #include <kiconloader.h>
00051 #include <kmessagebox.h>
00052 #ifndef KORG_NOKABC
00053 #include <kabc/addresseedialog.h>
00054 #include <kabc/vcardconverter.h>
00055 #include <libkdepim/addressesdialog.h>
00056 #include <libkdepim/addresseelineedit.h>
00057 #include <libkdepim/distributionlist.h>
00058 #include <kabc/stdaddressbook.h>
00059 #endif
00060 #include <libkdepim/kvcarddrag.h>
00061 #include <libemailfunctions/email.h>
00062 
00063 #include <libkcal/incidence.h>
00064 
00065 #include "koprefs.h"
00066 #include "koglobals.h"
00067 
00068 #include "koeditorfreebusy.h"
00069 
00070 #include "kocore.h"
00071 
00072 template <>
00073 CustomListViewItem<KCal::Attendee *>::~CustomListViewItem()
00074 {
00075   // do not delete mData here
00076 //  delete mData;
00077 }
00078 
00079 template <>
00080 void CustomListViewItem<KCal::Attendee *>::updateItem()
00081 {
00082   setText(0,mData->name());
00083   setText(1,mData->email());
00084   setText(2,mData->roleStr());
00085   setText(3,mData->statusStr());
00086   if (mData->RSVP() && !mData->email().isEmpty())
00087     setPixmap(4,KOGlobals::self()->smallIcon("mailappt"));
00088   else
00089     setPixmap(4,KOGlobals::self()->smallIcon("nomailappt"));
00090   setText(5, mData->delegate());
00091   setText(6, mData->delegator());
00092 }
00093 
00094 KOAttendeeListView::KOAttendeeListView ( QWidget *parent, const char *name )
00095   : KListView(parent, name)
00096 {
00097   setAcceptDrops( true );
00098   setAllColumnsShowFocus( true );
00099   setSorting( -1 );
00100 }
00101 
00107 KOAttendeeListView::~KOAttendeeListView()
00108 {
00109 }
00110 
00111 void KOAttendeeListView::contentsDragEnterEvent( QDragEnterEvent *e )
00112 {
00113   dragEnterEvent(e);
00114 }
00115 
00116 void KOAttendeeListView::contentsDragMoveEvent( QDragMoveEvent *e )
00117 {
00118 #ifndef KORG_NODND
00119   if ( KVCardDrag::canDecode( e ) || QTextDrag::canDecode( e ) ) {
00120     e->accept();
00121   } else {
00122     e->ignore();
00123   }
00124 #endif
00125 }
00126 
00127 void KOAttendeeListView::dragEnterEvent( QDragEnterEvent *e )
00128 {
00129 #ifndef KORG_NODND
00130   if ( KVCardDrag::canDecode( e ) || QTextDrag::canDecode( e ) ) {
00131     e->accept();
00132   } else {
00133     e->ignore();
00134   }
00135 #endif
00136 }
00137 
00138 void KOAttendeeListView::addAttendee( const QString &newAttendee )
00139 {
00140   kdDebug(5850) << " Email: " << newAttendee << endl;
00141   QString name;
00142   QString email;
00143   KPIM::getNameAndMail( newAttendee, name, email );
00144   emit dropped( new Attendee( name, email, true ) );
00145 }
00146 
00147 void KOAttendeeListView::contentsDropEvent( QDropEvent *e )
00148 {
00149   dropEvent(e);
00150 }
00151 
00152 void KOAttendeeListView::dropEvent( QDropEvent *e )
00153 {
00154 #ifndef KORG_NODND
00155   QString text;
00156   QString vcards;
00157 
00158 #ifndef KORG_NOKABC
00159   if ( KVCardDrag::decode( e, vcards ) ) {
00160     KABC::VCardConverter converter;
00161 
00162     KABC::Addressee::List list = converter.parseVCards( vcards );
00163     KABC::Addressee::List::Iterator it;
00164     for ( it = list.begin(); it != list.end(); ++it ) {
00165       QString em( (*it).fullEmail() );
00166       if (em.isEmpty()) {
00167         em=(*it).realName();
00168       }
00169       addAttendee( em );
00170     }
00171   } else
00172 #endif // KORG_NOKABC
00173   if (QTextDrag::decode(e,text)) {
00174     kdDebug(5850) << "Dropped : " << text << endl;
00175     QStringList emails = QStringList::split(",",text);
00176     for(QStringList::ConstIterator it = emails.begin();it!=emails.end();++it) {
00177       addAttendee(*it);
00178     }
00179   }
00180 #endif //KORG_NODND
00181 }
00182 
00183 
00184 KOEditorDetails::KOEditorDetails( int spacing, QWidget *parent,
00185                                   const char *name )
00186   : KOAttendeeEditor( parent, name), mDisableItemUpdate( false )
00187 {
00188   QBoxLayout *topLayout = new QVBoxLayout( this );
00189   topLayout->setSpacing( spacing );
00190 
00191   initOrganizerWidgets( this, topLayout );
00192 
00193   mListView = new KOAttendeeListView( this, "mListView" );
00194   QWhatsThis::add( mListView,
00195            i18n("Displays information about current attendees. "
00196             "To edit an attendee, select it in this list "
00197             "and modify the values in the area below. "
00198             "Clicking on a column title will sort the list "
00199             "according to that column. The RSVP column "
00200             "indicates whether or not a response is requested "
00201             "from the attendee.") );
00202   mListView->addColumn( i18n("Name"), 200 );
00203   mListView->addColumn( i18n("Email"), 200 );
00204   mListView->addColumn( i18n("Role"), 80 );
00205   mListView->addColumn( i18n("Status"), 100 );
00206   mListView->addColumn( i18n("RSVP"), 55 );
00207   mListView->addColumn( i18n("Delegated to"), 120 );
00208   mListView->addColumn( i18n("Delegated from" ), 120 );
00209   mListView->setResizeMode( QListView::LastColumn );
00210   if ( KOPrefs::instance()->mCompactDialogs ) {
00211     mListView->setFixedHeight( 78 );
00212   }
00213 
00214   connect( mListView, SIGNAL( selectionChanged( QListViewItem * ) ),
00215            SLOT( updateAttendeeInput() ) );
00216 #ifndef KORG_NODND
00217   connect( mListView, SIGNAL( dropped( Attendee * ) ),
00218            SLOT( slotInsertAttendee( Attendee * ) ) );
00219 #endif
00220   topLayout->addWidget( mListView );
00221 
00222   initEditWidgets( this, topLayout );
00223 
00224   connect( mRemoveButton, SIGNAL(clicked()), SLOT(removeAttendee()) );
00225 
00226   updateAttendeeInput();
00227 }
00228 
00229 KOEditorDetails::~KOEditorDetails()
00230 {
00231 }
00232 
00233 bool KOEditorDetails::hasAttendees()
00234 {
00235   return mListView->childCount() > 0;
00236 }
00237 
00238 void KOEditorDetails::removeAttendee()
00239 {
00240   AttendeeListItem *aItem =
00241       static_cast<AttendeeListItem *>( mListView->selectedItem() );
00242   if ( !aItem ) return;
00243 
00244   AttendeeListItem *nextSelectedItem = static_cast<AttendeeListItem*>( aItem->nextSibling() );
00245   if( mListView->childCount() == 1 )
00246       nextSelectedItem = 0;
00247   if( mListView->childCount() > 1 && aItem == mListView->lastItem() )
00248       nextSelectedItem = static_cast<AttendeeListItem*>(  mListView->firstChild() );
00249 
00250   Attendee *attendee = aItem->data();
00251   Attendee *delA = new Attendee( attendee->name(), attendee->email(),
00252                                  attendee->RSVP(), attendee->status(),
00253                                  attendee->role(), attendee->uid() );
00254   mdelAttendees.append( delA );
00255   delete aItem;
00256 
00257   if( nextSelectedItem ) {
00258       mListView->setSelected( nextSelectedItem, true );
00259   }
00260   updateAttendeeInput();
00261   emit updateAttendeeSummary( mListView->childCount() );
00262 }
00263 
00264 
00265 void KOEditorDetails::insertAttendee( Attendee *a, bool goodEmailAddress )
00266 {
00267   Q_UNUSED( goodEmailAddress );
00268 
00269   // lastItem() is O(n), but for n very small that should be fine
00270   AttendeeListItem *item = new AttendeeListItem(
00271     a, mListView, static_cast<KListViewItem*>( mListView->lastItem() ) );
00272   mListView->setSelected( item, true );
00273   emit updateAttendeeSummary( mListView->childCount() );
00274 }
00275 
00276 void KOEditorDetails::removeAttendee( Attendee *attendee )
00277 {
00278   QListViewItem *item;
00279   for ( item = mListView->firstChild(); item;  item = item->nextSibling() ) {
00280     AttendeeListItem *anItem = static_cast<AttendeeListItem *>( item );
00281     Attendee *att = anItem->data();
00282     if ( att == attendee ) {
00283       delete anItem;
00284       break;
00285     }
00286   }
00287 }
00288 
00289 void KOEditorDetails::setDefaults()
00290 {
00291   mRsvpButton->setChecked( true );
00292 }
00293 
00294 void KOEditorDetails::readEvent( Incidence *event )
00295 {
00296   mListView->clear();
00297   KOAttendeeEditor::readEvent( event );
00298 
00299   mListView->setSelected( mListView->firstChild(), true );
00300 
00301   emit updateAttendeeSummary( mListView->childCount() );
00302 }
00303 
00304 void KOEditorDetails::writeEvent(Incidence *event)
00305 {
00306   event->clearAttendees();
00307   QValueVector<QListViewItem*> toBeDeleted;
00308   QListViewItem *item;
00309   AttendeeListItem *a;
00310   for (item = mListView->firstChild(); item;
00311        item = item->nextSibling()) {
00312     a = (AttendeeListItem *)item;
00313     Attendee *attendee = a->data();
00314     Q_ASSERT( attendee );
00315     /* Check if the attendee is a distribution list and expand it */
00316     if ( attendee->email().isEmpty() ) {
00317       KPIM::DistributionList list =
00318         KPIM::DistributionList::findByName( KABC::StdAddressBook::self(), attendee->name() );
00319       if ( !list.isEmpty() ) {
00320         toBeDeleted.push_back( item ); // remove it once we are done expanding
00321         KPIM::DistributionList::Entry::List entries = list.entries( KABC::StdAddressBook::self() );
00322         KPIM::DistributionList::Entry::List::Iterator it( entries.begin() );
00323         while ( it != entries.end() ) {
00324           KPIM::DistributionList::Entry &e = ( *it );
00325           ++it;
00326           // this calls insertAttendee, which appends
00327           insertAttendeeFromAddressee( e.addressee, attendee );
00328           // TODO: duplicate check, in case it was already added manually
00329         }
00330       }
00331     } else {
00332       bool skip = false;
00333       if ( attendee->email().endsWith( "example.net" ) ) {
00334         if ( KMessageBox::warningYesNo( this, i18n("%1 does not look like a valid email address. "
00335                 "Are you sure you want to invite this participant?").arg( attendee->email() ),
00336               i18n("Invalid email address") ) != KMessageBox::Yes ) {
00337           skip = true;
00338         }
00339       }
00340       if ( !skip ) {
00341         event->addAttendee( new Attendee( *attendee ) );
00342       }
00343     }
00344   }
00345 
00346   KOAttendeeEditor::writeEvent( event );
00347 
00348   // cleanup
00349   QValueVector<QListViewItem*>::iterator it;
00350   for( it = toBeDeleted.begin(); it != toBeDeleted.end(); ++it ) {
00351     delete *it;
00352   }
00353 }
00354 
00355 bool KOEditorDetails::validateInput()
00356 {
00357   return true;
00358 }
00359 
00360 KCal::Attendee * KOEditorDetails::currentAttendee() const
00361 {
00362   QListViewItem *item = mListView->selectedItem();
00363   AttendeeListItem *aItem = static_cast<AttendeeListItem *>( item );
00364   if ( !aItem )
00365     return 0;
00366   return aItem->data();
00367 }
00368 
00369 void KOEditorDetails::updateCurrentItem()
00370 {
00371   AttendeeListItem *item = static_cast<AttendeeListItem*>( mListView->selectedItem() );
00372   if ( item )
00373     item->updateItem();
00374 }
00375 
00376 void KOEditorDetails::slotInsertAttendee( Attendee *a )
00377 {
00378   insertAttendee( a );
00379   mnewAttendees.append( a );
00380 }
00381 
00382 void KOEditorDetails::setSelected( int index )
00383 {
00384   int count = 0;
00385   for ( QListViewItemIterator it( mListView ); it.current(); ++it ) {
00386     if ( count == index ) {
00387       mListView->setSelected( *it, true );
00388       return;
00389     }
00390     count++;
00391   }
00392 }
00393 
00394 int KOEditorDetails::selectedIndex()
00395 {
00396   int index = 0;
00397   for ( QListViewItemIterator it( mListView ); it.current(); ++it ) {
00398     if ( mListView->isSelected( *it ) ) {
00399       break;
00400     }
00401     index++;
00402   }
00403   return index;
00404 }
00405 
00406 void KOEditorDetails::changeStatusForMe(Attendee::PartStat status)
00407 {
00408   const QStringList myEmails = KOPrefs::instance()->allEmails();
00409   for ( QListViewItemIterator it( mListView ); it.current(); ++it ) {
00410     AttendeeListItem *item = static_cast<AttendeeListItem*>( it.current() );
00411     for ( QStringList::ConstIterator it2( myEmails.begin() ), end( myEmails.end() ); it2 != end; ++it2 ) {
00412       if ( item->data()->email() == *it2 ) {
00413         item->data()->setStatus( status );
00414         item->updateItem();
00415       }
00416     }
00417   }
00418 }
00419 
00420 QListViewItem* KOEditorDetails::hasExampleAttendee() const
00421 {
00422   for ( QListViewItemIterator it( mListView ); it.current(); ++it ) {
00423     AttendeeListItem *item = static_cast<AttendeeListItem*>( it.current() );
00424     Attendee *attendee = item->data();
00425     Q_ASSERT( attendee );
00426     if ( isExampleAttendee( attendee ) )
00427         return item;
00428   }
00429   return 0;
00430 }
00431 
00432 #include "koeditordetails.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys