Eventviews

monthview.cpp
1/*
2 SPDX-FileCopyrightText: 2008 Bruno Virlet <bruno.virlet@gmail.com>
3 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
4 SPDX-FileContributor: Bertjan Broeksema <broeksema@kde.org>
5
6 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
7*/
8
9#include "monthview.h"
10#include "monthgraphicsitems.h"
11#include "monthitem.h"
12#include "monthscene.h"
13#include "prefs.h"
14
15#include <Akonadi/CalendarBase>
16#include <CalendarSupport/CollectionSelection>
17#include <CalendarSupport/KCalPrefs>
18#include <CalendarSupport/Utils>
19
20#include "calendarview_debug.h"
21#include <KCalendarCore/OccurrenceIterator>
22#include <KCheckableProxyModel>
23#include <KLocalizedString>
24#include <QIcon>
25
26#include <QHBoxLayout>
27#include <QTimer>
28#include <QToolButton>
29#include <QWheelEvent>
30
31#include <ranges>
32
33using namespace EventViews;
34
35namespace EventViews
36{
37class MonthViewPrivate : public KCalendarCore::Calendar::CalendarObserver
38{
39 MonthView *const q;
40
41public: /// Methods
42 explicit MonthViewPrivate(MonthView *qq);
43
44 MonthItem *loadCalendarIncidences(const Akonadi::CollectionCalendar::Ptr &calendar, const QDateTime &startDt, const QDateTime &endDt);
45
46 void addIncidence(const Akonadi::Item &incidence);
47 void moveStartDate(int weeks, int months);
48 // void setUpModels();
49 void triggerDelayedReload(EventView::Change reason);
50
51public: /// Members
52 QTimer reloadTimer;
53 MonthScene *scene = nullptr;
54 QDate selectedItemDate;
55 Akonadi::Item::Id selectedItemId;
56 MonthGraphicsView *view = nullptr;
57 QToolButton *fullView = nullptr;
58
59 // List of uids for QDate
60 QMap<QDate, QStringList> mBusyDays;
61
62protected:
63 /* reimplemented from KCalendarCore::Calendar::CalendarObserver */
64 void calendarIncidenceAdded(const KCalendarCore::Incidence::Ptr &incidence) override;
65 void calendarIncidenceChanged(const KCalendarCore::Incidence::Ptr &incidence) override;
66 void calendarIncidenceDeleted(const KCalendarCore::Incidence::Ptr &incidence, const KCalendarCore::Calendar *calendar) override;
67
68private:
69 // quiet --overloaded-virtual warning
71};
72}
73
74MonthViewPrivate::MonthViewPrivate(MonthView *qq)
75 : q(qq)
76 , scene(new MonthScene(qq))
77 , selectedItemId(-1)
78 , view(new MonthGraphicsView(qq))
79 , fullView(nullptr)
80{
81 reloadTimer.setSingleShot(true);
82 view->setScene(scene);
83}
84
85MonthItem *MonthViewPrivate::loadCalendarIncidences(const Akonadi::CollectionCalendar::Ptr &calendar, const QDateTime &startDt, const QDateTime &endDt)
86{
87 MonthItem *itemToReselect = nullptr;
88
89 const bool colorMonthBusyDays = q->preferences()->colorMonthBusyDays();
90
91 KCalendarCore::OccurrenceIterator occurIter(*calendar, startDt, endDt);
92 while (occurIter.hasNext()) {
93 occurIter.next();
94
95 // Remove the two checks when filtering is done through a proxyModel, when using calendar search
96 if (!q->preferences()->showTodosMonthView() && occurIter.incidence()->type() == KCalendarCore::Incidence::TypeTodo) {
97 continue;
98 }
99 if (!q->preferences()->showJournalsMonthView() && occurIter.incidence()->type() == KCalendarCore::Incidence::TypeJournal) {
100 continue;
101 }
102
103 const bool busyDay = colorMonthBusyDays && q->makesWholeDayBusy(occurIter.incidence());
104 if (busyDay) {
105 QStringList &list = mBusyDays[occurIter.occurrenceStartDate().date()];
106 list.append(occurIter.incidence()->uid());
107 }
108
109 const Akonadi::Item item = calendar->item(occurIter.incidence());
110 if (!item.isValid()) {
111 continue;
112 }
113 Q_ASSERT(item.isValid());
114 Q_ASSERT(item.hasPayload());
115 MonthItem *manager = new IncidenceMonthItem(scene, calendar, item, occurIter.incidence(), occurIter.occurrenceStartDate().toLocalTime().date());
116 scene->mManagerList.push_back(manager);
117 if (selectedItemId == item.id() && manager->realStartDate() == selectedItemDate) {
118 // only select it outside the loop because we are still creating items
119 itemToReselect = manager;
120 }
121 }
122
123 return itemToReselect;
124}
125
126void MonthViewPrivate::addIncidence(const Akonadi::Item &incidence)
127{
128 Q_UNUSED(incidence)
129 // TODO: add some more intelligence here...
130 q->setChanges(q->changes() | EventView::IncidencesAdded);
131 reloadTimer.start(50);
132}
133
134void MonthViewPrivate::moveStartDate(int weeks, int months)
135{
136 auto start = q->startDateTime();
137 auto end = q->endDateTime();
138 start = start.addDays(weeks * 7);
139 end = end.addDays(weeks * 7);
140 start = start.addMonths(months);
141 end = end.addMonths(months);
142
144 QDate d = start.date();
145 const QDate e = end.date();
146 dateList.reserve(d.daysTo(e) + 1);
147 while (d <= e) {
148 dateList.append(d);
149 d = d.addDays(1);
150 }
151
152 /**
153 * If we call q->setDateRange( start, end ); directly,
154 * it will change the selected dates in month view,
155 * but the application won't know about it.
156 * The correct way is to Q_EMIT datesSelected()
157 * #250256
158 * */
159 Q_EMIT q->datesSelected(dateList);
160}
161
162void MonthViewPrivate::triggerDelayedReload(EventView::Change reason)
163{
164 q->setChanges(q->changes() | reason);
165 if (!reloadTimer.isActive()) {
166 reloadTimer.start(50);
167 }
168}
169
170void MonthViewPrivate::calendarIncidenceAdded(const KCalendarCore::Incidence::Ptr &)
171{
172 triggerDelayedReload(MonthView::IncidencesAdded);
173}
174
175void MonthViewPrivate::calendarIncidenceChanged(const KCalendarCore::Incidence::Ptr &)
176{
177 triggerDelayedReload(MonthView::IncidencesEdited);
178}
179
180void MonthViewPrivate::calendarIncidenceDeleted(const KCalendarCore::Incidence::Ptr &incidence, const KCalendarCore::Calendar *calendar)
181{
182 Q_UNUSED(calendar)
183 Q_ASSERT(!incidence->uid().isEmpty());
184 scene->removeIncidence(incidence->uid());
185}
186
187/// MonthView
188
189MonthView::MonthView(NavButtonsVisibility visibility, QWidget *parent)
191 , d(new MonthViewPrivate(this))
192{
193 auto topLayout = new QHBoxLayout(this);
194 topLayout->addWidget(d->view);
195 topLayout->setContentsMargins({});
196
197 if (visibility == Visible) {
198 auto rightLayout = new QVBoxLayout();
199 rightLayout->setSpacing(0);
200 rightLayout->setContentsMargins({});
201
202 // push buttons to the bottom
203 rightLayout->addStretch(1);
204
205 d->fullView = new QToolButton(this);
206 d->fullView->setIcon(QIcon::fromTheme(QStringLiteral("view-fullscreen")));
207 d->fullView->setAutoRaise(true);
208 d->fullView->setCheckable(true);
209 d->fullView->setChecked(preferences()->fullViewMonth());
210 d->fullView->isChecked() ? d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a normal size"))
211 : d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a full window"));
212 d->fullView->setWhatsThis(i18nc("@info:whatsthis",
213 "Click this button and the month view will be enlarged to fill the "
214 "maximum available window space / or shrunk back to its normal size."));
215 connect(d->fullView, &QAbstractButton::clicked, this, &MonthView::changeFullView);
216
217 auto minusMonth = new QToolButton(this);
218 minusMonth->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up-double")));
219 minusMonth->setAutoRaise(true);
220 minusMonth->setToolTip(i18nc("@info:tooltip", "Go back one month"));
221 minusMonth->setWhatsThis(i18nc("@info:whatsthis", "Click this button and the view will be scrolled back in time by 1 month."));
223
224 auto minusWeek = new QToolButton(this);
225 minusWeek->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up")));
226 minusWeek->setAutoRaise(true);
227 minusWeek->setToolTip(i18nc("@info:tooltip", "Go back one week"));
228 minusWeek->setWhatsThis(i18nc("@info:whatsthis", "Click this button and the view will be scrolled back in time by 1 week."));
230
231 auto plusWeek = new QToolButton(this);
232 plusWeek->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down")));
233 plusWeek->setAutoRaise(true);
234 plusWeek->setToolTip(i18nc("@info:tooltip", "Go forward one week"));
235 plusWeek->setWhatsThis(i18nc("@info:whatsthis", "Click this button and the view will be scrolled forward in time by 1 week."));
237
238 auto plusMonth = new QToolButton(this);
239 plusMonth->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down-double")));
240 plusMonth->setAutoRaise(true);
241 plusMonth->setToolTip(i18nc("@info:tooltip", "Go forward one month"));
242 plusMonth->setWhatsThis(i18nc("@info:whatsthis", "Click this button and the view will be scrolled forward in time by 1 month."));
244
245 rightLayout->addWidget(d->fullView);
246 rightLayout->addWidget(minusMonth);
247 rightLayout->addWidget(minusWeek);
248 rightLayout->addWidget(plusWeek);
249 rightLayout->addWidget(plusMonth);
250
251 topLayout->addLayout(rightLayout);
252 } else {
253 d->view->setFrameStyle(QFrame::NoFrame);
254 }
255
256 connect(d->scene, &MonthScene::showIncidencePopupSignal, this, &MonthView::showIncidencePopupSignal);
257
258 connect(d->scene, &MonthScene::incidenceSelected, this, &EventView::incidenceSelected);
259
260 connect(d->scene, qOverload<>(&MonthScene::newEventSignal), this, qOverload<>(&EventView::newEventSignal));
261 connect(d->scene, qOverload<const QDate &>(&MonthScene::newEventSignal), this, qOverload<const QDate &>(&EventView::newEventSignal));
262
263 connect(d->scene, &MonthScene::showNewEventPopupSignal, this, &MonthView::showNewEventPopupSignal);
264
265 connect(&d->reloadTimer, &QTimer::timeout, this, &MonthView::reloadIncidences);
266 updateConfig();
267
268 // d->setUpModels();
269 d->reloadTimer.start(50);
270}
271
272MonthView::~MonthView()
273{
274 for (auto &calendar : calendars()) {
275 calendar->unregisterObserver(d.get());
276 }
277}
278
279void MonthView::addCalendar(const Akonadi::CollectionCalendar::Ptr &calendar)
280{
281 EventView::addCalendar(calendar);
282 calendar->registerObserver(d.get());
283 setChanges(changes() | ResourcesChanged);
284 d->reloadTimer.start(50);
285}
286
287void MonthView::removeCalendar(const Akonadi::CollectionCalendar::Ptr &calendar)
288{
289 EventView::removeCalendar(calendar);
290 calendar->unregisterObserver(d.get());
291 setChanges(changes() | ResourcesChanged);
292 d->reloadTimer.start(50);
293}
294
295void MonthView::updateConfig()
296{
297 d->scene->update();
298 setChanges(changes() | ConfigChanged);
299 d->reloadTimer.start(50);
300}
301
303{
304 return actualStartDateTime().date().daysTo(actualEndDateTime().date());
305}
306
308{
310 if (d->scene->selectedItem()) {
311 auto tmp = qobject_cast<IncidenceMonthItem *>(d->scene->selectedItem());
312 if (tmp) {
313 QDate selectedItemDate = tmp->realStartDate();
314 if (selectedItemDate.isValid()) {
315 list << selectedItemDate;
316 }
317 }
318 } else if (d->scene->selectedCell()) {
319 list << d->scene->selectedCell()->date();
320 }
321
322 return list;
323}
324
326{
327 if (d->scene->selectedCell()) {
328 return QDateTime(d->scene->selectedCell()->date().startOfDay());
329 } else {
330 return {};
331 }
332}
333
335{
336 // Only one cell can be selected (for now)
337 return selectionStart();
338}
339
340void MonthView::setDateRange(const QDateTime &start, const QDateTime &end, const QDate &preferredMonth)
341{
342 EventView::setDateRange(start, end, preferredMonth);
343 setChanges(changes() | DatesChanged);
344 d->reloadTimer.start(50);
345}
346
347static QTime nextQuarterHour(const QTime &time)
348{
349 if (time.second() % 900) {
350 return time.addSecs(900 - (time.minute() * 60 + time.second()) % 900);
351 }
352 return time; // roundup not needed
353}
354
355static QTime adjustedDefaultStartTime(const QDate &startDt)
356{
357 QTime prefTime;
358 if (CalendarSupport::KCalPrefs::instance()->startTime().isValid()) {
359 prefTime = CalendarSupport::KCalPrefs::instance()->startTime().time();
360 }
361
362 const QDateTime currentDateTime = QDateTime::currentDateTime();
363 if (startDt == currentDateTime.date()) {
364 // If today and the current time is already past the default time
365 // use the next quarter hour after the current time.
366 // but don't spill over into tomorrow.
367 const QTime currentTime = currentDateTime.time();
368 if (!prefTime.isValid() || (currentTime > prefTime && currentTime < QTime(23, 45))) {
369 prefTime = nextQuarterHour(currentTime);
370 }
371 }
372 return prefTime;
373}
374
375bool MonthView::eventDurationHint(QDateTime &startDt, QDateTime &endDt, bool &allDay) const
376{
377 Q_UNUSED(allDay);
378 auto defaultDuration = CalendarSupport::KCalPrefs::instance()->defaultDuration().time();
379 auto duration = (defaultDuration.hour() * 3600) + (defaultDuration.minute() * 60);
380 if (startDt.isValid()) {
381 if (endDt.isValid()) {
382 if (startDt >= endDt) {
383 endDt.setTime(startDt.time().addSecs(duration));
384 }
385 } else {
386 endDt.setDate(startDt.date());
387 endDt.setTime(startDt.time().addSecs(duration));
388 }
389 return true;
390 }
391
392 if (d->scene->selectedCell()) {
393 startDt.setDate(d->scene->selectedCell()->date());
394 startDt.setTime(adjustedDefaultStartTime(startDt.date()));
395
396 endDt.setDate(d->scene->selectedCell()->date());
397 endDt.setTime(startDt.time().addSecs(duration));
398 return true;
399 }
400
401 return false;
402}
403
404void MonthView::showIncidences(const Akonadi::Item::List &incidenceList, const QDate &date)
405{
406 Q_UNUSED(incidenceList)
407 Q_UNUSED(date)
408}
409
410void MonthView::changeIncidenceDisplay(const Akonadi::Item &incidence, int action)
411{
412 Q_UNUSED(incidence)
413 Q_UNUSED(action)
414
415 // TODO: add some more intelligence here...
416
417 // don't call reloadIncidences() directly. It would delete all
418 // MonthItems, but this changeIncidenceDisplay()-method was probably
419 // called by one of the MonthItem objects. So only schedule a reload
420 // as event
421 setChanges(changes() | IncidencesEdited);
422 d->reloadTimer.start(50);
423}
424
425void MonthView::updateView()
426{
427 d->view->update();
428}
429
430#ifndef QT_NO_WHEELEVENT
431void MonthView::wheelEvent(QWheelEvent *event)
432{
433 // invert direction to get scroll-like behaviour
434 if (event->angleDelta().y() > 0) {
435 d->moveStartDate(-1, 0);
436 } else if (event->angleDelta().y() < 0) {
437 d->moveStartDate(1, 0);
438 }
439
440 // call accept in every case, we do not want anybody else to react
441 event->accept();
442}
443
444#endif
445
446void MonthView::keyPressEvent(QKeyEvent *event)
447{
448 if (event->key() == Qt::Key_PageUp) {
449 d->moveStartDate(0, -1);
450 event->accept();
451 } else if (event->key() == Qt::Key_PageDown) {
452 d->moveStartDate(0, 1);
453 event->accept();
454 } else if (processKeyEvent(event)) {
455 event->accept();
456 } else {
457 event->ignore();
458 }
459}
460
461void MonthView::keyReleaseEvent(QKeyEvent *event)
462{
463 if (processKeyEvent(event)) {
464 event->accept();
465 } else {
466 event->ignore();
467 }
468}
469
470void MonthView::changeFullView()
471{
472 bool fullView = d->fullView->isChecked();
473
474 if (fullView) {
475 d->fullView->setIcon(QIcon::fromTheme(QStringLiteral("view-restore")));
476 d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a normal size"));
477 } else {
478 d->fullView->setIcon(QIcon::fromTheme(QStringLiteral("view-fullscreen")));
479 d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a full window"));
480 }
481 preferences()->setFullViewMonth(fullView);
482 preferences()->writeConfig();
483
484 Q_EMIT fullViewChanged(fullView);
485}
486
488{
489 d->moveStartDate(0, -1);
490}
491
493{
494 d->moveStartDate(-1, 0);
495}
496
498{
499 d->moveStartDate(1, 0);
500}
501
503{
504 d->moveStartDate(0, 1);
505}
506
507void MonthView::showDates(const QDate &start, const QDate &end, const QDate &preferedMonth)
508{
509 Q_UNUSED(start)
510 Q_UNUSED(end)
511 Q_UNUSED(preferedMonth)
512 d->triggerDelayedReload(DatesChanged);
513}
514
515QPair<QDateTime, QDateTime> MonthView::actualDateRange(const QDateTime &start, const QDateTime &, const QDate &preferredMonth) const
516{
517 QDateTime dayOne = preferredMonth.isValid() ? QDateTime(preferredMonth.startOfDay()) : start;
518
519 dayOne.setDate(QDate(dayOne.date().year(), dayOne.date().month(), 1));
520 const int weekdayCol = (dayOne.date().dayOfWeek() + 7 - preferences()->firstDayOfWeek()) % 7;
521 QDateTime actualStart = dayOne.addDays(-weekdayCol);
522 actualStart.setTime(QTime(0, 0, 0, 0));
523 QDateTime actualEnd = actualStart.addDays(6 * 7 - 1);
524 actualEnd.setTime(QTime(23, 59, 59, 99));
525 return qMakePair(actualStart, actualEnd);
526}
527
529{
530 Akonadi::Item::List selected;
531 if (d->scene->selectedItem()) {
532 auto tmp = qobject_cast<IncidenceMonthItem *>(d->scene->selectedItem());
533 if (tmp) {
534 Akonadi::Item incidenceSelected = tmp->akonadiItem();
535 if (incidenceSelected.isValid()) {
536 selected.append(incidenceSelected);
537 }
538 }
539 }
540 return selected;
541}
542
543KHolidays::Holiday::List MonthView::holidays(QDate startDate, QDate endDate)
544{
546 auto const regions = CalendarSupport::KCalPrefs::instance()->mHolidays;
547 for (auto const &r : regions) {
548 KHolidays::HolidayRegion region(r);
549 if (region.isValid()) {
550 holidays += region.rawHolidaysWithAstroSeasons(startDate, endDate);
551 }
552 }
553 return holidays;
554}
555
556void MonthView::reloadIncidences()
557{
558 if (changes() == NothingChanged) {
559 return;
560 }
561 // keep selection if it exists
562 Akonadi::Item incidenceSelected;
563
564 MonthItem *itemToReselect = nullptr;
565
566 if (auto tmp = qobject_cast<IncidenceMonthItem *>(d->scene->selectedItem())) {
567 d->selectedItemId = tmp->akonadiItem().id();
568 d->selectedItemDate = tmp->realStartDate();
569 if (!d->selectedItemDate.isValid()) {
570 return;
571 }
572 }
573
574 d->scene->resetAll();
575 d->mBusyDays.clear();
576 // build monthcells hash
577 int i = 0;
578 for (QDate date = actualStartDateTime().date(); date <= actualEndDateTime().date(); date = date.addDays(1)) {
579 d->scene->mMonthCellMap[date] = new MonthCell(i, date, d->scene);
580 i++;
581 }
582
583 // build global event list
584 for (const auto &calendar : calendars()) {
585 auto *newItemToReselect = d->loadCalendarIncidences(calendar, actualStartDateTime(), actualEndDateTime());
586 if (itemToReselect == nullptr) {
587 itemToReselect = newItemToReselect;
588 }
589 }
590
591 if (itemToReselect) {
592 d->scene->selectItem(itemToReselect);
593 }
594
595 // add holidays
596 for (auto const &h : holidays(actualStartDateTime().date(), actualEndDateTime().date())) {
597 if (h.dayType() == KHolidays::Holiday::NonWorkday) {
598 MonthItem *holidayItem = new HolidayMonthItem(d->scene, h.observedStartDate(), h.observedEndDate(), h.name());
599 d->scene->mManagerList << holidayItem;
600 }
601 }
602
603 // sort it
604 std::sort(d->scene->mManagerList.begin(), d->scene->mManagerList.end(), MonthItem::greaterThan);
605
606 // build each month's cell event list
607 for (MonthItem *manager : std::as_const(d->scene->mManagerList)) {
608 for (QDate date = manager->startDate(); date <= manager->endDate(); date = date.addDays(1)) {
609 MonthCell *cell = d->scene->mMonthCellMap.value(date);
610 if (cell) {
611 cell->mMonthItemList << manager;
612 }
613 }
614 }
615
616 for (MonthItem *manager : std::as_const(d->scene->mManagerList)) {
617 manager->updateMonthGraphicsItems();
618 manager->updatePosition();
619 }
620
621 for (MonthItem *manager : std::as_const(d->scene->mManagerList)) {
622 manager->updateGeometry();
623 }
624
625 d->scene->setInitialized(true);
626 d->view->update();
627 d->scene->update();
628}
629
631{
632 qCDebug(CALENDARVIEW_LOG);
633 d->triggerDelayedReload(ResourcesChanged);
634}
635
637{
638 return actualStartDateTime().date().addDays(actualStartDateTime().date().daysTo(actualEndDateTime().date()) / 2);
639}
640
641int MonthView::currentMonth() const
642{
643 return averageDate().month();
644}
645
646bool MonthView::usesFullWindow()
647{
648 return preferences()->fullViewMonth();
649}
650
651bool MonthView::isBusyDay(QDate day) const
652{
653 return !d->mBusyDays[day].isEmpty();
654}
655
656#include "moc_monthview.cpp"
Id id() const
bool isValid() const
bool hasPayload() const
QList< Item > List
bool processKeyEvent(QKeyEvent *)
Handles key events, opens the new event dialog when enter is pressed, activates type ahead.
virtual void setChanges(Changes changes)
Notifies the view that there are pending changes so a redraw is needed.
void newEventSignal()
instructs the receiver to create a new event in given collection.
EventView(QWidget *parent=nullptr)
Constructs a view.
Definition eventview.cpp:54
Changes changes() const
Returns if there are pending changes and a redraw is needed.
virtual void setDateRange(const QDateTime &start, const QDateTime &end, const QDate &preferredMonth=QDate())
QList< MonthItem * > mMonthItemList
This is used to get the height of the minimum height (vertical position) in the month cells.
Renders a MonthScene.
Definition monthscene.h:317
A month item manages different MonthGraphicsItems.
Definition monthitem.h:27
static bool greaterThan(const MonthItem *e1, const MonthItem *e2)
Compares two items to decide which to place in the view first.
void updateGeometry()
Updates geometry of all MonthGraphicsItems.
void updatePosition()
Find the lowest possible position for this item.
QDate startDate() const
The start date of the incidence, generally realStartDate.
void updateMonthGraphicsItems()
Update the monthgraphicsitems.
Definition monthitem.cpp:54
virtual QDate realStartDate() const =0
This is the real start date, usually the start date of the incidence.
QDateTime selectionStart() const override
Returns the start of the selection, or an invalid QDateTime if there is no selection or the view does...
void moveBackWeek()
Shift the view one month back.
void moveFwdMonth()
Shift the view one week forward.
void setDateRange(const QDateTime &start, const QDateTime &end, const QDate &preferredMonth=QDate()) override
void calendarReset() override
Shift the view one month forward.
MonthView(NavButtonsVisibility visibility=Visible, QWidget *parent=nullptr)
MonthView.
QDate averageDate() const
Returns the average date in the view.
Akonadi::Item::List selectedIncidences() const override
void moveFwdWeek()
Shift the view one week back.
bool eventDurationHint(QDateTime &startDt, QDateTime &endDt, bool &allDay) const override
Sets the default start/end date/time for new events.
void showDates(const QDate &start, const QDate &end, const QDate &preferedMonth=QDate()) override
QPair< QDateTime, QDateTime > actualDateRange(const QDateTime &start, const QDateTime &end, const QDate &preferredMonth=QDate()) const override
from the requested date range (passed via setDateRange()), calculates the adjusted date range actuall...
QDateTime selectionEnd() const override
Returns the end of the selection, or an invalid QDateTime if there is no selection or the view doesn'...
int currentDateCount() const override
Returns the number of currently shown dates.
void moveBackMonth()
Display in full window mode.
KCalendarCore::DateList selectedIncidenceDates() const override
Returns dates of the currently selected events.
virtual void calendarIncidenceDeleted(const Incidence::Ptr &incidence, const Calendar *calendar)
QSharedPointer< Calendar > Ptr
void unregisterObserver(CalendarObserver *observer)
QSharedPointer< Incidence > Ptr
QList< Holiday > List
Q_SCRIPTABLE QString start(QString train="")
Q_SCRIPTABLE Q_NOREPLY void start()
QString i18nc(const char *context, const char *text, const TYPE &arg...)
AKONADI_CALENDAR_EXPORT KCalendarCore::Incidence::Ptr incidence(const Akonadi::Item &item)
Namespace EventViews provides facilities for displaying incidences, including events,...
Definition agenda.h:33
QList< QDate > DateList
QAction * end(const QObject *recvr, const char *slot, QObject *parent)
bool isValid(QStringView ifopt)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
void clicked(bool checked)
QDate addDays(qint64 ndays) const const
qint64 daysTo(QDate d) const const
bool isValid(int year, int month, int day)
int month() const const
QDateTime startOfDay() const const
int year() const const
QDateTime addDays(qint64 ndays) const const
QDateTime currentDateTime()
QDate date() const const
bool isValid() const const
void setDate(QDate date)
void setTime(QTime time)
QTime time() const const
QIcon fromTheme(const QString &name)
void append(QList< T > &&value)
void reserve(qsizetype size)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool event(QEvent *e)
QObject * parent() const const
T qobject_cast(QObject *object)
Key_PageUp
QTime addSecs(int s) const const
bool isValid(int h, int m, int s, int ms)
int minute() const const
int second() const const
void timeout()
QWidget(QWidget *parent, Qt::WindowFlags f)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 11 2025 11:48:36 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.