Commit f10fccbf authored by Claudio Cambra's avatar Claudio Cambra
Browse files

Fix drag and drop and resize behaviour for recurring incidences

parent 8d458514
Pipeline #100680 passed with stage
in 5 minutes and 25 seconds
......@@ -707,6 +707,83 @@ void CalendarManager::editIncidence(IncidenceWrapper *incidenceWrapper)
});
}
void CalendarManager::updateIncidenceDates(IncidenceWrapper *incidenceWrapper, int startOffset, int endOffset, int occurrences, const QDateTime &occurrenceDate)
{ // start and end offsets are in msecs
Akonadi::Item item = m_calendar->item(incidenceWrapper->incidencePtr());
item.setPayload(incidenceWrapper->incidencePtr());
auto setNewDates = [&](KCalendarCore::Incidence::Ptr incidence) {
if (incidence->type() == KCalendarCore::Incidence::TypeTodo) {
// For to-dos endOffset is ignored because it will always be == to startOffset because we only
// support moving to-dos, not resizing them. There are no multi-day to-dos.
// Lets just call it offset to reduce confusion.
const int offset = startOffset;
KCalendarCore::Todo::Ptr todo = incidence.staticCast<KCalendarCore::Todo>();
QDateTime due = todo->dtDue();
QDateTime start = todo->dtStart();
if (due.isValid()) { // Due has priority over start.
// We will only move the due date, unlike events where we move both.
due = due.addMSecs(offset);
todo->setDtDue(due);
if (start.isValid() && start > due) {
// Start can't be bigger than due.
todo->setDtStart(due);
}
} else if (start.isValid()) {
// So we're displaying a to-do that doesn't have due date, only start...
start = start.addMSecs(offset);
todo->setDtStart(start);
} else {
// This never happens
// qCWarning(CALENDARVIEW_LOG) << "Move what? uid:" << todo->uid() << "; summary=" << todo->summary();
}
} else {
incidence->setDtStart(incidence->dtStart().addMSecs(startOffset));
if (incidence->type() == KCalendarCore::Incidence::TypeEvent) {
KCalendarCore::Event::Ptr event = incidence.staticCast<KCalendarCore::Event>();
event->setDtEnd(event->dtEnd().addMSecs(endOffset));
}
}
};
if (incidenceWrapper->incidencePtr()->recurs()) {
switch (occurrences) {
case KCalUtils::RecurrenceActions::AllOccurrences: {
// All occurrences
KCalendarCore::Incidence::Ptr oldIncidence(incidenceWrapper->incidencePtr()->clone());
setNewDates(incidenceWrapper->incidencePtr());
qDebug() << incidenceWrapper->incidenceStart();
m_changer->modifyIncidence(item, oldIncidence);
break;
}
case KCalUtils::RecurrenceActions::SelectedOccurrence: // Just this occurrence
case KCalUtils::RecurrenceActions::FutureOccurrences: { // All future occurrences
const bool thisAndFuture = (occurrences == KCalUtils::RecurrenceActions::FutureOccurrences);
auto tzedOccurrenceDate = occurrenceDate.toTimeZone(incidenceWrapper->incidenceStart().timeZone());
KCalendarCore::Incidence::Ptr newIncidence(
KCalendarCore::Calendar::createException(incidenceWrapper->incidencePtr(), tzedOccurrenceDate, thisAndFuture));
if (newIncidence) {
m_changer->startAtomicOperation(i18n("Move occurrence(s)"));
setNewDates(newIncidence);
m_changer->createIncidence(newIncidence, m_calendar->collection(incidenceWrapper->collectionId()));
m_changer->endAtomicOperation();
} else {
qDebug() << i18n("Unable to add the exception item to the calendar. No change will be done.");
}
break;
}
}
} else { // Doesn't recur
KCalendarCore::Incidence::Ptr oldIncidence(incidenceWrapper->incidencePtr()->clone());
setNewDates(incidenceWrapper->incidencePtr());
m_changer->modifyIncidence(item, oldIncidence);
}
}
bool CalendarManager::hasChildren(KCalendarCore::Incidence::Ptr incidence)
{
return !m_calendar->childIncidences(incidence->uid()).isEmpty();
......
......@@ -78,6 +78,11 @@ public:
Q_INVOKABLE void addIncidence(IncidenceWrapper *incidenceWrapper);
Q_INVOKABLE void editIncidence(IncidenceWrapper *incidenceWrapper);
Q_INVOKABLE void updateIncidenceDates(IncidenceWrapper *incidenceWrapper,
int startOffset,
int endOffset,
int occurrences = -1,
const QDateTime &occurrenceDate = QDateTime());
Q_INVOKABLE bool hasChildren(KCalendarCore::Incidence::Ptr incidence);
void deleteAllChildren(KCalendarCore::Incidence::Ptr incidence);
Q_INVOKABLE void deleteIncidence(KCalendarCore::Incidence::Ptr incidence, bool deleteChildren = false);
......
......@@ -21,6 +21,7 @@ Kirigami.Page {
signal completeTodo(var incidencePtr)
signal addSubTodo(var parentWrapper)
signal deselect()
signal moveIncidence(int startOffset, date occurrenceDate, var incidenceWrapper, Item caughtDelegate)
property var openOccurrence
property var model
......@@ -214,6 +215,7 @@ Kirigami.Page {
onCompleteTodo: monthPage.completeTodo(incidencePtr)
onAddSubTodo: monthPage.addSubTodo(parentWrapper)
onDeselect: monthPage.deselect()
onMoveIncidence: monthPage.moveIncidence(startOffset, occurrenceDate, incidenceWrapper, caughtDelegate)
}
}
}
......
......@@ -22,6 +22,7 @@ Item {
signal completeTodo(var incidencePtr)
signal addSubTodo(var parentWrapper)
signal deselect()
signal moveIncidence(int startOffset, date occurrenceDate, var incidenceWrapper, Item caughtDelegate)
property var openOccurrence
property var model
......@@ -169,8 +170,11 @@ Item {
const incidenceWrapper = Qt.createQmlObject('import org.kde.kalendar 1.0; IncidenceWrapper {id: incidence}', incidenceDropArea, "incidence");
incidenceWrapper.incidencePtr = drop.source.incidencePtr;
incidenceWrapper.collectionId = drop.source.collectionId;
incidenceWrapper.setIncidenceStartDate(backgroundDayMouseArea.addDate.getDate(), backgroundDayMouseArea.addDate.getMonth() + 1, backgroundDayMouseArea.addDate.getFullYear());
Kalendar.CalendarManager.editIncidence(incidenceWrapper);
let sameTimeOnDate = new Date(backgroundDayMouseArea.addDate);
sameTimeOnDate = new Date(sameTimeOnDate.setHours(drop.source.occurrenceDate.getHours(), drop.source.occurrenceDate.getMinutes()));
const offset = sameTimeOnDate.getTime() - drop.source.occurrenceDate.getTime();
root.moveIncidence(offset, drop.source.occurrenceDate, incidenceWrapper, drop.source);
}
}
}
......@@ -304,25 +308,6 @@ Item {
horizontalSpacing: linesRepeater.spacing
openOccurrenceId: root.openOccurrence ? root.openOccurrence.incidenceId : ""
isDark: root.isDark
states: [
State {
when: incidenceDelegate.mouseArea.drag.active
ParentChange { target: incidenceDelegate; parent: root }
PropertyChanges { target: incidenceDelegate; isOpenOccurrence: true }
},
State {
when: incidenceDelegate.caught
ParentChange { target: incidenceDelegate; parent: root }
PropertyChanges {
target: incidenceDelegate
repositionAnimationEnabled: true
x: caughtX
y: caughtY
opacity: 0
}
}
]
}
}
}
......
......@@ -14,6 +14,7 @@ Rectangle {
id: incidenceDelegate
x: ((dayWidth + parentViewSpacing) * modelData.starts) + horizontalSpacing
y: 0
z: 10
width: ((dayWidth + parentViewSpacing) * modelData.duration) - (horizontalSpacing * 2) - parentViewSpacing // Account for spacing added to x and for spacing at end of line
//Behavior on width { NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic } }
......@@ -56,6 +57,8 @@ Rectangle {
property alias mouseArea: mouseArea
property var incidencePtr: modelData.incidencePtr
property var collectionId: modelData.collectionId
property date occurrenceDate: modelData.startTime
property date occurrenceEndDate: modelData.endTime
property bool repositionAnimationEnabled: false
property bool caught: false
property real caughtX: 0
......@@ -65,6 +68,32 @@ Rectangle {
Drag.hotSpot.x: mouseArea.mouseX
Drag.hotSpot.y: mouseArea.mouseY
states: [
State {
when: !incidenceDelegate.mouseArea.drag.active && !incidenceDelegate.caught
},
State {
when: incidenceDelegate.mouseArea.drag.active
ParentChange { target: incidenceDelegate; parent: root }
PropertyChanges {
target: incidenceDelegate
isOpenOccurrence: true
y: 0
}
},
State {
when: incidenceDelegate.caught
ParentChange { target: incidenceDelegate; parent: root }
PropertyChanges {
target: incidenceDelegate
repositionAnimationEnabled: true
x: caughtX
y: caughtY
opacity: 0
}
}
]
IncidenceBackground {
id: incidenceBackground
isOpenOccurrence: parent.isOpenOccurrence
......
// SPDX-FileCopyrightText: 2021 Claudio Cambra <claudio.cambra@gmail.com>
// SPDX-License-Identifier: LGPL-2.1-or-later
import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami
import org.kde.kalendar 1.0
Kirigami.Page {
id: deleteSheet
signal changeAll
signal changeThis
signal changeThisAndFuture
signal cancel
// For incidence deletion
property var incidenceWrapper
property bool isMove: false
property int startOffset: 0
property int endOffset: 0
property date occurrenceDate
property Item caughtDelegate
padding: Kirigami.Units.largeSpacing
title: i18n("Change incidence date")
ColumnLayout {
anchors.fill: parent
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: true
QQC2.Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: i18n("The item you are trying to change is a recurring item. Should the changes be applied only to this single occurrence, also to future items, or to all items in the recurrence?")
wrapMode: Text.WordWrap
}
}
Kirigami.ActionToolBar {
Layout.fillWidth: true
flat: false
alignment: Qt.AlignRight
actions: [
QQC2.Action {
icon.name: "deletecell"
enabled: incidenceWrapper !== undefined
shortcut: "Return"
text: i18n("Only This Item")
onTriggered: changeThis()
},
QQC2.Action {
icon.name: "edit-table-delete-row"
text: i18n("Also Future Items")
onTriggered: changeThisAndFuture()
},
QQC2.Action {
icon.name: "group-delete"
text: i18n("All Occurrences")
onTriggered: changeAll()
},
QQC2.Action {
icon.name: "dialog-cancel"
text: i18n("Cancel")
onTriggered: cancel()
}
]
}
}
}
......@@ -21,6 +21,7 @@ Kirigami.Page {
signal completeTodo(var incidencePtr)
signal addSubTodo(var parentWrapper)
signal deselect()
signal moveIncidence(int startOffset, date occurrenceDate, var incidenceWrapper, Item caughtDelegate)
onAddIncidence: pathView.currentItem.item.savedYScrollPos = pathView.currentItem.item.QQC2.ScrollBar.vertical.visualPosition
onViewIncidence: pathView.currentItem.item.savedYScrollPos = pathView.currentItem.item.QQC2.ScrollBar.vertical.visualPosition
......@@ -28,6 +29,7 @@ Kirigami.Page {
onDeleteIncidence: pathView.currentItem.item.savedYScrollPos = pathView.currentItem.item.QQC2.ScrollBar.vertical.visualPosition
onCompleteTodo: pathView.currentItem.item.savedYScrollPos = pathView.currentItem.item.QQC2.ScrollBar.vertical.visualPosition
onAddSubTodo: pathView.currentItem.item.savedYScrollPos = pathView.currentItem.item.QQC2.ScrollBar.vertical.visualPosition
onMoveIncidence: pathView.currentItem.item.savedYScrollPos = pathView.currentItem.item.QQC2.ScrollBar.vertical.visualPosition
property var openOccurrence
property var model
......@@ -257,8 +259,11 @@ Kirigami.Page {
const incidenceWrapper = Qt.createQmlObject('import org.kde.kalendar 1.0; IncidenceWrapper {id: incidence}', incidenceDropArea, "incidence");
incidenceWrapper.incidencePtr = drop.source.incidencePtr;
incidenceWrapper.collectionId = drop.source.collectionId;
incidenceWrapper.setIncidenceStartDate(dayMouseArea.addDate.getDate(), dayMouseArea.addDate.getMonth() + 1, dayMouseArea.addDate.getFullYear());
Kalendar.CalendarManager.editIncidence(incidenceWrapper);
let sameTimeOnDate = new Date(dayMouseArea.addDate);
sameTimeOnDate = new Date(sameTimeOnDate.setHours(drop.source.occurrenceDate.getHours(), drop.source.occurrenceDate.getMinutes()));
const offset = sameTimeOnDate.getTime() - drop.source.occurrenceDate.getTime();
root.moveIncidence(offset, drop.source.occurrenceDate, incidenceWrapper, drop.source);
}
}
......@@ -395,6 +400,8 @@ Kirigami.Page {
property alias mouseArea: incidenceMouseArea
property var incidencePtr: modelData.incidencePtr
property var collectionId: modelData.collectionId
property date occurrenceDate: modelData.startTime
property date occurrenceEndDate: modelData.endTime
property bool repositionAnimationEnabled: false
property bool caught: false
property real caughtX: 0
......
......@@ -21,6 +21,8 @@ Kirigami.Page {
signal completeTodo(var incidencePtr)
signal addSubTodo(var parentWrapper)
signal deselect()
signal moveIncidence(int startOffset, date occurrenceDate, var incidenceWrapper, Item caughtDelegate)
signal resizeIncidence(int endOffset, date occurrenceDate, var incidenceWrapper, Item caughtDelegate)
property var openOccurrence: {}
property var model
......@@ -446,8 +448,11 @@ Kirigami.Page {
const incidenceWrapper = Qt.createQmlObject('import org.kde.kalendar 1.0; IncidenceWrapper {id: incidence}', incidenceDropArea, "incidence");
incidenceWrapper.incidencePtr = drop.source.incidencePtr;
incidenceWrapper.collectionId = drop.source.collectionId;
incidenceWrapper.setIncidenceStartDate(listViewMenu.addDate.getDate(), listViewMenu.addDate.getMonth() + 1, listViewMenu.addDate.getFullYear());
Kalendar.CalendarManager.editIncidence(incidenceWrapper);
let sameTimeOnDate = new Date(listViewMenu.addDate);
sameTimeOnDate = new Date(sameTimeOnDate.setHours(drop.source.occurrenceDate.getHours(), drop.source.occurrenceDate.getMinutes()));
const offset = sameTimeOnDate.getTime() - drop.source.occurrenceDate.getTime();
root.moveIncidence(offset, drop.source.occurrenceDate, incidenceWrapper, drop.source);
}
}
}
......@@ -476,24 +481,6 @@ Kirigami.Page {
openOccurrenceId: root.openOccurrence ? root.openOccurrence.incidenceId : ""
isDark: root.isDark
reactToCurrentMonth: false
states: [
State {
when: incidenceDelegate.mouseArea.drag.active
ParentChange { target: incidenceDelegate; parent: root }
PropertyChanges { target: incidenceDelegate; isOpenOccurrence: true }
},
State {
when: incidenceDelegate.caught
ParentChange { target: incidenceDelegate; parent: root }
PropertyChanges {
target: incidenceDelegate
repositionAnimationEnabled: true
x: caughtX
y: caughtY
}
}
]
}
}
}
......@@ -742,9 +729,8 @@ Kirigami.Page {
// We want the date as if it were "from the top" of the droparea
const posDate = new Date(backgroundDayMouseArea.addDate.getFullYear(), backgroundDayMouseArea.addDate.getMonth(), backgroundDayMouseArea.addDate.getDate(), backgroundRectangle.index, dropAreaRepeater.minutes * index);
// This is a case where we want to set datetime according to the view timezone
incidenceWrapper.setIncidenceStart(posDate, true);
Kalendar.CalendarManager.editIncidence(incidenceWrapper);
const startOffset = posDate.getTime() - drop.source.occurrenceDate.getTime();
root.moveIncidence(startOffset, drop.source.occurrenceDate, incidenceWrapper, drop.source);
} else { // The resize affects the end time
incidenceWrapper.incidencePtr = drop.source.parent.incidencePtr;
......@@ -760,8 +746,9 @@ Kirigami.Page {
const hour = isNextHour ? backgroundRectangle.index + 1 : backgroundRectangle.index;
const posDate = new Date(backgroundDayMouseArea.addDate.getFullYear(), backgroundDayMouseArea.addDate.getMonth(), backgroundDayMouseArea.addDate.getDate(), hour, minute);
incidenceWrapper.setIncidenceEnd(posDate, true);
Kalendar.CalendarManager.editIncidence(incidenceWrapper);
const endOffset = posDate.getTime() - drop.source.parent.occurrenceEndDate.getTime();
root.resizeIncidence(endOffset, drop.source.parent.occurrenceDate, incidenceWrapper, drop.source.parent);
}
}
......@@ -809,6 +796,8 @@ Kirigami.Page {
property alias mouseArea: mouseArea
property var incidencePtr: modelData.incidencePtr
property var collectionId: modelData.collectionId
property date occurrenceDate: modelData.startTime
property date occurrenceEndDate: modelData.endTime
property bool repositionAnimationEnabled: false
property bool caught: false
property real caughtX: x
......
......@@ -866,7 +866,7 @@ Kirigami.ApplicationWindow {
incidenceWrapper: incidenceWrapper,
deleteDate: deleteDate
}, {
width: Kirigami.Units.gridUnit * 30,
width: Kirigami.Units.gridUnit * 32,
height: Kirigami.Units.gridUnit * 6
});
......@@ -886,6 +886,28 @@ Kirigami.ApplicationWindow {
}
}
function setUpIncidenceDateChange(incidenceWrapper, startOffset, endOffset, occurrenceDate, caughtDelegate) {
if(incidenceWrapper.recurrenceData.type === 0) {
CalendarManager.updateIncidenceDates(incidenceWrapper, startOffset, endOffset);
} else {
const openDialogWindow = pageStack.pushDialogLayer(recurringIncidenceChangeSheetComponent, {
incidenceWrapper: incidenceWrapper,
startOffset: startOffset,
endOffset: endOffset,
occurrenceDate: occurrenceDate,
caughtDelegate: caughtDelegate
}, {
width: Kirigami.Units.gridUnit * 34,
height: Kirigami.Units.gridUnit * 6,
onClosing: caughtDelegate.caught = false
});
if(!Kirigami.Settings.isMobile) {
openDialogWindow.Keys.escapePressed.connect(function() { openDialogWindow.closeDialog() });
}
}
}
Component {
id: deleteIncidenceSheetComponent
DeleteIncidenceSheet {
......@@ -953,6 +975,30 @@ Kirigami.ApplicationWindow {
}
}
Component {
id: recurringIncidenceChangeSheetComponent
RecurringIncidenceChangeSheet {
id: recurringIncidenceChangeSheet
onChangeAll: {
CalendarManager.updateIncidenceDates(incidenceWrapper, startOffset, endOffset, IncidenceWrapper.AllOccurrences);
closeDialog();
}
onChangeThis: {
CalendarManager.updateIncidenceDates(incidenceWrapper, startOffset, endOffset, IncidenceWrapper.SelectedOccurrence, occurrenceDate);
closeDialog();
}
onChangeThisAndFuture: {
CalendarManager.updateIncidenceDates(incidenceWrapper, startOffset, endOffset, IncidenceWrapper.FutureOccurrences, occurrenceDate);
closeDialog();
}
onCancel: {
caughtDelegate.caught = false;
closeDialog();
}
}
}
Loader {
id: monthScaleModelLoader
active: Config.lastOpenedView === Config.MonthView || Config.lastOpenedView === Config.ScheduleView
......@@ -997,6 +1043,7 @@ Kirigami.ApplicationWindow {
onCompleteTodo: root.completeTodo(incidencePtr)
onAddSubTodo: root.setUpAddSubTodo(parentWrapper)
onDeselect: incidenceInfo.close()
onMoveIncidence: root.setUpIncidenceDateChange(incidenceWrapper, startOffset, startOffset, occurrenceDate, caughtDelegate)
onMonthChanged: if(month !== root.selectedDate.getMonth() && !initialMonth) root.selectedDate = new Date (year, month, 1)
onYearChanged: if(year !== root.selectedDate.getFullYear() && !initialMonth) root.selectedDate = new Date (year, month, 1)
......@@ -1035,6 +1082,7 @@ Kirigami.ApplicationWindow {
onCompleteTodo: root.completeTodo(incidencePtr)
onAddSubTodo: root.setUpAddSubTodo(parentWrapper)
onDeselect: incidenceInfo.close()
onMoveIncidence: root.setUpIncidenceDateChange(incidenceWrapper, startOffset, startOffset, occurrenceDate, caughtDelegate)
actions.contextualActions: createAction
}
......@@ -1071,6 +1119,8 @@ Kirigami.ApplicationWindow {
onCompleteTodo: root.completeTodo(incidencePtr)
onAddSubTodo: root.setUpAddSubTodo(parentWrapper)
onDeselect: incidenceInfo.close()
onMoveIncidence: root.setUpIncidenceDateChange(incidenceWrapper, startOffset, startOffset, occurrenceDate, caughtDelegate) // We move the entire incidence
onResizeIncidence: root.setUpIncidenceDateChange(incidenceWrapper, 0, endOffset, occurrenceDate, caughtDelegate)
actions.contextualActions: createAction
}
......
......@@ -121,58 +121,47 @@ void IncidenceOccurrenceModel::updateFromSource()
load();
if (m_coreCalendar) {
const auto allEvents = m_coreCalendar->events(mStart, mEnd); // get all events
const auto allTodos = m_coreCalendar->todos(mStart, mEnd);
Incidence::List allIncidences = Calendar::mergeIncidenceList(allEvents, allTodos, {});
// process all recurring events and their exceptions.
for (const auto &incidence : allIncidences) {
KCalendarCore::MemoryCalendar calendar{QTimeZone::systemTimeZone()};
calendar.addIncidence(incidence);
KCalendarCore::OccurrenceIterator occurrenceIterator{calendar, QDateTime{mStart, {0, 0, 0}}, QDateTime{mEnd, {12, 59, 59}}};
while (occurrenceIterator.hasNext()) {
occurrenceIterator.next();
const auto incidence = occurrenceIterator.incidence();
if (mFilter.contains(QLatin1String("tags")) && mFilter[QLatin1String("tags")].toStringList().length() > 0) {
bool match = false;
QStringList tags = mFilter[QLatin1String("tags")].toStringList();
for (const auto &tag : tags) {
if (incidence->categories().contains(tag)) {
match = true;
break;
}
KCalendarCore::OccurrenceIterator occurrenceIterator{*m_coreCalendar, QDateTime{mStart, {0, 0, 0}}, QDateTime{mEnd, {12, 59, 59}}};
while (occurrenceIterator.hasNext()) {
occurrenceIterator.next();
const auto incidence = occurrenceIterator.incidence();
if (mFilter.contains(QLatin1String("tags")) && mFilter[QLatin1String("tags")].toStringList().length() > 0) {
bool match = false;
QStringList tags = mFilter[QLatin1String("tags")].toStringList();
for (const auto &tag : tags) {
if (incidence->categories().contains(tag)) {
match = true;
break;
}
}
if (!match) {
continue;
}
if (!match) {
continue;
}
}
auto start = occurrenceIterator.occurrenceStartDate();
auto end = incidence->endDateForStart(start);
auto start = occurrenceIterator.occurrenceStartDate();
auto end = incidence->endDateForStart(start);
if (incidence->type() == KCalendarCore::Incidence::IncidenceType::TypeTodo) {
KCalendarCore::Todo::Ptr todo = incidence.staticCast<KCalendarCore::Todo>();
if (incidence->type() == KCalendarCore::Incidence::IncidenceType::TypeTodo) {
KCalendarCore::Todo::Ptr todo = incidence.staticCast<KCalendarCore::Todo>();
if (!start.isValid()) { // Todos are very likely not to have a set start date
start = todo->dtDue();
}
if (!start.isValid()) { // Todos are very likely not to have a set start date
start = todo->dtDue();
}
}
if (start.date() < mEnd && end.date() >= mStart) {
m_incidences.append(Occurrence{
start,
end,
incidence,
getColor(incidence),
getCollectionId(incidence),
incidence->allDay(),
});
}
if (start.date() < mEnd && end.date() >= mStart) {
m_incidences.append(Occurrence{
start,
end,
incidence,
getColor(incidence),
getCollectionId(incidence),
incidence->allDay(),
});
}
}
}
......