12#include "prefs_base.h"
14#include <CalendarSupport/KCalPrefs>
15#include <CalendarSupport/Utils>
17#include <Akonadi/TagCache>
19#include <KContacts/VCardDrag>
21#include <KCalUtils/ICalDrag>
22#include <KCalUtils/IncidenceFormatter>
23#include <KCalUtils/VCalDrag>
25#include <KEmailAddress>
27#include <KLocalizedString>
31#include <QDragEnterEvent>
35#include <QPainterPath>
36#include <QPixmapCache>
44QPixmap *AgendaItem::alarmPxmp =
nullptr;
45QPixmap *AgendaItem::recurPxmp =
nullptr;
46QPixmap *AgendaItem::readonlyPxmp =
nullptr;
47QPixmap *AgendaItem::replyPxmp =
nullptr;
48QPixmap *AgendaItem::groupPxmp =
nullptr;
49QPixmap *AgendaItem::groupPxmpTent =
nullptr;
50QPixmap *AgendaItem::organizerPxmp =
nullptr;
51QPixmap *AgendaItem::eventPxmp =
nullptr;
55AgendaItem::AgendaItem(
EventView *eventView,
56 const MultiViewCalendar::Ptr &calendar,
64 , mEventView(eventView)
67 , mOccurrenceDateTime(qd)
68 , mSelected(isSelected)
69 , mSpecialEvent(false)
77 if (mIncidence->customProperty(
"KABC",
"BIRTHDAY") ==
"YES"_L1 || mIncidence->customProperty(
"KABC",
"ANNIVERSARY") ==
"YES"_L1) {
80 mIncidence->setReadOnly(
false);
81 mIncidence->setSummary(
i18np(
"%2 (1 year)",
"%2 (%1 years)", years, mIncidence->summary()));
82 mIncidence->setReadOnly(
true);
87 mLabelText = mIncidence->summary();
90 mIconReadonly =
false;
93 mIconGroupTent =
false;
94 mIconOrganizer =
false;
95 mMultiItemInfo =
nullptr;
96 mStartMoveInfo =
nullptr;
99 mItemCount = itemCount;
107 setMouseTracking(
true);
108 mResourceColor =
QColor();
111 setAcceptDrops(
true);
114AgendaItem::~AgendaItem() =
default;
116void AgendaItem::updateIcons()
121 mIconReadonly = mIncidence->isReadOnly();
122 mIconRecur = mIncidence->recurs() || mIncidence->hasRecurrenceId();
123 mIconAlarm = mIncidence->hasEnabledAlarms();
124 if (mIncidence->attendeeCount() > 1) {
125 if (mEventView->kcalPreferences()->thatIsMe(mIncidence->organizer().email())) {
128 mIconGroupTent =
false;
129 mIconOrganizer =
true;
131 KCalendarCore::Attendee me = mIncidence->attendeeByMails(mEventView->kcalPreferences()->allEmails());
137 mIconGroupTent =
false;
138 mIconOrganizer =
false;
142 mIconGroupTent =
true;
143 mIconOrganizer =
false;
147 mIconGroupTent =
false;
148 mIconOrganizer =
false;
153 mIconGroupTent =
false;
154 mIconOrganizer =
false;
161void AgendaItem::select(
bool selected)
163 if (mSelected != selected) {
164 mSelected = selected;
169bool AgendaItem::dissociateFromMultiItem()
171 if (!isMultiItem()) {
175 AgendaItem::QPtr firstItem = firstMultiItem();
176 if (firstItem ==
this) {
177 firstItem = nextMultiItem();
180 AgendaItem::QPtr lastItem = lastMultiItem();
181 if (lastItem ==
this) {
182 lastItem = prevMultiItem();
185 AgendaItem::QPtr prevItem = prevMultiItem();
186 AgendaItem::QPtr nextItem = nextMultiItem();
189 prevItem->setMultiItem(firstItem, prevItem->prevMultiItem(), nextItem, lastItem);
192 nextItem->setMultiItem(firstItem, prevItem, nextItem->prevMultiItem(), lastItem);
194 delete mMultiItemInfo;
195 mMultiItemInfo =
nullptr;
204 mIncidence = incidence;
205 mLabelText = mIncidence->summary();
213int AgendaItem::cellHeight()
const
215 return mCellYBottom - mCellYTop + 1;
221int AgendaItem::cellWidth()
const
223 return mCellXRight - mCellXLeft + 1;
228 mOccurrenceDateTime = qd;
231QDate AgendaItem::occurrenceDate()
const
236void AgendaItem::setCellXY(
int X,
int YTop,
int YBottom)
240 mCellYBottom = YBottom;
243void AgendaItem::setCellXRight(
int XRight)
245 mCellXRight = XRight;
248void AgendaItem::setCellX(
int XLeft,
int XRight)
251 mCellXRight = XRight;
254void AgendaItem::setCellY(
int YTop,
int YBottom)
257 mCellYBottom = YBottom;
260void AgendaItem::setMultiItem(
const AgendaItem::QPtr &first,
const AgendaItem::QPtr &prev,
const AgendaItem::QPtr &next,
const AgendaItem::QPtr &last)
262 if (!mMultiItemInfo) {
263 mMultiItemInfo =
new MultiItemInfo;
265 mMultiItemInfo->mFirstMultiItem = first;
266 mMultiItemInfo->mPrevMultiItem = prev;
267 mMultiItemInfo->mNextMultiItem =
next;
268 mMultiItemInfo->mLastMultiItem = last;
271bool AgendaItem::isMultiItem()
const
273 return mMultiItemInfo;
276AgendaItem::QPtr AgendaItem::prependMoveItem(
const AgendaItem::QPtr &e)
282 AgendaItem::QPtr first =
nullptr;
283 AgendaItem::QPtr last =
nullptr;
285 first = mMultiItemInfo->mFirstMultiItem;
286 last = mMultiItemInfo->mLastMultiItem;
295 e->setMultiItem(
nullptr,
nullptr, first, last);
296 first->setMultiItem(e, e, first->nextMultiItem(), first->lastMultiItem());
298 AgendaItem::QPtr tmp = first->nextMultiItem();
300 tmp->setMultiItem(e, tmp->prevMultiItem(), tmp->nextMultiItem(), tmp->lastMultiItem());
301 tmp = tmp->nextMultiItem();
304 if (mStartMoveInfo && !e->moveInfo()) {
305 e->mStartMoveInfo =
new MultiItemInfo(*mStartMoveInfo);
308 e->moveInfo()->mPrevMultiItem =
nullptr;
309 e->moveInfo()->mNextMultiItem = first;
312 if (first && first->moveInfo()) {
313 first->moveInfo()->mPrevMultiItem = e;
318AgendaItem::QPtr AgendaItem::appendMoveItem(
const AgendaItem::QPtr &e)
324 AgendaItem::QPtr first =
nullptr;
325 AgendaItem::QPtr last =
nullptr;
327 first = mMultiItemInfo->mFirstMultiItem;
328 last = mMultiItemInfo->mLastMultiItem;
337 e->setMultiItem(first, last,
nullptr,
nullptr);
338 AgendaItem::QPtr tmp = first;
341 tmp->setMultiItem(tmp->firstMultiItem(), tmp->prevMultiItem(), tmp->nextMultiItem(), e);
342 tmp = tmp->nextMultiItem();
344 last->setMultiItem(last->firstMultiItem(), last->prevMultiItem(), e, e);
346 if (mStartMoveInfo && !e->moveInfo()) {
347 e->mStartMoveInfo =
new MultiItemInfo(*mStartMoveInfo);
350 e->moveInfo()->mPrevMultiItem = last;
351 e->moveInfo()->mNextMultiItem =
nullptr;
353 if (last && last->moveInfo()) {
354 last->moveInfo()->mNextMultiItem = e;
359AgendaItem::QPtr AgendaItem::removeMoveItem(
const AgendaItem::QPtr &e)
362 AgendaItem::QPtr first = mMultiItemInfo->mFirstMultiItem;
363 AgendaItem::QPtr
next;
364 AgendaItem::QPtr prev;
365 AgendaItem::QPtr last = mMultiItemInfo->mLastMultiItem;
373 first = first->nextMultiItem();
374 first->setMultiItem(
nullptr,
nullptr, first->nextMultiItem(), first->lastMultiItem());
377 last = last->prevMultiItem();
378 last->setMultiItem(last->firstMultiItem(), last->prevMultiItem(),
nullptr,
nullptr);
381 AgendaItem::QPtr tmp = first;
383 delete mMultiItemInfo;
385 mMultiItemInfo =
nullptr;
388 next = tmp->nextMultiItem();
389 prev = tmp->prevMultiItem();
394 prev = prev->prevMultiItem();
396 tmp->setMultiItem((tmp == first) ?
nullptr : first, (tmp == prev) ?
nullptr : prev, (tmp == next) ?
nullptr : next, (tmp == last) ?
nullptr : last);
397 tmp = tmp->nextMultiItem();
406 AgendaItem::QPtr first =
this;
407 if (isMultiItem() && mMultiItemInfo->mFirstMultiItem) {
408 first = mMultiItemInfo->mFirstMultiItem;
410 first->startMovePrivate();
415 mStartMoveInfo =
new MultiItemInfo;
416 mStartMoveInfo->mStartCellXLeft = mCellXLeft;
417 mStartMoveInfo->mStartCellXRight = mCellXRight;
418 mStartMoveInfo->mStartCellYTop = mCellYTop;
419 mStartMoveInfo->mStartCellYBottom = mCellYBottom;
420 if (mMultiItemInfo) {
421 mStartMoveInfo->mFirstMultiItem = mMultiItemInfo->mFirstMultiItem;
422 mStartMoveInfo->mLastMultiItem = mMultiItemInfo->mLastMultiItem;
423 mStartMoveInfo->mPrevMultiItem = mMultiItemInfo->mPrevMultiItem;
424 mStartMoveInfo->mNextMultiItem = mMultiItemInfo->mNextMultiItem;
426 mStartMoveInfo->mFirstMultiItem =
nullptr;
427 mStartMoveInfo->mLastMultiItem =
nullptr;
428 mStartMoveInfo->mPrevMultiItem =
nullptr;
429 mStartMoveInfo->mNextMultiItem =
nullptr;
431 if (isMultiItem() && mMultiItemInfo->mNextMultiItem) {
432 mMultiItemInfo->mNextMultiItem->startMovePrivate();
438 if (mStartMoveInfo) {
439 if (mStartMoveInfo->mFirstMultiItem) {
440 mStartMoveInfo->mFirstMultiItem->resetMovePrivate();
447void AgendaItem::resetMovePrivate()
449 if (mStartMoveInfo) {
450 mCellXLeft = mStartMoveInfo->mStartCellXLeft;
451 mCellXRight = mStartMoveInfo->mStartCellXRight;
452 mCellYTop = mStartMoveInfo->mStartCellYTop;
453 mCellYBottom = mStartMoveInfo->mStartCellYBottom;
458 if (mMultiItemInfo) {
460 mMultiItemInfo->mFirstMultiItem = mStartMoveInfo->mFirstMultiItem;
461 mMultiItemInfo->mPrevMultiItem = mStartMoveInfo->mPrevMultiItem;
462 mMultiItemInfo->mNextMultiItem = mStartMoveInfo->mNextMultiItem;
463 mMultiItemInfo->mLastMultiItem = mStartMoveInfo->mLastMultiItem;
465 if (!mStartMoveInfo->mFirstMultiItem) {
467 AgendaItem::QPtr toDel = mStartMoveInfo->mPrevMultiItem;
468 AgendaItem::QPtr nowDel =
nullptr;
471 if (nowDel->moveInfo()) {
472 toDel = nowDel->moveInfo()->mPrevMultiItem;
474 Q_EMIT removeAgendaItem(nowDel);
476 mMultiItemInfo->mFirstMultiItem =
nullptr;
477 mMultiItemInfo->mPrevMultiItem =
nullptr;
479 if (!mStartMoveInfo->mLastMultiItem) {
481 AgendaItem::QPtr toDel = mStartMoveInfo->mNextMultiItem;
482 AgendaItem::QPtr nowDel =
nullptr;
485 if (nowDel->moveInfo()) {
486 toDel = nowDel->moveInfo()->mNextMultiItem;
488 Q_EMIT removeAgendaItem(nowDel);
490 mMultiItemInfo->mLastMultiItem =
nullptr;
491 mMultiItemInfo->mNextMultiItem =
nullptr;
494 if (mStartMoveInfo->mFirstMultiItem ==
nullptr && mStartMoveInfo->mLastMultiItem ==
nullptr) {
496 delete mMultiItemInfo;
497 mMultiItemInfo =
nullptr;
500 delete mStartMoveInfo;
501 mStartMoveInfo =
nullptr;
503 Q_EMIT showAgendaItem(
this);
504 if (nextMultiItem()) {
505 nextMultiItem()->resetMovePrivate();
511 AgendaItem::QPtr first = firstMultiItem();
515 first->endMovePrivate();
518void AgendaItem::endMovePrivate()
520 if (mStartMoveInfo) {
522 if (!firstMultiItem() || firstMultiItem() ==
this) {
523 AgendaItem::QPtr toDel = mStartMoveInfo->mPrevMultiItem;
524 AgendaItem::QPtr nowDel =
nullptr;
527 if (nowDel->moveInfo()) {
528 toDel = nowDel->moveInfo()->mPrevMultiItem;
530 Q_EMIT removeAgendaItem(nowDel);
534 if (!lastMultiItem() || lastMultiItem() ==
this) {
535 AgendaItem::QPtr toDel = mStartMoveInfo->mNextMultiItem;
536 AgendaItem::QPtr nowDel =
nullptr;
539 if (nowDel->moveInfo()) {
540 toDel = nowDel->moveInfo()->mNextMultiItem;
542 Q_EMIT removeAgendaItem(nowDel);
546 delete mStartMoveInfo;
547 mStartMoveInfo =
nullptr;
548 if (nextMultiItem()) {
549 nextMultiItem()->endMovePrivate();
554void AgendaItem::moveRelative(
int dx,
int dy)
556 int newXLeft = cellXLeft() + dx;
557 int newXRight = cellXRight() + dx;
558 int newYTop = cellYTop() + dy;
559 int newYBottom = cellYBottom() + dy;
560 setCellXY(newXLeft, newYTop, newYBottom);
561 setCellXRight(newXRight);
566 int newYTop = cellYTop() + dy;
567 int newYBottom = cellYBottom();
568 if (newYTop > newYBottom && !allowOverLimit) {
569 newYTop = newYBottom;
571 setCellY(newYTop, newYBottom);
574void AgendaItem::expandBottom(
int dy)
576 int newYTop = cellYTop();
577 int newYBottom = cellYBottom() + dy;
578 if (newYBottom < newYTop) {
579 newYBottom = newYTop;
581 setCellY(newYTop, newYBottom);
584void AgendaItem::expandLeft(
int dx)
586 int newXLeft = cellXLeft() + dx;
587 int newXRight = cellXRight();
588 if (newXLeft > newXRight) {
589 newXLeft = newXRight;
591 setCellX(newXLeft, newXRight);
594void AgendaItem::expandRight(
int dx)
596 int newXLeft = cellXLeft();
597 int newXRight = cellXRight() + dx;
598 if (newXRight < newXLeft) {
599 newXRight = newXLeft;
601 setCellX(newXLeft, newXRight);
604void AgendaItem::dragEnterEvent(QDragEnterEvent *e)
606 const QMimeData *md = e->
mimeData();
619void AgendaItem::addAttendee(
const QString &newAttendee)
629 mIncidence->addAttendee(KCalendarCore::Attendee(name, email));
632 i18nc(
"@title:window",
"Attendee added"),
633 QStringLiteral(
"AttendeeDroppedAdded"));
637void AgendaItem::dropEvent(QDropEvent *e)
647 const QMimeData *md = e->
mimeData();
650 QString text = md->
text();
651 if (decoded && text.startsWith(
"file:"_L1)) {
652 mIncidence->addAttachment(KCalendarCore::Attachment(text));
659 for (
const KContacts::Addressee &addressee : std::as_const(list)) {
660 QString em(addressee.fullEmail());
662 em = addressee.realName();
669QList<AgendaItem::QPtr> &AgendaItem::conflictItems()
671 return mConflictItems;
674void AgendaItem::setConflictItems(
const QList<AgendaItem::QPtr> &ci)
677 for (QList<AgendaItem::QPtr>::iterator it = mConflictItems.begin(),
end(mConflictItems.end()); it != end; ++it) {
678 (*it)->addConflictItem(
this);
682void AgendaItem::addConflictItem(
const AgendaItem::QPtr &ci)
684 if (!mConflictItems.contains(ci)) {
685 mConflictItems.append(ci);
689QString AgendaItem::label()
const
696 AgendaItem::QPtr other =
static_cast<AgendaItem *
>(o);
698 if (cellXLeft() <= other->cellXRight() && cellXRight() >= other->cellXLeft()) {
699 if ((cellYTop() <= other->cellYBottom()) && (cellYBottom() >= other->cellYTop())) {
707static void conditionalPaint(
QPainter *p,
bool condition,
int &x,
int y,
int ft,
const QPixmap &pxmp)
711 x += pxmp.
width() + ft;
715void AgendaItem::paintIcon(QPainter *p,
int &x,
int y,
int ft)
718 if (mIncidence->customProperty(
"KABC",
"ANNIVERSARY") ==
"YES"_L1) {
719 mSpecialEvent =
true;
720 iconName = QStringLiteral(
"view-calendar-wedding-anniversary");
721 }
else if (mIncidence->customProperty(
"KABC",
"BIRTHDAY") ==
"YES"_L1) {
722 mSpecialEvent =
true;
729void AgendaItem::paintIcons(QPainter *p,
int &x,
int y,
int ft)
731 if (!mEventView->preferences()->enableAgendaItemIcons()) {
735 paintIcon(p,
x,
y, ft);
737 QSet<EventView::ItemIcon> icons = mEventView->preferences()->agendaViewIcons();
739 if (icons.
contains(EventViews::EventView::CalendarCustomIcon)) {
740 const QString iconName = mCalendar->iconForIncidence(mIncidence);
741 if (!iconName.
isEmpty() && iconName !=
"view-calendar"_L1 && iconName !=
"office-calendar"_L1) {
746 const bool isTodo = mIncidence && mIncidence->type() == Incidence::TypeTodo;
748 if (isTodo && icons.
contains(EventViews::EventView::TaskIcon)) {
749 const QString iconName = mIncidence->iconName(mOccurrenceDateTime.toLocalTime());
750 conditionalPaint(p, !mSpecialEvent,
x,
y, ft,
QIcon::fromTheme(iconName).pixmap(16, 16));
753 if (icons.
contains(EventView::RecurringIcon)) {
754 conditionalPaint(p, mIconRecur && !mSpecialEvent,
x,
y, ft, *recurPxmp);
757 if (icons.
contains(EventView::ReminderIcon)) {
758 conditionalPaint(p, mIconAlarm && !mSpecialEvent,
x,
y, ft, *alarmPxmp);
761 if (icons.
contains(EventView::ReadOnlyIcon)) {
762 conditionalPaint(p, mIconReadonly && !mSpecialEvent,
x,
y, ft, *readonlyPxmp);
765 if (icons.
contains(EventView::ReplyIcon)) {
766 conditionalPaint(p, mIconReply,
x,
y, ft, *replyPxmp);
769 if (icons.
contains(EventView::AttendingIcon)) {
770 conditionalPaint(p, mIconGroup,
x,
y, ft, *groupPxmp);
773 if (icons.
contains(EventView::TentativeIcon)) {
774 conditionalPaint(p, mIconGroupTent,
x,
y, ft, *groupPxmpTent);
777 if (icons.
contains(EventView::OrganizerIcon)) {
778 conditionalPaint(p, mIconOrganizer,
x,
y, ft, *organizerPxmp);
782void AgendaItem::paintEvent(QPaintEvent *ev)
799 const int fmargin = 0;
802 const int margin = 5 + ft + fmargin;
810 alarmPxmp =
new QPixmap(
QIcon::fromTheme(QStringLiteral(
"task-reminder")).pixmap(16, 16));
811 recurPxmp =
new QPixmap(
QIcon::fromTheme(QStringLiteral(
"appointment-recurring")).pixmap(16, 16));
812 readonlyPxmp =
new QPixmap(
QIcon::fromTheme(QStringLiteral(
"object-locked")).pixmap(16, 16));
813 replyPxmp =
new QPixmap(
QIcon::fromTheme(QStringLiteral(
"mail-reply-sender")).pixmap(16, 16));
814 groupPxmp =
new QPixmap(
QIcon::fromTheme(QStringLiteral(
"meeting-attending")).pixmap(16, 16));
815 groupPxmpTent =
new QPixmap(
QIcon::fromTheme(QStringLiteral(
"meeting-attending-tentative")).pixmap(16, 16));
816 organizerPxmp =
new QPixmap(
QIcon::fromTheme(QStringLiteral(
"meeting-organizer")).pixmap(16, 16));
819 const auto categoryColor = getCategoryColor();
820 const auto resourceColor = mResourceColor.isValid() ? mResourceColor : categoryColor;
821 const auto frameColor = getFrameColor(resourceColor, categoryColor);
822 const auto bgBaseColor = getBackgroundColor(resourceColor, categoryColor);
823 const auto bgColor = mSelected ? bgBaseColor.lighter(EventView::BRIGHTNESS_FACTOR) : bgBaseColor;
828 p.
setFont(mEventView->preferences()->agendaViewFont());
833 const bool roundTop = !prevMultiItem();
834 const bool roundBottom = !nextMultiItem();
837 QRect(fmargin, fmargin,
width() - fmargin * 2,
height() - fmargin * 2),
851 if (!isMultiItem()) {
854 if (CalendarSupport::hasEvent(mIncidence)) {
860 }
else if (!mMultiItemInfo->mFirstMultiItem) {
865 longH =
i18n(
"- %1", shortH);
873 qMax(alarmPxmp->height(),
874 qMax(recurPxmp->height(), qMax(readonlyPxmp->height(), qMax(replyPxmp->height(), qMax(groupPxmp->height(), organizerPxmp->height()))))));
876 const bool completelyRenderable = th < (
height() - 2 * ft - 2 - hlHeight);
884 int x = qRound((
width() - 16) / 2.0);
885 paintIcon(&p,
x , margin, ft);
890 if ((2 * singleLineHeight) > (
height() - 2 * margin)) {
894 if (mIncidence->allDay()) {
896 const int y = qRound((
height() - 16) / 2.0);
897 paintIcons(&p,
x,
y, ft);
898 txtWidth = visRect.
right() - margin -
x;
900 const int y = qRound((
height() - 16) / 2.0);
901 paintIcons(&p,
x,
y, ft);
902 txtWidth =
width() - margin -
x;
905 const int y = ((
height() - singleLineHeight) / 2) + fm.
ascent();
912 if (((!completelyRenderable) && ((
height() - (2 * margin)) <= (5 * singleLineHeight)))
913 || (isMultiItem() && mMultiItemInfo->mNextMultiItem && mMultiItemInfo->mFirstMultiItem)) {
917 if (mIncidence->allDay()) {
919 paintIcons(&p,
x, margin, ft);
920 txtWidth = visRect.
right() - margin -
x;
922 paintIcons(&p,
x, margin, ft);
923 txtWidth =
width() - margin -
x;
934 int y = 2 * ft + hlHeight;
935 if (completelyRenderable) {
936 y += (
height() - (2 * ft) - margin - hlHeight - th) / 2;
944 if (mIncidence->allDay()) {
951 shortH =
i18n(
"%1 - %2",
952 QLocale().
toString(mIncidence->dtStart().toLocalTime().date()),
958 QRect(fmargin, fmargin,
width() - fmargin * 2, -fmargin * 2 + margin + hlHeight),
971 QRect(fmargin, fmargin,
width() - fmargin * 2, -fmargin * 2 + margin + hlHeight),
985 QRect(fmargin, fmargin,
width() - fmargin * 2, -fmargin * 2 + margin + hlHeight),
997 txtWidth = visRect.
right() - margin -
x;
998 paintIcons(&p,
x, margin / 2, ft);
999 hTxtWidth = visRect.
right() - margin -
x;
1003 QRect(fmargin, fmargin,
width() - fmargin * 2, -fmargin * 2 + margin + hlHeight),
1012 txtWidth =
width() - margin -
x;
1014 paintIcons(&p,
x, margin / 2, ft);
1015 hTxtWidth =
width() - margin -
x;
1020 if (hw > hTxtWidth) {
1023 if (hw < txtWidth) {
1024 x += (hTxtWidth - hw) / 2;
1028 x += (hTxtWidth - hw) / 2;
1040 if (QStringView(ws).
left(
ws.length() - 1).indexOf(QLatin1Char(
'\n')) >= 0) {
1047void AgendaItem::drawRoundedRect(QPainter *p,
1050 const QColor &bgColor,
1051 const QColor &frameColor,
1064 const int RECT_MARGIN = 2;
1065 const int RADIUS = 2;
1067 const QRect rectWithMargin(
rect.x() + RECT_MARGIN,
rect.y() + RECT_MARGIN,
rect.width() - 2 * RECT_MARGIN,
rect.height() - 2 * RECT_MARGIN);
1069 const QPoint pointLeftTop(rectWithMargin.x(), rectWithMargin.y());
1070 const QPoint pointRightTop(rectWithMargin.x() + rectWithMargin.width(), rectWithMargin.y());
1071 const QPoint pointLeftBottom(rectWithMargin.x(), rectWithMargin.y() + rectWithMargin.height());
1072 const QPoint pointRightBottom(rectWithMargin.x() + rectWithMargin.width(), rectWithMargin.y() + rectWithMargin.height());
1074 if (!roundTop && !roundBottom) {
1075 path.addRect(rectWithMargin);
1076 }
else if (roundTop && roundBottom) {
1078 }
else if (roundTop) {
1079 path.moveTo(pointRightBottom);
1080 path.lineTo(pointLeftBottom);
1081 path.lineTo(QPoint(pointLeftTop.x(), pointLeftTop.y() + RADIUS));
1082 path.quadTo(pointLeftTop, QPoint(pointLeftTop.x() + RADIUS, pointLeftTop.y()));
1083 path.lineTo(QPoint(pointRightTop.x() - RADIUS, pointRightTop.y()));
1084 path.quadTo(pointRightTop, QPoint(pointRightTop.x(), pointRightTop.y() + RADIUS));
1085 path.lineTo(pointRightBottom);
1086 }
else if (roundBottom) {
1087 path.moveTo(pointRightTop);
1088 path.lineTo(QPoint(pointRightBottom.x(), pointRightBottom.y() - RADIUS));
1089 path.quadTo(pointRightBottom, QPoint(pointRightBottom.x() - RADIUS, pointRightBottom.y()));
1090 path.lineTo(QPoint(pointLeftBottom.x() + RADIUS, pointLeftBottom.y()));
1091 path.quadTo(pointLeftBottom, QPoint(pointLeftBottom.x(), pointLeftBottom.y() - RADIUS));
1092 path.lineTo(pointLeftTop);
1093 path.lineTo(pointRightTop);
1096 path.closeSubpath();
1106 QColor top = bgColor.
darker(250);
1108 brushSolid.setColor(top);
1125QColor AgendaItem::getCategoryColor()
const
1127 const QStringList &categories = mIncidence->categories();
1129 const auto colorPreference = mEventView->preferences()->agendaViewColors();
1130 if (colorPreference == PrefsBase::CategoryOnly || !mResourceColor.isValid()) {
1131 return CalendarSupport::KCalPrefs::instance()->unsetCategoryColor();
1133 return mResourceColor;
1138QColor AgendaItem::getFrameColor(
const QColor &
resourceColor,
const QColor &categoryColor)
const
1140 const auto colorPreference = mEventView->preferences()->agendaViewColors();
1141 const bool frameDisplaysCategory = (colorPreference == PrefsBase::CategoryOnly || colorPreference == PrefsBase::ResourceInsideCategoryOutside);
1142 return frameDisplaysCategory ? categoryColor : resourceColor;
1145QColor AgendaItem::getBackgroundColor(
const QColor &
resourceColor,
const QColor &categoryColor)
const
1147 if (CalendarSupport::hasTodo(mIncidence) && !mEventView->preferences()->todosUseCategoryColors()) {
1150 const QDate dueDate =
todo->dtDue().toLocalTime().date();
1152 const QDate occurrenceDate = this->occurrenceDate();
1153 if (
todo->isOverdue() && today >= occurrenceDate) {
1154 return mEventView->preferences()->todoOverdueColor();
1155 }
else if (dueDate == today && dueDate == occurrenceDate && !
todo->isCompleted()) {
1156 return mEventView->preferences()->todoDueTodayColor();
1159 const auto colorPreference = mEventView->preferences()->agendaViewColors();
1160 const bool bgDisplaysCategory = (colorPreference == PrefsBase::CategoryOnly || colorPreference == PrefsBase::CategoryInsideResourceOutside);
1161 return bgDisplaysCategory ? categoryColor : resourceColor;
1164bool AgendaItem::eventFilter(QObject *obj, QEvent *event)
1174bool AgendaItem::event(QEvent *event)
1177 if (!mEventView->preferences()->enableToolTips()) {
1179 }
else if (mValid) {
1180 auto helpEvent =
static_cast<QHelpEvent *
>(event);
1189#include "moc_agendaitem.cpp"
QColor tagColor(const QString &tagName) const
static TagCache * instance()
void setOccurrenceDateTime(const QDateTime &qd)
Update the date of this item's occurrence (not in the event)
bool overlaps(CellItem *o) const override
Tells whether this item overlaps item o.
void endMove()
End the movement (i.e.
void expandTop(int dy, const bool allowOverLimit=false)
Expands the item's top.
void startMovePrivate()
private movement functions.
void resetMove()
Reset to original values.
void startMove()
Start movement.
EventView is the abstract base class from which all other calendar views for event data are derived.
QSharedPointer< Event > Ptr
QSharedPointer< Incidence > Ptr
QSharedPointer< Todo > Ptr
QRect boundingRect() const
static KWordWrap formatText(QFontMetrics &fm, const QRect &r, int flags, const QString &str, int len=-1)
static void drawFadeoutText(QPainter *p, int x, int y, int maxW, const QString &t)
void drawText(QPainter *painter, int x, int y, int flags=Qt::AlignLeft) const
QString wrappedString() const
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::Todo::Ptr todo(const Akonadi::Item &item)
char * toString(const EngineQuery &query)
Namespace EventViews provides facilities for displaying incidences, including events,...
EVENTVIEWS_EXPORT QColor resourceColor(const Akonadi::Collection &collection, const PrefsPtr &preferences)
This method returns the proper resource / subresource color for the view.
QPixmap cachedSmallIcon(const QString &name)
Equivalent to SmallIcon( name ), but uses QPixmapCache.
int yearDiff(QDate start, QDate end)
Returns the number of years between the start QDate and the end QDate (i.e.
QColor getTextColor(const QColor &c)
Returns a nice QColor for text, give the input color &c.
KCALUTILS_EXPORT bool canDecode(const QMimeData *)
KCALUTILS_EXPORT bool canDecode(const QMimeData *)
QAction * end(const QObject *recvr, const char *slot, QObject *parent)
QString name(const QVariant &location)
QString path(const QString &relativePath)
void information(QWidget *parent, const QString &text, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
const QList< QKeySequence > & next()
QColor darker(int factor) const const
bool isValid() const const
QDateTime toLocalTime() const const
const QMimeData * mimeData() const const
QRect boundingRect(QChar ch) const const
QIcon fromTheme(const QString &name)
bool isEmpty() const const
bool hasText() const const
QString text() const const
virtual bool eventFilter(QObject *watched, QEvent *event)
void drawPath(const QPainterPath &path)
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
QFontMetrics fontMetrics() const const
void setBackground(const QBrush &brush)
void setBrush(Qt::BrushStyle style)
void setFont(const QFont &font)
void setPen(Qt::PenStyle style)
void setRenderHint(RenderHint hint, bool on)
const QRect & rect() const const
void setColor(ColorGroup group, ColorRole role, const QColor &color)
bool isValid() const const
QRect boundingRect() const const
bool contains(const QSet< T > &other) const const
bool isEmpty() const const
QTextStream & left(QTextStream &stream)
QTextStream & ws(QTextStream &stream)
QTimeZone systemTimeZone()
void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect, int msecDisplayTime)