10#include "kdatetable_p.h"
13#include <QActionEvent>
14#include <QApplication>
16#include <QFontDatabase>
20#include <QStyleOptionViewItem>
24class KDateTable::KDateTablePrivate
27 KDateTablePrivate(KDateTable *qq)
30 m_popupMenuEnabled =
false;
31 m_useCustomColors =
false;
40 void setDate(
const QDate &date);
43 void beginningOfMonth();
45 void beginningOfWeek();
58 int m_weekDayFirstOfMonth;
63 int m_numDaysThisMonth;
85 bool m_popupMenuEnabled;
86 bool m_useCustomColors;
88 struct DatePaintingMode {
91 BackgroundMode bgMode;
98KDateTable::KDateTable(
const QDate &date,
QWidget *parent)
100 , d(new KDateTablePrivate(this))
105KDateTable::KDateTable(
QWidget *parent)
107 , d(std::make_unique<KDateTablePrivate>(this))
112KDateTable::~KDateTable()
116void KDateTable::initWidget(
const QDate &date)
118 d->m_numWeekRows = 7;
123 setAutoFillBackground(
true);
130void KDateTable::initAccels()
133 next->setObjectName(QStringLiteral(
"next"));
141 prior->setObjectName(QStringLiteral(
"prior"));
149 beginMonth->setObjectName(QStringLiteral(
"beginMonth"));
153 d->beginningOfMonth();
157 endMonth->setObjectName(QStringLiteral(
"endMonth"));
165 beginWeek->setObjectName(QStringLiteral(
"beginWeek"));
169 d->beginningOfWeek();
173 endWeek->setObjectName(QStringLiteral(
"endWeek"));
181int KDateTable::posFromDate(
const QDate &date)
183 int initialPosition = date.
day();
184 int offset = (d->m_weekDayFirstOfMonth - locale().firstDayOfWeek() + d->m_numDayColumns) % d->m_numDayColumns;
189 offset += d->m_numDayColumns;
192 return initialPosition + offset;
195QDate KDateTable::dateFromPos(
int position)
197 int offset = (d->m_weekDayFirstOfMonth - locale().firstDayOfWeek() + d->m_numDayColumns) % d->m_numDayColumns;
202 offset += d->m_numDayColumns;
205 return QDate(d->m_date.year(), d->m_date.month(), 1).
addDays(position - offset);
212 double cellWidth = width() / (double)d->m_numDayColumns;
213 double cellHeight = height() / (double)d->m_numWeekRows;
214 int leftCol = (int)std::floor(rectToUpdate.left() / cellWidth);
215 int topRow = (int)std::floor(rectToUpdate.top() / cellHeight);
216 int rightCol = (int)std::ceil(rectToUpdate.right() / cellWidth);
217 int bottomRow = (int)std::ceil(rectToUpdate.bottom() / cellHeight);
218 bottomRow = qMin(bottomRow, d->m_numWeekRows - 1);
219 rightCol = qMin(rightCol, d->m_numDayColumns - 1);
221 p.translate((d->m_numDayColumns - leftCol - 1) * cellWidth, topRow * cellHeight);
223 p.translate(leftCol * cellWidth, topRow * cellHeight);
225 for (
int i = leftCol; i <= rightCol; ++i) {
226 for (
int j = topRow; j <= bottomRow; ++j) {
228 p.translate(0, cellHeight);
231 p.translate(-cellWidth, 0);
233 p.translate(cellWidth, 0);
235 p.translate(0, -cellHeight * (bottomRow - topRow + 1));
239void KDateTable::paintCell(
QPainter *painter,
int row,
int col)
241 double w = (width() / (double)d->m_numDayColumns) - 1;
242 double h = (height() / (double)d->m_numWeekRows) - 1;
245 QColor cellBackgroundColor;
248 bool workingDay =
false;
253 pos = d->m_numDayColumns * (row - 1) + col;
256 if (col + locale().firstDayOfWeek() <= d->m_numDayColumns) {
257 cellWeekDay = col + locale().firstDayOfWeek();
259 cellWeekDay = col + locale().firstDayOfWeek() - d->m_numDayColumns;
264 if (locale().weekdays().first() <= locale().weekdays().last()) {
265 if (cellWeekDay >= locale().weekdays().first() && cellWeekDay <= locale().weekdays().last()) {
269 if (cellWeekDay >= locale().weekdays().first()
270 || cellWeekDay <= locale().weekdays().last()) {
294 QDate cellDate = dateFromPos(pos);
296 bool validDay = cellDate.
isValid();
300 cellText = locale().toString(cellDate.
day());
305 if (!validDay || cellDate.
month() != d->m_date.month()) {
310 cellBackgroundColor = palette().color(backgroundRole());
331 bool selectedDay = (cellDate == date());
336 bool customDay = (d->m_useCustomColors && d->m_customPaintingModes.contains(cellDate.
toJulianDay()));
339 cellBackgroundColor = palette().color(backgroundRole());
340 cellTextColor = palette().color(foregroundRole());
357 KDateTablePrivate::DatePaintingMode mode = d->m_customPaintingModes[cellDate.
toJulianDay()];
358 if (mode.bgMode != NoBgMode) {
360 cellBackgroundColor = mode.bgColor;
363 cellTextColor = mode.fgColor;
367 if (!customDay && dayOfPray) {
375 painter->
setPen(cellBackgroundColor);
376 painter->
setBrush(cellBackgroundColor);
378 }
else if (cellBackgroundColor != palette().color(backgroundRole()) || pos == d->m_hoveredPos) {
382 if (cellBackgroundColor != palette().color(backgroundRole())) {
389 opt.state &=
~QStyle::State_MouseOver;
391 opt.showDecorationSelected =
true;
397 painter->
setPen(cellTextColor);
403 painter->
setPen(palette().color(foregroundRole()));
409 if (cell.
width() > d->m_maxCell.width()) {
410 d->m_maxCell.setWidth(cell.
width());
412 if (cell.
height() > d->m_maxCell.height()) {
413 d->m_maxCell.setHeight(cell.
height());
417void KDateTable::KDateTablePrivate::nextMonth()
423void KDateTable::KDateTablePrivate::previousMonth()
426 q->setDate(m_date.addMonths(-1));
429void KDateTable::KDateTablePrivate::beginningOfMonth()
432 q->setDate(
QDate(m_date.year(), m_date.month(), 1));
435void KDateTable::KDateTablePrivate::endOfMonth()
438 q->setDate(
QDate(m_date.year(), m_date.month() + 1, 0));
442void KDateTable::KDateTablePrivate::beginningOfWeek()
445 q->setDate(m_date.addDays(1 - m_date.dayOfWeek()));
449void KDateTable::KDateTablePrivate::endOfWeek()
452 q->setDate(m_date.addDays(7 - m_date.dayOfWeek()));
455void KDateTable::keyPressEvent(
QKeyEvent *e)
460 setDate(d->m_date.addDays(-d->m_numDayColumns));
464 setDate(d->m_date.addDays(d->m_numDayColumns));
468 setDate(d->m_date.addDays(-1));
472 setDate(d->m_date.addDays(1));
476 setDate(d->m_date.addDays(-1));
480 setDate(d->m_date.addDays(1));
488 Q_EMIT tableClicked();
503void KDateTable::setFontSize(
int size)
510 d->m_maxCell.setWidth(0);
511 d->m_maxCell.setHeight(0);
512 for (
int weekday = 1; weekday <= 7; ++weekday) {
514 d->m_maxCell.
setWidth(qMax(d->m_maxCell.width(), rect.
width()));
515 d->m_maxCell.setHeight(qMax(d->m_maxCell.height(), rect.
height()));
518 rect = metrics.boundingRect(QStringLiteral(
"88"));
519 d->m_maxCell.
setWidth(qMax(d->m_maxCell.width() + 2, rect.
width()));
520 d->m_maxCell.setHeight(qMax(d->m_maxCell.height() + 4, rect.
height()));
525 setDate(d->m_date.addMonths(-(
int)(e->
angleDelta().
y() / 120)));
529bool KDateTable::event(
QEvent *ev)
531 switch (ev->
type()) {
534 const int row = e->
position().
y() * d->m_numWeekRows / height();
537 col = d->m_numDayColumns - (e->
position().x() * d->m_numDayColumns / width()) - 1;
539 col = e->
position().
x() * d->m_numDayColumns / width();
542 const int pos = row < 1 ? -1 : (d->m_numDayColumns * (row - 1)) + col;
544 if (pos != d->m_hoveredPos) {
545 d->m_hoveredPos = pos;
551 if (d->m_hoveredPos != -1) {
552 d->m_hoveredPos = -1;
578 row = mouseCoord.
y() * d->m_numWeekRows / height();
580 col = d->m_numDayColumns - (mouseCoord.
x() * d->m_numDayColumns / width()) - 1;
582 col = mouseCoord.
x() * d->m_numDayColumns / width();
585 if (row < 1 || col < 0) {
593 pos = (d->m_numDayColumns * (row - 1)) + col;
594 QDate clickedDate = dateFromPos(pos);
599 setDate(clickedDate);
607 Q_EMIT tableClicked();
612 Q_EMIT aboutToShowContextMenu(menu, clickedDate);
617void KDateTable::KDateTablePrivate::setDate(
const QDate &date)
621 m_numDaysThisMonth = m_date.daysInMonth();
625bool KDateTable::setDate(
const QDate &toDate)
631 if (toDate == date()) {
636 Q_EMIT dateChanged(date());
642const QDate &KDateTable::date()
const
657QSize KDateTable::sizeHint()
const
659 if (d->m_maxCell.height() > 0 && d->m_maxCell.width() > 0) {
660 return QSize(qRound(d->m_maxCell.width() * d->m_numDayColumns), (qRound(d->m_maxCell.height() + 2) * d->m_numWeekRows));
663 return QSize(-1, -1);
667void KDateTable::setPopupMenuEnabled(
bool enable)
669 d->m_popupMenuEnabled = enable;
672bool KDateTable::popupMenuEnabled()
const
674 return d->m_popupMenuEnabled;
677void KDateTable::setCustomDatePainting(
const QDate &date,
const QColor &fgColor, BackgroundMode bgMode,
const QColor &bgColor)
680 unsetCustomDatePainting(date);
684 KDateTablePrivate::DatePaintingMode mode;
685 mode.bgMode = bgMode;
686 mode.fgColor = fgColor;
687 mode.bgColor = bgColor;
689 d->m_customPaintingModes.insert(date.
toJulianDay(), mode);
690 d->m_useCustomColors =
true;
694void KDateTable::unsetCustomDatePainting(
const QDate &date)
696 d->m_customPaintingModes.remove(date.
toJulianDay());
697 if (d->m_customPaintingModes.isEmpty()) {
698 d->m_useCustomColors =
false;
703#include "moc_kdatetable_p.cpp"
void update(Part *part, const QByteArray &data, qint64 dataSize)
char * toString(const EngineQuery &query)
const QList< QKeySequence > & next()
const QList< QKeySequence > & prior()
void triggered(bool checked)
bool isValid() const const
QDate addDays(qint64 ndays) const const
QDate addMonths(int nmonths) const const
int dayOfWeek() const const
bool isValid(int year, int month, int day)
qint64 toJulianDay() const const
void setBold(bool enable)
QFont systemFont(SystemFont type)
Qt::KeyboardModifiers modifiers() const const
QList< QKeySequence > keyBindings(StandardKey key)
void drawLine(const QLine &line)
void drawRect(const QRect &rectangle)
void drawText(const QPoint &position, const QString &text)
void setBrush(Qt::BrushStyle style)
void setFont(const QFont &font)
void setPen(Qt::PenStyle style)
const QRect & rect() const const
QPoint toPoint() const const
qreal height() const const
void setWidth(qreal width)
QRect toRect() const const
qreal width() const const
QPointF globalPosition() const const
QPointF position() const const
void initFrom(const QWidget *widget)
WidgetWithChildrenShortcut
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QPoint angleDelta() const const