From 98ba7836da96585ee4d2f51ca697feafc6f24ed3 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 15 Jun 2021 01:42:47 +0200 Subject: [PATCH 01/43] Added new RemindersModel --- src/CMakeLists.txt | 2 +- src/remindersmodel.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++ src/remindersmodel.h | 44 +++++++++++++++++++++++ 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/remindersmodel.cpp create mode 100644 src/remindersmodel.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b31522f7..a0ac3ba4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: BSD-2-Clause -add_executable(kalendar about.cpp main.cpp agentconfiguration.cpp eventoccurrencemodel.cpp calendarmanager.cpp multidayeventmodel.cpp eventwrapper.cpp resources.qrc) +add_executable(kalendar about.cpp main.cpp agentconfiguration.cpp eventoccurrencemodel.cpp calendarmanager.cpp multidayeventmodel.cpp eventwrapper.cpp remindersmodel.cpp resources.qrc) target_link_libraries(kalendar Qt5::Core diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp new file mode 100644 index 00000000..37e04d19 --- /dev/null +++ b/src/remindersmodel.cpp @@ -0,0 +1,81 @@ +// SPDX-FileCopyrightText: 2021 Claudio Cambra +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include +#include + +RemindersModel::RemindersModel(QObject *parent) + : QAbstractItemModel(parent) + , m_event(nullptr) +{ + QObject::connect(this, &RemindersModel::eventPtrChanged, this, &RemindersModel::loadReminders); +} + +KCalendarCore::Event::Ptr RemindersModel::eventPtr() +{ + return m_event; +} + +void RemindersModel::setEventPtr(KCalendarCore::Event::Ptr event) +{ + if (m_event == event) { + return; + } + m_event = event; + Q_EMIT eventPtrChanged(); +} + +void RemindersModel::loadReminders() +{ + if (!m_event) { + return; + } + beginResetModel(); + m_alarms = m_event->alarms(); +} + +QVariant RemindersModel::data(const QModelIndex &idx, int role) const +{ + if (!hasIndex(idx.row(), idx.column())) { + return {}; + } + auto alarm = m_alarms.at(idx.row()); + switch (role) { + case Type: + return alarm->type(); + case Time: + return alarm->time(); + case StartOffset: + return alarm->startOffset().asSeconds(); + case EndOffset: + return alarm->endOffset().asSeconds(); + default: + qWarning() << "Unknown role for event:" << QMetaEnum::fromType().valueToKey(role); + return {}; + } +} + +QModelIndex RemindersModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) { + return {}; + } + + if (!parent.isValid()) { + return createIndex(row, column); + } + return {}; +} + +QModelIndex RemindersModel::parent(const QModelIndex &) const +{ + return {}; +} + +int RemindersModel::rowCount(const QModelIndex &parent) const +{ + if (!parent.isValid()) { + return m_alarms.size(); + } + return 0; +} diff --git a/src/remindersmodel.h b/src/remindersmodel.h new file mode 100644 index 00000000..2059f0dc --- /dev/null +++ b/src/remindersmodel.h @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: 2021 Claudio Cambra +// SPDX-License-Identifier: LGPL-2.1-or-later + +#pragma once + +#include +#include +#include +#include +#include + +class RemindersModel : public QAbstractItemModel +{ + Q_OBJECT + Q_PROPERTY(KCalendarCore::Event::Ptr eventPtr READ eventPtr WRITE setEventPtr NOTIFY eventPtrChanged) + +public: + enum Roles { + Type = Qt::UserRole + 1, + Time, + StartOffset, + EndOffset + }; + Q_ENUM(Roles); + + explicit RemindersModel(QObject *parent = nullptr); + ~RemindersModel(); + + KCalendarCore::Event::Ptr eventPtr(); + void setEventPtr(KCalendarCore::Event::Ptr event); + void loadReminders(); + + QVariant data(const QModelIndex &idx, int role) const override; + QModelIndex index(int row, int column, const QModelIndex &parent) const override; + QModelIndex parent(const QModelIndex &) const override; + int rowCount(const QModelIndex &parent) const override; + +Q_SIGNALS: + void eventPtrChanged(); + +private: + KCalendarCore::Event::Ptr m_event; + KCalendarCore::Alarm::List m_alarms; +}; -- GitLab From af0f70875ec44762dc94c937f534636f896fd938 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 15 Jun 2021 12:27:48 +0200 Subject: [PATCH 02/43] Added default to RemindersModel destructor, added columncount method --- src/remindersmodel.cpp | 5 +++++ src/remindersmodel.h | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index 37e04d19..823d5241 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -79,3 +79,8 @@ int RemindersModel::rowCount(const QModelIndex &parent) const } return 0; } + +int RemindersModel::columnCount(const QModelIndex &) const +{ + return 1; +} diff --git a/src/remindersmodel.h b/src/remindersmodel.h index 2059f0dc..48065bdc 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -24,7 +24,7 @@ public: Q_ENUM(Roles); explicit RemindersModel(QObject *parent = nullptr); - ~RemindersModel(); + ~RemindersModel() = default; KCalendarCore::Event::Ptr eventPtr(); void setEventPtr(KCalendarCore::Event::Ptr event); @@ -33,7 +33,8 @@ public: QVariant data(const QModelIndex &idx, int role) const override; QModelIndex index(int row, int column, const QModelIndex &parent) const override; QModelIndex parent(const QModelIndex &) const override; - int rowCount(const QModelIndex &parent) const override; + int rowCount(const QModelIndex &parent = {}) const override; + int columnCount(const QModelIndex &parent) const override; Q_SIGNALS: void eventPtrChanged(); -- GitLab From 8833dd49e05b66fb3036a932b55d834691a90880 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 15 Jun 2021 17:03:09 +0200 Subject: [PATCH 03/43] Can now add reminders to RemindersModel --- src/contents/ui/EventEditor.qml | 108 ++++++++++++++++---------------- src/eventwrapper.cpp | 19 +++--- src/eventwrapper.h | 9 ++- src/remindersmodel.cpp | 8 +++ src/remindersmodel.h | 4 +- 5 files changed, 79 insertions(+), 69 deletions(-) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 870bec9f..387b883a 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -268,6 +268,7 @@ Kirigami.OverlaySheet { } } } + QQC2.ComboBox { id: repeatComboBox Kirigami.FormData.label: i18n("Repeat:") @@ -289,6 +290,7 @@ Kirigami.OverlaySheet { placeholderText: i18n("Optional") Layout.fillWidth: true } + ColumnLayout { Kirigami.FormData.label: i18n("Reminder:") Layout.fillWidth: true @@ -303,66 +305,62 @@ Kirigami.OverlaySheet { property int buttonIndex: 0 - onClicked: { - var newReminder = Qt.createQmlObject(` - import QtQuick 2.15 - import QtQuick.Controls 2.15 as QQC2 - import QtQuick.Layouts 1.15 - import org.kde.kirigami 2.15 as Kirigami - - - RowLayout { - Layout.fillWidth: true + onClicked: event.remindersModel.addAlarm(); + } - QQC2.ComboBox { - id: remindersComboBox${buttonIndex} - Layout.fillWidth: true + Repeater { + Layout.fillWidth: true - function secondsToReminderLabel(seconds) { - if (seconds) { - var numAndUnit = ( - seconds >= 2 * 24 * 60 * 60 ? Math.round(seconds / (24*60*60)) + " days" : // 2 days + - seconds >= 1 * 24 * 60 * 60 ? "1 day" : - seconds >= 2 * 60 * 60 ? Math.round(seconds / (60*60)) + " hours" : // 2 hours + - seconds >= 1 * 60 * 60 ? "1 hour" : - Math.round(seconds / 60) + " minutes") - return numAndUnit + " before"; - } else { - return "On event start"; - } - } - - property var beforeEventSeconds: 0 - - displayText: secondsToReminderLabel(Number(currentText)) - - model: [0, - 5 * 60, // 5 minutes - 10 * 60, - 15 * 60, - 30 * 60, - 45 * 60, - 1 * 60 * 60, // 1 hour - 2 * 60 * 60, - 1 * 24 * 60 * 60, // 1 day - 2 * 24 * 60 * 60, - 5 * 24 * 60 * 60] - // All these times are in seconds. - delegate: Kirigami.BasicListItem { - label: remindersComboBox${buttonIndex}.secondsToReminderLabel(modelData) - onClicked: remindersComboBox${buttonIndex}.beforeEventSeconds = modelData - } - popup.z: 1000 + model: event.remindersModel + + delegate: RowLayout { + Layout.fillWidth: true + + QQC2.ComboBox { + //id: remindersComboBox${buttonIndex} + Layout.fillWidth: true + + function secondsToReminderLabel(seconds) { + if (seconds) { + var numAndUnit = ( + seconds >= 2 * 24 * 60 * 60 ? Math.round(seconds / (24*60*60)) + " days" : // 2 days + + seconds >= 1 * 24 * 60 * 60 ? "1 day" : + seconds >= 2 * 60 * 60 ? Math.round(seconds / (60*60)) + " hours" : // 2 hours + + seconds >= 1 * 60 * 60 ? "1 hour" : + Math.round(seconds / 60) + " minutes") + return numAndUnit + " before"; + } else { + return "On event start"; } + } - QQC2.Button { - icon.name: "edit-delete-remove" - onClicked: parent.destroy() - } + property var beforeEventSeconds: 0 + + displayText: secondsToReminderLabel(Number(currentText)) + + model: [0, + 5 * 60, // 5 minutes + 10 * 60, + 15 * 60, + 30 * 60, + 45 * 60, + 1 * 60 * 60, // 1 hour + 2 * 60 * 60, + 1 * 24 * 60 * 60, // 1 day + 2 * 24 * 60 * 60, + 5 * 24 * 60 * 60] + // All these times are in seconds. + delegate: Kirigami.BasicListItem { + label: parent.secondsToReminderLabel(modelData) + onClicked: parent.beforeEventSeconds = modelData } - `, this.parent, `remindersComboBox${buttonIndex}`) - remindersColumn.reminderCombos.push(newReminder) - buttonIndex += 1 + popup.z: 1000 + } + + QQC2.Button { + icon.name: "edit-delete-remove" + onClicked: parent.destroy() + } } } } diff --git a/src/eventwrapper.cpp b/src/eventwrapper.cpp index d368423e..0cb35790 100644 --- a/src/eventwrapper.cpp +++ b/src/eventwrapper.cpp @@ -6,13 +6,10 @@ EventWrapper::EventWrapper(QObject *parent) : QObject(parent) , m_event(new KCalendarCore::Event) + , m_remindersModel(parent) { - -} - -EventWrapper::~EventWrapper() -{ - + m_remindersModel.setEventPtr(m_event); + m_remindersModel.loadReminders(); } KCalendarCore::Event::Ptr EventWrapper::eventPtr() const @@ -91,11 +88,12 @@ KCalendarCore::Attendee::List EventWrapper::attendees() const return m_event->attendees(); } -KCalendarCore::Alarm::List EventWrapper::alarms() const +RemindersModel * EventWrapper::remindersModel() { - return m_event->alarms(); + return &m_remindersModel; } + void EventWrapper::setAllDay(bool allDay) { m_event->setAllDay(allDay); @@ -104,13 +102,14 @@ void EventWrapper::setAllDay(bool allDay) void EventWrapper::addAlarm(int startOffset, KCalendarCore::Alarm::Type alarmType) { - KCalendarCore::Alarm::Ptr alarm (new KCalendarCore::Alarm(nullptr)); + /*KCalendarCore::Alarm::Ptr alarm (new KCalendarCore::Alarm(nullptr)); // offset can be set in seconds or days, if we want it to be before the event, // it has to be set to a negative value. KCalendarCore::Duration offset(startOffset *= -1); m_event->addAlarm(alarm); alarm ->setType(alarmType); - alarm->setStartOffset(offset); + alarm->setStartOffset(offset);*/ + m_remindersModel.addAlarm(); } diff --git a/src/eventwrapper.h b/src/eventwrapper.h index 6cf6ee8f..ff06d2d8 100644 --- a/src/eventwrapper.h +++ b/src/eventwrapper.h @@ -7,6 +7,7 @@ #include #include #include +#include "remindersmodel.h" /** * This class is a wrapper for a KCalendarCore::Event::Ptr object. @@ -27,11 +28,11 @@ class EventWrapper : public QObject Q_PROPERTY(QDateTime eventEnd READ eventEnd WRITE setEventEnd NOTIFY eventEndChanged) Q_PROPERTY(KCalendarCore::Recurrence * recurrence READ recurrence) Q_PROPERTY(KCalendarCore::Attendee::List attendees READ attendees) - Q_PROPERTY(KCalendarCore::Alarm::List alarms READ alarms) + Q_PROPERTY(RemindersModel * remindersModel READ remindersModel NOTIFY remindersModelChanged) public: EventWrapper(QObject *parent = nullptr); - ~EventWrapper() override; + ~EventWrapper() = default; KCalendarCore::Event::Ptr eventPtr() const; void setEventPtr(KCalendarCore::Event::Ptr eventPtr); @@ -47,7 +48,7 @@ public: void setEventEnd(QDateTime eventEnd); KCalendarCore::Recurrence * recurrence() const; KCalendarCore::Attendee::List attendees() const; - KCalendarCore::Alarm::List alarms() const; + RemindersModel * remindersModel(); Q_INVOKABLE void setAllDay(bool allDay); Q_INVOKABLE void addAlarm(int startOffset, KCalendarCore::Alarm::Type alarmType = KCalendarCore::Alarm::Type::Display); @@ -59,7 +60,9 @@ Q_SIGNALS: void locationChanged(); void eventStartChanged(); void eventEndChanged(); + void remindersModelChanged(); private: KCalendarCore::Event::Ptr m_event; + RemindersModel m_remindersModel; }; diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index 823d5241..ef9b1847 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -32,6 +32,7 @@ void RemindersModel::loadReminders() } beginResetModel(); m_alarms = m_event->alarms(); + endResetModel(); } QVariant RemindersModel::data(const QModelIndex &idx, int role) const @@ -84,3 +85,10 @@ int RemindersModel::columnCount(const QModelIndex &) const { return 1; } + +void RemindersModel::addAlarm() +{ + beginInsertRows(index(rowCount(), 0), rowCount(), rowCount()); + endInsertRows(); + qDebug() << rowCount(); +} diff --git a/src/remindersmodel.h b/src/remindersmodel.h index 48065bdc..d5329bd2 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -31,11 +31,13 @@ public: void loadReminders(); QVariant data(const QModelIndex &idx, int role) const override; - QModelIndex index(int row, int column, const QModelIndex &parent) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex &) const override; int rowCount(const QModelIndex &parent = {}) const override; int columnCount(const QModelIndex &parent) const override; + Q_INVOKABLE void addAlarm(); + Q_SIGNALS: void eventPtrChanged(); -- GitLab From 0dc20a2988f867d64e68af6ae8fb13d87ebbf915 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 15 Jun 2021 18:40:48 +0200 Subject: [PATCH 04/43] Can now also delete reminders from RemindersModel, updated in eventeditor --- src/contents/ui/EventEditor.qml | 39 +++++++++++++++++++-------------- src/remindersmodel.cpp | 22 +++++++++++++++++-- src/remindersmodel.h | 2 ++ 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 387b883a..030117d8 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -296,6 +296,20 @@ Kirigami.OverlaySheet { Layout.fillWidth: true id: remindersColumn + function secondsToReminderLabel(seconds) { + if (seconds) { + var numAndUnit = ( + seconds >= 2 * 24 * 60 * 60 ? Math.round(seconds / (24*60*60)) + " days" : // 2 days + + seconds >= 1 * 24 * 60 * 60 ? "1 day" : + seconds >= 2 * 60 * 60 ? Math.round(seconds / (60*60)) + " hours" : // 2 hours + + seconds >= 1 * 60 * 60 ? "1 hour" : + Math.round(seconds / 60) + " minutes") + return numAndUnit + " before"; + } else { + return "On event start"; + } + } + property var reminderCombos: [] QQC2.Button { @@ -309,34 +323,25 @@ Kirigami.OverlaySheet { } Repeater { + id: remindersRepeater Layout.fillWidth: true model: event.remindersModel + Component.onCompleted: console.log(Object.keys(model)) + delegate: RowLayout { Layout.fillWidth: true + Component.onCompleted: console.log(model.index) + QQC2.ComboBox { //id: remindersComboBox${buttonIndex} Layout.fillWidth: true - function secondsToReminderLabel(seconds) { - if (seconds) { - var numAndUnit = ( - seconds >= 2 * 24 * 60 * 60 ? Math.round(seconds / (24*60*60)) + " days" : // 2 days + - seconds >= 1 * 24 * 60 * 60 ? "1 day" : - seconds >= 2 * 60 * 60 ? Math.round(seconds / (60*60)) + " hours" : // 2 hours + - seconds >= 1 * 60 * 60 ? "1 hour" : - Math.round(seconds / 60) + " minutes") - return numAndUnit + " before"; - } else { - return "On event start"; - } - } - property var beforeEventSeconds: 0 - displayText: secondsToReminderLabel(Number(currentText)) + displayText: remindersColumn.secondsToReminderLabel(Number(currentText)) model: [0, 5 * 60, // 5 minutes @@ -351,7 +356,7 @@ Kirigami.OverlaySheet { 5 * 24 * 60 * 60] // All these times are in seconds. delegate: Kirigami.BasicListItem { - label: parent.secondsToReminderLabel(modelData) + label: remindersColumn.secondsToReminderLabel(modelData) onClicked: parent.beforeEventSeconds = modelData } popup.z: 1000 @@ -359,7 +364,7 @@ Kirigami.OverlaySheet { QQC2.Button { icon.name: "edit-delete-remove" - onClicked: parent.destroy() + onClicked: event.remindersModel.deleteAlarm(model.index); } } } diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index ef9b1847..a3744530 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -40,7 +40,7 @@ QVariant RemindersModel::data(const QModelIndex &idx, int role) const if (!hasIndex(idx.row(), idx.column())) { return {}; } - auto alarm = m_alarms.at(idx.row()); + auto alarm = m_alarms[idx.row()]; switch (role) { case Type: return alarm->type(); @@ -88,7 +88,25 @@ int RemindersModel::columnCount(const QModelIndex &) const void RemindersModel::addAlarm() { - beginInsertRows(index(rowCount(), 0), rowCount(), rowCount()); + QModelIndex indexToUse = index(rowCount(), 0); + beginInsertRows(indexToUse, rowCount(), rowCount()); + + KCalendarCore::Alarm::Ptr alarm (new KCalendarCore::Alarm(nullptr)); + m_alarms.append(alarm); + Q_EMIT alarmsChanged(); + endInsertRows(); +} + +void RemindersModel::deleteAlarm(int row) +{ + QModelIndex indexToUse = index(row, 0); + beginRemoveRows(indexToUse, row, row); + + m_alarms.removeAt(row); qDebug() << rowCount(); + Q_EMIT alarmsChanged(); + + endRemoveRows(); + Q_EMIT layoutChanged(); } diff --git a/src/remindersmodel.h b/src/remindersmodel.h index d5329bd2..4a75b06e 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -37,9 +37,11 @@ public: int columnCount(const QModelIndex &parent) const override; Q_INVOKABLE void addAlarm(); + Q_INVOKABLE void deleteAlarm(int row); Q_SIGNALS: void eventPtrChanged(); + void alarmsChanged(); private: KCalendarCore::Event::Ptr m_event; -- GitLab From 0e47f916e3146d78d1e34f5ab1248e8f1c428a04 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 15 Jun 2021 23:54:13 +0200 Subject: [PATCH 05/43] Added alarm modification functions in RemindersModel, modified eventwrapper a bit --- src/eventwrapper.cpp | 17 +++++++---------- src/eventwrapper.h | 4 ++-- src/remindersmodel.cpp | 28 ++++++++++++++++++++++++++++ src/remindersmodel.h | 4 ++++ 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/eventwrapper.cpp b/src/eventwrapper.cpp index 0cb35790..e724e4d0 100644 --- a/src/eventwrapper.cpp +++ b/src/eventwrapper.cpp @@ -8,6 +8,9 @@ EventWrapper::EventWrapper(QObject *parent) , m_event(new KCalendarCore::Event) , m_remindersModel(parent) { + connect(this, SIGNAL(eventPtrChanged(KCalendarCore::Event::Ptr)), + this, SLOT(m_remindersModel.setEventPtr(KCalendarCore::Event::Ptr))); + m_remindersModel.setEventPtr(m_event); m_remindersModel.loadReminders(); } @@ -100,16 +103,10 @@ void EventWrapper::setAllDay(bool allDay) } -void EventWrapper::addAlarm(int startOffset, KCalendarCore::Alarm::Type alarmType) +void EventWrapper::addAlarms(KCalendarCore::Alarm::List alarms) { - /*KCalendarCore::Alarm::Ptr alarm (new KCalendarCore::Alarm(nullptr)); - // offset can be set in seconds or days, if we want it to be before the event, - // it has to be set to a negative value. - KCalendarCore::Duration offset(startOffset *= -1); - - m_event->addAlarm(alarm); - alarm ->setType(alarmType); - alarm->setStartOffset(offset);*/ - m_remindersModel.addAlarm(); + for (int i = 0; i < alarms.size(); i++) { + m_event->addAlarm(alarms[i]); + } } diff --git a/src/eventwrapper.h b/src/eventwrapper.h index ff06d2d8..7da56442 100644 --- a/src/eventwrapper.h +++ b/src/eventwrapper.h @@ -51,10 +51,10 @@ public: RemindersModel * remindersModel(); Q_INVOKABLE void setAllDay(bool allDay); - Q_INVOKABLE void addAlarm(int startOffset, KCalendarCore::Alarm::Type alarmType = KCalendarCore::Alarm::Type::Display); + Q_INVOKABLE void addAlarms(KCalendarCore::Alarm::List alarms); Q_SIGNALS: - void eventPtrChanged(); + void eventPtrChanged(KCalendarCore::Event::Ptr eventPtr); void summaryChanged(); void descriptionChanged(); void locationChanged(); diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index a3744530..a7dcada5 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -83,12 +83,14 @@ int RemindersModel::rowCount(const QModelIndex &parent) const int RemindersModel::columnCount(const QModelIndex &) const { + // Our data, m_alarms, is a list -- so it's one dimensional, and only has 1 column. return 1; } void RemindersModel::addAlarm() { QModelIndex indexToUse = index(rowCount(), 0); + // This should maybe be reimplemented with insertRows()? beginInsertRows(indexToUse, rowCount(), rowCount()); KCalendarCore::Alarm::Ptr alarm (new KCalendarCore::Alarm(nullptr)); @@ -100,6 +102,10 @@ void RemindersModel::addAlarm() void RemindersModel::deleteAlarm(int row) { + if (!hasIndex(row, 0)) { + return; + } + QModelIndex indexToUse = index(row, 0); beginRemoveRows(indexToUse, row, row); @@ -110,3 +116,25 @@ void RemindersModel::deleteAlarm(int row) endRemoveRows(); Q_EMIT layoutChanged(); } + +void RemindersModel::setAlarmStartOffset(int row, int seconds) +{ + // offset can be set in seconds or days, if we want it to be before the event, + // it has to be set to a negative value. + KCalendarCore::Duration offset(seconds); + m_alarms[row]->setStartOffset(offset); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} + +void RemindersModel::setAlarmEndOffset(int row, int seconds) +{ + KCalendarCore::Duration offset(seconds); + m_alarms[row]->setEndOffset(offset); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} + +void RemindersModel::setAlarmType(int row, KCalendarCore::Alarm::Type type) +{ + m_alarms[row]->setType(type); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} diff --git a/src/remindersmodel.h b/src/remindersmodel.h index 4a75b06e..36ddf874 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -39,6 +39,10 @@ public: Q_INVOKABLE void addAlarm(); Q_INVOKABLE void deleteAlarm(int row); + Q_INVOKABLE void setAlarmStartOffset(int row, int seconds); + Q_INVOKABLE void setAlarmEndOffset(int row, int seconds); + Q_INVOKABLE void setAlarmType(int row, KCalendarCore::Alarm::Type type); + Q_SIGNALS: void eventPtrChanged(); void alarmsChanged(); -- GitLab From 7a5723ac48b2d144700939958ad6b7e2870fdfcb Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 15 Jun 2021 23:58:53 +0200 Subject: [PATCH 06/43] m_event in remindersmodel now set in constructor --- src/eventwrapper.cpp | 5 +---- src/remindersmodel.cpp | 5 +++-- src/remindersmodel.h | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/eventwrapper.cpp b/src/eventwrapper.cpp index e724e4d0..5d388357 100644 --- a/src/eventwrapper.cpp +++ b/src/eventwrapper.cpp @@ -6,13 +6,10 @@ EventWrapper::EventWrapper(QObject *parent) : QObject(parent) , m_event(new KCalendarCore::Event) - , m_remindersModel(parent) + , m_remindersModel(parent, m_event) { connect(this, SIGNAL(eventPtrChanged(KCalendarCore::Event::Ptr)), this, SLOT(m_remindersModel.setEventPtr(KCalendarCore::Event::Ptr))); - - m_remindersModel.setEventPtr(m_event); - m_remindersModel.loadReminders(); } KCalendarCore::Event::Ptr EventWrapper::eventPtr() const diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index a7dcada5..5d58ee74 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -4,11 +4,12 @@ #include #include -RemindersModel::RemindersModel(QObject *parent) +RemindersModel::RemindersModel(QObject *parent, KCalendarCore::Event::Ptr eventPtr) : QAbstractItemModel(parent) - , m_event(nullptr) + , m_event(eventPtr) { QObject::connect(this, &RemindersModel::eventPtrChanged, this, &RemindersModel::loadReminders); + loadReminders(); } KCalendarCore::Event::Ptr RemindersModel::eventPtr() diff --git a/src/remindersmodel.h b/src/remindersmodel.h index 36ddf874..a58a7446 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -23,7 +23,7 @@ public: }; Q_ENUM(Roles); - explicit RemindersModel(QObject *parent = nullptr); + explicit RemindersModel(QObject *parent = nullptr, KCalendarCore::Event::Ptr eventPtr = nullptr); ~RemindersModel() = default; KCalendarCore::Event::Ptr eventPtr(); -- GitLab From 1a0b7611890b1dcdab0b77e222a2e968bfbe7edb Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 00:36:43 +0200 Subject: [PATCH 07/43] RemindersModel now respects single source of truth (m_event), simplified addition and removal of alarms code --- src/eventwrapper.cpp | 2 +- src/remindersmodel.cpp | 25 ++++++++++--------------- src/remindersmodel.h | 2 ++ 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/eventwrapper.cpp b/src/eventwrapper.cpp index 5d388357..4de92036 100644 --- a/src/eventwrapper.cpp +++ b/src/eventwrapper.cpp @@ -9,7 +9,7 @@ EventWrapper::EventWrapper(QObject *parent) , m_remindersModel(parent, m_event) { connect(this, SIGNAL(eventPtrChanged(KCalendarCore::Event::Ptr)), - this, SLOT(m_remindersModel.setEventPtr(KCalendarCore::Event::Ptr))); + &m_remindersModel, SLOT(setEventPtr(KCalendarCore::Event::Ptr))); } KCalendarCore::Event::Ptr EventWrapper::eventPtr() const diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index 5d58ee74..1e08de38 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -8,7 +8,8 @@ RemindersModel::RemindersModel(QObject *parent, KCalendarCore::Event::Ptr eventP : QAbstractItemModel(parent) , m_event(eventPtr) { - QObject::connect(this, &RemindersModel::eventPtrChanged, this, &RemindersModel::loadReminders); + connect(this, &RemindersModel::eventPtrChanged, this, &RemindersModel::loadReminders); + connect(this, &RemindersModel::alarmsChanged, this, &RemindersModel::loadReminders); loadReminders(); } @@ -26,6 +27,12 @@ void RemindersModel::setEventPtr(KCalendarCore::Event::Ptr event) Q_EMIT eventPtrChanged(); } +KCalendarCore::Alarm::List RemindersModel::alarms() +{ + return m_alarms; +} + + void RemindersModel::loadReminders() { if (!m_event) { @@ -90,15 +97,9 @@ int RemindersModel::columnCount(const QModelIndex &) const void RemindersModel::addAlarm() { - QModelIndex indexToUse = index(rowCount(), 0); - // This should maybe be reimplemented with insertRows()? - beginInsertRows(indexToUse, rowCount(), rowCount()); - KCalendarCore::Alarm::Ptr alarm (new KCalendarCore::Alarm(nullptr)); - m_alarms.append(alarm); + m_event->addAlarm(alarm); Q_EMIT alarmsChanged(); - - endInsertRows(); } void RemindersModel::deleteAlarm(int row) @@ -107,14 +108,8 @@ void RemindersModel::deleteAlarm(int row) return; } - QModelIndex indexToUse = index(row, 0); - beginRemoveRows(indexToUse, row, row); - - m_alarms.removeAt(row); - qDebug() << rowCount(); + m_event->removeAlarm(m_alarms[row]); Q_EMIT alarmsChanged(); - - endRemoveRows(); Q_EMIT layoutChanged(); } diff --git a/src/remindersmodel.h b/src/remindersmodel.h index a58a7446..b6e24dfa 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -13,6 +13,7 @@ class RemindersModel : public QAbstractItemModel { Q_OBJECT Q_PROPERTY(KCalendarCore::Event::Ptr eventPtr READ eventPtr WRITE setEventPtr NOTIFY eventPtrChanged) + Q_PROPERTY(KCalendarCore::Alarm::List alarms READ alarms NOTIFY alarmsChanged) public: enum Roles { @@ -28,6 +29,7 @@ public: KCalendarCore::Event::Ptr eventPtr(); void setEventPtr(KCalendarCore::Event::Ptr event); + KCalendarCore::Alarm::List alarms(); void loadReminders(); QVariant data(const QModelIndex &idx, int role) const override; -- GitLab From 055f7bdc1c4baf39dc7a7cdec5f608f24c5a7e39 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 00:46:30 +0200 Subject: [PATCH 08/43] Kalendar can now once again set reminders, now using the new RemindersModel --- src/contents/ui/EventEditor.qml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 030117d8..f702cfc9 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -56,11 +56,6 @@ Kirigami.OverlaySheet { event.eventEnd = endDate; } - // There is also a chance here to add a feature for the user to pick reminder type. - for (let reminderCombo of remindersColumn.reminderCombos) { - event.addAlarm(reminderCombo.beforeEventSeconds) - } - added(calendarCombo.selectedCollectionId, event); } eventEditorSheet.close(); @@ -337,6 +332,7 @@ Kirigami.OverlaySheet { QQC2.ComboBox { //id: remindersComboBox${buttonIndex} + // There is also a chance here to add a feature for the user to pick reminder type. Layout.fillWidth: true property var beforeEventSeconds: 0 @@ -357,7 +353,7 @@ Kirigami.OverlaySheet { // All these times are in seconds. delegate: Kirigami.BasicListItem { label: remindersColumn.secondsToReminderLabel(modelData) - onClicked: parent.beforeEventSeconds = modelData + onClicked: event.remindersModel.setAlarmStartOffset(parent.index, modelData * -1) // Negative for before start } popup.z: 1000 } -- GitLab From 8d2f5f8658a0da7c2f7d9f0ddf9eee20f98000bd Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 00:55:43 +0200 Subject: [PATCH 09/43] Added explainer comment to RemindersModel header file --- src/remindersmodel.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/remindersmodel.h b/src/remindersmodel.h index b6e24dfa..cce01b57 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -9,6 +9,17 @@ #include #include +/** + * This class provides a QAbstractItemModel for an events' reminders/alarms. + * This can be useful for letting users add, modify, or delete events on new or pre-existing events. + * It treats the event's list of alarms as the signle source of truth (and it should be kept this way!) + * + * The data for the model comes from m_event, which is set in the constructor. This is a pointer to the + * event this model is getting the alarm info from. All alarm pointers are then added to m_alarms, which + * is a list. Elements in this model are therefore accessed through row numbers, as the list is a one- + * dimensional data structure. + */ + class RemindersModel : public QAbstractItemModel { Q_OBJECT -- GitLab From a1acae6e9dc071c2e299bba902fd168d47091a3e Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 00:59:55 +0200 Subject: [PATCH 10/43] Added small comments to signals connects in eventwrapper.cpp and remindersmodel.cpp --- src/eventwrapper.cpp | 1 + src/remindersmodel.cpp | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/eventwrapper.cpp b/src/eventwrapper.cpp index 4de92036..2c4ae0ea 100644 --- a/src/eventwrapper.cpp +++ b/src/eventwrapper.cpp @@ -8,6 +8,7 @@ EventWrapper::EventWrapper(QObject *parent) , m_event(new KCalendarCore::Event) , m_remindersModel(parent, m_event) { + // Change event pointer in remindersmodel if changed here connect(this, SIGNAL(eventPtrChanged(KCalendarCore::Event::Ptr)), &m_remindersModel, SLOT(setEventPtr(KCalendarCore::Event::Ptr))); } diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index 1e08de38..f6b76c55 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -8,6 +8,8 @@ RemindersModel::RemindersModel(QObject *parent, KCalendarCore::Event::Ptr eventP : QAbstractItemModel(parent) , m_event(eventPtr) { + // These signals ensure that any time the event itself or its alarms change, we are + // reloading our store of alarms in teh model too. connect(this, &RemindersModel::eventPtrChanged, this, &RemindersModel::loadReminders); connect(this, &RemindersModel::alarmsChanged, this, &RemindersModel::loadReminders); loadReminders(); @@ -91,7 +93,7 @@ int RemindersModel::rowCount(const QModelIndex &parent) const int RemindersModel::columnCount(const QModelIndex &) const { - // Our data, m_alarms, is a list -- so it's one dimensional, and only has 1 column. + // Our data, m_alarms, is a list, so it's one dimensional and only has 1 column. return 1; } -- GitLab From 35efc5382d34938d91ac3df339605854af00e80b Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 01:03:13 +0200 Subject: [PATCH 11/43] Removed unused code for alarm setting in event editor --- src/contents/ui/EventEditor.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index f702cfc9..aa31b49b 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -322,8 +322,7 @@ Kirigami.OverlaySheet { Layout.fillWidth: true model: event.remindersModel - - Component.onCompleted: console.log(Object.keys(model)) + // All of the alarms are handled within the delegates. delegate: RowLayout { Layout.fillWidth: true @@ -331,7 +330,6 @@ Kirigami.OverlaySheet { Component.onCompleted: console.log(model.index) QQC2.ComboBox { - //id: remindersComboBox${buttonIndex} // There is also a chance here to add a feature for the user to pick reminder type. Layout.fillWidth: true -- GitLab From 720f1af3c7adadec6c1d6e786d72347e769c4115 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 02:01:52 +0200 Subject: [PATCH 12/43] No more m_alarms middleman in remindersmodel --- src/remindersmodel.cpp | 34 ++++++++++------------------------ src/remindersmodel.h | 2 -- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index f6b76c55..d3f99d18 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -8,11 +8,7 @@ RemindersModel::RemindersModel(QObject *parent, KCalendarCore::Event::Ptr eventP : QAbstractItemModel(parent) , m_event(eventPtr) { - // These signals ensure that any time the event itself or its alarms change, we are - // reloading our store of alarms in teh model too. - connect(this, &RemindersModel::eventPtrChanged, this, &RemindersModel::loadReminders); - connect(this, &RemindersModel::alarmsChanged, this, &RemindersModel::loadReminders); - loadReminders(); + } KCalendarCore::Event::Ptr RemindersModel::eventPtr() @@ -31,18 +27,7 @@ void RemindersModel::setEventPtr(KCalendarCore::Event::Ptr event) KCalendarCore::Alarm::List RemindersModel::alarms() { - return m_alarms; -} - - -void RemindersModel::loadReminders() -{ - if (!m_event) { - return; - } - beginResetModel(); - m_alarms = m_event->alarms(); - endResetModel(); + return m_event->alarms(); } QVariant RemindersModel::data(const QModelIndex &idx, int role) const @@ -50,7 +35,7 @@ QVariant RemindersModel::data(const QModelIndex &idx, int role) const if (!hasIndex(idx.row(), idx.column())) { return {}; } - auto alarm = m_alarms[idx.row()]; + auto alarm = m_event->alarms()[idx.row()]; switch (role) { case Type: return alarm->type(); @@ -86,14 +71,14 @@ QModelIndex RemindersModel::parent(const QModelIndex &) const int RemindersModel::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) { - return m_alarms.size(); + return m_event->alarms().size(); } return 0; } int RemindersModel::columnCount(const QModelIndex &) const { - // Our data, m_alarms, is a list, so it's one dimensional and only has 1 column. + // Our data is a list, so it's one dimensional and only has 1 column. return 1; } @@ -102,6 +87,7 @@ void RemindersModel::addAlarm() KCalendarCore::Alarm::Ptr alarm (new KCalendarCore::Alarm(nullptr)); m_event->addAlarm(alarm); Q_EMIT alarmsChanged(); + Q_EMIT layoutChanged(); } void RemindersModel::deleteAlarm(int row) @@ -110,7 +96,7 @@ void RemindersModel::deleteAlarm(int row) return; } - m_event->removeAlarm(m_alarms[row]); + m_event->removeAlarm(m_event->alarms()[row]); Q_EMIT alarmsChanged(); Q_EMIT layoutChanged(); } @@ -120,19 +106,19 @@ void RemindersModel::setAlarmStartOffset(int row, int seconds) // offset can be set in seconds or days, if we want it to be before the event, // it has to be set to a negative value. KCalendarCore::Duration offset(seconds); - m_alarms[row]->setStartOffset(offset); + m_event->alarms()[row]->setStartOffset(offset); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } void RemindersModel::setAlarmEndOffset(int row, int seconds) { KCalendarCore::Duration offset(seconds); - m_alarms[row]->setEndOffset(offset); + m_event->alarms()[row]->setEndOffset(offset); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } void RemindersModel::setAlarmType(int row, KCalendarCore::Alarm::Type type) { - m_alarms[row]->setType(type); + m_event->alarms()[row]->setType(type); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } diff --git a/src/remindersmodel.h b/src/remindersmodel.h index cce01b57..403cd2bb 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -41,7 +41,6 @@ public: KCalendarCore::Event::Ptr eventPtr(); void setEventPtr(KCalendarCore::Event::Ptr event); KCalendarCore::Alarm::List alarms(); - void loadReminders(); QVariant data(const QModelIndex &idx, int role) const override; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; @@ -62,5 +61,4 @@ Q_SIGNALS: private: KCalendarCore::Event::Ptr m_event; - KCalendarCore::Alarm::List m_alarms; }; -- GitLab From 6aab15f0fcba2ab573338198432e741413557589 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 18:32:43 +0200 Subject: [PATCH 13/43] Added (for now read-only) AttendeesModel --- src/CMakeLists.txt | 2 +- src/attendeesmodel.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++ src/attendeesmodel.h | 57 ++++++++++++++++++++++++ src/eventwrapper.cpp | 1 + src/eventwrapper.h | 2 + 5 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 src/attendeesmodel.cpp create mode 100644 src/attendeesmodel.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a0ac3ba4..0334f3bf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: BSD-2-Clause -add_executable(kalendar about.cpp main.cpp agentconfiguration.cpp eventoccurrencemodel.cpp calendarmanager.cpp multidayeventmodel.cpp eventwrapper.cpp remindersmodel.cpp resources.qrc) +add_executable(kalendar about.cpp main.cpp agentconfiguration.cpp eventoccurrencemodel.cpp calendarmanager.cpp multidayeventmodel.cpp eventwrapper.cpp remindersmodel.cpp attendeesmodel.cpp resources.qrc) target_link_libraries(kalendar Qt5::Core diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp new file mode 100644 index 00000000..5f506676 --- /dev/null +++ b/src/attendeesmodel.cpp @@ -0,0 +1,98 @@ +// SPDX-FileCopyrightText: 2021 Claudio Cambra +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include +#include "attendeesmodel.h" + +AttendeesModel::AttendeesModel(QObject* parent, KCalendarCore::Event::Ptr eventPtr) + : QAbstractItemModel(parent) + , m_event(eventPtr) +{ + +} + +KCalendarCore::Event::Ptr AttendeesModel::eventPtr() +{ + return m_event; +} + +void AttendeesModel::setEventPtr(KCalendarCore::Event::Ptr event) +{ + if (m_event == event) { + return; + } + m_event = event; + Q_EMIT eventPtrChanged(); +} + +KCalendarCore::Attendee::List AttendeesModel::attendees() +{ + return m_event->attendees(); +} + +QVariant AttendeesModel::data(const QModelIndex &idx, int role) const +{ + if (!hasIndex(idx.row(), idx.column())) { + return {}; + } + auto attendee = m_event->attendees()[idx.row()]; + switch (role) { + case CuType: + return attendee.cuType(); + case Delegate: + return attendee.delegate(); + case Delegator: + return attendee.delegator(); + case Email: + return attendee.email(); + case FullName: + return attendee.fullName(); + case isNull: + return attendee.isNull(); + case Name: + return attendee.name(); + case Role: + return attendee.role(); + case RSVP: + return attendee.RSVP(); + case Status: + return attendee.status(); + case Uid: + return attendee.uid(); + default: + qWarning() << "Unknown role for event:" << QMetaEnum::fromType().valueToKey(role); + return {}; + } +} + +QModelIndex AttendeesModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) { + return {}; + } + + if (!parent.isValid()) { + return createIndex(row, column); + } + return {}; +} + +QModelIndex AttendeesModel::parent(const QModelIndex &) const +{ + return {}; +} + +int AttendeesModel::rowCount(const QModelIndex &parent) const +{ + if (!parent.isValid()) { + return m_event->attendees().size(); + } + return 0; +} + +int AttendeesModel::columnCount(const QModelIndex &) const +{ + // Our data is a list, so it's one dimensional and only has 1 column. + return 1; +} + diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h new file mode 100644 index 00000000..99910769 --- /dev/null +++ b/src/attendeesmodel.h @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: 2021 Claudio Cambra +// SPDX-License-Identifier: LGPL-2.1-or-later + +#pragma once + +#include +#include +#include +#include +#include + +/** + * + */ + +class AttendeesModel : public QAbstractItemModel +{ + Q_OBJECT + Q_PROPERTY(KCalendarCore::Event::Ptr eventPtr READ eventPtr WRITE setEventPtr NOTIFY eventPtrChanged) + Q_PROPERTY(KCalendarCore::Attendee::List attendees READ attendees NOTIFY attendeesChanged) + +public: + enum Roles { + CuType = Qt::UserRole + 1, + Delegate, + Delegator, + Email, + FullName, + isNull, + Name, + Role, + RSVP, + Status, + Uid + }; + Q_ENUM(Roles); + + explicit AttendeesModel(QObject *parent = nullptr, KCalendarCore::Event::Ptr eventPtr = nullptr); + ~AttendeesModel() = default; + + KCalendarCore::Event::Ptr eventPtr(); + void setEventPtr(KCalendarCore::Event::Ptr event); + KCalendarCore::Attendee::List attendees(); + + QVariant data(const QModelIndex &idx, int role) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &) const override; + int rowCount(const QModelIndex &parent = {}) const override; + int columnCount(const QModelIndex &parent) const override; + +Q_SIGNALS: + void eventPtrChanged(); + void attendeesChanged(); + +private: + KCalendarCore::Event::Ptr m_event; +}; diff --git a/src/eventwrapper.cpp b/src/eventwrapper.cpp index 2c4ae0ea..61f3190e 100644 --- a/src/eventwrapper.cpp +++ b/src/eventwrapper.cpp @@ -7,6 +7,7 @@ EventWrapper::EventWrapper(QObject *parent) : QObject(parent) , m_event(new KCalendarCore::Event) , m_remindersModel(parent, m_event) + , m_attendeesModel(parent, m_event) { // Change event pointer in remindersmodel if changed here connect(this, SIGNAL(eventPtrChanged(KCalendarCore::Event::Ptr)), diff --git a/src/eventwrapper.h b/src/eventwrapper.h index 7da56442..87ea7e6e 100644 --- a/src/eventwrapper.h +++ b/src/eventwrapper.h @@ -8,6 +8,7 @@ #include #include #include "remindersmodel.h" +#include "attendeesmodel.h" /** * This class is a wrapper for a KCalendarCore::Event::Ptr object. @@ -65,4 +66,5 @@ Q_SIGNALS: private: KCalendarCore::Event::Ptr m_event; RemindersModel m_remindersModel; + AttendeesModel m_attendeesModel; }; -- GitLab From 47755bb8871d129b764dfb748d1d4c299228c375 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 19:18:36 +0200 Subject: [PATCH 14/43] Added attendee property setters to AttendeeModel --- src/attendeesmodel.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++ src/attendeesmodel.h | 10 ++++++++ 2 files changed, 63 insertions(+) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 5f506676..b1c22a54 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -96,3 +96,56 @@ int AttendeesModel::columnCount(const QModelIndex &) const return 1; } +void AttendeesModel::setAttendeeCuType(int row, KCalendarCore::Attendee::CuType cutype) +{ + m_event->attendees()[row].setCuType(cutype); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} + +void AttendeesModel::setAttendeeDelegate(int row, QString delegate) +{ + m_event->attendees()[row].setDelegate(delegate); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} + +void AttendeesModel::setAttendeeDelegator(int row, QString delegator) +{ + m_event->attendees()[row].setDelegator(delegator); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} + +void AttendeesModel::setAttendeeEmail(int row, QString email) +{ + m_event->attendees()[row].setEmail(email); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} + +void AttendeesModel::setAttendeeName(int row, QString name) +{ + m_event->attendees()[row].setName(name); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} + +void AttendeesModel::setAttendeeRole(int row, KCalendarCore::Attendee::Role role) +{ + m_event->attendees()[row].setRole(role); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} + +void AttendeesModel::setAttendeeRSVP(int row, bool rsvp) +{ + m_event->attendees()[row].setRSVP(rsvp); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} + +void AttendeesModel::setAttendeeStatus(int row, KCalendarCore::Attendee::PartStat status) +{ + m_event->attendees()[row].setStatus(status); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} + +void AttendeesModel::setAttendeeUid(int row, QString uid) +{ + m_event->attendees()[row].setUid(uid); + Q_EMIT dataChanged(index(row, 0), index(row, 0)); +} diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index 99910769..41489443 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -48,6 +48,16 @@ public: int rowCount(const QModelIndex &parent = {}) const override; int columnCount(const QModelIndex &parent) const override; + Q_INVOKABLE void setAttendeeCuType(int row, KCalendarCore::Attendee::CuType cutype); + Q_INVOKABLE void setAttendeeDelegate(int row, QString delegate); + Q_INVOKABLE void setAttendeeDelegator(int row, QString delegator); + Q_INVOKABLE void setAttendeeEmail(int row, QString email); + Q_INVOKABLE void setAttendeeName(int row, QString name); + Q_INVOKABLE void setAttendeeRole(int row, KCalendarCore::Attendee::Role role); + Q_INVOKABLE void setAttendeeRSVP(int row, bool rsvp); + Q_INVOKABLE void setAttendeeStatus(int row, KCalendarCore::Attendee::PartStat status); + Q_INVOKABLE void setAttendeeUid(int row, QString uid); + Q_SIGNALS: void eventPtrChanged(); void attendeesChanged(); -- GitLab From 88cd4b0854063e20b532a0f5995687e6e8c55114 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 19:26:14 +0200 Subject: [PATCH 15/43] Added attendee adder and remover dunctions to AttendeesModel --- src/attendeesmodel.cpp | 20 ++++++++++++++++++++ src/attendeesmodel.h | 3 +++ 2 files changed, 23 insertions(+) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index b1c22a54..d368375c 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -96,6 +96,26 @@ int AttendeesModel::columnCount(const QModelIndex &) const return 1; } +void AttendeesModel::addAttendee() +{ + KCalendarCore::Attendee attendee; + m_event->addAttendee(attendee); + Q_EMIT attendeesChanged(); + Q_EMIT layoutChanged(); +} + +void AttendeesModel::deleteAttendee(int row) +{ + if (!hasIndex(row, 0)) { + return; + } + + m_event->attendees().removeAt(row); + Q_EMIT attendeesChanged(); + Q_EMIT layoutChanged(); +} + + void AttendeesModel::setAttendeeCuType(int row, KCalendarCore::Attendee::CuType cutype) { m_event->attendees()[row].setCuType(cutype); diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index 41489443..7d808b3b 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -48,6 +48,9 @@ public: int rowCount(const QModelIndex &parent = {}) const override; int columnCount(const QModelIndex &parent) const override; + Q_INVOKABLE void addAttendee(); + Q_INVOKABLE void deleteAttendee(int row); + Q_INVOKABLE void setAttendeeCuType(int row, KCalendarCore::Attendee::CuType cutype); Q_INVOKABLE void setAttendeeDelegate(int row, QString delegate); Q_INVOKABLE void setAttendeeDelegator(int row, QString delegator); -- GitLab From 44f55e5dc23d54eee3a87efeba1eab386bc94587 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 20:09:10 +0200 Subject: [PATCH 16/43] Can now add and delete attendees from eventeditor --- src/attendeesmodel.cpp | 14 +++++++---- src/attendeesmodel.h | 2 +- src/contents/ui/EventEditor.qml | 43 ++++++++++++++------------------- src/eventwrapper.cpp | 4 +++ src/eventwrapper.h | 3 +++ 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index d368375c..8ef3505c 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -85,7 +85,7 @@ QModelIndex AttendeesModel::parent(const QModelIndex &) const int AttendeesModel::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) { - return m_event->attendees().size(); + return m_event->attendeeCount(); } return 0; } @@ -96,21 +96,25 @@ int AttendeesModel::columnCount(const QModelIndex &) const return 1; } -void AttendeesModel::addAttendee() +void AttendeesModel::addAttendee(QString name, QString email) { - KCalendarCore::Attendee attendee; + KCalendarCore::Attendee attendee(name, email); m_event->addAttendee(attendee); Q_EMIT attendeesChanged(); Q_EMIT layoutChanged(); + qDebug() << rowCount(); } void AttendeesModel::deleteAttendee(int row) { + qDebug() << row; if (!hasIndex(row, 0)) { return; } - - m_event->attendees().removeAt(row); + KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); + currentAttendees.removeAt(row); + m_event->setAttendees(currentAttendees); + rowCount(); Q_EMIT attendeesChanged(); Q_EMIT layoutChanged(); } diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index 7d808b3b..93a3d8cd 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -48,7 +48,7 @@ public: int rowCount(const QModelIndex &parent = {}) const override; int columnCount(const QModelIndex &parent) const override; - Q_INVOKABLE void addAttendee(); + Q_INVOKABLE void addAttendee(QString name, QString email); Q_INVOKABLE void deleteAttendee(int row); Q_INVOKABLE void setAttendeeCuType(int row, KCalendarCore::Attendee::CuType cutype); diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index aa31b49b..57c6b32c 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -312,8 +312,6 @@ Kirigami.OverlaySheet { text: i18n("Add reminder") Layout.fillWidth: true - property int buttonIndex: 0 - onClicked: event.remindersModel.addAlarm(); } @@ -374,29 +372,24 @@ Kirigami.OverlaySheet { text: i18n("Add attendee") Layout.fillWidth: true - property int buttonIndex: 0 - - onClicked: { - var newAttendee = Qt.createQmlObject(` - import QtQuick 2.15 - import QtQuick.Controls 2.15 as QQC2 - import QtQuick.Layouts 1.15 - - RowLayout { - Layout.fillWidth: true - - QQC2.ComboBox { - id: attendeesComboBox${buttonIndex} - Layout.fillWidth: true - editable: true - } - QQC2.Button { - icon.name: "edit-delete-remove" - onClicked: parent.destroy() - } - } - `, this.parent, `attendeesComboBox${buttonIndex}`) - buttonIndex += 1 + onClicked: event.attendeesModel.addAttendee("name", "email"); + } + + Repeater { + model: event.attendeesModel + // All of the alarms are handled within the delegates. + + delegate: RowLayout { + Layout.fillWidth: true + + QQC2.ComboBox { + Layout.fillWidth: true + editable: true + } + QQC2.Button { + icon.name: "edit-delete-remove" + onClicked: event.attendeesModel.deleteAttendee(model.index); + } } } } diff --git a/src/eventwrapper.cpp b/src/eventwrapper.cpp index 61f3190e..2c41dd49 100644 --- a/src/eventwrapper.cpp +++ b/src/eventwrapper.cpp @@ -95,6 +95,10 @@ RemindersModel * EventWrapper::remindersModel() return &m_remindersModel; } +AttendeesModel * EventWrapper::attendeesModel() +{ + return &m_attendeesModel; +} void EventWrapper::setAllDay(bool allDay) { diff --git a/src/eventwrapper.h b/src/eventwrapper.h index 87ea7e6e..d685aaf9 100644 --- a/src/eventwrapper.h +++ b/src/eventwrapper.h @@ -30,6 +30,7 @@ class EventWrapper : public QObject Q_PROPERTY(KCalendarCore::Recurrence * recurrence READ recurrence) Q_PROPERTY(KCalendarCore::Attendee::List attendees READ attendees) Q_PROPERTY(RemindersModel * remindersModel READ remindersModel NOTIFY remindersModelChanged) + Q_PROPERTY(AttendeesModel * attendeesModel READ attendeesModel NOTIFY attendeesModelChanged) public: EventWrapper(QObject *parent = nullptr); @@ -50,6 +51,7 @@ public: KCalendarCore::Recurrence * recurrence() const; KCalendarCore::Attendee::List attendees() const; RemindersModel * remindersModel(); + AttendeesModel * attendeesModel(); Q_INVOKABLE void setAllDay(bool allDay); Q_INVOKABLE void addAlarms(KCalendarCore::Alarm::List alarms); @@ -62,6 +64,7 @@ Q_SIGNALS: void eventStartChanged(); void eventEndChanged(); void remindersModelChanged(); + void attendeesModelChanged(); private: KCalendarCore::Event::Ptr m_event; -- GitLab From 0169ebf01fac6e9c92df59f97452158d10b1a9a8 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 21:06:20 +0200 Subject: [PATCH 17/43] EventEditor can now display data from models thanks to new roleName functions in AttendeesModel and RemindersModel --- src/attendeesmodel.cpp | 10 ++++++ src/attendeesmodel.h | 1 + src/contents/ui/EventEditor.qml | 59 +++++++++++++++++++-------------- src/remindersmodel.cpp | 9 +++++ src/remindersmodel.h | 1 + 5 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 8ef3505c..7d88f514 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -65,6 +65,15 @@ QVariant AttendeesModel::data(const QModelIndex &idx, int role) const } } +QHash AttendeesModel::roleNames() const +{ + QHash roles; + for (int i = 0; i < QMetaEnum::fromType().keyCount(); i++) { + roles.insert(Qt::UserRole + i + 1, QMetaEnum::fromType().key(i)); + } + return roles; +} + QModelIndex AttendeesModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) { @@ -98,6 +107,7 @@ int AttendeesModel::columnCount(const QModelIndex &) const void AttendeesModel::addAttendee(QString name, QString email) { + qDebug() << roleNames(); KCalendarCore::Attendee attendee(name, email); m_event->addAttendee(attendee); Q_EMIT attendeesChanged(); diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index 93a3d8cd..2c151aa5 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -43,6 +43,7 @@ public: KCalendarCore::Attendee::List attendees(); QVariant data(const QModelIndex &idx, int role) const override; + QHash roleNames() const override; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex &) const override; int rowCount(const QModelIndex &parent = {}) const override; diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 57c6b32c..6aafa528 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -292,14 +292,24 @@ Kirigami.OverlaySheet { id: remindersColumn function secondsToReminderLabel(seconds) { - if (seconds) { - var numAndUnit = ( - seconds >= 2 * 24 * 60 * 60 ? Math.round(seconds / (24*60*60)) + " days" : // 2 days + - seconds >= 1 * 24 * 60 * 60 ? "1 day" : - seconds >= 2 * 60 * 60 ? Math.round(seconds / (60*60)) + " hours" : // 2 hours + - seconds >= 1 * 60 * 60 ? "1 hour" : - Math.round(seconds / 60) + " minutes") - return numAndUnit + " before"; + + function numAndUnit(secs) { + if(secs >= 2 * 24 * 60 * 60) + return Math.round(secs / (24*60*60)) + " days"; // 2 days + + else if (secs >= 1 * 24 * 60 * 60) + return "1 day"; + else if (secs >= 2 * 60 * 60) + return Math.round(secs / (60*60)) + " hours"; // 2 hours + + else if (secs >= 1 * 60 * 60) + return "1 hour"; + else + return Math.round(secs / 60) + " minutes"; + } + + if (seconds < 0) { + return numAndUnit(seconds * -1) + " before"; + } else if (seconds < 0) { + return numAndUnit(seconds) + " after"; } else { return "On event start"; } @@ -325,7 +335,7 @@ Kirigami.OverlaySheet { delegate: RowLayout { Layout.fillWidth: true - Component.onCompleted: console.log(model.index) + Component.onCompleted: console.log(Object.keys(model)) QQC2.ComboBox { // There is also a chance here to add a feature for the user to pick reminder type. @@ -333,23 +343,23 @@ Kirigami.OverlaySheet { property var beforeEventSeconds: 0 - displayText: remindersColumn.secondsToReminderLabel(Number(currentText)) - - model: [0, - 5 * 60, // 5 minutes - 10 * 60, - 15 * 60, - 30 * 60, - 45 * 60, - 1 * 60 * 60, // 1 hour - 2 * 60 * 60, - 1 * 24 * 60 * 60, // 1 day - 2 * 24 * 60 * 60, - 5 * 24 * 60 * 60] + displayText: remindersColumn.secondsToReminderLabel(StartOffset) + + model: [0, // We times by -1 to make times be before event + -1 * 5 * 60, // 5 minutes + -1 * 10 * 60, + -1 * 15 * 60, + -1 * 30 * 60, + -1 * 45 * 60, + -1 * 1 * 60 * 60, // 1 hour + -1 * 2 * 60 * 60, + -1 * 1 * 24 * 60 * 60, // 1 day + -1 * 2 * 24 * 60 * 60, + -1 * 5 * 24 * 60 * 60] // All these times are in seconds. delegate: Kirigami.BasicListItem { label: remindersColumn.secondsToReminderLabel(modelData) - onClicked: event.remindersModel.setAlarmStartOffset(parent.index, modelData * -1) // Negative for before start + onClicked: event.remindersModel.setAlarmStartOffset(parent.index, modelData) } popup.z: 1000 } @@ -382,9 +392,10 @@ Kirigami.OverlaySheet { delegate: RowLayout { Layout.fillWidth: true - QQC2.ComboBox { + QQC2.ComboBox { // When clicked, this combo should show all contacts. Layout.fillWidth: true editable: true + editText: Email } QQC2.Button { icon.name: "edit-delete-remove" diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index d3f99d18..d460fdac 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -51,6 +51,15 @@ QVariant RemindersModel::data(const QModelIndex &idx, int role) const } } +QHash RemindersModel::roleNames() const +{ + QHash roles; + for (int i = 0; i < QMetaEnum::fromType().keyCount(); i++) { + roles.insert(Qt::UserRole + i + 1, QMetaEnum::fromType().key(i)); + } + return roles; +} + QModelIndex RemindersModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) { diff --git a/src/remindersmodel.h b/src/remindersmodel.h index 403cd2bb..c3ceca00 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -43,6 +43,7 @@ public: KCalendarCore::Alarm::List alarms(); QVariant data(const QModelIndex &idx, int role) const override; + QHash roleNames() const override; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex &) const override; int rowCount(const QModelIndex &parent = {}) const override; -- GitLab From 8ac9d0e10a20111bb7f7a938ceb2f9519de7911a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 22:45:05 +0200 Subject: [PATCH 18/43] Attendee setter functions in AttendeesModel now work --- src/attendeesmodel.cpp | 41 +++++++++++++++++++++++++-------- src/contents/ui/EventEditor.qml | 15 ++++++++---- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 7d88f514..822ec864 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -129,57 +129,80 @@ void AttendeesModel::deleteAttendee(int row) Q_EMIT layoutChanged(); } +// When modifying attendees, remember you cannot change them directly from m_event->attendees (is a const). void AttendeesModel::setAttendeeCuType(int row, KCalendarCore::Attendee::CuType cutype) { - m_event->attendees()[row].setCuType(cutype); + KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); + currentAttendees[row].setCuType(cutype); + m_event->setAttendees(currentAttendees); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } void AttendeesModel::setAttendeeDelegate(int row, QString delegate) { - m_event->attendees()[row].setDelegate(delegate); + KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); + currentAttendees[row].setDelegate(delegate); + m_event->setAttendees(currentAttendees); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } void AttendeesModel::setAttendeeDelegator(int row, QString delegator) { - m_event->attendees()[row].setDelegator(delegator); + KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); + currentAttendees[row].setDelegator(delegator); + m_event->setAttendees(currentAttendees); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } void AttendeesModel::setAttendeeEmail(int row, QString email) { - m_event->attendees()[row].setEmail(email); + qDebug() << email; + KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); + currentAttendees[row].setEmail(email); + m_event->setAttendees(currentAttendees); + qDebug() << m_event->attendees()[row].email(); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } void AttendeesModel::setAttendeeName(int row, QString name) { - m_event->attendees()[row].setName(name); + qDebug() << name; + KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); + currentAttendees[row].setName(name); + m_event->setAttendees(currentAttendees); + qDebug() << m_event->attendees()[row].name(); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } void AttendeesModel::setAttendeeRole(int row, KCalendarCore::Attendee::Role role) { - m_event->attendees()[row].setRole(role); + KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); + currentAttendees[row].setRole(role); + m_event->setAttendees(currentAttendees); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } void AttendeesModel::setAttendeeRSVP(int row, bool rsvp) { - m_event->attendees()[row].setRSVP(rsvp); + KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); + currentAttendees[row].setRSVP(rsvp); + m_event->setAttendees(currentAttendees); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } void AttendeesModel::setAttendeeStatus(int row, KCalendarCore::Attendee::PartStat status) { - m_event->attendees()[row].setStatus(status); + KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); + currentAttendees[row].setStatus(status); + m_event->setAttendees(currentAttendees); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } void AttendeesModel::setAttendeeUid(int row, QString uid) { - m_event->attendees()[row].setUid(uid); + KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); + currentAttendees[row].setUid(uid); + m_event->setAttendees(currentAttendees); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 6aafa528..0636abbb 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -392,14 +392,21 @@ Kirigami.OverlaySheet { delegate: RowLayout { Layout.fillWidth: true - QQC2.ComboBox { // When clicked, this combo should show all contacts. + QQC2.TextField { // When clicked, this combo should show all contacts. Layout.fillWidth: true - editable: true - editText: Email + //editText: Name + onTextChanged: event.attendeesModel.setAttendeeName(index, text) + Component.onCompleted: text = Name + } + QQC2.TextField { + Layout.fillWidth: true + //editText: Email + onTextChanged: event.attendeesModel.setAttendeeEmail(index, text) + Component.onCompleted: text = Email } QQC2.Button { icon.name: "edit-delete-remove" - onClicked: event.attendeesModel.deleteAttendee(model.index); + onClicked: event.attendeesModel.deleteAttendee(index); } } } -- GitLab From 5245625da17bceda6bc6ea4cc12413c8b0932087 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 22:53:19 +0200 Subject: [PATCH 19/43] Added comments to EventEditor.qml --- src/contents/ui/EventEditor.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 0636abbb..25ae266e 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -291,7 +291,7 @@ Kirigami.OverlaySheet { Layout.fillWidth: true id: remindersColumn - function secondsToReminderLabel(seconds) { + function secondsToReminderLabel(seconds) { // Gives prettified time function numAndUnit(secs) { if(secs >= 2 * 24 * 60 * 60) @@ -382,7 +382,9 @@ Kirigami.OverlaySheet { text: i18n("Add attendee") Layout.fillWidth: true - onClicked: event.attendeesModel.addAttendee("name", "email"); + onClicked: event.attendeesModel.addAttendee("Enter name", "Enter email"); + // With these placeholders, the attendee still won't be added to the event + // but it will show up on the model. Still, this is a little janky. } Repeater { -- GitLab From 6e2bb5600c5aedfd5fedaf065bbe6d9dd3189def Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 23:41:46 +0200 Subject: [PATCH 20/43] Improved attendee delegate in eventeditor --- src/contents/ui/EventEditor.qml | 65 +++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 25ae266e..a9757019 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -391,24 +391,57 @@ Kirigami.OverlaySheet { model: event.attendeesModel // All of the alarms are handled within the delegates. - delegate: RowLayout { - Layout.fillWidth: true - - QQC2.TextField { // When clicked, this combo should show all contacts. - Layout.fillWidth: true - //editText: Name - onTextChanged: event.attendeesModel.setAttendeeName(index, text) - Component.onCompleted: text = Name + delegate: ColumnLayout { + RowLayout { + QQC2.Label { + Layout.fillWidth: true + text: i18n("Attendee " + String(index + 1)) + } + QQC2.Button { + icon.name: "edit-delete-remove" + onClicked: event.attendeesModel.deleteAttendee(index); + } } - QQC2.TextField { + + GridLayout { Layout.fillWidth: true - //editText: Email - onTextChanged: event.attendeesModel.setAttendeeEmail(index, text) - Component.onCompleted: text = Email - } - QQC2.Button { - icon.name: "edit-delete-remove" - onClicked: event.attendeesModel.deleteAttendee(index); + columns: 5 + + QQC2.Label{ + text: i18n("Name:") + } + QQC2.TextField { // When clicked, this combo should show all contacts. + Layout.fillWidth: true + Layout.columnSpan: 4 + //editText: Name + onTextChanged: event.attendeesModel.setAttendeeName(index, text) + Component.onCompleted: text = Name + } + + QQC2.Label { + text: i18n("Email:") + } + QQC2.TextField { + Layout.fillWidth: true + Layout.columnSpan: 4 + //editText: Email + onTextChanged: event.attendeesModel.setAttendeeEmail(index, text) + Component.onCompleted: text = Email + } + QQC2.Label { + text: i18n("Status:") + } + QQC2.ComboBox { + Layout.row: 2 + Layout.column: 1 + Layout.columnSpan: 2 + } + QQC2.CheckBox { + Layout.row: 2 + Layout.column: 3 + Layout.columnSpan: 2 + text: i18n("Request RSVP") + } } } } -- GitLab From cc55f63c494f0ad6267b7fb17a1bb597f6797bad Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 16 Jun 2021 23:52:51 +0200 Subject: [PATCH 21/43] Request RSVP checkbox for attendees now functions --- src/attendeesmodel.cpp | 9 ++------- src/contents/ui/EventEditor.qml | 6 ++---- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 822ec864..ed763416 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -107,17 +107,14 @@ int AttendeesModel::columnCount(const QModelIndex &) const void AttendeesModel::addAttendee(QString name, QString email) { - qDebug() << roleNames(); KCalendarCore::Attendee attendee(name, email); m_event->addAttendee(attendee); Q_EMIT attendeesChanged(); Q_EMIT layoutChanged(); - qDebug() << rowCount(); } void AttendeesModel::deleteAttendee(int row) { - qDebug() << row; if (!hasIndex(row, 0)) { return; } @@ -157,21 +154,17 @@ void AttendeesModel::setAttendeeDelegator(int row, QString delegator) void AttendeesModel::setAttendeeEmail(int row, QString email) { - qDebug() << email; KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); currentAttendees[row].setEmail(email); m_event->setAttendees(currentAttendees); - qDebug() << m_event->attendees()[row].email(); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } void AttendeesModel::setAttendeeName(int row, QString name) { - qDebug() << name; KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); currentAttendees[row].setName(name); m_event->setAttendees(currentAttendees); - qDebug() << m_event->attendees()[row].name(); Q_EMIT dataChanged(index(row, 0), index(row, 0)); } @@ -185,10 +178,12 @@ void AttendeesModel::setAttendeeRole(int row, KCalendarCore::Attendee::Role role void AttendeesModel::setAttendeeRSVP(int row, bool rsvp) { + qDebug() << rsvp; KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); currentAttendees[row].setRSVP(rsvp); m_event->setAttendees(currentAttendees); Q_EMIT dataChanged(index(row, 0), index(row, 0)); + qDebug() << m_event->attendees()[row].RSVP(); } void AttendeesModel::setAttendeeStatus(int row, KCalendarCore::Attendee::PartStat status) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index a9757019..cc526e70 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -432,15 +432,13 @@ Kirigami.OverlaySheet { text: i18n("Status:") } QQC2.ComboBox { - Layout.row: 2 - Layout.column: 1 Layout.columnSpan: 2 } QQC2.CheckBox { - Layout.row: 2 - Layout.column: 3 Layout.columnSpan: 2 text: i18n("Request RSVP") + checked: RSVP + onCheckedChanged: event.attendeesModel.setAttendeeRSVP(index, checked) } } } -- GitLab From f74b749757ea3d0bd084c2eb3eb4b7b78a1e35ed Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 17 Jun 2021 20:10:11 +0200 Subject: [PATCH 22/43] Added AttendeeStatusModel --- src/attendeesmodel.cpp | 88 ++++++++++++++++++++++++++++++++- src/attendeesmodel.h | 33 +++++++++++++ src/contents/ui/EventEditor.qml | 5 ++ 3 files changed, 124 insertions(+), 2 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index ed763416..9e5d0373 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -2,11 +2,91 @@ // SPDX-License-Identifier: LGPL-2.1-or-later #include +#include #include "attendeesmodel.h" +AttendeeStatusModel::AttendeeStatusModel(QObject *parent) + : QAbstractItemModel(parent) +{ + +} + +QVariant AttendeeStatusModel::data(const QModelIndex &idx, int role) const +{ + if (!hasIndex(idx.row(), idx.column())) { + return {}; + } + + int value = QMetaEnum::fromType().value(idx.row()); + // Workaround for QT_NO_CAST_FROM_ASCII + QString enumName = QLatin1String(QMetaEnum::fromType().valueToKey(value)); + + switch (role) { + case EnumName: + return enumName; + case DisplayName: + // Regular expression adds space between every lowercase and Capitalised character + return enumName.replace(QRegularExpression(QLatin1String("([a-z])([A-Z])")), QLatin1String("\\1 \\2")); + case Value: + return value; + default: + qWarning() << "Unknown role for event:" << QMetaEnum::fromType().valueToKey(role); + return {}; + } +} + +QHash AttendeeStatusModel::roleNames() const +{ + QHash roles; + for (int i = 0; i < QMetaEnum::fromType().keyCount(); i++) { + roles.insert(Qt::UserRole + i + 1, QMetaEnum::fromType().key(i)); + } + return roles; +} + +QModelIndex AttendeeStatusModel::index(int row, int column, const QModelIndex &parent) const +{ + + if (!hasIndex(row, column, parent)) { + qWarning() << "Invalid index: " << row; + return {}; + } + + if (!parent.isValid()) { + return createIndex(row, column); + } + return {}; +} + +QModelIndex AttendeeStatusModel::parent(const QModelIndex &) const +{ + return {}; +} + +int AttendeeStatusModel::rowCount(const QModelIndex &parent) const +{ + if (!parent.isValid()) { + return QMetaEnum::fromType().keyCount(); + } + return 0; +} + +int AttendeeStatusModel::columnCount(const QModelIndex &) const +{ + return 1; +} + + + + + + + + AttendeesModel::AttendeesModel(QObject* parent, KCalendarCore::Event::Ptr eventPtr) : QAbstractItemModel(parent) , m_event(eventPtr) + , m_attendeeStatusModel(parent) { } @@ -30,6 +110,12 @@ KCalendarCore::Attendee::List AttendeesModel::attendees() return m_event->attendees(); } +AttendeeStatusModel * AttendeesModel::attendeeStatusModel() +{ + return &m_attendeeStatusModel; +} + + QVariant AttendeesModel::data(const QModelIndex &idx, int role) const { if (!hasIndex(idx.row(), idx.column())) { @@ -178,12 +264,10 @@ void AttendeesModel::setAttendeeRole(int row, KCalendarCore::Attendee::Role role void AttendeesModel::setAttendeeRSVP(int row, bool rsvp) { - qDebug() << rsvp; KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); currentAttendees[row].setRSVP(rsvp); m_event->setAttendees(currentAttendees); Q_EMIT dataChanged(index(row, 0), index(row, 0)); - qDebug() << m_event->attendees()[row].RSVP(); } void AttendeesModel::setAttendeeStatus(int row, KCalendarCore::Attendee::PartStat status) diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index 2c151aa5..f820f211 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -12,12 +12,42 @@ /** * */ +class AttendeeStatusModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + enum Roles { + EnumName = Qt::UserRole + 1, + DisplayName, + Value + }; + Q_ENUM(Roles); + + AttendeeStatusModel(QObject *parent = nullptr); + ~AttendeeStatusModel() = default; + + QVariant data(const QModelIndex &idx, int role) const override; + QHash roleNames() const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &) const override; + + int rowCount(const QModelIndex &parent = {}) const override; + int columnCount(const QModelIndex &parent) const override; + +private: + QHash m_status; +}; + + + class AttendeesModel : public QAbstractItemModel { Q_OBJECT Q_PROPERTY(KCalendarCore::Event::Ptr eventPtr READ eventPtr WRITE setEventPtr NOTIFY eventPtrChanged) Q_PROPERTY(KCalendarCore::Attendee::List attendees READ attendees NOTIFY attendeesChanged) + Q_PROPERTY(AttendeeStatusModel * attendeeStatusModel READ attendeeStatusModel NOTIFY attendeeStatusModelChanged) public: enum Roles { @@ -41,6 +71,7 @@ public: KCalendarCore::Event::Ptr eventPtr(); void setEventPtr(KCalendarCore::Event::Ptr event); KCalendarCore::Attendee::List attendees(); + AttendeeStatusModel * attendeeStatusModel(); QVariant data(const QModelIndex &idx, int role) const override; QHash roleNames() const override; @@ -65,7 +96,9 @@ public: Q_SIGNALS: void eventPtrChanged(); void attendeesChanged(); + void attendeeStatusModelChanged(); private: KCalendarCore::Event::Ptr m_event; + AttendeeStatusModel m_attendeeStatusModel; }; diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index cc526e70..ba507de5 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -433,6 +433,11 @@ Kirigami.OverlaySheet { } QQC2.ComboBox { Layout.columnSpan: 2 + model: event.attendeesModel.attendeeStatusModel + Component.onCompleted: console.log(event.attendeesModel.attendeeStatusModel.rowCount()); + delegate: Kirigami.BasicListItem { + + } } QQC2.CheckBox { Layout.columnSpan: 2 -- GitLab From 5f059133f7530758c0084858ab8b3950f2a4ab3a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 17 Jun 2021 20:20:13 +0200 Subject: [PATCH 23/43] Combobox should now display proper label --- src/contents/ui/EventEditor.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index ba507de5..30e19186 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -434,9 +434,10 @@ Kirigami.OverlaySheet { QQC2.ComboBox { Layout.columnSpan: 2 model: event.attendeesModel.attendeeStatusModel - Component.onCompleted: console.log(event.attendeesModel.attendeeStatusModel.rowCount()); + displayText: currentText delegate: Kirigami.BasicListItem { - + label: DisplayName + Component.onCompleted: console.log(DisplayName); } } QQC2.CheckBox { -- GitLab From 2e5a8e8d913135a826e9942314b292b598405e3c Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 17 Jun 2021 21:28:12 +0200 Subject: [PATCH 24/43] Fixed attendee status combobox in eventeditor and is now fully functional --- src/contents/ui/EventEditor.qml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 30e19186..3230bf6d 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -86,6 +86,8 @@ Kirigami.OverlaySheet { property int selectedCollectionId: null displayText: i18n("Please select a calendar...") + textRole: "display" + valueRole: "collectionId" // Should default to default collection // Should also only show *calendars* @@ -434,11 +436,15 @@ Kirigami.OverlaySheet { QQC2.ComboBox { Layout.columnSpan: 2 model: event.attendeesModel.attendeeStatusModel - displayText: currentText + textRole: "DisplayName" + valueRole: "Value" + currentIndex: Status + onCurrentValueChanged: event.attendeesModel.setAttendeeStatus(index, currentValue) + delegate: Kirigami.BasicListItem { label: DisplayName - Component.onCompleted: console.log(DisplayName); } + popup.z: 1000 } QQC2.CheckBox { Layout.columnSpan: 2 -- GitLab From 4067dfefc3a64a62bd821386e9219cb5c558a9de Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 17 Jun 2021 21:31:54 +0200 Subject: [PATCH 25/43] Adding new attendees now creates empty fields --- src/attendeesmodel.cpp | 5 +++-- src/attendeesmodel.h | 2 +- src/contents/ui/EventEditor.qml | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 9e5d0373..a92c501c 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -191,9 +191,10 @@ int AttendeesModel::columnCount(const QModelIndex &) const return 1; } -void AttendeesModel::addAttendee(QString name, QString email) +void AttendeesModel::addAttendee() { - KCalendarCore::Attendee attendee(name, email); + // QLatin1String is a workaround for QT_NO_CAST_FROM_ASCII + KCalendarCore::Attendee attendee(QLatin1String(""), QLatin1String("")); m_event->addAttendee(attendee); Q_EMIT attendeesChanged(); Q_EMIT layoutChanged(); diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index f820f211..493d8bc3 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -80,7 +80,7 @@ public: int rowCount(const QModelIndex &parent = {}) const override; int columnCount(const QModelIndex &parent) const override; - Q_INVOKABLE void addAttendee(QString name, QString email); + Q_INVOKABLE void addAttendee(); Q_INVOKABLE void deleteAttendee(int row); Q_INVOKABLE void setAttendeeCuType(int row, KCalendarCore::Attendee::CuType cutype); diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 3230bf6d..6f4b7a1b 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -384,7 +384,7 @@ Kirigami.OverlaySheet { text: i18n("Add attendee") Layout.fillWidth: true - onClicked: event.attendeesModel.addAttendee("Enter name", "Enter email"); + onClicked: event.attendeesModel.addAttendee(); // With these placeholders, the attendee still won't be added to the event // but it will show up on the model. Still, this is a little janky. } -- GitLab From f9f7a2821ea81e14ddbcce510b3e45f65f75679b Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 17 Jun 2021 21:36:05 +0200 Subject: [PATCH 26/43] Added some spacing to attendee inputs delegate, added comments to AttendeesModel --- src/attendeesmodel.cpp | 1 + src/contents/ui/EventEditor.qml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index a92c501c..035994c7 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -195,6 +195,7 @@ void AttendeesModel::addAttendee() { // QLatin1String is a workaround for QT_NO_CAST_FROM_ASCII KCalendarCore::Attendee attendee(QLatin1String(""), QLatin1String("")); + // addAttendee won't actually add any attendees without a set name m_event->addAttendee(attendee); Q_EMIT attendeesChanged(); Q_EMIT layoutChanged(); diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 6f4b7a1b..9794c99c 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -385,8 +385,6 @@ Kirigami.OverlaySheet { Layout.fillWidth: true onClicked: event.attendeesModel.addAttendee(); - // With these placeholders, the attendee still won't be added to the event - // but it will show up on the model. Still, this is a little janky. } Repeater { @@ -394,6 +392,8 @@ Kirigami.OverlaySheet { // All of the alarms are handled within the delegates. delegate: ColumnLayout { + Layout.leftMargin: Kirigami.Units.largeSpacing + RowLayout { QQC2.Label { Layout.fillWidth: true -- GitLab From ed60407234ef463093f7bd53a48e3cccbb94634e Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Thu, 17 Jun 2021 20:58:22 +0000 Subject: [PATCH 27/43] Apply 1 suggestion(s) to 1 file(s) --- src/attendeesmodel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index 493d8bc3..8c5595fe 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -12,7 +12,7 @@ /** * */ -class AttendeeStatusModel : public QAbstractItemModel +class AttendeeStatusModel : public QAbstractListModel { Q_OBJECT -- GitLab From 94c131dc796ab36d7c30a26e789094595c054b7d Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Thu, 17 Jun 2021 20:58:31 +0000 Subject: [PATCH 28/43] Apply 1 suggestion(s) to 1 file(s) --- src/attendeesmodel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index 8c5595fe..96cf9f0c 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -42,7 +42,7 @@ private: -class AttendeesModel : public QAbstractItemModel +class AttendeesModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(KCalendarCore::Event::Ptr eventPtr READ eventPtr WRITE setEventPtr NOTIFY eventPtrChanged) -- GitLab From 0ad5842b7d5467e1699cafdc6758254e2540d145 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 17 Jun 2021 23:05:40 +0200 Subject: [PATCH 29/43] Simplified AttendeesModel and AttendeeStatusModel to QAbstractListModels, also removing need for parent, index, and columnCount functions --- src/attendeesmodel.cpp | 51 ++---------------------------------------- src/attendeesmodel.h | 7 ------ 2 files changed, 2 insertions(+), 56 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 035994c7..17313137 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -6,7 +6,7 @@ #include "attendeesmodel.h" AttendeeStatusModel::AttendeeStatusModel(QObject *parent) - : QAbstractItemModel(parent) + : QAbstractListModel(parent) { } @@ -44,25 +44,6 @@ QHash AttendeeStatusModel::roleNames() const return roles; } -QModelIndex AttendeeStatusModel::index(int row, int column, const QModelIndex &parent) const -{ - - if (!hasIndex(row, column, parent)) { - qWarning() << "Invalid index: " << row; - return {}; - } - - if (!parent.isValid()) { - return createIndex(row, column); - } - return {}; -} - -QModelIndex AttendeeStatusModel::parent(const QModelIndex &) const -{ - return {}; -} - int AttendeeStatusModel::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) { @@ -71,11 +52,6 @@ int AttendeeStatusModel::rowCount(const QModelIndex &parent) const return 0; } -int AttendeeStatusModel::columnCount(const QModelIndex &) const -{ - return 1; -} - @@ -84,7 +60,7 @@ int AttendeeStatusModel::columnCount(const QModelIndex &) const AttendeesModel::AttendeesModel(QObject* parent, KCalendarCore::Event::Ptr eventPtr) - : QAbstractItemModel(parent) + : QAbstractListModel(parent) , m_event(eventPtr) , m_attendeeStatusModel(parent) { @@ -160,23 +136,6 @@ QHash AttendeesModel::roleNames() const return roles; } -QModelIndex AttendeesModel::index(int row, int column, const QModelIndex &parent) const -{ - if (!hasIndex(row, column, parent)) { - return {}; - } - - if (!parent.isValid()) { - return createIndex(row, column); - } - return {}; -} - -QModelIndex AttendeesModel::parent(const QModelIndex &) const -{ - return {}; -} - int AttendeesModel::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) { @@ -185,12 +144,6 @@ int AttendeesModel::rowCount(const QModelIndex &parent) const return 0; } -int AttendeesModel::columnCount(const QModelIndex &) const -{ - // Our data is a list, so it's one dimensional and only has 1 column. - return 1; -} - void AttendeesModel::addAttendee() { // QLatin1String is a workaround for QT_NO_CAST_FROM_ASCII diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index 96cf9f0c..846ae4c3 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -29,11 +29,7 @@ public: QVariant data(const QModelIndex &idx, int role) const override; QHash roleNames() const override; - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &) const override; - int rowCount(const QModelIndex &parent = {}) const override; - int columnCount(const QModelIndex &parent) const override; private: QHash m_status; @@ -75,10 +71,7 @@ public: QVariant data(const QModelIndex &idx, int role) const override; QHash roleNames() const override; - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &) const override; int rowCount(const QModelIndex &parent = {}) const override; - int columnCount(const QModelIndex &parent) const override; Q_INVOKABLE void addAttendee(); Q_INVOKABLE void deleteAttendee(int row); -- GitLab From 681cabf59483ea4ea31a31e84f917db007f9ed67 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 17 Jun 2021 23:07:43 +0200 Subject: [PATCH 30/43] Converted RemindersModel to QAbstractListModel, simplfying it --- src/remindersmodel.cpp | 25 +------------------------ src/remindersmodel.h | 5 +---- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index d460fdac..7a5ab067 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -5,7 +5,7 @@ #include RemindersModel::RemindersModel(QObject *parent, KCalendarCore::Event::Ptr eventPtr) - : QAbstractItemModel(parent) + : QAbstractListModel(parent) , m_event(eventPtr) { @@ -60,23 +60,6 @@ QHash RemindersModel::roleNames() const return roles; } -QModelIndex RemindersModel::index(int row, int column, const QModelIndex &parent) const -{ - if (!hasIndex(row, column, parent)) { - return {}; - } - - if (!parent.isValid()) { - return createIndex(row, column); - } - return {}; -} - -QModelIndex RemindersModel::parent(const QModelIndex &) const -{ - return {}; -} - int RemindersModel::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) { @@ -85,12 +68,6 @@ int RemindersModel::rowCount(const QModelIndex &parent) const return 0; } -int RemindersModel::columnCount(const QModelIndex &) const -{ - // Our data is a list, so it's one dimensional and only has 1 column. - return 1; -} - void RemindersModel::addAlarm() { KCalendarCore::Alarm::Ptr alarm (new KCalendarCore::Alarm(nullptr)); diff --git a/src/remindersmodel.h b/src/remindersmodel.h index c3ceca00..3962299b 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -20,7 +20,7 @@ * dimensional data structure. */ -class RemindersModel : public QAbstractItemModel +class RemindersModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(KCalendarCore::Event::Ptr eventPtr READ eventPtr WRITE setEventPtr NOTIFY eventPtrChanged) @@ -44,10 +44,7 @@ public: QVariant data(const QModelIndex &idx, int role) const override; QHash roleNames() const override; - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &) const override; int rowCount(const QModelIndex &parent = {}) const override; - int columnCount(const QModelIndex &parent) const override; Q_INVOKABLE void addAlarm(); Q_INVOKABLE void deleteAlarm(int row); -- GitLab From fe408e2445c60249c8ec54d8a64bfff895e726d4 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Thu, 17 Jun 2021 21:11:47 +0000 Subject: [PATCH 31/43] Apply 1 suggestion(s) to 1 file(s) --- src/attendeesmodel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index 846ae4c3..74371cc2 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -52,7 +52,7 @@ public: Delegator, Email, FullName, - isNull, + IsNull, Name, Role, RSVP, -- GitLab From b8077a54c6576d346b29287db51c79c38c128989 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 17 Jun 2021 23:32:45 +0200 Subject: [PATCH 32/43] Changed role names to be more descriptive --- src/attendeesmodel.cpp | 38 +++++++++++++++++++-------------- src/attendeesmodel.h | 28 ++++++++++++------------ src/contents/ui/EventEditor.qml | 16 +++++++------- src/remindersmodel.cpp | 8 +++---- src/remindersmodel.h | 8 +++---- 5 files changed, 52 insertions(+), 46 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 17313137..286d429b 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -18,16 +18,22 @@ QVariant AttendeeStatusModel::data(const QModelIndex &idx, int role) const } int value = QMetaEnum::fromType().value(idx.row()); - // Workaround for QT_NO_CAST_FROM_ASCII + // QLatin1String is a workaround for QT_NO_CAST_FROM_ASCII QString enumName = QLatin1String(QMetaEnum::fromType().valueToKey(value)); switch (role) { - case EnumName: + case EnumNameRole: return enumName; - case DisplayName: - // Regular expression adds space between every lowercase and Capitalised character + case DisplayNameRole: + { + // Regular expression adds space between every lowercase and Capitalised character then does the same + // for capitalised letters together, e.g. ThisIsATest. Not a problem right now, but best to be safe. + QString displayName = enumName.replace(QRegularExpression(QLatin1String("Role")), QLatin1String("")); + displayName.replace(QRegularExpression(QLatin1String("([a-z])([A-Z])")), QLatin1String("\\1 \\2")); + displayName.replace(QRegularExpression(QLatin1String("([A-Z])([A-Z])")), QLatin1String("\\1 \\2")); return enumName.replace(QRegularExpression(QLatin1String("([a-z])([A-Z])")), QLatin1String("\\1 \\2")); - case Value: + } + case ValueRole: return value; default: qWarning() << "Unknown role for event:" << QMetaEnum::fromType().valueToKey(role); @@ -99,27 +105,27 @@ QVariant AttendeesModel::data(const QModelIndex &idx, int role) const } auto attendee = m_event->attendees()[idx.row()]; switch (role) { - case CuType: + case CuTypeRole: return attendee.cuType(); - case Delegate: + case DelegateRole: return attendee.delegate(); - case Delegator: + case DelegatorRole: return attendee.delegator(); - case Email: + case EmailRole: return attendee.email(); - case FullName: + case FullNameRole: return attendee.fullName(); - case isNull: + case IsNullRole: return attendee.isNull(); - case Name: + case NameRole: return attendee.name(); - case Role: + case RoleRole: return attendee.role(); - case RSVP: + case RSVPRole: return attendee.RSVP(); - case Status: + case StatusRole: return attendee.status(); - case Uid: + case UidRole: return attendee.uid(); default: qWarning() << "Unknown role for event:" << QMetaEnum::fromType().valueToKey(role); diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index 74371cc2..c527b3b4 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -18,9 +18,9 @@ class AttendeeStatusModel : public QAbstractListModel public: enum Roles { - EnumName = Qt::UserRole + 1, - DisplayName, - Value + EnumNameRole = Qt::UserRole + 1, + DisplayNameRole, + ValueRole }; Q_ENUM(Roles); @@ -47,17 +47,17 @@ class AttendeesModel : public QAbstractListModel public: enum Roles { - CuType = Qt::UserRole + 1, - Delegate, - Delegator, - Email, - FullName, - IsNull, - Name, - Role, - RSVP, - Status, - Uid + CuTypeRole = Qt::UserRole + 1, + DelegateRole, + DelegatorRole, + EmailRole, + FullNameRole, + IsNullRole, + NameRole, + RoleRole, + RSVPRole, + StatusRole, + UidRole }; Q_ENUM(Roles); diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 9794c99c..71bda348 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -345,7 +345,7 @@ Kirigami.OverlaySheet { property var beforeEventSeconds: 0 - displayText: remindersColumn.secondsToReminderLabel(StartOffset) + displayText: remindersColumn.secondsToReminderLabel(StartOffsetRole) model: [0, // We times by -1 to make times be before event -1 * 5 * 60, // 5 minutes @@ -417,7 +417,7 @@ Kirigami.OverlaySheet { Layout.columnSpan: 4 //editText: Name onTextChanged: event.attendeesModel.setAttendeeName(index, text) - Component.onCompleted: text = Name + Component.onCompleted: text = NameRole } QQC2.Label { @@ -428,7 +428,7 @@ Kirigami.OverlaySheet { Layout.columnSpan: 4 //editText: Email onTextChanged: event.attendeesModel.setAttendeeEmail(index, text) - Component.onCompleted: text = Email + Component.onCompleted: text = EmailRole } QQC2.Label { text: i18n("Status:") @@ -436,20 +436,20 @@ Kirigami.OverlaySheet { QQC2.ComboBox { Layout.columnSpan: 2 model: event.attendeesModel.attendeeStatusModel - textRole: "DisplayName" - valueRole: "Value" - currentIndex: Status + textRole: "DisplayNameRole" + valueRole: "ValueRole" + currentIndex: StatusRole onCurrentValueChanged: event.attendeesModel.setAttendeeStatus(index, currentValue) delegate: Kirigami.BasicListItem { - label: DisplayName + label: DisplayNameRole } popup.z: 1000 } QQC2.CheckBox { Layout.columnSpan: 2 text: i18n("Request RSVP") - checked: RSVP + checked: RSVPRole onCheckedChanged: event.attendeesModel.setAttendeeRSVP(index, checked) } } diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index 7a5ab067..2be89805 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -37,13 +37,13 @@ QVariant RemindersModel::data(const QModelIndex &idx, int role) const } auto alarm = m_event->alarms()[idx.row()]; switch (role) { - case Type: + case TypeRole: return alarm->type(); - case Time: + case TimeRole: return alarm->time(); - case StartOffset: + case StartOffsetRole: return alarm->startOffset().asSeconds(); - case EndOffset: + case EndOffsetRole: return alarm->endOffset().asSeconds(); default: qWarning() << "Unknown role for event:" << QMetaEnum::fromType().valueToKey(role); diff --git a/src/remindersmodel.h b/src/remindersmodel.h index 3962299b..784cd426 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -28,10 +28,10 @@ class RemindersModel : public QAbstractListModel public: enum Roles { - Type = Qt::UserRole + 1, - Time, - StartOffset, - EndOffset + TypeRole = Qt::UserRole + 1, + TimeRole, + StartOffsetRole, + EndOffsetRole }; Q_ENUM(Roles); -- GitLab From 5a7224bad9f2fd42d436a94e178de45746a92d0a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 18 Jun 2021 12:39:20 +0200 Subject: [PATCH 33/43] Made model rolename variables in eventeditor explicitly model.rolename --- src/contents/ui/EventEditor.qml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 71bda348..daf96a54 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -96,7 +96,7 @@ Kirigami.OverlaySheet { leftPadding: Kirigami.Units.largeSpacing * kDescendantLevel label: display icon: decoration - onClicked: calendarCombo.displayText = display, calendarCombo.selectedCollectionId = collectionId + onClicked: calendarCombo.displayText = model.display, calendarCombo.selectedCollectionId = model.collectionId } popup.z: 1000 } @@ -417,7 +417,7 @@ Kirigami.OverlaySheet { Layout.columnSpan: 4 //editText: Name onTextChanged: event.attendeesModel.setAttendeeName(index, text) - Component.onCompleted: text = NameRole + Component.onCompleted: text = model.NameRole } QQC2.Label { @@ -428,7 +428,7 @@ Kirigami.OverlaySheet { Layout.columnSpan: 4 //editText: Email onTextChanged: event.attendeesModel.setAttendeeEmail(index, text) - Component.onCompleted: text = EmailRole + Component.onCompleted: text = model.EmailRole } QQC2.Label { text: i18n("Status:") @@ -438,7 +438,7 @@ Kirigami.OverlaySheet { model: event.attendeesModel.attendeeStatusModel textRole: "DisplayNameRole" valueRole: "ValueRole" - currentIndex: StatusRole + currentIndex: model.StatusRole onCurrentValueChanged: event.attendeesModel.setAttendeeStatus(index, currentValue) delegate: Kirigami.BasicListItem { @@ -449,7 +449,7 @@ Kirigami.OverlaySheet { QQC2.CheckBox { Layout.columnSpan: 2 text: i18n("Request RSVP") - checked: RSVPRole + checked: model.RSVPRole onCheckedChanged: event.attendeesModel.setAttendeeRSVP(index, checked) } } -- GitLab From 14db5d56ca2b108f1dfa25909c80804ba5924984 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 18 Jun 2021 18:17:22 +0200 Subject: [PATCH 34/43] AttendeesModel now uses setData insteadof several setter functions --- src/attendeesmodel.cpp | 167 ++++++++++++++++++-------------- src/attendeesmodel.h | 14 +-- src/contents/ui/EventEditor.qml | 10 +- 3 files changed, 101 insertions(+), 90 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 286d429b..815feb6e 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -70,7 +70,11 @@ AttendeesModel::AttendeesModel(QObject* parent, KCalendarCore::Event::Ptr eventP , m_event(eventPtr) , m_attendeeStatusModel(parent) { - + for(int i = 0; i < QMetaEnum::fromType().keyCount(); i++) { + int value = QMetaEnum::fromType().value(i); + QLatin1String key(QMetaEnum::fromType().key(i)); + m_dataRoles[key] = value; + } } KCalendarCore::Event::Ptr AttendeesModel::eventPtr() @@ -97,6 +101,10 @@ AttendeeStatusModel * AttendeesModel::attendeeStatusModel() return &m_attendeeStatusModel; } +QVariantMap AttendeesModel::dataroles() +{ + return m_dataRoles; +} QVariant AttendeesModel::data(const QModelIndex &idx, int role) const { @@ -133,6 +141,89 @@ QVariant AttendeesModel::data(const QModelIndex &idx, int role) const } } +bool AttendeesModel::setData(const QModelIndex &idx, const QVariant &value, int role) +{ + if (!idx.isValid()) { + return false; + } + + // When modifying attendees, remember you cannot change them directly from m_event->attendees (is a const). + KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); + + switch (role) { + case CuTypeRole: + { + KCalendarCore::Attendee::CuType cuType = static_cast(value.toInt()); + currentAttendees[idx.row()].setCuType(cuType); + break; + } + case DelegateRole: + { + QString delegate = value.toString(); + currentAttendees[idx.row()].setDelegate(delegate); + break; + } + case DelegatorRole: + { + QString delegator = value.toString(); + currentAttendees[idx.row()].setDelegator(delegator); + break; + } + case EmailRole: + { + QString email = value.toString(); + currentAttendees[idx.row()].setEmail(email); + break; + } + case FullNameRole: + { + // Not a writable property + return false; + } + case IsNullRole: + { + // Not an editable value + return false; + } + case NameRole: + { + QString name = value.toString(); + currentAttendees[idx.row()].setName(name); + break; + } + case RoleRole: + { + KCalendarCore::Attendee::Role role = static_cast(value.toInt()); + currentAttendees[idx.row()].setRole(role); + break; + } + case RSVPRole: + { + bool rsvp = value.toBool(); + currentAttendees[idx.row()].setRSVP(rsvp); + break; + } + case StatusRole: + { + KCalendarCore::Attendee::PartStat status = static_cast(value.toInt()); + currentAttendees[idx.row()].setStatus(status); + break; + } + case UidRole: + { + QString uid = value.toString(); + currentAttendees[idx.row()].setUid(uid); + break; + } + default: + qWarning() << "Unknown role for event:" << QMetaEnum::fromType().valueToKey(role); + return false; + } + m_event->setAttendees(currentAttendees); + emit dataChanged(idx, idx); + return true; +} + QHash AttendeesModel::roleNames() const { QHash roles; @@ -172,77 +263,3 @@ void AttendeesModel::deleteAttendee(int row) Q_EMIT attendeesChanged(); Q_EMIT layoutChanged(); } - -// When modifying attendees, remember you cannot change them directly from m_event->attendees (is a const). - -void AttendeesModel::setAttendeeCuType(int row, KCalendarCore::Attendee::CuType cutype) -{ - KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); - currentAttendees[row].setCuType(cutype); - m_event->setAttendees(currentAttendees); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} - -void AttendeesModel::setAttendeeDelegate(int row, QString delegate) -{ - KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); - currentAttendees[row].setDelegate(delegate); - m_event->setAttendees(currentAttendees); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} - -void AttendeesModel::setAttendeeDelegator(int row, QString delegator) -{ - KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); - currentAttendees[row].setDelegator(delegator); - m_event->setAttendees(currentAttendees); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} - -void AttendeesModel::setAttendeeEmail(int row, QString email) -{ - KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); - currentAttendees[row].setEmail(email); - m_event->setAttendees(currentAttendees); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} - -void AttendeesModel::setAttendeeName(int row, QString name) -{ - KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); - currentAttendees[row].setName(name); - m_event->setAttendees(currentAttendees); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} - -void AttendeesModel::setAttendeeRole(int row, KCalendarCore::Attendee::Role role) -{ - KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); - currentAttendees[row].setRole(role); - m_event->setAttendees(currentAttendees); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} - -void AttendeesModel::setAttendeeRSVP(int row, bool rsvp) -{ - KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); - currentAttendees[row].setRSVP(rsvp); - m_event->setAttendees(currentAttendees); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} - -void AttendeesModel::setAttendeeStatus(int row, KCalendarCore::Attendee::PartStat status) -{ - KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); - currentAttendees[row].setStatus(status); - m_event->setAttendees(currentAttendees); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} - -void AttendeesModel::setAttendeeUid(int row, QString uid) -{ - KCalendarCore::Attendee::List currentAttendees(m_event->attendees()); - currentAttendees[row].setUid(uid); - m_event->setAttendees(currentAttendees); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index c527b3b4..51c453b5 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -44,6 +44,7 @@ class AttendeesModel : public QAbstractListModel Q_PROPERTY(KCalendarCore::Event::Ptr eventPtr READ eventPtr WRITE setEventPtr NOTIFY eventPtrChanged) Q_PROPERTY(KCalendarCore::Attendee::List attendees READ attendees NOTIFY attendeesChanged) Q_PROPERTY(AttendeeStatusModel * attendeeStatusModel READ attendeeStatusModel NOTIFY attendeeStatusModelChanged) + Q_PROPERTY(QVariantMap dataroles READ dataroles CONSTANT) public: enum Roles { @@ -68,24 +69,16 @@ public: void setEventPtr(KCalendarCore::Event::Ptr event); KCalendarCore::Attendee::List attendees(); AttendeeStatusModel * attendeeStatusModel(); + QVariantMap dataroles(); QVariant data(const QModelIndex &idx, int role) const override; + bool setData(const QModelIndex &idx, const QVariant &value, int role) override; QHash roleNames() const override; int rowCount(const QModelIndex &parent = {}) const override; Q_INVOKABLE void addAttendee(); Q_INVOKABLE void deleteAttendee(int row); - Q_INVOKABLE void setAttendeeCuType(int row, KCalendarCore::Attendee::CuType cutype); - Q_INVOKABLE void setAttendeeDelegate(int row, QString delegate); - Q_INVOKABLE void setAttendeeDelegator(int row, QString delegator); - Q_INVOKABLE void setAttendeeEmail(int row, QString email); - Q_INVOKABLE void setAttendeeName(int row, QString name); - Q_INVOKABLE void setAttendeeRole(int row, KCalendarCore::Attendee::Role role); - Q_INVOKABLE void setAttendeeRSVP(int row, bool rsvp); - Q_INVOKABLE void setAttendeeStatus(int row, KCalendarCore::Attendee::PartStat status); - Q_INVOKABLE void setAttendeeUid(int row, QString uid); - Q_SIGNALS: void eventPtrChanged(); void attendeesChanged(); @@ -94,4 +87,5 @@ Q_SIGNALS: private: KCalendarCore::Event::Ptr m_event; AttendeeStatusModel m_attendeeStatusModel; + QVariantMap m_dataRoles; }; diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index daf96a54..e6d2d088 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -416,7 +416,7 @@ Kirigami.OverlaySheet { Layout.fillWidth: true Layout.columnSpan: 4 //editText: Name - onTextChanged: event.attendeesModel.setAttendeeName(index, text) + onTextChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), text, event.attendeesModel.dataroles["NameRole"]) Component.onCompleted: text = model.NameRole } @@ -427,7 +427,7 @@ Kirigami.OverlaySheet { Layout.fillWidth: true Layout.columnSpan: 4 //editText: Email - onTextChanged: event.attendeesModel.setAttendeeEmail(index, text) + onTextChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), text, event.attendeesModel.dataroles["EmailRole"]) Component.onCompleted: text = model.EmailRole } QQC2.Label { @@ -438,8 +438,8 @@ Kirigami.OverlaySheet { model: event.attendeesModel.attendeeStatusModel textRole: "DisplayNameRole" valueRole: "ValueRole" - currentIndex: model.StatusRole - onCurrentValueChanged: event.attendeesModel.setAttendeeStatus(index, currentValue) + currentIndex: StatusRole // Of parent + onCurrentValueChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), currentValue, event.attendeesModel.dataroles["StatusRole"]) delegate: Kirigami.BasicListItem { label: DisplayNameRole @@ -450,7 +450,7 @@ Kirigami.OverlaySheet { Layout.columnSpan: 2 text: i18n("Request RSVP") checked: model.RSVPRole - onCheckedChanged: event.attendeesModel.setAttendeeRSVP(index, checked) + onCheckedChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), checked, event.attendeesModel.dataroles["RSVPRole"]) } } } -- GitLab From 3d1a24c25b08d1b735a3ab412d106bed51979bd6 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 18 Jun 2021 19:09:22 +0200 Subject: [PATCH 35/43] RemindersModel now uses setData as well --- src/contents/ui/EventEditor.qml | 21 +++++++--- src/remindersmodel.cpp | 74 +++++++++++++++++++++++---------- src/remindersmodel.h | 8 ++-- 3 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index e6d2d088..7b7a5275 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -346,6 +346,10 @@ Kirigami.OverlaySheet { property var beforeEventSeconds: 0 displayText: remindersColumn.secondsToReminderLabel(StartOffsetRole) + textRole: "DisplayNameRole" + onCurrentValueChanged: event.remindersModel.setData(event.remindersModel.index(index, 0), + currentValue, + event.remindersModel.dataroles["StartOffsetRole"]) model: [0, // We times by -1 to make times be before event -1 * 5 * 60, // 5 minutes @@ -361,7 +365,6 @@ Kirigami.OverlaySheet { // All these times are in seconds. delegate: Kirigami.BasicListItem { label: remindersColumn.secondsToReminderLabel(modelData) - onClicked: event.remindersModel.setAlarmStartOffset(parent.index, modelData) } popup.z: 1000 } @@ -416,7 +419,9 @@ Kirigami.OverlaySheet { Layout.fillWidth: true Layout.columnSpan: 4 //editText: Name - onTextChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), text, event.attendeesModel.dataroles["NameRole"]) + onTextChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), + text, + event.attendeesModel.dataroles["NameRole"]) Component.onCompleted: text = model.NameRole } @@ -427,7 +432,9 @@ Kirigami.OverlaySheet { Layout.fillWidth: true Layout.columnSpan: 4 //editText: Email - onTextChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), text, event.attendeesModel.dataroles["EmailRole"]) + onTextChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), + text, + event.attendeesModel.dataroles["EmailRole"]) Component.onCompleted: text = model.EmailRole } QQC2.Label { @@ -439,7 +446,9 @@ Kirigami.OverlaySheet { textRole: "DisplayNameRole" valueRole: "ValueRole" currentIndex: StatusRole // Of parent - onCurrentValueChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), currentValue, event.attendeesModel.dataroles["StatusRole"]) + onCurrentValueChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), + currentValue, + event.attendeesModel.dataroles["StatusRole"]) delegate: Kirigami.BasicListItem { label: DisplayNameRole @@ -450,7 +459,9 @@ Kirigami.OverlaySheet { Layout.columnSpan: 2 text: i18n("Request RSVP") checked: model.RSVPRole - onCheckedChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), checked, event.attendeesModel.dataroles["RSVPRole"]) + onCheckedChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), + checked, + event.attendeesModel.dataroles["RSVPRole"]) } } } diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index 2be89805..624b5e5f 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -8,7 +8,11 @@ RemindersModel::RemindersModel(QObject *parent, KCalendarCore::Event::Ptr eventP : QAbstractListModel(parent) , m_event(eventPtr) { - + for(int i = 0; i < QMetaEnum::fromType().keyCount(); i++) { + int value = QMetaEnum::fromType().value(i); + QLatin1String key(QMetaEnum::fromType().key(i)); + m_dataRoles[key] = value; + } } KCalendarCore::Event::Ptr RemindersModel::eventPtr() @@ -30,6 +34,11 @@ KCalendarCore::Alarm::List RemindersModel::alarms() return m_event->alarms(); } +QVariantMap RemindersModel::dataroles() +{ + return m_dataRoles; +} + QVariant RemindersModel::data(const QModelIndex &idx, int role) const { if (!hasIndex(idx.row(), idx.column())) { @@ -51,6 +60,47 @@ QVariant RemindersModel::data(const QModelIndex &idx, int role) const } } +bool RemindersModel::setData(const QModelIndex &idx, const QVariant &value, int role) +{ + if (!idx.isValid()) { + return false; + } + + switch (role) { + case TypeRole: + { + KCalendarCore::Alarm::Type type = static_cast(value.toInt()); + m_event->alarms()[idx.row()]->setType(type); + break; + } + case TimeRole: + { + QDateTime time = value.toDateTime(); + m_event->alarms()[idx.row()]->setTime(time); + break; + } + case StartOffsetRole: + { + // offset can be set in seconds or days, if we want it to be before the event, + // it has to be set to a negative value. + KCalendarCore::Duration offset(value.toInt()); + m_event->alarms()[idx.row()]->setStartOffset(offset); + break; + } + case EndOffsetRole: + { + KCalendarCore::Duration offset(value.toInt()); + m_event->alarms()[idx.row()]->setEndOffset(offset); + break; + } + default: + qWarning() << "Unknown role for event:" << QMetaEnum::fromType().valueToKey(role); + return false; + } + emit dataChanged(idx, idx); + return true; +} + QHash RemindersModel::roleNames() const { QHash roles; @@ -86,25 +136,3 @@ void RemindersModel::deleteAlarm(int row) Q_EMIT alarmsChanged(); Q_EMIT layoutChanged(); } - -void RemindersModel::setAlarmStartOffset(int row, int seconds) -{ - // offset can be set in seconds or days, if we want it to be before the event, - // it has to be set to a negative value. - KCalendarCore::Duration offset(seconds); - m_event->alarms()[row]->setStartOffset(offset); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} - -void RemindersModel::setAlarmEndOffset(int row, int seconds) -{ - KCalendarCore::Duration offset(seconds); - m_event->alarms()[row]->setEndOffset(offset); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} - -void RemindersModel::setAlarmType(int row, KCalendarCore::Alarm::Type type) -{ - m_event->alarms()[row]->setType(type); - Q_EMIT dataChanged(index(row, 0), index(row, 0)); -} diff --git a/src/remindersmodel.h b/src/remindersmodel.h index 784cd426..44062ea2 100644 --- a/src/remindersmodel.h +++ b/src/remindersmodel.h @@ -25,6 +25,7 @@ class RemindersModel : public QAbstractListModel Q_OBJECT Q_PROPERTY(KCalendarCore::Event::Ptr eventPtr READ eventPtr WRITE setEventPtr NOTIFY eventPtrChanged) Q_PROPERTY(KCalendarCore::Alarm::List alarms READ alarms NOTIFY alarmsChanged) + Q_PROPERTY(QVariantMap dataroles READ dataroles CONSTANT) public: enum Roles { @@ -41,22 +42,21 @@ public: KCalendarCore::Event::Ptr eventPtr(); void setEventPtr(KCalendarCore::Event::Ptr event); KCalendarCore::Alarm::List alarms(); + QVariantMap dataroles(); QVariant data(const QModelIndex &idx, int role) const override; + bool setData(const QModelIndex &idx, const QVariant &value, int role) override; QHash roleNames() const override; int rowCount(const QModelIndex &parent = {}) const override; Q_INVOKABLE void addAlarm(); Q_INVOKABLE void deleteAlarm(int row); - Q_INVOKABLE void setAlarmStartOffset(int row, int seconds); - Q_INVOKABLE void setAlarmEndOffset(int row, int seconds); - Q_INVOKABLE void setAlarmType(int row, KCalendarCore::Alarm::Type type); - Q_SIGNALS: void eventPtrChanged(); void alarmsChanged(); private: KCalendarCore::Event::Ptr m_event; + QVariantMap m_dataRoles; }; -- GitLab From afccd6d88d24fd7132b31ce7281a3a6e3fc2fc6b Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Fri, 18 Jun 2021 17:13:11 +0000 Subject: [PATCH 36/43] Apply 1 suggestion(s) to 1 file(s) --- src/attendeesmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 815feb6e..161b1d28 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -13,7 +13,7 @@ AttendeeStatusModel::AttendeeStatusModel(QObject *parent) QVariant AttendeeStatusModel::data(const QModelIndex &idx, int role) const { - if (!hasIndex(idx.row(), idx.column())) { + if (!index.isValid()) { return {}; } -- GitLab From ae31d05ab44c875a1ed5d8abdd1056afe93ab644 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 18 Jun 2021 19:19:14 +0200 Subject: [PATCH 37/43] Stopped overwriting delegates where unneeded in comboboxes --- src/attendeesmodel.cpp | 2 +- src/contents/ui/EventEditor.qml | 16 ++++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 161b1d28..403446f1 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -13,7 +13,7 @@ AttendeeStatusModel::AttendeeStatusModel(QObject *parent) QVariant AttendeeStatusModel::data(const QModelIndex &idx, int role) const { - if (!index.isValid()) { + if (!idx.isValid()) { return {}; } diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 7b7a5275..8ee9c0d0 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -31,7 +31,7 @@ Kirigami.OverlaySheet { QQC2.Button { text: editMode ? i18n("Done") : i18n("Add") - enabled: titleField.text && eventEditorSheet.validDates && calendarCombo.selectedCollectionId + enabled: titleField.text && eventEditorSheet.validDates && calendarCombo.currentValue QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole } @@ -56,7 +56,7 @@ Kirigami.OverlaySheet { event.eventEnd = endDate; } - added(calendarCombo.selectedCollectionId, event); + added(calendarCombo.currentValue, event); } eventEditorSheet.close(); } @@ -85,7 +85,6 @@ Kirigami.OverlaySheet { property int selectedCollectionId: null - displayText: i18n("Please select a calendar...") textRole: "display" valueRole: "collectionId" @@ -96,7 +95,6 @@ Kirigami.OverlaySheet { leftPadding: Kirigami.Units.largeSpacing * kDescendantLevel label: display icon: decoration - onClicked: calendarCombo.displayText = model.display, calendarCombo.selectedCollectionId = model.collectionId } popup.z: 1000 } @@ -363,9 +361,7 @@ Kirigami.OverlaySheet { -1 * 2 * 24 * 60 * 60, -1 * 5 * 24 * 60 * 60] // All these times are in seconds. - delegate: Kirigami.BasicListItem { - label: remindersColumn.secondsToReminderLabel(modelData) - } + popup.z: 1000 } @@ -415,10 +411,9 @@ Kirigami.OverlaySheet { QQC2.Label{ text: i18n("Name:") } - QQC2.TextField { // When clicked, this combo should show all contacts. + QQC2.TextField { Layout.fillWidth: true Layout.columnSpan: 4 - //editText: Name onTextChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), text, event.attendeesModel.dataroles["NameRole"]) @@ -450,9 +445,6 @@ Kirigami.OverlaySheet { currentValue, event.attendeesModel.dataroles["StatusRole"]) - delegate: Kirigami.BasicListItem { - label: DisplayNameRole - } popup.z: 1000 } QQC2.CheckBox { -- GitLab From 086db31e0d13cf050e890b7ee1c600b54fb24124 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 18 Jun 2021 19:46:19 +0200 Subject: [PATCH 38/43] AttendeeStatusModel now uses QHash --- src/attendeesmodel.cpp | 28 +++++++++++++++++----------- src/attendeesmodel.h | 3 +-- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 403446f1..17a6d39c 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -3,11 +3,26 @@ #include #include +#include #include "attendeesmodel.h" AttendeeStatusModel::AttendeeStatusModel(QObject *parent) : QAbstractListModel(parent) { + for(int i = 0; i < QMetaEnum::fromType().keyCount(); i++) { + int value = QMetaEnum::fromType().value(i); + + // QLatin1String is a workaround for QT_NO_CAST_FROM_ASCII. + // Regular expression adds space between every lowercase and Capitalised character then does the same + // for capitalised letters together, e.g. ThisIsATest. Not a problem right now, but best to be safe. + QString enumName = QLatin1String(QMetaEnum::fromType().key(i)); + QString displayName = enumName.replace(QRegularExpression(QLatin1String("Role$")), QLatin1String("")); + displayName.replace(QRegularExpression(QLatin1String("([a-z])([A-Z])")), QLatin1String("\\1 \\2")); + displayName.replace(QRegularExpression(QLatin1String("([A-Z])([A-Z])")), QLatin1String("\\1 \\2")); + displayName.replace(QRegularExpression(QLatin1String("([a-z])([A-Z])")), QLatin1String("\\1 \\2")); + + m_status[value] = i18n(displayName.toStdString().c_str()); + } } @@ -18,20 +33,11 @@ QVariant AttendeeStatusModel::data(const QModelIndex &idx, int role) const } int value = QMetaEnum::fromType().value(idx.row()); - // QLatin1String is a workaround for QT_NO_CAST_FROM_ASCII - QString enumName = QLatin1String(QMetaEnum::fromType().valueToKey(value)); switch (role) { - case EnumNameRole: - return enumName; case DisplayNameRole: { - // Regular expression adds space between every lowercase and Capitalised character then does the same - // for capitalised letters together, e.g. ThisIsATest. Not a problem right now, but best to be safe. - QString displayName = enumName.replace(QRegularExpression(QLatin1String("Role")), QLatin1String("")); - displayName.replace(QRegularExpression(QLatin1String("([a-z])([A-Z])")), QLatin1String("\\1 \\2")); - displayName.replace(QRegularExpression(QLatin1String("([A-Z])([A-Z])")), QLatin1String("\\1 \\2")); - return enumName.replace(QRegularExpression(QLatin1String("([a-z])([A-Z])")), QLatin1String("\\1 \\2")); + return m_status[value]; } case ValueRole: return value; @@ -53,7 +59,7 @@ QHash AttendeeStatusModel::roleNames() const int AttendeeStatusModel::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) { - return QMetaEnum::fromType().keyCount(); + return m_status.size(); } return 0; } diff --git a/src/attendeesmodel.h b/src/attendeesmodel.h index 51c453b5..9568ffc4 100644 --- a/src/attendeesmodel.h +++ b/src/attendeesmodel.h @@ -18,8 +18,7 @@ class AttendeeStatusModel : public QAbstractListModel public: enum Roles { - EnumNameRole = Qt::UserRole + 1, - DisplayNameRole, + DisplayNameRole = Qt::UserRole + 1, ValueRole }; Q_ENUM(Roles); -- GitLab From 10f9a30ea20b797428459aed84d8e1ab2fdf9842 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 18 Jun 2021 20:02:43 +0200 Subject: [PATCH 39/43] Using simpler roleNames in AttendeeStatus and AttendeeStatusModel --- src/attendeesmodel.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 17a6d39c..4cea23f0 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -49,11 +49,11 @@ QVariant AttendeeStatusModel::data(const QModelIndex &idx, int role) const QHash AttendeeStatusModel::roleNames() const { - QHash roles; - for (int i = 0; i < QMetaEnum::fromType().keyCount(); i++) { - roles.insert(Qt::UserRole + i + 1, QMetaEnum::fromType().key(i)); - } - return roles; + return { + { DisplayNameRole, QByteArrayLiteral("display") }, + { ValueRole, QByteArrayLiteral("value") } + }; + } int AttendeeStatusModel::rowCount(const QModelIndex &parent) const @@ -232,11 +232,19 @@ bool AttendeesModel::setData(const QModelIndex &idx, const QVariant &value, int QHash AttendeesModel::roleNames() const { - QHash roles; - for (int i = 0; i < QMetaEnum::fromType().keyCount(); i++) { - roles.insert(Qt::UserRole + i + 1, QMetaEnum::fromType().key(i)); - } - return roles; + return { + { CuTypeRole, QByteArrayLiteral("cuType") }, + { DelegateRole, QByteArrayLiteral("delegate") }, + { DelegatorRole, QByteArrayLiteral("delegator") }, + { EmailRole, QByteArrayLiteral("email") }, + { FullNameRole, QByteArrayLiteral("fullName") }, + { IsNullRole, QByteArrayLiteral("isNull") }, + { NameRole, QByteArrayLiteral("name") }, + { RoleRole, QByteArrayLiteral("role") }, + { RSVPRole, QByteArrayLiteral("rsvp") }, + { StatusRole, QByteArrayLiteral("status") }, + { UidRole, QByteArrayLiteral("uid") } + }; } int AttendeesModel::rowCount(const QModelIndex &parent) const -- GitLab From cadb5f68e80c37c928343cffa2f2d115bd634ca8 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 18 Jun 2021 20:15:48 +0200 Subject: [PATCH 40/43] Changed roleNames for remindersModel and fixed combobox for attendee status --- src/attendeesmodel.cpp | 2 +- src/contents/ui/EventEditor.qml | 18 +++++++++--------- src/remindersmodel.cpp | 13 +++++++------ 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index 4cea23f0..b36bb18e 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -78,7 +78,7 @@ AttendeesModel::AttendeesModel(QObject* parent, KCalendarCore::Event::Ptr eventP { for(int i = 0; i < QMetaEnum::fromType().keyCount(); i++) { int value = QMetaEnum::fromType().value(i); - QLatin1String key(QMetaEnum::fromType().key(i)); + QString key = QLatin1String(roleNames()[value]); m_dataRoles[key] = value; } } diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 8ee9c0d0..be2b303b 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -343,11 +343,11 @@ Kirigami.OverlaySheet { property var beforeEventSeconds: 0 - displayText: remindersColumn.secondsToReminderLabel(StartOffsetRole) - textRole: "DisplayNameRole" + displayText: remindersColumn.secondsToReminderLabel(startOffset) + //textRole: "DisplayNameRole" onCurrentValueChanged: event.remindersModel.setData(event.remindersModel.index(index, 0), currentValue, - event.remindersModel.dataroles["StartOffsetRole"]) + event.remindersModel.dataroles["startOffset"]) model: [0, // We times by -1 to make times be before event -1 * 5 * 60, // 5 minutes @@ -416,7 +416,7 @@ Kirigami.OverlaySheet { Layout.columnSpan: 4 onTextChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), text, - event.attendeesModel.dataroles["NameRole"]) + event.attendeesModel.dataroles["name"]) Component.onCompleted: text = model.NameRole } @@ -429,7 +429,7 @@ Kirigami.OverlaySheet { //editText: Email onTextChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), text, - event.attendeesModel.dataroles["EmailRole"]) + event.attendeesModel.dataroles["email"]) Component.onCompleted: text = model.EmailRole } QQC2.Label { @@ -438,12 +438,12 @@ Kirigami.OverlaySheet { QQC2.ComboBox { Layout.columnSpan: 2 model: event.attendeesModel.attendeeStatusModel - textRole: "DisplayNameRole" - valueRole: "ValueRole" + textRole: "display" + valueRole: "value" currentIndex: StatusRole // Of parent onCurrentValueChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), currentValue, - event.attendeesModel.dataroles["StatusRole"]) + event.attendeesModel.dataroles["status"]) popup.z: 1000 } @@ -453,7 +453,7 @@ Kirigami.OverlaySheet { checked: model.RSVPRole onCheckedChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), checked, - event.attendeesModel.dataroles["RSVPRole"]) + event.attendeesModel.dataroles["rsvp"]) } } } diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index 624b5e5f..3ca6c96f 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -10,7 +10,7 @@ RemindersModel::RemindersModel(QObject *parent, KCalendarCore::Event::Ptr eventP { for(int i = 0; i < QMetaEnum::fromType().keyCount(); i++) { int value = QMetaEnum::fromType().value(i); - QLatin1String key(QMetaEnum::fromType().key(i)); + QString key = QLatin1String(roleNames()[value]); m_dataRoles[key] = value; } } @@ -103,11 +103,12 @@ bool RemindersModel::setData(const QModelIndex &idx, const QVariant &value, int QHash RemindersModel::roleNames() const { - QHash roles; - for (int i = 0; i < QMetaEnum::fromType().keyCount(); i++) { - roles.insert(Qt::UserRole + i + 1, QMetaEnum::fromType().key(i)); - } - return roles; + return { + { TypeRole, QByteArrayLiteral("type") }, + { TimeRole, QByteArrayLiteral("time") }, + { StartOffsetRole, QByteArrayLiteral("startOffset") }, + { EndOffsetRole, QByteArrayLiteral("endOffset") } + }; } int RemindersModel::rowCount(const QModelIndex &parent) const -- GitLab From e4367ffcf4a86ed3401e2fc60d084f70f6b43894 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 18 Jun 2021 20:20:30 +0200 Subject: [PATCH 41/43] Readded delegate overwrite for reminders combobox for now --- src/contents/ui/EventEditor.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index be2b303b..70d46bd7 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -361,6 +361,9 @@ Kirigami.OverlaySheet { -1 * 2 * 24 * 60 * 60, -1 * 5 * 24 * 60 * 60] // All these times are in seconds. + delegate: Kirigami.BasicListItem { + text: remindersColumn.secondsToReminderLabel(modelData) + } popup.z: 1000 } -- GitLab From e75fe7e1ac7989cf06a62514d855e44a65153061 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Sat, 19 Jun 2021 12:39:46 +0200 Subject: [PATCH 42/43] Simplified rowCount() funcs in QAbstractListModel models --- src/attendeesmodel.cpp | 14 ++++---------- src/remindersmodel.cpp | 7 ++----- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/attendeesmodel.cpp b/src/attendeesmodel.cpp index b36bb18e..9460692f 100644 --- a/src/attendeesmodel.cpp +++ b/src/attendeesmodel.cpp @@ -56,12 +56,9 @@ QHash AttendeeStatusModel::roleNames() const } -int AttendeeStatusModel::rowCount(const QModelIndex &parent) const +int AttendeeStatusModel::rowCount(const QModelIndex &) const { - if (!parent.isValid()) { - return m_status.size(); - } - return 0; + return m_status.size(); } @@ -247,12 +244,9 @@ QHash AttendeesModel::roleNames() const }; } -int AttendeesModel::rowCount(const QModelIndex &parent) const +int AttendeesModel::rowCount(const QModelIndex &) const { - if (!parent.isValid()) { - return m_event->attendeeCount(); - } - return 0; + return m_event->attendeeCount(); } void AttendeesModel::addAttendee() diff --git a/src/remindersmodel.cpp b/src/remindersmodel.cpp index 3ca6c96f..40c2005c 100644 --- a/src/remindersmodel.cpp +++ b/src/remindersmodel.cpp @@ -111,12 +111,9 @@ QHash RemindersModel::roleNames() const }; } -int RemindersModel::rowCount(const QModelIndex &parent) const +int RemindersModel::rowCount(const QModelIndex &) const { - if (!parent.isValid()) { - return m_event->alarms().size(); - } - return 0; + return m_event->alarms().size(); } void RemindersModel::addAlarm() -- GitLab From 1e58e9257135f0e538726ae326590d1a38212ab9 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Sat, 19 Jun 2021 13:27:14 +0200 Subject: [PATCH 43/43] Fixed model roles in event editor --- src/contents/ui/EventEditor.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/contents/ui/EventEditor.qml b/src/contents/ui/EventEditor.qml index 70d46bd7..d4c39c18 100644 --- a/src/contents/ui/EventEditor.qml +++ b/src/contents/ui/EventEditor.qml @@ -420,7 +420,7 @@ Kirigami.OverlaySheet { onTextChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), text, event.attendeesModel.dataroles["name"]) - Component.onCompleted: text = model.NameRole + Component.onCompleted: text = model.name } QQC2.Label { @@ -433,7 +433,7 @@ Kirigami.OverlaySheet { onTextChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), text, event.attendeesModel.dataroles["email"]) - Component.onCompleted: text = model.EmailRole + Component.onCompleted: text = model.email } QQC2.Label { text: i18n("Status:") @@ -443,7 +443,7 @@ Kirigami.OverlaySheet { model: event.attendeesModel.attendeeStatusModel textRole: "display" valueRole: "value" - currentIndex: StatusRole // Of parent + currentIndex: status // role of parent onCurrentValueChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), currentValue, event.attendeesModel.dataroles["status"]) @@ -453,7 +453,7 @@ Kirigami.OverlaySheet { QQC2.CheckBox { Layout.columnSpan: 2 text: i18n("Request RSVP") - checked: model.RSVPRole + checked: model.rsvp onCheckedChanged: event.attendeesModel.setData(event.attendeesModel.index(index, 0), checked, event.attendeesModel.dataroles["rsvp"]) -- GitLab