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