14#include "agendaview.h"
17#include <Akonadi/CalendarUtils>
18#include <Akonadi/IncidenceChanger>
19#include <CalendarSupport/Utils>
21#include <KCalendarCore/Incidence>
23#include <KCalUtils/RecurrenceActions>
25#include "calendarview_debug.h"
28#include <KLocalizedString>
29#include <QApplication>
36#include <QResizeEvent>
44using namespace std::chrono_literals;
49class EventViews::MarcusBainsPrivate
52 MarcusBainsPrivate(EventView *eventView, Agenda *agenda)
53 : mEventView(eventView)
58 [[nodiscard]]
int todayColumn()
const;
61 EventView *
const mEventView;
62 Agenda *
const mAgenda;
63 QTimer *mTimer =
nullptr;
64 QLabel *mTimeBox =
nullptr;
65 QDateTime mOldDateTime;
66 int mOldTodayCol = -1;
69int MarcusBainsPrivate::todayColumn()
const
75 for (
const QDate &date : dateList) {
76 if (date == currentDate) {
85MarcusBains::MarcusBains(
EventView *eventView, Agenda *agenda)
87 , d(new MarcusBainsPrivate(eventView, agenda))
89 d->mTimeBox =
new QLabel(d->mAgenda);
92 d->mTimer =
new QTimer(
this);
93 d->mTimer->setSingleShot(
true);
98MarcusBains::~MarcusBains() =
default;
100void MarcusBains::updateLocation()
102 updateLocationRecalc();
105void MarcusBains::updateLocationRecalc(
bool recalculate)
107 const bool showSeconds = d->mEventView->preferences()->marcusBainsShowSeconds();
108 const QColor color = d->mEventView->preferences()->agendaMarcusBainsLineLineColor();
111 const QTime time = now.
time();
113 if (now.
date() != d->mOldDateTime.date()) {
116 const int todayCol = recalculate ? d->todayColumn() : d->mOldTodayCol;
119 const int minutes = time.
hour() * 60 + time.
minute();
120 const int minutesPerCell = 24 * 60 / d->mAgenda->rows();
122 d->mOldDateTime = now;
123 d->mOldTodayCol = todayCol;
125 int y = int(minutes * d->mAgenda->gridSpacingY() / minutesPerCell);
126 int x = int(d->mAgenda->gridSpacingX() * todayCol);
128 bool hideIt = !(d->mEventView->preferences()->marcusBainsEnabled());
129 if (!
isHidden() && (hideIt || (todayCol < 0))) {
142 const int fw = d->mEventView->preferences()->agendaMarcusBainsLineFont().weight();
156 d->mTimeBox->setFont(d->mEventView->preferences()->agendaMarcusBainsLineFont());
157 QPalette pal1 = d->mTimeBox->palette();
159 if (!d->mEventView->preferences()->useSystemColor()) {
164 d->mTimeBox->setPalette(pal1);
165 d->mTimeBox->setAutoFillBackground(
true);
167 d->mTimeBox->adjustSize();
168 if (
y - d->mTimeBox->height() >= 0) {
169 y -= d->mTimeBox->height();
173 if (
x - d->mTimeBox->width() + d->mAgenda->gridSpacingX() > 0) {
174 x += int(d->mAgenda->gridSpacingX() - d->mTimeBox->width() - 1);
178 d->mTimeBox->move(
x,
y);
179 d->mTimeBox->raise();
181 if (showSeconds || recalculate) {
182 d->mTimer->start(1s);
184 d->mTimer->start(1000 * (60 - time.
second()));
190class EventViews::AgendaPrivate
193 AgendaPrivate(AgendaView *agendaView, QScrollArea *scrollArea,
int columns,
int rows,
int rowSize,
bool isInteractive)
194 : mAgendaView(agendaView)
195 , mScrollArea(scrollArea)
198 , mGridSpacingY(rowSize)
199 , mDesiredGridSpacingY(rowSize)
200 , mIsInteractive(isInteractive)
202 if (mGridSpacingY < 4 || mGridSpacingY > 30) {
210 return mAgendaView->preferences();
213 bool isQueuedForDeletion(
const QString &uid)
const
217 return mItemsQueuedForDeletion.contains(uid) && !mAgendaItemsById.contains(uid);
220 QMultiHash<QString, AgendaItem::QPtr> mAgendaItemsById;
222 QSet<QString> mItemsQueuedForDeletion;
224 AgendaView *mAgendaView =
nullptr;
225 QScrollArea *mScrollArea =
nullptr;
227 bool mAllDayMode{
false};
236 double mGridSpacingX{0.0};
237 double mGridSpacingY;
238 double mDesiredGridSpacingY;
240 Akonadi::IncidenceChanger *mChanger =
nullptr;
243 int mResizeBorderWidth{0};
246 int mScrollBorderWidth{0};
248 int mScrollOffset{0};
250 QTimer mScrollUpTimer;
251 QTimer mScrollDownTimer;
258 bool mWorkingHoursEnable{
false};
259 QList<bool> *mHolidayMask =
nullptr;
260 int mWorkingHoursYTop{0};
261 int mWorkingHoursYBottom{0};
264 bool mHasSelection{
false};
265 QPoint mSelectionStartPoint;
266 QPoint mSelectionStartCell;
267 QPoint mSelectionEndCell;
273 QPointer<AgendaItem> mClickedItem;
276 QPointer<AgendaItem> mActionItem;
279 QPointer<AgendaItem> mSelectedItem;
286 MarcusBains *mMarcusBains =
nullptr;
288 Agenda::MouseActionType mActionType{Agenda::NOP};
290 bool mItemMoved{
false};
293 QList<AgendaItem::QPtr> mItems;
294 QList<AgendaItem::QPtr> mItemsToDelete;
296 int mOldLowerScrollValue{0};
297 int mOldUpperScrollValue{0};
299 bool mReturnPressed{
false};
302 MultiViewCalendar::Ptr mCalendar;
308Agenda::Agenda(
AgendaView *agendaView, QScrollArea *scrollArea,
int columns,
int rows,
int rowSize,
bool isInteractive)
309 : QWidget(scrollArea)
310 , d(new AgendaPrivate(agendaView, scrollArea, columns, rows, rowSize, isInteractive))
312 setMouseTracking(
true);
323 , d(new AgendaPrivate(agendaView, scrollArea, columns, 1, 24, isInteractive))
325 d->mAllDayMode =
true;
332 delete d->mMarcusBains;
340QDate Agenda::selectedIncidenceDate()
const
342 return d->mSelectedItem ? d->mSelectedItem->occurrenceDate() : QDate();
345QString Agenda::lastSelectedItemUid()
const
347 return d->mSelectedId;
354 d->mGridSpacingX =
static_cast<double>(d->mScrollArea->width()) / d->mColumns;
355 d->mDesiredGridSpacingY = d->preferences()->hourSize();
356 if (d->mDesiredGridSpacingY < 4 || d->mDesiredGridSpacingY > 30) {
357 d->mDesiredGridSpacingY = 10;
361 d->mGridSpacingY =
static_cast<double>(
height()) / d->mRows;
362 if (d->mGridSpacingY < d->mDesiredGridSpacingY) {
363 d->mGridSpacingY = d->mDesiredGridSpacingY;
366 d->mResizeBorderWidth = 12;
367 d->mScrollBorderWidth = 12;
368 d->mScrollDelay = 30;
369 d->mScrollOffset = 10;
378 d->mStartCell = QPoint(0, 0);
379 d->mEndCell = QPoint(0, 0);
381 d->mHasSelection =
false;
382 d->mSelectionStartPoint = QPoint(0, 0);
383 d->mSelectionStartCell = QPoint(0, 0);
384 d->mSelectionEndCell = QPoint(0, 0);
386 d->mOldLowerScrollValue = -1;
387 d->mOldUpperScrollValue = -1;
389 d->mClickedItem =
nullptr;
391 d->mActionItem =
nullptr;
392 d->mActionType = NOP;
393 d->mItemMoved =
false;
395 d->mSelectedItem =
nullptr;
402 d->mScrollArea->viewport()->update();
406 calculateWorkingHours();
411 if (d->mAllDayMode) {
412 d->mMarcusBains =
nullptr;
414 d->mMarcusBains =
new MarcusBains(d->mAgendaView,
this);
420 qDeleteAll(d->mItems);
421 qDeleteAll(d->mItemsToDelete);
423 d->mItemsToDelete.clear();
424 d->mAgendaItemsById.clear();
425 d->mItemsQueuedForDeletion.clear();
427 d->mSelectedItem =
nullptr;
432void Agenda::clearSelection()
434 d->mHasSelection =
false;
435 d->mActionType = NOP;
439void Agenda::marcus_bains()
441 if (d->mMarcusBains) {
442 d->mMarcusBains->updateLocationRecalc(
true);
446void Agenda::changeColumns(
int columns)
449 qCDebug(CALENDARVIEW_LOG) <<
"called with argument 0";
454 d->mColumns = columns;
464int Agenda::columns()
const
469int Agenda::rows()
const
474double Agenda::gridSpacingX()
const
476 return d->mGridSpacingX;
479double Agenda::gridSpacingY()
const
481 return d->mGridSpacingY;
488bool Agenda::eventFilter(QObject *
object, QEvent *event)
490 switch (
event->type()) {
495 return eventFilter_mouse(
object,
static_cast<QMouseEvent *
>(
event));
496#ifndef QT_NO_WHEELEVENT
498 return eventFilter_wheel(
object,
static_cast<QWheelEvent *
>(
event));
502 return eventFilter_key(
object,
static_cast<QKeyEvent *
>(
event));
506 if (!d->mActionItem) {
511 if (
object ==
this) {
521#ifndef QT_NO_DRAGANDDROP
527 return eventFilter_drag(
object,
static_cast<QDropEvent *
>(
event));
535bool Agenda::eventFilter_drag(QObject *obj, QDropEvent *de)
537#ifndef QT_NO_DRAGANDDROP
538 const QMimeData *md = de->
mimeData();
540 switch (de->
type()) {
543 if (!CalendarSupport::canDecode(md)) {
547 if (CalendarSupport::mimeDataHasIncidence(md)) {
558 if (!CalendarSupport::canDecode(md)) {
562 const QList<QUrl> incidenceUrls = CalendarSupport::incidenceItemUrls(md);
571 if (dropTarget && dropTarget !=
this) {
572 dropPosition = dropTarget->
mapTo(
this, dropPosition);
575 const QPoint gridPosition = contentsToGrid(dropPosition);
576 if (!incidenceUrls.
isEmpty()) {
577 Q_EMIT droppedIncidences(incidenceUrls, gridPosition, d->mAllDayMode);
579 Q_EMIT droppedIncidences(incidences, gridPosition, d->mAllDayMode);
592#ifndef QT_NO_WHEELEVENT
593bool Agenda::eventFilter_wheel(QObject *
object, QWheelEvent *e)
596 bool accepted =
false;
599 if (
object !=
this) {
600 viewportPos = ((
QWidget *)
object)->mapToParent(
pos);
610 if (
object !=
this) {
611 viewportPos = ((
QWidget *)
object)->mapToParent(
pos);
616 Q_EMIT mousePosSignal(gridToContents(contentsToGrid(viewportPos)));
627bool Agenda::eventFilter_key(QObject *, QKeyEvent *ke)
629 return d->mAgendaView->processKeyEvent(ke);
632bool Agenda::eventFilter_mouse(QObject *
object, QMouseEvent *me)
635 if (
object !=
this) {
638 viewportPos = me->
pos();
641 switch (me->
type()) {
643 if (
object !=
this) {
646 if (d->mClickedItem) {
647 selectItem(d->mClickedItem);
648 Q_EMIT showIncidencePopupSignal(d->mClickedItem->incidence(), d->mClickedItem->occurrenceDate());
655 d->mActionItem =
nullptr;
657 d->mActionItem = item;
658 startItemAction(viewportPos);
670 QPoint gpos = contentsToGrid(viewportPos);
671 if (!ptInSelection(gpos)) {
672 d->mSelectionStartCell = gpos;
673 d->mSelectionEndCell = gpos;
674 d->mHasSelection =
true;
675 Q_EMIT newStartSelectSignal();
676 Q_EMIT newTimeSpanSignal(d->mSelectionStartCell, d->mSelectionEndCell);
679 Q_EMIT showNewEventPopupSignal();
682 d->mActionItem =
nullptr;
686 startSelectAction(viewportPos);
693 if (d->mActionItem) {
695 }
else if (d->mActionType == SELECT) {
696 endSelectAction(viewportPos);
700 Q_EMIT mousePosSignal(gridToContents(contentsToGrid(viewportPos)));
704 if (!d->mIsInteractive) {
710 QPoint indicatorPos = gridToContents(contentsToGrid(viewportPos));
711 if (
object !=
this) {
714 if (incidence && !
incidence->isReadOnly()) {
715 if (!d->mActionItem) {
716 setNoActionCursor(moveItem, viewportPos);
718 performItemAction(viewportPos);
720 if (d->mActionType == MOVE) {
722 AgendaItem::QPtr firstItem = d->mActionItem->firstMultiItem();
724 firstItem = d->mActionItem;
726 indicatorPos = gridToContents(QPoint(firstItem->cellXLeft(), firstItem->cellYTop()));
727 }
else if (d->mActionType == RESIZEBOTTOM) {
729 indicatorPos = gridToContents(QPoint(d->mActionItem->cellXLeft(), d->mActionItem->cellYBottom() + 1));
734 if (d->mActionType == SELECT) {
735 performSelectAction(viewportPos);
738 if (((d->mStartCell.y() < d->mEndCell.y()) && (d->mEndCell.x() >= d->mStartCell.x())) || (d->mEndCell.x() > d->mStartCell.x())) {
739 indicatorPos = gridToContents(QPoint(d->mEndCell.x(), d->mEndCell.y() + 1));
741 indicatorPos = gridToContents(d->mEndCell);
745 Q_EMIT mousePosSignal(indicatorPos);
750 if (
object ==
this) {
755 if (doubleClickedItem) {
756 selectItem(doubleClickedItem);
757 Q_EMIT editIncidenceSignal(doubleClickedItem->incidence());
769bool Agenda::ptInSelection(QPoint gpos)
const
771 if (!d->mHasSelection) {
773 }
else if (gpos.
x() < d->mSelectionStartCell.x() || gpos.
x() > d->mSelectionEndCell.x()) {
775 }
else if ((gpos.
x() == d->mSelectionStartCell.x()) && (gpos.
y() < d->mSelectionStartCell.y())) {
777 }
else if ((gpos.
x() == d->mSelectionEndCell.x()) && (gpos.
y() > d->mSelectionEndCell.y())) {
783void Agenda::startSelectAction(QPoint viewportPos)
785 Q_EMIT newStartSelectSignal();
787 d->mActionType = SELECT;
788 d->mSelectionStartPoint = viewportPos;
789 d->mHasSelection =
true;
791 QPoint
pos = viewportPos;
792 QPoint gpos = contentsToGrid(
pos);
795 d->mStartCell = gpos;
797 d->mSelectionStartCell = gpos;
798 d->mSelectionEndCell = gpos;
803void Agenda::performSelectAction(QPoint pos)
805 const QPoint gpos = contentsToGrid(
pos);
808 if (
pos.y() - contentsY() < d->mScrollBorderWidth && contentsY() > 0) {
809 d->mScrollUpTimer.start(d->mScrollDelay);
810 }
else if (contentsY() + d->mScrollArea->viewport()->height() - d->mScrollBorderWidth <
pos.y()) {
811 d->mScrollDownTimer.start(d->mScrollDelay);
813 d->mScrollUpTimer.stop();
814 d->mScrollDownTimer.stop();
817 if (gpos != d->mEndCell) {
819 if (d->mStartCell.x() > d->mEndCell.x() || (d->mStartCell.x() == d->mEndCell.x() && d->mStartCell.y() > d->mEndCell.y())) {
821 d->mSelectionStartCell = d->mEndCell;
822 d->mSelectionEndCell = d->mStartCell;
824 d->mSelectionStartCell = d->mStartCell;
825 d->mSelectionEndCell = d->mEndCell;
832void Agenda::endSelectAction(
const QPoint ¤tPos)
834 d->mScrollUpTimer.stop();
835 d->mScrollDownTimer.stop();
837 d->mActionType = NOP;
839 Q_EMIT newTimeSpanSignal(d->mSelectionStartCell, d->mSelectionEndCell);
841 if (d->preferences()->selectionStartsEditor()) {
848Agenda::MouseActionType Agenda::isInResizeArea(
bool horizontal, QPoint pos,
const AgendaItem::QPtr &item)
853 QPoint gridpos = contentsToGrid(
pos);
857 int clXLeft = item->cellXLeft();
858 int clXRight = item->cellXRight();
864 int gridDistanceX = int(
pos.x() - contpos.
x());
865 if (gridDistanceX < d->mResizeBorderWidth && clXLeft == gridpos.
x()) {
871 }
else if ((d->mGridSpacingX - gridDistanceX) < d->mResizeBorderWidth && clXRight == gridpos.
x()) {
881 int gridDistanceY = int(
pos.y() - contpos.
y());
882 if (gridDistanceY < d->mResizeBorderWidth && item->cellYTop() == gridpos.
y() && !item->firstMultiItem()) {
884 }
else if ((d->mGridSpacingY - gridDistanceY) < d->mResizeBorderWidth && item->cellYBottom() == gridpos.
y() && !item->lastMultiItem()) {
892void Agenda::startItemAction(
const QPoint &pos)
894 Q_ASSERT(d->mActionItem);
896 d->mStartCell = contentsToGrid(
pos);
897 d->mEndCell = d->mStartCell;
899 bool noResize = CalendarSupport::hasTodo(d->mActionItem->incidence());
901 d->mActionType = MOVE;
903 d->mActionType = isInResizeArea(d->mAllDayMode,
pos, d->mActionItem);
906 d->mActionItem->startMove();
907 setActionCursor(d->mActionType,
true);
910void Agenda::performItemAction(QPoint pos)
912 QPoint gpos = contentsToGrid(
pos);
916 if (
pos.y() < 0 ||
pos.y() >= contentsY() + d->mScrollArea->viewport()->height() ||
pos.x() < 0 ||
pos.x() >=
width()) {
917 if (d->mActionType == MOVE) {
918 d->mScrollUpTimer.stop();
919 d->mScrollDownTimer.stop();
920 d->mActionItem->resetMove();
921 placeSubCells(d->mActionItem);
922 Q_EMIT startDragSignal(d->mActionItem->incidence());
929 d->mActionItem =
nullptr;
930 d->mActionType = NOP;
931 d->mItemMoved =
false;
935 setActionCursor(d->mActionType,
true);
939 const int distanceToTop =
pos.y() - contentsY();
940 if (distanceToTop < d->mScrollBorderWidth && distanceToTop > -d->mScrollBorderWidth) {
941 d->mScrollUpTimer.start(d->mScrollDelay);
942 }
else if (contentsY() + d->mScrollArea->viewport()->height() - d->mScrollBorderWidth <
pos.y()) {
943 d->mScrollDownTimer.start(d->mScrollDelay);
945 d->mScrollUpTimer.stop();
946 d->mScrollDownTimer.stop();
950 if (d->mEndCell != gpos) {
951 if (!d->mItemMoved) {
955 "Unable to lock item for modification. "
956 "You cannot make any changes."),
957 i18nc(
"@title:window",
"Locking Failed"),
958 QStringLiteral(
"AgendaLockingFailed"));
959 d->mScrollUpTimer.stop();
960 d->mScrollDownTimer.stop();
961 d->mActionItem->resetMove();
962 placeSubCells(d->mActionItem);
966 d->mActionItem =
nullptr;
967 d->mActionType = NOP;
968 d->mItemMoved =
false;
971 d->mItemMoved =
true;
973 d->mActionItem->raise();
974 if (d->mActionType == MOVE) {
976 AgendaItem::QPtr firstItem = d->mActionItem->firstMultiItem();
978 firstItem = d->mActionItem;
980 AgendaItem::QPtr lastItem = d->mActionItem->lastMultiItem();
982 lastItem = d->mActionItem;
984 QPoint deltapos = gpos - d->mEndCell;
985 AgendaItem::QPtr moveItem = firstItem;
987 bool changed =
false;
988 if (deltapos.
x() != 0) {
989 moveItem->moveRelative(deltapos.
x(), 0);
993 if (moveItem == firstItem && !d->mAllDayMode) {
994 int newY = deltapos.
y() + moveItem->cellYTop();
996 if (newY < 0 && newY > d->mScrollBorderWidth) {
997 moveItem->expandTop(-moveItem->cellYTop());
999 AgendaItem::QPtr newFirst = firstItem->prevMoveItem();
1003 newFirst->setCellXY(moveItem->cellXLeft() - 1, rows() + newY, rows() - 1);
1004 d->mItems.append(newFirst);
1005 moveItem->resize(
int(d->mGridSpacingX * newFirst->cellWidth()),
int(d->mGridSpacingY * newFirst->cellHeight()));
1006 QPoint cpos = gridToContents(QPoint(newFirst->cellXLeft(), newFirst->cellYTop()));
1007 newFirst->setParent(
this);
1008 newFirst->move(cpos.
x(), cpos.
y());
1010 newFirst = insertItem(moveItem->incidence(),
1011 moveItem->occurrenceDateTime(),
1012 moveItem->cellXLeft() - 1,
1015 moveItem->itemPos(),
1016 moveItem->itemCount(),
1022 moveItem->prependMoveItem(newFirst);
1023 firstItem = newFirst;
1024 }
else if (newY >= rows()) {
1027 firstItem = moveItem->nextMultiItem();
1029 d->mItems.removeAll(moveItem);
1031 d->mActionItem->removeMoveItem(moveItem);
1032 moveItem = firstItem;
1035 moveItem->expandTop(rows() - newY);
1038 moveItem->expandTop(deltapos.
y(),
true);
1042 if (moveItem && !moveItem->lastMultiItem() && !d->mAllDayMode) {
1043 int newY = deltapos.
y() + moveItem->cellYBottom();
1046 lastItem = moveItem->prevMultiItem();
1048 d->mItems.removeAll(moveItem);
1050 moveItem->removeMoveItem(moveItem);
1051 moveItem = lastItem;
1052 moveItem->expandBottom(newY + 1);
1053 }
else if (newY >= rows()) {
1054 moveItem->expandBottom(rows() - moveItem->cellYBottom() - 1);
1056 AgendaItem::QPtr newLast = lastItem->nextMoveItem();
1058 newLast->setCellXY(moveItem->cellXLeft() + 1, 0, newY - rows() - 1);
1059 d->mItems.append(newLast);
1060 moveItem->resize(
int(d->mGridSpacingX * newLast->cellWidth()),
int(d->mGridSpacingY * newLast->cellHeight()));
1061 QPoint cpos = gridToContents(QPoint(newLast->cellXLeft(), newLast->cellYTop()));
1062 newLast->setParent(
this);
1063 newLast->move(cpos.
x(), cpos.
y());
1065 newLast = insertItem(moveItem->incidence(),
1066 moveItem->occurrenceDateTime(),
1067 moveItem->cellXLeft() + 1,
1070 moveItem->itemPos(),
1071 moveItem->itemCount(),
1074 moveItem->appendMoveItem(newLast);
1078 moveItem->expandBottom(deltapos.
y());
1083 adjustItemPosition(moveItem);
1086 moveItem = moveItem->nextMultiItem();
1089 }
else if (d->mActionType == RESIZETOP) {
1090 if (d->mEndCell.y() <= d->mActionItem->cellYBottom()) {
1091 d->mActionItem->expandTop(gpos.
y() - d->mEndCell.y());
1092 adjustItemPosition(d->mActionItem);
1094 }
else if (d->mActionType == RESIZEBOTTOM) {
1095 if (d->mEndCell.y() >= d->mActionItem->cellYTop()) {
1096 d->mActionItem->expandBottom(gpos.
y() - d->mEndCell.y());
1097 adjustItemPosition(d->mActionItem);
1099 }
else if (d->mActionType == RESIZELEFT) {
1100 if (d->mEndCell.x() <= d->mActionItem->cellXRight()) {
1101 d->mActionItem->expandLeft(gpos.
x() - d->mEndCell.x());
1102 adjustItemPosition(d->mActionItem);
1104 }
else if (d->mActionType == RESIZERIGHT) {
1105 if (d->mEndCell.x() >= d->mActionItem->cellXLeft()) {
1106 d->mActionItem->expandRight(gpos.
x() - d->mEndCell.x());
1107 adjustItemPosition(d->mActionItem);
1114void Agenda::endItemAction()
1117 d->mActionType = NOP;
1118 d->mScrollUpTimer.stop();
1119 d->mScrollDownTimer.stop();
1125 qCCritical(CALENDARVIEW_LOG) <<
"No IncidenceChanger set";
1129 bool multiModify =
false;
1132 const auto recurrenceId = d->mActionItem->occurrenceDateTime();
1134 d->mItemMoved = d->mItemMoved && !(d->mStartCell.x() == d->mEndCell.x() && d->mStartCell.y() == d->mEndCell.y());
1136 if (d->mItemMoved) {
1137 bool addIncidence =
false;
1138 bool modify =
false;
1144 if (CalendarSupport::hasEvent(incidence)) {
1145 mainIncidence = cal->event(
incidence->uid());
1146 }
else if (CalendarSupport::hasTodo(incidence)) {
1147 mainIncidence = cal->todo(
incidence->uid());
1152 Akonadi::Item item = d->mCalendar->item(incidence);
1154 const int res = d->mAgendaView->showMoveRecurDialog(incidence, recurrenceId.date());
1156 if (!d->mActionItem) {
1157 qCWarning(CALENDARVIEW_LOG) <<
"mActionItem was reset while the 'move' dialog was active";
1158 d->mItemMoved =
false;
1172 d->mChanger->startAtomicOperation(
i18nc(
"@info/plain",
"Dissociate event from recurrence"));
1175 newInc->removeCustomProperty(
"VOLATILE",
"AKONADI-ID");
1176 Akonadi::Item newItem = d->mCalendar->item(newInc);
1178 if (newItem.
isValid() && newItem != item) {
1180 newInc->setCustomProperty(
"VOLATILE",
"AKONADI-ID",
QString::number(newItem.
id()));
1181 addIncidence =
false;
1183 addIncidence =
true;
1186 d->mAgendaView->enableAgendaUpdate(
false);
1188 d->mActionItem->setIncidence(newInc);
1189 (void)d->mActionItem->dissociateFromMultiItem();
1191 d->mAgendaView->enableAgendaUpdate(
true);
1195 "Unable to add the exception item to the calendar. "
1196 "No change will be done."),
1197 i18nc(
"@title:window",
"Error Occurred"));
1203 d->mActionItem->resetMove();
1204 placeSubCells(d->mActionItem);
1209 AgendaItem::QPtr placeItem = d->mActionItem->firstMultiItem();
1211 placeItem = d->mActionItem;
1226 d->mActionItem->endMove();
1228 AgendaItem::QPtr modif = placeItem;
1230 QList<AgendaItem::QPtr> oldconflictItems = placeItem->conflictItems();
1231 QList<AgendaItem::QPtr>::iterator it;
1232 for (it = oldconflictItems.
begin(); it != oldconflictItems.
end(); ++it) {
1238 placeSubCells(placeItem);
1239 placeItem = placeItem->nextMultiItem();
1250 d->mAgendaView->updateEventDates(modif, addIncidence, saveCollection);
1260 d->mAgendaView->updateEventDates(placeItem, addIncidence, saveCollection);
1265 d->mActionItem =
nullptr;
1266 d->mItemMoved =
false;
1269 d->mChanger->endAtomicOperation();
1273void Agenda::setActionCursor(
int actionType,
bool acting)
1276 switch (actionType) {
1298void Agenda::setNoActionCursor(
const AgendaItem::QPtr &moveItem, QPoint pos)
1302 const bool noResize = CalendarSupport::hasTodo(item);
1304 Agenda::MouseActionType resizeType = MOVE;
1306 resizeType = isInResizeArea(d->mAllDayMode,
pos, moveItem);
1308 setActionCursor(resizeType);
1313double Agenda::calcSubCellWidth(
const AgendaItem::QPtr &item)
1317 pt = gridToContents(QPoint(item->cellXLeft(), item->cellYTop()));
1318 pt1 = gridToContents(QPoint(item->cellXLeft(), item->cellYTop()) + QPoint(1, 1));
1320 int maxSubCells = item->subCells();
1321 double newSubCellWidth;
1322 if (d->mAllDayMode) {
1323 newSubCellWidth =
static_cast<double>(pt1.
y()) / maxSubCells;
1325 newSubCellWidth =
static_cast<double>(pt1.
x()) / maxSubCells;
1327 return newSubCellWidth;
1330void Agenda::adjustItemPosition(
const AgendaItem::QPtr &item)
1335 item->resize(
int(d->mGridSpacingX * item->cellWidth()),
int(d->mGridSpacingY * item->cellHeight()));
1336 int clXLeft = item->cellXLeft();
1338 clXLeft = item->cellXRight() + 1;
1340 QPoint cpos = gridToContents(QPoint(clXLeft, item->cellYTop()));
1341 item->move(cpos.
x(), cpos.
y());
1344void Agenda::placeAgendaItem(
const AgendaItem::QPtr &item,
double subCellWidth)
1348 QPoint pt = gridToContents(QPoint(item->cellXLeft(), item->cellYTop()));
1350 QPoint pt1 = gridToContents(QPoint(item->cellXLeft() + item->cellWidth(), item->cellYBottom() + 1));
1352 double subCellPos = item->subCell() * subCellWidth;
1356 double delta = 0.01;
1357 if (subCellWidth < 0) {
1364 if (d->mAllDayMode) {
1366 height = int(subCellPos + subCellWidth + delta) - int(subCellPos);
1368 ypos = pt.
y() + int(subCellPos);
1370 width = int(subCellPos + subCellWidth + delta) - int(subCellPos);
1372 xpos = pt.
x() + int(subCellPos);
1384 item->move(xpos, ypos);
1397void Agenda::placeSubCells(
const AgendaItem::QPtr &placeItem)
1400 qCDebug(CALENDARVIEW_LOG);
1404 qCDebug(CALENDARVIEW_LOG) <<
" event is 0";
1406 qCDebug(CALENDARVIEW_LOG) <<
" event:" <<
event->summary();
1409 qCDebug(CALENDARVIEW_LOG) <<
" placeItem is 0";
1411 qCDebug(CALENDARVIEW_LOG) <<
"Agenda::placeSubCells()...";
1414 QList<CalendarSupport::CellItem *> cells;
1415 for (CalendarSupport::CellItem *item : std::as_const(d->mItems)) {
1421 QList<CalendarSupport::CellItem *> items = CalendarSupport::CellItem::placeItem(cells, placeItem);
1423 placeItem->setConflictItems(QList<AgendaItem::QPtr>());
1424 double newSubCellWidth = calcSubCellWidth(placeItem);
1425 QList<CalendarSupport::CellItem *>::iterator it;
1426 for (it = items.
begin(); it != items.
end(); ++it) {
1428 AgendaItem::QPtr item =
static_cast<AgendaItem *
>(*it);
1429 placeAgendaItem(item, newSubCellWidth);
1430 item->addConflictItem(placeItem);
1431 placeItem->addConflictItem(item);
1435 placeAgendaItem(placeItem, newSubCellWidth);
1437 placeItem->update();
1440int Agenda::columnWidth(
int column)
const
1442 int start = gridToContents(QPoint(column, 0)).x();
1448 int end = gridToContents(QPoint(column, 0)).x();
1452void Agenda::paintEvent(QPaintEvent *)
1455 drawContents(&p, 0, -
y(), d->mGridSpacingX * d->mColumns, d->mGridSpacingY * d->mRows +
y());
1461void Agenda::drawContents(QPainter *p,
int cx,
int cy,
int cw,
int ch)
1471 if (!d->preferences()->useSystemColor()) {
1472 dbp.fillRect(0, 0, cw, ch, d->preferences()->agendaGridBackgroundColor());
1477 dbp.translate(-cx, -cy);
1479 double lGridSpacingY = d->mGridSpacingY * 2;
1485 const QList<bool> busyDayMask = d->mAgendaView->busyDayMask();
1488 if (d->mWorkingHoursEnable && d->mHolidayMask) {
1490 if (!d->preferences()->useSystemColor()) {
1491 workColor = d->preferences()->workingHoursColor();
1496 QPoint pt1(cx, d->mWorkingHoursYTop);
1497 QPoint pt2(cx + cw, d->mWorkingHoursYBottom);
1498 if (pt2.x() >= pt1.
x() ) {
1499 int gxStart = contentsToGrid(pt1).x();
1500 int gxEnd = contentsToGrid(pt2).x();
1502 if (gxStart > gxEnd) {
1508 while (gxStart <= gxEnd) {
1509 int xStart = gridToContents(QPoint(gxStart + xoffset, 0)).x();
1510 int xWidth = columnWidth(gxStart) + 1;
1512 if (pt2.y() < pt1.
y()) {
1514 if (((gxStart == 0) && !d->mHolidayMask->at(d->mHolidayMask->count() - 1))
1515 || ((gxStart > 0) && (gxStart <
int(d->mHolidayMask->count())) && (!d->mHolidayMask->at(gxStart - 1)))) {
1517 dbp.fillRect(xStart, cy, xWidth, pt2.y() - cy + 1, workColor);
1520 if ((gxStart <
int(d->mHolidayMask->count() - 1)) && (!d->mHolidayMask->at(gxStart))) {
1521 if (pt1.
y() < cy + ch - 1) {
1522 dbp.fillRect(xStart, pt1.
y(), xWidth, cy + ch - pt1.
y() + 1, workColor);
1528 if (gxStart <
int(d->mHolidayMask->count() - 1) && !d->mHolidayMask->at(gxStart)) {
1529 dbp.fillRect(xStart, pt1.
y(), xWidth, pt2.y() - pt1.
y() + 1, workColor);
1538 if (d->preferences()->colorAgendaBusyDays() && !d->mAllDayMode) {
1539 for (
int i = 0; i < busyDayMask.
count(); ++i) {
1540 if (busyDayMask[i]) {
1541 const QPoint pt1(cx + d->mGridSpacingX * i, 0);
1544 if (!d->preferences()->useSystemColor()) {
1545 busyColor = d->preferences()->viewBgBusyColor();
1548 if ((busyColor.
blue() + busyColor.
red() + busyColor.
green()) > (256 / 2 * 3)) {
1550 busyColor = busyColor.
lighter(140);
1553 busyColor = busyColor.
darker(140);
1556 busyColor.
setAlpha(EventViews::BUSY_BACKGROUND_ALPHA);
1557 dbp.fillRect(pt1.
x(), pt1.
y(), d->mGridSpacingX, cy + ch, busyColor);
1563 if (d->mHasSelection && d->mAgendaView->dateRangeSelectionEnabled()) {
1566 QColor highlightColor;
1567 if (!d->preferences()->useSystemColor()) {
1568 highlightColor = d->preferences()->agendaGridHighlightColor();
1573 if (d->mSelectionEndCell.x() > d->mSelectionStartCell.x()) {
1575 pt = gridToContents(d->mSelectionStartCell);
1576 pt1 = gridToContents(QPoint(d->mSelectionStartCell.x() + 1, d->mRows + 1));
1577 dbp.fillRect(QRect(pt, pt1), highlightColor);
1579 for (
int c = d->mSelectionStartCell.x() + 1; c < d->mSelectionEndCell.x(); ++c) {
1580 pt = gridToContents(QPoint(c, 0));
1581 pt1 = gridToContents(QPoint(c + 1, d->mRows + 1));
1582 dbp.fillRect(QRect(pt, pt1), highlightColor);
1585 pt = gridToContents(QPoint(d->mSelectionEndCell.x(), 0));
1586 pt1 = gridToContents(d->mSelectionEndCell + QPoint(1, 1));
1587 dbp.fillRect(QRect(pt, pt1), highlightColor);
1589 pt = gridToContents(d->mSelectionStartCell);
1590 pt1 = gridToContents(d->mSelectionEndCell + QPoint(1, 1));
1591 dbp.fillRect(QRect(pt, pt1), highlightColor);
1601 if (windowTextColor.
red() + windowTextColor.
green() + windowTextColor.
blue() < (256 / 2 * 3)) {
1603 hourPen = windowTextColor.
lighter(200);
1604 halfHourPen = windowTextColor.
lighter(500);
1607 hourPen = windowTextColor.
darker(150);
1608 halfHourPen = windowTextColor.
darker(200);
1611 dbp.setPen(hourPen);
1614 double x = (int(cx / d->mGridSpacingX)) * d->mGridSpacingX;
1615 while (
x < cx + cw) {
1616 dbp.drawLine(
int(
x), cy,
int(
x), cy + ch);
1617 x += d->mGridSpacingX;
1621 double y = (int(cy / (2 * lGridSpacingY))) * 2 * lGridSpacingY;
1622 while (
y < cy + ch) {
1623 dbp.drawLine(cx,
int(
y), cx + cw,
int(
y));
1624 y += 2 * lGridSpacingY;
1626 y = (2 * int(cy / (2 * lGridSpacingY)) + 1) * lGridSpacingY;
1627 dbp.setPen(halfHourPen);
1628 while (
y < cy + ch) {
1629 dbp.drawLine(cx,
int(
y), cx + cw,
int(
y));
1630 y += 2 * lGridSpacingY;
1638QPoint Agenda::contentsToGrid(QPoint pos)
const
1641 int gy = int(
pos.y() / d->mGridSpacingY);
1648QPoint Agenda::gridToContents(QPoint gpos)
const
1651 int y = int(gpos.
y() * d->mGridSpacingY);
1659int Agenda::timeToY(QTime time)
const
1661 int minutesPerCell = 24 * 60 / d->mRows;
1662 int timeMinutes = time.
hour() * 60 + time.
minute();
1663 int Y = (timeMinutes + (minutesPerCell / 2)) / minutesPerCell;
1672QTime Agenda::gyToTime(
int gy)
const
1674 int secondsPerCell = 24 * 60 * 60 / d->mRows;
1675 int timeSeconds = secondsPerCell * gy;
1677 QTime time(0, 0, 0);
1678 if (timeSeconds < 24 * 60 * 60) {
1679 time = time.
addSecs(timeSeconds);
1686QList<int> Agenda::minContentsY()
const
1688 QList<int> minArray;
1689 minArray.
fill(timeToY(QTime(23, 59)), d->mSelectedDates.count());
1690 for (
const AgendaItem::QPtr &item : std::as_const(d->mItems)) {
1692 int ymin = item->cellYTop();
1693 int index = item->cellXLeft();
1694 if (index >= 0 && index < (
int)(d->mSelectedDates.count())) {
1695 if (ymin < minArray[index] && !d->mItemsToDelete.contains(item)) {
1696 minArray[index] = ymin;
1705QList<int> Agenda::maxContentsY()
const
1707 QList<int> maxArray;
1708 maxArray.
fill(timeToY(QTime(0, 0)), d->mSelectedDates.count());
1709 for (
const AgendaItem::QPtr &item : std::as_const(d->mItems)) {
1711 int ymax = item->cellYBottom();
1713 int index = item->cellXLeft();
1714 if (index >= 0 && index < (
int)(d->mSelectedDates.count())) {
1715 if (ymax > maxArray[index] && !d->mItemsToDelete.contains(item)) {
1716 maxArray[index] = ymax;
1725void Agenda::setStartTime(QTime startHour)
1727 const double startPos = (startHour.
hour() / 24. + startHour.
minute() / 1440. + startHour.
second() / 86400.) * d->mRows * gridSpacingY();
1729 verticalScrollBar()->setValue(startPos);
1736 const QDateTime &recurrenceId,
1744 if (d->mAllDayMode) {
1745 qCDebug(CALENDARVIEW_LOG) <<
"using this in all-day mode is illegal.";
1749 d->mActionType = NOP;
1751 AgendaItem::QPtr agendaItem = createAgendaItem(incidence, itemPos, itemCount, recurrenceId, isSelected);
1756 if (YTop >= d->mRows) {
1757 YBottom -= YTop - (d->mRows - 1);
1758 YTop = d->mRows - 1;
1760 if (YBottom <= YTop) {
1761 qCDebug(CALENDARVIEW_LOG) <<
"Text:" << agendaItem->text() <<
" YSize<0";
1765 agendaItem->resize(
int((X + 1) * d->mGridSpacingX) -
int(X * d->mGridSpacingX),
int(YTop * d->mGridSpacingY) -
int((YBottom + 1) * d->mGridSpacingY));
1766 agendaItem->setCellXY(X, YTop, YBottom);
1767 agendaItem->setCellXRight(X);
1768 agendaItem->setResourceColor(d->mCalendar->resourceColor(incidence));
1769 agendaItem->installEventFilter(
this);
1771 agendaItem->move(
int(X * d->mGridSpacingX),
int(YTop * d->mGridSpacingY));
1773 d->mItems.append(agendaItem);
1775 placeSubCells(agendaItem);
1787AgendaItem::QPtr Agenda::insertAllDayItem(
const KCalendarCore::Incidence::Ptr &incidence,
const QDateTime &recurrenceId,
int XBegin,
int XEnd,
bool isSelected)
1789 if (!d->mAllDayMode) {
1790 qCCritical(CALENDARVIEW_LOG) <<
"using this in non all-day mode is illegal.";
1794 d->mActionType = NOP;
1796 AgendaItem::QPtr agendaItem = createAgendaItem(incidence, 1, 1, recurrenceId, isSelected);
1801 agendaItem->setCellXY(XBegin, 0, 0);
1802 agendaItem->setCellXRight(XEnd);
1804 const double startIt = d->mGridSpacingX * (agendaItem->cellXLeft());
1805 const double endIt = d->mGridSpacingX * (agendaItem->cellWidth() + agendaItem->cellXLeft());
1807 agendaItem->resize(
int(endIt) -
int(startIt),
int(d->mGridSpacingY));
1809 agendaItem->installEventFilter(
this);
1810 agendaItem->setResourceColor(d->mCalendar->resourceColor(incidence));
1811 agendaItem->move(
int(XBegin * d->mGridSpacingX), 0);
1812 d->mItems.append(agendaItem);
1814 placeSubCells(agendaItem);
1822Agenda::createAgendaItem(
const KCalendarCore::Incidence::Ptr &incidence,
int itemPos,
int itemCount,
const QDateTime &recurrenceId,
bool isSelected)
1825 qCWarning(CALENDARVIEW_LOG) <<
"Agenda::createAgendaItem() item is invalid.";
1829 AgendaItem::QPtr agendaItem =
new AgendaItem(d->mAgendaView, d->mCalendar, incidence, itemPos, itemCount, recurrenceId, isSelected,
this);
1831 connect(agendaItem.
data(), &AgendaItem::removeAgendaItem,
this, &Agenda::removeAgendaItem);
1832 connect(agendaItem.
data(), &AgendaItem::showAgendaItem,
this, &Agenda::showAgendaItem);
1834 d->mAgendaItemsById.insert(
incidence->uid(), agendaItem);
1840 const QDateTime &recurrenceId,
1849 if (d->mAllDayMode) {
1850 qCDebug(CALENDARVIEW_LOG) <<
"using this in all-day mode is illegal.";
1854 d->mActionType = NOP;
1859 int width = XEnd - XBegin + 1;
1861 AgendaItem::QPtr current =
nullptr;
1862 QList<AgendaItem::QPtr> multiItems;
1863 int visibleCount = d->mSelectedDates.first().daysTo(d->mSelectedDates.last());
1864 for (cellX = XBegin; cellX <= XEnd; ++cellX) {
1867 if (cellX >= 0 && cellX <= visibleCount) {
1868 if (cellX == XBegin) {
1873 if (cellX == XEnd) {
1874 cellYBottom = YBottom;
1876 cellYBottom = rows() - 1;
1878 newtext = QStringLiteral(
"(%1/%2): ").
arg(count).
arg(
width);
1879 newtext.
append(ev->summary());
1881 current = insertItem(
event, recurrenceId, cellX, cellYTop, cellYBottom, count,
width, isSelected);
1883 current->setText(newtext);
1884 multiItems.
append(current);
1888 QList<AgendaItem::QPtr>::iterator it = multiItems.
begin();
1889 QList<AgendaItem::QPtr>::iterator e = multiItems.
end();
1892 AgendaItem::QPtr first = multiItems.
first();
1893 AgendaItem::QPtr last = multiItems.
last();
1894 AgendaItem::QPtr prev =
nullptr;
1895 AgendaItem::QPtr
next =
nullptr;
1898 AgendaItem::QPtr item = *it;
1900 next = (it == e) ?
nullptr : (*it);
1902 item->setMultiItem((item == first) ?
nullptr : first, prev, next, (item == last) ?
nullptr : last);
1914 qCWarning(CALENDARVIEW_LOG) <<
"Agenda::removeIncidence() incidence is invalid" <<
incidence->uid();
1918 if (d->isQueuedForDeletion(
incidence->uid())) {
1922 const AgendaItem::List agendaItems = d->mAgendaItemsById.values(
incidence->uid());
1923 if (agendaItems.isEmpty()) {
1928 for (
const AgendaItem::QPtr &agendaItem : agendaItems) {
1930 if (
incidence->instanceIdentifier() != agendaItem->incidence()->instanceIdentifier()) {
1933 if (!removeAgendaItem(agendaItem)) {
1934 qCWarning(CALENDARVIEW_LOG) <<
"Agenda::removeIncidence() Failed to remove " <<
incidence->uid();
1940void Agenda::showAgendaItem(
const AgendaItem::QPtr &agendaItem)
1943 qCCritical(CALENDARVIEW_LOG) <<
"Show what?";
1949 agendaItem->setParent(
this);
1951 if (!d->mItems.contains(agendaItem)) {
1952 d->mItems.append(agendaItem);
1954 placeSubCells(agendaItem);
1959bool Agenda::removeAgendaItem(
const AgendaItem::QPtr &agendaItem)
1961 Q_ASSERT(agendaItem);
1963 QList<AgendaItem::QPtr> conflictItems = agendaItem->conflictItems();
1966 bool taken = d->mItems.removeAll(agendaItem) > 0;
1967 d->mAgendaItemsById.remove(agendaItem->incidence()->uid(), agendaItem);
1969 QList<AgendaItem::QPtr>::iterator it;
1970 for (it = conflictItems.
begin(); it != conflictItems.
end(); ++it) {
1972 (*it)->setSubCells((*it)->subCells() - 1);
1976 for (it = conflictItems.
begin(); it != conflictItems.
end(); ++it) {
1978 if (*it && *it != agendaItem) {
1982 d->mItemsToDelete.append(agendaItem);
1983 d->mItemsQueuedForDeletion.insert(agendaItem->incidence()->uid());
1984 agendaItem->setVisible(
false);
1989void Agenda::deleteItemsToDelete()
1991 qDeleteAll(d->mItemsToDelete);
1992 d->mItemsToDelete.clear();
1993 d->mItemsQueuedForDeletion.clear();
2013void Agenda::resizeEvent(QResizeEvent *ev)
2015 QSize newSize(ev->
size());
2017 if (d->mAllDayMode) {
2018 d->mGridSpacingX =
static_cast<double>(newSize.width()) / d->mColumns;
2019 d->mGridSpacingY = newSize.height();
2021 d->mGridSpacingX =
static_cast<double>(newSize.width()) / d->mColumns;
2023 d->mGridSpacingY =
static_cast<double>(newSize.height()) / d->mRows;
2024 if (d->mGridSpacingY < d->mDesiredGridSpacingY) {
2025 d->mGridSpacingY = d->mDesiredGridSpacingY;
2028 calculateWorkingHours();
2031 Q_EMIT gridSpacingYChanged(d->mGridSpacingY * 4);
2037void Agenda::resizeAllContents()
2039 double subCellWidth;
2040 for (
const AgendaItem::QPtr &item : std::as_const(d->mItems)) {
2042 subCellWidth = calcSubCellWidth(item);
2043 placeAgendaItem(item, subCellWidth);
2063 checkScrollBoundaries();
2068void Agenda::scrollUp()
2070 int currentValue = verticalScrollBar()->value();
2071 verticalScrollBar()->setValue(currentValue - d->mScrollOffset);
2074void Agenda::scrollDown()
2076 int currentValue = verticalScrollBar()->value();
2077 verticalScrollBar()->setValue(currentValue + d->mScrollOffset);
2080QSize Agenda::minimumSize()
const
2085QSize Agenda::minimumSizeHint()
const
2090int Agenda::minimumHeight()
const
2095 if (d->mAllDayMode) {
2098 return d->mGridSpacingY * d->mRows;
2102void Agenda::updateConfig()
2104 const double oldGridSpacingY = d->mGridSpacingY;
2106 if (!d->mAllDayMode) {
2107 d->mDesiredGridSpacingY = d->preferences()->hourSize();
2108 if (d->mDesiredGridSpacingY < 4 || d->mDesiredGridSpacingY > 30) {
2109 d->mDesiredGridSpacingY = 10;
2121 if (fabs(oldGridSpacingY - d->mDesiredGridSpacingY) > 0.1) {
2122 d->mGridSpacingY = d->mDesiredGridSpacingY;
2127 calculateWorkingHours();
2132void Agenda::checkScrollBoundaries()
2135 d->mOldLowerScrollValue = -1;
2136 d->mOldUpperScrollValue = -1;
2138 checkScrollBoundaries(verticalScrollBar()->value());
2141void Agenda::checkScrollBoundaries(
int v)
2143 int yMin = int((v) / d->mGridSpacingY);
2144 int yMax = int((v + d->mScrollArea->height()) / d->mGridSpacingY);
2146 if (yMin != d->mOldLowerScrollValue) {
2147 d->mOldLowerScrollValue = yMin;
2148 Q_EMIT lowerYChanged(yMin);
2150 if (yMax != d->mOldUpperScrollValue) {
2151 d->mOldUpperScrollValue = yMax;
2152 Q_EMIT upperYChanged(yMax);
2156int Agenda::visibleContentsYMin()
const
2158 int v = verticalScrollBar()->value();
2159 return int(v / d->mGridSpacingY);
2162int Agenda::visibleContentsYMax()
const
2164 int v = verticalScrollBar()->value();
2165 return int((v + d->mScrollArea->height()) / d->mGridSpacingY);
2168void Agenda::deselectItem()
2170 if (d->mSelectedItem.isNull()) {
2176 for (AgendaItem::QPtr item : std::as_const(d->mItems)) {
2179 if (itemInc && selectedItem && itemInc->uid() == selectedItem->uid()) {
2180 item->select(
false);
2185 d->mSelectedItem =
nullptr;
2188void Agenda::selectItem(
const AgendaItem::QPtr &item)
2190 if ((AgendaItem::QPtr)d->mSelectedItem == item) {
2194 if (item ==
nullptr) {
2198 d->mSelectedItem = item;
2199 d->mSelectedItem->select();
2200 Q_ASSERT(d->mSelectedItem->incidence());
2201 d->mSelectedId = d->mSelectedItem->incidence()->uid();
2203 for (AgendaItem::QPtr item : std::as_const(d->mItems)) {
2204 if (item && item->incidence()->uid() == d->mSelectedId) {
2208 Q_EMIT incidenceSelected(d->mSelectedItem->incidence(), d->mSelectedItem->occurrenceDate());
2211void Agenda::selectIncidenceByUid(
const QString &uid)
2213 for (
const AgendaItem::QPtr &item : std::as_const(d->mItems)) {
2214 if (item && item->incidence()->uid() == uid) {
2221void Agenda::selectItem(
const Akonadi::Item &item)
2227void Agenda::keyPressEvent(QKeyEvent *kev)
2229 switch (kev->
key()) {
2246void Agenda::calculateWorkingHours()
2248 d->mWorkingHoursEnable = !d->mAllDayMode;
2250 QTime tmp = d->preferences()->workingHoursStart().time();
2251 d->mWorkingHoursYTop = int(4 * d->mGridSpacingY * (tmp.
hour() + tmp.
minute() / 60. + tmp.
second() / 3600.));
2252 tmp = d->preferences()->workingHoursEnd().time();
2253 d->mWorkingHoursYBottom = int(4 * d->mGridSpacingY * (tmp.
hour() + tmp.
minute() / 60. + tmp.
second() / 3600.) - 1);
2258 d->mSelectedDates = selectedDates;
2264 return d->mSelectedDates;
2267void Agenda::setCalendar(
const MultiViewCalendar::Ptr &cal)
2272void Agenda::setIncidenceChanger(Akonadi::IncidenceChanger *changer)
2274 d->mChanger = changer;
2277void Agenda::setHolidayMask(QList<bool> *mask)
2279 d->mHolidayMask =
mask;
2282void Agenda::contentsMousePressEvent(QMouseEvent *event)
2287QSize Agenda::sizeHint()
const
2289 if (d->mAllDayMode) {
2292 return {
parentWidget()->
width(),
static_cast<int>(d->mGridSpacingY * d->mRows)};
2296QScrollBar *Agenda::verticalScrollBar()
const
2298 return d->mScrollArea->verticalScrollBar();
2301QScrollArea *Agenda::scrollArea()
const
2303 return d->mScrollArea;
2306AgendaItem::List Agenda::agendaItems(
const QString &uid)
const
2308 return d->mAgendaItemsById.values(uid);
2311AgendaScrollArea::AgendaScrollArea(
bool isAllDay,
AgendaView *agendaView,
bool isInteractive, QWidget *parent)
2312 : QScrollArea(parent)
2315 mAgenda =
new Agenda(agendaView,
this, 1, isInteractive);
2318 mAgenda =
new Agenda(agendaView,
this, 1, 96, agendaView->preferences()->hourSize(), isInteractive);
2321 setWidgetResizable(
true);
2325 mAgenda->setStartTime(agendaView->preferences()->dayBegins().time());
2328AgendaScrollArea::~AgendaScrollArea() =
default;
2330Agenda *AgendaScrollArea::agenda()
const
2335#include "moc_agenda.cpp"
Collection & parentCollection()
Collection::Id storageCollectionId() const
AgendaView is the agenda-like view that displays events in a single or multi-day view.
EventView is the abstract base class from which all other calendar views for event data are derived.
QSharedPointer< Calendar > Ptr
static Incidence::Ptr createException(const Incidence::Ptr &incidence, const QDateTime &recurrenceId, bool thisAndFuture=false)
QSharedPointer< Event > Ptr
QSharedPointer< Incidence > Ptr
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)
char * toString(const EngineQuery &query)
Namespace EventViews provides facilities for displaying incidences, including events,...
void information(QWidget *parent, const QString &text, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
const QList< QKeySequence > & next()
const QList< QKeySequence > & end()
const QList< QKeySequence > & preferences()
void valueChanged(int value)
QColor darker(int factor) const const
QColor lighter(int factor) const const
bool sendEvent(QObject *receiver, QEvent *event)
QDateTime currentDateTime()
const QMimeData * mimeData() const const
QPointF position() const const
void setDropAction(Qt::DropAction action)
void setFrameStyle(int style)
void append(QList< T > &&value)
qsizetype count() const const
QList< T > & fill(parameter_type value, qsizetype size)
bool isEmpty() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool eventFilter(QObject *watched, QEvent *event)
void installEventFilter(QObject *filterObj)
T qobject_cast(QObject *object)
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
void setColor(ColorGroup group, ColorRole role, const QColor &color)
QPoint toPoint() const const
const QSize & size() const const
QPointF position() const const
QString & append(QChar ch)
QString arg(Args &&... args) const const
QString number(double n, char format, int precision)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QTime addSecs(int s) const const
bool setHMS(int h, int m, int s, int ms)
QPoint angleDelta() const const