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     setRisktype(task.effort()->risktype());
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,  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, 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, 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, m_task.effort()->pessimisticRatio(), x));
00171         modified = true;
00172     }
00173     if (m_task.effort()->risktype() != risktype()) {
00174         cmd->addCommand(new EffortModifyRiskCmd(part, m_task, m_task.effort()->risktype(), risktype()));
00175         modified = true;
00176     }
00177     if (!modified) {
00178         delete cmd;
00179         return 0;
00180     }
00181     return cmd;
00182 }
00183 
00184 bool TaskGeneralPanel::ok() {
00185     if (idfield->text() != m_task.id() && m_task.findNode(idfield->text())) {
00186         KMessageBox::sorry(this, i18n("Task id must be unique"));
00187         idfield->setFocus();
00188         return false;
00189     }
00190     return true;
00191 }
00192 
00193 void TaskGeneralPanel::estimationTypeChanged(int type) {
00194     if (type == 0 /*Effort*/) {
00195         Duration d = estimationValue();
00196         setEstimateScales(m_dayLength);
00197         //setEstimate(d);
00198         estimate->setEnabled(true);
00199     } else {
00200         Duration d = estimationValue();
00201         setEstimateScales(24);
00202         //setEstimate(d);
00203         if (schedulingType() == 6) { /*Fixed interval*/
00204             estimate->setEnabled(false);
00205         } else {
00206             estimate->setEnabled(true);
00207         }
00208         
00209     }
00210     TaskGeneralPanelImpl::estimationTypeChanged(type);
00211 }
00212 
00213 void TaskGeneralPanel::scheduleTypeChanged(int value)
00214 {
00215     if (value == 6 /*Fixed interval*/) { 
00216         if (estimateType->currentItem() == 1/*duration*/){
00217             setEstimateScales(24);
00218             estimate->setEnabled(false);
00219             setEstimate(DateTime(endDateTime()) - DateTime(startDateTime()));
00220         }
00221     } else {
00222         setEstimateScales(m_dayLength);
00223         estimate->setEnabled(true);
00224     }
00225     TaskGeneralPanelImpl::scheduleTypeChanged(value);
00226 }
00227 
00228 //-----------------------------
00229 TaskGeneralPanelImpl::TaskGeneralPanelImpl(QWidget *p, const char *n)
00230     : TaskGeneralPanelBase(p, n) {
00231     
00232     connect(idfield, SIGNAL(textChanged(const QString &)), SLOT(checkAllFieldsFilled()));
00233     connect(namefield, SIGNAL(textChanged(const QString &)), SLOT(checkAllFieldsFilled()));
00234     connect(leaderfield, SIGNAL(textChanged(const QString &)), SLOT(checkAllFieldsFilled()));
00235     connect(chooseLeader, SIGNAL(clicked()), SLOT(changeLeader()));
00236     connect(estimateType, SIGNAL(activated(int)), SLOT(estimationTypeChanged(int)));
00237     connect(scheduleType, SIGNAL(activated(int)), SLOT(scheduleTypeChanged(int)));
00238     connect(scheduleStartDate, SIGNAL(changed(QDate)), SLOT(startDateChanged()));
00239     connect(scheduleStartTime, SIGNAL(valueChanged(const QTime&)), SLOT(startTimeChanged(const QTime&)));
00240     connect(scheduleEndDate, SIGNAL(changed(QDate)), SLOT(endDateChanged()));
00241     connect(scheduleEndTime, SIGNAL(valueChanged(const QTime&)), SLOT(endTimeChanged(const QTime&)));
00242     connect(estimate, SIGNAL(valueChanged()), SLOT(checkAllFieldsFilled()));
00243     connect(optimisticValue, SIGNAL(valueChanged(int)), SLOT(checkAllFieldsFilled()));
00244     connect(pessimisticValue, SIGNAL(valueChanged(int)), SLOT(checkAllFieldsFilled()));
00245     connect(descriptionfield, SIGNAL(textChanged()), SLOT(checkAllFieldsFilled()));
00246     connect(risk, SIGNAL(activated(int)), SLOT(checkAllFieldsFilled()));
00247 }
00248 
00249 void TaskGeneralPanelImpl::setSchedulingType(int type)
00250 {
00251     enableDateTime(type);
00252     scheduleType->setCurrentItem(type);
00253     emit schedulingTypeChanged(type);
00254 }
00255 
00256 int TaskGeneralPanelImpl::schedulingType() const 
00257 {
00258     return scheduleType->currentItem();
00259 }
00260 
00261 void TaskGeneralPanelImpl::changeLeader()
00262 {
00263     KABC::Addressee a = KABC::AddresseeDialog::getAddressee(this);
00264     if (!a.isEmpty())
00265     {
00266         leaderfield->setText(a.fullEmail());
00267     }
00268 }
00269 
00270 void TaskGeneralPanelImpl::setEstimationType( int type )
00271 {
00272     estimateType->setCurrentItem(type);
00273 }
00274 
00275 int TaskGeneralPanelImpl::estimationType() const
00276 {
00277     return estimateType->currentItem();
00278 }
00279 
00280 void TaskGeneralPanelImpl::setOptimistic( int value )
00281 {
00282     optimisticValue->setValue(value);
00283 }
00284 
00285 void TaskGeneralPanelImpl::setPessimistic( int value )
00286 {
00287     pessimisticValue->setValue(value);
00288 }
00289 
00290 int TaskGeneralPanelImpl::optimistic() const
00291 {
00292     return optimisticValue->value();
00293 }
00294 
00295 int TaskGeneralPanelImpl::pessimistic()
00296 {
00297     return pessimisticValue->value();
00298 }
00299 
00300 void TaskGeneralPanelImpl::enableDateTime( int scheduleType )
00301 {
00302     scheduleStartTime->setEnabled(false);
00303     scheduleEndTime->setEnabled(false);
00304     scheduleStartDate->setEnabled(false);
00305     scheduleEndDate->setEnabled(false);
00306     switch (scheduleType)
00307     {
00308     case 0: //ASAP
00309     case 1: //ALAP
00310         break;
00311     case 2: //Must start on
00312     case 4: // Start not earlier
00313         if (useTime) {
00314             scheduleStartTime->setEnabled(true);
00315             scheduleEndTime->setEnabled(false);
00316         }
00317         scheduleStartDate->setEnabled(true);
00318         scheduleEndDate->setEnabled(false);
00319         break;
00320     case 3: //Must finish on
00321     case 5: // Finish not later
00322         if (useTime) {
00323             scheduleStartTime->setEnabled(false);
00324             scheduleEndTime->setEnabled(true);
00325         }
00326         scheduleStartDate->setEnabled(false);
00327         scheduleEndDate->setEnabled(true);
00328         break;
00329     case 6: //Fixed interval
00330         if (useTime) {
00331             scheduleStartTime->setEnabled(true);
00332             scheduleEndTime->setEnabled(true);
00333         }
00334         scheduleStartDate->setEnabled(true);
00335         scheduleEndDate->setEnabled(true);
00336         break;
00337     default:
00338         break;
00339     }
00340 }
00341 
00342 
00343 void TaskGeneralPanelImpl::estimationTypeChanged( int /*type*/ )
00344 {
00345     checkAllFieldsFilled();
00346 }
00347 
00348 
00349 
00350 void TaskGeneralPanelImpl::setEstimate( const Duration & duration)
00351 {
00352     estimate->setValue( duration );
00353 }
00354 
00355 
00356 void TaskGeneralPanelImpl::setEstimateType( int type)
00357 {
00358     estimateType->setCurrentItem(type);
00359 }
00360 
00361 
00362 void TaskGeneralPanelImpl::checkAllFieldsFilled()
00363 {
00364     emit changed();
00365     emit obligatedFieldsFilled(!namefield->text().isEmpty() && !idfield->text().isEmpty());
00366 }
00367 
00368 
00369 Duration TaskGeneralPanelImpl::estimationValue()
00370 {
00371     return estimate->value();
00372 }
00373 
00374 
00375 void TaskGeneralPanelImpl::setEstimateFields( int mask )
00376 {
00377     estimate->setVisibleFields(mask);
00378 }
00379 
00380 
00381 void TaskGeneralPanelImpl::setEstimateScales( double day )
00382 {
00383     estimate->setFieldScale(0, day);
00384     estimate->setFieldRightscale(0, day);
00385     
00386     estimate->setFieldLeftscale(1, day);
00387 }
00388 
00389 
00390 void TaskGeneralPanelImpl::setEstimateFieldUnit( int field, QString unit )
00391 {
00392     estimate->setFieldUnit(field, unit);
00393 }
00394 
00395 void TaskGeneralPanelImpl::startDateChanged()
00396 {
00397     if (!scheduleStartDate->isEnabled()) {
00398         return;
00399     }
00400     QDate date = startDate();
00401     if (startDateTime() > endDateTime()) 
00402     {
00403         scheduleEndTime->blockSignals(true);
00404         scheduleEndDate->blockSignals(true);
00405         setEndDate(date);
00406         setEndTime(startTime());
00407         scheduleEndTime->blockSignals(false);
00408         scheduleEndDate->blockSignals(false);
00409     }
00410     if (scheduleType->currentItem() == 6 /*FixedInterval*/)
00411     {
00412         estimationTypeChanged(estimateType->currentItem());
00413     }
00414     checkAllFieldsFilled();
00415 }
00416 
00417 void TaskGeneralPanelImpl::startTimeChanged( const QTime &time )
00418 {
00419     if (!scheduleStartTime->isEnabled()) {
00420         return;
00421     }
00422     if (startDateTime() > endDateTime()) 
00423     {
00424         scheduleEndTime->blockSignals(true);
00425         setEndTime(time);
00426         scheduleEndTime->blockSignals(false);
00427     }
00428     if (scheduleType->currentItem() == 6 /*FixedInterval*/)
00429     {
00430         estimationTypeChanged(estimateType->currentItem());
00431     }
00432     checkAllFieldsFilled();
00433 }
00434 
00435 
00436 void TaskGeneralPanelImpl::endDateChanged()
00437 {
00438     if (!scheduleEndDate->isEnabled()) {
00439         return;
00440     }
00441     QDate date = endDate();
00442     if (endDateTime() < startDateTime()) 
00443     {
00444         scheduleStartTime->blockSignals(true);
00445         scheduleStartDate->blockSignals(true);
00446         setStartDate(date);
00447         setStartTime(endTime());
00448         scheduleStartTime->blockSignals(false);
00449         scheduleStartDate->blockSignals(false);
00450     }
00451     
00452     if (scheduleType->currentItem() == 6 /*FixedInterval*/)
00453     {
00454         estimationTypeChanged(estimateType->currentItem());
00455     }
00456     checkAllFieldsFilled();
00457 }
00458 
00459 void TaskGeneralPanelImpl::endTimeChanged( const QTime &time )
00460 {
00461     if (!scheduleEndTime->isEnabled()) {
00462         return;
00463     }
00464     if (endDateTime() < startDateTime()) 
00465     {
00466         scheduleStartTime->blockSignals(true);
00467         setStartTime(time);
00468         scheduleStartTime->blockSignals(false);
00469     }
00470     
00471     if (scheduleType->currentItem() == 6 /*FixedInterval*/)
00472     {
00473         estimationTypeChanged(estimateType->currentItem());
00474     }
00475     checkAllFieldsFilled();
00476 }
00477 
00478 void TaskGeneralPanelImpl::scheduleTypeChanged( int value )
00479 {
00480      estimationTypeChanged(estimateType->currentItem());
00481      enableDateTime(value);
00482      checkAllFieldsFilled();
00483 }
00484 
00485 
00486 QDateTime TaskGeneralPanelImpl::startDateTime()
00487 {
00488     return QDateTime(startDate(), startTime());
00489 }
00490 
00491 
00492 QDateTime TaskGeneralPanelImpl::endDateTime()
00493 {
00494     return QDateTime(endDate(), endTime());
00495 }
00496 
00497 void TaskGeneralPanelImpl::setStartTime( const QTime &time )
00498 {
00499     scheduleStartTime->setTime(time);
00500 }
00501 
00502 void TaskGeneralPanelImpl::setEndTime( const QTime &time )
00503 {
00504     scheduleEndTime->setTime(time);
00505 }
00506 
00507 QTime TaskGeneralPanelImpl::startTime() const
00508 {
00509     return scheduleStartTime->time();
00510 }
00511 
00512 QTime TaskGeneralPanelImpl::endTime()
00513 {
00514     return scheduleEndTime->time();
00515 }
00516 
00517 QDate TaskGeneralPanelImpl::startDate()
00518 {
00519     return scheduleStartDate->date();
00520 }
00521 
00522 
00523 QDate TaskGeneralPanelImpl::endDate()
00524 {
00525     return scheduleEndDate->date();
00526 }
00527 
00528 void TaskGeneralPanelImpl::setStartDateTime( const QDateTime &dt )
00529 {
00530     setStartDate(dt.date());
00531     setStartTime(dt.time());
00532 }
00533 
00534 
00535 void TaskGeneralPanelImpl::setEndDateTime( const QDateTime &dt )
00536 {
00537     setEndDate(dt.date());
00538     setEndTime(dt.time());
00539 }
00540 
00541 void TaskGeneralPanelImpl::setStartDate( const QDate &date )
00542 {
00543     scheduleStartDate->setDate(date);
00544 }
00545 
00546 
00547 void TaskGeneralPanelImpl::setEndDate( const QDate &date )
00548 {
00549     scheduleEndDate->setDate(date);
00550 }
00551 
00552 void TaskGeneralPanelImpl::setRisktype( int r )
00553 {
00554     risk->setCurrentItem(r);
00555 }
00556 
00557 int TaskGeneralPanelImpl::risktype() const
00558 {
00559     return risk->currentItem();
00560 }
00561 
00562 
00563 
00564 }  //KPlato namespace
00565 
00566 #include "kpttaskgeneralpanel.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys