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   emit dialogClose( mEvent );
00063 }
00064 
00065 void KOEventEditor::init()
00066 {
00067   setupGeneral();
00068 //  setupAlarmsTab();
00069   setupRecurrence();
00070   setupFreeBusy();
00071   setupDesignerTabs( "event" );
00072 
00073   // Propagate date time settings to recurrence tab
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   // Propagate date time settings to gantt tab and back
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 //    QBoxLayout *alarmLineLayout = new QHBoxLayout(topLayout);
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 /*modification*/)
00169 {
00170   // Play dump, just reload the event. This dialog has become so complicated
00171   // that there is no point in trying to be smart here...
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       // Don't do anything
00282       kdDebug(5850) << "Event not changed\n";
00283     else {
00284       kdDebug(5850) << "Event changed\n";
00285       //IncidenceChanger::assignIncidence( mEvent, event );
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     // 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.
00298     if ( !mChanger->addIncidence( mEvent, this ) ) {
00299       delete mEvent;
00300       mEvent = 0;
00301       return false;
00302     }
00303   }
00304   // if "this" was deleted, freeBusy is 0 (being a guardedptr)
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 //  mAlarms->readIncidence( event );
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( /*const*/ 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"
KDE Home | KDE Accessibility Home | Description of Access Keys