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 <qtooltip.h>
00027 #include <qframe.h>
00028 #include <qpixmap.h>
00029 #include <qlayout.h>
00030 #include <qwidgetstack.h>
00031 #include <qwhatsthis.h>
00032
00033 #include <kiconloader.h>
00034 #include <kdebug.h>
00035 #include <klocale.h>
00036 #include <kmessagebox.h>
00037 #include <libkcal/calendarresources.h>
00038 #include <libkcal/resourcecalendar.h>
00039 #include <libkcal/incidenceformatter.h>
00040 #include <libkcal/calendarlocal.h>
00041
00042 #include "koprefs.h"
00043 #include "koeditorgeneralevent.h"
00044 #include "koeditorrecurrence.h"
00045 #include "koeditordetails.h"
00046 #include "koeditorfreebusy.h"
00047 #include "kogroupware.h"
00048 #include "kodialogmanager.h"
00049 #include "incidencechanger.h"
00050
00051 #include "koeventeditor.h"
00052
00053 KOEventEditor::KOEventEditor( Calendar *calendar, QWidget *parent )
00054 : KOIncidenceEditor( QString::null, calendar, parent ),
00055 mEvent( 0 ), mCalendar( 0 ), mGeneral( 0 ), mRecurrence( 0 ), mFreeBusy( 0 )
00056 {
00057 }
00058
00059 KOEventEditor::~KOEventEditor()
00060 {
00061 if ( !mIsCounter )
00062 emit dialogClose( mEvent );
00063 }
00064
00065 void KOEventEditor::init()
00066 {
00067 setupGeneral();
00068 setupRecurrence();
00069 setupFreeBusy();
00070 setupDesignerTabs( "event" );
00071
00072
00073 connect( mGeneral, SIGNAL( dateTimesChanged( const QDateTime &, const QDateTime & ) ),
00074 mRecurrence, SLOT( setDateTimes( const QDateTime &, const QDateTime &) ) );
00075 connect( mGeneral, SIGNAL( dateTimeStrChanged( const QString & ) ),
00076 mRecurrence, SLOT( setDateTimeStr( const QString & ) ) );
00077 connect( mFreeBusy, SIGNAL( dateTimesChanged( const QDateTime &, const QDateTime & ) ),
00078 mRecurrence, SLOT( setDateTimes( const QDateTime &, const QDateTime & ) ) );
00079
00080
00081 connect( mGeneral, SIGNAL( dateTimesChanged( const QDateTime &, const QDateTime & ) ),
00082 mFreeBusy, SLOT( slotUpdateGanttView( const QDateTime &, const QDateTime & ) ) );
00083 connect( mFreeBusy, SIGNAL( dateTimesChanged( const QDateTime &, const QDateTime & ) ),
00084 mGeneral, SLOT( setDateTimes( const QDateTime &, const QDateTime & ) ) );
00085
00086 connect( mGeneral, SIGNAL( focusReceivedSignal() ),
00087 SIGNAL( focusReceivedSignal() ) );
00088
00089 connect( mGeneral, SIGNAL( openCategoryDialog() ),
00090 SIGNAL( editCategories() ) );
00091 connect( this, SIGNAL( updateCategoryConfig() ),
00092 mGeneral, SIGNAL( updateCategoryConfig() ) );
00093
00094 connect( mFreeBusy, SIGNAL(updateAttendeeSummary(int)),
00095 mGeneral, SLOT(updateAttendeeSummary(int)) );
00096
00097 connect( mGeneral, SIGNAL(editRecurrence()),
00098 mRecurrenceDialog, SLOT(show()) );
00099 connect( mRecurrenceDialog, SIGNAL(okClicked()),
00100 SLOT(updateRecurrenceSummary()) );
00101
00102 connect( mGeneral, SIGNAL(acceptInvitation()),
00103 mFreeBusy, SLOT(acceptForMe()) );
00104 connect( mGeneral, SIGNAL(declineInvitation()),
00105 mFreeBusy, SLOT(declineForMe()) );
00106 }
00107
00108 void KOEventEditor::reload()
00109 {
00110 kdDebug(5850) << "KOEventEditor::reload()" << endl;
00111
00112 if ( mEvent ) {
00113 readEvent( mEvent, mCalendar, QDate() );
00114 }
00115 }
00116
00117 void KOEventEditor::setupGeneral()
00118 {
00119 mGeneral = new KOEditorGeneralEvent( this );
00120
00121 if( KOPrefs::instance()->mCompactDialogs ) {
00122 QFrame *topFrame = addPage(i18n("General"));
00123 QWhatsThis::add( topFrame,
00124 i18n("The General tab allows you to set the most common "
00125 "options for the event.") );
00126
00127 QBoxLayout *topLayout = new QVBoxLayout(topFrame);
00128 topLayout->setSpacing(spacingHint());
00129
00130 mGeneral->initHeader( topFrame, topLayout );
00131 mGeneral->initTime(topFrame,topLayout);
00132
00133 topLayout->addStretch( 1 );
00134
00135 QFrame *topFrame2 = addPage(i18n("Details"));
00136
00137 QBoxLayout *topLayout2 = new QVBoxLayout(topFrame2);
00138 topLayout2->setSpacing(spacingHint());
00139
00140 mGeneral->initClass(topFrame2,topLayout2);
00141 mGeneral->initSecrecy( topFrame2, topLayout2 );
00142 mGeneral->initDescription(topFrame2,topLayout2);
00143 } else {
00144 QFrame *topFrame = addPage(i18n("&General"));
00145 QWhatsThis::add( topFrame,
00146 i18n("The General tab allows you to set the most common "
00147 "options for the event.") );
00148
00149 QBoxLayout *topLayout = new QVBoxLayout(topFrame);
00150 topLayout->setSpacing(spacingHint());
00151
00152 mGeneral->initInvitationBar( topFrame, topLayout );
00153 mGeneral->initHeader( topFrame, topLayout );
00154 mGeneral->initTime(topFrame,topLayout);
00155 mGeneral->initDescription(topFrame,topLayout);
00156 mGeneral->initAttachments(topFrame,topLayout);
00157 connect( mGeneral, SIGNAL( openURL( const KURL& ) ),
00158 this, SLOT( openURL( const KURL& ) ) );
00159 connect( this, SIGNAL( signalAddAttachments( const QStringList&, const QStringList&, bool ) ),
00160 mGeneral, SLOT( addAttachments( const QStringList&, const QStringList&, bool ) ) );
00161 }
00162
00163 mGeneral->finishSetup();
00164 }
00165
00166 void KOEventEditor::modified()
00167 {
00168
00169
00170 reload();
00171 }
00172
00173 void KOEventEditor::setupRecurrence()
00174 {
00175 mRecurrenceDialog = new KOEditorRecurrenceDialog( this );
00176 mRecurrenceDialog->hide();
00177 mRecurrence = mRecurrenceDialog->editor();
00178 }
00179
00180 void KOEventEditor::setupFreeBusy()
00181 {
00182 QFrame *freeBusyPage = addPage( i18n("&Attendees") );
00183 QWhatsThis::add( freeBusyPage,
00184 i18n("The Free/Busy tab allows you to see whether "
00185 "other attendees are free or busy during your event.") );
00186
00187 QBoxLayout *topLayout = new QVBoxLayout( freeBusyPage );
00188
00189 mAttendeeEditor = mFreeBusy = new KOEditorFreeBusy( spacingHint(), freeBusyPage );
00190 topLayout->addWidget( mFreeBusy );
00191 }
00192
00193 void KOEventEditor::editIncidence( Incidence *incidence,
00194 const QDate &date,
00195 Calendar *calendar )
00196 {
00197 Event*event = dynamic_cast<Event*>(incidence);
00198 if ( event ) {
00199 init();
00200
00201 mEvent = event;
00202 mCalendar = calendar;
00203
00204 const QDate &dt = mRecurIncidence && date.isValid() ? date : incidence->dtStart().date();
00205 readEvent( mEvent, mCalendar, dt );
00206 }
00207
00208 setCaption( i18n("Edit Event") );
00209 }
00210
00211 void KOEventEditor::newEvent()
00212 {
00213 init();
00214 mEvent = 0;
00215 loadDefaults();
00216 setCaption( i18n("New Event") );
00217 }
00218
00219 void KOEventEditor::setDates( const QDateTime &from, const QDateTime &to, bool allDay )
00220 {
00221 mGeneral->setDefaults( from, to, allDay );
00222 mRecurrence->setDefaults( from, to, allDay );
00223 if( mFreeBusy ) {
00224 if ( allDay )
00225 mFreeBusy->setDateTimes( from, to.addDays( 1 ) );
00226 else
00227 mFreeBusy->setDateTimes( from, to );
00228 }
00229 }
00230
00231 void KOEventEditor::setTexts( const QString &summary, const QString &description )
00232 {
00233 if ( description.isEmpty() && summary.contains("\n") ) {
00234 mGeneral->setDescription( summary );
00235 int pos = summary.find( "\n" );
00236 mGeneral->setSummary( summary.left( pos ) );
00237 } else {
00238 mGeneral->setSummary( summary );
00239 mGeneral->setDescription( description );
00240 }
00241 }
00242
00243 void KOEventEditor::loadDefaults()
00244 {
00245 QDateTime from( QDate::currentDate(), KOPrefs::instance()->mStartTime.time() );
00246 int addSecs = ( KOPrefs::instance()->mDefaultDuration.time().hour()*3600 ) +
00247 ( KOPrefs::instance()->mDefaultDuration.time().minute()*60 );
00248 QDateTime to( from.addSecs( addSecs ) );
00249
00250 setDates( from, to, false );
00251 }
00252
00253 bool KOEventEditor::processInput()
00254 {
00255 kdDebug(5850) << "KOEventEditor::processInput(); event is " << mEvent << endl;
00256
00257 if ( !validateInput() || !mChanger ) {
00258 kdDebug(5850) << " mChanger is " << mChanger << endl;
00259 return false;
00260 }
00261
00262 QGuardedPtr<KOEditorFreeBusy> freeBusy( mFreeBusy );
00263
00264 if ( mEvent ) {
00265 bool rc = true;
00266 Event *oldEvent = mEvent->clone();
00267 Event *event = mEvent->clone();
00268
00269 kdDebug(5850) << "KOEventEditor::processInput() write event." << endl;
00270 writeEvent( event );
00271 kdDebug(5850) << "KOEventEditor::processInput() event written." << endl;
00272
00273 if( *event == *mEvent ) {
00274
00275 kdDebug(5850) << "Event not changed" << endl;
00276 if ( mIsCounter ) {
00277 KMessageBox::information( this, i18n("You didn't change the event, thus no counter proposal has been sent to the organizer."), i18n("No changes") );
00278 }
00279 } else {
00280 kdDebug(5850) << "Event changed" << endl;
00281
00282 writeEvent( mEvent );
00283 if ( mIsCounter ) {
00284 KOGroupware::instance()->sendCounterProposal( mCalendar, oldEvent, mEvent );
00285
00286 Event *event = mEvent->clone();
00287 event->clearAttendees();
00288 event->setSummary( i18n("My counter proposal for: %1").arg( mEvent->summary() ) );
00289 mChanger->addIncidence( event, mResource, mSubResource, this );
00290 } else {
00291 if ( mRecurIncidence && mRecurIncidenceAfterDissoc ) {
00292 mChanger->addIncidence( mEvent, mResource, mSubResource, this );
00293
00294 mChanger->changeIncidence( mRecurIncidence, mRecurIncidenceAfterDissoc,
00295 KOGlobals::RECURRENCE_MODIFIED_ALL_FUTURE, this );
00296
00297 } else {
00298 mChanger->changeIncidence( oldEvent, mEvent, KOGlobals::NOTHING_MODIFIED, this );
00299 }
00300 }
00301 }
00302 delete event;
00303 delete oldEvent;
00304 return rc;
00305 } else {
00306 mEvent = new Event;
00307 mEvent->setOrganizer( Person( KOPrefs::instance()->fullName(),
00308 KOPrefs::instance()->email() ) );
00309 writeEvent( mEvent );
00310
00311 if ( !mChanger->addIncidence( mEvent, mResource, mSubResource, this ) ) {
00312 delete mEvent;
00313 mEvent = 0;
00314 return false;
00315 }
00316 }
00317
00318 if ( freeBusy ) {
00319 freeBusy->cancelReload();
00320 }
00321
00322 return true;
00323 }
00324
00325 void KOEventEditor::processCancel()
00326 {
00327 kdDebug(5850) << "KOEventEditor::processCancel()" << endl;
00328
00329 if ( mFreeBusy ) mFreeBusy->cancelReload();
00330
00331 if ( mRecurIncidence && mRecurIncidenceAfterDissoc ) {
00332 *mRecurIncidenceAfterDissoc = *mRecurIncidence;
00333 }
00334
00335 }
00336
00337 void KOEventEditor::deleteEvent()
00338 {
00339 kdDebug(5850) << "Delete event" << endl;
00340
00341 if ( mEvent )
00342 emit deleteIncidenceSignal( mEvent );
00343 emit dialogClose( mEvent );
00344 reject();
00345 }
00346
00347 void KOEventEditor::readEvent( Event *event, Calendar *calendar, const QDate &date, bool tmpl )
00348 {
00349 mGeneral->readEvent( event, calendar, date, tmpl );
00350 mRecurrence->readIncidence( event );
00351
00352 if ( mFreeBusy ) {
00353 mFreeBusy->readEvent( event );
00354 mFreeBusy->triggerReload();
00355 }
00356
00357 createEmbeddedURLPages( event );
00358 readDesignerFields( event );
00359
00360 if ( mIsCounter )
00361 mGeneral->invitationBar()->hide();
00362 }
00363
00364 void KOEventEditor::writeEvent( Event *event )
00365 {
00366 mGeneral->writeEvent( event );
00367 if ( mFreeBusy )
00368 mFreeBusy->writeEvent( event );
00369
00370 cancelRemovedAttendees( event );
00371
00372 mRecurrence->writeIncidence( event );
00373
00374 writeDesignerFields( event );
00375 }
00376
00377 bool KOEventEditor::validateInput()
00378 {
00379 if ( !mGeneral->validateInput() ||
00380 !mDetails->validateInput() ||
00381 !mRecurrence->validateInput() ) {
00382 kdDebug(5850) << "ValidateInput returns false" << endl;
00383 return false;
00384 } else {
00385 return true;
00386 }
00387 }
00388
00389 int KOEventEditor::msgItemDelete()
00390 {
00391 return KMessageBox::warningContinueCancel(this,
00392 i18n("This item will be permanently deleted."),
00393 i18n("KOrganizer Confirmation"),KGuiItem(i18n("Delete"),"editdelete"));
00394 }
00395
00396 void KOEventEditor::loadTemplate( CalendarLocal& cal )
00397 {
00398 const Event::List events = cal.events();
00399 if ( events.count() == 0 ) {
00400 KMessageBox::error( this,
00401 i18n("Template does not contain a valid event.") );
00402 } else {
00403 kdDebug(5850) << "KOEventEditor::slotLoadTemplate(): readTemplate" << endl;
00404 readEvent( events.first(), 0, QDate(), true );
00405 }
00406 }
00407
00408 QStringList& KOEventEditor::templates() const
00409 {
00410 return KOPrefs::instance()->mEventTemplates;
00411 }
00412
00413 void KOEventEditor::slotSaveTemplate( const QString &templateName )
00414 {
00415 kdDebug(5006) << "SlotSaveTemplate" << endl;
00416 Event *event = new Event;
00417 writeEvent( event );
00418 saveAsTemplate( event, templateName );
00419 }
00420
00421 QObject *KOEventEditor::typeAheadReceiver() const
00422 {
00423 return mGeneral->typeAheadReceiver();
00424 }
00425
00426 void KOEventEditor::updateRecurrenceSummary()
00427 {
00428 Event *ev = new Event();
00429 writeEvent( ev );
00430 mGeneral->updateRecurrenceSummary( ev );
00431 delete ev;
00432 }
00433
00434 void KOEventEditor::selectInvitationCounterProposal(bool enable)
00435 {
00436 KOIncidenceEditor::selectInvitationCounterProposal( enable );
00437 if ( enable )
00438 mGeneral->invitationBar()->hide();
00439 }
00440
00441 #include "koeventeditor.moc"