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 ) readEvent( mEvent, mCalendar );
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 mGeneral->initAlarm(topFrame,topLayout);
00134 mGeneral->enableAlarm( false );
00135
00136 topLayout->addStretch( 1 );
00137
00138 QFrame *topFrame2 = addPage(i18n("Details"));
00139
00140 QBoxLayout *topLayout2 = new QVBoxLayout(topFrame2);
00141 topLayout2->setSpacing(spacingHint());
00142
00143 mGeneral->initClass(topFrame2,topLayout2);
00144 mGeneral->initSecrecy( topFrame2, topLayout2 );
00145 mGeneral->initDescription(topFrame2,topLayout2);
00146 } else {
00147 QFrame *topFrame = addPage(i18n("&General"));
00148 QWhatsThis::add( topFrame,
00149 i18n("The General tab allows you to set the most common "
00150 "options for the event.") );
00151
00152 QBoxLayout *topLayout = new QVBoxLayout(topFrame);
00153 topLayout->setSpacing(spacingHint());
00154
00155 mGeneral->initInvitationBar( topFrame, topLayout );
00156 mGeneral->initHeader( topFrame, topLayout );
00157 mGeneral->initTime(topFrame,topLayout);
00158 mGeneral->initDescription(topFrame,topLayout);
00159 mGeneral->initAttachments(topFrame,topLayout);
00160 connect( mGeneral, SIGNAL( openURL( const KURL& ) ),
00161 this, SLOT( openURL( const KURL& ) ) );
00162 connect( this, SIGNAL( signalAddAttachments( const QStringList&, const QStringList&, bool ) ),
00163 mGeneral, SLOT( addAttachments( const QStringList&, const QStringList&, bool ) ) );
00164 }
00165
00166 mGeneral->finishSetup();
00167 }
00168
00169 void KOEventEditor::modified (int )
00170 {
00171
00172
00173 reload();
00174 }
00175
00176 void KOEventEditor::setupRecurrence()
00177 {
00178 #if 0
00179 QFrame *topFrame = addPage( i18n("Rec&urrence") );
00180
00181 QWhatsThis::add( topFrame,
00182 i18n("The Recurrence tab allows you to set options on "
00183 "how often this event recurs.") );
00184
00185 QBoxLayout *topLayout = new QVBoxLayout( topFrame );
00186
00187 mRecurrence = new KOEditorRecurrence( topFrame );
00188 topLayout->addWidget( mRecurrence );
00189 #endif
00190 mRecurrenceDialog = new KOEditorRecurrenceDialog( this );
00191 mRecurrenceDialog->hide();
00192 mRecurrence = mRecurrenceDialog->editor();
00193 }
00194
00195 void KOEventEditor::setupFreeBusy()
00196 {
00197 QFrame *freeBusyPage = addPage( i18n("&Attendees") );
00198 QWhatsThis::add( freeBusyPage,
00199 i18n("The Free/Busy tab allows you to see whether "
00200 "other attendees are free or busy during your event.") );
00201
00202 QBoxLayout *topLayout = new QVBoxLayout( freeBusyPage );
00203
00204 mAttendeeEditor = mFreeBusy = new KOEditorFreeBusy( spacingHint(), freeBusyPage );
00205 topLayout->addWidget( mFreeBusy );
00206 }
00207
00208 void KOEventEditor::editIncidence( Incidence *incidence, Calendar *calendar )
00209 {
00210 Event*event = dynamic_cast<Event*>(incidence);
00211 if ( event ) {
00212 init();
00213
00214 mEvent = event;
00215 mCalendar = calendar;
00216 readEvent( mEvent, mCalendar );
00217 }
00218
00219 setCaption( i18n("Edit Event") );
00220 }
00221
00222 void KOEventEditor::newEvent()
00223 {
00224 init();
00225 mEvent = 0;
00226 loadDefaults();
00227 setCaption( i18n("New Event") );
00228 }
00229
00230 void KOEventEditor::setDates( const QDateTime &from, const QDateTime &to, bool allDay )
00231 {
00232 mGeneral->setDefaults( from, to, allDay );
00233 mRecurrence->setDefaults( from, to, allDay );
00234 if( mFreeBusy ) {
00235 if ( allDay )
00236 mFreeBusy->setDateTimes( from, to.addDays( 1 ) );
00237 else
00238 mFreeBusy->setDateTimes( from, to );
00239 }
00240 }
00241
00242 void KOEventEditor::setTexts( const QString &summary, const QString &description )
00243 {
00244 if ( description.isEmpty() && summary.contains("\n") ) {
00245 mGeneral->setDescription( summary );
00246 int pos = summary.find( "\n" );
00247 mGeneral->setSummary( summary.left( pos ) );
00248 } else {
00249 mGeneral->setSummary( summary );
00250 mGeneral->setDescription( description );
00251 }
00252 }
00253
00254 void KOEventEditor::loadDefaults()
00255 {
00256 QDateTime from( QDate::currentDate(), KOPrefs::instance()->mStartTime.time() );
00257 int addSecs = ( KOPrefs::instance()->mDefaultDuration.time().hour()*3600 ) +
00258 ( KOPrefs::instance()->mDefaultDuration.time().minute()*60 );
00259 QDateTime to( from.addSecs( addSecs ) );
00260
00261 setDates( from, to, false );
00262 }
00263
00264 bool KOEventEditor::processInput()
00265 {
00266 kdDebug(5850) << "KOEventEditor::processInput()" << endl;
00267
00268 if ( !validateInput() || !mChanger ) return false;
00269
00270 QGuardedPtr<KOEditorFreeBusy> freeBusy( mFreeBusy );
00271
00272 if ( mEvent ) {
00273 bool rc = true;
00274 Event *oldEvent = mEvent->clone();
00275 Event *event = mEvent->clone();
00276
00277 kdDebug(5850) << "KOEventEditor::processInput() write event." << endl;
00278 writeEvent( event );
00279 kdDebug(5850) << "KOEventEditor::processInput() event written." << endl;
00280
00281 if( *event == *mEvent )
00282
00283 kdDebug(5850) << "Event not changed\n";
00284 else {
00285 kdDebug(5850) << "Event changed\n";
00286
00287 writeEvent( mEvent );
00288 if ( mIsCounter ) {
00289 Event *event = mEvent->clone();
00290 event->clearAttendees();
00291 event->setSummary( i18n("My counter proposal for: %1").arg( mEvent->summary() ) );
00292 mChanger->changeIncidence( oldEvent, event, -1, mIsCounter );
00293 } else {
00294 mChanger->changeIncidence( oldEvent, mEvent, -1, mIsCounter );
00295 }
00296 }
00297 delete event;
00298 delete oldEvent;
00299 return rc;
00300 } else {
00301 mEvent = new Event;
00302 mEvent->setOrganizer( Person( KOPrefs::instance()->fullName(),
00303 KOPrefs::instance()->email() ) );
00304 writeEvent( mEvent );
00305
00306 if ( !mChanger->addIncidence( mEvent, this ) ) {
00307 delete mEvent;
00308 mEvent = 0;
00309 return false;
00310 }
00311 }
00312
00313 if ( freeBusy ) freeBusy->cancelReload();
00314
00315 return true;
00316 }
00317
00318 void KOEventEditor::processCancel()
00319 {
00320 kdDebug(5850) << "KOEventEditor::processCancel()" << endl;
00321
00322 if ( mFreeBusy ) mFreeBusy->cancelReload();
00323 }
00324
00325 void KOEventEditor::deleteEvent()
00326 {
00327 kdDebug(5850) << "Delete event" << endl;
00328
00329 if ( mEvent )
00330 emit deleteIncidenceSignal( mEvent );
00331 emit dialogClose( mEvent );
00332 reject();
00333 }
00334
00335 void KOEventEditor::readEvent( Event *event, Calendar *calendar, bool tmpl )
00336 {
00337 mGeneral->readEvent( event, calendar, tmpl );
00338 mRecurrence->readIncidence( event );
00339
00340 if ( mFreeBusy ) {
00341 mFreeBusy->readEvent( event );
00342 mFreeBusy->triggerReload();
00343 }
00344
00345 createEmbeddedURLPages( event );
00346 readDesignerFields( event );
00347
00348 if ( mIsCounter )
00349 mGeneral->invitationBar()->hide();
00350 }
00351
00352 void KOEventEditor::writeEvent( Event *event )
00353 {
00354 mGeneral->writeEvent( event );
00355 if ( mFreeBusy )
00356 mFreeBusy->writeEvent( event );
00357
00358 cancelRemovedAttendees( event );
00359
00360 mRecurrence->writeIncidence( event );
00361
00362 writeDesignerFields( event );
00363 }
00364
00365 bool KOEventEditor::validateInput()
00366 {
00367 if ( !mGeneral->validateInput() ) return false;
00368 if ( !mDetails->validateInput() ) return false;
00369 if ( !mRecurrence->validateInput() ) return false;
00370
00371 return true;
00372 }
00373
00374 int KOEventEditor::msgItemDelete()
00375 {
00376 return KMessageBox::warningContinueCancel(this,
00377 i18n("This item will be permanently deleted."),
00378 i18n("KOrganizer Confirmation"),KGuiItem(i18n("Delete"),"editdelete"));
00379 }
00380
00381 void KOEventEditor::loadTemplate( CalendarLocal& cal )
00382 {
00383 const Event::List events = cal.events();
00384 if ( events.count() == 0 ) {
00385 KMessageBox::error( this,
00386 i18n("Template does not contain a valid event.") );
00387 } else {
00388 kdDebug(5850) << "KOEventEditor::slotLoadTemplate(): readTemplate" << endl;
00389 readEvent( events.first(), 0, true );
00390 }
00391 }
00392
00393 QStringList& KOEventEditor::templates() const
00394 {
00395 return KOPrefs::instance()->mEventTemplates;
00396 }
00397
00398 void KOEventEditor::slotSaveTemplate( const QString &templateName )
00399 {
00400 kdDebug(5006) << "SlotSaveTemplate" << endl;
00401 Event *event = new Event;
00402 writeEvent( event );
00403 saveAsTemplate( event, templateName );
00404 }
00405
00406 QObject *KOEventEditor::typeAheadReceiver() const
00407 {
00408 return mGeneral->typeAheadReceiver();
00409 }
00410
00411 void KOEventEditor::updateRecurrenceSummary()
00412 {
00413 Event *ev = new Event();
00414 writeEvent( ev );
00415 mGeneral->updateRecurrenceSummary( IncidenceFormatter::recurrenceString( ev ) );
00416 delete ev;
00417 }
00418
00419 void KOEventEditor::selectInvitationCounterProposal(bool enable)
00420 {
00421 KOIncidenceEditor::selectInvitationCounterProposal( enable );
00422 if ( enable )
00423 mGeneral->invitationBar()->hide();
00424 }
00425
00426 #include "koeventeditor.moc"