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 "eventsmodel.h" 0022 0023 #include <KLocalizedString> 0024 0025 #include "ktt_debug.h" 0026 #include "task.h" 0027 0028 void EventsModel::load(const KCalendarCore::Event::List &events) 0029 { 0030 clear(); 0031 0032 for (const auto &event : events) { 0033 m_events.append(new Event(event)); 0034 } 0035 } 0036 0037 EventsModel::~EventsModel() 0038 { 0039 clear(); 0040 } 0041 0042 QList<Event *> EventsModel::events() const 0043 { 0044 return m_events; 0045 } 0046 0047 QList<Event *> EventsModel::eventsForTask(const Task *task) const 0048 { 0049 QList<Event *> res; 0050 for (auto *event : events()) { 0051 if (event->relatedTo() == task->uid()) { 0052 res.append(event); 0053 } 0054 } 0055 0056 return res; 0057 } 0058 0059 Event *EventsModel::eventByUID(const QString &uid) const 0060 { 0061 for (auto *event : events()) { 0062 if (event->uid() == uid) { 0063 return event; 0064 } 0065 } 0066 0067 return nullptr; 0068 } 0069 0070 void EventsModel::clear() 0071 { 0072 for (auto *event : m_events) { 0073 delete event; 0074 } 0075 m_events.clear(); 0076 } 0077 0078 void EventsModel::removeAllForTask(const Task *task) 0079 { 0080 for (auto it = m_events.begin(); it != m_events.end();) { 0081 Event *event = *it; 0082 if (event->relatedTo() == task->uid()) { 0083 delete event; 0084 it = m_events.erase(it); 0085 } else { 0086 ++it; 0087 } 0088 } 0089 } 0090 0091 void EventsModel::removeByUID(const QString &uid) 0092 { 0093 for (auto it = m_events.begin(); it != m_events.end(); ++it) { 0094 Event *event = *it; 0095 if (event->uid() == uid) { 0096 delete event; 0097 m_events.erase(it); 0098 return; 0099 } 0100 } 0101 } 0102 0103 void EventsModel::addEvent(Event *event) 0104 { 0105 m_events.append(event); 0106 } 0107 0108 static KCalendarCore::Event::Ptr baseEvent(const Task *task) 0109 { 0110 qCDebug(KTT_LOG) << "Entering function"; 0111 KCalendarCore::Event::Ptr e(new KCalendarCore::Event()); 0112 QStringList categories; 0113 e->setSummary(task->name()); 0114 0115 // Can't use setRelatedToUid()--no error, but no RelatedTo written to disk 0116 e->setRelatedTo(task->uid()); 0117 0118 // Debugging: some events where not getting a related-to field written. 0119 Q_ASSERT(e->relatedTo() == task->uid()); 0120 0121 // Have to turn this off to get datetimes in date fields. 0122 e->setAllDay(false); 0123 e->setDtStart(task->startTime()); 0124 0125 // So someone can filter this mess out of their calendar display 0126 categories.append(i18n("KTimeTracker")); 0127 e->setCategories(categories); 0128 0129 return e; 0130 } 0131 0132 void EventsModel::changeTime(const Task *task, int64_t deltaSeconds) 0133 { 0134 qCDebug(KTT_LOG) << "Entering function; deltaSeconds=" << deltaSeconds; 0135 QDateTime end; 0136 auto kcalEvent = baseEvent(task); 0137 auto *e = new Event(kcalEvent); 0138 0139 // Don't use duration, as ICalFormatImpl::writeIncidence never writes a 0140 // duration, even though it looks like it's used in event.cpp. 0141 end = task->startTime(); 0142 if (deltaSeconds > 0) { 0143 end = task->startTime().addSecs(deltaSeconds); 0144 } 0145 e->setDtEnd(end); 0146 0147 // Use a custom property to keep a record of negative durations 0148 e->setDuration(deltaSeconds); 0149 0150 addEvent(e); 0151 } 0152 0153 bool EventsModel::bookTime(const Task *task, const QDateTime &startDateTime, int64_t durationInSeconds) 0154 { 0155 qCDebug(KTT_LOG) << "Entering function"; 0156 0157 auto kcalEvent = baseEvent(task); 0158 auto *e = new Event(kcalEvent); 0159 0160 e->setDtStart(startDateTime); 0161 e->setDtEnd(startDateTime.addSecs(durationInSeconds)); 0162 0163 // Use a custom property to keep a record of negative durations 0164 e->setDuration(durationInSeconds); 0165 0166 addEvent(e); 0167 return true; 0168 } 0169 0170 void EventsModel::startTask(const Task *task) 0171 { 0172 auto *e = new Event(baseEvent(task)); 0173 0174 // TODO support passing of a different start time from TimeTrackerStorage::buildTaskView? 0175 e->setDtStart(QDateTime::currentDateTime()); 0176 addEvent(e); 0177 } 0178 0179 void EventsModel::stopTask(const Task *task, const QDateTime &when) 0180 { 0181 QList<Event *> openEvents; 0182 for (auto *event : eventsForTask(task)) { 0183 if (!event->hasEndDate()) { 0184 openEvents.append(event); 0185 } 0186 } 0187 0188 if (openEvents.isEmpty()) { 0189 qCWarning(KTT_LOG) << "Task to stop has no open events, uid=" << task->uid() << ", name=" << task->name(); 0190 } else if (openEvents.size() > 1) { 0191 qCWarning(KTT_LOG) << "Task to stop has multiple open events (" << openEvents.size() << "), uid=" << task->uid() << ", name=" << task->name(); 0192 } 0193 0194 for (auto *event : openEvents) { 0195 qCDebug(KTT_LOG) << "found an event for task, event=" << event->uid(); 0196 event->setDtEnd(when); 0197 } 0198 } 0199 0200 #include "moc_eventsmodel.cpp"