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
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)
190 : EventView(parent)
191 , d(new MonthViewPrivate(this))
192{
193 auto topLayout = new QHBoxLayout(this);
194 topLayout->addWidget(d->view);
195 topLayout->setContentsMargins(0, 0, 0, 0);
196
197 if (visibility == Visible) {
198 auto rightLayout = new QVBoxLayout();
199 rightLayout->setSpacing(0);
200 rightLayout->setContentsMargins(0, 0, 0, 0);
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, &MonthScene::newEventSignal, this, qOverload<>(&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
346bool MonthView::eventDurationHint(QDateTime &startDt, QDateTime &endDt, bool &allDay) const
347{
348 if (d->scene->selectedCell()) {
349 startDt.setDate(d->scene->selectedCell()->date());
350 endDt.setDate(d->scene->selectedCell()->date());
351 allDay = true;
352 return true;
353 }
354
355 return false;
356}
357
358void MonthView::showIncidences(const Akonadi::Item::List &incidenceList, const QDate &date)
359{
360 Q_UNUSED(incidenceList)
361 Q_UNUSED(date)
362}
363
364void MonthView::changeIncidenceDisplay(const Akonadi::Item &incidence, int action)
365{
366 Q_UNUSED(incidence)
367 Q_UNUSED(action)
368
369 // TODO: add some more intelligence here...
370
371 // don't call reloadIncidences() directly. It would delete all
372 // MonthItems, but this changeIncidenceDisplay()-method was probably
373 // called by one of the MonthItem objects. So only schedule a reload
374 // as event
375 setChanges(changes() | IncidencesEdited);
376 d->reloadTimer.start(50);
377}
378
379void MonthView::updateView()
380{
381 d->view->update();
382}
383
384#ifndef QT_NO_WHEELEVENT
385void MonthView::wheelEvent(QWheelEvent *event)
386{
387 // invert direction to get scroll-like behaviour
388 if (event->angleDelta().y() > 0) {
389 d->moveStartDate(-1, 0);
390 } else if (event->angleDelta().y() < 0) {
391 d->moveStartDate(1, 0);
392 }
393
394 // call accept in every case, we do not want anybody else to react
395 event->accept();
396}
397
398#endif
399
400void MonthView::keyPressEvent(QKeyEvent *event)
401{
402 if (event->key() == Qt::Key_PageUp) {
403 d->moveStartDate(0, -1);
404 event->accept();
405 } else if (event->key() == Qt::Key_PageDown) {
406 d->moveStartDate(0, 1);
407 event->accept();
408 } else if (processKeyEvent(event)) {
409 event->accept();
410 } else {
411 event->ignore();
412 }
413}
414
415void MonthView::keyReleaseEvent(QKeyEvent *event)
416{
417 if (processKeyEvent(event)) {
418 event->accept();
419 } else {
420 event->ignore();
421 }
422}
423
424void MonthView::changeFullView()
425{
426 bool fullView = d->fullView->isChecked();
427
428 if (fullView) {
429 d->fullView->setIcon(QIcon::fromTheme(QStringLiteral("view-restore")));
430 d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a normal size"));
431 } else {
432 d->fullView->setIcon(QIcon::fromTheme(QStringLiteral("view-fullscreen")));
433 d->fullView->setToolTip(i18nc("@info:tooltip", "Display calendar in a full window"));
434 }
435 preferences()->setFullViewMonth(fullView);
436 preferences()->writeConfig();
437
438 Q_EMIT fullViewChanged(fullView);
439}
440
442{
443 d->moveStartDate(0, -1);
444}
445
447{
448 d->moveStartDate(-1, 0);
449}
450
452{
453 d->moveStartDate(1, 0);
454}
455
457{
458 d->moveStartDate(0, 1);
459}
460
461void MonthView::showDates(const QDate &start, const QDate &end, const QDate &preferedMonth)
462{
463 Q_UNUSED(start)
464 Q_UNUSED(end)
465 Q_UNUSED(preferedMonth)
466 d->triggerDelayedReload(DatesChanged);
467}
468
469QPair<QDateTime, QDateTime> MonthView::actualDateRange(const QDateTime &start, const QDateTime &, const QDate &preferredMonth) const
470{
471 QDateTime dayOne = preferredMonth.isValid() ? QDateTime(preferredMonth.startOfDay()) : start;
472
473 dayOne.setDate(QDate(dayOne.date().year(), dayOne.date().month(), 1));
474 const int weekdayCol = (dayOne.date().dayOfWeek() + 7 - preferences()->firstDayOfWeek()) % 7;
475 QDateTime actualStart = dayOne.addDays(-weekdayCol);
476 actualStart.setTime(QTime(0, 0, 0, 0));
477 QDateTime actualEnd = actualStart.addDays(6 * 7 - 1);
478 actualEnd.setTime(QTime(23, 59, 59, 99));
479 return qMakePair(actualStart, actualEnd);
480}
481
483{
484 Akonadi::Item::List selected;
485 if (d->scene->selectedItem()) {
486 auto tmp = qobject_cast<IncidenceMonthItem *>(d->scene->selectedItem());
487 if (tmp) {
488 Akonadi::Item incidenceSelected = tmp->akonadiItem();
489 if (incidenceSelected.isValid()) {
490 selected.append(incidenceSelected);
491 }
492 }
493 }
494 return selected;
495}
496
497KHolidays::Holiday::List MonthView::holidays(QDate startDate, QDate endDate)
498{
500 auto const regions = CalendarSupport::KCalPrefs::instance()->mHolidays;
501 for (auto const &r : regions) {
502 KHolidays::HolidayRegion region(r);
503 if (region.isValid()) {
504 holidays += region.rawHolidaysWithAstroSeasons(startDate, endDate);
505 }
506 }
507 return holidays;
508}
509
510void MonthView::reloadIncidences()
511{
512 if (changes() == NothingChanged) {
513 return;
514 }
515 // keep selection if it exists
516 Akonadi::Item incidenceSelected;
517
518 MonthItem *itemToReselect = nullptr;
519
520 if (auto tmp = qobject_cast<IncidenceMonthItem *>(d->scene->selectedItem())) {
521 d->selectedItemId = tmp->akonadiItem().id();
522 d->selectedItemDate = tmp->realStartDate();
523 if (!d->selectedItemDate.isValid()) {
524 return;
525 }
526 }
527
528 d->scene->resetAll();
529 d->mBusyDays.clear();
530 // build monthcells hash
531 int i = 0;
532 for (QDate date = actualStartDateTime().date(); date <= actualEndDateTime().date(); date = date.addDays(1)) {
533 d->scene->mMonthCellMap[date] = new MonthCell(i, date, d->scene);
534 i++;
535 }
536
537 // build global event list
538 for (const auto &calendar : calendars()) {
539 auto *newItemToReselect = d->loadCalendarIncidences(calendar, actualStartDateTime(), actualEndDateTime());
540 if (itemToReselect == nullptr) {
541 itemToReselect = newItemToReselect;
542 }
543 }
544
545 if (itemToReselect) {
546 d->scene->selectItem(itemToReselect);
547 }
548
549 // add holidays
550 for (auto const &h : holidays(actualStartDateTime().date(), actualEndDateTime().date())) {
551 if (h.dayType() == KHolidays::Holiday::NonWorkday) {
552 MonthItem *holidayItem = new HolidayMonthItem(d->scene, h.observedStartDate(), h.observedEndDate(), h.name());
553 d->scene->mManagerList << holidayItem;
554 }
555 }
556
557 // sort it
558 std::sort(d->scene->mManagerList.begin(), d->scene->mManagerList.end(), MonthItem::greaterThan);
559
560 // build each month's cell event list
561 for (MonthItem *manager : std::as_const(d->scene->mManagerList)) {
562 for (QDate date = manager->startDate(); date <= manager->endDate(); date = date.addDays(1)) {
563 MonthCell *cell = d->scene->mMonthCellMap.value(date);
564 if (cell) {
565 cell->mMonthItemList << manager;
566 }
567 }
568 }
569
570 for (MonthItem *manager : std::as_const(d->scene->mManagerList)) {
571 manager->updateMonthGraphicsItems();
572 manager->updatePosition();
573 }
574
575 for (MonthItem *manager : std::as_const(d->scene->mManagerList)) {
576 manager->updateGeometry();
577 }
578
579 d->scene->setInitialized(true);
580 d->view->update();
581 d->scene->update();
582}
583
585{
586 qCDebug(CALENDARVIEW_LOG);
587 d->triggerDelayedReload(ResourcesChanged);
588}
589
591{
592 return actualStartDateTime().date().addDays(actualStartDateTime().date().daysTo(actualEndDateTime().date()) / 2);
593}
594
595int MonthView::currentMonth() const
596{
597 return averageDate().month();
598}
599
600bool MonthView::usesFullWindow()
601{
602 return preferences()->fullViewMonth();
603}
604
605bool MonthView::isBusyDay(QDate day) const
606{
607 return !d->mBusyDays[day].isEmpty();
608}
609
610#include "moc_monthview.cpp"
Id id() const
bool isValid() const
bool hasPayload() const
EventView is the abstract base class from which all other calendar views for event data are derived.
Definition eventview.h:67
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.
void datesSelected(const KCalendarCore::DateList &datelist)
when the view changes the dates that are selected in one way or another, this signal is emitted.
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())
Keeps information about a month cell.
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:309
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.
QDate endDate() const
The end date of the incidence, generally realEndDate.
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)
void unregisterObserver(CalendarObserver *observer)
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
KIOCORE_EXPORT QStringList list(const QString &fileClass)
const QList< QKeySequence > & end()
void clicked(bool checked)
QDate addDays(qint64 ndays) const const
int dayOfWeek() 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
QDate date() const const
void setDate(QDate date)
void setTime(QTime time)
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)
Key_PageUp
bool isActive() const const
void start()
void timeout()
virtual bool event(QEvent *event) override
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:12:29 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.