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