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 
00157 #ifndef KORG_NOKABC
00158   KABC::Addressee::List list;
00159   if ( KVCardDrag::decode( e, list ) ) {
00160     KABC::Addressee::List::Iterator it;
00161     for ( it = list.begin(); it != list.end(); ++it ) {
00162       QString em( (*it).fullEmail() );
00163       if ( em.isEmpty() ) {
00164         em = (*it).realName();
00165       }
00166       addAttendee( em );
00167     }
00168   } else
00169 #endif // KORG_NOKABC
00170   if (QTextDrag::decode(e,text)) {
00171     kdDebug(5850) << "Dropped : " << text << endl;
00172     QStringList emails = QStringList::split(",",text);
00173     for(QStringList::ConstIterator it = emails.begin();it!=emails.end();++it) {
00174       addAttendee(*it);
00175     }
00176   }
00177 #endif //KORG_NODND
00178 }
00179 
00180 
00181 KOEditorDetails::KOEditorDetails( int spacing, QWidget *parent,
00182                                   const char *name )
00183   : KOAttendeeEditor( parent, name), mDisableItemUpdate( false )
00184 {
00185   QBoxLayout *topLayout = new QVBoxLayout( this );
00186   topLayout->setSpacing( spacing );
00187 
00188   initOrganizerWidgets( this, topLayout );
00189 
00190   mListView = new KOAttendeeListView( this, "mListView" );
00191   QWhatsThis::add( mListView,
00192            i18n("Displays information about current attendees. "
00193             "To edit an attendee, select it in this list "
00194             "and modify the values in the area below. "
00195             "Clicking on a column title will sort the list "
00196             "according to that column. The RSVP column "
00197             "indicates whether or not a response is requested "
00198             "from the attendee.") );
00199   mListView->addColumn( i18n("Name"), 200 );
00200   mListView->addColumn( i18n("Email"), 200 );
00201   mListView->addColumn( i18n("Role"), 80 );
00202   mListView->addColumn( i18n("Status"), 100 );
00203   mListView->addColumn( i18n("RSVP"), 55 );
00204   mListView->addColumn( i18n("Delegated to"), 120 );
00205   mListView->addColumn( i18n("Delegated from" ), 120 );
00206   mListView->setResizeMode( QListView::LastColumn );
00207   if ( KOPrefs::instance()->mCompactDialogs ) {
00208     mListView->setFixedHeight( 78 );
00209   }
00210 
00211   connect( mListView, SIGNAL( selectionChanged( QListViewItem * ) ),
00212            SLOT( updateAttendeeInput() ) );
00213 #ifndef KORG_NODND
00214   connect( mListView, SIGNAL( dropped( Attendee * ) ),
00215            SLOT( slotInsertAttendee( Attendee * ) ) );
00216 #endif
00217   topLayout->addWidget( mListView );
00218 
00219   initEditWidgets( this, topLayout );
00220 
00221   connect( mRemoveButton, SIGNAL(clicked()), SLOT(removeAttendee()) );
00222 
00223   updateAttendeeInput();
00224 }
00225 
00226 KOEditorDetails::~KOEditorDetails()
00227 {
00228 }
00229 
00230 bool KOEditorDetails::hasAttendees()
00231 {
00232   return mListView->childCount() > 0;
00233 }
00234 
00235 void KOEditorDetails::removeAttendee()
00236 {
00237   AttendeeListItem *aItem =
00238       static_cast<AttendeeListItem *>( mListView->selectedItem() );
00239   if ( !aItem ) return;
00240 
00241   AttendeeListItem *nextSelectedItem = static_cast<AttendeeListItem*>( aItem->nextSibling() );
00242   if( mListView->childCount() == 1 )
00243       nextSelectedItem = 0;
00244   if( mListView->childCount() > 1 && aItem == mListView->lastItem() )
00245       nextSelectedItem = static_cast<AttendeeListItem*>(  mListView->firstChild() );
00246 
00247   Attendee *attendee = aItem->data();
00248   Attendee *delA = new Attendee( attendee->name(), attendee->email(),
00249                                  attendee->RSVP(), attendee->status(),
00250                                  attendee->role(), attendee->uid() );
00251   mdelAttendees.append( delA );
00252   delete aItem;
00253 
00254   if( nextSelectedItem ) {
00255       mListView->setSelected( nextSelectedItem, true );
00256   }
00257   updateAttendeeInput();
00258   emit updateAttendeeSummary( mListView->childCount() );
00259 }
00260 
00261 
00262 void KOEditorDetails::insertAttendee( Attendee *a, bool goodEmailAddress )
00263 {
00264   Q_UNUSED( goodEmailAddress );
00265 
00266   // lastItem() is O(n), but for n very small that should be fine
00267   AttendeeListItem *item = new AttendeeListItem(
00268     a, mListView, static_cast<KListViewItem*>( mListView->lastItem() ) );
00269   mListView->setSelected( item, true );
00270   emit updateAttendeeSummary( mListView->childCount() );
00271 }
00272 
00273 void KOEditorDetails::removeAttendee( Attendee *attendee )
00274 {
00275   QListViewItem *item;
00276   for ( item = mListView->firstChild(); item;  item = item->nextSibling() ) {
00277     AttendeeListItem *anItem = static_cast<AttendeeListItem *>( item );
00278     Attendee *att = anItem->data();
00279     if ( att == attendee ) {
00280       delete anItem;
00281       break;
00282     }
00283   }
00284 }
00285 
00286 void KOEditorDetails::setDefaults()
00287 {
00288   mRsvpButton->setChecked( true );
00289 }
00290 
00291 void KOEditorDetails::readEvent( Incidence *event )
00292 {
00293   mListView->clear();
00294   KOAttendeeEditor::readEvent( event );
00295 
00296   mListView->setSelected( mListView->firstChild(), true );
00297 
00298   emit updateAttendeeSummary( mListView->childCount() );
00299 }
00300 
00301 void KOEditorDetails::writeEvent(Incidence *event)
00302 {
00303   event->clearAttendees();
00304   QValueVector<QListViewItem*> toBeDeleted;
00305   QListViewItem *item;
00306   AttendeeListItem *a;
00307   for (item = mListView->firstChild(); item;
00308        item = item->nextSibling()) {
00309     a = (AttendeeListItem *)item;
00310     Attendee *attendee = a->data();
00311     Q_ASSERT( attendee );
00312     /* Check if the attendee is a distribution list and expand it */
00313     if ( attendee->email().isEmpty() ) {
00314       KPIM::DistributionList list =
00315         KPIM::DistributionList::findByName( KABC::StdAddressBook::self(), attendee->name() );
00316       if ( !list.isEmpty() ) {
00317         toBeDeleted.push_back( item ); // remove it once we are done expanding
00318         KPIM::DistributionList::Entry::List entries = list.entries( KABC::StdAddressBook::self() );
00319         KPIM::DistributionList::Entry::List::Iterator it( entries.begin() );
00320         while ( it != entries.end() ) {
00321           KPIM::DistributionList::Entry &e = ( *it );
00322           ++it;
00323           // this calls insertAttendee, which appends
00324           insertAttendeeFromAddressee( e.addressee, attendee );
00325           // TODO: duplicate check, in case it was already added manually
00326         }
00327       }
00328     } else {
00329       bool skip = false;
00330       if ( attendee->email().endsWith( "example.net" ) ) {
00331         if ( KMessageBox::warningYesNo( this, i18n("%1 does not look like a valid email address. "
00332                 "Are you sure you want to invite this participant?").arg( attendee->email() ),
00333               i18n("Invalid email address") ) != KMessageBox::Yes ) {
00334           skip = true;
00335         }
00336       }
00337       if ( !skip ) {
00338         event->addAttendee( new Attendee( *attendee ) );
00339       }
00340     }
00341   }
00342 
00343   KOAttendeeEditor::writeEvent( event );
00344 
00345   // cleanup
00346   QValueVector<QListViewItem*>::iterator it;
00347   for( it = toBeDeleted.begin(); it != toBeDeleted.end(); ++it ) {
00348     delete *it;
00349   }
00350 }
00351 
00352 bool KOEditorDetails::validateInput()
00353 {
00354   return true;
00355 }
00356 
00357 KCal::Attendee * KOEditorDetails::currentAttendee() const
00358 {
00359   QListViewItem *item = mListView->selectedItem();
00360   AttendeeListItem *aItem = static_cast<AttendeeListItem *>( item );
00361   if ( !aItem )
00362     return 0;
00363   return aItem->data();
00364 }
00365 
00366 void KOEditorDetails::updateCurrentItem()
00367 {
00368   AttendeeListItem *item = static_cast<AttendeeListItem*>( mListView->selectedItem() );
00369   if ( item )
00370     item->updateItem();
00371 }
00372 
00373 void KOEditorDetails::slotInsertAttendee( Attendee *a )
00374 {
00375   insertAttendee( a );
00376   mnewAttendees.append( a );
00377 }
00378 
00379 void KOEditorDetails::setSelected( int index )
00380 {
00381   int count = 0;
00382   for ( QListViewItemIterator it( mListView ); it.current(); ++it ) {
00383     if ( count == index ) {
00384       mListView->setSelected( *it, true );
00385       return;
00386     }
00387     count++;
00388   }
00389 }
00390 
00391 int KOEditorDetails::selectedIndex()
00392 {
00393   int index = 0;
00394   for ( QListViewItemIterator it( mListView ); it.current(); ++it ) {
00395     if ( mListView->isSelected( *it ) ) {
00396       break;
00397     }
00398     index++;
00399   }
00400   return index;
00401 }
00402 
00403 void KOEditorDetails::changeStatusForMe(Attendee::PartStat status)
00404 {
00405   const QStringList myEmails = KOPrefs::instance()->allEmails();
00406   for ( QListViewItemIterator it( mListView ); it.current(); ++it ) {
00407     AttendeeListItem *item = static_cast<AttendeeListItem*>( it.current() );
00408     for ( QStringList::ConstIterator it2( myEmails.begin() ), end( myEmails.end() ); it2 != end; ++it2 ) {
00409       if ( item->data()->email() == *it2 ) {
00410         item->data()->setStatus( status );
00411         item->updateItem();
00412       }
00413     }
00414   }
00415 }
00416 
00417 QListViewItem* KOEditorDetails::hasExampleAttendee() const
00418 {
00419   for ( QListViewItemIterator it( mListView ); it.current(); ++it ) {
00420     AttendeeListItem *item = static_cast<AttendeeListItem*>( it.current() );
00421     Attendee *attendee = item->data();
00422     Q_ASSERT( attendee );
00423     if ( isExampleAttendee( attendee ) )
00424         return item;
00425   }
00426   return 0;
00427 }
00428 
00429 #include "koeditordetails.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys