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   delete mData;
00076 }
00077 
00078 template <>
00079 void CustomListViewItem<KCal::Attendee *>::updateItem()
00080 {
00081   setText(0,mData->name());
00082   setText(1,mData->email());
00083   setText(2,mData->roleStr());
00084   setText(3,mData->statusStr());
00085   if (mData->RSVP() && !mData->email().isEmpty())
00086     setPixmap(4,KOGlobals::self()->smallIcon("mailappt"));
00087   else
00088     setPixmap(4,KOGlobals::self()->smallIcon("nomailappt"));
00089   setText(5, mData->delegate());
00090   setText(6, mData->delegator());
00091 }
00092 
00093 KOAttendeeListView::KOAttendeeListView ( QWidget *parent, const char *name )
00094   : KListView(parent, name)
00095 {
00096   setAcceptDrops( true );
00097   setAllColumnsShowFocus( true );
00098   setSorting( -1 );
00099 }
00100 
00106 KOAttendeeListView::~KOAttendeeListView()
00107 {
00108 }
00109 
00110 void KOAttendeeListView::contentsDragEnterEvent( QDragEnterEvent *e )
00111 {
00112   dragEnterEvent(e);
00113 }
00114 
00115 void KOAttendeeListView::contentsDragMoveEvent( QDragMoveEvent *e )
00116 {
00117 #ifndef KORG_NODND
00118   if ( KVCardDrag::canDecode( e ) || QTextDrag::canDecode( e ) ) {
00119     e->accept();
00120   } else {
00121     e->ignore();
00122   }
00123 #endif
00124 }
00125 
00126 void KOAttendeeListView::dragEnterEvent( QDragEnterEvent *e )
00127 {
00128 #ifndef KORG_NODND
00129   if ( KVCardDrag::canDecode( e ) || QTextDrag::canDecode( e ) ) {
00130     e->accept();
00131   } else {
00132     e->ignore();
00133   }
00134 #endif
00135 }
00136 
00137 void KOAttendeeListView::addAttendee( const QString &newAttendee )
00138 {
00139   kdDebug(5850) << " Email: " << newAttendee << endl;
00140   QString name;
00141   QString email;
00142   KPIM::getNameAndMail( newAttendee, name, email );
00143   emit dropped( new Attendee( name, email, true ) );
00144 }
00145 
00146 void KOAttendeeListView::contentsDropEvent( QDropEvent *e )
00147 {
00148   dropEvent(e);
00149 }
00150 
00151 void KOAttendeeListView::dropEvent( QDropEvent *e )
00152 {
00153 #ifndef KORG_NODND
00154   QString text;
00155   QString vcards;
00156 
00157 #ifndef KORG_NOKABC
00158   if ( KVCardDrag::decode( e, vcards ) ) {
00159     KABC::VCardConverter converter;
00160 
00161     KABC::Addressee::List list = converter.parseVCards( vcards );
00162     KABC::Addressee::List::Iterator it;
00163     for ( it = list.begin(); it != list.end(); ++it ) {
00164       QString em( (*it).fullEmail() );
00165       if (em.isEmpty()) {
00166         em=(*it).realName();
00167       }
00168       addAttendee( em );
00169     }
00170   } else
00171 #endif // KORG_NOKABC
00172   if (QTextDrag::decode(e,text)) {
00173     kdDebug(5850) << "Dropped : " << text << endl;
00174     QStringList emails = QStringList::split(",",text);
00175     for(QStringList::ConstIterator it = emails.begin();it!=emails.end();++it) {
00176       addAttendee(*it);
00177     }
00178   }
00179 #endif //KORG_NODND
00180 }
00181 
00182 
00183 KOEditorDetails::KOEditorDetails( int spacing, QWidget *parent,
00184                                   const char *name )
00185   : KOAttendeeEditor( parent, name), mDisableItemUpdate( false )
00186 {
00187   QBoxLayout *topLayout = new QVBoxLayout( this );
00188   topLayout->setSpacing( spacing );
00189 
00190   initOrganizerWidgets( this, topLayout );
00191 
00192   mListView = new KOAttendeeListView( this, "mListView" );
00193   QWhatsThis::add( mListView,
00194            i18n("Displays information about current attendees. "
00195             "To edit an attendee, select it in this list "
00196             "and modify the values in the area below. "
00197             "Clicking on a column title will sort the list "
00198             "according to that column. The RSVP column "
00199             "indicates whether or not a response is requested "
00200             "from the attendee.") );
00201   mListView->addColumn( i18n("Name"), 200 );
00202   mListView->addColumn( i18n("Email"), 200 );
00203   mListView->addColumn( i18n("Role"), 80 );
00204   mListView->addColumn( i18n("Status"), 100 );
00205   mListView->addColumn( i18n("RSVP"), 55 );
00206   mListView->addColumn( i18n("Delegated to"), 120 );
00207   mListView->addColumn( i18n("Delegated from" ), 120 );
00208   mListView->setResizeMode( QListView::LastColumn );
00209   if ( KOPrefs::instance()->mCompactDialogs ) {
00210     mListView->setFixedHeight( 78 );
00211   }
00212 
00213   connect( mListView, SIGNAL( selectionChanged( QListViewItem * ) ),
00214            SLOT( updateAttendeeInput() ) );
00215 #ifndef KORG_NODND
00216   connect( mListView, SIGNAL( dropped( Attendee * ) ),
00217            SLOT( slotInsertAttendee( Attendee * ) ) );
00218 #endif
00219   topLayout->addWidget( mListView );
00220 
00221   initEditWidgets( this, topLayout );
00222 
00223   connect( mRemoveButton, SIGNAL(clicked()), SLOT(removeAttendee()) );
00224 
00225   updateAttendeeInput();
00226 }
00227 
00228 KOEditorDetails::~KOEditorDetails()
00229 {
00230 }
00231 
00232 bool KOEditorDetails::hasAttendees()
00233 {
00234   return mListView->childCount() > 0;
00235 }
00236 
00237 void KOEditorDetails::removeAttendee()
00238 {
00239   AttendeeListItem *aItem =
00240       static_cast<AttendeeListItem *>( mListView->selectedItem() );
00241   if ( !aItem ) return;
00242 
00243   Attendee *delA = new Attendee( aItem->data()->name(), aItem->data()->email(),
00244                                  aItem->data()->RSVP(), aItem->data()->status(),
00245                                  aItem->data()->role(), aItem->data()->uid() );
00246   mdelAttendees.append( delA );
00247 
00248   delete aItem;
00249 
00250   updateAttendeeInput();
00251   emit updateAttendeeSummary( mListView->childCount() );
00252 }
00253 
00254 
00255 void KOEditorDetails::insertAttendee( Attendee *a, bool goodEmailAddress )
00256 {
00257   Q_UNUSED( goodEmailAddress );
00258 
00259   // lastItem() is O(n), but for n very small that should be fine
00260   AttendeeListItem *item = new AttendeeListItem( a, mListView,
00261       static_cast<KListViewItem*>( mListView->lastItem() ) );
00262   mListView->setSelected( item, true );
00263   emit updateAttendeeSummary( mListView->childCount() );
00264 }
00265 
00266 void KOEditorDetails::setDefaults()
00267 {
00268   mRsvpButton->setChecked( true );
00269 }
00270 
00271 void KOEditorDetails::readEvent( Incidence *event )
00272 {
00273   mListView->clear();
00274   KOAttendeeEditor::readEvent( event );
00275 
00276   mListView->setSelected( mListView->firstChild(), true );
00277 
00278   emit updateAttendeeSummary( mListView->childCount() );
00279 }
00280 
00281 void KOEditorDetails::writeEvent(Incidence *event)
00282 {
00283   event->clearAttendees();
00284   QValueVector<QListViewItem*> toBeDeleted;
00285   QListViewItem *item;
00286   AttendeeListItem *a;
00287   for (item = mListView->firstChild(); item;
00288        item = item->nextSibling()) {
00289     a = (AttendeeListItem *)item;
00290     Attendee *attendee = a->data();
00291     Q_ASSERT( attendee );
00292     /* Check if the attendee is a distribution list and expand it */
00293     if ( attendee->email().isEmpty() ) {
00294       KPIM::DistributionList list =
00295         KPIM::DistributionList::findByName( KABC::StdAddressBook::self(), attendee->name() );
00296       if ( !list.isEmpty() ) {
00297         toBeDeleted.push_back( item ); // remove it once we are done expanding
00298         KPIM::DistributionList::Entry::List entries = list.entries( KABC::StdAddressBook::self() );
00299         KPIM::DistributionList::Entry::List::Iterator it( entries.begin() );
00300         while ( it != entries.end() ) {
00301           KPIM::DistributionList::Entry &e = ( *it );
00302           ++it;
00303           // this calls insertAttendee, which appends
00304           insertAttendeeFromAddressee( e.addressee, attendee );
00305           // TODO: duplicate check, in case it was already added manually
00306         }
00307       }
00308     } else {
00309       bool skip = false;
00310       if ( attendee->email().endsWith( "example.net" ) ) {
00311         if ( KMessageBox::warningYesNo( this, i18n("%1 does not look like a valid email address. "
00312                 "Are you sure you want to invite this participant?").arg( attendee->email() ),
00313               i18n("Invalid email address") ) != KMessageBox::Yes ) {
00314           skip = true;
00315         }
00316       }
00317       if ( !skip ) {
00318         event->addAttendee( new Attendee( *attendee ) );
00319       }
00320     }
00321   }
00322 
00323   KOAttendeeEditor::writeEvent( event );
00324 
00325   // cleanup
00326   QValueVector<QListViewItem*>::iterator it;
00327   for( it = toBeDeleted.begin(); it != toBeDeleted.end(); ++it ) {
00328     delete *it;
00329   }
00330 }
00331 
00332 bool KOEditorDetails::validateInput()
00333 {
00334   return true;
00335 }
00336 
00337 KCal::Attendee * KOEditorDetails::currentAttendee() const
00338 {
00339   QListViewItem *item = mListView->selectedItem();
00340   AttendeeListItem *aItem = static_cast<AttendeeListItem *>( item );
00341   if ( !aItem )
00342     return 0;
00343   return aItem->data();
00344 }
00345 
00346 void KOEditorDetails::updateCurrentItem()
00347 {
00348   AttendeeListItem *item = static_cast<AttendeeListItem*>( mListView->selectedItem() );
00349   if ( item )
00350     item->updateItem();
00351 }
00352 
00353 void KOEditorDetails::slotInsertAttendee(Attendee * a)
00354 {
00355   insertAttendee( a );
00356 }
00357 
00358 void KOEditorDetails::changeStatusForMe(Attendee::PartStat status)
00359 {
00360   const QStringList myEmails = KOPrefs::instance()->allEmails();
00361   for ( QListViewItemIterator it( mListView ); it.current(); ++it ) {
00362     AttendeeListItem *item = static_cast<AttendeeListItem*>( it.current() );
00363     for ( QStringList::ConstIterator it2( myEmails.begin() ), end( myEmails.end() ); it2 != end; ++it2 ) {
00364       if ( item->data()->email() == *it2 ) {
00365         item->data()->setStatus( status );
00366         item->updateItem();
00367       }
00368     }
00369   }
00370 }
00371 
00372 QListViewItem* KOEditorDetails::hasExampleAttendee() const
00373 {
00374   for ( QListViewItemIterator it( mListView ); it.current(); ++it ) {
00375     AttendeeListItem *item = static_cast<AttendeeListItem*>( it.current() );
00376     Attendee *attendee = item->data();
00377     Q_ASSERT( attendee );
00378     if ( isExampleAttendee( attendee ) )
00379         return item;
00380   }
00381   return 0;
00382 }
00383 
00384 #include "koeditordetails.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys