File indexing completed on 2024-04-28 03:59:04
0001 /* -*- C++ -*- 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 1997 Tim D. Gilman <tdgilman@best.org> 0004 SPDX-FileCopyrightText: 1998-2001 Mirko Boehm <mirko@kde.org> 0005 SPDX-FileCopyrightText: 2007 John Layt <john@layt.net> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #include "kdatetable_p.h" 0011 0012 #include <QAction> 0013 #include <QActionEvent> 0014 #include <QApplication> 0015 #include <QDate> 0016 #include <QFontDatabase> 0017 #include <QMenu> 0018 #include <QPainter> 0019 #include <QStyle> 0020 #include <QStyleOptionViewItem> 0021 0022 #include <cmath> 0023 0024 class KDateTable::KDateTablePrivate 0025 { 0026 public: 0027 KDateTablePrivate(KDateTable *qq) 0028 : q(qq) 0029 { 0030 m_popupMenuEnabled = false; 0031 m_useCustomColors = false; 0032 m_hoveredPos = -1; 0033 setDate(QDate::currentDate()); 0034 } 0035 0036 ~KDateTablePrivate() 0037 { 0038 } 0039 0040 void setDate(const QDate &date); 0041 void nextMonth(); 0042 void previousMonth(); 0043 void beginningOfMonth(); 0044 void endOfMonth(); 0045 void beginningOfWeek(); 0046 void endOfWeek(); 0047 0048 KDateTable *q; 0049 0050 /** 0051 * The currently selected date. 0052 */ 0053 QDate m_date; 0054 0055 /** 0056 * The weekday number of the first day in the month [1..daysInWeek()]. 0057 */ 0058 int m_weekDayFirstOfMonth; 0059 0060 /** 0061 * The number of days in the current month. 0062 */ 0063 int m_numDaysThisMonth; 0064 0065 /** 0066 * Save the size of the largest used cell content. 0067 */ 0068 QRectF m_maxCell; 0069 0070 /** 0071 * How many week rows we are to draw. 0072 */ 0073 int m_numWeekRows; 0074 0075 /** 0076 * How many day columns we are to draw, i.e. days in a week. 0077 */ 0078 int m_numDayColumns; 0079 0080 /** 0081 * The font size of the displayed text. 0082 */ 0083 int fontsize; 0084 0085 bool m_popupMenuEnabled; 0086 bool m_useCustomColors; 0087 0088 struct DatePaintingMode { 0089 QColor fgColor; 0090 QColor bgColor; 0091 BackgroundMode bgMode; 0092 }; 0093 QHash<int, DatePaintingMode> m_customPaintingModes; 0094 0095 int m_hoveredPos; 0096 }; 0097 0098 KDateTable::KDateTable(const QDate &date, QWidget *parent) 0099 : QWidget(parent) 0100 , d(new KDateTablePrivate(this)) 0101 { 0102 initWidget(date); 0103 } 0104 0105 KDateTable::KDateTable(QWidget *parent) 0106 : QWidget(parent) 0107 , d(std::make_unique<KDateTablePrivate>(this)) 0108 { 0109 initWidget(QDate::currentDate()); 0110 } 0111 0112 KDateTable::~KDateTable() 0113 { 0114 } 0115 0116 void KDateTable::initWidget(const QDate &date) 0117 { 0118 d->m_numWeekRows = 7; 0119 0120 setFontSize(10); 0121 setFocusPolicy(Qt::StrongFocus); 0122 setBackgroundRole(QPalette::Base); 0123 setAutoFillBackground(true); 0124 initAccels(); 0125 setAttribute(Qt::WA_Hover, true); 0126 0127 setDate(date); 0128 } 0129 0130 void KDateTable::initAccels() 0131 { 0132 QAction *next = new QAction(this); 0133 next->setObjectName(QStringLiteral("next")); 0134 next->setShortcuts(QKeySequence::keyBindings(QKeySequence::Forward)); 0135 next->setShortcutContext(Qt::WidgetWithChildrenShortcut); 0136 connect(next, &QAction::triggered, this, [this]() { 0137 d->nextMonth(); 0138 }); 0139 0140 QAction *prior = new QAction(this); 0141 prior->setObjectName(QStringLiteral("prior")); 0142 prior->setShortcuts(QKeySequence::keyBindings(QKeySequence::Back)); 0143 prior->setShortcutContext(Qt::WidgetWithChildrenShortcut); 0144 connect(prior, &QAction::triggered, this, [this]() { 0145 d->previousMonth(); 0146 }); 0147 0148 QAction *beginMonth = new QAction(this); 0149 beginMonth->setObjectName(QStringLiteral("beginMonth")); 0150 beginMonth->setShortcuts(QKeySequence::keyBindings(QKeySequence::MoveToStartOfDocument)); 0151 beginMonth->setShortcutContext(Qt::WidgetWithChildrenShortcut); 0152 connect(beginMonth, &QAction::triggered, this, [this]() { 0153 d->beginningOfMonth(); 0154 }); 0155 0156 QAction *endMonth = new QAction(this); 0157 endMonth->setObjectName(QStringLiteral("endMonth")); 0158 endMonth->setShortcuts(QKeySequence::keyBindings(QKeySequence::MoveToEndOfDocument)); 0159 endMonth->setShortcutContext(Qt::WidgetWithChildrenShortcut); 0160 connect(endMonth, &QAction::triggered, this, [this]() { 0161 d->endOfMonth(); 0162 }); 0163 0164 QAction *beginWeek = new QAction(this); 0165 beginWeek->setObjectName(QStringLiteral("beginWeek")); 0166 beginWeek->setShortcuts(QKeySequence::keyBindings(QKeySequence::MoveToStartOfLine)); 0167 beginWeek->setShortcutContext(Qt::WidgetWithChildrenShortcut); 0168 connect(beginWeek, &QAction::triggered, this, [this]() { 0169 d->beginningOfWeek(); 0170 }); 0171 0172 QAction *endWeek = new QAction(this); 0173 endWeek->setObjectName(QStringLiteral("endWeek")); 0174 endWeek->setShortcuts(QKeySequence::keyBindings(QKeySequence::MoveToEndOfLine)); 0175 endWeek->setShortcutContext(Qt::WidgetWithChildrenShortcut); 0176 connect(endWeek, &QAction::triggered, this, [this]() { 0177 d->endOfWeek(); 0178 }); 0179 } 0180 0181 int KDateTable::posFromDate(const QDate &date) 0182 { 0183 int initialPosition = date.day(); 0184 int offset = (d->m_weekDayFirstOfMonth - locale().firstDayOfWeek() + d->m_numDayColumns) % d->m_numDayColumns; 0185 0186 // make sure at least one day of the previous month is visible. 0187 // adjust this < 1 if more days should be forced visible: 0188 if (offset < 1) { 0189 offset += d->m_numDayColumns; 0190 } 0191 0192 return initialPosition + offset; 0193 } 0194 0195 QDate KDateTable::dateFromPos(int position) 0196 { 0197 int offset = (d->m_weekDayFirstOfMonth - locale().firstDayOfWeek() + d->m_numDayColumns) % d->m_numDayColumns; 0198 0199 // make sure at least one day of the previous month is visible. 0200 // adjust this < 1 if more days should be forced visible: 0201 if (offset < 1) { 0202 offset += d->m_numDayColumns; 0203 } 0204 0205 return QDate(d->m_date.year(), d->m_date.month(), 1).addDays(position - offset); 0206 } 0207 0208 void KDateTable::paintEvent(QPaintEvent *e) 0209 { 0210 QPainter p(this); 0211 const QRect &rectToUpdate = e->rect(); 0212 double cellWidth = width() / (double)d->m_numDayColumns; 0213 double cellHeight = height() / (double)d->m_numWeekRows; 0214 int leftCol = (int)std::floor(rectToUpdate.left() / cellWidth); 0215 int topRow = (int)std::floor(rectToUpdate.top() / cellHeight); 0216 int rightCol = (int)std::ceil(rectToUpdate.right() / cellWidth); 0217 int bottomRow = (int)std::ceil(rectToUpdate.bottom() / cellHeight); 0218 bottomRow = qMin(bottomRow, d->m_numWeekRows - 1); 0219 rightCol = qMin(rightCol, d->m_numDayColumns - 1); 0220 if (layoutDirection() == Qt::RightToLeft) { 0221 p.translate((d->m_numDayColumns - leftCol - 1) * cellWidth, topRow * cellHeight); 0222 } else { 0223 p.translate(leftCol * cellWidth, topRow * cellHeight); 0224 } 0225 for (int i = leftCol; i <= rightCol; ++i) { 0226 for (int j = topRow; j <= bottomRow; ++j) { 0227 paintCell(&p, j, i); 0228 p.translate(0, cellHeight); 0229 } 0230 if (layoutDirection() == Qt::RightToLeft) { 0231 p.translate(-cellWidth, 0); 0232 } else { 0233 p.translate(cellWidth, 0); 0234 } 0235 p.translate(0, -cellHeight * (bottomRow - topRow + 1)); 0236 } 0237 } 0238 0239 void KDateTable::paintCell(QPainter *painter, int row, int col) 0240 { 0241 double w = (width() / (double)d->m_numDayColumns) - 1; 0242 double h = (height() / (double)d->m_numWeekRows) - 1; 0243 QRectF cell = QRectF(0, 0, w, h); 0244 QString cellText; 0245 QColor cellBackgroundColor; 0246 QColor cellTextColor; 0247 QFont cellFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont); 0248 bool workingDay = false; 0249 int cellWeekDay; 0250 int pos; 0251 0252 // Calculate the position of the cell in the grid 0253 pos = d->m_numDayColumns * (row - 1) + col; 0254 0255 // Calculate what day of the week the cell is 0256 if (col + locale().firstDayOfWeek() <= d->m_numDayColumns) { 0257 cellWeekDay = col + locale().firstDayOfWeek(); 0258 } else { 0259 cellWeekDay = col + locale().firstDayOfWeek() - d->m_numDayColumns; 0260 } 0261 0262 // FIXME This is wrong if the widget is not using the global! 0263 // See if cell day is normally a working day 0264 if (locale().weekdays().first() <= locale().weekdays().last()) { 0265 if (cellWeekDay >= locale().weekdays().first() && cellWeekDay <= locale().weekdays().last()) { 0266 workingDay = true; 0267 } 0268 } else { 0269 if (cellWeekDay >= locale().weekdays().first() // 0270 || cellWeekDay <= locale().weekdays().last()) { 0271 workingDay = true; 0272 } 0273 } 0274 0275 if (row == 0) { 0276 // We are drawing a header cell 0277 0278 // If not a normal working day, then use "do not work today" color 0279 if (workingDay) { 0280 cellTextColor = palette().color(QPalette::WindowText); 0281 } else { 0282 cellTextColor = Qt::darkRed; 0283 } 0284 cellBackgroundColor = palette().color(QPalette::Window); 0285 0286 // Set the text to the short day name and bold it 0287 cellFont.setBold(true); 0288 cellText = locale().dayName(cellWeekDay, QLocale::ShortFormat); 0289 0290 } else { 0291 // We are drawing a day cell 0292 0293 // Calculate the date the cell represents 0294 QDate cellDate = dateFromPos(pos); 0295 0296 bool validDay = cellDate.isValid(); 0297 0298 // Draw the day number in the cell, if the date is not valid then we don't want to show it 0299 if (validDay) { 0300 cellText = locale().toString(cellDate.day()); 0301 } else { 0302 cellText = QString(); 0303 } 0304 0305 if (!validDay || cellDate.month() != d->m_date.month()) { 0306 // we are either 0307 // ° painting an invalid day 0308 // ° painting a day of the previous month or 0309 // ° painting a day of the following month or 0310 cellBackgroundColor = palette().color(backgroundRole()); 0311 cellTextColor = palette().color(QPalette::Disabled, QPalette::Text); 0312 } else { 0313 // Paint a day of the current month 0314 0315 // Background Colour priorities will be (high-to-low): 0316 // * Selected Day Background Colour 0317 // * Customized Day Background Colour 0318 // * Normal Day Background Colour 0319 0320 // Background Shape priorities will be (high-to-low): 0321 // * Customized Day Shape 0322 // * Normal Day Shape 0323 0324 // Text Colour priorities will be (high-to-low): 0325 // * Customized Day Colour 0326 // * Day of Pray Colour (Red letter) 0327 // * Selected Day Colour 0328 // * Normal Day Colour 0329 0330 // Determine various characteristics of the cell date 0331 bool selectedDay = (cellDate == date()); 0332 bool currentDay = (cellDate == QDate::currentDate()); 0333 bool dayOfPray = (cellDate.dayOfWeek() == Qt::Sunday); 0334 // TODO: Uncomment if QLocale ever gets the feature... 0335 // bool dayOfPray = ( cellDate.dayOfWeek() == locale().dayOfPray() ); 0336 bool customDay = (d->m_useCustomColors && d->m_customPaintingModes.contains(cellDate.toJulianDay())); 0337 0338 // Default values for a normal cell 0339 cellBackgroundColor = palette().color(backgroundRole()); 0340 cellTextColor = palette().color(foregroundRole()); 0341 0342 // If we are drawing the current date, then draw it bold and active 0343 if (currentDay) { 0344 cellFont.setBold(true); 0345 cellTextColor = palette().color(QPalette::LinkVisited); 0346 } 0347 0348 // if we are drawing the day cell currently selected in the table 0349 if (selectedDay) { 0350 // set the background to highlighted 0351 cellBackgroundColor = palette().color(QPalette::Highlight); 0352 cellTextColor = palette().color(QPalette::HighlightedText); 0353 } 0354 0355 // If custom colors or shape are required for this date 0356 if (customDay) { 0357 KDateTablePrivate::DatePaintingMode mode = d->m_customPaintingModes[cellDate.toJulianDay()]; 0358 if (mode.bgMode != NoBgMode) { 0359 if (!selectedDay) { 0360 cellBackgroundColor = mode.bgColor; 0361 } 0362 } 0363 cellTextColor = mode.fgColor; 0364 } 0365 0366 // If the cell day is the day of religious observance, then always color text red unless Custom overrides 0367 if (!customDay && dayOfPray) { 0368 cellTextColor = Qt::darkRed; 0369 } 0370 } 0371 } 0372 0373 // Draw the background 0374 if (row == 0) { 0375 painter->setPen(cellBackgroundColor); 0376 painter->setBrush(cellBackgroundColor); 0377 painter->drawRect(cell); 0378 } else if (cellBackgroundColor != palette().color(backgroundRole()) || pos == d->m_hoveredPos) { 0379 QStyleOptionViewItem opt; 0380 opt.initFrom(this); 0381 opt.rect = cell.toRect(); 0382 if (cellBackgroundColor != palette().color(backgroundRole())) { 0383 opt.palette.setBrush(QPalette::Highlight, cellBackgroundColor); 0384 opt.state |= QStyle::State_Selected; 0385 } 0386 if (pos == d->m_hoveredPos && opt.state & QStyle::State_Enabled) { 0387 opt.state |= QStyle::State_MouseOver; 0388 } else { 0389 opt.state &= ~QStyle::State_MouseOver; 0390 } 0391 opt.showDecorationSelected = true; 0392 opt.viewItemPosition = QStyleOptionViewItem::OnlyOne; 0393 style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, this); 0394 } 0395 0396 // Draw the text 0397 painter->setPen(cellTextColor); 0398 painter->setFont(cellFont); 0399 painter->drawText(cell, Qt::AlignCenter, cellText, &cell); 0400 0401 // Draw the base line 0402 if (row == 0) { 0403 painter->setPen(palette().color(foregroundRole())); 0404 painter->drawLine(QPointF(0, h), QPointF(w, h)); 0405 } 0406 0407 // If the day cell we just drew is bigger than the current max cell sizes, 0408 // then adjust the max to the current cell 0409 if (cell.width() > d->m_maxCell.width()) { 0410 d->m_maxCell.setWidth(cell.width()); 0411 } 0412 if (cell.height() > d->m_maxCell.height()) { 0413 d->m_maxCell.setHeight(cell.height()); 0414 } 0415 } 0416 0417 void KDateTable::KDateTablePrivate::nextMonth() 0418 { 0419 // setDate does validity checking for us 0420 q->setDate(m_date.addMonths(1)); 0421 } 0422 0423 void KDateTable::KDateTablePrivate::previousMonth() 0424 { 0425 // setDate does validity checking for us 0426 q->setDate(m_date.addMonths(-1)); 0427 } 0428 0429 void KDateTable::KDateTablePrivate::beginningOfMonth() 0430 { 0431 // setDate does validity checking for us 0432 q->setDate(QDate(m_date.year(), m_date.month(), 1)); 0433 } 0434 0435 void KDateTable::KDateTablePrivate::endOfMonth() 0436 { 0437 // setDate does validity checking for us 0438 q->setDate(QDate(m_date.year(), m_date.month() + 1, 0)); 0439 } 0440 0441 // JPL Do these make the assumption that first day of week is weekday 1? As it may not be. 0442 void KDateTable::KDateTablePrivate::beginningOfWeek() 0443 { 0444 // setDate does validity checking for us 0445 q->setDate(m_date.addDays(1 - m_date.dayOfWeek())); 0446 } 0447 0448 // JPL Do these make the assumption that first day of week is weekday 1? As it may not be. 0449 void KDateTable::KDateTablePrivate::endOfWeek() 0450 { 0451 // setDate does validity checking for us 0452 q->setDate(m_date.addDays(7 - m_date.dayOfWeek())); 0453 } 0454 0455 void KDateTable::keyPressEvent(QKeyEvent *e) 0456 { 0457 switch (e->key()) { 0458 case Qt::Key_Up: 0459 // setDate does validity checking for us 0460 setDate(d->m_date.addDays(-d->m_numDayColumns)); 0461 break; 0462 case Qt::Key_Down: 0463 // setDate does validity checking for us 0464 setDate(d->m_date.addDays(d->m_numDayColumns)); 0465 break; 0466 case Qt::Key_Left: 0467 // setDate does validity checking for us 0468 setDate(d->m_date.addDays(-1)); 0469 break; 0470 case Qt::Key_Right: 0471 // setDate does validity checking for us 0472 setDate(d->m_date.addDays(1)); 0473 break; 0474 case Qt::Key_Minus: 0475 // setDate does validity checking for us 0476 setDate(d->m_date.addDays(-1)); 0477 break; 0478 case Qt::Key_Plus: 0479 // setDate does validity checking for us 0480 setDate(d->m_date.addDays(1)); 0481 break; 0482 case Qt::Key_N: 0483 // setDate does validity checking for us 0484 setDate(QDate::currentDate()); 0485 break; 0486 case Qt::Key_Return: 0487 case Qt::Key_Enter: 0488 Q_EMIT tableClicked(); 0489 break; 0490 case Qt::Key_Control: 0491 case Qt::Key_Alt: 0492 case Qt::Key_Meta: 0493 case Qt::Key_Shift: 0494 // Don't beep for modifiers 0495 break; 0496 default: 0497 if (!e->modifiers()) { // hm 0498 QApplication::beep(); 0499 } 0500 } 0501 } 0502 0503 void KDateTable::setFontSize(int size) 0504 { 0505 QFontMetricsF metrics(fontMetrics()); 0506 QRectF rect; 0507 // ----- store rectangles: 0508 d->fontsize = size; 0509 // ----- find largest day name: 0510 d->m_maxCell.setWidth(0); 0511 d->m_maxCell.setHeight(0); 0512 for (int weekday = 1; weekday <= 7; ++weekday) { 0513 rect = metrics.boundingRect(locale().dayName(weekday, QLocale::ShortFormat)); 0514 d->m_maxCell.setWidth(qMax(d->m_maxCell.width(), rect.width())); 0515 d->m_maxCell.setHeight(qMax(d->m_maxCell.height(), rect.height())); 0516 } 0517 // ----- compare with a real wide number and add some space: 0518 rect = metrics.boundingRect(QStringLiteral("88")); 0519 d->m_maxCell.setWidth(qMax(d->m_maxCell.width() + 2, rect.width())); 0520 d->m_maxCell.setHeight(qMax(d->m_maxCell.height() + 4, rect.height())); 0521 } 0522 0523 void KDateTable::wheelEvent(QWheelEvent *e) 0524 { 0525 setDate(d->m_date.addMonths(-(int)(e->angleDelta().y() / 120))); 0526 e->accept(); 0527 } 0528 0529 bool KDateTable::event(QEvent *ev) 0530 { 0531 switch (ev->type()) { 0532 case QEvent::HoverMove: { 0533 QHoverEvent *e = static_cast<QHoverEvent *>(ev); 0534 const int row = e->position().y() * d->m_numWeekRows / height(); 0535 int col; 0536 if (layoutDirection() == Qt::RightToLeft) { 0537 col = d->m_numDayColumns - (e->position().x() * d->m_numDayColumns / width()) - 1; 0538 } else { 0539 col = e->position().x() * d->m_numDayColumns / width(); 0540 } 0541 0542 const int pos = row < 1 ? -1 : (d->m_numDayColumns * (row - 1)) + col; 0543 0544 if (pos != d->m_hoveredPos) { 0545 d->m_hoveredPos = pos; 0546 update(); 0547 } 0548 break; 0549 } 0550 case QEvent::HoverLeave: 0551 if (d->m_hoveredPos != -1) { 0552 d->m_hoveredPos = -1; 0553 update(); 0554 } 0555 break; 0556 default: 0557 break; 0558 } 0559 return QWidget::event(ev); 0560 } 0561 0562 void KDateTable::mousePressEvent(QMouseEvent *e) 0563 { 0564 if (e->type() != QEvent::MouseButtonPress) { // the KDatePicker only reacts on mouse press events: 0565 return; 0566 } 0567 0568 if (!isEnabled()) { 0569 QApplication::beep(); 0570 return; 0571 } 0572 0573 int row; 0574 int col; 0575 int pos; 0576 0577 QPoint mouseCoord = e->pos(); 0578 row = mouseCoord.y() * d->m_numWeekRows / height(); 0579 if (layoutDirection() == Qt::RightToLeft) { 0580 col = d->m_numDayColumns - (mouseCoord.x() * d->m_numDayColumns / width()) - 1; 0581 } else { 0582 col = mouseCoord.x() * d->m_numDayColumns / width(); 0583 } 0584 0585 if (row < 1 || col < 0) { // the user clicked on the frame of the table 0586 return; 0587 } 0588 0589 // Rows and columns are zero indexed. The (row - 1) below is to avoid counting 0590 // the row with the days of the week in the calculation. 0591 0592 // new position and date 0593 pos = (d->m_numDayColumns * (row - 1)) + col; 0594 QDate clickedDate = dateFromPos(pos); 0595 0596 // set the new date. If it is in the previous or next month, the month will 0597 // automatically be changed, no need to do that manually... 0598 // validity checking done inside setDate 0599 setDate(clickedDate); 0600 0601 // This could be optimized to only call update over the regions 0602 // of old and new cell, but 99% of times there is also a call to 0603 // setDate that already calls update() so no need to optimize that 0604 // much here 0605 update(); 0606 0607 Q_EMIT tableClicked(); 0608 0609 if (e->button() == Qt::RightButton && d->m_popupMenuEnabled) { 0610 QMenu *menu = new QMenu(); 0611 menu->addSection(locale().toString(d->m_date)); 0612 Q_EMIT aboutToShowContextMenu(menu, clickedDate); 0613 menu->popup(e->globalPosition().toPoint()); 0614 } 0615 } 0616 0617 void KDateTable::KDateTablePrivate::setDate(const QDate &date) 0618 { 0619 m_date = date; 0620 m_weekDayFirstOfMonth = QDate(date.year(), date.month(), 1).dayOfWeek(); 0621 m_numDaysThisMonth = m_date.daysInMonth(); 0622 m_numDayColumns = 7; 0623 } 0624 0625 bool KDateTable::setDate(const QDate &toDate) 0626 { 0627 if (!toDate.isValid()) { 0628 return false; 0629 } 0630 0631 if (toDate == date()) { 0632 return true; 0633 } 0634 0635 d->setDate(toDate); 0636 Q_EMIT dateChanged(date()); 0637 update(); 0638 0639 return true; 0640 } 0641 0642 const QDate &KDateTable::date() const 0643 { 0644 return d->m_date; 0645 } 0646 0647 void KDateTable::focusInEvent(QFocusEvent *e) 0648 { 0649 QWidget::focusInEvent(e); 0650 } 0651 0652 void KDateTable::focusOutEvent(QFocusEvent *e) 0653 { 0654 QWidget::focusOutEvent(e); 0655 } 0656 0657 QSize KDateTable::sizeHint() const 0658 { 0659 if (d->m_maxCell.height() > 0 && d->m_maxCell.width() > 0) { 0660 return QSize(qRound(d->m_maxCell.width() * d->m_numDayColumns), (qRound(d->m_maxCell.height() + 2) * d->m_numWeekRows)); 0661 } else { 0662 // qCDebug(KWidgetsAddonsLog) << "KDateTable::sizeHint: obscure failure - " << endl; 0663 return QSize(-1, -1); 0664 } 0665 } 0666 0667 void KDateTable::setPopupMenuEnabled(bool enable) 0668 { 0669 d->m_popupMenuEnabled = enable; 0670 } 0671 0672 bool KDateTable::popupMenuEnabled() const 0673 { 0674 return d->m_popupMenuEnabled; 0675 } 0676 0677 void KDateTable::setCustomDatePainting(const QDate &date, const QColor &fgColor, BackgroundMode bgMode, const QColor &bgColor) 0678 { 0679 if (!fgColor.isValid()) { 0680 unsetCustomDatePainting(date); 0681 return; 0682 } 0683 0684 KDateTablePrivate::DatePaintingMode mode; 0685 mode.bgMode = bgMode; 0686 mode.fgColor = fgColor; 0687 mode.bgColor = bgColor; 0688 0689 d->m_customPaintingModes.insert(date.toJulianDay(), mode); 0690 d->m_useCustomColors = true; 0691 update(); 0692 } 0693 0694 void KDateTable::unsetCustomDatePainting(const QDate &date) 0695 { 0696 d->m_customPaintingModes.remove(date.toJulianDay()); 0697 if (d->m_customPaintingModes.isEmpty()) { 0698 d->m_useCustomColors = false; 0699 } 0700 update(); 0701 } 0702 0703 #include "moc_kdatetable_p.cpp"