diff --git a/korganizer/koeditorgeneraltodo.cpp b/korganizer/koeditorgeneraltodo.cpp index 529635ff93..8c3d3c77fc 100644 --- a/korganizer/koeditorgeneraltodo.cpp +++ b/korganizer/koeditorgeneraltodo.cpp @@ -1,602 +1,603 @@ /* This file is part of KOrganizer. Copyright (c) 2000,2001 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "koprefs.h" #include "koglobals.h" #include "ktimeedit.h" #include "koeditorgeneraltodo.h" #include "koeditorgeneraltodo.moc" KOEditorGeneralTodo::KOEditorGeneralTodo(QObject* parent, const char* name) : KOEditorGeneral( parent, name) { setType( "Todo" ); } KOEditorGeneralTodo::~KOEditorGeneralTodo() { } void KOEditorGeneralTodo::finishSetup() { QWidget::setTabOrder( mSummaryEdit, mLocationEdit ); QWidget::setTabOrder( mLocationEdit, mStartCheck ); QWidget::setTabOrder( mStartCheck, mStartDateEdit ); QWidget::setTabOrder( mStartDateEdit, mStartTimeEdit ); QWidget::setTabOrder( mStartTimeEdit, mDueCheck ); QWidget::setTabOrder( mDueCheck, mDueDateEdit ); QWidget::setTabOrder( mDueDateEdit, mDueTimeEdit ); QWidget::setTabOrder( mDueTimeEdit, mTimeButton ); QWidget::setTabOrder( mTimeButton, mRecEditButton ); QWidget::setTabOrder( mRecEditButton, mCompletedCombo ); QWidget::setTabOrder( mCompletedCombo, mPriorityCombo ); QWidget::setTabOrder( mPriorityCombo, mAlarmButton ); QWidget::setTabOrder( mAlarmButton, mAlarmTimeEdit ); QWidget::setTabOrder( mAlarmTimeEdit, mAlarmIncrCombo ); // QWidget::setTabOrder( mAlarmIncrCombo, mAlarmSoundButton ); QWidget::setTabOrder( mAlarmIncrCombo, mAlarmEditButton ); // QWidget::setTabOrder( mAlarmSoundButton, mAlarmProgramButton ); // QWidget::setTabOrder( mAlarmProgramButton, mDescriptionEdit ); QWidget::setTabOrder( mAlarmEditButton, mDescriptionEdit ); QWidget::setTabOrder( mDescriptionEdit, mCategoriesButton ); QWidget::setTabOrder( mCategoriesButton, mSecrecyCombo ); // QWidget::setTabOrder( mSecrecyCombo, mDescriptionEdit ); mSummaryEdit->setFocus(); } void KOEditorGeneralTodo::initTime(QWidget *parent,QBoxLayout *topLayout) { kdDebug(5850) << k_funcinfo << endl; QBoxLayout *timeLayout = new QVBoxLayout(topLayout); QGroupBox *timeGroupBox = new QGroupBox(1,QGroupBox::Horizontal, i18n("Date && Time"),parent); timeLayout->addWidget(timeGroupBox); QFrame *timeBoxFrame = new QFrame(timeGroupBox); QWhatsThis::add( timeBoxFrame, i18n("Sets options for due and start dates and times " "for this to-do.") ); QGridLayout *layoutTimeBox = new QGridLayout(timeBoxFrame,1,1); layoutTimeBox->setSpacing(topLayout->spacing()); QString whatsThis = i18n("Sets the start date for this to-do"); mStartCheck = new QCheckBox(i18n("Sta&rt:"),timeBoxFrame); QWhatsThis::add( mStartCheck, whatsThis ); layoutTimeBox->addWidget(mStartCheck,0,0); connect(mStartCheck,SIGNAL(toggled(bool)),SLOT(enableStartEdit(bool))); connect(mStartCheck,SIGNAL(toggled(bool)),SLOT(startDateModified())); mStartDateEdit = new KDateEdit(timeBoxFrame); QWhatsThis::add( mStartDateEdit, whatsThis ); layoutTimeBox->addWidget(mStartDateEdit,0,1); connect(mStartDateEdit,SIGNAL(dateChanged(const QDate&)),SLOT(startDateModified())); mStartTimeEdit = new KTimeEdit(timeBoxFrame); QWhatsThis::add( mStartTimeEdit, i18n("Sets the start time for this to-do.") ); layoutTimeBox->addWidget(mStartTimeEdit,0,2); connect(mStartTimeEdit,SIGNAL(timeChanged(QTime)),SLOT(startDateModified())); whatsThis = i18n("Sets the due date for this to-do."); mDueCheck = new QCheckBox(i18n("&Due:"),timeBoxFrame); QWhatsThis::add( mDueCheck, whatsThis ); layoutTimeBox->addWidget(mDueCheck,1,0); connect(mDueCheck,SIGNAL(toggled(bool)),SLOT(enableDueEdit(bool))); connect(mDueCheck,SIGNAL(toggled(bool)),SLOT(showAlarm())); connect(mDueCheck,SIGNAL(toggled(bool)),SIGNAL(dueDateEditToggle(bool))); connect(mDueCheck,SIGNAL(toggled(bool)),SLOT(dateChanged())); mDueDateEdit = new KDateEdit(timeBoxFrame); QWhatsThis::add( mDueDateEdit, whatsThis ); layoutTimeBox->addWidget(mDueDateEdit,1,1); connect(mDueDateEdit,SIGNAL(dateChanged(const QDate&)),SLOT(dateChanged())); mDueTimeEdit = new KTimeEdit(timeBoxFrame); QWhatsThis::add( mDueTimeEdit, i18n("Sets the due time for this to-do.") ); layoutTimeBox->addWidget(mDueTimeEdit,1,2); connect(mDueTimeEdit,SIGNAL(timeChanged( QTime )),SLOT(dateChanged())); mTimeButton = new QCheckBox(i18n("Ti&me associated"),timeBoxFrame); QWhatsThis::add( mTimeButton, i18n("Sets whether or not this to-do's start and due dates " "have times associated with them.") ); layoutTimeBox->addWidget( mTimeButton, 0, 3 ); connect(mTimeButton,SIGNAL(toggled(bool)),SLOT(enableTimeEdits(bool))); connect(mTimeButton,SIGNAL(toggled(bool)),SLOT(dateChanged())); QLabel *label = new QLabel( i18n( "Recurrence:" ), timeBoxFrame ); layoutTimeBox->addWidget( label, 3, 0 ); QBoxLayout *recLayout = new QHBoxLayout(); layoutTimeBox->addMultiCellLayout( recLayout, 3, 3, 1, 4 ); mRecEditButton = new QPushButton( timeBoxFrame ); mRecEditButton->setIconSet( KOGlobals::self()->smallIconSet( "recur", 16 ) ); recLayout->addWidget( mRecEditButton ); connect( mRecEditButton, SIGNAL(clicked()), SIGNAL(editRecurrence()) ); mRecEditLabel = new QLabel( QString(), timeBoxFrame ); recLayout->addWidget( mRecEditLabel ); recLayout->addStretch( 1 ); // some more layouting layoutTimeBox->setColStretch( 3, 1 ); QBoxLayout *secLayout = new QHBoxLayout(); layoutTimeBox->addLayout( secLayout, 0, 4 ); initSecrecy( timeBoxFrame, secLayout ); } void KOEditorGeneralTodo::initCompletion(QWidget *parent, QBoxLayout *topLayout) { QString whatsThis = i18n("Sets the current completion status of this to-do " "as a percentage."); mCompletedCombo = new QComboBox(parent); QWhatsThis::add( mCompletedCombo, whatsThis ); for (int i = 0; i <= 100; i+=10) { // xgettext:no-c-format QString label = i18n("Percent complete", "%1 %").arg (i); mCompletedCombo->insertItem(label); } connect(mCompletedCombo,SIGNAL(activated(int)),SLOT(completedChanged(int))); topLayout->addWidget(mCompletedCombo); mCompletedLabel = new QLabel(i18n("co&mpleted"),parent); topLayout->addWidget(mCompletedLabel); mCompletedLabel->setBuddy( mCompletedCombo ); mCompletionDateEdit = new KDateEdit( parent ); mCompletionDateEdit->hide(); topLayout->addWidget( mCompletionDateEdit ); mCompletionTimeEdit = new KTimeEdit( parent, QTime() ); mCompletionTimeEdit->hide(); topLayout->addWidget( mCompletionTimeEdit ); } void KOEditorGeneralTodo::initPriority(QWidget *parent, QBoxLayout *topLayout) { QString whatsThis = i18n("Sets the priority of this to-do on a scale " "from one to nine, with one being the highest " "priority, five being a medium priority, and " "nine being the lowest. In programs that have a " "different scale, the numbers will be adjusted " "to match the appropriate scale."); QLabel *priorityLabel = new QLabel(i18n("&Priority:"),parent); topLayout->addWidget(priorityLabel); mPriorityCombo = new QComboBox(parent); mPriorityCombo->insertItem(i18n("unspecified")); mPriorityCombo->insertItem(i18n("1 (highest)")); mPriorityCombo->insertItem(i18n("2")); mPriorityCombo->insertItem(i18n("3")); mPriorityCombo->insertItem(i18n("4")); mPriorityCombo->insertItem(i18n("5 (medium)")); mPriorityCombo->insertItem(i18n("6")); mPriorityCombo->insertItem(i18n("7")); mPriorityCombo->insertItem(i18n("8")); mPriorityCombo->insertItem(i18n("9 (lowest)")); topLayout->addWidget(mPriorityCombo); priorityLabel->setBuddy( mPriorityCombo ); } void KOEditorGeneralTodo::initStatus(QWidget *parent,QBoxLayout *topLayout) { QBoxLayout *statusLayout = new QHBoxLayout(topLayout); initCompletion( parent, statusLayout ); statusLayout->addStretch( 1 ); initPriority( parent, statusLayout ); } void KOEditorGeneralTodo::setDefaults( const QDateTime &due, bool allDay ) { kdDebug(5850) << k_funcinfo << due <setChecked( !allDay ); mTimeButton->setEnabled( mTimeButton->isChecked() /* i.e. !allDay */ ); enableTimeEdits( !allDay ); mDueCheck->setChecked( due.isValid() ); enableDueEdit( due.isValid() ); mStartCheck->setChecked(false); enableStartEdit(false); if ( due.isValid() ) { mDueDateEdit->setDate( due.date() ); mDueTimeEdit->setTime( due.time() ); } else { // Make it due tomorrow. mDueDateEdit->setDate( QDate::currentDate().addDays(1) ); mDueTimeEdit->setTime( QTime::currentTime() ); } if ( !due.isValid() || (QDateTime::currentDateTime() < due) ) { mStartDateEdit->setDate( QDate::currentDate() ); mStartTimeEdit->setTime( QTime::currentTime() ); } else { mStartDateEdit->setDate( due.date().addDays( -1 ) ); mStartTimeEdit->setTime( due.time() ); } mStartDateModified = false; mPriorityCombo->setCurrentItem(5); mCompletedCombo->setCurrentItem(0); } void KOEditorGeneralTodo::readTodo(Todo *todo, Calendar *calendar, const QDate &date ) { KOEditorGeneral::readIncidence(todo, calendar); QDateTime dueDT; if (todo->hasDueDate()) { enableAlarm( true ); dueDT = todo->dtDue(); if ( todo->doesRecur() && date.isValid() ) { dueDT.addDays( todo->dtDue().date().daysTo( date ) ); } mDueDateEdit->setDate(dueDT.date()); mDueTimeEdit->setTime(dueDT.time()); mDueCheck->setChecked(true); } else { enableAlarm( false ); mDueDateEdit->setEnabled(false); mDueTimeEdit->setEnabled(false); mDueDateEdit->setDate(QDate::currentDate()); mDueTimeEdit->setTime(QTime::currentTime()); mDueCheck->setChecked(false); } if (todo->hasStartDate()) { QDateTime startDT = todo->dtStart(); if ( todo->doesRecur() && date.isValid() ) { startDT.setDate( date ); } mStartDateEdit->setDate(startDT.date()); mStartTimeEdit->setTime(startDT.time()); mStartCheck->setChecked(true); } else { mStartDateEdit->setEnabled(false); mStartTimeEdit->setEnabled(false); mStartDateEdit->setDate(QDate::currentDate()); mStartTimeEdit->setTime(QTime::currentTime()); mStartCheck->setChecked(false); } - mTimeButton->setChecked( !todo->doesFloat() ); + mTimeButton->setChecked( !todo->doesFloat() && + todo->dtDue().time() != QTime( 0, 0 ) ); updateRecurrenceSummary( todo ); mAlreadyComplete = false; mCompletedCombo->setCurrentItem(todo->percentComplete() / 10); if (todo->isCompleted() && todo->hasCompletedDate()) { mCompleted = todo->completed(); mAlreadyComplete = true; } setCompletedDate(); mPriorityCombo->setCurrentItem( todo->priority() ); mStartDateModified = false; } void KOEditorGeneralTodo::writeTodo(Todo *todo) { KOEditorGeneral::writeIncidence(todo); // temp. until something better happens. QString tmpStr; todo->setHasDueDate(mDueCheck->isChecked()); todo->setHasStartDate(mStartCheck->isChecked()); QDate tmpSDate, tmpDDate; QTime tmpSTime, tmpDTime; QDateTime tmpStartDT, tmpDueDT; if ( mTimeButton->isChecked() ) { todo->setFloats(false); // set due date/time tmpDDate = mDueDateEdit->date(); tmpDTime = mDueTimeEdit->getTime(); tmpDueDT.setDate(tmpDDate); tmpDueDT.setTime(tmpDTime); // set start date/time if ( mStartCheck->isChecked() ) { tmpSDate = mStartDateEdit->date(); tmpSTime = mStartTimeEdit->getTime(); tmpStartDT.setDate(tmpSDate); tmpStartDT.setTime(tmpSTime); } else { tmpStartDT = tmpDueDT; } } else { todo->setFloats(true); // need to change this. tmpDDate = mDueDateEdit->date(); tmpDTime.setHMS(0,0,0); tmpDueDT.setDate(tmpDDate); tmpDueDT.setTime(tmpDTime); if ( mStartCheck->isChecked() ) { tmpSDate = mStartDateEdit->date(); tmpSTime.setHMS(0,0,0); tmpStartDT.setDate(tmpSDate); tmpStartDT.setTime(tmpSTime); } else { tmpStartDT = tmpDueDT; } } // TODO: Don't use the due date for the recurrence, but the start date (cf. rfc 2445) if ( todo->doesRecur() && !mStartDateModified ) { todo->setDtDue( tmpDueDT ); } else { todo->setDtDue( tmpDueDT, true ); todo->setDtStart( tmpStartDT ); todo->setDtRecurrence( tmpDueDT ); } todo->setPriority( mPriorityCombo->currentItem() ); // set completion state todo->setPercentComplete(mCompletedCombo->currentItem() * 10); if (mCompletedCombo->currentItem() == 10 && mCompleted.isValid()) { QDateTime completed( mCompletionDateEdit->date(), mCompletionTimeEdit->getTime() ); int difference = mCompleted.secsTo( completed ); if ( (difference < 60) && (difference > -60) && (completed.time().minute() == mCompleted.time().minute() ) ) { // completion time wasn't changed substantially (only the seconds // truncated, but that's an effect done by KTimeEdit automatically). completed = mCompleted; } todo->setCompleted( completed ); } } void KOEditorGeneralTodo::enableDueEdit(bool enable) { mDueDateEdit->setEnabled( enable ); if(mDueCheck->isChecked() || mStartCheck->isChecked()) { mTimeButton->setEnabled(true); } else { mTimeButton->setEnabled(false); } if (enable) { mDueTimeEdit->setEnabled( mTimeButton->isChecked() ); } else { mDueTimeEdit->setEnabled( false ); } } void KOEditorGeneralTodo::enableStartEdit( bool enable ) { mStartDateEdit->setEnabled( enable ); if(mDueCheck->isChecked() || mStartCheck->isChecked()) { mTimeButton->setEnabled(true); } else { mTimeButton->setEnabled(false); mTimeButton->setChecked(false); } if (enable) { mStartTimeEdit->setEnabled( mTimeButton->isChecked() ); } else { mStartTimeEdit->setEnabled( false ); } } void KOEditorGeneralTodo::enableTimeEdits(bool enable) { if(mStartCheck->isChecked()) { mStartTimeEdit->setEnabled( enable ); } if(mDueCheck->isChecked()) { mDueTimeEdit->setEnabled( enable ); } } void KOEditorGeneralTodo::showAlarm() { enableAlarm( mDueCheck->isChecked() ); } bool KOEditorGeneralTodo::validateInput() { if (mDueCheck->isChecked()) { if (!mDueDateEdit->date().isValid()) { KMessageBox::sorry(0,i18n("Please specify a valid due date.")); return false; } if (mTimeButton->isChecked()) { if (!mDueTimeEdit->inputIsValid()) { KMessageBox::sorry(0,i18n("Please specify a valid due time.")); return false; } } } if (mStartCheck->isChecked()) { if (!mStartDateEdit->date().isValid()) { KMessageBox::sorry(0,i18n("Please specify a valid start date.")); return false; } if (mTimeButton->isChecked()) { if (!mStartTimeEdit->inputIsValid()) { KMessageBox::sorry(0,i18n("Please specify a valid start time.")); return false; } } } if (mStartCheck->isChecked() && mDueCheck->isChecked()) { QDateTime startDate; QDateTime dueDate; startDate.setDate(mStartDateEdit->date()); dueDate.setDate(mDueDateEdit->date()); if (mTimeButton->isChecked()) { startDate.setTime(mStartTimeEdit->getTime()); dueDate.setTime(mDueTimeEdit->getTime()); } if (startDate > dueDate) { KMessageBox::sorry(0, i18n("The start date cannot be after the due date.")); return false; } } return KOEditorGeneral::validateInput(); } void KOEditorGeneralTodo::updateRecurrenceSummary( Todo *todo ) { if ( todo->doesRecur() ) { mRecEditLabel->setText( IncidenceFormatter::recurrenceString( todo ) ); } else { mRecEditLabel->setText( QString() ); } } void KOEditorGeneralTodo::completedChanged(int index) { if (index == 10) { mCompleted = QDateTime::currentDateTime(); } setCompletedDate(); } void KOEditorGeneralTodo::dateChanged() { KLocale *l = KGlobal::locale(); QString dateTimeStr = ""; if ( mStartCheck->isChecked() ) { dateTimeStr += i18n("Start: %1").arg( l->formatDate( mStartDateEdit->date() ) ); if ( mTimeButton->isChecked() ) dateTimeStr += QString(" %1").arg( l->formatTime( mStartTimeEdit->getTime() ) ); } if ( mDueCheck->isChecked() ) { dateTimeStr += i18n(" Due: %1").arg( l->formatDate( mDueDateEdit->date() ) ); if ( mTimeButton->isChecked() ) dateTimeStr += QString(" %1").arg( l->formatTime( mDueTimeEdit->getTime() ) ); } emit dateTimeStrChanged( dateTimeStr ); QDateTime endDt( mDueDateEdit->date(), mDueTimeEdit->getTime() ); emit signalDateTimeChanged( endDt, endDt ); } void KOEditorGeneralTodo::startDateModified() { mStartDateModified = true; dateChanged(); } void KOEditorGeneralTodo::setCompletedDate() { if (mCompletedCombo->currentItem() == 10 && mCompleted.isValid()) { mCompletedLabel->setText(i18n("co&mpleted on")); // .arg(KGlobal::locale()->formatDateTime(mCompleted))); mCompletionDateEdit->show(); mCompletionTimeEdit->show(); mCompletionDateEdit->setDate( mCompleted.date() ); mCompletionTimeEdit->setTime( mCompleted.time() ); } else { mCompletedLabel->setText(i18n("co&mpleted")); mCompletionDateEdit->hide(); mCompletionTimeEdit->hide(); } } void KOEditorGeneralTodo::modified (Todo* todo, KOGlobals::HowChanged modification) { switch (modification) { case KOGlobals::PRIORITY_MODIFIED: mPriorityCombo->setCurrentItem( todo->priority() ); break; case KOGlobals::COMPLETION_MODIFIED: mCompletedCombo->setCurrentItem(todo->percentComplete() / 10); if (todo->isCompleted() && todo->hasCompletedDate()) { mCompleted = todo->completed(); } setCompletedDate(); break; case KOGlobals::CATEGORY_MODIFIED: setCategories( todo->categories() ); break; case KOGlobals::UNKNOWN_MODIFIED: // fall through default: readTodo( todo, 0, QDate() ); break; } }