diff options
Diffstat (limited to 'korganizer/koeditorgeneraltodo.cpp')
-rw-r--r-- | korganizer/koeditorgeneraltodo.cpp | 571 |
1 files changed, 571 insertions, 0 deletions
diff --git a/korganizer/koeditorgeneraltodo.cpp b/korganizer/koeditorgeneraltodo.cpp new file mode 100644 index 000000000..89deed4f2 --- /dev/null +++ b/korganizer/koeditorgeneraltodo.cpp @@ -0,0 +1,571 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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 <qtooltip.h> +#include <qfiledialog.h> +#include <qlayout.h> +#include <qvbox.h> +#include <qbuttongroup.h> +#include <qvgroupbox.h> +#include <qwidgetstack.h> +#include <qdatetime.h> +#include <qcheckbox.h> +#include <qlabel.h> +#include <qspinbox.h> +#include <qpushbutton.h> +#include <qwhatsthis.h> + +#include <kglobal.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kdebug.h> +#include <kstandarddirs.h> +#include <kfiledialog.h> +#include <ktextedit.h> + +#include <libkcal/todo.h> + +#include <libkdepim/kdateedit.h> + +#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) +{ +} + +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, 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->addMultiCellWidget(mTimeButton,2,2,0,2); + + connect(mTimeButton,SIGNAL(toggled(bool)),SLOT(enableTimeEdits(bool))); + connect(mTimeButton,SIGNAL(toggled(bool)),SLOT(dateChanged())); + + // 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 <<endl; + KOEditorGeneral::setDefaults(allDay); + + mTimeButton->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) +{ + KOEditorGeneral::readIncidence(todo, calendar); + + QDateTime dueDT; + + if (todo->hasDueDate()) { + enableAlarm( true ); + dueDT = todo->dtDue(); + mDueDateEdit->setDate(todo->dtDue().date()); + mDueTimeEdit->setTime(todo->dtDue().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()) { + mStartDateEdit->setDate(todo->dtStart().date()); + mStartTimeEdit->setTime(todo->dtStart().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() ); + + 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::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, int 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 ); + break; + } +} |