diff --git a/src/libs/ui/kpttaskprogresspanel.cpp b/src/libs/ui/kpttaskprogresspanel.cpp index 09a30deb..42b4d5f1 100644 --- a/src/libs/ui/kpttaskprogresspanel.cpp +++ b/src/libs/ui/kpttaskprogresspanel.cpp @@ -1,425 +1,437 @@ /* This file is part of the KDE project Copyright (C) 2004 - 2007, 2012 Dag Andersen Copyright (C) 2019 Dag Andersen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ // clazy:excludeall=qstring-arg #include "kpttaskprogresspanel.h" #include "kptusedefforteditor.h" #include #include #include #include #include "kpttask.h" #include "kptcommand.h" #include "kptcalendar.h" #include "kptresource.h" #include "kptdurationspinbox.h" #include "kptschedule.h" #include "kptproject.h" #include "kptdebug.h" using namespace KPlato; int toEditMode(Completion::Entrymode m) { const QList modes = QList() << Completion::EnterEffortPerResource << Completion::EnterEffortPerTask << Completion::EnterCompleted; return qBound(0, modes.indexOf(m), 1); } Completion::Entrymode fromEditMode(int m) { const QList modes = QList() << Completion::EnterEffortPerResource << Completion::EnterEffortPerTask; return modes.value(m); } //----------------- TaskProgressPanel::TaskProgressPanel(Task &task, ScheduleManager *sm, StandardWorktime *workTime, QWidget *parent) : TaskProgressPanelImpl(task, parent) { Q_UNUSED(workTime); debugPlan; started->setChecked(m_completion.isStarted()); finished->setChecked(m_completion.isFinished()); startTime->setDateTime(m_completion.startTime()); finishTime->setDateTime(m_completion.finishTime()); finishTime->setMinimumDateTime(qMax(startTime->dateTime(), QDateTime(m_completion.entryDate(), QTime(), Qt::LocalTime))); scheduledEffort = task.estimate()->expectedValue(); setYear(QDate::currentDate().year()); if (m_completion.usedEffortMap().isEmpty() || m_task.requests().isEmpty()) { foreach (ResourceGroupRequest *g, m_task.requests().requests()) { foreach (ResourceRequest *r, g->resourceRequests()) { m_completion.addUsedEffort(r->resource()); } } } enableWidgets(); started->setFocus(); connect(weekNumber, SIGNAL(currentIndexChanged(int)), SLOT(slotWeekNumberChanged(int))); connect(ui_resourceCombo, SIGNAL(activated(QString)), resourceTable->model(), SLOT(addResource(QString))); connect(addEntryBtn, &QAbstractButton::clicked, entryTable, &CompletionEntryEditor::addEntry); connect(removeEntryBtn, &QAbstractButton::clicked, entryTable, &CompletionEntryEditor::removeEntry); entryTable->model()->setManager(sm); entryTable->model()->setTask(&task); entryTable->setCompletion(&m_completion); connect(entryTable, &CompletionEntryEditor::rowInserted, this, &TaskProgressPanel::slotEntryAdded); + connect(entryTable, &CompletionEntryEditor::rowRemoved, this, &TaskProgressPanel::slotEntryRemoved); resourceTable->setProject(static_cast(task.projectNode())); resourceTable->setCompletion(&m_completion); slotWeekNumberChanged(weekNumber->currentIndex()); updateResourceCombo(); connect(resourceTable->model(), &UsedEffortItemModel::rowInserted, this, &TaskProgressPanelImpl::updateResourceCombo); //resourceTable->resizeColumnsToContents(); connect(started, &QAbstractButton::toggled, this, &TaskProgressPanelImpl::slotStartedChanged); connect(started, &QAbstractButton::toggled, this, &TaskProgressPanelImpl::slotChanged); connect(finished, &QAbstractButton::toggled, this, &TaskProgressPanelImpl::slotFinishedChanged); connect(finished, &QAbstractButton::toggled, this, &TaskProgressPanelImpl::slotChanged); connect(startTime, &QDateTimeEdit::dateTimeChanged, this, &TaskProgressPanelImpl::slotChanged); connect(startTime, &QDateTimeEdit::dateTimeChanged, this, &TaskProgressPanelImpl::slotStartTimeChanged); connect(finishTime, &QDateTimeEdit::dateTimeChanged, this, &TaskProgressPanelImpl::slotChanged); connect(finishTime, &QDateTimeEdit::dateTimeChanged, this, &TaskProgressPanelImpl::slotFinishTimeChanged); + + finishTime->setToolTip(xi18nc("@info:tooltip", "Select the tasks finish time")); + finished->setToolTip(xi18nc("@info:tooltip", "Finish the task at the selected time")); } MacroCommand *TaskProgressPanel::buildCommand() { Project *project = dynamic_cast(m_task.projectNode()); if (project == 0) { return 0; } return buildCommand(*project, m_original, m_completion); } MacroCommand *TaskProgressPanel::buildCommand(const Project &project, Completion &org, Completion &curr) { MacroCommand *cmd = 0; KUndo2MagicString c = kundo2_i18n("Modify task completion"); if (org.entrymode() != curr.entrymode()) { if (cmd == 0) cmd = new MacroCommand(c); cmd->addCommand(new ModifyCompletionEntrymodeCmd(org, curr.entrymode())); } if (org.startTime() != curr.startTime()) { if (cmd == 0) cmd = new MacroCommand(c); cmd->addCommand(new ModifyCompletionStartTimeCmd(org, curr.startTime())); } if (org.finishTime() != curr.finishTime()) { if (cmd == 0) cmd = new MacroCommand(c); cmd->addCommand(new ModifyCompletionFinishTimeCmd(org, curr.finishTime())); } if (org.isStarted() != curr.isStarted()) { if (cmd == 0) cmd = new MacroCommand(c); cmd->addCommand(new ModifyCompletionStartedCmd(org, curr.isStarted())); } if (org.isFinished() != curr.isFinished()) { if (cmd == 0) cmd = new MacroCommand(c); cmd->addCommand(new ModifyCompletionFinishedCmd(org, curr.isFinished())); } QList orgdates = org.entries().keys(); QList currdates = curr.entries().keys(); foreach (const QDate &d, orgdates) { if (currdates.contains(d)) { if (curr.entry(d) == org.entry(d)) { continue; } if (cmd == 0) cmd = new MacroCommand(c); debugPlan<<"modify entry "<addCommand(new ModifyCompletionEntryCmd(org, d, e)); } else { if (cmd == 0) cmd = new MacroCommand(c); debugPlan<<"remove entry "<addCommand(new RemoveCompletionEntryCmd(org, d)); } } foreach (const QDate &d, currdates) { if (! orgdates.contains(d)) { if (cmd == 0) cmd = new MacroCommand(c); Completion::Entry *e = new Completion::Entry(* (curr.entry(d))); debugPlan<<"add entry "<addCommand(new AddCompletionEntryCmd(org, d, e)); } } const Completion::ResourceUsedEffortMap &map = curr.usedEffortMap(); Completion::ResourceUsedEffortMap::const_iterator it; for (it = map.constBegin(); it != map.constEnd(); ++it) { Resource *r = project.findResource(it.key()->id()); if (r == 0) { warnPlan<<"Can't find resource:"<id()<name(); continue; } Completion::UsedEffort *ue = map[ r ]; if (ue == 0) { continue; } if (org.usedEffort(r) == 0 || *ue != *(org.usedEffort(r))) { if (cmd == 0) cmd = new MacroCommand(c); cmd->addCommand(new AddCompletionUsedEffortCmd(org, r, new Completion::UsedEffort(*ue))); } } return cmd; } void TaskProgressPanel::slotWeekNumberChanged(int index) { debugPlan<setCurrentMonday(date); } void TaskProgressPanel::slotEntryAdded(const QDate &date) { - debugPlan<setText(task.name()); connect(entryTable, &CompletionEntryEditor::selectedItemsChanged, this, &TaskProgressPanelImpl::slotSelectionChanged); removeEntryBtn->setEnabled(false); editmode->setCurrentIndex(toEditMode(m_original.entrymode())); connect(editmode, SIGNAL(currentIndexChanged(int)), SLOT(slotEditmodeChanged(int))); connect(editmode, SIGNAL(activated(int)), SLOT(slotChanged())); connect(resourceTable, &UsedEffortEditor::changed, this, &TaskProgressPanelImpl::slotChanged); connect(resourceTable, &UsedEffortEditor::resourceAdded, this, &TaskProgressPanelImpl::slotChanged); connect(resourceTable->model(), &UsedEffortItemModel::effortChanged, this, &TaskProgressPanelImpl::slotEffortChanged); connect(entryTable, &CompletionEntryEditor::changed, this, &TaskProgressPanelImpl::slotChanged); connect(entryTable, &CompletionEntryEditor::rowInserted, this, &TaskProgressPanelImpl::slotChanged); connect(entryTable, &CompletionEntryEditor::changed, this, &TaskProgressPanelImpl::slotEntryChanged); connect(entryTable, &CompletionEntryEditor::rowInserted, this, &TaskProgressPanelImpl::slotEntryChanged); connect(entryTable, &CompletionEntryEditor::rowRemoved, this, &TaskProgressPanelImpl::slotEntryChanged); connect(prevWeekBtn, &QAbstractButton::clicked, this, &TaskProgressPanelImpl::slotPrevWeekBtnClicked); connect(nextWeekBtn, &QAbstractButton::clicked, this, &TaskProgressPanelImpl::slotNextWeekBtnClicked); connect (ui_year, SIGNAL(valueChanged(int)), SLOT(slotFillWeekNumbers(int))); int y = 0; int wn = QDate::currentDate().weekNumber(&y); setYear(y); weekNumber->setCurrentIndex(wn - m_weekOffset); } +void TaskProgressPanelImpl::updateFinishedDateTime() +{ + finishTime->setMinimumDateTime(qMax(startTime->dateTime(), QDateTime(m_completion.entryDate(), QTime(), Qt::LocalTime))); +} + void TaskProgressPanelImpl::slotEffortChanged(const QDate &date) { if (date.isValid()) { entryTable->insertEntry(date); } } void TaskProgressPanelImpl::slotChanged() { emit changed(); } void TaskProgressPanelImpl::slotEditmodeChanged(int idx) { m_completion.setEntrymode(fromEditMode(idx)); entryTable->model()->slotDataChanged(); enableWidgets(); } void TaskProgressPanelImpl::slotStartedChanged(bool state) { m_completion.setStarted(state); if (state) { QTime t = QTime::currentTime(); t.setHMS(t.hour(), t.minute(), 0); m_completion.setStartTime(QDateTime(QDate::currentDate(), t, Qt::LocalTime)); startTime->setDateTime(m_completion.startTime()); slotCalculateEffort(); } enableWidgets(); } void TaskProgressPanelImpl::setFinished() { - QTime t = QTime::currentTime(); - t.setHMS(t.hour(), t.minute(), 0); - finishTime->setDateTime(QDateTime(QDate::currentDate(), t, Qt::LocalTime)); - slotFinishTimeChanged(finishTime->dateTime()); + const QDateTime dt = finishTime->dateTime(); + m_completion.setPercentFinished(dt.date(), 100); + m_completion.setRemainingEffort(dt.date(), Duration::zeroDuration); + entryTable->setCompletion(&m_completion); // for refresh + updateFinishedDateTime(); } void TaskProgressPanelImpl::slotFinishedChanged(bool state) { debugPlan<dateTime(); } enableWidgets(); } void TaskProgressPanelImpl::slotFinishTimeChanged(const QDateTime &dt) { + qInfo()<setCompletion(&m_completion); // for refresh } void TaskProgressPanelImpl::slotStartTimeChanged(const QDateTime &dt) { m_completion.setStartTime(dt); - finishTime->setMinimumDateTime(qMax(startTime->dateTime(), QDateTime(m_completion.entryDate(), QTime(), Qt::LocalTime))); - + updateFinishedDateTime(); } void TaskProgressPanelImpl::slotEntryChanged() { - finishTime->setMinimumDateTime(qMax(startTime->dateTime(), QDateTime(m_completion.entryDate(), QTime(), Qt::LocalTime))); + updateFinishedDateTime(); } void TaskProgressPanelImpl::updateResourceCombo() { ui_resourceCombo->blockSignals(true); ui_resourceCombo->clear(); ui_resourceCombo->addItems(resourceTable->model()->freeResources().keys()); ui_resourceCombo->blockSignals(false); } void TaskProgressPanelImpl::enableWidgets() { editmode->setEnabled(!finished->isChecked()); started->setEnabled(!finished->isChecked()); finished->setEnabled(started->isChecked()); - finishTime->setEnabled(finished->isChecked()); + finishTime->setEnabled(!finished->isChecked()); startTime->setEnabled(started->isChecked() && !finished->isChecked()); addEntryBtn->setEnabled(started->isChecked() && !finished->isChecked()); removeEntryBtn->setEnabled(! entryTable->selectionModel()->selectedIndexes().isEmpty() && started->isChecked() && ! finished->isChecked()); ui_resourceFrame->setVisible(m_completion.entrymode() == Completion::EnterEffortPerResource); resourceTable->model()->setReadOnly((! started->isChecked()) || finished->isChecked() || editmode->currentIndex() != 0); } void TaskProgressPanelImpl::slotPercentFinishedChanged(int) { slotCalculateEffort(); } void TaskProgressPanelImpl::slotCalculateEffort() { } void TaskProgressPanelImpl::slotPrevWeekBtnClicked() { debugPlan; int i = weekNumber->currentIndex(); if (i == 0) { debugPlan<value() - 1); if (m_lastIsNextYear) { decr = 2; } weekNumber->setCurrentIndex(weekNumber->count() - decr); } else { weekNumber->setCurrentIndex(i - 1); } } void TaskProgressPanelImpl::slotNextWeekBtnClicked() { int i = weekNumber->currentIndex(); debugPlan<count(); if (i == weekNumber->count() - 1) { debugPlan<value() + 1); if (m_firstIsPrevYear) { index = 1; } weekNumber->setCurrentIndex(index); } else { weekNumber->setCurrentIndex(i + 1); } } void TaskProgressPanelImpl::setYear(int year) { debugPlan; ui_year->setValue(year); } void TaskProgressPanelImpl::slotFillWeekNumbers(int year) { debugPlan; weekNumber->clear(); m_year = year; m_weekOffset = 1; int y = 0; QDate date(year, 1, 1); int wn = date.weekNumber(&y); m_firstIsPrevYear = false; debugPlan<addItem(i18nc("Week number (year)", "Week %1 (%2)", wn, y)); m_weekOffset = 0; m_firstIsPrevYear = true; debugPlan<<"Added last week of prev year"; } for (int i=1; i <= 52; ++i) { weekNumber->addItem(i18nc("Week number", "Week %1", i)); } date = QDate(year, 12, 31); wn = date.weekNumber(&y); debugPlan<addItem(i18nc("Week number", "Week %1", wn)); } else if (wn == 1) { weekNumber->addItem(i18nc("Week number (year)", "Week %1 (%2)", wn, y)); m_lastIsNextYear = true; } } void TaskProgressPanelImpl::slotSelectionChanged(const QItemSelection &sel) { removeEntryBtn->setEnabled(! sel.isEmpty() && started->isChecked() && ! finished->isChecked()); } diff --git a/src/libs/ui/kpttaskprogresspanel.h b/src/libs/ui/kpttaskprogresspanel.h index 18567413..2ccb51cb 100644 --- a/src/libs/ui/kpttaskprogresspanel.h +++ b/src/libs/ui/kpttaskprogresspanel.h @@ -1,105 +1,108 @@ /* This file is part of the KDE project Copyright (C) 2004 - 2007 Dag Andersen Copyright (C) 2019 Dag Andersen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KPTTASKPROGRESSPANEL_H #define KPTTASKPROGRESSPANEL_H #include "planui_export.h" #include "ui_kpttaskprogresspanelbase.h" #include "kpttask.h" #include namespace KPlato { class StandardWorktime; class Duration; class ScheduleManager; class MacroCommand; //------------------------ class PLANUI_EXPORT TaskProgressPanelImpl : public QWidget, public Ui_TaskProgressPanelBase { Q_OBJECT public: explicit TaskProgressPanelImpl(Task &task, QWidget *parent=0); void enableWidgets(); void setYear(int year); Q_SIGNALS: void changed(); public Q_SLOTS: void slotChanged(); void slotEditmodeChanged(int idx); void slotStartedChanged(bool state); void slotFinishedChanged(bool state); void slotPercentFinishedChanged(int value); void slotStartTimeChanged(const QDateTime &dt); void slotFinishTimeChanged(const QDateTime &dt); void slotEntryChanged(); void slotSelectionChanged(const QItemSelection &sel); void slotPrevWeekBtnClicked(); void slotNextWeekBtnClicked(); void updateResourceCombo(); void slotEffortChanged(const QDate &date); protected Q_SLOTS: void slotCalculateEffort(); void slotFillWeekNumbers(int year); + void updateFinishedDateTime(); + protected: void setFinished(); Task &m_task; Completion &m_original; Completion m_completion; int m_dayLength; Duration scheduledEffort; int m_weekOffset; int m_year; bool m_firstIsPrevYear; bool m_lastIsNextYear; }; class PLANUI_EXPORT TaskProgressPanel : public TaskProgressPanelImpl { Q_OBJECT public: explicit TaskProgressPanel(Task &task, ScheduleManager *sm, StandardWorktime *workTime=0, QWidget *parent=0); MacroCommand *buildCommand(); static MacroCommand *buildCommand(const Project &project, Completion &org, Completion &curr); protected Q_SLOTS: void slotWeekNumberChanged(int); void slotEntryAdded(const QDate &date); + void slotEntryRemoved(const QDate &date); }; } //KPlato namespace #endif // TASKPROGRESSPANEL_H diff --git a/src/libs/ui/kpttaskprogresspanelbase.ui b/src/libs/ui/kpttaskprogresspanelbase.ui index dd61d6bf..5fffd707 100644 --- a/src/libs/ui/kpttaskprogresspanelbase.ui +++ b/src/libs/ui/kpttaskprogresspanelbase.ui @@ -1,357 +1,372 @@ Dag Andersen <danders@get2net.dk> KPlato::TaskProgressPanelBase 0 0 887 427 Task: true QFrame::StyledPanel QFrame::Raised Started: true - + Finished: - - + + finishTime true + + + + + + + + + + Qt::Horizontal 36 20 0 0 0 0 Edit mode: Per resource Per task QFrame::StyledPanel QFrame::Raised 0 0 0 0 1900 2999 Prev .. Next .. Qt::Horizontal 16 25 0 0 0 0 Add resource: 0 0 false 70 true QFrame::StyledPanel QFrame::Raised Add Entry .. Remove Entry .. Qt::Horizontal 40 20 0 0 0 100 false KComboBox QComboBox
kcombobox.h
CompletionEntryEditor QTableView
kptusedefforteditor.h
UsedEffortEditor QTableView
kptusedefforteditor.h
started startTime - finished finishTime - addEntryBtn - removeEntryBtn + finished + editmode ui_year prevWeekBtn weekNumber nextWeekBtn + ui_resourceCombo + addEntryBtn + removeEntryBtn + entryTable + taskName + resourceTable