00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qtooltip.h>
00025 #include <qfiledialog.h>
00026 #include <qlayout.h>
00027 #include <qvbox.h>
00028 #include <qbuttongroup.h>
00029 #include <qvgroupbox.h>
00030 #include <qwidgetstack.h>
00031 #include <qdatetime.h>
00032 #include <qcheckbox.h>
00033 #include <qpushbutton.h>
00034 #include <qlabel.h>
00035
00036 #include <kglobal.h>
00037 #include <klocale.h>
00038 #include <kiconloader.h>
00039 #include <kmessagebox.h>
00040 #include <kdebug.h>
00041 #include <krestrictedline.h>
00042 #include <kstandarddirs.h>
00043 #include <kfiledialog.h>
00044 #include <ktextedit.h>
00045
00046 #include <libkcal/todo.h>
00047
00048 #include <libkdepim/kdateedit.h>
00049
00050 #include "koprefs.h"
00051 #include "koglobals.h"
00052 #include "ktimeedit.h"
00053
00054 #include "koeditorgeneraltodo.h"
00055 #include "koeditorgeneraltodo.moc"
00056
00057 KOEditorGeneralTodo::KOEditorGeneralTodo(QObject* parent,
00058 const char* name)
00059 : KOEditorGeneral( parent, name)
00060 {
00061 }
00062
00063 KOEditorGeneralTodo::~KOEditorGeneralTodo()
00064 {
00065 }
00066
00067 void KOEditorGeneralTodo::finishSetup()
00068 {
00069 QWidget::setTabOrder( mSummaryEdit, mLocationEdit );
00070 QWidget::setTabOrder( mLocationEdit, mDueCheck );
00071 QWidget::setTabOrder( mDueCheck, mDueDateEdit );
00072 QWidget::setTabOrder( mDueDateEdit, mDueTimeEdit );
00073 QWidget::setTabOrder( mDueTimeEdit, mStartCheck );
00074 QWidget::setTabOrder( mStartCheck, mStartDateEdit );
00075 QWidget::setTabOrder( mStartDateEdit, mStartTimeEdit );
00076 QWidget::setTabOrder( mStartTimeEdit, mTimeButton );
00077 QWidget::setTabOrder( mTimeButton, mCompletedCombo );
00078 QWidget::setTabOrder( mCompletedCombo, mPriorityCombo );
00079 QWidget::setTabOrder( mPriorityCombo, mAlarmButton );
00080 QWidget::setTabOrder( mAlarmButton, mAlarmTimeEdit );
00081 QWidget::setTabOrder( mAlarmTimeEdit, mAlarmIncrCombo );
00082 QWidget::setTabOrder( mAlarmIncrCombo, mAlarmSoundButton );
00083 QWidget::setTabOrder( mAlarmSoundButton, mAlarmProgramButton );
00084 QWidget::setTabOrder( mAlarmProgramButton, mDescriptionEdit );
00085 QWidget::setTabOrder( mDescriptionEdit, mCategoriesButton );
00086 QWidget::setTabOrder( mCategoriesButton, mSecrecyCombo );
00087
00088
00089 mSummaryEdit->setFocus();
00090 }
00091
00092 void KOEditorGeneralTodo::initTime(QWidget *parent,QBoxLayout *topLayout)
00093 {
00094 QBoxLayout *timeLayout = new QVBoxLayout(topLayout);
00095
00096 QGroupBox *timeGroupBox = new QGroupBox(1,QGroupBox::Horizontal,
00097 i18n("Date && Time"),parent);
00098 timeLayout->addWidget(timeGroupBox);
00099
00100 QFrame *timeBoxFrame = new QFrame(timeGroupBox);
00101
00102 QGridLayout *layoutTimeBox = new QGridLayout(timeBoxFrame,1,1);
00103 layoutTimeBox->setSpacing(topLayout->spacing());
00104
00105
00106 mDueCheck = new QCheckBox(i18n("&Due:"),timeBoxFrame);
00107 layoutTimeBox->addWidget(mDueCheck,0,0);
00108 connect(mDueCheck,SIGNAL(toggled(bool)),SLOT(enableDueEdit(bool)));
00109 connect(mDueCheck,SIGNAL(toggled(bool)),SLOT(showAlarm()));
00110 connect(mDueCheck,SIGNAL(toggled(bool)),SIGNAL(dueDateEditToggle(bool)));
00111 connect(mDueCheck,SIGNAL(toggled(bool)),SLOT(dateChanged()));
00112
00113 mDueDateEdit = new KDateEdit(timeBoxFrame);
00114 layoutTimeBox->addWidget(mDueDateEdit,0,1);
00115 connect(mDueDateEdit,SIGNAL(dateChanged(QDate)),SLOT(dateChanged()));
00116
00117 mDueTimeEdit = new KTimeEdit(timeBoxFrame);
00118 layoutTimeBox->addWidget(mDueTimeEdit,0,2);
00119 connect(mDueTimeEdit,SIGNAL(timeChanged( QTime )),SLOT(dateChanged()));
00120
00121 mStartCheck = new QCheckBox(i18n("Sta&rt:"),timeBoxFrame);
00122 layoutTimeBox->addWidget(mStartCheck,1,0);
00123 connect(mStartCheck,SIGNAL(toggled(bool)),SLOT(enableStartEdit(bool)));
00124 connect(mStartCheck,SIGNAL(toggled(bool)),SLOT(startDateModified()));
00125
00126 mStartDateEdit = new KDateEdit(timeBoxFrame);
00127 layoutTimeBox->addWidget(mStartDateEdit,1,1);
00128 connect(mStartDateEdit,SIGNAL(dateChanged(QDate)),SLOT(startDateModified()));
00129
00130 mStartTimeEdit = new KTimeEdit(timeBoxFrame);
00131 layoutTimeBox->addWidget(mStartTimeEdit,1,2);
00132 connect(mStartTimeEdit,SIGNAL(timeChanged(QTime)),SLOT(startDateModified()));
00133
00134 mTimeButton = new QCheckBox(i18n("Ti&me associated"),timeBoxFrame);
00135 layoutTimeBox->addMultiCellWidget(mTimeButton,2,2,0,2);
00136
00137 connect(mTimeButton,SIGNAL(toggled(bool)),SLOT(enableTimeEdits(bool)));
00138 connect(mTimeButton,SIGNAL(toggled(bool)),SLOT(dateChanged()));
00139
00140
00141 layoutTimeBox->setColStretch(3,1);
00142 }
00143
00144
00145 void KOEditorGeneralTodo::initCompletion(QWidget *parent, QBoxLayout *topLayout)
00146 {
00147 mCompletedCombo = new QComboBox(parent);
00148 for (int i = 0; i <= 100; i+=10) {
00149
00150 QString label = i18n("Percent complete", "%1 %").arg (i);
00151 mCompletedCombo->insertItem(label);
00152 }
00153 connect(mCompletedCombo,SIGNAL(activated(int)),SLOT(completedChanged(int)));
00154 topLayout->addWidget(mCompletedCombo);
00155
00156 mCompletedLabel = new QLabel(i18n("co&mpleted"),parent);
00157 topLayout->addWidget(mCompletedLabel);
00158 mCompletedLabel->setBuddy( mCompletedCombo );
00159 }
00160
00161 void KOEditorGeneralTodo::initPriority(QWidget *parent, QBoxLayout *topLayout)
00162 {
00163 QLabel *priorityLabel = new QLabel(i18n("&Priority:"),parent);
00164 topLayout->addWidget(priorityLabel);
00165
00166 mPriorityCombo = new QComboBox(parent);
00167 mPriorityCombo->insertItem(i18n("1 (highest)"));
00168 mPriorityCombo->insertItem(i18n("2"));
00169 mPriorityCombo->insertItem(i18n("3"));
00170 mPriorityCombo->insertItem(i18n("4"));
00171 mPriorityCombo->insertItem(i18n("5 (lowest)"));
00172 topLayout->addWidget(mPriorityCombo);
00173 priorityLabel->setBuddy( mPriorityCombo );
00174 }
00175
00176 void KOEditorGeneralTodo::initStatus(QWidget *parent,QBoxLayout *topLayout)
00177 {
00178 QBoxLayout *statusLayout = new QHBoxLayout(topLayout);
00179
00180 initCompletion( parent, statusLayout );
00181
00182 statusLayout->addStretch( 1 );
00183
00184 initPriority( parent, statusLayout );
00185 }
00186
00187 void KOEditorGeneralTodo::setDefaults(QDateTime due,bool allDay)
00188 {
00189 KOEditorGeneral::setDefaults(allDay);
00190
00191 mTimeButton->setChecked( !allDay );
00192 if(mTimeButton->isChecked()) {
00193 mTimeButton->setEnabled(true);
00194 }
00195 else {
00196 mTimeButton->setEnabled(false);
00197 }
00198
00199 enableTimeEdits( !allDay );
00200
00201 mDueCheck->setChecked(false);
00202 enableDueEdit(false);
00203
00204 alarmDisable(true);
00205
00206 mStartCheck->setChecked(false);
00207 enableStartEdit(false);
00208
00209 if ( due.isValid() ) {
00210 mDueDateEdit->setDate(due.date());
00211 mDueTimeEdit->setTime(due.time());
00212 }
00213
00214 mStartDateEdit->setDate(QDate::currentDate());
00215 mStartTimeEdit->setTime(QTime::currentTime());
00216 mStartDateModified = false;
00217
00218 mPriorityCombo->setCurrentItem(2);
00219
00220 mCompletedCombo->setCurrentItem(0);
00221 }
00222
00223 void KOEditorGeneralTodo::readTodo(Todo *todo)
00224 {
00225 KOEditorGeneral::readIncidence(todo);
00226
00227 QDateTime dueDT;
00228
00229 if (todo->hasDueDate()) {
00230 enableAlarmEdit(true);
00231 dueDT = todo->dtDue();
00232 mDueDateEdit->setDate(todo->dtDue().date());
00233 mDueTimeEdit->setTime(todo->dtDue().time());
00234 mDueCheck->setChecked(true);
00235 } else {
00236 alarmDisable(true);
00237 mDueDateEdit->setEnabled(false);
00238 mDueTimeEdit->setEnabled(false);
00239 mDueDateEdit->setDate(QDate::currentDate());
00240 mDueTimeEdit->setTime(QTime::currentTime());
00241 mDueCheck->setChecked(false);
00242 }
00243
00244 if (todo->hasStartDate()) {
00245 mStartDateEdit->setDate(todo->dtStart().date());
00246 mStartTimeEdit->setTime(todo->dtStart().time());
00247 mStartCheck->setChecked(true);
00248 } else {
00249 mStartDateEdit->setEnabled(false);
00250 mStartTimeEdit->setEnabled(false);
00251 mStartDateEdit->setDate(QDate::currentDate());
00252 mStartTimeEdit->setTime(QTime::currentTime());
00253 mStartCheck->setChecked(false);
00254 }
00255
00256 mTimeButton->setChecked( !todo->doesFloat() );
00257
00258 mAlreadyComplete = false;
00259 mCompletedCombo->setCurrentItem(todo->percentComplete() / 10);
00260 if (todo->isCompleted() && todo->hasCompletedDate()) {
00261 mCompleted = todo->completed();
00262 mAlreadyComplete = true;
00263 }
00264 setCompletedDate();
00265
00266 mPriorityCombo->setCurrentItem(todo->priority()-1);
00267 mStartDateModified = false;
00268 }
00269
00270 void KOEditorGeneralTodo::writeTodo(Todo *todo)
00271 {
00272 KOEditorGeneral::writeIncidence(todo);
00273
00274
00275 QString tmpStr;
00276
00277 todo->setHasDueDate(mDueCheck->isChecked());
00278 todo->setHasStartDate(mStartCheck->isChecked());
00279
00280 QDate tmpSDate, tmpDDate;
00281 QTime tmpSTime, tmpDTime;
00282 QDateTime tmpStartDT, tmpDueDT;
00283 if ( mTimeButton->isChecked() ) {
00284 todo->setFloats(false);
00285
00286
00287 tmpDDate = mDueDateEdit->date();
00288 tmpDTime = mDueTimeEdit->getTime();
00289 tmpDueDT.setDate(tmpDDate);
00290 tmpDueDT.setTime(tmpDTime);
00291
00292
00293 if ( mStartCheck->isChecked() ) {
00294 tmpSDate = mStartDateEdit->date();
00295 tmpSTime = mStartTimeEdit->getTime();
00296 tmpStartDT.setDate(tmpSDate);
00297 tmpStartDT.setTime(tmpSTime);
00298 } else {
00299 tmpStartDT = tmpDueDT;
00300 }
00301 } else {
00302 todo->setFloats(true);
00303
00304
00305 tmpDDate = mDueDateEdit->date();
00306 tmpDTime.setHMS(0,0,0);
00307 tmpDueDT.setDate(tmpDDate);
00308 tmpDueDT.setTime(tmpDTime);
00309
00310 if ( mStartCheck->isChecked() ) {
00311 tmpSDate = mStartDateEdit->date();
00312 tmpSTime.setHMS(0,0,0);
00313 tmpStartDT.setDate(tmpSDate);
00314 tmpStartDT.setTime(tmpSTime);
00315 } else {
00316 tmpStartDT = tmpDueDT;
00317 }
00318 }
00319
00320 if ( todo->doesRecur() && !mStartDateModified ) {
00321 todo->setDtDue( tmpDueDT );
00322 } else {
00323 todo->setDtDue( tmpDueDT, true );
00324 todo->setDtStart( tmpStartDT );
00325 todo->setDtRecurrence( tmpDueDT );
00326 }
00327
00328 todo->setPriority(mPriorityCombo->currentItem()+1);
00329
00330
00331 todo->setPercentComplete(mCompletedCombo->currentItem() * 10);
00332
00333 if (mCompletedCombo->currentItem() == 10 && mCompleted.isValid()) {
00334 if (! mAlreadyComplete) emit todoCompleted( todo );
00335 else todo->setCompleted(mCompleted);
00336 }
00337 }
00338
00339 void KOEditorGeneralTodo::enableDueEdit(bool enable)
00340 {
00341 mDueDateEdit->setEnabled( enable );
00342
00343 if(mDueCheck->isChecked() || mStartCheck->isChecked()) {
00344 mTimeButton->setEnabled(true);
00345 }
00346 else {
00347 mTimeButton->setEnabled(false);
00348 mTimeButton->setChecked(false);
00349 }
00350
00351 if (enable) {
00352 mDueTimeEdit->setEnabled( mTimeButton->isChecked() );
00353 } else {
00354 mDueTimeEdit->setEnabled( false );
00355 }
00356 }
00357
00358 void KOEditorGeneralTodo::enableStartEdit( bool enable )
00359 {
00360 mStartDateEdit->setEnabled( enable );
00361
00362 if(mDueCheck->isChecked() || mStartCheck->isChecked()) {
00363 mTimeButton->setEnabled(true);
00364 }
00365 else {
00366 mTimeButton->setEnabled(false);
00367 mTimeButton->setChecked(false);
00368 }
00369
00370 if (enable) {
00371 mStartTimeEdit->setEnabled( mTimeButton->isChecked() );
00372 } else {
00373 mStartTimeEdit->setEnabled( false );
00374 }
00375 }
00376
00377 void KOEditorGeneralTodo::enableTimeEdits(bool enable)
00378 {
00379 if(mStartCheck->isChecked()) {
00380 mStartTimeEdit->setEnabled( enable );
00381 }
00382 if(mDueCheck->isChecked()) {
00383 mDueTimeEdit->setEnabled( enable );
00384 }
00385 }
00386
00387 void KOEditorGeneralTodo::showAlarm()
00388 {
00389 if ( mDueCheck->isChecked() ) {
00390 alarmDisable(false);
00391 }
00392 else {
00393 alarmDisable(true);
00394 }
00395 }
00396
00397 bool KOEditorGeneralTodo::validateInput()
00398 {
00399 if (mDueCheck->isChecked()) {
00400 if (!mDueDateEdit->inputIsValid()) {
00401 KMessageBox::sorry(0,i18n("Please specify a valid due date."));
00402 return false;
00403 }
00404 if (mTimeButton->isChecked()) {
00405 if (!mDueTimeEdit->inputIsValid()) {
00406 KMessageBox::sorry(0,i18n("Please specify a valid due time."));
00407 return false;
00408 }
00409 }
00410 }
00411
00412 if (mStartCheck->isChecked()) {
00413 if (!mStartDateEdit->inputIsValid()) {
00414 KMessageBox::sorry(0,i18n("Please specify a valid start date."));
00415 return false;
00416 }
00417 if (mTimeButton->isChecked()) {
00418 if (!mStartTimeEdit->inputIsValid()) {
00419 KMessageBox::sorry(0,i18n("Please specify a valid start time."));
00420 return false;
00421 }
00422 }
00423 }
00424
00425 if (mStartCheck->isChecked() && mDueCheck->isChecked()) {
00426 QDateTime startDate;
00427 QDateTime dueDate;
00428 startDate.setDate(mStartDateEdit->date());
00429 dueDate.setDate(mDueDateEdit->date());
00430 if (mTimeButton->isChecked()) {
00431 startDate.setTime(mStartTimeEdit->getTime());
00432 dueDate.setTime(mDueTimeEdit->getTime());
00433 }
00434 if (startDate > dueDate) {
00435 KMessageBox::sorry(0,
00436 i18n("The start date cannot be after the due date."));
00437 return false;
00438 }
00439 }
00440
00441 return KOEditorGeneral::validateInput();
00442 }
00443
00444 void KOEditorGeneralTodo::completedChanged(int index)
00445 {
00446 if (index == 10) {
00447 mCompleted = QDateTime::currentDateTime();
00448 }
00449 setCompletedDate();
00450 }
00451
00452 void KOEditorGeneralTodo::dateChanged()
00453 {
00454 KLocale *l = KGlobal::locale();
00455 QString dateTimeStr = "";
00456
00457 if ( mStartCheck->isChecked() ) {
00458 dateTimeStr += i18n("Start: %1").arg(
00459 l->formatDate( mStartDateEdit->date() ) );
00460 if ( mTimeButton->isChecked() )
00461 dateTimeStr += QString(" %1").arg(
00462 l->formatTime( mStartTimeEdit->getTime() ) );
00463 }
00464
00465 if ( mDueCheck->isChecked() ) {
00466 dateTimeStr += i18n(" Due: %1").arg(
00467 l->formatDate( mDueDateEdit->date() ) );
00468 if ( mTimeButton->isChecked() )
00469 dateTimeStr += QString(" %1").arg(
00470 l->formatTime( mDueTimeEdit->getTime() ) );
00471 }
00472
00473 emit dateTimeStrChanged( dateTimeStr );
00474 QDateTime endDt( mDueDateEdit->date(), mDueTimeEdit->getTime() );
00475 emit signalDateTimeChanged( endDt, endDt );
00476 }
00477
00478 void KOEditorGeneralTodo::startDateModified()
00479 {
00480 mStartDateModified = true;
00481 dateChanged();
00482 }
00483
00484 void KOEditorGeneralTodo::setCompletedDate()
00485 {
00486 if (mCompletedCombo->currentItem() == 10 && mCompleted.isValid()) {
00487 mCompletedLabel->setText(i18n("co&mpleted on %1")
00488 .arg(KGlobal::locale()->formatDateTime(mCompleted)));
00489 } else {
00490 mCompletedLabel->setText(i18n("co&mpleted"));
00491 }
00492 }
00493
00494 void KOEditorGeneralTodo::modified (Todo* todo, int modification)
00495 {
00496 switch (modification) {
00497 case KOGlobals::PRIORITY_MODIFIED:
00498 mPriorityCombo->setCurrentItem(todo->priority()-1);
00499 break;
00500 case KOGlobals::COMPLETION_MODIFIED:
00501 mCompletedCombo->setCurrentItem(todo->percentComplete() / 10);
00502 if (todo->isCompleted() && todo->hasCompletedDate()) {
00503 mCompleted = todo->completed();
00504 }
00505 setCompletedDate();
00506 break;
00507 case KOGlobals::CATEGORY_MODIFIED:
00508 setCategories (todo->categoriesStr ());
00509 break;
00510 case KOGlobals::UNKNOWN_MODIFIED:
00511 default:
00512 readTodo( todo );
00513 break;
00514 }
00515 }