File indexing completed on 2024-11-17 04:49:33
0001 /* 0002 * Copyright (c) 2019 Alexander Potashev <aspotashev@gmail.com> 0003 * 0004 * This program is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU General Public License as 0006 * published by the Free Software Foundation; either version 2 of 0007 * the License or (at your option) version 3 or any later version 0008 * accepted by the membership of KDE e.V. (or its successor approved 0009 * by the membership of KDE e.V.), which shall act as a proxy 0010 * defined in Section 14 of version 3 of the license. 0011 * 0012 * This program is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 * GNU General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU General Public License 0018 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0019 */ 0020 0021 #include "projectmodel.h" 0022 0023 #include "event.h" 0024 #include "eventsmodel.h" 0025 #include "import/plannerparser.h" 0026 #include "ktt_debug.h" 0027 #include "task.h" 0028 #include "tasksmodel.h" 0029 0030 ProjectModel::ProjectModel() 0031 : m_tasksModel(new TasksModel()) 0032 , m_eventsModel(new EventsModel()) 0033 { 0034 } 0035 0036 TasksModel *ProjectModel::tasksModel() 0037 { 0038 return m_tasksModel; 0039 } 0040 0041 EventsModel *ProjectModel::eventsModel() 0042 { 0043 return m_eventsModel; 0044 } 0045 0046 std::unique_ptr<FileCalendar> ProjectModel::asCalendar(const QUrl &url) const 0047 { 0048 std::unique_ptr<FileCalendar> calendar(new FileCalendar(url)); 0049 for (auto *item : m_tasksModel->getAllItems()) { 0050 Task *task = dynamic_cast<Task *>(item); 0051 0052 KCalendarCore::Todo::Ptr todo(new KCalendarCore::Todo()); 0053 calendar->addTodo(task->asTodo(todo)); 0054 } 0055 0056 0057 // TODO: Use libkcalcore comments 0058 // todo->addComment(comment); 0059 // temporary 0060 // todo->setDescription(task->comment()); 0061 0062 0063 for (Event *event : m_eventsModel->events()) { 0064 KCalendarCore::Event::Ptr calEvent(new KCalendarCore::Event()); 0065 calendar->addEvent(event->asCalendarEvent(calEvent)); 0066 } 0067 0068 return calendar; 0069 } 0070 0071 void ProjectModel::resetTimeForAllTasks() 0072 { 0073 for (Task *task : tasksModel()->getAllTasks()) { 0074 task->resetTimes(); 0075 } 0076 0077 eventsModel()->clear(); 0078 } 0079 0080 void ProjectModel::importPlanner(const QString &fileName, Task *currentTask) 0081 { 0082 auto *handler = new PlannerParser(this, currentTask); 0083 QFile xmlFile(fileName); 0084 QXmlInputSource source(&xmlFile); 0085 QXmlSimpleReader reader; 0086 reader.setContentHandler(handler); 0087 reader.parse(source); 0088 0089 refresh(); 0090 } 0091 0092 void ProjectModel::refresh() 0093 { 0094 for (Task *task : tasksModel()->getAllTasks()) { 0095 task->invalidateCompletedState(); 0096 task->update(); // maybe there was a change in the times's format 0097 } 0098 } 0099 0100 void ProjectModel::refreshTimes() 0101 { 0102 // This procedure resets all times (session and overall) for all tasks and subtasks. 0103 // Reset session and total time for all tasks - do not touch the storage. 0104 for (Task *task : tasksModel()->getAllTasks()) { 0105 task->resetTimes(); 0106 } 0107 0108 for (Task *task : tasksModel()->getAllTasks()) { 0109 // get all events for task 0110 for (const auto *event : eventsModel()->eventsForTask(task)) { 0111 QDateTime eventStart = event->dtStart(); 0112 QDateTime eventEnd = event->dtEnd(); 0113 0114 const int64_t duration = event->duration() / 60; 0115 task->addTime(duration); 0116 qCDebug(KTT_LOG) << "duration is" << duration; 0117 0118 if (task->sessionStartTiMe().isValid()) { 0119 // if there is a session 0120 if (task->sessionStartTiMe().secsTo(eventStart) > 0 && task->sessionStartTiMe().secsTo(eventEnd) > 0) { 0121 // if the event is after the session start 0122 task->addSessionTime(duration); 0123 } 0124 } else { 0125 // so there is no session at all 0126 task->addSessionTime(duration); 0127 } 0128 } 0129 } 0130 0131 // Recalculate total times after changing hierarchy by drag&drop 0132 for (Task *task : tasksModel()->getAllTasks()) { 0133 // Start recursive method recalculateTotalTimesSubtree() for each top-level task. 0134 if (task->isRoot()) { 0135 task->recalculateTotalTimesSubtree(); 0136 } 0137 } 0138 0139 refresh(); 0140 }