korganizer

koeventeditor.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 2001, 2002, 2003 Cornelius Schumacher <schumacher@kde.org>
00005     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020 
00021     As a special exception, permission is given to link this program
00022     with any edition of Qt, and distribute the resulting executable,
00023     without including the source code for Qt in the source distribution.
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 //  setupAlarmsTab();
00070   setupRecurrence();
00071   setupFreeBusy();
00072   setupDesignerTabs( "event" );
00073 
00074   // Propagate date time settings to recurrence tab
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   // Propagate date time settings to gantt tab and back
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 //    QBoxLayout *alarmLineLayout = new QHBoxLayout(topLayout);
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 /*modification*/)
00170 {
00171   // Play dump, just reload the event. This dialog has become so complicated
00172   // that there is no point in trying to be smart here...
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       // Don't do anything
00283       kdDebug(5850) << "Event not changed\n";
00284     else {
00285       kdDebug(5850) << "Event changed\n";
00286       //IncidenceChanger::assignIncidence( mEvent, event );
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     // NOTE: triggered by addIncidence, the kolab resource might open a non-modal dialog (parent is not available in the resource) to select a resource folder. Thus the user can close this dialog before addIncidence() returns.
00306     if ( !mChanger->addIncidence( mEvent, this ) ) {
00307       delete mEvent;
00308       mEvent = 0;
00309       return false;
00310     }
00311   }
00312   // if "this" was deleted, freeBusy is 0 (being a guardedptr)
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 //  mAlarms->readIncidence( event );
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( /*const*/ 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"
KDE Home | KDE Accessibility Home | Description of Access Keys