File indexing completed on 2024-06-02 05:18:01
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Sandro Knauß <knauss@kolabsys.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 * 0006 */ 0007 0008 #include "freebusycalendar.h" 0009 #include "calendarsupport_debug.h" 0010 0011 #include <KCalendarCore/FreeBusyPeriod> 0012 #include <KCalendarCore/MemoryCalendar> 0013 0014 #include <KLocalizedString> 0015 0016 #include <QTimeZone> 0017 0018 using namespace CalendarSupport; 0019 0020 class CalendarSupport::FreeBusyCalendarPrivate 0021 { 0022 public: 0023 FreeBusyCalendarPrivate() = default; 0024 0025 FreeBusyItemModel *mModel = nullptr; 0026 KCalendarCore::Calendar::Ptr mCalendar; 0027 QMap<QModelIndex, KCalendarCore::Event::Ptr> mFbEvent; 0028 }; 0029 0030 FreeBusyCalendar::FreeBusyCalendar(QObject *parent) 0031 : QObject(parent) 0032 , d(new CalendarSupport::FreeBusyCalendarPrivate) 0033 { 0034 d->mCalendar = KCalendarCore::Calendar::Ptr(new KCalendarCore::MemoryCalendar(QTimeZone::systemTimeZone())); 0035 qCDebug(CALENDARSUPPORT_LOG) << "creating" << this; 0036 } 0037 0038 FreeBusyCalendar::~FreeBusyCalendar() 0039 { 0040 qCDebug(CALENDARSUPPORT_LOG) << "deleting" << this; 0041 } 0042 0043 KCalendarCore::Calendar::Ptr FreeBusyCalendar::calendar() const 0044 { 0045 return d->mCalendar; 0046 } 0047 0048 FreeBusyItemModel *FreeBusyCalendar::model() const 0049 { 0050 return d->mModel; 0051 } 0052 0053 void FreeBusyCalendar::setModel(FreeBusyItemModel *model) 0054 { 0055 if (model != d->mModel) { 0056 if (d->mModel) { 0057 disconnect(d->mModel, nullptr, nullptr, nullptr); 0058 } 0059 d->mModel = model; 0060 connect(d->mModel, &QAbstractItemModel::layoutChanged, this, &FreeBusyCalendar::onLayoutChanged); 0061 connect(d->mModel, &QAbstractItemModel::modelReset, this, &FreeBusyCalendar::onLayoutChanged); 0062 connect(d->mModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &FreeBusyCalendar::onRowsRemoved); 0063 connect(d->mModel, &QAbstractItemModel::rowsInserted, this, &FreeBusyCalendar::onRowsInserted); 0064 connect(d->mModel, &QAbstractItemModel::dataChanged, this, &FreeBusyCalendar::onRowsChanged); 0065 } 0066 } 0067 0068 void FreeBusyCalendar::deleteAllEvents() 0069 { 0070 const KCalendarCore::Event::List lstEvents = d->mCalendar->events(); 0071 for (const KCalendarCore::Event::Ptr &event : lstEvents) { 0072 d->mCalendar->deleteEvent(event); 0073 } 0074 } 0075 0076 void FreeBusyCalendar::onLayoutChanged() 0077 { 0078 if (!d->mFbEvent.isEmpty()) { 0079 deleteAllEvents(); 0080 d->mFbEvent.clear(); 0081 for (int i = d->mModel->rowCount() - 1; i >= 0; --i) { 0082 QModelIndex parent = d->mModel->index(i, 0); 0083 onRowsInserted(parent, 0, d->mModel->rowCount(parent) - 1); 0084 } 0085 } 0086 } 0087 0088 void FreeBusyCalendar::onRowsInserted(const QModelIndex &parent, int first, int last) 0089 { 0090 if (!parent.isValid()) { 0091 return; 0092 } 0093 for (int i = first; i <= last; ++i) { 0094 QModelIndex index = d->mModel->index(i, 0, parent); 0095 0096 const KCalendarCore::FreeBusyPeriod &period = d->mModel->data(index, FreeBusyItemModel::FreeBusyPeriodRole).value<KCalendarCore::FreeBusyPeriod>(); 0097 const KCalendarCore::FreeBusy::Ptr &fb = d->mModel->data(parent, FreeBusyItemModel::FreeBusyRole).value<KCalendarCore::FreeBusy::Ptr>(); 0098 0099 KCalendarCore::Event::Ptr inc = KCalendarCore::Event::Ptr(new KCalendarCore::Event()); 0100 inc->setDtStart(period.start()); 0101 inc->setDtEnd(period.end()); 0102 inc->setUid(QLatin1StringView("fb-") + fb->uid() + QLatin1StringView("-") + QString::number(i)); 0103 0104 inc->setCustomProperty("FREEBUSY", "STATUS", QString::number(period.type())); 0105 QString summary = period.summary(); 0106 if (summary.isEmpty()) { 0107 switch (period.type()) { 0108 case KCalendarCore::FreeBusyPeriod::Free: 0109 summary = i18n("Free"); 0110 break; 0111 case KCalendarCore::FreeBusyPeriod::Busy: 0112 summary = i18n("Busy"); 0113 break; 0114 case KCalendarCore::FreeBusyPeriod::BusyUnavailable: 0115 summary = i18n("Unavailable"); 0116 break; 0117 case KCalendarCore::FreeBusyPeriod::BusyTentative: 0118 summary = i18n("Tentative"); 0119 break; 0120 default: 0121 summary = i18n("Unknown"); 0122 } 0123 } 0124 inc->setSummary(summary); 0125 0126 d->mFbEvent.insert(index, inc); 0127 d->mCalendar->addEvent(inc); 0128 } 0129 } 0130 0131 void FreeBusyCalendar::onRowsRemoved(const QModelIndex &parent, int first, int last) 0132 { 0133 if (!parent.isValid()) { 0134 for (int i = first; i <= last; ++i) { 0135 QModelIndex index = d->mModel->index(i, 0); 0136 onRowsRemoved(index, 0, d->mModel->rowCount(index) - 1); 0137 } 0138 } else { 0139 for (int i = first; i <= last; ++i) { 0140 QModelIndex index = d->mModel->index(i, 0, parent); 0141 KCalendarCore::Event::Ptr inc = d->mFbEvent.take(index); 0142 d->mCalendar->deleteEvent(inc); 0143 } 0144 } 0145 } 0146 0147 void FreeBusyCalendar::onRowsChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) 0148 { 0149 if (!topLeft.parent().isValid()) { 0150 return; 0151 } 0152 for (int i = topLeft.row(); i <= bottomRight.row(); ++i) { 0153 QModelIndex index = d->mModel->index(i, 0, topLeft.parent()); 0154 KCalendarCore::Event::Ptr inc = d->mFbEvent.value(index); 0155 d->mCalendar->beginChange(inc); 0156 d->mCalendar->endChange(inc); 0157 } 0158 } 0159 0160 #include "moc_freebusycalendar.cpp"