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