File indexing completed on 2024-05-12 05:13:27
0001 /* 0002 SPDX-FileCopyrightText: 2000, 2001 Cornelius Schumacher <schumacher@kde.org> 0003 SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> 0004 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net> 0005 SPDX-FileContributor: Kevin Krammer <krake@kdab.com> 0006 SPDX-FileContributor: Sergio Martins <sergio@kdab.com> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0009 */ 0010 0011 #include "eventview_p.h" 0012 #include "prefs.h" 0013 0014 #include <CalendarSupport/CollectionSelection> 0015 #include <CalendarSupport/KCalPrefs> 0016 0017 #include <Akonadi/CalendarUtils> 0018 #include <Akonadi/ETMViewStateSaver> 0019 #include <Akonadi/EntityDisplayAttribute> 0020 #include <Akonadi/EntityTreeModel> 0021 0022 #include <KCalendarCore/CalFilter> 0023 0024 #include <KCalUtils/RecurrenceActions> 0025 0026 #include <KHolidays/HolidayRegion> 0027 0028 #include "calendarview_debug.h" 0029 #include <KCheckableProxyModel> 0030 #include <KGuiItem> 0031 #include <KLocalizedString> 0032 #include <KRandom> 0033 #include <KRearrangeColumnsProxyModel> 0034 #include <KViewStateMaintainer> 0035 0036 #include <QApplication> 0037 #include <QKeyEvent> 0038 #include <QSortFilterProxyModel> 0039 0040 using namespace KCalendarCore; 0041 using namespace EventViews; 0042 using namespace Akonadi; 0043 0044 CalendarSupport::CollectionSelection *EventViewPrivate::sGlobalCollectionSelection = nullptr; 0045 0046 /* static */ 0047 void EventView::setGlobalCollectionSelection(CalendarSupport::CollectionSelection *s) 0048 { 0049 EventViewPrivate::sGlobalCollectionSelection = s; 0050 } 0051 0052 EventView::EventView(QWidget *parent) 0053 : QWidget(parent) 0054 , d_ptr(new EventViewPrivate(this)) 0055 { 0056 QByteArray cname = metaObject()->className(); 0057 cname.replace(':', '_'); 0058 d_ptr->identifier = cname + '_' + KRandom::randomString(8).toLatin1(); 0059 0060 // AKONADI_PORT review: the FocusLineEdit in the editor emits focusReceivedSignal(), 0061 // which triggered finishTypeAhead. But the global focus widget in QApplication is 0062 // changed later, thus subsequent keyevents still went to this view, triggering another 0063 // editor, for each keypress. 0064 // Thus, listen to the global focusChanged() signal (seen in Qt 4.6-stable-patched 20091112 -Frank) 0065 connect(qobject_cast<QApplication *>(QApplication::instance()), &QApplication::focusChanged, this, &EventView::focusChanged); 0066 0067 d_ptr->setUpModels(); 0068 } 0069 0070 EventView::~EventView() = default; 0071 0072 void EventView::defaultAction(const Akonadi::Item &aitem) 0073 { 0074 qCDebug(CALENDARVIEW_LOG); 0075 const Incidence::Ptr incidence = Akonadi::CalendarUtils::incidence(aitem); 0076 if (!incidence) { 0077 return; 0078 } 0079 0080 qCDebug(CALENDARVIEW_LOG) << " type:" << int(incidence->type()); 0081 0082 if (incidence->isReadOnly()) { 0083 Q_EMIT showIncidenceSignal(aitem); 0084 } else { 0085 Q_EMIT editIncidenceSignal(aitem); 0086 } 0087 } 0088 0089 void EventView::setHolidayRegions(const QStringList ®ions) 0090 { 0091 Q_D(EventView); 0092 d->mHolidayRegions.clear(); 0093 for (const QString ®ionStr : regions) { 0094 auto region = std::make_unique<KHolidays::HolidayRegion>(regionStr); 0095 if (region->isValid()) { 0096 d->mHolidayRegions.push_back(std::move(region)); 0097 } 0098 } 0099 } 0100 0101 int EventView::showMoveRecurDialog(const Incidence::Ptr &inc, QDate date) 0102 { 0103 QDateTime dateTime(date, {}, Qt::LocalTime); 0104 0105 int availableOccurrences = KCalUtils::RecurrenceActions::availableOccurrences(inc, dateTime); 0106 0107 const QString caption = i18nc("@title:window", "Changing Recurring Item"); 0108 KGuiItem itemFuture(i18n("Also &Future Items")); 0109 KGuiItem itemSelected(i18n("Only &This Item")); 0110 KGuiItem itemAll(i18n("&All Occurrences")); 0111 0112 switch (availableOccurrences) { 0113 case KCalUtils::RecurrenceActions::NoOccurrence: 0114 return KCalUtils::RecurrenceActions::NoOccurrence; 0115 0116 case KCalUtils::RecurrenceActions::SelectedOccurrence: 0117 return KCalUtils::RecurrenceActions::SelectedOccurrence; 0118 0119 case KCalUtils::RecurrenceActions::AllOccurrences: 0120 Q_ASSERT(availableOccurrences & KCalUtils::RecurrenceActions::SelectedOccurrence); 0121 0122 // if there are all kinds of ooccurrences (i.e. past present and future) the user might 0123 // want the option only apply to current and future occurrences, leaving the past ones 0124 // provide a third choice for that ("Also future") 0125 if (availableOccurrences == KCalUtils::RecurrenceActions::AllOccurrences) { 0126 const QString message = i18n( 0127 "The item you are trying to change is a recurring item. " 0128 "Should the changes be applied only to this single occurrence, " 0129 "also to future items, or to all items in the recurrence?"); 0130 return KCalUtils::RecurrenceActions::questionSelectedFutureAllCancel(message, caption, itemSelected, itemFuture, itemAll, this); 0131 } 0132 [[fallthrough]]; 0133 0134 default: 0135 Q_ASSERT(availableOccurrences & KCalUtils::RecurrenceActions::SelectedOccurrence); 0136 // selected occurrence and either past or future occurrences 0137 const QString message = i18n( 0138 "The item you are trying to change is a recurring item. " 0139 "Should the changes be applied only to this single occurrence " 0140 "or to all items in the recurrence?"); 0141 return KCalUtils::RecurrenceActions::questionSelectedAllCancel(message, caption, itemSelected, itemAll, this); 0142 break; 0143 } 0144 0145 return KCalUtils::RecurrenceActions::NoOccurrence; 0146 } 0147 0148 void EventView::addCalendar(const Akonadi::CollectionCalendar::Ptr &calendar) 0149 { 0150 Q_D(EventView); 0151 d->mCalendars.push_back(calendar); 0152 } 0153 0154 void EventView::removeCalendar(const Akonadi::CollectionCalendar::Ptr &calendar) 0155 { 0156 Q_D(EventView); 0157 d->mCalendars.removeOne(calendar); 0158 } 0159 0160 void EventView::setModel(QAbstractItemModel *model) 0161 { 0162 Q_D(EventView); 0163 if (d->model != model) { 0164 d->model = model; 0165 if (d->model) { 0166 if (d->collectionSelectionModel) { 0167 d->collectionSelectionModel->setSourceModel(d->model); 0168 } 0169 0170 d->setEtm(d->model); 0171 d->setUpModels(); 0172 0173 connect(d->model, &QAbstractItemModel::dataChanged, this, [this](const QModelIndex &topLeft, const QModelIndex &bottomRight) { 0174 Q_D(EventView); 0175 0176 for (int i = topLeft.row(); i <= bottomRight.row(); ++i) { 0177 const auto index = topLeft.siblingAtRow(i); 0178 const auto col = d->model->data(index, Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>(); 0179 if (col.isValid()) { 0180 // TODO: we have no way of knowing what has actually changed in the model :( 0181 onCollectionChanged(col, {"AccessRights"}); 0182 } 0183 } 0184 }); 0185 } 0186 } 0187 } 0188 0189 QAbstractItemModel *EventView::model() const 0190 { 0191 Q_D(const EventView); 0192 return d->model; 0193 } 0194 0195 Akonadi::EntityTreeModel *EventView::entityTreeModel() const 0196 { 0197 Q_D(const EventView); 0198 return d->etm; 0199 } 0200 0201 void EventView::setPreferences(const PrefsPtr &preferences) 0202 { 0203 Q_D(EventView); 0204 if (d->mPrefs != preferences) { 0205 if (preferences) { 0206 d->mPrefs = preferences; 0207 } else { 0208 d->mPrefs = PrefsPtr(new Prefs()); 0209 } 0210 updateConfig(); 0211 } 0212 } 0213 0214 void EventView::setKCalPreferences(const KCalPrefsPtr &preferences) 0215 { 0216 Q_D(EventView); 0217 if (d->mKCalPrefs != preferences) { 0218 if (preferences) { 0219 d->mKCalPrefs = preferences; 0220 } else { 0221 d->mKCalPrefs = KCalPrefsPtr(new CalendarSupport::KCalPrefs()); 0222 } 0223 updateConfig(); 0224 } 0225 } 0226 0227 PrefsPtr EventView::preferences() const 0228 { 0229 Q_D(const EventView); 0230 return d->mPrefs; 0231 } 0232 0233 KCalPrefsPtr EventView::kcalPreferences() const 0234 { 0235 Q_D(const EventView); 0236 return d->mKCalPrefs; 0237 } 0238 0239 void EventView::dayPassed(const QDate &) 0240 { 0241 updateView(); 0242 } 0243 0244 void EventView::setIncidenceChanger(Akonadi::IncidenceChanger *changer) 0245 { 0246 Q_D(EventView); 0247 d->mChanger = changer; 0248 } 0249 0250 void EventView::flushView() 0251 { 0252 } 0253 0254 EventView *EventView::viewAt(const QPoint &) 0255 { 0256 return this; 0257 } 0258 0259 void EventView::updateConfig() 0260 { 0261 } 0262 0263 QDateTime EventView::selectionStart() const 0264 { 0265 return {}; 0266 } 0267 0268 QDateTime EventView::selectionEnd() const 0269 { 0270 return {}; 0271 } 0272 0273 bool EventView::dateRangeSelectionEnabled() const 0274 { 0275 Q_D(const EventView); 0276 return d->mDateRangeSelectionEnabled; 0277 } 0278 0279 void EventView::setDateRangeSelectionEnabled(bool enable) 0280 { 0281 Q_D(EventView); 0282 d->mDateRangeSelectionEnabled = enable; 0283 } 0284 0285 bool EventView::supportsZoom() const 0286 { 0287 return false; 0288 } 0289 0290 bool EventView::hasConfigurationDialog() const 0291 { 0292 return false; 0293 } 0294 0295 void EventView::setDateRange(const QDateTime &start, const QDateTime &end, const QDate &preferredMonth) 0296 { 0297 Q_D(EventView); 0298 0299 d->startDateTime = start; 0300 d->endDateTime = end; 0301 showDates(start.date(), end.date(), preferredMonth); 0302 const QPair<QDateTime, QDateTime> adjusted = actualDateRange(start, end, preferredMonth); 0303 d->actualStartDateTime = adjusted.first; 0304 d->actualEndDateTime = adjusted.second; 0305 } 0306 0307 QDateTime EventView::startDateTime() const 0308 { 0309 Q_D(const EventView); 0310 return d->startDateTime; 0311 } 0312 0313 QDateTime EventView::endDateTime() const 0314 { 0315 Q_D(const EventView); 0316 return d->endDateTime; 0317 } 0318 0319 QDateTime EventView::actualStartDateTime() const 0320 { 0321 Q_D(const EventView); 0322 return d->actualStartDateTime; 0323 } 0324 0325 QDateTime EventView::actualEndDateTime() const 0326 { 0327 Q_D(const EventView); 0328 return d->actualEndDateTime; 0329 } 0330 0331 void EventView::showConfigurationDialog(QWidget *) 0332 { 0333 } 0334 0335 bool EventView::processKeyEvent(QKeyEvent *ke) 0336 { 0337 Q_D(EventView); 0338 // If Return is pressed bring up an editor for the current selected time span. 0339 if (ke->key() == Qt::Key_Return) { 0340 if (ke->type() == QEvent::KeyPress) { 0341 d->mReturnPressed = true; 0342 } else if (ke->type() == QEvent::KeyRelease) { 0343 if (d->mReturnPressed) { 0344 Q_EMIT newEventSignal(); 0345 d->mReturnPressed = false; 0346 return true; 0347 } else { 0348 d->mReturnPressed = false; 0349 } 0350 } 0351 } 0352 0353 // Ignore all input that does not produce any output 0354 if (ke->text().isEmpty() || (ke->modifiers() & Qt::ControlModifier)) { 0355 return false; 0356 } 0357 0358 if (ke->type() == QEvent::KeyPress) { 0359 switch (ke->key()) { 0360 case Qt::Key_Escape: 0361 case Qt::Key_Return: 0362 case Qt::Key_Enter: 0363 case Qt::Key_Tab: 0364 case Qt::Key_Backtab: 0365 case Qt::Key_Left: 0366 case Qt::Key_Right: 0367 case Qt::Key_Up: 0368 case Qt::Key_Down: 0369 case Qt::Key_Backspace: 0370 case Qt::Key_Delete: 0371 case Qt::Key_PageUp: 0372 case Qt::Key_PageDown: 0373 case Qt::Key_Home: 0374 case Qt::Key_End: 0375 case Qt::Key_Control: 0376 case Qt::Key_Meta: 0377 case Qt::Key_Alt: 0378 break; 0379 default: 0380 d->mTypeAheadEvents.append(new QKeyEvent(ke->type(), ke->key(), ke->modifiers(), ke->text(), ke->isAutoRepeat(), static_cast<ushort>(ke->count()))); 0381 if (!d->mTypeAhead) { 0382 d->mTypeAhead = true; 0383 Q_EMIT newEventSignal(); 0384 } 0385 return true; 0386 } 0387 } 0388 return false; 0389 } 0390 0391 void EventView::setTypeAheadReceiver(QObject *o) 0392 { 0393 Q_D(EventView); 0394 d->mTypeAheadReceiver = o; 0395 } 0396 0397 void EventView::focusChanged(QWidget *, QWidget *now) 0398 { 0399 Q_D(EventView); 0400 if (d->mTypeAhead && now && now == d->mTypeAheadReceiver) { 0401 d->finishTypeAhead(); 0402 } 0403 } 0404 0405 CalendarSupport::CollectionSelection *EventView::collectionSelection() const 0406 { 0407 Q_D(const EventView); 0408 return d->customCollectionSelection ? d->customCollectionSelection.get() : globalCollectionSelection(); 0409 } 0410 0411 void EventView::setCustomCollectionSelectionProxyModel(KCheckableProxyModel *model) 0412 { 0413 Q_D(EventView); 0414 if (d->collectionSelectionModel == model) { 0415 return; 0416 } 0417 0418 delete d->collectionSelectionModel; 0419 d->collectionSelectionModel = model; 0420 d->setUpModels(); 0421 } 0422 0423 KCheckableProxyModel *EventView::customCollectionSelectionProxyModel() const 0424 { 0425 Q_D(const EventView); 0426 return d->collectionSelectionModel; 0427 } 0428 0429 KCheckableProxyModel *EventView::takeCustomCollectionSelectionProxyModel() 0430 { 0431 Q_D(EventView); 0432 KCheckableProxyModel *m = d->collectionSelectionModel; 0433 d->collectionSelectionModel = nullptr; 0434 d->setUpModels(); 0435 return m; 0436 } 0437 0438 CalendarSupport::CollectionSelection *EventView::customCollectionSelection() const 0439 { 0440 Q_D(const EventView); 0441 return d->customCollectionSelection.get(); 0442 } 0443 0444 void EventView::clearSelection() 0445 { 0446 } 0447 0448 bool EventView::eventDurationHint(QDateTime &startDt, QDateTime &endDt, bool &allDay) const 0449 { 0450 Q_UNUSED(startDt) 0451 Q_UNUSED(endDt) 0452 Q_UNUSED(allDay) 0453 return false; 0454 } 0455 0456 Akonadi::IncidenceChanger *EventView::changer() const 0457 { 0458 Q_D(const EventView); 0459 return d->mChanger; 0460 } 0461 0462 void EventView::doRestoreConfig(const KConfigGroup &) 0463 { 0464 } 0465 0466 void EventView::doSaveConfig(KConfigGroup &) 0467 { 0468 } 0469 0470 QPair<QDateTime, QDateTime> EventView::actualDateRange(const QDateTime &start, const QDateTime &end, const QDate &preferredMonth) const 0471 { 0472 Q_UNUSED(preferredMonth) 0473 return qMakePair(start, end); 0474 } 0475 0476 /* 0477 void EventView::incidencesAdded( const Akonadi::Item::List & ) 0478 { 0479 } 0480 0481 void EventView::incidencesAboutToBeRemoved( const Akonadi::Item::List & ) 0482 { 0483 } 0484 0485 void EventView::incidencesChanged( const Akonadi::Item::List & ) 0486 { 0487 } 0488 */ 0489 0490 void EventView::handleBackendError(const QString &errorString) 0491 { 0492 qCCritical(CALENDARVIEW_LOG) << errorString; 0493 } 0494 0495 void EventView::calendarReset() 0496 { 0497 } 0498 0499 CalendarSupport::CollectionSelection *EventView::globalCollectionSelection() 0500 { 0501 return EventViewPrivate::sGlobalCollectionSelection; 0502 } 0503 0504 QByteArray EventView::identifier() const 0505 { 0506 Q_D(const EventView); 0507 return d->identifier; 0508 } 0509 0510 void EventView::setIdentifier(const QByteArray &identifier) 0511 { 0512 Q_D(EventView); 0513 d->identifier = identifier; 0514 } 0515 0516 void EventView::setChanges(Changes changes) 0517 { 0518 Q_D(EventView); 0519 if (d->mChanges == NothingChanged) { 0520 QMetaObject::invokeMethod(this, &EventView::updateView, Qt::QueuedConnection); 0521 } 0522 0523 d->mChanges = changes; 0524 } 0525 0526 EventView::Changes EventView::changes() const 0527 { 0528 Q_D(const EventView); 0529 return d->mChanges; 0530 } 0531 0532 void EventView::restoreConfig(const KConfigGroup &configGroup) 0533 { 0534 Q_D(EventView); 0535 const bool useCustom = configGroup.readEntry("UseCustomCollectionSelection", false); 0536 if (!d->collectionSelectionModel && !useCustom) { 0537 delete d->collectionSelectionModel; 0538 d->collectionSelectionModel = nullptr; 0539 d->setUpModels(); 0540 } else if (useCustom) { 0541 if (!d->collectionSelectionModel) { 0542 // Sort the calendar model on calendar name 0543 auto sortProxy = new QSortFilterProxyModel(this); 0544 sortProxy->setDynamicSortFilter(true); 0545 sortProxy->setSortCaseSensitivity(Qt::CaseInsensitive); 0546 sortProxy->setSourceModel(d->model); 0547 0548 // Only show the first column. 0549 auto columnFilterProxy = new KRearrangeColumnsProxyModel(this); 0550 columnFilterProxy->setSourceColumns(QList<int>() << 0); 0551 columnFilterProxy->setSourceModel(sortProxy); 0552 0553 // Make the calendar model checkable. 0554 d->collectionSelectionModel = new KCheckableProxyModel(this); 0555 d->collectionSelectionModel->setSourceModel(columnFilterProxy); 0556 0557 d->setUpModels(); 0558 } 0559 const KConfigGroup selectionGroup = configGroup.config()->group(configGroup.name() + QLatin1StringView("_selectionSetup")); 0560 0561 KViewStateMaintainer<ETMViewStateSaver> maintainer(selectionGroup); 0562 maintainer.setSelectionModel(d->collectionSelectionModel->selectionModel()); 0563 maintainer.restoreState(); 0564 } 0565 0566 doRestoreConfig(configGroup); 0567 } 0568 0569 void EventView::saveConfig(KConfigGroup &configGroup) 0570 { 0571 Q_D(EventView); 0572 configGroup.writeEntry("UseCustomCollectionSelection", d->collectionSelectionModel != nullptr); 0573 0574 if (d->collectionSelectionModel) { 0575 KConfigGroup selectionGroup = configGroup.config()->group(configGroup.name() + QLatin1StringView("_selectionSetup")); 0576 0577 KViewStateMaintainer<ETMViewStateSaver> maintainer(selectionGroup); 0578 maintainer.setSelectionModel(d->collectionSelectionModel->selectionModel()); 0579 maintainer.saveState(); 0580 } 0581 0582 doSaveConfig(configGroup); 0583 } 0584 0585 bool EventView::makesWholeDayBusy(const KCalendarCore::Incidence::Ptr &incidence) const 0586 { 0587 // Must be event 0588 // Must be all day 0589 // Must be marked busy (TRANSP: OPAQUE) 0590 // You must be attendee or organizer 0591 0592 if (incidence->type() != KCalendarCore::Incidence::TypeEvent || !incidence->allDay()) { 0593 return false; 0594 } 0595 0596 KCalendarCore::Event::Ptr ev = incidence.staticCast<KCalendarCore::Event>(); 0597 0598 if (ev->transparency() != KCalendarCore::Event::Opaque) { 0599 return false; 0600 } 0601 0602 // Last check: must be organizer or attendee: 0603 0604 if (kcalPreferences()->thatIsMe(ev->organizer().email())) { 0605 return true; 0606 } 0607 0608 KCalendarCore::Attendee::List attendees = ev->attendees(); 0609 KCalendarCore::Attendee::List::ConstIterator it; 0610 for (it = attendees.constBegin(); it != attendees.constEnd(); ++it) { 0611 if (kcalPreferences()->thatIsMe((*it).email())) { 0612 return true; 0613 } 0614 } 0615 0616 return false; 0617 } 0618 0619 /*static*/ 0620 QColor EventView::itemFrameColor(const QColor &color, bool selected) 0621 { 0622 if (color.isValid()) { 0623 return selected ? QColor(85 + color.red() * 2.0 / 3, 85 + color.green() * 2.0 / 3, 85 + color.blue() * 2.0 / 3) : color.darker(115); 0624 } else { 0625 return Qt::black; 0626 } 0627 } 0628 0629 QString EventView::iconForItem(const Akonadi::Item &item) 0630 { 0631 Q_D(EventView); 0632 QString iconName; 0633 Akonadi::Collection collection = item.parentCollection(); 0634 while (collection.parentCollection().isValid() && collection.parentCollection() != Akonadi::Collection::root()) { 0635 collection = Akonadi::EntityTreeModel::updatedCollection(d->model, collection.parentCollection()); 0636 } 0637 0638 if (collection.isValid() && collection.hasAttribute<Akonadi::EntityDisplayAttribute>()) { 0639 iconName = collection.attribute<Akonadi::EntityDisplayAttribute>()->iconName(); 0640 } 0641 0642 return iconName; 0643 } 0644 0645 void EventView::onCollectionChanged(const Akonadi::Collection &collection, const QSet<QByteArray> &changedAttributes) 0646 { 0647 Q_UNUSED(collection) 0648 if (changedAttributes.contains("AccessRights")) { 0649 setChanges(changes() | EventViews::EventView::ResourcesChanged); 0650 updateView(); 0651 } 0652 } 0653 0654 QList<Akonadi::CollectionCalendar::Ptr> EventView::calendars() const 0655 { 0656 Q_D(const EventView); 0657 return d->mCalendars; 0658 } 0659 0660 Akonadi::CollectionCalendar::Ptr EventView::calendar3(const Akonadi::Item &item) const 0661 { 0662 Q_D(const EventView); 0663 return calendarForCollection(item.storageCollectionId()); 0664 } 0665 0666 Akonadi::CollectionCalendar::Ptr EventView::calendar3(const KCalendarCore::Incidence::Ptr &incidence) const 0667 { 0668 Q_D(const EventView); 0669 const auto collectionId = incidence->customProperty("VOLATILE", "COLLECTION-ID").toLongLong(); 0670 return calendarForCollection(collectionId); 0671 } 0672 0673 Akonadi::CollectionCalendar::Ptr EventView::calendarForCollection(Akonadi::Collection::Id collectionId) const 0674 { 0675 const auto hasCollectionId = [collectionId](const Akonadi::CollectionCalendar::Ptr &calendar) { 0676 return calendar->collection().id() == collectionId; 0677 }; 0678 0679 Q_D(const EventView); 0680 const auto cal = std::find_if(d->mCalendars.cbegin(), d->mCalendars.cend(), hasCollectionId); 0681 return cal != d->mCalendars.cend() ? *cal : Akonadi::CollectionCalendar::Ptr{}; 0682 } 0683 0684 Akonadi::CollectionCalendar::Ptr EventView::calendarForCollection(const Akonadi::Collection &collection) const 0685 { 0686 return calendarForCollection(collection.id()); 0687 } 0688 0689 #include "moc_eventview.cpp"