8#include "multidayincidencemodel.h"
12MultiDayIncidenceModel::MultiDayIncidenceModel(
QObject *parent)
15 mRefreshTimer.setSingleShot(
true);
25 if (!
hasIndex(row, column, parent)) {
29 if (!parent.isValid()) {
40int MultiDayIncidenceModel::rowCount(
const QModelIndex &parent)
const
43 if (!parent.isValid() && mSourceModel) {
44 return qMax(mSourceModel->length() / mPeriodLength, 1);
49int MultiDayIncidenceModel::columnCount(
const QModelIndex &)
const
56 return qMax(
start.daysTo(end) + 1, 1ll);
64 const auto rowEnd = rowStart.
addDays(mPeriodLength > 1 ? mPeriodLength : 0);
65 QList<QModelIndex> sorted;
66 sorted.
reserve(mSourceModel->rowCount());
68 for (
int row = 0; row < mSourceModel->rowCount(); row++) {
69 const auto srcIdx = mSourceModel->index(row, 0, {});
70 const auto start = srcIdx.data(IncidenceOccurrenceModel::StartTime).toDateTime().date();
71 const auto end = srcIdx.data(IncidenceOccurrenceModel::EndTime).toDateTime().date();
74 if (end < rowStart || start > rowEnd) {
79 if (!incidencePassesFilter(srcIdx)) {
89 std::sort(sorted.
begin(), sorted.
end(), [&](
const QModelIndex &left,
const QModelIndex &right) {
91 const auto leftAllDay = left.data(IncidenceOccurrenceModel::AllDay).toBool();
92 const auto rightAllDay = right.data(IncidenceOccurrenceModel::AllDay).toBool();
94 const auto leftDuration =
95 getDuration(left.data(IncidenceOccurrenceModel::StartTime).toDateTime().date(), left.data(IncidenceOccurrenceModel::EndTime).toDateTime().date());
96 const auto rightDuration =
97 getDuration(right.data(IncidenceOccurrenceModel::StartTime).toDateTime().date(), right.data(IncidenceOccurrenceModel::EndTime).toDateTime().date());
99 const auto leftDt = left.data(IncidenceOccurrenceModel::StartTime).toDateTime();
100 const auto rightDt = right.data(IncidenceOccurrenceModel::StartTime).toDateTime();
102 if (leftAllDay && !rightAllDay) {
105 if (!leftAllDay && rightAllDay) {
108 if (leftAllDay && rightAllDay) {
109 return leftDuration < rightDuration;
113 return leftDt < rightDt && leftDuration <= rightDuration;
128QVariantList MultiDayIncidenceModel::layoutLines(
const QDate &rowStart)
const
130 auto getStart = [&rowStart](
const QDate &
start) {
134 QList<QModelIndex> sorted = sortedIncidencesFromSourceModel(rowStart);
142 auto result = QVariantList{};
145 const auto startDate = srcIdx.data(IncidenceOccurrenceModel::StartTime).toDateTime().date() < rowStart
147 : srcIdx.data(IncidenceOccurrenceModel::StartTime).toDateTime().date();
148 const auto start = getStart(srcIdx.data(IncidenceOccurrenceModel::StartTime).toDateTime().date());
149 const auto duration = qMin(getDuration(startDate, srcIdx.data(IncidenceOccurrenceModel::EndTime).toDateTime().date()), mPeriodLength -
start);
153 auto currentLine = QVariantList{};
155 auto addToLine = [¤tLine](
const QModelIndex &idx,
int start,
int duration) {
156 currentLine.append(QVariantMap{
157 {QStringLiteral(
"text"), idx.
data(IncidenceOccurrenceModel::Summary)},
158 {QStringLiteral(
"description"), idx.
data(IncidenceOccurrenceModel::Description)},
159 {QStringLiteral(
"location"), idx.
data(IncidenceOccurrenceModel::Location)},
160 {QStringLiteral(
"startTime"), idx.
data(IncidenceOccurrenceModel::StartTime)},
161 {QStringLiteral(
"endTime"), idx.
data(IncidenceOccurrenceModel::EndTime)},
162 {QStringLiteral(
"allDay"), idx.
data(IncidenceOccurrenceModel::AllDay)},
163 {QStringLiteral(
"todoCompleted"), idx.
data(IncidenceOccurrenceModel::TodoCompleted)},
164 {QStringLiteral(
"priority"), idx.
data(IncidenceOccurrenceModel::Priority)},
165 {QStringLiteral(
"starts"),
start},
166 {QStringLiteral(
"duration"), duration},
167 {QStringLiteral(
"durationString"), idx.
data(IncidenceOccurrenceModel::DurationString)},
168 {QStringLiteral(
"recurs"), idx.
data(IncidenceOccurrenceModel::Recurs)},
169 {QStringLiteral(
"hasReminders"), idx.
data(IncidenceOccurrenceModel::HasReminders)},
170 {QStringLiteral(
"isOverdue"), idx.
data(IncidenceOccurrenceModel::IsOverdue)},
171 {QStringLiteral(
"isReadOnly"), idx.
data(IncidenceOccurrenceModel::IsReadOnly)},
172 {QStringLiteral(
"color"), idx.
data(IncidenceOccurrenceModel::Color)},
173 {QStringLiteral(
"collectionId"), idx.
data(IncidenceOccurrenceModel::CollectionId)},
174 {QStringLiteral(
"incidenceId"), idx.
data(IncidenceOccurrenceModel::IncidenceId)},
175 {QStringLiteral(
"incidenceType"), idx.
data(IncidenceOccurrenceModel::IncidenceType)},
176 {QStringLiteral(
"incidenceTypeStr"), idx.
data(IncidenceOccurrenceModel::IncidenceTypeStr)},
177 {QStringLiteral(
"incidenceTypeIcon"), idx.
data(IncidenceOccurrenceModel::IncidenceTypeIcon)},
178 {QStringLiteral(
"incidencePtr"), idx.
data(IncidenceOccurrenceModel::IncidencePtr)},
179 {QStringLiteral(
"incidenceOccurrence"), idx.
data(IncidenceOccurrenceModel::IncidenceOccurrence)},
183 if (
start >= mPeriodLength) {
189 addToLine(srcIdx,
start, duration);
193 QBitArray takenSpaces(mPeriodLength);
195 for (
int i =
start; i <
start + duration; i++) {
196 takenSpaces[i] =
true;
199 auto doesIntersect = [&](
int start,
int end) {
201 if (takenSpaces[i]) {
209 takenSpaces[i] =
true;
214 for (
auto it = sorted.
begin(); it != sorted.
end();) {
215 const auto idx = *it;
216 const auto startDate = idx.
data(IncidenceOccurrenceModel::StartTime).
toDateTime().
date() < rowStart
220 const auto duration = qMin(getDuration(startDate, idx.
data(IncidenceOccurrenceModel::EndTime).
toDateTime().
date()), mPeriodLength -
start);
228 if (doesIntersect(
start, end)) {
231 addToLine(idx,
start, duration);
232 it = sorted.
erase(it);
249 const auto rowStart = mSourceModel->start().
addDays(idx.
row() * mPeriodLength);
251 case PeriodStartDate:
254 return layoutLines(rowStart);
270 mSourceModel = model;
272 auto resetModel = [
this] {
273 if (!mRefreshTimer.isActive()) {
276 Q_EMIT incidenceCountChanged();
277 mRefreshTimer.start(50);
289int MultiDayIncidenceModel::periodLength()
291 return mPeriodLength;
294void MultiDayIncidenceModel::setPeriodLength(
int periodLength)
296 mPeriodLength = periodLength;
299MultiDayIncidenceModel::Filters MultiDayIncidenceModel::filters()
304void MultiDayIncidenceModel::setFilters(MultiDayIncidenceModel::Filters filters)
312bool MultiDayIncidenceModel::incidencePassesFilter(
const QModelIndex &idx)
const
317 bool include =
false;
322 if (m_filters.testFlag(AllDayOnly) && idx.
data(IncidenceOccurrenceModel::AllDay).
toBool()) {
326 if (m_filters.testFlag(NoStartDateOnly) && !
start.isValid()) {
329 if (m_filters.testFlag(MultiDayOnly) && idx.
data(IncidenceOccurrenceModel::Duration).
value<KCalendarCore::Duration>().asDays() >= 1) {
342int MultiDayIncidenceModel::incidenceCount()
346 for (
int i = 0; i < rowCount({}); i++) {
347 const auto rowStart = mSourceModel->start().
addDays(i * mPeriodLength);
348 const auto rowEnd = rowStart.
addDays(mPeriodLength > 1 ? mPeriodLength : 0);
350 for (
int row = 0; row < mSourceModel->rowCount(); row++) {
351 const auto srcIdx = mSourceModel->index(row, 0, {});
352 const auto start = srcIdx.data(IncidenceOccurrenceModel::StartTime).toDateTime().date();
353 const auto end = srcIdx.data(IncidenceOccurrenceModel::EndTime).toDateTime().date();
356 if (end < rowStart || start > rowEnd) {
361 if (!incidencePassesFilter(srcIdx)) {
375 {Incidences,
"incidences"},
376 {PeriodStartDate,
"periodStartDate"},
Loads all event occurrences within the given period and matching the given filter.
Q_SCRIPTABLE QString start(QString train="")
Q_SCRIPTABLE Q_NOREPLY void start()
const QList< QKeySequence > & end()
QModelIndex createIndex(int row, int column, const void *ptr) const const
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles)
bool hasIndex(int row, int column, const QModelIndex &parent) const const
void layoutChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
void rowsInserted(const QModelIndex &parent, int first, int last)
void rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
void rowsRemoved(const QModelIndex &parent, int first, int last)
QDate addDays(qint64 ndays) const const
qint64 daysTo(QDate d) const const
QDateTime startOfDay() const const
void append(QList< T > &&value)
iterator erase(const_iterator begin, const_iterator end)
bool isEmpty() const const
void reserve(qsizetype size)
QVariant data(int role) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
QVariant fromValue(T &&value)
bool toBool() const const
QDateTime toDateTime() const const