Warning, file /pim/kalarm/src/daymatrix.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * daymatrix.cpp - calendar day matrix display 0003 * Program: kalarm 0004 * This class is adapted from KODayMatrix in KOrganizer. 0005 * 0006 * SPDX-FileCopyrightText: 2001 Eitzenberger Thomas <thomas.eitzenberger@siemens.at> 0007 * Parts of the source code have been copied from kdpdatebutton.cpp 0008 * 0009 * SPDX-FileCopyrightText: 2003 Cornelius Schumacher <schumacher@kde.org> 0010 * SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> 0011 * SPDX-FileCopyrightText: 2021-2023 David Jarvie <djarvie@kde.org> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0014 */ 0015 0016 #include "daymatrix.h" 0017 0018 #include "newalarmaction.h" 0019 #include "preferences.h" 0020 #include "resources/resources.h" 0021 #include "kalarmcalendar/holidays.h" 0022 0023 #include <KLocalizedString> 0024 0025 #include <QMenu> 0026 #include <QApplication> 0027 #include <QMouseEvent> 0028 #include <QPainter> 0029 #include <QToolTip> 0030 0031 #include <cmath> 0032 0033 namespace 0034 { 0035 const int NUMROWS = 6; // number of rows displayed in the matrix 0036 const int NUMDAYS = NUMROWS * 7; // number of days displayed in the matrix 0037 const int NO_SELECTION = -1000000; // invalid selection start/end value 0038 0039 const QColor HOLIDAY_BACKGROUND_COLOUR(255,100,100); // add a preference for this? 0040 const int TODAY_MARGIN_WIDTH(2); 0041 0042 struct TextColours 0043 { 0044 QColor disabled; 0045 QColor thisMonth; 0046 QColor otherMonth; 0047 QColor thisMonthHoliday {HOLIDAY_BACKGROUND_COLOUR}; 0048 QColor otherMonthHoliday; 0049 0050 explicit TextColours(const QPalette& palette); 0051 0052 private: 0053 QColor getShadedColour(const QColor& colour, bool enabled) const; 0054 }; 0055 } 0056 0057 DayMatrix::DayMatrix(QWidget* parent) 0058 : QFrame(parent) 0059 , mDayLabels(NUMDAYS) 0060 , mSelStart(NO_SELECTION) 0061 , mSelEnd(NO_SELECTION) 0062 { 0063 mHolidays.reserve(NUMDAYS); 0064 for (int i = 0; i < NUMDAYS; ++i) 0065 mHolidays.append(QString()); 0066 0067 Resources* resources = Resources::instance(); 0068 connect(resources, &Resources::resourceAdded, this, &DayMatrix::resourceUpdated); 0069 connect(resources, &Resources::resourceRemoved, this, &DayMatrix::resourceRemoved); 0070 connect(resources, &Resources::settingsChanged, this, &DayMatrix::resourceSettingsChanged); 0071 connect(resources, &Resources::eventsAdded, this, &DayMatrix::resourceUpdated); 0072 connect(resources, &Resources::eventUpdated, this, &DayMatrix::resourceUpdated); 0073 connect(resources, &Resources::eventsRemoved, this, &DayMatrix::resourceUpdated); 0074 Preferences::connect(&Preferences::holidaysChanged, this, &DayMatrix::slotUpdateView); 0075 Preferences::connect(&Preferences::workTimeChanged, this, &DayMatrix::slotUpdateView); 0076 } 0077 0078 DayMatrix::~DayMatrix() 0079 { 0080 } 0081 0082 /****************************************************************************** 0083 * Return all selected dates from mSelStart to mSelEnd, in date order. 0084 */ 0085 QList<QDate> DayMatrix::selectedDates() const 0086 { 0087 QList<QDate> selDays; 0088 if (mSelStart != NO_SELECTION) 0089 { 0090 selDays.reserve(mSelEnd - mSelStart + 1); 0091 for (int i = mSelStart; i <= mSelEnd; ++i) 0092 selDays.append(mStartDate.addDays(i)); 0093 } 0094 return selDays; 0095 } 0096 0097 /****************************************************************************** 0098 * Clear the current selection of dates. 0099 */ 0100 void DayMatrix::clearSelection() 0101 { 0102 setMouseSelection(NO_SELECTION, NO_SELECTION, true); 0103 } 0104 0105 /****************************************************************************** 0106 * Evaluate the index for today, and update the display if it has changed. 0107 */ 0108 void DayMatrix::updateToday(const QDate& newDate) 0109 { 0110 const int index = mStartDate.daysTo(newDate); 0111 if (index != mTodayIndex) 0112 { 0113 mTodayIndex = index; 0114 updateEvents(); 0115 0116 if (mSelStart != NO_SELECTION && mSelStart < mTodayIndex) 0117 { 0118 if (mSelEnd < mTodayIndex) 0119 setMouseSelection(NO_SELECTION, NO_SELECTION, true); 0120 else 0121 setMouseSelection(mTodayIndex, mSelEnd, true); 0122 } 0123 else 0124 update(); 0125 } 0126 } 0127 0128 /****************************************************************************** 0129 * Set a new start date for the matrix. If changed, or other changes are 0130 * pending, recalculates which days in the matrix alarms occur on, and which are 0131 * holidays/non-work days, and repaints. 0132 */ 0133 void DayMatrix::setStartDate(const QDate& startDate) 0134 { 0135 if (!startDate.isValid()) 0136 return; 0137 0138 if (startDate != mStartDate) 0139 { 0140 if (mSelStart != NO_SELECTION) 0141 { 0142 // Adjust selection indexes to be relative to the new start date. 0143 const int diff = startDate.daysTo(mStartDate); 0144 mSelStart += diff; 0145 mSelEnd += diff; 0146 if (mSelectionMustBeVisible) 0147 { 0148 // Ensure that the whole selection is still visible: if not, cancel the selection. 0149 if (mSelStart < 0 || mSelEnd >= NUMDAYS) 0150 setMouseSelection(NO_SELECTION, NO_SELECTION, true); 0151 } 0152 } 0153 0154 mStartDate = startDate; 0155 0156 QLocale locale; 0157 mMonthStartIndex = -1; 0158 mMonthEndIndex = NUMDAYS-1; 0159 for (int i = 0; i < NUMDAYS; ++i) 0160 { 0161 const int day = mStartDate.addDays(i).day(); 0162 mDayLabels[i] = locale.toString(day); 0163 0164 if (day == 1) // start of a month 0165 { 0166 if (mMonthStartIndex < 0) 0167 mMonthStartIndex = i; 0168 else 0169 mMonthEndIndex = i - 1; 0170 } 0171 } 0172 0173 mTodayIndex = mStartDate.daysTo(KADateTime::currentDateTime(Preferences::timeSpec()).date()); 0174 updateView(); 0175 } 0176 else if (mPendingChanges) 0177 updateView(); 0178 } 0179 0180 /****************************************************************************** 0181 * If changes are pending, recalculate which days in the matrix have alarms 0182 * occurring, and which are holidays/non-work days. Repaint the matrix. 0183 */ 0184 void DayMatrix::updateView(const Resource& resource) 0185 { 0186 if (!mStartDate.isValid()) 0187 return; 0188 0189 // TODO_Recurrence: If we just change the selection, but not the data, 0190 // there's no need to update the whole list of alarms... This is just a 0191 // waste of computational power 0192 updateEvents(resource); 0193 0194 // Find which holidays occur for the dates in the matrix. 0195 const KAlarmCal::Holidays& holidays = Preferences::holidays(); 0196 for (int i = 0; i < NUMDAYS; ++i) 0197 { 0198 const QStringList names = holidays.holidayNames(mStartDate.addDays(i)); 0199 if (!names.isEmpty()) 0200 mHolidays[i] = names.join(i18nc("delimiter for joining holiday names", ",")); 0201 else 0202 mHolidays[i].clear(); 0203 } 0204 0205 update(); 0206 } 0207 0208 /****************************************************************************** 0209 * Find which days currently displayed have alarms scheduled, for all active 0210 * resources. 0211 */ 0212 void DayMatrix::updateEvents(const Resource& resource) 0213 { 0214 const QDate startDate = (mTodayIndex <= 0) ? mStartDate : mStartDate.addDays(mTodayIndex); 0215 const KADateTime before = KADateTime(startDate, QTime(0,0,0), Preferences::timeSpec()).addSecs(-60); 0216 const KADateTime to(mStartDate.addDays(NUMDAYS-1), QTime(23,59,0), Preferences::timeSpec()); 0217 0218 mEventDates.clear(); 0219 const QList<Resource> resources = Resources::enabledResources(CalEvent::ACTIVE); 0220 for (const Resource& res : resources) 0221 { 0222 if (!resource.isValid() || res.id() == resource.id()) 0223 updateEvents(res, before, to); 0224 if (mEventDates.count() < NUMDAYS) 0225 mEventDates |= mResourceEventDates[res.id()]; 0226 } 0227 0228 mPendingChanges = false; 0229 } 0230 0231 /****************************************************************************** 0232 * Find which days currently displayed have alarms scheduled for a resource. 0233 */ 0234 void DayMatrix::updateEvents(const Resource& resource, const KADateTime& before, const KADateTime& to) 0235 { 0236 ResourceId id = resource.id(); 0237 const KADateTime::Spec timeSpec = Preferences::timeSpec(); 0238 0239 mResourceEventDates[id].clear(); 0240 const QList<KAEvent> events = resource.events(); 0241 const CalEvent::Types types = resource.enabledTypes() & CalEvent::ACTIVE; 0242 for (const KAEvent& event : events) 0243 { 0244 if (event.enabled() && (event.category() & types)) 0245 { 0246 // The event has an enabled alarm type. 0247 // Find all its recurrences/repetitions within the time period. 0248 DateTime nextDt; 0249 for (KADateTime from = before; ; ) 0250 { 0251 event.nextOccurrence(from, nextDt, KAEvent::Repeats::Return); 0252 if (!nextDt.isValid()) 0253 break; 0254 from = nextDt.effectiveKDateTime().toTimeSpec(timeSpec); 0255 if (from > to) 0256 break; 0257 if (!event.excludedByWorkTimeOrHoliday(from)) 0258 { 0259 mResourceEventDates[id] += from.date(); 0260 if (mResourceEventDates[id].count() >= NUMDAYS) 0261 break; // all days have alarms due 0262 } 0263 0264 // If the alarm recurs more than once per day, don't waste 0265 // time checking any more occurrences for the same day. 0266 from.setTime(QTime(23,59,0)); 0267 } 0268 if (mResourceEventDates[id].count() >= NUMDAYS) 0269 break; // all days have alarms due 0270 } 0271 } 0272 } 0273 0274 /****************************************************************************** 0275 * Return the holiday description (if any) for a date. 0276 */ 0277 QString DayMatrix::getHolidayLabel(int offset) const 0278 { 0279 if (offset < 0 || offset > NUMDAYS - 1) 0280 return {}; 0281 return mHolidays[offset]; 0282 } 0283 0284 /****************************************************************************** 0285 * Determine the day index at a geometric position. 0286 * Return = NO_SELECTION if outside the widget, or if the date is earlier than today. 0287 */ 0288 int DayMatrix::getDayIndex(const QPoint& pt) const 0289 { 0290 const int x = pt.x(); 0291 const int y = pt.y(); 0292 if (x < 0 || y < 0 || x > width() || y > height()) 0293 return NO_SELECTION; 0294 const int xd = static_cast<int>(x / mDaySize.width()); 0295 const int i = 7 * int(y / mDaySize.height()) 0296 + (QApplication::isRightToLeft() ? 6 - xd : xd); 0297 if (i < mTodayIndex || i > NUMDAYS-1) 0298 return NO_SELECTION; 0299 return i; 0300 } 0301 0302 void DayMatrix::setRowHeight(int rowHeight) 0303 { 0304 mRowHeight = rowHeight; 0305 setMinimumSize(minimumWidth(), mRowHeight * NUMROWS + TODAY_MARGIN_WIDTH*2); 0306 } 0307 0308 /****************************************************************************** 0309 * Called when the events in a resource have been updated. 0310 * Re-evaluate all events in the resource. 0311 */ 0312 void DayMatrix::resourceUpdated(Resource& resource) 0313 { 0314 mPendingChanges = true; 0315 updateView(resource); 0316 } 0317 0318 /****************************************************************************** 0319 * Called when a resource has been removed. 0320 * Remove all its events from the view. 0321 */ 0322 void DayMatrix::resourceRemoved(ResourceId id) 0323 { 0324 mPendingChanges = true; 0325 updateView(Resources::resource(id)); 0326 } 0327 0328 /****************************************************************************** 0329 * Called when a resource's settings have been changed. 0330 * If it has been disabled, remove all its events from the view. 0331 */ 0332 void DayMatrix::resourceSettingsChanged(Resource& resource, ResourceType::Changes changes) 0333 { 0334 if (changes == ResourceType::Enabled) 0335 { 0336 if (!resource.isEnabled(CalEvent::ACTIVE)) 0337 { 0338 // Active events are now disabled for the resource. 0339 mPendingChanges = true; 0340 updateView(resource); 0341 } 0342 // else if active events are now enabled, they will be added by eventsAdded() 0343 } 0344 } 0345 0346 /****************************************************************************** 0347 * Called when the holiday or work time settings have changed. 0348 * Re-evaluate all events in the view. 0349 */ 0350 void DayMatrix::slotUpdateView() 0351 { 0352 mPendingChanges = true; 0353 updateView(); 0354 Q_EMIT selected(mLastSelectedDates, true); 0355 } 0356 0357 // ---------------------------------------------------------------------------- 0358 // M O U S E E V E N T H A N D L I N G 0359 // ---------------------------------------------------------------------------- 0360 0361 bool DayMatrix::event(QEvent* event) 0362 { 0363 if (event->type() == QEvent::ToolTip) 0364 { 0365 // Tooltip event: show the holiday name. 0366 auto* helpEvent = static_cast<QHelpEvent*>(event); 0367 const int i = getDayIndex(helpEvent->pos()); 0368 const QString tipText = getHolidayLabel(i); 0369 if (!tipText.isEmpty()) 0370 QToolTip::showText(helpEvent->globalPos(), tipText); 0371 else 0372 QToolTip::hideText(); 0373 } 0374 return QWidget::event(event); 0375 } 0376 0377 void DayMatrix::mousePressEvent(QMouseEvent* e) 0378 { 0379 int i = getDayIndex(e->pos()); 0380 if (i < 0) 0381 { 0382 mSelInit = NO_SELECTION; // invalid: it's not in the matrix or it's before today 0383 setMouseSelection(NO_SELECTION, NO_SELECTION, true); 0384 return; 0385 } 0386 if (e->button() == Qt::RightButton) 0387 { 0388 if (i < mSelStart || i > mSelEnd) 0389 setMouseSelection(i, i, true); 0390 popupMenu(e->globalPosition().toPoint()); 0391 } 0392 else if (e->button() == Qt::LeftButton) 0393 { 0394 if (i >= mSelStart && i <= mSelEnd) 0395 { 0396 mSelInit = NO_SELECTION; // already selected: cancel the current selection 0397 setMouseSelection(NO_SELECTION, NO_SELECTION, true); 0398 return; 0399 } 0400 mSelInit = i; 0401 setMouseSelection(i, i, false); // don't emit signal until mouse move has completed 0402 } 0403 } 0404 0405 void DayMatrix::popupMenu(const QPoint& pos) 0406 { 0407 NewAlarmAction newAction(false, QString(), nullptr); 0408 QMenu* popup = newAction.menu(); 0409 connect(&newAction, &NewAlarmAction::selected, this, &DayMatrix::newAlarm); 0410 connect(&newAction, &NewAlarmAction::selectedTemplate, this, &DayMatrix::newAlarmFromTemplate); 0411 popup->exec(pos); 0412 } 0413 0414 void DayMatrix::mouseReleaseEvent(QMouseEvent* e) 0415 { 0416 if (e->button() != Qt::LeftButton) 0417 return; 0418 0419 if (mSelInit < 0) 0420 return; 0421 int i = getDayIndex(e->pos()); 0422 if (i < 0) 0423 { 0424 // Emit signal after move (without changing the selection). 0425 setMouseSelection(mSelStart, mSelEnd, true); 0426 return; 0427 } 0428 0429 setMouseSelection(mSelInit, i, true); 0430 } 0431 0432 void DayMatrix::mouseMoveEvent(QMouseEvent* e) 0433 { 0434 if (mSelInit < 0) 0435 return; 0436 int i = getDayIndex(e->pos()); 0437 setMouseSelection(mSelInit, i, false); // don't emit signal until mouse move has completed 0438 } 0439 0440 /****************************************************************************** 0441 * Set the current day selection, and update the display. 0442 * Note that the selection may extend past the end of the current matrix. 0443 */ 0444 void DayMatrix::setMouseSelection(int start, int end, bool emitSignal) 0445 { 0446 if (!mAllowMultipleSelection) 0447 start = end; 0448 if (end < start) 0449 std::swap(start, end); 0450 if (start != mSelStart || end != mSelEnd) 0451 { 0452 mSelStart = start; 0453 mSelEnd = end; 0454 if (mSelStart < 0 || mSelEnd < 0) 0455 mSelStart = mSelEnd = NO_SELECTION; 0456 update(); 0457 } 0458 0459 if (emitSignal) 0460 { 0461 const QList<QDate> dates = selectedDates(); 0462 if (dates != mLastSelectedDates) 0463 { 0464 mLastSelectedDates = dates; 0465 Q_EMIT selected(dates, false); 0466 } 0467 } 0468 } 0469 0470 /****************************************************************************** 0471 * Called to paint the widget. 0472 */ 0473 void DayMatrix::paintEvent(QPaintEvent*) 0474 { 0475 QPainter p; 0476 const QRect rect = frameRect(); 0477 const double dayHeight = mDaySize.height(); 0478 const double dayWidth = mDaySize.width(); 0479 const bool isRTL = QApplication::isRightToLeft(); 0480 0481 const QPalette pal = palette(); 0482 0483 p.begin(this); 0484 0485 // Draw the background 0486 p.fillRect(0, 0, rect.width(), rect.height(), QBrush(pal.color(QPalette::Base))); 0487 0488 // Draw the frame 0489 p.setPen(pal.color(QPalette::Mid)); 0490 p.drawRect(0, 0, rect.width() - 1, rect.height() - 1); 0491 p.translate(1, 1); // don't paint over borders 0492 0493 // Draw the background colour for all days not in the selected month. 0494 const QColor GREY_COLOUR(pal.color(QPalette::AlternateBase)); 0495 if (mMonthStartIndex >= 0) 0496 colourBackground(p, GREY_COLOUR, 0, mMonthStartIndex - 1); 0497 colourBackground(p, GREY_COLOUR, mMonthEndIndex + 1, NUMDAYS - 1); 0498 0499 // Draw the background colour for all selected days. 0500 if (mSelStart != NO_SELECTION) 0501 { 0502 const QColor SELECTION_COLOUR(pal.color(QPalette::Highlight)); 0503 colourBackground(p, SELECTION_COLOUR, mSelStart, mSelEnd); 0504 } 0505 0506 // Find holidays which are non-work days. 0507 QSet<QDate> nonWorkHolidays; 0508 { 0509 const KAlarmCal::Holidays& holidays = Preferences::holidays(); 0510 for (int i = 0; i < NUMDAYS; ++i) 0511 { 0512 const QDate date = mStartDate.addDays(i); 0513 if (holidays.isHoliday(date)) 0514 nonWorkHolidays += date; 0515 } 0516 } 0517 const QBitArray workDays = Preferences::workDays(); 0518 0519 // Draw the day label for each day in the matrix. 0520 TextColours textColours(pal); 0521 const QFont savedFont = font(); 0522 QColor lastColour; 0523 for (int i = 0; i < NUMDAYS; ++i) 0524 { 0525 const int row = i / 7; 0526 const int column = isRTL ? 6 - (i - row * 7) : i - row * 7; 0527 0528 const bool nonWorkDay = (i >= mTodayIndex) && (!workDays[mStartDate.addDays(i).dayOfWeek()-1] || nonWorkHolidays.contains(mStartDate.addDays(i))); 0529 0530 const QColor colour = textColour(textColours, pal, i, !nonWorkDay); 0531 if (colour != lastColour) 0532 { 0533 lastColour = colour; 0534 p.setPen(colour); 0535 } 0536 0537 if (mTodayIndex == i) 0538 { 0539 // Draw a rectangle round today. 0540 const QPen savedPen = p.pen(); 0541 QPen todayPen = savedPen; 0542 todayPen.setWidth(TODAY_MARGIN_WIDTH); 0543 p.setPen(todayPen); 0544 p.drawRect(QRectF(column * dayWidth, row * dayHeight, dayWidth, dayHeight)); 0545 p.setPen(savedPen); 0546 } 0547 0548 // If any events occur on the day, draw it in bold 0549 const bool hasEvent = mEventDates.contains(mStartDate.addDays(i)); 0550 if (hasEvent) 0551 { 0552 QFont evFont = savedFont; 0553 evFont.setWeight(QFont::Black); 0554 evFont.setPointSize(evFont.pointSize() + 1); 0555 evFont.setStretch(110); 0556 p.setFont(evFont); 0557 } 0558 0559 p.drawText(QRectF(column * dayWidth, row * dayHeight, dayWidth, dayHeight), 0560 Qt::AlignHCenter | Qt::AlignVCenter, mDayLabels.at(i)); 0561 0562 if (hasEvent) 0563 p.setFont(savedFont); // restore normal font 0564 } 0565 p.end(); 0566 } 0567 0568 /****************************************************************************** 0569 * Paint a background colour for a range of days. 0570 */ 0571 void DayMatrix::colourBackground(QPainter& p, const QColor& colour, int start, int end) 0572 { 0573 if (end < 0) 0574 return; 0575 if (start < 0) 0576 start = 0; 0577 const int row = start / 7; 0578 if (row >= NUMROWS) 0579 return; 0580 const int column = start - row * 7; 0581 0582 const double dayHeight = mDaySize.height(); 0583 const double dayWidth = mDaySize.width(); 0584 const bool isRTL = QApplication::isRightToLeft(); 0585 0586 if (row == end / 7) 0587 { 0588 // Single row to highlight. 0589 p.fillRect(QRectF((isRTL ? (7 - (end - start + 1) - column) : column) * dayWidth, 0590 row * dayHeight, 0591 (end - start + 1) * dayWidth - 2, 0592 dayHeight), 0593 colour); 0594 } 0595 else 0596 { 0597 // Draw first row, to the right of the start day. 0598 p.fillRect(QRectF((isRTL ? 0 : column * dayWidth), row * dayHeight, 0599 (7 - column) * dayWidth - 2, dayHeight), 0600 colour); 0601 // Draw full block till last line 0602 int selectionHeight = end / 7 - row; 0603 if (selectionHeight + row >= NUMROWS) 0604 selectionHeight = NUMROWS - row; 0605 if (selectionHeight > 1) 0606 p.fillRect(QRectF(0, (row + 1) * dayHeight, 0607 7 * dayWidth - 2, (selectionHeight - 1) * dayHeight), 0608 colour); 0609 // Draw last row, to the left of the end day. 0610 if (end / 7 < NUMROWS) 0611 { 0612 const int selectionWidth = end - 7 * (end / 7) + 1; 0613 p.fillRect(QRectF((isRTL ? (7 - selectionWidth) * dayWidth : 0), 0614 (row + selectionHeight) * dayHeight, 0615 selectionWidth * dayWidth - 2, dayHeight), 0616 colour); 0617 } 0618 } 0619 } 0620 0621 /****************************************************************************** 0622 * Called when the widget is resized. Set the size of each date in the matrix. 0623 */ 0624 void DayMatrix::resizeEvent(QResizeEvent*) 0625 { 0626 const QRect sz = frameRect(); 0627 const int padding = style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing) / 2; 0628 mDaySize.setHeight((sz.height() - padding) * 7.0 / NUMDAYS); 0629 mDaySize.setWidth(sz.width() / 7.0); 0630 } 0631 0632 /****************************************************************************** 0633 * Evaluate the text color to show a given date. 0634 */ 0635 QColor DayMatrix::textColour(const TextColours& textColours, const QPalette& palette, int dayIndex, bool workDay) const 0636 { 0637 if (dayIndex >= mSelStart && dayIndex <= mSelEnd) 0638 { 0639 if (dayIndex == mTodayIndex) 0640 return QColor(QStringLiteral("lightgrey")); 0641 if (workDay) 0642 return palette.color(QPalette::HighlightedText); 0643 } 0644 if (dayIndex < mTodayIndex) 0645 return textColours.disabled; 0646 if (dayIndex >= mMonthStartIndex && dayIndex <= mMonthEndIndex) 0647 return workDay ? textColours.thisMonth : textColours.thisMonthHoliday; 0648 else 0649 return workDay ? textColours.otherMonth : textColours.otherMonthHoliday; 0650 } 0651 0652 /*===========================================================================*/ 0653 0654 TextColours::TextColours(const QPalette& palette) 0655 { 0656 thisMonth = palette.color(QPalette::Text); 0657 disabled = getShadedColour(thisMonth, false); 0658 otherMonth = getShadedColour(thisMonth, true); 0659 thisMonthHoliday = thisMonth; 0660 thisMonthHoliday.setRed((thisMonthHoliday.red() + 255) / 2); 0661 otherMonthHoliday = getShadedColour(thisMonthHoliday, true); 0662 } 0663 0664 QColor TextColours::getShadedColour(const QColor& colour, bool enabled) const 0665 { 0666 QColor shaded; 0667 int h = 0; 0668 int s = 0; 0669 int v = 0; 0670 colour.getHsv(&h, &s, &v); 0671 s = s / (enabled ? 2 : 4); 0672 v = enabled ? (4*v + 5*255) / 9 : (v + 5*255) / 6; 0673 shaded.setHsv(h, s, v); 0674 return shaded; 0675 } 0676 0677 #include "moc_daymatrix.cpp" 0678 0679 // vim: et sw=4: