Eventviews

listview.cpp
1/*
2 SPDX-FileCopyrightText: 1999 Preston Brown <pbrown@kde.org>
3 SPDX-FileCopyrightText: 2000, 2001 Cornelius Schumacher <schumacher@kde.org>
4 SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
5 SPDX-FileCopyrightText: 2010 Sérgio Martins <iamsergio@gmail.com>
6 SPDX-FileCopyrightText: 2012-2013 Allen Winter <winter@kde.org>
7
8 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
9*/
10
11// TODO: put a reminder and/or recurs icon on the item?
12
13#include "listview.h"
14#include "helper.h"
15
16#include <CalendarSupport/Utils>
17
18#include <Akonadi/CalendarUtils>
19#include <Akonadi/IncidenceChanger>
20
21#include <KCalUtils/IncidenceFormatter>
22#include <KCalendarCore/Visitor>
23
24#include <KConfig>
25#include <KConfigGroup>
26
27#include "calendarview_debug.h"
28#include <QBoxLayout>
29#include <QHeaderView>
30#include <QIcon>
31#include <QLocale>
32#include <QTreeWidget>
33
34using namespace EventViews;
35using namespace KCalendarCore;
36using namespace KCalUtils;
37
38enum {
39 Summary_Column = 0,
40 StartDateTime_Column,
41 EndDateTime_Column,
42 Categories_Column,
43 Dummy_EOF_Column // Dummy enum value for iteration purposes only. Always keep at the end.
44};
45
46static const QTime DAY_START{00, 00};
47static const QTime DAY_END{23, 59, 59, 999};
48
49static QString cleanSummary(const QString &summary, const QDateTime &next)
50{
51 QString retStr = summary;
52 retStr.replace(QLatin1Char('\n'), QLatin1Char(' '));
53
54 if (next.isValid()) {
55 const QString dateStr = QLocale().toString(next.date(), QLocale::ShortFormat);
56 retStr = i18nc("%1 is an item summary. %2 is the date when this item reoccurs", "%1 (next: %2)", retStr, dateStr);
57 }
58 return retStr;
59}
60
61class ListViewItem : public QTreeWidgetItem
62{
63public:
64 ListViewItem(const Akonadi::Item &incidence, const Akonadi::CollectionCalendar::Ptr &calendar, QTreeWidget *parent)
66 , mTreeWidget(parent)
67 , mIncidence(incidence)
68 , mCalendar(calendar)
69 {
70 }
71
72 QVariant data(int column, int role) const override
73 {
74 if (role == Qt::ToolTipRole) {
75 const auto incidence = mIncidence.payload<KCalendarCore::Incidence::Ptr>();
77 incidence,
78 start.date());
79 }
80
81 return QTreeWidgetItem::data(column, role);
82 }
83
84 bool operator<(const QTreeWidgetItem &other) const override;
85
86 QTreeWidget *const mTreeWidget;
87 const Akonadi::Item mIncidence;
88 QDateTime start;
89 QDateTime end;
91};
92
93bool ListViewItem::operator<(const QTreeWidgetItem &other) const
94{
95 const auto otheritem = static_cast<const ListViewItem *>(&other);
96
97 switch (treeWidget()->sortColumn()) {
98 case StartDateTime_Column:
99 // Missing start times are sorted before any defined time.
100 return otheritem->start.isValid() && (!start.isValid() || start < otheritem->start);
101 case EndDateTime_Column:
102 // Missing end times are sorted after any defined time.
103 return end.isValid() && (!otheritem->end.isValid() || end < otheritem->end);
104 default:
105 return QTreeWidgetItem::operator<(other);
106 }
107}
108
109class EventViews::ListViewPrivate
110{
111public:
112 ListViewPrivate() = default;
113
114 ~ListViewPrivate() = default;
115
116 void addIncidences(const Akonadi::CollectionCalendar::Ptr &calendar, const KCalendarCore::Incidence::List &incidenceList, QDate date);
117 void addIncidence(const Akonadi::CollectionCalendar::Ptr &calendar, const KCalendarCore::Incidence::Ptr &, QDate date);
118 void addIncidence(const Akonadi::CollectionCalendar::Ptr &calendar, const Akonadi::Item &, QDate date);
119 ListViewItem *getItemForIncidence(const Akonadi::Item &);
120
121 QTreeWidget *mTreeWidget = nullptr;
122 ListViewItem *mActiveItem = nullptr;
125 QDate mStartDate;
126 QDate mEndDate;
127 DateList mSelectedDates;
128 int mSortColumn = StartDateTime_Column;
130
131 // if it's non interactive we disable context menu, and incidence editing
132 bool mIsNonInteractive;
133 class ListItemVisitor;
134};
135
136/**
137 This class provides the initialization of a ListViewItem for calendar
138 components using the Incidence::Visitor.
139*/
140class ListViewPrivate::ListItemVisitor : public KCalendarCore::Visitor
141{
142public:
143 ListItemVisitor(ListViewItem *item, QDate dt)
144 : mItem(item)
145 , mStartDate(dt)
146 {
147 }
148
149 ~ListItemVisitor() override = default;
150
151 bool visit(const Event::Ptr &) override;
152 bool visit(const Todo::Ptr &) override;
153 bool visit(const Journal::Ptr &) override;
154 bool visit(const FreeBusy::Ptr &) override
155 {
156 // to inhibit hidden virtual compile warning
157 return true;
158 }
159
160private:
161 ListViewItem *mItem = nullptr;
162 QDate mStartDate;
163};
164
165bool ListViewPrivate::ListItemVisitor::visit(const Event::Ptr &e)
166{
167 QIcon eventPxmp;
168 if (e->customProperty("KABC", "ANNIVERSARY") == QLatin1StringView("YES")) {
169 eventPxmp = QIcon::fromTheme(QStringLiteral("view-calendar-wedding-anniversary"));
170 } else if (e->customProperty("KABC", "BIRTHDAY") == QLatin1StringView("YES")) {
171 eventPxmp = QIcon::fromTheme(QStringLiteral("view-calendar-birthday"));
172 } else {
173 eventPxmp = QIcon::fromTheme(e->iconName());
174 }
175 mItem->setIcon(Summary_Column, eventPxmp);
176
178 if (e->recurs()) {
179 const qint64 duration = e->dtStart().secsTo(e->dtEnd());
180 QDateTime kdt(mStartDate, DAY_START);
181 kdt = kdt.addMSecs(-1);
182 mItem->start = e->recurrence()->getNextDateTime(kdt).toLocalTime();
183 mItem->end = mItem->start.addSecs(duration);
184 next = e->recurrence()->getNextDateTime(mItem->start).toLocalTime();
185 } else {
186 mItem->start = e->dtStart().toLocalTime();
187 mItem->end = e->dtEnd().toLocalTime();
188 }
189
190 mItem->setText(Summary_Column, cleanSummary(e->summary(), next));
191
192 if (e->allDay()) {
193 mItem->start.setTime(DAY_START);
194 mItem->end.setTime(DAY_END);
195 mItem->setText(StartDateTime_Column, QLocale().toString(mItem->start.date(), QLocale::ShortFormat));
196 mItem->setText(EndDateTime_Column, QLocale().toString(mItem->end.date(), QLocale::ShortFormat));
197 } else {
198 mItem->setText(StartDateTime_Column, QLocale().toString(mItem->start, QLocale::ShortFormat));
199 mItem->setText(EndDateTime_Column, QLocale().toString(mItem->end, QLocale::ShortFormat));
200 }
201
202 mItem->setText(Categories_Column, e->categoriesStr());
203
204 return true;
205}
206
207bool ListViewPrivate::ListItemVisitor::visit(const Todo::Ptr &t)
208{
209 mItem->setIcon(Summary_Column, QIcon::fromTheme(t->iconName()));
210
211 if (t->recurs()) {
212 QDateTime kdt(mStartDate, DAY_START);
213 kdt = kdt.addMSecs(-1);
214 mItem->start = t->recurrence()->getNextDateTime(kdt).toLocalTime();
215 if (t->hasDueDate()) {
216 const qint64 duration = t->dtStart().secsTo(t->dtDue());
217 mItem->end = mItem->start.addSecs(duration);
218 } else {
219 mItem->end = QDateTime();
220 }
221 } else {
222 mItem->start = t->hasStartDate() ? t->dtStart().toLocalTime() : QDateTime();
223 mItem->end = t->hasDueDate() ? t->dtDue().toLocalTime() : QDateTime();
224 }
225 if (t->allDay()) {
226 mItem->start.setTime(DAY_START);
227 mItem->end.setTime(DAY_END);
228 }
229
230 mItem->setText(Summary_Column, cleanSummary(t->summary(), QDateTime()));
231
232 if (t->hasStartDate()) {
233 if (t->allDay()) {
234 mItem->setText(StartDateTime_Column, QLocale().toString(t->dtStart().toLocalTime().date(), QLocale::ShortFormat));
235 } else {
236 mItem->setText(StartDateTime_Column, QLocale().toString(t->dtStart().toLocalTime(), QLocale::ShortFormat));
237 }
238 } else {
239 mItem->setText(StartDateTime_Column, QStringLiteral("---"));
240 }
241
242 if (t->hasDueDate()) {
243 if (t->allDay()) {
244 mItem->setText(EndDateTime_Column, QLocale().toString(t->dtDue().toLocalTime().date(), QLocale::ShortFormat));
245 } else {
246 mItem->setText(EndDateTime_Column, QLocale().toString(t->dtDue().toLocalTime(), QLocale::ShortFormat));
247 }
248 } else {
249 mItem->setText(EndDateTime_Column, QStringLiteral("---"));
250 }
251 mItem->setText(Categories_Column, t->categoriesStr());
252
253 return true;
254}
255
256bool ListViewPrivate::ListItemVisitor::visit(const Journal::Ptr &j)
257{
258 mItem->setIcon(Summary_Column, QIcon::fromTheme(j->iconName()));
259
260 mItem->start = j->dtStart();
261 mItem->end = QDateTime();
262
263 if (j->summary().isEmpty()) {
264 mItem->setText(Summary_Column, cleanSummary(j->description().section(QLatin1Char('\n'), 0, 0), QDateTime()));
265 } else {
266 mItem->setText(Summary_Column, cleanSummary(j->summary(), QDateTime()));
267 }
268 if (j->allDay()) {
269 mItem->start.setTime(DAY_START);
270 mItem->setText(StartDateTime_Column, QLocale().toString(j->dtStart().toLocalTime().date(), QLocale::ShortFormat));
271 } else {
272 mItem->setText(StartDateTime_Column, QLocale().toString(j->dtStart().toLocalTime(), QLocale::ShortFormat));
273 }
274 mItem->setText(EndDateTime_Column, QStringLiteral("---"));
275 mItem->setText(Categories_Column, j->categoriesStr());
276
277 return true;
278}
279
280ListView::ListView(QWidget *parent, bool nonInteractive)
281 : EventView(parent)
282 , d(std::make_unique<ListViewPrivate>())
283{
284 d->mActiveItem = nullptr;
285 d->mIsNonInteractive = nonInteractive;
286
287 d->mTreeWidget = new QTreeWidget(this);
288 d->mTreeWidget->setColumnCount(4);
289 d->mTreeWidget->setSortingEnabled(true);
290 d->mTreeWidget->headerItem()->setText(Summary_Column, i18n("Summary"));
291 d->mTreeWidget->headerItem()->setText(StartDateTime_Column, i18n("Start Date/Time"));
292 d->mTreeWidget->headerItem()->setText(EndDateTime_Column, i18n("End Date/Time"));
293 d->mTreeWidget->headerItem()->setText(Categories_Column, i18n("Tags"));
294
295 d->mTreeWidget->setWordWrap(true);
296 d->mTreeWidget->setAllColumnsShowFocus(true);
297 d->mTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
298 d->mTreeWidget->setRootIsDecorated(false);
299
300 QBoxLayout *layoutTop = new QVBoxLayout(this);
301 layoutTop->setContentsMargins(0, 0, 0, 0);
302 layoutTop->addWidget(d->mTreeWidget);
303
304 QObject::connect(d->mTreeWidget,
305 qOverload<const QModelIndex &>(&QTreeWidget::doubleClicked),
306 this,
307 qOverload<const QModelIndex &>(&ListView::defaultItemAction));
308 QObject::connect(d->mTreeWidget, &QTreeWidget::customContextMenuRequested, this, &ListView::popupMenu);
309 QObject::connect(d->mTreeWidget, &QTreeWidget::itemSelectionChanged, this, &ListView::processSelectionChange);
310 QObject::connect(d->mTreeWidget->header(), &QHeaderView::sortIndicatorChanged, this, &ListView::slotSortIndicatorChanged);
311
312 d->mSelectedDates.append(QDate::currentDate());
313
314 updateView();
315}
316
317ListView::~ListView() = default;
318
320{
321 return d->mSelectedDates.count();
322}
323
325{
326 Akonadi::Item::List eventList;
327 QTreeWidgetItem *item = d->mTreeWidget->selectedItems().isEmpty() ? nullptr : d->mTreeWidget->selectedItems().first();
328 if (item) {
329 auto i = static_cast<ListViewItem *>(item);
330 eventList.append(i->mIncidence);
331 }
332 return eventList;
333}
334
336{
337 return d->mSelectedDates;
338}
339
340void ListView::updateView()
341{
342 static int maxLen = 38;
343
344 /* Set the width of the summary column to show 'maxlen' chars, at most */
345 int width = qMin(maxLen * fontMetrics().averageCharWidth(), maxLen * 12);
346 width += 24; // for the icon
347
348 d->mTreeWidget->setColumnWidth(Summary_Column, width);
349 for (int col = StartDateTime_Column; col < Dummy_EOF_Column; ++col) {
350 d->mTreeWidget->resizeColumnToContents(col);
351 }
352 d->mTreeWidget->sortItems(d->mSortColumn, d->mSortOrder);
353}
354
355void ListView::showDates(const QDate &start, const QDate &end, const QDate &preferredMonth)
356{
357 Q_UNUSED(preferredMonth)
358 clear();
359
360 d->mStartDate = start;
361 d->mEndDate = end;
362
364 const QString endStr = QLocale().toString(end, QLocale::ShortFormat);
365
366 d->mTreeWidget->headerItem()->setText(Summary_Column, i18n("Summary [%1 - %2]", startStr, endStr));
367
368 QDate date = start;
369 while (date <= end) {
370 for (const auto &calendar : calendars()) {
371 d->addIncidences(calendar, calendar->incidences(date), date);
372 }
373 d->mSelectedDates.append(date);
374 date = date.addDays(1);
375 }
376
377 updateView();
378
379 Q_EMIT incidenceSelected(Akonadi::Item(), QDate());
380}
381
382void ListView::showAll()
383{
384 for (const auto &calendar : calendars()) {
385 d->addIncidences(calendar, calendar->incidences(), QDate());
386 }
387}
388
389void ListViewPrivate::addIncidences(const Akonadi::CollectionCalendar::Ptr &calendar, const KCalendarCore::Incidence::List &incidences, QDate date)
390{
391 for (const KCalendarCore::Incidence::Ptr &incidence : incidences) {
392 addIncidence(calendar, incidence, date);
393 }
394}
395
396void ListViewPrivate::addIncidence(const Akonadi::CollectionCalendar::Ptr &calendar, const Akonadi::Item &item, QDate date)
397{
398 Q_ASSERT(calendar);
399 if (item.isValid() && item.hasPayload<KCalendarCore::Incidence::Ptr>()) {
400 addIncidence(calendar, item.payload<KCalendarCore::Incidence::Ptr>(), date);
401 }
402}
403
404void ListViewPrivate::addIncidence(const Akonadi::CollectionCalendar::Ptr &calendar, const KCalendarCore::Incidence::Ptr &incidence, QDate date)
405{
406 if (!incidence) {
407 return;
408 }
409
410 Akonadi::Item aitem = calendar->item(incidence);
411
412 if (!aitem.isValid() || mItems.contains(aitem.id())) {
413 return;
414 }
415
416 mDateList.insert(aitem.id(), date);
417 mItems.insert(aitem.id(), aitem);
419
420 if (tinc->customProperty("KABC", "BIRTHDAY") == QLatin1StringView("YES") || tinc->customProperty("KABC", "ANNIVERSARY") == QLatin1StringView("YES")) {
421 const int years = EventViews::yearDiff(tinc->dtStart().date(), mEndDate);
422 if (years > 0) {
423 tinc = Incidence::Ptr(incidence->clone());
424 tinc->setReadOnly(false);
425 tinc->setSummary(i18np("%2 (1 year)", "%2 (%1 years)", years, cleanSummary(incidence->summary(), QDateTime())));
426 tinc->setReadOnly(true);
427 }
428 }
429 auto item = new ListViewItem(aitem, calendar, mTreeWidget);
430
431 ListItemVisitor v(item, mStartDate);
432 if (!tinc->accept(v, tinc)) {
433 delete item;
434 return;
435 }
436
437 item->setData(0, Qt::UserRole, QVariant(aitem.id()));
438}
439
440void ListView::showIncidences(const Akonadi::Item::List &itemList, const QDate &date)
441{
442 clear();
443 for (const auto &item : itemList) {
444 const auto calendar = calendar3(item);
445 if (calendar) {
446 d->addIncidence(calendar, Akonadi::CalendarUtils::incidence(item), date);
447 }
448 }
449 updateView();
450
451 // After new creation of list view no events are selected.
452 Q_EMIT incidenceSelected(Akonadi::Item(), date);
453}
454
455void ListView::changeIncidenceDisplay(const Akonadi::Item &aitem, int action)
456{
458 const auto calendar = calendar3(aitem);
459
460 ListViewItem *item = nullptr;
461 const QDate f = d->mSelectedDates.constFirst();
462 const QDate l = d->mSelectedDates.constLast();
463
464 QDate date;
465 if (CalendarSupport::hasTodo(aitem)) {
466 date = Akonadi::CalendarUtils::todo(aitem)->dtDue().toLocalTime().date();
467 } else {
468 date = incidence->dtStart().toLocalTime().date();
469 }
470
471 switch (action) {
472 case Akonadi::IncidenceChanger::ChangeTypeCreate:
473 if (date >= f && date <= l) {
474 d->addIncidence(calendar, aitem, date);
475 }
476 break;
477 case Akonadi::IncidenceChanger::ChangeTypeModify:
478 item = d->getItemForIncidence(aitem);
479 if (item) {
480 delete item;
481 d->mItems.remove(aitem.id());
482 d->mDateList.remove(aitem.id());
483 }
484 if (date >= f && date <= l) {
485 d->addIncidence(calendar, aitem, date);
486 }
487 break;
488 case Akonadi::IncidenceChanger::ChangeTypeDelete:
489 item = d->getItemForIncidence(aitem);
490 delete item;
491 break;
492 default:
493 qCDebug(CALENDARVIEW_LOG) << "Illegal action" << action;
494 }
495}
496
497ListViewItem *ListViewPrivate::getItemForIncidence(const Akonadi::Item &aitem)
498{
499 int index = 0;
500 while (QTreeWidgetItem *it = mTreeWidget->topLevelItem(index)) {
501 auto item = static_cast<ListViewItem *>(it);
502 if (item->mIncidence.id() == aitem.id()) {
503 return item;
504 }
505 ++index;
506 }
507
508 return nullptr;
509}
510
511void ListView::slotSortIndicatorChanged(int logicalIndex, Qt::SortOrder order)
512{
513 d->mSortColumn = logicalIndex;
514 d->mSortOrder = order;
515}
516
517void ListView::defaultItemAction(const QModelIndex &index)
518{
519 if (!d->mIsNonInteractive) {
520 // Get the first column, it has our Akonadi::Id
521 const QModelIndex col0Idx = d->mTreeWidget->model()->index(index.row(), 0);
522 Akonadi::Item::Id id = d->mTreeWidget->model()->data(col0Idx, Qt::UserRole).toLongLong();
523 defaultAction(d->mItems.value(id));
524 }
525}
526
527void ListView::defaultItemAction(const Akonadi::Item::Id id)
528{
529 if (!d->mIsNonInteractive) {
530 defaultAction(d->mItems.value(id));
531 }
532}
533
534void ListView::popupMenu(const QPoint &point)
535{
536 d->mActiveItem = static_cast<ListViewItem *>(d->mTreeWidget->itemAt(point));
537
538 if (d->mActiveItem && !d->mIsNonInteractive) {
539 const Akonadi::Item aitem = d->mActiveItem->mIncidence;
540 const auto calendar = calendar3(aitem);
541 // FIXME: For recurring incidences we don't know the date of this
542 // occurrence, there's no reference to it at all!
543
544 Q_EMIT showIncidencePopupSignal(calendar, aitem, Akonadi::CalendarUtils::incidence(aitem)->dtStart().date());
545 } else {
546 Q_EMIT showNewEventPopupSignal();
547 }
548}
549
551{
552 KConfigGroup cfgGroup = config->group(QStringLiteral("ListView Layout"));
553 readSettings(cfgGroup);
554}
555
557{
558 const QByteArray state = cfgGroup.readEntry("ViewState", QByteArray());
559 d->mTreeWidget->header()->restoreState(state);
560 d->mSortColumn = cfgGroup.readEntry("SortColumn", static_cast<int>(StartDateTime_Column));
561 d->mSortOrder = static_cast<Qt::SortOrder>(cfgGroup.readEntry("SortOrder", static_cast<int>(Qt::AscendingOrder)));
562}
563
565{
566 KConfigGroup cfgGroup = config->group(QStringLiteral("ListView Layout"));
567}
568
570{
571 const QByteArray state = d->mTreeWidget->header()->saveState();
572 cfgGroup.writeEntry("ViewState", state);
573 cfgGroup.writeEntry("SortColumn", d->mSortColumn);
574 cfgGroup.writeEntry("SortOrder", static_cast<int>(d->mSortOrder));
575}
576
577void ListView::processSelectionChange()
578{
579 if (!d->mIsNonInteractive) {
580 ListViewItem *item;
581 if (d->mTreeWidget->selectedItems().isEmpty()) {
582 item = nullptr;
583 } else {
584 item = static_cast<ListViewItem *>(d->mTreeWidget->selectedItems().first());
585 }
586
587 if (!item) {
588 Q_EMIT incidenceSelected(Akonadi::Item(), QDate());
589 } else {
590 Q_EMIT incidenceSelected(item->mIncidence, d->mDateList.value(item->mIncidence.id()));
591 }
592 }
593}
594
595void ListView::clearSelection()
596{
597 d->mTreeWidget->clearSelection();
598}
599
600void ListView::clear()
601{
602 d->mSelectedDates.clear();
603 d->mTreeWidget->clear();
604 d->mDateList.clear();
605 d->mItems.clear();
606}
607
608QSize ListView::sizeHint() const
609{
610 const QSize s = EventView::sizeHint();
611 return {s.width() + style()->pixelMetric(QStyle::PM_ScrollBarExtent) + 1, s.height()};
612}
613
614#include "moc_listview.cpp"
T payload() const
Collection & parentCollection()
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
void defaultAction(const Akonadi::Item &incidence)
Perform the default action for an incidence, e.g.
Definition eventview.cpp:72
void writeSettings(KConfig *config)
Write settings to the "ListView Layout" group of the configuration.
Definition listview.cpp:564
Akonadi::Item::List selectedIncidences() const override
Definition listview.cpp:324
int currentDateCount() const override
Returns the number of currently shown dates.
Definition listview.cpp:319
void readSettings(KConfig *config)
Read settings from the "ListView Layout" group of the configuration.
Definition listview.cpp:550
KCalendarCore::DateList selectedIncidenceDates() const override
Returns a list of the dates of selected events.
Definition listview.cpp:335
QSharedPointer< Incidence > Ptr
KConfigGroup group(const QString &group)
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
QString readEntry(const char *key, const char *aDefault=nullptr) const
Q_SCRIPTABLE Q_NOREPLY void start()
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
AKONADI_CALENDAR_EXPORT KCalendarCore::Incidence::Ptr incidence(const Akonadi::Item &item)
AKONADI_CALENDAR_EXPORT KCalendarCore::Todo::Ptr todo(const Akonadi::Item &item)
AKONADI_CALENDAR_EXPORT QString displayName(Akonadi::ETMCalendar *calendar, const Akonadi::Collection &collection)
char * toString(const EngineQuery &query)
Namespace EventViews provides facilities for displaying incidences, including events,...
Definition agenda.h:33
int yearDiff(QDate start, QDate end)
Returns the number of years between the start QDate and the end QDate (i.e.
Definition helper.cpp:78
KCALUTILS_EXPORT QString toolTipStr(const QString &sourceName, const KCalendarCore::IncidenceBase::Ptr &incidence, QDate date=QDate(), bool richText=true)
const QList< QKeySequence > & next()
const QList< QKeySequence > & end()
void doubleClicked(const QModelIndex &index)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
QDate addDays(qint64 ndays) const const
QDate currentDate()
QDateTime addSecs(qint64 s) const const
QDate date() const const
bool isValid() const const
void setTime(QTime time)
bool contains(const Key &key) const const
iterator insert(const Key &key, const T &value)
void sortIndicatorChanged(int logicalIndex, Qt::SortOrder order)
QIcon fromTheme(const QString &name)
void setContentsMargins(const QMargins &margins)
void append(QList< T > &&value)
QString toString(QDate date, FormatType format) const const
int row() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
int height() const const
int width() const const
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
PM_ScrollBarExtent
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const const=0
CustomContextMenu
ToolTipRole
SortOrder
void itemSelectionChanged()
int sortColumn() const const
QTreeWidgetItem * topLevelItem(int index) const const
virtual QVariant data(int column, int role) const const
virtual bool operator<(const QTreeWidgetItem &other) const const
QTreeWidgetItem * parent() const const
void setIcon(int column, const QIcon &icon)
void setText(int column, const QString &text)
QTreeWidget * treeWidget() const const
void customContextMenuRequested(const QPoint &pos)
QFontMetrics fontMetrics() const const
QStyle * style() const const
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.