From e3aeadc41729ab4a2d493a42daade6a2eafa181e Mon Sep 17 00:00:00 2001 From: "p.chebotarev" Date: Tue, 26 May 2020 13:14:10 +0300 Subject: [PATCH] [nemo-qml-plugin-calendar] Add participant list model. Contributes to JB#49920 --- src/calendarattendeemodel.cpp | 115 ++++++++++++++++++++++++++++++++++ src/calendarattendeemodel.h | 53 ++++++++++++++++ src/plugin.cpp | 2 + src/src.pro | 6 +- 4 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 src/calendarattendeemodel.cpp create mode 100644 src/calendarattendeemodel.h diff --git a/src/calendarattendeemodel.cpp b/src/calendarattendeemodel.cpp new file mode 100644 index 00000000..42f44128 --- /dev/null +++ b/src/calendarattendeemodel.cpp @@ -0,0 +1,115 @@ +#include "calendarattendeemodel.h" +#include + +static CalendarAttendeeModel::SectionRoles sectionRole(const Person *person) +{ + return person->isOrganizer() + ? CalendarAttendeeModel::OrganizerSection + : CalendarAttendeeModel::SectionRoles(qBound(0, person->participationRole(), 3)); +} + +CalendarAttendeeModel::CalendarAttendeeModel(QObject *parent) + : QAbstractListModel(parent) +{ +} + +CalendarAttendeeModel::~CalendarAttendeeModel() +{ + qDeleteAll(m_people); +} + +int CalendarAttendeeModel::rowCount(const QModelIndex &index) const +{ + if (index != QModelIndex()) + return 0; + + return m_people.size(); +} + +QVariant CalendarAttendeeModel::data(const QModelIndex &index, int role) const +{ + QVariant ret; + if (!index.isValid() || index.row() < 0 || index.row() >= m_people.size()) + return ret; + + const Person* person = m_people[index.row()]; + + switch (role) { + case NameRole: + ret = person->name(); + break; + case EmailRole: + ret = person->email(); + break; + case IsOrganizerRole: + ret = person->isOrganizer(); + break; + case ParticipationRoleRole: + ret = person->participationRole(); + break; + case ParticipationStatusRole: + ret = person->participationStatus(); + break; + case ParticipationSectionRole: + ret = sectionRole(person); + break; + } + return ret; +} + +int CalendarAttendeeModel::count() const +{ + return m_people.size(); +} + +void CalendarAttendeeModel::doFill(const QList &people) +{ + const int rulesTable[] = { + 1, // Required + 3, // Optional + 4, // Non, + 2, // Chair, + 0, // Organizer + }; + + auto groupingAndSorting = [&rulesTable](const Person* lhs, const Person* rhs) -> bool { + const SectionRoles lhsRole = sectionRole(lhs); + const SectionRoles rhsRole = sectionRole(rhs); + + return lhsRole != rhsRole + ? rulesTable[lhsRole] < rulesTable[rhsRole] + : QString::localeAwareCompare(lhs->name(), rhs->name()) < 0; + }; + + beginResetModel(); + for (auto it : people) { + auto person = qobject_cast(it); + Q_ASSERT_X(person != nullptr, + "qobject cast to class Person", + "The container doesn't contain an instance of Person class"); + m_people.push_back(new Person(person->name(), + person->email(), + person->isOrganizer(), + Person::AttendeeRole(person->participationRole()), + Person::ParticipationStatus(person->participationStatus()))); + } + std::sort(m_people.begin(), m_people.end(), groupingAndSorting); + endResetModel(); + + if (people.size() != m_people.size()) { + emit countChanged(); + } +} + +QHash CalendarAttendeeModel::roleNames() const +{ + static QHash roleNames { + { NameRole, "name" }, + { EmailRole, "email" }, + { IsOrganizerRole, "isOrganizer" }, + { ParticipationRoleRole, "participationRole" }, + { ParticipationStatusRole, "participationStatus" }, + { ParticipationSectionRole, "participationSection" } + }; + return roleNames; +} diff --git a/src/calendarattendeemodel.h b/src/calendarattendeemodel.h new file mode 100644 index 00000000..4b1c8542 --- /dev/null +++ b/src/calendarattendeemodel.h @@ -0,0 +1,53 @@ +#ifndef CALENDARATTENDEEMODEL_H +#define CALENDARATTENDEEMODEL_H + +#include +#include +#include "calendareventquery.h" + +class CalendarAttendeeModel : public QAbstractListModel +{ + Q_OBJECT + Q_ENUMS(SectionRoles) + Q_PROPERTY(int count READ count NOTIFY countChanged) + +public: + enum AttendeeRoles { + NameRole = Qt::UserRole, + EmailRole, + IsOrganizerRole, + ParticipationRoleRole, + ParticipationStatusRole, + ParticipationSectionRole + }; + + enum SectionRoles { + RequiredSection = Person::RequiredParticipant, + OptionalSection = Person::OptionalParticipant, + NonSection = Person::NonParticipant, + ChairSection = Person::ChairParticipant, + OrganizerSection + }; + + explicit CalendarAttendeeModel(QObject *parent = nullptr); + virtual ~CalendarAttendeeModel(); + + int rowCount(const QModelIndex &index) const override; + QVariant data(const QModelIndex &index, int role) const override; + + int count() const; + + Q_INVOKABLE void doFill(const QList& people); + +signals: + void countChanged(); + +protected: + virtual QHash roleNames() const override; + +private: + QVector m_people; + +}; + +#endif // CALENDARATTENDEEMODEL_H diff --git a/src/plugin.cpp b/src/plugin.cpp index cf8fa70b..ceb163d6 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -47,6 +47,7 @@ #include "calendarnotebookquery.h" #include "calendarimportmodel.h" #include "calendarcontactmodel.h" +#include "calendarattendeemodel.h" class QtDate : public QObject { @@ -131,6 +132,7 @@ class Q_DECL_EXPORT NemoCalendarPlugin : public QQmlExtensionPlugin qmlRegisterSingletonType(uri, 1, 0, "Calendar", CalendarApi::New); qmlRegisterType(uri, 1, 0, "ImportModel"); qmlRegisterType(uri, 1, 0, "ContactModel"); + qmlRegisterType(uri, 1, 0, "AttendeeModel"); } }; diff --git a/src/src.pro b/src/src.pro index cddbc2c1..40daf980 100644 --- a/src/src.pro +++ b/src/src.pro @@ -41,7 +41,8 @@ SOURCES += \ $$SRCDIR/calendarutils.cpp \ $$SRCDIR/calendarimportmodel.cpp \ $$SRCDIR/calendarimportevent.cpp \ - $$SRCDIR/calendarcontactmodel.cpp + $$SRCDIR/calendarcontactmodel.cpp \ + $$SRCDIR/calendarattendeemodel.cpp HEADERS += \ $$SRCDIR/calendarevent.h \ @@ -60,7 +61,8 @@ HEADERS += \ $$SRCDIR/calendarutils.h \ $$SRCDIR/calendarimportmodel.h \ $$SRCDIR/calendarimportevent.h \ - $$SRCDIR/calendarcontactmodel.h + $$SRCDIR/calendarcontactmodel.h \ + $$SRCDIR/calendarattendeemodel.h OTHER_FILES += qmldir