korganizer

koeditorgeneraltodo.cpp

00001 /*
00002     This file is part of KOrganizer.
00003     Copyright (c) 2000,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 Qt, and distribute the resulting executable,
00022     without including the source code for Qt in the source distribution.
00023 */
00024 
00025 #include <tqtooltip.h>
00026 #include <tqfiledialog.h>
00027 #include <tqlayout.h>
00028 #include <tqvbox.h>
00029 #include <tqbuttongroup.h>
00030 #include <tqvgroupbox.h>
00031 #include <tqwidgetstack.h>
00032 #include <tqdatetime.h>
00033 #include <tqcheckbox.h>
00034 #include <tqlabel.h>
00035 #include <tqspinbox.h>
00036 #include <tqpushbutton.h>
00037 #include <tqwhatsthis.h>
00038 
00039 #include <kglobal.h>
00040 #include <klocale.h>
00041 #include <kmessagebox.h>
00042 #include <kdebug.h>
00043 #include <kstandarddirs.h>
00044 #include <kfiledialog.h>
00045 #include <ktextedit.h>
00046 
00047 #include <libkcal/incidenceformatter.h>
00048 #include <libkcal/todo.h>
00049 
00050 #include <libkdepim/kdateedit.h>
00051 
00052 #include "koprefs.h"
00053 #include "koglobals.h"
00054 #include "ktimeedit.h"
00055 
00056 #include "koeditorgeneraltodo.h"
00057 #include "koeditorgeneraltodo.moc"
00058 
00059 KOEditorGeneralTodo::KOEditorGeneralTodo( TQObject *parent, const char *name )
00060   : KOEditorGeneral( parent, name )
00061 {
00062   setType( "Todo" );
00063 }
00064 
00065 KOEditorGeneralTodo::~KOEditorGeneralTodo()
00066 {
00067 }
00068 
00069 void KOEditorGeneralTodo::finishSetup()
00070 {
00071   TQWidget::setTabOrder( mSummaryEdit, mLocationEdit );
00072   TQWidget::setTabOrder( mLocationEdit, mStartCheck );
00073   TQWidget::setTabOrder( mStartCheck, mStartDateEdit );
00074   TQWidget::setTabOrder( mStartDateEdit, mStartTimeEdit );
00075   TQWidget::setTabOrder( mStartTimeEdit, mDueCheck );
00076   TQWidget::setTabOrder( mDueCheck, mDueDateEdit );
00077   TQWidget::setTabOrder( mDueDateEdit, mDueTimeEdit );
00078   TQWidget::setTabOrder( mDueTimeEdit, mTimeButton );
00079   TQWidget::setTabOrder( mTimeButton, mRecEditButton );
00080   TQWidget::setTabOrder( mRecEditButton, mCompletedToggle );
00081   TQWidget::setTabOrder( mCompletedToggle, mCompletedCombo );
00082   TQWidget::setTabOrder( mCompletedCombo, mPriorityCombo );
00083   TQWidget::setTabOrder( mPriorityCombo, mAlarmButton );
00084   TQWidget::setTabOrder( mAlarmButton, mAlarmTimeEdit );
00085   TQWidget::setTabOrder( mAlarmTimeEdit, mAlarmIncrCombo );
00086   TQWidget::setTabOrder( mAlarmIncrCombo, mAlarmAdvancedButton );
00087   TQWidget::setTabOrder( mAlarmAdvancedButton, mDescriptionEdit );
00088   TQWidget::setTabOrder( mDescriptionEdit, mCategoriesButton );
00089   TQWidget::setTabOrder( mCategoriesButton, mSecrecyCombo );
00090 
00091   mSummaryEdit->setFocus();
00092 }
00093 
00094 void KOEditorGeneralTodo::initTime(TQWidget *parent,TQBoxLayout *topLayout)
00095 {
00096   kdDebug(5850) << k_funcinfo << endl;
00097   TQBoxLayout *timeLayout = new TQVBoxLayout(topLayout);
00098 
00099   TQGroupBox *timeGroupBox = new TQGroupBox(1,TQGroupBox::Horizontal,
00100                                           i18n("Date && Time"),parent);
00101   timeLayout->addWidget(timeGroupBox);
00102 
00103   TQFrame *timeBoxFrame = new TQFrame(timeGroupBox);
00104   TQWhatsThis::add( timeBoxFrame,
00105                    i18n("Sets options for due and start dates and times "
00106                         "for this to-do.") );
00107 
00108   TQGridLayout *layoutTimeBox = new TQGridLayout(timeBoxFrame,1,1);
00109   layoutTimeBox->setSpacing(topLayout->spacing());
00110 
00111 
00112   TQString whatsThis = i18n("Sets the start date for this to-do");
00113   mStartCheck = new TQCheckBox(i18n("Sta&rt:"),timeBoxFrame);
00114   TQWhatsThis::add( mStartCheck, whatsThis );
00115   layoutTimeBox->addWidget(mStartCheck,0,0);
00116   connect(mStartCheck,TQT_SIGNAL(toggled(bool)),TQT_SLOT(enableStartEdit(bool)));
00117   connect(mStartCheck,TQT_SIGNAL(toggled(bool)),TQT_SLOT(startDateModified()));
00118 
00119   mStartDateEdit = new KDateEdit(timeBoxFrame);
00120   TQWhatsThis::add( mStartDateEdit, whatsThis );
00121   layoutTimeBox->addWidget(mStartDateEdit,0,1);
00122   connect(mStartDateEdit,TQT_SIGNAL(dateChanged(const TQDate&)),TQT_SLOT(startDateModified()));
00123 
00124   mStartTimeEdit = new KTimeEdit(timeBoxFrame);
00125   TQWhatsThis::add( mStartTimeEdit,
00126                    i18n("Sets the start time for this to-do.") );
00127   layoutTimeBox->addWidget(mStartTimeEdit,0,2);
00128   connect(mStartTimeEdit,TQT_SIGNAL(timeChanged(TQTime)),TQT_SLOT(startDateModified()));
00129 
00130   whatsThis = i18n("Sets the due date for this to-do.");
00131   mDueCheck = new TQCheckBox(i18n("&Due:"),timeBoxFrame);
00132   TQWhatsThis::add( mDueCheck, whatsThis );
00133   layoutTimeBox->addWidget(mDueCheck,1,0);
00134   connect(mDueCheck,TQT_SIGNAL(toggled(bool)),TQT_SLOT(enableDueEdit(bool)));
00135   connect(mDueCheck,TQT_SIGNAL(toggled(bool)),TQT_SIGNAL(dueDateEditToggle(bool)));
00136   connect(mDueCheck,TQT_SIGNAL(toggled(bool)),TQT_SLOT(dateChanged()));
00137 
00138   mDueDateEdit = new KDateEdit(timeBoxFrame);
00139   TQWhatsThis::add( mDueDateEdit, whatsThis );
00140   layoutTimeBox->addWidget(mDueDateEdit,1,1);
00141   connect(mDueDateEdit,TQT_SIGNAL(dateChanged(const TQDate&)),TQT_SLOT(dateChanged()));
00142 
00143   mDueTimeEdit = new KTimeEdit(timeBoxFrame);
00144   TQWhatsThis::add( mDueTimeEdit,
00145                    i18n("Sets the due time for this to-do.") );
00146   layoutTimeBox->addWidget(mDueTimeEdit,1,2);
00147   connect(mDueTimeEdit,TQT_SIGNAL(timeChanged( TQTime )),TQT_SLOT(dateChanged()));
00148 
00149   mTimeButton = new TQCheckBox(i18n("Ti&me associated"),timeBoxFrame);
00150   TQWhatsThis::add( mTimeButton,
00151                    i18n("Sets whether or not this to-do's start and due dates "
00152                         "have times associated with them.") );
00153   layoutTimeBox->addWidget( mTimeButton, 0, 3 );
00154   connect(mTimeButton,TQT_SIGNAL(toggled(bool)),TQT_SLOT(enableTimeEdits(bool)));
00155   connect(mTimeButton,TQT_SIGNAL(toggled(bool)),TQT_SLOT(dateChanged()));
00156 
00157   TQLabel *label = new TQLabel( i18n( "Recurrence:" ), timeBoxFrame );
00158   layoutTimeBox->addWidget( label, 3, 0 );
00159   TQBoxLayout *recLayout = new TQHBoxLayout();
00160   layoutTimeBox->addMultiCellLayout( recLayout, 3, 3, 1, 4 );
00161   mRecEditButton = new TQPushButton( timeBoxFrame );
00162   mRecEditButton->setIconSet( KOGlobals::self()->smallIconSet( "recur", 16 ) );
00163   recLayout->addWidget( mRecEditButton );
00164   connect( mRecEditButton, TQT_SIGNAL(clicked()), TQT_SIGNAL(editRecurrence()) );
00165   mRecEditLabel = new TQLabel( TQString(), timeBoxFrame );
00166   recLayout->addWidget( mRecEditLabel );
00167   recLayout->addStretch( 1 );
00168 
00169   label = new TQLabel( i18n("Reminder:"), timeBoxFrame );
00170   layoutTimeBox->addWidget( label, 4, 0 );
00171   TQBoxLayout *alarmLineLayout = new TQHBoxLayout();
00172   layoutTimeBox->addMultiCellLayout( alarmLineLayout, 4, 4, 1, 4 );
00173   initAlarm( timeBoxFrame, alarmLineLayout );
00174   alarmLineLayout->addStretch( 1 );
00175 
00176   // some more layouting
00177   layoutTimeBox->setColStretch( 3, 1 );
00178 
00179   TQBoxLayout *secLayout = new TQHBoxLayout();
00180   layoutTimeBox->addLayout( secLayout, 0, 4 );
00181   initSecrecy( timeBoxFrame, secLayout );
00182 }
00183 
00184 
00185 void KOEditorGeneralTodo::initCompletion( TQWidget *parent, TQBoxLayout *topLayout )
00186 {
00187   TQHBoxLayout *completionLayout = new TQHBoxLayout( topLayout );
00188 
00189   TQLabel *label = new TQLabel( i18n( "&Completed:" ), parent );
00190   completionLayout->addWidget( label );
00191 
00192   mCompletedToggle = new TQCheckBox( parent );
00193   TQToolTip::add( mCompletedToggle,
00194                  i18n( "Toggle between 0% and 100% complete" ) );
00195   TQWhatsThis::add( mCompletedToggle,
00196                    i18n( "Click this checkbox to toggle the completed percentage of the to-do "
00197                          "between 0% or 100%" ) );
00198   connect( mCompletedToggle, TQT_SIGNAL(clicked()), TQT_SLOT(completedChanged()) );
00199   completionLayout->addWidget( mCompletedToggle );
00200   label->setBuddy( mCompletedToggle );
00201 
00202   mCompletedCombo = new TQComboBox( parent );
00203   TQToolTip::add( mCompletedCombo,
00204                  i18n( "Select the completed percentage" ) );
00205   TQWhatsThis::add( mCompletedCombo,
00206                    i18n( "Use this combobox to set the completion percentage of the to-do." ) );
00207   for ( int i = 0; i <= 100; i+=10 ) {
00208     // xgettext:no-c-format
00209     TQString label = i18n( "Percent complete", "%1 %" ).arg( i );
00210     mCompletedCombo->insertItem( label );
00211   }
00212   connect( mCompletedCombo, TQT_SIGNAL(activated(int)), TQT_SLOT(completedChanged(int)) );
00213   completionLayout->addWidget( mCompletedCombo );
00214 
00215   mCompletedLabel = new TQLabel( i18n( "completed on", "on" ), parent );
00216   mCompletedLabel->hide();
00217   completionLayout->addWidget( mCompletedLabel );
00218 
00219   mCompletionDateEdit = new KDateEdit( parent );
00220   mCompletionDateEdit->hide();
00221   completionLayout->addWidget( mCompletionDateEdit );
00222 
00223   mCompletionTimeEdit = new KTimeEdit( parent, TQTime() );
00224   mCompletionTimeEdit->hide();
00225   completionLayout->addWidget( mCompletionTimeEdit );
00226 }
00227 
00228 void KOEditorGeneralTodo::initPriority(TQWidget *parent, TQBoxLayout *topLayout)
00229 {
00230   TQLabel *priorityLabel = new TQLabel( i18n( "&Priority:" ), parent );
00231   topLayout->addWidget( priorityLabel );
00232 
00233   mPriorityCombo = new TQComboBox( parent );
00234   TQToolTip::add( mPriorityCombo,
00235                  i18n( "Set the priority of the to-do" ) );
00236   TQWhatsThis::add( mPriorityCombo,
00237                    i18n( "Sets the priority of this to-do on a scale from one to nine, "
00238                          "with one being the highest priority, five being a medium priority, "
00239                          "and nine being the lowest. In programs that have a different scale, "
00240                          "the numbers will be adjusted to match the appropriate scale." ) );
00241   mPriorityCombo->insertItem( i18n( "unspecified" ) );
00242   mPriorityCombo->insertItem( i18n( "1 (highest)" ) );
00243   mPriorityCombo->insertItem( i18n( "2" ) );
00244   mPriorityCombo->insertItem( i18n( "3" ) );
00245   mPriorityCombo->insertItem( i18n( "4" ) );
00246   mPriorityCombo->insertItem( i18n( "5 (medium)" ) );
00247   mPriorityCombo->insertItem( i18n( "6" ) );
00248   mPriorityCombo->insertItem( i18n( "7" ) );
00249   mPriorityCombo->insertItem( i18n( "8" ) );
00250   mPriorityCombo->insertItem( i18n( "9 (lowest)" ) );
00251   topLayout->addWidget( mPriorityCombo );
00252   priorityLabel->setBuddy( mPriorityCombo );
00253 }
00254 
00255 void KOEditorGeneralTodo::initStatus(TQWidget *parent,TQBoxLayout *topLayout)
00256 {
00257   TQBoxLayout *statusLayout = new TQHBoxLayout(topLayout);
00258 
00259   initCompletion( parent, statusLayout );
00260 
00261   statusLayout->addStretch( 1 );
00262 
00263   initPriority( parent, statusLayout );
00264 }
00265 
00266 void KOEditorGeneralTodo::setDefaults( const TQDateTime &due, bool allDay )
00267 {
00268   kdDebug(5850) << k_funcinfo << due <<endl;
00269   KOEditorGeneral::setDefaults(allDay);
00270 
00271   mTimeButton->setChecked( !allDay );
00272   mTimeButton->setEnabled( mTimeButton->isChecked() /* i.e. !allDay */ );
00273 
00274   enableTimeEdits( !allDay );
00275 
00276   mDueCheck->setChecked( due.isValid() );
00277   enableDueEdit( due.isValid() );
00278 
00279   mStartCheck->setChecked(false);
00280   enableStartEdit(false);
00281 
00282   if ( due.isValid() ) {
00283     mDueDateEdit->setDate( due.date() );
00284     mDueTimeEdit->setTime( due.time() );
00285   } else {
00286     // Make it due tomorrow.
00287     mDueDateEdit->setDate( TQDate::currentDate().addDays(1) );
00288     mDueTimeEdit->setTime( TQTime::currentTime() );
00289   }
00290 
00291   if ( !due.isValid() || (TQDateTime::currentDateTime() < due) ) {
00292     mStartDateEdit->setDate( TQDate::currentDate() );
00293     mStartTimeEdit->setTime( TQTime::currentTime() );
00294   } else {
00295     mStartDateEdit->setDate( due.date().addDays( -1 ) );
00296     mStartTimeEdit->setTime( due.time() );
00297   }
00298   mStartDateModified = false;
00299 
00300   mPriorityCombo->setCurrentItem( 5 );
00301 
00302   mCompletedToggle->setChecked( false );
00303   mCompletedCombo->setCurrentItem( 0 );
00304 }
00305 
00306 void KOEditorGeneralTodo::readTodo(Todo *todo, Calendar *calendar, const TQDate &date )
00307 {
00308   KOEditorGeneral::readIncidence(todo, calendar);
00309 
00310   TQDateTime dueDT;
00311 
00312   if (todo->hasDueDate()) {
00313     dueDT = todo->dtDue();
00314     if ( todo->doesRecur() && date.isValid() ) {
00315       TQDateTime dt( date, TQTime( 0, 0, 0 ) );
00316       dt = dt.addSecs( -1 );
00317       dueDT.setDate( todo->recurrence()->getNextDateTime( dt ).date() );
00318     }
00319     mDueDateEdit->setDate(dueDT.date());
00320     mDueTimeEdit->setTime(dueDT.time());
00321     mDueCheck->setChecked(true);
00322   } else {
00323     mDueDateEdit->setEnabled(false);
00324     mDueTimeEdit->setEnabled(false);
00325     mDueDateEdit->setDate(TQDate::currentDate());
00326     mDueTimeEdit->setTime(TQTime::currentTime());
00327     mDueCheck->setChecked(false);
00328   }
00329 
00330   if (todo->hasStartDate()) {
00331     TQDateTime startDT = todo->dtStart();
00332     if ( todo->doesRecur() && date.isValid() && todo->hasDueDate() ) {
00333       int days = todo->dtStart( true ).daysTo( todo->dtDue( true ) );
00334       startDT.setDate( date.addDays( -days ) );
00335     }
00336     mStartDateEdit->setDate(startDT.date());
00337     mStartTimeEdit->setTime(startDT.time());
00338     mStartCheck->setChecked(true);
00339   } else {
00340     mStartDateEdit->setEnabled(false);
00341     mStartTimeEdit->setEnabled(false);
00342     mStartDateEdit->setDate(TQDate::currentDate());
00343     mStartTimeEdit->setTime(TQTime::currentTime());
00344     mStartCheck->setChecked(false);
00345   }
00346 
00347   mTimeButton->setChecked( !todo->doesFloat() );
00348 
00349   updateRecurrenceSummary( todo );
00350 
00351   mAlreadyComplete = false;
00352   mCompletedCombo->setCurrentItem( todo->percentComplete() / 10 );
00353   if ( todo->isCompleted() && todo->hasCompletedDate() ) {
00354     mCompletedDateTime = todo->completed();
00355     mCompletedToggle->setChecked( true );
00356     mAlreadyComplete = true;
00357   }
00358   setCompletedDate();
00359 
00360   mPriorityCombo->setCurrentItem( todo->priority() );
00361   mStartDateModified = false;
00362 }
00363 
00364 void KOEditorGeneralTodo::writeTodo(Todo *todo)
00365 {
00366   KOEditorGeneral::writeIncidence(todo);
00367 
00368   // temp. until something better happens.
00369   TQString tmpStr;
00370 
00371   todo->setHasDueDate(mDueCheck->isChecked());
00372   todo->setHasStartDate(mStartCheck->isChecked());
00373 
00374   TQDate tmpSDate, tmpDDate;
00375   TQTime tmpSTime, tmpDTime;
00376   TQDateTime tmpStartDT, tmpDueDT;
00377   if ( mTimeButton->isChecked() ) {
00378     todo->setFloats(false);
00379 
00380     // set due date/time
00381     tmpDDate = mDueDateEdit->date();
00382     tmpDTime = mDueTimeEdit->getTime();
00383     tmpDueDT.setDate(tmpDDate);
00384     tmpDueDT.setTime(tmpDTime);
00385 
00386     // set start date/time
00387     if ( mStartCheck->isChecked() ) {
00388       tmpSDate = mStartDateEdit->date();
00389       tmpSTime = mStartTimeEdit->getTime();
00390       tmpStartDT.setDate(tmpSDate);
00391       tmpStartDT.setTime(tmpSTime);
00392     } else {
00393       tmpStartDT = tmpDueDT;
00394     }
00395   } else {
00396     todo->setFloats(true);
00397 
00398     // need to change this.
00399     tmpDDate = mDueDateEdit->date();
00400     tmpDTime.setHMS(0,0,0);
00401     tmpDueDT.setDate(tmpDDate);
00402     tmpDueDT.setTime(tmpDTime);
00403 
00404     if ( mStartCheck->isChecked() ) {
00405       tmpSDate = mStartDateEdit->date();
00406       tmpSTime.setHMS(0,0,0);
00407       tmpStartDT.setDate(tmpSDate);
00408       tmpStartDT.setTime(tmpSTime);
00409     } else {
00410       tmpStartDT = tmpDueDT;
00411     }
00412   }
00413 
00414   // TODO: Don't use the due date for the recurrence, but the start date (cf. rfc 2445)
00415   if ( todo->doesRecur() && !mStartDateModified ) {
00416     todo->setDtDue( tmpDueDT );
00417   } else {
00418     todo->setDtDue( tmpDueDT, true );
00419     todo->setDtStart( tmpStartDT );
00420     todo->setDtRecurrence( tmpDueDT );
00421   }
00422 
00423   todo->setPriority( mPriorityCombo->currentItem() );
00424 
00425   // set completion state
00426   todo->setPercentComplete( mCompletedCombo->currentItem() * 10 );
00427 
00428   if (mCompletedCombo->currentItem() == 10 && mCompletedDateTime.isValid()) {
00429     TQDateTime completed( mCompletionDateEdit->date(),
00430                          mCompletionTimeEdit->getTime() );
00431     int difference = mCompletedDateTime.secsTo( completed );
00432     if ( (difference < 60) && (difference > -60) &&
00433          (completed.time().minute() == mCompletedDateTime.time().minute() ) ) {
00434       // completion time wasn't changed substantially (only the seconds
00435       // truncated, but that's an effect done by KTimeEdit automatically).
00436       completed = mCompletedDateTime;
00437     }
00438     todo->setCompleted( completed );
00439   }
00440 }
00441 
00442 void KOEditorGeneralTodo::enableDueEdit(bool enable)
00443 {
00444   mDueDateEdit->setEnabled( enable );
00445 
00446   if(mDueCheck->isChecked() || mStartCheck->isChecked()) {
00447     mTimeButton->setEnabled(true);
00448   } else {
00449     mTimeButton->setEnabled(false);
00450   }
00451 
00452   if (enable) {
00453     mDueTimeEdit->setEnabled( mTimeButton->isChecked() );
00454   } else {
00455     mDueTimeEdit->setEnabled( false );
00456   }
00457 }
00458 
00459 void KOEditorGeneralTodo::enableStartEdit( bool enable )
00460 {
00461   mStartDateEdit->setEnabled( enable );
00462 
00463   if(mDueCheck->isChecked() || mStartCheck->isChecked()) {
00464     mTimeButton->setEnabled(true);
00465   }
00466   else {
00467     mTimeButton->setEnabled(false);
00468     mTimeButton->setChecked(false);
00469   }
00470 
00471   if (enable) {
00472     mStartTimeEdit->setEnabled( mTimeButton->isChecked() );
00473   } else {
00474     mStartTimeEdit->setEnabled( false );
00475   }
00476 }
00477 
00478 void KOEditorGeneralTodo::enableTimeEdits(bool enable)
00479 {
00480   if(mStartCheck->isChecked()) {
00481     mStartTimeEdit->setEnabled( enable );
00482   }
00483   if(mDueCheck->isChecked()) {
00484     mDueTimeEdit->setEnabled( enable );
00485   }
00486 }
00487 
00488 bool KOEditorGeneralTodo::validateInput()
00489 {
00490   if (mDueCheck->isChecked()) {
00491     if (!mDueDateEdit->date().isValid()) {
00492       KMessageBox::sorry(0,i18n("Please specify a valid due date."));
00493       return false;
00494     }
00495     if (mTimeButton->isChecked()) {
00496       if (!mDueTimeEdit->inputIsValid()) {
00497         KMessageBox::sorry(0,i18n("Please specify a valid due time."));
00498         return false;
00499       }
00500     }
00501   }
00502 
00503   if (mStartCheck->isChecked()) {
00504     if (!mStartDateEdit->date().isValid()) {
00505       KMessageBox::sorry(0,i18n("Please specify a valid start date."));
00506       return false;
00507     }
00508     if (mTimeButton->isChecked()) {
00509       if (!mStartTimeEdit->inputIsValid()) {
00510         KMessageBox::sorry(0,i18n("Please specify a valid start time."));
00511         return false;
00512       }
00513     }
00514   }
00515 
00516   if (mStartCheck->isChecked() && mDueCheck->isChecked()) {
00517     TQDateTime startDate;
00518     TQDateTime dueDate;
00519     startDate.setDate(mStartDateEdit->date());
00520     dueDate.setDate(mDueDateEdit->date());
00521     if (mTimeButton->isChecked()) {
00522       startDate.setTime(mStartTimeEdit->getTime());
00523       dueDate.setTime(mDueTimeEdit->getTime());
00524     }
00525     if (startDate > dueDate) {
00526       KMessageBox::sorry(0,
00527                          i18n("The start date cannot be after the due date."));
00528       return false;
00529     }
00530   }
00531 
00532   return KOEditorGeneral::validateInput();
00533 }
00534 
00535 void KOEditorGeneralTodo::updateRecurrenceSummary( Todo *todo )
00536 {
00537   if ( todo->doesRecur() ) {
00538     mRecEditLabel->setText( IncidenceFormatter::recurrenceString( todo ) );
00539   } else {
00540     mRecEditLabel->setText( TQString() );
00541   }
00542 }
00543 
00544 void KOEditorGeneralTodo::completedChanged( int index )
00545 {
00546   if ( index == 10 ) {
00547     mCompletedToggle->setChecked( true );
00548     mCompletedDateTime = TQDateTime::currentDateTime();
00549   } else {
00550     mCompletedToggle->setChecked( false );
00551   }
00552   setCompletedDate();
00553 }
00554 
00555 void KOEditorGeneralTodo::completedChanged()
00556 {
00557   if ( mCompletedToggle->isChecked() ) {
00558     mCompletedCombo->setCurrentItem( 10 );
00559     mCompletedDateTime = TQDateTime::currentDateTime();
00560   } else {
00561     mCompletedCombo->setCurrentItem( 0 );
00562   }
00563   setCompletedDate();
00564 }
00565 
00566 void KOEditorGeneralTodo::dateChanged()
00567 {
00568   KLocale *l = KGlobal::locale();
00569   TQString dateTimeStr = "";
00570 
00571   if ( mStartCheck->isChecked() ) {
00572     dateTimeStr += i18n("Start: %1").arg(
00573                                      l->formatDate( mStartDateEdit->date() ) );
00574     if ( mTimeButton->isChecked() )
00575       dateTimeStr += TQString(" %1").arg(
00576                                    l->formatTime( mStartTimeEdit->getTime() ) );
00577   }
00578 
00579   if ( mDueCheck->isChecked() ) {
00580     dateTimeStr += i18n("   Due: %1").arg(
00581                                       l->formatDate( mDueDateEdit->date() ) );
00582     if ( mTimeButton->isChecked() )
00583       dateTimeStr += TQString(" %1").arg(
00584                                     l->formatTime( mDueTimeEdit->getTime() ) );
00585   }
00586 
00587   emit dateTimeStrChanged( dateTimeStr );
00588   TQDateTime endDt( mDueDateEdit->date(), mDueTimeEdit->getTime() );
00589   emit signalDateTimeChanged( endDt, endDt );
00590 }
00591 
00592 void KOEditorGeneralTodo::startDateModified()
00593 {
00594   mStartDateModified = true;
00595   dateChanged();
00596 }
00597 
00598 void KOEditorGeneralTodo::setCompletedDate()
00599 {
00600   if ( mCompletedCombo->currentItem() == 10 && mCompletedDateTime.isValid() ) {
00601     mCompletedLabel->show();
00602     mCompletionDateEdit->show();
00603     mCompletionTimeEdit->show();
00604     mCompletionDateEdit->setDate( mCompletedDateTime.date() );
00605     mCompletionTimeEdit->setTime( mCompletedDateTime.time() );
00606   } else {
00607     mCompletedLabel->hide();
00608     mCompletionDateEdit->hide();
00609     mCompletionTimeEdit->hide();
00610   }
00611 }
00612 
00613 void KOEditorGeneralTodo::modified (Todo* todo, KOGlobals::HowChanged modification)
00614 {
00615   switch (modification) {
00616   case KOGlobals::PRIORITY_MODIFIED:
00617     mPriorityCombo->setCurrentItem( todo->priority() );
00618     break;
00619   case KOGlobals::COMPLETION_MODIFIED:
00620     mCompletedCombo->setCurrentItem(todo->percentComplete() / 10);
00621     if (todo->isCompleted() && todo->hasCompletedDate()) {
00622       mCompletedDateTime = todo->completed();
00623       mCompletedToggle->setChecked( true );
00624     }
00625     setCompletedDate();
00626     break;
00627   case KOGlobals::CATEGORY_MODIFIED:
00628     setCategories( todo->categories() );
00629     break;
00630   case KOGlobals::UNKNOWN_MODIFIED: // fall through
00631   default:
00632     readTodo( todo, 0, TQDate() );
00633     break;
00634   }
00635 }