korganizer

koeditorgeneralevent.cpp
00001 /*
00002     This file is part of KOrganizer.
00003     Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
00004     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of TQt, and distribute the resulting executable,
00022     without including the source code for TQt in the source distribution.
00023 */
00024 
00025 #include <tqtooltip.h>
00026 #include <tqlayout.h>
00027 #include <tqvbox.h>
00028 #include <tqbuttongroup.h>
00029 #include <tqvgroupbox.h>
00030 #include <tqwidgetstack.h>
00031 #include <tqspinbox.h>
00032 #include <tqdatetime.h>
00033 #include <tqlabel.h>
00034 #include <tqcheckbox.h>
00035 #include <tqcombobox.h>
00036 #include <tqpushbutton.h>
00037 #include <tqwhatsthis.h>
00038 
00039 #include <kdebug.h>
00040 #include <tdeglobal.h>
00041 #include <tdelocale.h>
00042 #include <tdemessagebox.h>
00043 #include <tdefiledialog.h>
00044 #include <kstandarddirs.h>
00045 #include <ktextedit.h>
00046 
00047 #include <libkcal/event.h>
00048 #include <libkcal/incidenceformatter.h>
00049 
00050 #include "ktimeedit.h"
00051 #include <libtdepim/kdateedit.h>
00052 
00053 #include "koprefs.h"
00054 #include "koglobals.h"
00055 
00056 #include "koeditorgeneralevent.h"
00057 #include "koeditorgeneralevent.moc"
00058 
00059 KOEditorGeneralEvent::KOEditorGeneralEvent(TQObject* parent,
00060                                            const char* name) :
00061   KOEditorGeneral( parent, name)
00062 {
00063   connect( this, TQT_SIGNAL( dateTimesChanged( const TQDateTime &, const TQDateTime & )),
00064            TQT_SLOT( setDuration() ) );
00065   connect( this, TQT_SIGNAL( dateTimesChanged( const TQDateTime &, const TQDateTime & )),
00066            TQT_SLOT( emitDateTimeStr() ));
00067 }
00068 
00069 KOEditorGeneralEvent::~KOEditorGeneralEvent()
00070 {
00071 }
00072 
00073 void KOEditorGeneralEvent::finishSetup()
00074 {
00075   TQWidget::setTabOrder( mSummaryEdit, mLocationEdit );
00076   TQWidget::setTabOrder( mLocationEdit, mStartDateEdit );
00077   TQWidget::setTabOrder( mStartDateEdit, mStartTimeEdit );
00078   TQWidget::setTabOrder( mStartTimeEdit, mEndDateEdit );
00079   TQWidget::setTabOrder( mEndDateEdit, mEndTimeEdit );
00080   TQWidget::setTabOrder( mEndTimeEdit, mAlldayEventCheckbox );
00081   TQWidget::setTabOrder( mAlldayEventCheckbox, mRecEditButton );
00082   TQWidget::setTabOrder( mRecEditButton, mAlarmButton );
00083   TQWidget::setTabOrder( mAlarmButton, mAlarmTimeEdit );
00084   TQWidget::setTabOrder( mAlarmTimeEdit, mAlarmIncrCombo );
00085   TQWidget::setTabOrder( mAlarmIncrCombo, mAlarmAdvancedButton );
00086   TQWidget::setTabOrder( mAlarmAdvancedButton, mFreeTimeCombo );
00087   TQWidget::setTabOrder( mFreeTimeCombo, mDescriptionEdit );
00088   TQWidget::setTabOrder( mDescriptionEdit, mCategoriesButton );
00089   TQWidget::setTabOrder( mCategoriesButton, mSecrecyCombo );
00090 
00091   mSummaryEdit->setFocus();
00092 }
00093 
00094 void KOEditorGeneralEvent::initTime(TQWidget *parent,TQBoxLayout *topLayout)
00095 {
00096   TQBoxLayout *timeLayout = new TQVBoxLayout(topLayout);
00097 
00098   TQGroupBox *timeGroupBox = new TQGroupBox(1,Qt::Horizontal,
00099                                           i18n("Date && Time"),parent);
00100   TQWhatsThis::add( timeGroupBox,
00101        i18n("Sets options related to the date and time of the "
00102             "event or to-do.") );
00103   timeLayout->addWidget(timeGroupBox);
00104 
00105   TQFrame *timeBoxFrame = new TQFrame(timeGroupBox);
00106 
00107   TQGridLayout *layoutTimeBox = new TQGridLayout( timeBoxFrame );
00108   layoutTimeBox->setSpacing(topLayout->spacing());
00109   layoutTimeBox->setColStretch( 3, 1 );
00110 
00111   mStartDateLabel = new TQLabel(i18n("&Start:"),timeBoxFrame);
00112   layoutTimeBox->addWidget(mStartDateLabel,0,0);
00113 
00114   mStartDateEdit = new KDateEdit(timeBoxFrame);
00115   layoutTimeBox->addWidget(mStartDateEdit,0,1);
00116   mStartDateLabel->setBuddy( mStartDateEdit );
00117 
00118   mStartTimeEdit = new KTimeEdit(timeBoxFrame);
00119   layoutTimeBox->addWidget(mStartTimeEdit,0,2);
00120 
00121   mEndDateLabel = new TQLabel(i18n("&End:"),timeBoxFrame);
00122   layoutTimeBox->addWidget(mEndDateLabel,1,0);
00123 
00124   mEndDateEdit = new KDateEdit(timeBoxFrame);
00125   layoutTimeBox->addWidget(mEndDateEdit,1,1);
00126   mEndDateLabel->setBuddy( mEndDateEdit );
00127 
00128   mEndTimeEdit = new KTimeEdit(timeBoxFrame);
00129   layoutTimeBox->addWidget(mEndTimeEdit,1,2);
00130 
00131   mAlldayEventCheckbox = new TQCheckBox(i18n("All-&day"),timeBoxFrame);
00132   layoutTimeBox->addWidget( mAlldayEventCheckbox, 0, 3 );
00133   connect(mAlldayEventCheckbox, TQT_SIGNAL(toggled(bool)),TQT_SLOT(associateTime(bool)));
00134 
00135   mDurationLabel = new TQLabel( timeBoxFrame );
00136   layoutTimeBox->addWidget( mDurationLabel, 1, 3 );
00137 
00138   // time widgets are checked if they contain a valid time
00139   connect(mStartTimeEdit, TQT_SIGNAL(timeChanged(TQTime)),
00140           this, TQT_SLOT(startTimeChanged(TQTime)));
00141   connect(mEndTimeEdit, TQT_SIGNAL(timeChanged(TQTime)),
00142           this, TQT_SLOT(endTimeChanged(TQTime)));
00143 
00144   // date widgets are checked if they contain a valid date
00145   connect(mStartDateEdit, TQT_SIGNAL(dateChanged(const TQDate&)),
00146           this, TQT_SLOT(startDateChanged(const TQDate&)));
00147   connect(mEndDateEdit, TQT_SIGNAL(dateChanged(const TQDate&)),
00148           this, TQT_SLOT(endDateChanged(const TQDate&)));
00149 
00150   TQLabel *label = new TQLabel( i18n( "Recurrence:" ), timeBoxFrame );
00151   layoutTimeBox->addWidget( label, 2, 0 );
00152   TQBoxLayout *recLayout = new TQHBoxLayout();
00153   layoutTimeBox->addMultiCellLayout( recLayout, 2, 2, 1, 4 );
00154   mRecEditButton = new TQPushButton( timeBoxFrame );
00155   mRecEditButton->setIconSet( KOGlobals::self()->smallIconSet( "recur", 16 ) );
00156   recLayout->addWidget( mRecEditButton );
00157   connect( mRecEditButton, TQT_SIGNAL(clicked()), TQT_SIGNAL(editRecurrence()) );
00158   mRecEditLabel = new TQLabel( TQString(), timeBoxFrame );
00159   recLayout->addWidget( mRecEditLabel );
00160   recLayout->addStretch( 1 );
00161 
00162   label = new TQLabel( i18n("Reminder:"), timeBoxFrame );
00163   layoutTimeBox->addWidget( label, 3, 0 );
00164   TQBoxLayout *alarmLineLayout = new TQHBoxLayout();
00165   layoutTimeBox->addMultiCellLayout( alarmLineLayout, 3, 3, 1, 4 );
00166   initAlarm( timeBoxFrame, alarmLineLayout );
00167   alarmLineLayout->addStretch( 1 );
00168 
00169   TQBoxLayout *secLayout = new TQHBoxLayout();
00170   layoutTimeBox->addLayout( secLayout, 0, 4 );
00171   initSecrecy( timeBoxFrame, secLayout );
00172 
00173   TQBoxLayout *classLayout = new TQHBoxLayout();
00174   layoutTimeBox->addLayout( classLayout, 1, 4 );
00175   initClass( timeBoxFrame, classLayout );
00176 }
00177 
00178 void KOEditorGeneralEvent::initClass(TQWidget *parent,TQBoxLayout *topLayout)
00179 {
00180   TQBoxLayout *classLayout = new TQHBoxLayout(topLayout);
00181 
00182   TQLabel *freeTimeLabel = new TQLabel(i18n("S&how time as:"),parent);
00183   TQString whatsThis = i18n("Sets how this time will appear on your Free/Busy "
00184                            "information.");
00185   TQWhatsThis::add( freeTimeLabel, whatsThis );
00186   classLayout->addWidget(freeTimeLabel);
00187 
00188   mFreeTimeCombo = new TQComboBox(false, parent);
00189   TQWhatsThis::add( mFreeTimeCombo, whatsThis );
00190   mFreeTimeCombo->insertItem(i18n("Busy"));
00191   mFreeTimeCombo->insertItem(i18n("Free"));
00192   classLayout->addWidget(mFreeTimeCombo);
00193   freeTimeLabel->setBuddy( mFreeTimeCombo );
00194 }
00195 
00196 void KOEditorGeneralEvent::initInvitationBar(TQWidget * parent, TQBoxLayout * layout)
00197 {
00198   TQBoxLayout *topLayout = new TQHBoxLayout( layout );
00199   mInvitationBar = new TQFrame( parent );
00200   mInvitationBar->setPaletteBackgroundColor( TDEGlobalSettings::alternateBackgroundColor() );
00201   topLayout->addWidget( mInvitationBar );
00202 
00203   TQBoxLayout *barLayout = new TQHBoxLayout( mInvitationBar );
00204   barLayout->setSpacing( layout->spacing() );
00205   TQLabel *label = new TQLabel( i18n("You have not yet definitely responded to this invitation." ), mInvitationBar );
00206   barLayout->addWidget( label );
00207   barLayout->addStretch( 1 );
00208   TQPushButton *button = new TQPushButton( i18n("Accept"), mInvitationBar );
00209   connect( button, TQT_SIGNAL(clicked()), TQT_SIGNAL(acceptInvitation()) );
00210   connect( button, TQT_SIGNAL(clicked()), mInvitationBar, TQT_SLOT(hide()) );
00211   barLayout->addWidget( button );
00212   button = new TQPushButton( i18n("Decline"), mInvitationBar );
00213   connect( button, TQT_SIGNAL(clicked()), TQT_SIGNAL(declineInvitation()) );
00214   connect( button, TQT_SIGNAL(clicked()), mInvitationBar, TQT_SLOT(hide()) );
00215   barLayout->addWidget( button );
00216 
00217   mInvitationBar->hide();
00218 }
00219 
00220 void KOEditorGeneralEvent::timeStuffDisable(bool disable)
00221 {
00222   mStartTimeEdit->setEnabled( !disable );
00223   mEndTimeEdit->setEnabled( !disable );
00224 
00225   setDuration();
00226   emitDateTimeStr();
00227 }
00228 
00229 void KOEditorGeneralEvent::associateTime(bool time)
00230 {
00231   timeStuffDisable(time);
00232   allDayChanged(time);
00233 }
00234 
00235 void KOEditorGeneralEvent::setDateTimes( const TQDateTime &start, const TQDateTime &end )
00236 {
00237 //  kdDebug(5850) << "KOEditorGeneralEvent::setDateTimes(): Start DateTime: " << start.toString() << endl;
00238 
00239   mStartDateEdit->setDate(start.date());
00240   // KTimeEdit seems to emit some signals when setTime() is called.
00241   mStartTimeEdit->blockSignals( true );
00242   mStartTimeEdit->setTime(start.time());
00243   mStartTimeEdit->blockSignals( false );
00244   mEndDateEdit->setDate(end.date());
00245   mEndTimeEdit->setTime(end.time());
00246 
00247   mCurrStartDateTime = start;
00248   mCurrEndDateTime = end;
00249 
00250   setDuration();
00251   emitDateTimeStr();
00252 }
00253 
00254 void KOEditorGeneralEvent::startTimeChanged( TQTime newtime )
00255 {
00256   kdDebug(5850) << "KOEditorGeneralEvent::startTimeChanged() " << TQString(newtime.toString()) << endl;
00257 
00258   int secsep = mCurrStartDateTime.secsTo(mCurrEndDateTime);
00259 
00260   mCurrStartDateTime.setTime(newtime);
00261 
00262   // adjust end time so that the event has the same duration as before.
00263   mCurrEndDateTime = mCurrStartDateTime.addSecs(secsep);
00264   mEndTimeEdit->setTime(mCurrEndDateTime.time());
00265   mEndDateEdit->setDate(mCurrEndDateTime.date());
00266 
00267   emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00268 }
00269 
00270 void KOEditorGeneralEvent::endTimeChanged( TQTime newtime )
00271 {
00272 //  kdDebug(5850) << "KOEditorGeneralEvent::endTimeChanged " << newtime.toString() << endl;
00273 
00274   TQDateTime newdt(mCurrEndDateTime.date(), newtime);
00275   mCurrEndDateTime = newdt;
00276 
00277   emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00278 }
00279 
00280 void KOEditorGeneralEvent::startDateChanged( const TQDate &newdate )
00281 {
00282   if ( !newdate.isValid() )
00283     return;
00284 
00285   int daysep = mCurrStartDateTime.daysTo(mCurrEndDateTime);
00286 
00287   mCurrStartDateTime.setDate(newdate);
00288 
00289   // adjust end date so that the event has the same duration as before
00290   mCurrEndDateTime.setDate(mCurrStartDateTime.date().addDays(daysep));
00291   mEndDateEdit->setDate(mCurrEndDateTime.date());
00292 
00293   emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00294 }
00295 
00296 void KOEditorGeneralEvent::endDateChanged( const TQDate &newdate )
00297 {
00298   if ( !newdate.isValid() )
00299     return;
00300 
00301   TQDateTime newdt(newdate, mCurrEndDateTime.time());
00302   mCurrEndDateTime = newdt;
00303 
00304   emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00305 }
00306 
00307 void KOEditorGeneralEvent::setDefaults( const TQDateTime &from,
00308                                         const TQDateTime &to, bool allDay)
00309 {
00310   KOEditorGeneral::setDefaults(allDay);
00311 
00312   mAlldayEventCheckbox->setChecked(allDay);
00313   timeStuffDisable(allDay);
00314 
00315   setDateTimes(from,to);
00316 }
00317 
00318 void KOEditorGeneralEvent::readEvent( Event *event, Calendar *calendar, const TQDate &date, bool tmpl )
00319 {
00320   TQString tmpStr;
00321 
00322   mAlldayEventCheckbox->setChecked(event->doesFloat());
00323   timeStuffDisable(event->doesFloat());
00324 
00325   if ( !tmpl ) {
00326     TQDateTime startDT = event->dtStart();
00327     TQDateTime endDT = event->dtEnd();
00328     if ( event->doesRecur() && date.isValid() ) {
00329       // Consider the active date when editing recurring Events.
00330       TQDateTime kdt( date, TQTime( 0, 0, 0 ) );
00331       const int eventLength = startDT.daysTo( endDT );
00332       kdt = kdt.addSecs( -1 );
00333       startDT.setDate( event->recurrence()->getNextDateTime( kdt ).date() );
00334       if ( event->hasEndDate() ) {
00335         endDT.setDate( startDT.addDays( eventLength ).date() );
00336       } else {
00337         if ( event->hasDuration() ) {
00338           endDT = startDT.addSecs( event->duration() );
00339         } else {
00340           endDT = startDT;
00341         }
00342       }
00343     }
00344     // the rest is for the events only
00345     setDateTimes( startDT, endDT );
00346   }
00347 
00348   switch( event->transparency() ) {
00349   case Event::Transparent:
00350     mFreeTimeCombo->setCurrentItem(1);
00351     break;
00352   case Event::Opaque:
00353     mFreeTimeCombo->setCurrentItem(0);
00354     break;
00355   }
00356 
00357   updateRecurrenceSummary( event );
00358 
00359   Attendee *me = event->attendeeByMails( KOPrefs::instance()->allEmails() );
00360   if ( event->attendeeCount() > 1 &&
00361        me && ( me->status() == Attendee::NeedsAction ||
00362        me->status() == Attendee::Tentative ||
00363        me->status() == Attendee::InProcess ) ) {
00364     mInvitationBar->show();
00365   } else {
00366     mInvitationBar->hide();
00367   }
00368 
00369   readIncidence(event, calendar);
00370 }
00371 
00372 void KOEditorGeneralEvent::writeEvent(Event *event)
00373 {
00374 //  kdDebug(5850) << "KOEditorGeneralEvent::writeEvent()" << endl;
00375 
00376   writeIncidence(event);
00377 
00378   TQDate tmpDate;
00379   TQTime tmpTime;
00380   TQDateTime tmpDT;
00381 
00382   // temp. until something better happens.
00383   TQString tmpStr;
00384 
00385   if (mAlldayEventCheckbox->isChecked()) {
00386     event->setFloats(true);
00387     // need to change this.
00388     tmpDate = mStartDateEdit->date();
00389     tmpTime.setHMS(0,0,0);
00390     tmpDT.setDate(tmpDate);
00391     tmpDT.setTime(tmpTime);
00392     event->setDtStart(tmpDT);
00393 
00394     tmpDate = mEndDateEdit->date();
00395     tmpTime.setHMS(0,0,0);
00396     tmpDT.setDate(tmpDate);
00397     tmpDT.setTime(tmpTime);
00398     event->setDtEnd(tmpDT);
00399   } else {
00400     event->setFloats(false);
00401 
00402     // set date/time end
00403     tmpDate = mEndDateEdit->date();
00404     tmpTime = mEndTimeEdit->getTime();
00405     tmpDT.setDate(tmpDate);
00406     tmpDT.setTime(tmpTime);
00407     event->setDtEnd(tmpDT);
00408 
00409     // set date/time start
00410     tmpDate = mStartDateEdit->date();
00411     tmpTime = mStartTimeEdit->getTime();
00412     tmpDT.setDate(tmpDate);
00413     tmpDT.setTime(tmpTime);
00414     event->setDtStart(tmpDT);
00415   } // check for float
00416 
00417   event->setTransparency(mFreeTimeCombo->currentItem() > 0
00418                          ? KCal::Event::Transparent
00419                          : KCal::Event::Opaque);
00420 
00421 //  kdDebug(5850) << "KOEditorGeneralEvent::writeEvent() done" << endl;
00422 }
00423 
00424 void KOEditorGeneralEvent::setDuration()
00425 {
00426   TQString tmpStr, catStr;
00427   int hourdiff, minutediff;
00428   // end<date is an accepted temporary state while typing, but don't show
00429   // any duration if this happens
00430   if(mCurrEndDateTime >= mCurrStartDateTime) {
00431 
00432     if (mAlldayEventCheckbox->isChecked()) {
00433       int daydiff = mCurrStartDateTime.date().daysTo(mCurrEndDateTime.date()) + 1;
00434       tmpStr = i18n("Duration: ");
00435       tmpStr.append(i18n("1 Day","%n Days",daydiff));
00436     } else {
00437       hourdiff = mCurrStartDateTime.date().daysTo(mCurrEndDateTime.date()) * 24;
00438       hourdiff += mCurrEndDateTime.time().hour() -
00439                   mCurrStartDateTime.time().hour();
00440       minutediff = mCurrEndDateTime.time().minute() -
00441                    mCurrStartDateTime.time().minute();
00442       // If minutediff is negative, "borrow" 60 minutes from hourdiff
00443       if (minutediff < 0 && hourdiff > 0) {
00444         hourdiff -= 1;
00445         minutediff += 60;
00446       }
00447       if (hourdiff || minutediff){
00448         tmpStr = i18n("Duration: ");
00449         if (hourdiff){
00450           catStr = i18n("1 hour","%n hours",hourdiff);
00451           tmpStr.append(catStr);
00452         }
00453         if (hourdiff && minutediff){
00454           tmpStr += i18n(", ");
00455         }
00456         if (minutediff){
00457           catStr = i18n("1 minute","%n minutes",minutediff);
00458           tmpStr += catStr;
00459         }
00460       } else tmpStr = "";
00461     }
00462   }
00463   mDurationLabel->setText(tmpStr);
00464   TQWhatsThis::add( mDurationLabel,
00465        i18n("Shows the duration of the event or to-do with the "
00466       "current start and end dates and times.") );
00467 }
00468 
00469 void KOEditorGeneralEvent::emitDateTimeStr()
00470 {
00471   TDELocale *l = TDEGlobal::locale();
00472 
00473   TQString from,to;
00474   if (mAlldayEventCheckbox->isChecked()) {
00475     from = l->formatDate(mCurrStartDateTime.date());
00476     to = l->formatDate(mCurrEndDateTime.date());
00477   } else {
00478     from = l->formatDateTime(mCurrStartDateTime);
00479     to = l->formatDateTime(mCurrEndDateTime);
00480   }
00481 
00482   TQString str = i18n("From: %1   To: %2   %3").arg(from).arg(to)
00483                 .arg(mDurationLabel->text());
00484 
00485   emit dateTimeStrChanged(str);
00486 }
00487 
00488 bool KOEditorGeneralEvent::validateInput()
00489 {
00490 //  kdDebug(5850) << "KOEditorGeneralEvent::validateInput()" << endl;
00491 
00492   if (!mAlldayEventCheckbox->isChecked()) {
00493     if (!mStartTimeEdit->inputIsValid()) {
00494       KMessageBox::sorry( 0,
00495           i18n("Please specify a valid start time, for example '%1'.")
00496           .arg( TDEGlobal::locale()->formatTime( TQTime::currentTime() ) ) );
00497       return false;
00498     }
00499 
00500     if (!mEndTimeEdit->inputIsValid()) {
00501       KMessageBox::sorry( 0,
00502           i18n("Please specify a valid end time, for example '%1'.")
00503           .arg( TDEGlobal::locale()->formatTime( TQTime::currentTime() ) ) );
00504       return false;
00505     }
00506   }
00507 
00508   if (!mStartDateEdit->date().isValid()) {
00509     KMessageBox::sorry( 0,
00510         i18n("Please specify a valid start date, for example '%1'.")
00511         .arg( TDEGlobal::locale()->formatDate( TQDate::currentDate() ) ) );
00512     return false;
00513   }
00514 
00515   if (!mEndDateEdit->date().isValid()) {
00516     KMessageBox::sorry( 0,
00517         i18n("Please specify a valid end date, for example '%1'.")
00518         .arg( TDEGlobal::locale()->formatDate( TQDate::currentDate() ) ) );
00519     return false;
00520   }
00521 
00522   TQDateTime startDt,endDt;
00523   startDt.setDate(mStartDateEdit->date());
00524   endDt.setDate(mEndDateEdit->date());
00525   if (!mAlldayEventCheckbox->isChecked()) {
00526     startDt.setTime(mStartTimeEdit->getTime());
00527     endDt.setTime(mEndTimeEdit->getTime());
00528   }
00529 
00530   if ( startDt > endDt ) {
00531     KMessageBox::sorry(
00532       0,
00533       i18n( "The event ends before it starts.\n"
00534             "Please correct dates and times." ) );
00535     return false;
00536   }
00537 
00538   return KOEditorGeneral::validateInput();
00539 }
00540 
00541 void KOEditorGeneralEvent::updateRecurrenceSummary( Event *event )
00542 {
00543   if ( event->doesRecur() ) {
00544     mRecEditLabel->setText( IncidenceFormatter::recurrenceString( event ) );
00545   } else {
00546     mRecEditLabel->setText( TQString() );
00547   }
00548 }