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{-1};
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 , view(new MonthGraphicsView(qq))
78
79{
80 reloadTimer.setSingleShot(true);
81 view->setScene(scene);
82}
83
84MonthItem *MonthViewPrivate::loadCalendarIncidences(const Akonadi::CollectionCalendar::Ptr &calendar, const QDateTime &startDt, const QDateTime &endDt)
85{
86 MonthItem *itemToReselect = nullptr;
87
88 const bool colorMonthBusyDays = q->preferences()->colorMonthBusyDays();
89
90 KCalendarCore::OccurrenceIterator occurIter(*calendar, startDt, endDt);
91 while (occurIter.hasNext()) {
92 occurIter.next();
93
94 // Remove the two checks when filtering is done through a proxyModel, when using calendar search
95 if (!q->preferences()->showTodosMonthView() && occurIter.incidence()->type() == KCalendarCore::Incidence::TypeTodo) {
96 continue;
97 }
98 if (!q->preferences()->showJournalsMonthView() && occurIter.incidence()->type() == KCalendarCore::Incidence::TypeJournal) {
99 continue;
100 }
101
102 const bool busyDay = colorMonthBusyDays && q->makesWholeDayBusy(occurIter.incidence());
103 if (busyDay) {
104 QStringList &list = mBusyDays[occurIter.occurrenceStartDate().date()];
105 list.append(occurIter.incidence()->uid());
106 }
107
108 const Akonadi::Item item = calendar->item(occurIter.incidence());
109 if (!item.isValid()) {
110 continue;
111 }
112 Q_ASSERT(item.isValid());
113 Q_ASSERT(item.hasPayload());
114 MonthItem *manager = new IncidenceMonthItem(scene, calendar, item, occurIter.incidence(), occurIter.occurrenceStartDate().toLocalTime().date());
115 scene->mManagerList.push_back(manager);
116 if (selectedItemId == item.id() && manager->realStartDate() == selectedItemDate) {
117 // only select it outside the loop because we are still creating items
118 itemToReselect = manager;
119 }
120 }
121
122 return itemToReselect;
123}
124
125void MonthViewPrivate::addIncidence(const Akonadi::Item &incidence)
126{
127 Q_UNUSED(incidence)
128 // TODO: add some more intelligence here...
129 q->setChanges(q->changes() | EventView::IncidencesAdded);
130 reloadTimer.start(50);
131}
132
133void MonthViewPrivate::moveStartDate(int weeks, int months)
134{
135 auto start = q->startDateTime();
136 auto end = q->endDateTime();
137 start = start.addDays(weeks * 7);
138 end = end.addDays(weeks * 7);
139 start = start.addMonths(months);
140 end = end.addMonths(months);
141
143 QDate d = start.date();
144 const QDate e = end.date();
145 dateList.reserve(d.daysTo(e) + 1);
146 while (d <= e) {
147 dateList.append(d);
148 d = d.addDays(1);
149 }
150
151 /**
152 * If we call q->setDateRange( start, end ); directly,
153 * it will change the selected dates in month view,
154 * but the application won't know about it.
155 * The correct way is to Q_EMIT datesSelected()
156 * #250256
157 * */
158 Q_EMIT q->datesSelected(dateList);
159}
160
161void MonthViewPrivate::triggerDelayedReload(EventView::Change reason)
162{
163 q->setChanges(q->changes() | reason);
164 if (!reloadTimer.isActive()) {
165 reloadTimer.start(50);
166 }
167}
168
169void MonthViewPrivate::calendarIncidenceAdded(const KCalendarCore::Incidence::Ptr &)
170{
171 triggerDelayedReload(MonthView::IncidencesAdded);
172}
173
174void MonthViewPrivate::calendarIncidenceChanged(const KCalendarCore::Incidence::Ptr &)
175{
176 triggerDelayedReload(MonthView::IncidencesEdited);
177}
178
179void MonthViewPrivate::calendarIncidenceDeleted(const KCalendarCore::Incidence::Ptr &incidence, const KCalendarCore::Calendar *calendar)
180{
181 Q_UNUSED(calendar)
182 Q_ASSERT(!incidence->uid().isEmpty());
183 scene->removeIncidence(incidence->uid());
184}
185
186/// MonthView
187
188MonthView::MonthView(NavButtonsVisibility visibility, QWidget *parent)
190 , d(new MonthViewPrivate(this))
191{
192 auto topLayout = new QHBoxLayout(this);
193 topLayout->addWidget(d->view);
194 topLayout->setContentsMargins({});
195
196 if (visibility == Visible) {
197 auto rightLayout = new QVBoxLayout();
198 rightLayout->setSpacing(0);
199 rightLayout->setContentsMargins({});
200
201 // push buttons to the bottom
202 rightLayout->addStretch(1);
203
204 d->fullView = new QToolButton(this);
205 d->fullView->setIcon(QIcon::fromTheme(QStringLiteral("view-fullscreen")));
206 d->fullView->setAutoRaise(true);
207 d->fullView->setCheckable(true);
208 d->fullView->setChecked(preferences()->fullViewMonth());
209 d->fullView->isChecked() ? d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a normal size"))
210 : d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a full window"));
211 d->fullView->setWhatsThis(i18nc("@info:whatsthis",
212 "Click this button and the month view will be enlarged to fill the "
213 "maximum available window space / or shrunk back to its normal size."));
214 connect(d->fullView, &QAbstractButton::clicked, this, &MonthView::changeFullView);
215
216 auto minusMonth = new QToolButton(this);
217 minusMonth->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up-double")));
218 minusMonth->setAutoRaise(true);
219 minusMonth->setToolTip(i18nc("@info:tooltip", "Go back one month"));
220 minusMonth->setWhatsThis(i18nc("@info:whatsthis", "Click this button and the view will be scrolled back in time by 1 month."));
222
223 auto minusWeek = new QToolButton(this);
224 minusWeek->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up")));
225 minusWeek->setAutoRaise(true);
226 minusWeek->setToolTip(i18nc("@info:tooltip", "Go back one week"));
227 minusWeek->setWhatsThis(i18nc("@info:whatsthis", "Click this button and the view will be scrolled back in time by 1 week."));
229
230 auto plusWeek = new QToolButton(this);
231 plusWeek->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down")));
232 plusWeek->setAutoRaise(true);
233 plusWeek->setToolTip(i18nc("@info:tooltip", "Go forward one week"));
234 plusWeek->setWhatsThis(i18nc("@info:whatsthis", "Click this button and the view will be scrolled forward in time by 1 week."));
236
237 auto plusMonth = new QToolButton(this);
238 plusMonth->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down-double")));
239 plusMonth->setAutoRaise(true);
240 plusMonth->setToolTip(i18nc("@info:tooltip", "Go forward one month"));
241 plusMonth->setWhatsThis(i18nc("@info:whatsthis", "Click this button and the view will be scrolled forward in time by 1 month."));
243
244 rightLayout->addWidget(d->fullView);
245 rightLayout->addWidget(minusMonth);
246 rightLayout->addWidget(minusWeek);
247 rightLayout->addWidget(plusWeek);
248 rightLayout->addWidget(plusMonth);
249
250 topLayout->addLayout(rightLayout);
251 } else {
252 d->view->setFrameStyle(QFrame::NoFrame);
253 }
254
255 connect(d->scene, &MonthScene::showIncidencePopupSignal, this, &MonthView::showIncidencePopupSignal);
256
257 connect(d->scene, &MonthScene::incidenceSelected, this, &EventView::incidenceSelected);
258
259 connect(d->scene, qOverload<>(&MonthScene::newEventSignal), this, qOverload<>(&EventView::newEventSignal));
260 connect(d->scene, qOverload<const QDate &>(&MonthScene::newEventSignal), this, qOverload<const QDate &>(&EventView::newEventSignal));
261
262 connect(d->scene, &MonthScene::showNewEventPopupSignal, this, &MonthView::showNewEventPopupSignal);
263
264 connect(&d->reloadTimer, &QTimer::timeout, this, &MonthView::reloadIncidences);
265 updateConfig();
266
267 // d->setUpModels();
268 d->reloadTimer.start(50);
269}
270
271MonthView::~MonthView()
272{
273 for (auto &calendar : calendars()) {
274 calendar->unregisterObserver(d.get());
275 }
276}
277
278void MonthView::addCalendar(const Akonadi::CollectionCalendar::Ptr &calendar)
279{
280 EventView::addCalendar(calendar);
281 calendar->registerObserver(d.get());
282 setChanges(changes() | ResourcesChanged);
283 d->reloadTimer.start(50);
284}
285
286void MonthView::removeCalendar(const Akonadi::CollectionCalendar::Ptr &calendar)
287{
288 EventView::removeCalendar(calendar);
289 calendar->unregisterObserver(d.get());
290 setChanges(changes() | ResourcesChanged);
291 d->reloadTimer.start(50);
292}
293
294void MonthView::updateConfig()
295{
296 d->scene->update();
297 setChanges(changes() | ConfigChanged);
298 d->reloadTimer.start(50);
299}
300
302{
303 return actualStartDateTime().date().daysTo(actualEndDateTime().date());
304}
305
307{
309 if (d->scene->selectedItem()) {
310 auto tmp = qobject_cast<IncidenceMonthItem *>(d->scene->selectedItem());
311 if (tmp) {
312 QDate selectedItemDate = tmp->realStartDate();
313 if (selectedItemDate.isValid()) {
314 list << selectedItemDate;
315 }
316 }
317 } else if (d->scene->selectedCell()) {
318 list << d->scene->selectedCell()->date();
319 }
320
321 return list;
322}
323
325{
326 if (d->scene->selectedCell()) {
327 return QDateTime(d->scene->selectedCell()->date().startOfDay());
328 } else {
329 return {};
330 }
331}
332
334{
335 // Only one cell can be selected (for now)
336 return selectionStart();
337}
338
339void MonthView::setDateRange(const QDateTime &start, const QDateTime &end, const QDate &preferredMonth)
340{
341 EventView::setDateRange(start, end, preferredMonth);
342 setChanges(changes() | DatesChanged);
343 d->reloadTimer.start(50);
344}
345
346static QTime nextQuarterHour(const QTime &time)
347{
348 if (time.second() % 900) {
349 return time.addSecs(900 - (time.minute() * 60 + time.second()) % 900);
350 }
351 return time; // roundup not needed
352}
353
354static QTime adjustedDefaultStartTime(const QDate &startDt)
355{
356 QTime prefTime;
357 if (CalendarSupport::KCalPrefs::instance()->startTime().isValid()) {
358 prefTime = CalendarSupport::KCalPrefs::instance()->startTime().time();
359 }
360
361 const QDateTime currentDateTime = QDateTime::currentDateTime();
362 if (startDt == currentDateTime.date()) {
363 // If today and the current time is already past the default time
364 // use the next quarter hour after the current time.
365 // but don't spill over into tomorrow.
366 const QTime currentTime = currentDateTime.time();
367 if (!prefTime.isValid() || (currentTime > prefTime && currentTime < QTime(23, 45))) {
368 prefTime = nextQuarterHour(currentTime);
369 }
370 }
371 return prefTime;
372}
373
374bool MonthView::eventDurationHint(QDateTime &startDt, QDateTime &endDt, bool &allDay) const
375{
376 Q_UNUSED(allDay);
377 auto defaultDuration = CalendarSupport::KCalPrefs::instance()->defaultDuration().time();
378 auto duration = (defaultDuration.hour() * 3600) + (defaultDuration.minute() * 60);
379 if (startDt.isValid()) {
380 if (endDt.isValid()) {
381 if (startDt >= endDt) {
382 endDt.setTime(startDt.time().addSecs(duration));
383 }
384 } else {
385 endDt.setDate(startDt.date());
386 endDt.setTime(startDt.time().addSecs(duration));
387 }
388 return true;
389 }
390
391 if (d->scene->selectedCell()) {
392 startDt.setDate(d->scene->selectedCell()->date());
393 startDt.setTime(adjustedDefaultStartTime(startDt.date()));
394
395 endDt.setDate(d->scene->selectedCell()->date());
396 endDt.setTime(startDt.time().addSecs(duration));
397 return true;
398 }
399
400 return false;
401}
402
403void MonthView::showIncidences(const Akonadi::Item::List &incidenceList, const QDate &date)
404{
405 Q_UNUSED(incidenceList)
406 Q_UNUSED(date)
407}
408
409void MonthView::changeIncidenceDisplay(const Akonadi::Item &incidence, int action)
410{
411 Q_UNUSED(incidence)
412 Q_UNUSED(action)
413
414 // TODO: add some more intelligence here...
415
416 // don't call reloadIncidences() directly. It would delete all
417 // MonthItems, but this changeIncidenceDisplay()-method was probably
418 // called by one of the MonthItem objects. So only schedule a reload
419 // as event
420 setChanges(changes() | IncidencesEdited);
421 d->reloadTimer.start(50);
422}
423
424void MonthView::updateView()
425{
426 d->view->update();
427}
428
429#ifndef QT_NO_WHEELEVENT
430void MonthView::wheelEvent(QWheelEvent *event)
431{
432 // invert direction to get scroll-like behaviour
433 if (event->angleDelta().y() > 0) {
434 d->moveStartDate(-1, 0);
435 } else if (event->angleDelta().y() < 0) {
436 d->moveStartDate(1, 0);
437 }
438
439 // call accept in every case, we do not want anybody else to react
440 event->accept();
441}
442
443#endif
444
445void MonthView::keyPressEvent(QKeyEvent *event)
446{
447 if (event->key() == Qt::Key_PageUp) {
448 d->moveStartDate(0, -1);
449 event->accept();
450 } else if (event->key() == Qt::Key_PageDown) {
451 d->moveStartDate(0, 1);
452 event->accept();
453 } else if (processKeyEvent(event)) {
454 event->accept();
455 } else {
456 event->ignore();
457 }
458}
459
460void MonthView::keyReleaseEvent(QKeyEvent *event)
461{
462 if (processKeyEvent(event)) {
463 event->accept();
464 } else {
465 event->ignore();
466 }
467}
468
469void MonthView::changeFullView()
470{
471 bool fullView = d->fullView->isChecked();
472
473 if (fullView) {
474 d->fullView->setIcon(QIcon::fromTheme(QStringLiteral("view-restore")));
475 d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a normal size"));
476 } else {
477 d->fullView->setIcon(QIcon::fromTheme(QStringLiteral("view-fullscreen")));
478 d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a full window"));
479 }
480 preferences()->setFullViewMonth(fullView);
481 preferences()->writeConfig();
482
483 Q_EMIT fullViewChanged(fullView);
484}
485
487{
488 d->moveStartDate(0, -1);
489}
490
492{
493 d->moveStartDate(-1, 0);
494}
495
497{
498 d->moveStartDate(1, 0);
499}
500
502{
503 d->moveStartDate(0, 1);
504}
505
506void MonthView::showDates(const QDate &start, const QDate &end, const QDate &preferedMonth)
507{
508 Q_UNUSED(start)
509 Q_UNUSED(end)
510 Q_UNUSED(preferedMonth)
511 d->triggerDelayedReload(DatesChanged);
512}
513
514QPair<QDateTime, QDateTime> MonthView::actualDateRange(const QDateTime &start, const QDateTime &, const QDate &preferredMonth) const
515{
516 QDateTime dayOne = preferredMonth.isValid() ? QDateTime(preferredMonth.startOfDay()) : start;
517
518 dayOne.setDate(QDate(dayOne.date().year(), dayOne.date().month(), 1));
519 const int weekdayCol = (dayOne.date().dayOfWeek() + 7 - preferences()->firstDayOfWeek()) % 7;
520 QDateTime actualStart = dayOne.addDays(-weekdayCol);
521 actualStart.setTime(QTime(0, 0, 0, 0));
522 QDateTime actualEnd = actualStart.addDays(6 * 7 - 1);
523 actualEnd.setTime(QTime(23, 59, 59, 99));
524 return qMakePair(actualStart, actualEnd);
525}
526
528{
529 Akonadi::Item::List selected;
530 if (d->scene->selectedItem()) {
531 auto tmp = qobject_cast<IncidenceMonthItem *>(d->scene->selectedItem());
532 if (tmp) {
533 Akonadi::Item incidenceSelected = tmp->akonadiItem();
534 if (incidenceSelected.isValid()) {
535 selected.append(incidenceSelected);
536 }
537 }
538 }
539 return selected;
540}
541
542KHolidays::Holiday::List MonthView::holidays(QDate startDate, QDate endDate)
543{
545 auto const regions = CalendarSupport::KCalPrefs::instance()->mHolidays;
546 for (auto const &r : regions) {
547 KHolidays::HolidayRegion region(r);
548 if (region.isValid()) {
549 holidays += region.rawHolidaysWithAstroSeasons(startDate, endDate);
550 }
551 }
552 return holidays;
553}
554
555void MonthView::reloadIncidences()
556{
557 if (changes() == NothingChanged) {
558 return;
559 }
560 // keep selection if it exists
561 Akonadi::Item incidenceSelected;
562
563 MonthItem *itemToReselect = nullptr;
564
565 if (auto tmp = qobject_cast<IncidenceMonthItem *>(d->scene->selectedItem())) {
566 d->selectedItemId = tmp->akonadiItem().id();
567 d->selectedItemDate = tmp->realStartDate();
568 if (!d->selectedItemDate.isValid()) {
569 return;
570 }
571 }
572
573 d->scene->resetAll();
574 d->mBusyDays.clear();
575 // build monthcells hash
576 int i = 0;
577 for (QDate date = actualStartDateTime().date(); date <= actualEndDateTime().date(); date = date.addDays(1)) {
578 d->scene->mMonthCellMap[date] = new MonthCell(i, date, d->scene);
579 i++;
580 }
581
582 // build global event list
583 for (const auto &calendar : calendars()) {
584 auto *newItemToReselect = d->loadCalendarIncidences(calendar, actualStartDateTime(), actualEndDateTime());
585 if (itemToReselect == nullptr) {
586 itemToReselect = newItemToReselect;
587 }
588 }
589
590 if (itemToReselect) {
591 d->scene->selectItem(itemToReselect);
592 }
593
594 // add holidays
595 for (auto const &h : holidays(actualStartDateTime().date(), actualEndDateTime().date())) {
596 if (h.dayType() == KHolidays::Holiday::NonWorkday) {
597 MonthItem *holidayItem = new HolidayMonthItem(d->scene, h.observedStartDate(), h.observedEndDate(), h.name());
598 d->scene->mManagerList << holidayItem;
599 }
600 }
601
602 // sort it
603 std::sort(d->scene->mManagerList.begin(), d->scene->mManagerList.end(), MonthItem::greaterThan);
604
605 // build each month's cell event list
606 for (MonthItem *manager : std::as_const(d->scene->mManagerList)) {
607 for (QDate date = manager->startDate(); date <= manager->endDate(); date = date.addDays(1)) {
608 MonthCell *cell = d->scene->mMonthCellMap.value(date);
609 if (cell) {
610 cell->mMonthItemList << manager;
611 }
612 }
613 }
614
615 for (MonthItem *manager : std::as_const(d->scene->mManagerList)) {
616 manager->updateMonthGraphicsItems();
617 manager->updatePosition();
618 }
619
620 for (MonthItem *manager : std::as_const(d->scene->mManagerList)) {
621 manager->updateGeometry();
622 }
623
624 d->scene->setInitialized(true);
625 d->view->update();
626 d->scene->update();
627}
628
630{
631 qCDebug(CALENDARVIEW_LOG);
632 d->triggerDelayedReload(ResourcesChanged);
633}
634
636{
637 return actualStartDateTime().date().addDays(actualStartDateTime().date().daysTo(actualEndDateTime().date()) / 2);
638}
639
640int MonthView::currentMonth() const
641{
642 return averageDate().month();
643}
644
645bool MonthView::usesFullWindow()
646{
647 return preferences()->fullViewMonth();
648}
649
650bool MonthView::isBusyDay(QDate day) const
651{
652 return !d->mBusyDays[day].isEmpty();
653}
654
655#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
bool isValid(QStringView ifopt)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
const QList< QKeySequence > & end()
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)
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)
virtual bool event(QEvent *event) override
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 25 2025 11:46:21 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.