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