kplato

kpttaskgeneralpanel.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004 - 2006 Dag Andersen <danders@get2net.dk>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation;
00007    version 2 of the License.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kpttaskgeneralpanel.h"
00021 #include "kpttaskdialog.h"
00022 #include "kpttask.h"
00023 #include "kptcommand.h"
00024 #include "kptduration.h"
00025 #include "kptdurationwidget.h"
00026 #include "kptcalendar.h"
00027 #include "kptdatetime.h"
00028 #include "kptconfig.h"
00029 #include "kptpart.h"
00030 
00031 #include <kmessagebox.h>
00032 #include <klineedit.h>
00033 #include <ktextedit.h>
00034 #include <kcombobox.h>
00035 #include <kdatetimewidget.h>
00036 #include <klocale.h>
00037 #include <kcommand.h>
00038 #include <kabc/addressee.h>
00039 #include <kabc/addresseedialog.h>
00040 #include <kdatewidget.h>
00041 
00042 #include <qlayout.h>
00043 #include <qlabel.h>
00044 #include <qdatetime.h> 
00045 #include <qdatetimeedit.h> 
00046 #include <qgroupbox.h>
00047 #include <qpushbutton.h>
00048 #include <qspinbox.h>
00049 
00050 #include <kdebug.h>
00051 
00052 namespace KPlato
00053 {
00054 
00055 TaskGeneralPanel::TaskGeneralPanel(Task &task, StandardWorktime *workTime, bool /*baseline*/, QWidget *p, const char *n)
00056     : TaskGeneralPanelImpl(p, n),
00057       m_task(task),
00058       m_dayLength(24)
00059 {
00060     useTime = true;
00061     setStartValues(task, workTime);
00062 /*  Why is this done?  Its useless (its not actually read only, but that may be a Qt thing) and I have to
00063     edit these to actually be able to OK the dialog.   TZ-8-2005
00064     namefield->setReadOnly(baseline);
00065     leaderfield->setReadOnly(baseline);
00066     idfield->setReadOnly(baseline);
00067     schedulingGroup->setEnabled(!baseline);
00068 */
00069 }
00070 
00071 void TaskGeneralPanel::setStartValues(Task &task, StandardWorktime *workTime) {
00072     m_effort = m_duration = task.effort()->expected();
00073     namefield->setText(task.name());
00074     leaderfield->setText(task.leader());
00075     descriptionfield->setText(task.description());
00076     idfield->setText(task.id());
00077     wbsfield->setText(task.wbs());
00078     
00079     setEstimateFields(DurationWidget::Days|DurationWidget::Hours|DurationWidget::Minutes);
00080     if (workTime) {
00081         //kdDebug()<<k_funcinfo<<"daylength="<<workTime->day()<<endl;
00082         m_dayLength = workTime->day();
00083         if (task.effort()->type() == Effort::Type_Effort) {
00084             setEstimateScales(m_dayLength);
00085         }
00086     }
00087     setEstimateFieldUnit(0, i18n("days", "d"));
00088     setEstimateFieldUnit(1, i18n("hours", "h"));
00089     setEstimateFieldUnit(2, i18n("minutes", "m"));
00090     setEstimateType(task.effort()->type());
00091     
00092     setSchedulingType(task.constraint());
00093     if (task.constraintStartTime().isValid()) {
00094         setStartDateTime(task.constraintStartTime());
00095     } else {
00096         QDate date = QDate::currentDate();
00097         setStartDateTime(QDateTime(date, QTime())); 
00098     }
00099     if (task.constraintEndTime().isValid()) {
00100         setEndDateTime(task.constraintEndTime());
00101     } else {
00102         setEndDateTime(QDateTime(startDate().addDays(1), QTime())); 
00103     }
00104     //kdDebug()<<k_funcinfo<<"Effort: "<<task.effort()->expected().toString()<<endl;
00105     setEstimate(task.effort()->expected()); 
00106     setOptimistic(task.effort()->optimisticRatio());
00107     setPessimistic(task.effort()->pessimisticRatio());
00108     
00109     namefield->setFocus();
00110 }
00111 
00112 KMacroCommand *TaskGeneralPanel::buildCommand(Part *part) {
00113     KMacroCommand *cmd = new KMacroCommand(i18n("Modify Task"));
00114     bool modified = false;
00115 
00116     Duration dt = Duration();
00117 
00118     if (!namefield->isHidden() && m_task.name() != namefield->text()) {
00119         cmd->addCommand(new NodeModifyNameCmd(part, m_task, namefield->text()));
00120         modified = true;
00121     }
00122     if (!leaderfield->isHidden() && m_task.leader() != leaderfield->text()) {
00123         cmd->addCommand(new NodeModifyLeaderCmd(part, m_task, leaderfield->text()));
00124         modified = true;
00125     }
00126     if (!descriptionfield->isHidden() && 
00127         m_task.description() != descriptionfield->text()) {
00128         cmd->addCommand(new NodeModifyDescriptionCmd(part, m_task, descriptionfield->text()));
00129         modified = true;
00130     }
00131     Node::ConstraintType c = (Node::ConstraintType)schedulingType();
00132     if (c != m_task.constraint()) {
00133         cmd->addCommand(new NodeModifyConstraintCmd(part, m_task, c));
00134         modified = true;
00135     }
00136     if (startDateTime() != m_task.constraintStartTime() &&
00137         (c == Node::FixedInterval || c == Node::StartNotEarlier || c == Node::MustStartOn)) {
00138         cmd->addCommand(new NodeModifyConstraintStartTimeCmd(part, m_task, startDateTime()));
00139         modified = true;
00140     }
00141     if (endDateTime() != m_task.constraintEndTime() &&
00142         (c == Node::FinishNotLater || c == Node::FixedInterval || c == Node::MustFinishOn)) {
00143         cmd->addCommand(new NodeModifyConstraintEndTimeCmd(part, m_task, endDateTime()));
00144         modified = true;
00145     }
00146     if (!idfield->isHidden() && idfield->text() != m_task.id()) {
00147         
00148         cmd->addCommand(new NodeModifyIdCmd(part, m_task, idfield->text()));
00149         modified = true;
00150     }
00151     int et = estimationType();
00152     if (et != m_task.effort()->type()) {
00153         cmd->addCommand(new ModifyEffortTypeCmd(part, m_task.effort(),  m_task.effort()->type(), et));
00154         modified = true;
00155     }
00156     dt = estimationValue();
00157     kdDebug()<<k_funcinfo<<"Estimate: "<<dt.toString()<<endl;
00158     bool expchanged = dt != m_task.effort()->expected();
00159     if ( expchanged ) {
00160         cmd->addCommand(new ModifyEffortCmd(part, m_task.effort(), m_task.effort()->expected(), dt));
00161         modified = true;
00162     }
00163     int x = optimistic();
00164     if ( x != m_task.effort()->optimisticRatio() || expchanged) {
00165         cmd->addCommand(new EffortModifyOptimisticRatioCmd(part, m_task.effort(), m_task.effort()->optimisticRatio(), x));
00166         modified = true;
00167     }
00168     x = pessimistic();
00169     if ( x != m_task.effort()->pessimisticRatio() || expchanged) {
00170         cmd->addCommand(new EffortModifyPessimisticRatioCmd(part, m_task.effort(), m_task.effort()->pessimisticRatio(), x));
00171         modified = true;
00172     }
00173     if (!modified) {
00174         delete cmd;
00175         return 0;
00176     }
00177     return cmd;
00178 }
00179 
00180 bool TaskGeneralPanel::ok() {
00181     if (idfield->text() != m_task.id() && m_task.findNode(idfield->text())) {
00182         KMessageBox::sorry(this, i18n("Task id must be unique"));
00183         idfield->setFocus();
00184         return false;
00185     }
00186     return true;
00187 }
00188 
00189 void TaskGeneralPanel::estimationTypeChanged(int type) {
00190     if (type == 0 /*Effort*/) {
00191         Duration d = estimationValue();
00192         setEstimateScales(m_dayLength);
00193         //setEstimate(d);
00194         estimate->setEnabled(true);
00195     } else {
00196         Duration d = estimationValue();
00197         setEstimateScales(24);
00198         //setEstimate(d);
00199         if (schedulingType() == 6) { /*Fixed interval*/
00200             estimate->setEnabled(false);
00201         } else {
00202             estimate->setEnabled(true);
00203         }
00204         
00205     }
00206     TaskGeneralPanelImpl::estimationTypeChanged(type);
00207 }
00208 
00209 void TaskGeneralPanel::scheduleTypeChanged(int value)
00210 {
00211     if (value == 6 /*Fixed interval*/) { 
00212         if (estimateType->currentItem() == 1/*duration*/){
00213             setEstimateScales(24);
00214             estimate->setEnabled(false);
00215             setEstimate(DateTime(endDateTime()) - DateTime(startDateTime()));
00216         }
00217     } else {
00218         setEstimateScales(m_dayLength);
00219         estimate->setEnabled(true);
00220     }
00221     TaskGeneralPanelImpl::scheduleTypeChanged(value);
00222 }
00223 
00224 //-----------------------------
00225 TaskGeneralPanelImpl::TaskGeneralPanelImpl(QWidget *p, const char *n)
00226     : TaskGeneralPanelBase(p, n) {
00227     
00228     connect(idfield, SIGNAL(textChanged(const QString &)), SLOT(checkAllFieldsFilled()));
00229     connect(namefield, SIGNAL(textChanged(const QString &)), SLOT(checkAllFieldsFilled()));
00230     connect(leaderfield, SIGNAL(textChanged(const QString &)), SLOT(checkAllFieldsFilled()));
00231     connect(chooseLeader, SIGNAL(clicked()), SLOT(changeLeader()));
00232     connect(estimateType, SIGNAL(activated(int)), SLOT(estimationTypeChanged(int)));
00233     connect(scheduleType, SIGNAL(activated(int)), SLOT(scheduleTypeChanged(int)));
00234     connect(scheduleStartDate, SIGNAL(changed(QDate)), SLOT(startDateChanged()));
00235     connect(scheduleStartTime, SIGNAL(valueChanged(const QTime&)), SLOT(startTimeChanged(const QTime&)));
00236     connect(scheduleEndDate, SIGNAL(changed(QDate)), SLOT(endDateChanged()));
00237     connect(scheduleEndTime, SIGNAL(valueChanged(const QTime&)), SLOT(endTimeChanged(const QTime&)));
00238     connect(estimate, SIGNAL(valueChanged()), SLOT(checkAllFieldsFilled()));
00239     connect(optimisticValue, SIGNAL(valueChanged(int)), SLOT(checkAllFieldsFilled()));
00240     connect(pessimisticValue, SIGNAL(valueChanged(int)), SLOT(checkAllFieldsFilled()));
00241     connect(descriptionfield, SIGNAL(textChanged()), SLOT(checkAllFieldsFilled()));
00242 }
00243 
00244 void TaskGeneralPanelImpl::setSchedulingType(int type)
00245 {
00246     enableDateTime(type);
00247     scheduleType->setCurrentItem(type);
00248     emit schedulingTypeChanged(type);
00249 }
00250 
00251 int TaskGeneralPanelImpl::schedulingType() const 
00252 {
00253     return scheduleType->currentItem();
00254 }
00255 
00256 void TaskGeneralPanelImpl::changeLeader()
00257 {
00258     KABC::Addressee a = KABC::AddresseeDialog::getAddressee(this);
00259     if (!a.isEmpty())
00260     {
00261         leaderfield->setText(a.fullEmail());
00262     }
00263 }
00264 
00265 void TaskGeneralPanelImpl::setEstimationType( int type )
00266 {
00267     estimateType->setCurrentItem(type);
00268 }
00269 
00270 int TaskGeneralPanelImpl::estimationType() const
00271 {
00272     return estimateType->currentItem();
00273 }
00274 
00275 void TaskGeneralPanelImpl::setOptimistic( int value )
00276 {
00277     optimisticValue->setValue(value);
00278 }
00279 
00280 void TaskGeneralPanelImpl::setPessimistic( int value )
00281 {
00282     pessimisticValue->setValue(value);
00283 }
00284 
00285 int TaskGeneralPanelImpl::optimistic() const
00286 {
00287     return optimisticValue->value();
00288 }
00289 
00290 int TaskGeneralPanelImpl::pessimistic()
00291 {
00292     return pessimisticValue->value();
00293 }
00294 
00295 void TaskGeneralPanelImpl::enableDateTime( int scheduleType )
00296 {
00297     scheduleStartTime->setEnabled(false);
00298     scheduleEndTime->setEnabled(false);
00299     scheduleStartDate->setEnabled(false);
00300     scheduleEndDate->setEnabled(false);
00301     switch (scheduleType)
00302     {
00303     case 0: //ASAP
00304     case 1: //ALAP
00305         break;
00306     case 2: //Must start on
00307     case 4: // Start not earlier
00308         if (useTime) {
00309             scheduleStartTime->setEnabled(true);
00310             scheduleEndTime->setEnabled(false);
00311         }
00312         scheduleStartDate->setEnabled(true);
00313         scheduleEndDate->setEnabled(false);
00314         break;
00315     case 3: //Must finish on
00316     case 5: // Finish not later
00317         if (useTime) {
00318             scheduleStartTime->setEnabled(false);
00319             scheduleEndTime->setEnabled(true);
00320         }
00321         scheduleStartDate->setEnabled(false);
00322         scheduleEndDate->setEnabled(true);
00323         break;
00324     case 6: //Fixed interval
00325         if (useTime) {
00326             scheduleStartTime->setEnabled(true);
00327             scheduleEndTime->setEnabled(true);
00328         }
00329         scheduleStartDate->setEnabled(true);
00330         scheduleEndDate->setEnabled(true);
00331         break;
00332     default:
00333         break;
00334     }
00335 }
00336 
00337 
00338 void TaskGeneralPanelImpl::estimationTypeChanged( int /*type*/ )
00339 {
00340     checkAllFieldsFilled();
00341 }
00342 
00343 
00344 
00345 void TaskGeneralPanelImpl::setEstimate( const Duration & duration)
00346 {
00347     estimate->setValue( duration );
00348 }
00349 
00350 
00351 void TaskGeneralPanelImpl::setEstimateType( int type)
00352 {
00353     estimateType->setCurrentItem(type);
00354 }
00355 
00356 
00357 void TaskGeneralPanelImpl::checkAllFieldsFilled()
00358 {
00359     emit changed();
00360     emit obligatedFieldsFilled(!namefield->text().isEmpty() && !idfield->text().isEmpty());
00361 }
00362 
00363 
00364 Duration TaskGeneralPanelImpl::estimationValue()
00365 {
00366     return estimate->value();
00367 }
00368 
00369 
00370 void TaskGeneralPanelImpl::setEstimateFields( int mask )
00371 {
00372     estimate->setVisibleFields(mask);
00373 }
00374 
00375 
00376 void TaskGeneralPanelImpl::setEstimateScales( double day )
00377 {
00378     estimate->setFieldScale(0, day);
00379     estimate->setFieldRightscale(0, day);
00380     
00381     estimate->setFieldLeftscale(1, day);
00382 }
00383 
00384 
00385 void TaskGeneralPanelImpl::setEstimateFieldUnit( int field, QString unit )
00386 {
00387     estimate->setFieldUnit(field, unit);
00388 }
00389 
00390 void TaskGeneralPanelImpl::startDateChanged()
00391 {
00392     if (!scheduleStartDate->isEnabled()) {
00393         return;
00394     }
00395     QDate date = startDate();
00396     if (startDateTime() > endDateTime()) 
00397     {
00398         scheduleEndTime->blockSignals(true);
00399         scheduleEndDate->blockSignals(true);
00400         setEndDate(date);
00401         setEndTime(startTime());
00402         scheduleEndTime->blockSignals(false);
00403         scheduleEndDate->blockSignals(false);
00404     }
00405     if (scheduleType->currentItem() == 6 /*FixedInterval*/)
00406     {
00407         estimationTypeChanged(estimateType->currentItem());
00408     }
00409     checkAllFieldsFilled();
00410 }
00411 
00412 void TaskGeneralPanelImpl::startTimeChanged( const QTime &time )
00413 {
00414     if (!scheduleStartTime->isEnabled()) {
00415         return;
00416     }
00417     if (startDateTime() > endDateTime()) 
00418     {
00419         scheduleEndTime->blockSignals(true);
00420         setEndTime(time);
00421         scheduleEndTime->blockSignals(false);
00422     }
00423     if (scheduleType->currentItem() == 6 /*FixedInterval*/)
00424     {
00425         estimationTypeChanged(estimateType->currentItem());
00426     }
00427     checkAllFieldsFilled();
00428 }
00429 
00430 
00431 void TaskGeneralPanelImpl::endDateChanged()
00432 {
00433     if (!scheduleEndDate->isEnabled()) {
00434         return;
00435     }
00436     QDate date = endDate();
00437     if (endDateTime() < startDateTime()) 
00438     {
00439         scheduleStartTime->blockSignals(true);
00440         scheduleStartDate->blockSignals(true);
00441         setStartDate(date);
00442         setStartTime(endTime());
00443         scheduleStartTime->blockSignals(false);
00444         scheduleStartDate->blockSignals(false);
00445     }
00446     
00447     if (scheduleType->currentItem() == 6 /*FixedInterval*/)
00448     {
00449         estimationTypeChanged(estimateType->currentItem());
00450     }
00451     checkAllFieldsFilled();
00452 }
00453 
00454 void TaskGeneralPanelImpl::endTimeChanged( const QTime &time )
00455 {
00456     if (!scheduleEndTime->isEnabled()) {
00457         return;
00458     }
00459     if (endDateTime() < startDateTime()) 
00460     {
00461         scheduleStartTime->blockSignals(true);
00462         setStartTime(time);
00463         scheduleStartTime->blockSignals(false);
00464     }
00465     
00466     if (scheduleType->currentItem() == 6 /*FixedInterval*/)
00467     {
00468         estimationTypeChanged(estimateType->currentItem());
00469     }
00470     checkAllFieldsFilled();
00471 }
00472 
00473 void TaskGeneralPanelImpl::scheduleTypeChanged( int value )
00474 {
00475      estimationTypeChanged(estimateType->currentItem());
00476      enableDateTime(value);
00477      checkAllFieldsFilled();
00478 }
00479 
00480 
00481 QDateTime TaskGeneralPanelImpl::startDateTime()
00482 {
00483     return QDateTime(startDate(), startTime());
00484 }
00485 
00486 
00487 QDateTime TaskGeneralPanelImpl::endDateTime()
00488 {
00489     return QDateTime(endDate(), endTime());
00490 }
00491 
00492 void TaskGeneralPanelImpl::setStartTime( const QTime &time )
00493 {
00494     scheduleStartTime->setTime(time);
00495 }
00496 
00497 void TaskGeneralPanelImpl::setEndTime( const QTime &time )
00498 {
00499     scheduleEndTime->setTime(time);
00500 }
00501 
00502 QTime TaskGeneralPanelImpl::startTime() const
00503 {
00504     return scheduleStartTime->time();
00505 }
00506 
00507 QTime TaskGeneralPanelImpl::endTime()
00508 {
00509     return scheduleEndTime->time();
00510 }
00511 
00512 QDate TaskGeneralPanelImpl::startDate()
00513 {
00514     return scheduleStartDate->date();
00515 }
00516 
00517 
00518 QDate TaskGeneralPanelImpl::endDate()
00519 {
00520     return scheduleEndDate->date();
00521 }
00522 
00523 void TaskGeneralPanelImpl::setStartDateTime( const QDateTime &dt )
00524 {
00525     setStartDate(dt.date());
00526     setStartTime(dt.time());
00527 }
00528 
00529 
00530 void TaskGeneralPanelImpl::setEndDateTime( const QDateTime &dt )
00531 {
00532     setEndDate(dt.date());
00533     setEndTime(dt.time());
00534 }
00535 
00536 void TaskGeneralPanelImpl::setStartDate( const QDate &date )
00537 {
00538     scheduleStartDate->setDate(date);
00539 }
00540 
00541 
00542 void TaskGeneralPanelImpl::setEndDate( const QDate &date )
00543 {
00544     scheduleEndDate->setDate(date);
00545 }
00546 
00547 
00548 
00549 }  //KPlato namespace
00550 
00551 #include "kpttaskgeneralpanel.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys