8#include "freebusyitemmodel.h"
10#include <Akonadi/FreeBusyManager>
12#include <KLocalizedString>
17using namespace CalendarSupport;
22 ItemPrivateData(ItemPrivateData *parent)
29 qDeleteAll(childItems);
32 ItemPrivateData *child(
int row)
34 return childItems.value(row);
37 void appendChild(ItemPrivateData *item)
39 childItems.append(item);
42 ItemPrivateData *removeChild(
int row)
44 return childItems.takeAt(row);
47 [[nodiscard]]
int childCount()
const
49 return childItems.count();
52 [[nodiscard]]
int row()
const
55 return parentItem->childItems.indexOf(
const_cast<ItemPrivateData *
>(
this));
60 ItemPrivateData *parent()
66 QList<ItemPrivateData *> childItems;
67 ItemPrivateData *parentItem =
nullptr;
70class CalendarSupport::FreeBusyItemModelPrivate
73 ~FreeBusyItemModelPrivate()
79 bool mForceDownload =
false;
80 QList<FreeBusyItem::Ptr> mFreeBusyItems;
81 ItemPrivateData *mRootData =
nullptr;
84FreeBusyItemModel::FreeBusyItemModel(
QObject *parent)
86 , d(new CalendarSupport::FreeBusyItemModelPrivate)
88 qRegisterMetaType<KCalendarCore::Attendee>();
89 qRegisterMetaType<KCalendarCore::FreeBusy::Ptr>(
"KCalendarCore::FreeBusy::Ptr");
90 qRegisterMetaType<KCalendarCore::Period>(
"KCalendarCore::Period");
92 Akonadi::FreeBusyManager *m = Akonadi::FreeBusyManager::self();
93 connect(m, &Akonadi::FreeBusyManager::freeBusyRetrieved,
this, &FreeBusyItemModel::slotInsertFreeBusy);
96 d->mReloadTimer.setSingleShot(
true);
98 d->mRootData =
new ItemPrivateData(
nullptr);
101FreeBusyItemModel::~FreeBusyItemModel() =
default;
105 if (!index.isValid()) {
109 auto data = (ItemPrivateData *)index.internalPointer();
111 if (data->parent() == d->mRootData) {
112 int row = index.row();
113 if (row >= d->mFreeBusyItems.size()) {
119 return d->mFreeBusyItems.at(row)->attendee().fullName();
120 case FreeBusyItemModel::AttendeeRole:
122 case FreeBusyItemModel::FreeBusyRole:
123 if (d->mFreeBusyItems.at(row)->freeBusy()) {
133 FreeBusyItem::Ptr fbitem = d->mFreeBusyItems.at(data->parent()->row());
134 if (!fbitem->freeBusy() || index.row() >= fbitem->freeBusy()->busyPeriods().size()) {
138 KCalendarCore::FreeBusyPeriod period = fbitem->freeBusy()->fullBusyPeriods().at(index.row());
143 case FreeBusyItemModel::FreeBusyPeriodRole:
150int FreeBusyItemModel::rowCount(
const QModelIndex &parent)
const
152 ItemPrivateData *parentData =
nullptr;
153 if (parent.column() > 0) {
157 if (!parent.isValid()) {
158 parentData = d->mRootData;
160 parentData =
static_cast<ItemPrivateData *
>(parent.internalPointer());
163 return parentData->childCount();
166int FreeBusyItemModel::columnCount(
const QModelIndex &parent)
const
172QModelIndex FreeBusyItemModel::index(
int row,
int column,
const QModelIndex &parent)
const
174 if (!
hasIndex(row, column, parent)) {
178 ItemPrivateData *parentData =
nullptr;
179 if (!parent.isValid()) {
180 parentData = d->mRootData;
182 parentData =
static_cast<ItemPrivateData *
>(parent.internalPointer());
185 ItemPrivateData *childData = parentData->child(row);
199 auto childData =
static_cast<ItemPrivateData *
>(child.
internalPointer());
200 ItemPrivateData *parentData = childData->parent();
201 if (parentData == d->mRootData) {
205 return createIndex(parentData->row(), 0, parentData);
208QVariant FreeBusyItemModel::headerData(
int section,
Qt::Orientation orientation,
int role)
const
211 return i18n(
"Attendee");
216void FreeBusyItemModel::addItem(
const FreeBusyItem::Ptr &freebusy)
218 int row = d->mFreeBusyItems.size();
220 d->mFreeBusyItems.append(freebusy);
221 auto data =
new ItemPrivateData(d->mRootData);
222 d->mRootData->appendChild(data);
225 if (freebusy->freeBusy() && !freebusy->freeBusy()->fullBusyPeriods().isEmpty()) {
226 QModelIndex parent = index(row, 0);
227 setFreeBusyPeriods(parent, freebusy->freeBusy()->fullBusyPeriods());
229 updateFreeBusyData(freebusy);
234 if (!parent.isValid()) {
238 auto parentData =
static_cast<ItemPrivateData *
>(parent.internalPointer());
240 int childCount = parentData->childCount();
241 QModelIndex first = index(0, 0, parent);
242 QModelIndex last = index(childCount - 1, 0, parent);
244 if (childCount > 0 && fb_count < childCount) {
245 beginRemoveRows(parent, fb_count - 1 < 0 ? 0 : fb_count - 1, childCount - 1);
246 for (
int i = childCount - 1; i > fb_count; --i) {
247 delete parentData->removeChild(i);
251 last = index(fb_count - 1, 0, parent);
254 }
else if (fb_count > childCount) {
256 for (
int i = childCount; i < fb_count; ++i) {
257 auto childData =
new ItemPrivateData(parentData);
258 parentData->appendChild(childData);
261 if (childCount > 0) {
262 last = index(childCount - 1, 0, parent);
265 }
else if (fb_count == childCount && fb_count > 0) {
270void FreeBusyItemModel::clear()
273 d->mFreeBusyItems.clear();
275 d->mRootData =
new ItemPrivateData(
nullptr);
279void FreeBusyItemModel::removeRow(
int row)
282 d->mFreeBusyItems.removeAt(row);
283 ItemPrivateData *data = d->mRootData->removeChild(row);
288void FreeBusyItemModel::removeItem(
const FreeBusyItem::Ptr &freebusy)
290 int row = d->mFreeBusyItems.indexOf(freebusy);
296void FreeBusyItemModel::removeAttendee(
const KCalendarCore::Attendee &attendee)
298 FreeBusyItem::Ptr anItem;
299 for (
int i = 0; i < d->mFreeBusyItems.count(); ++i) {
300 anItem = d->mFreeBusyItems[i];
301 if (anItem->attendee() == attendee) {
302 if (anItem->updateTimerID() != 0) {
311bool FreeBusyItemModel::containsAttendee(
const KCalendarCore::Attendee &attendee)
313 FreeBusyItem::Ptr anItem;
314 for (
int i = 0; i < d->mFreeBusyItems.count(); ++i) {
315 anItem = d->mFreeBusyItems[i];
316 if (anItem->attendee() == attendee) {
323void FreeBusyItemModel::updateFreeBusyData(
const FreeBusyItem::Ptr &item)
325 if (item->isDownloading()) {
330 if (item->updateTimerID() != 0) {
340void FreeBusyItemModel::timerEvent(QTimerEvent *event)
343 for (FreeBusyItem::Ptr item : std::as_const(d->mFreeBusyItems)) {
344 if (item->updateTimerID() ==
event->timerId()) {
345 item->setUpdateTimerID(0);
346 item->startDownload(d->mForceDownload);
358 if (fb->fullBusyPeriods().isEmpty()) {
364 for (FreeBusyItem::Ptr item : std::as_const(d->mFreeBusyItems)) {
365 if (item->email() == email) {
366 item->setFreeBusy(fb);
367 const int row = d->mFreeBusyItems.indexOf(item);
368 const QModelIndex parent = index(row, 0);
370 setFreeBusyPeriods(parent, fb->fullBusyPeriods());
375void FreeBusyItemModel::autoReload()
377 d->mForceDownload =
false;
381void FreeBusyItemModel::reload()
383 for (FreeBusyItem::Ptr item : std::as_const(d->mFreeBusyItems)) {
384 if (d->mForceDownload) {
385 item->startDownload(d->mForceDownload);
387 updateFreeBusyData(item);
392void FreeBusyItemModel::triggerReload()
394 d->mReloadTimer.start(1000);
397void FreeBusyItemModel::cancelReload()
399 d->mReloadTimer.stop();
402#include "moc_freebusyitemmodel.cpp"
QList< FreeBusyPeriod > List
QSharedPointer< FreeBusy > Ptr
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
void beginInsertRows(const QModelIndex &parent, int first, int last)
void beginRemoveRows(const QModelIndex &parent, int first, int last)
QModelIndex createIndex(int row, int column, const void *ptr) const const
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles)
bool hasIndex(int row, int column, const QModelIndex &parent) const const
QDateTime toLocalTime() const const
qsizetype size() const const
void * internalPointer() const const
bool isValid() const const
virtual bool event(QEvent *e)
QObject * parent() const const
int startTimer(int interval, Qt::TimerType timerType)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QVariant fromValue(T &&value)