cf12defd28
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
704 lines
21 KiB
C++
704 lines
21 KiB
C++
/* -*- C++ -*-
|
|
This file is part of the KDE libraries
|
|
SPDX-FileCopyrightText: 1997 Tim D. Gilman <tdgilman@best.org>
|
|
SPDX-FileCopyrightText: 1998-2001 Mirko Boehm <mirko@kde.org>
|
|
SPDX-FileCopyrightText: 2007 John Layt <john@layt.net>
|
|
|
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
|
*/
|
|
|
|
#include "kdatetable_p.h"
|
|
|
|
#include <QAction>
|
|
#include <QActionEvent>
|
|
#include <QApplication>
|
|
#include <QDate>
|
|
#include <QFontDatabase>
|
|
#include <QMenu>
|
|
#include <QPainter>
|
|
#include <QStyle>
|
|
#include <QStyleOptionViewItem>
|
|
|
|
#include <cmath>
|
|
|
|
class KDateTable::KDateTablePrivate
|
|
{
|
|
public:
|
|
KDateTablePrivate(KDateTable *qq)
|
|
: q(qq)
|
|
{
|
|
m_popupMenuEnabled = false;
|
|
m_useCustomColors = false;
|
|
m_hoveredPos = -1;
|
|
setDate(QDate::currentDate());
|
|
}
|
|
|
|
~KDateTablePrivate()
|
|
{
|
|
}
|
|
|
|
void setDate(const QDate &date);
|
|
void nextMonth();
|
|
void previousMonth();
|
|
void beginningOfMonth();
|
|
void endOfMonth();
|
|
void beginningOfWeek();
|
|
void endOfWeek();
|
|
|
|
KDateTable *q;
|
|
|
|
/**
|
|
* The currently selected date.
|
|
*/
|
|
QDate m_date;
|
|
|
|
/**
|
|
* The weekday number of the first day in the month [1..daysInWeek()].
|
|
*/
|
|
int m_weekDayFirstOfMonth;
|
|
|
|
/**
|
|
* The number of days in the current month.
|
|
*/
|
|
int m_numDaysThisMonth;
|
|
|
|
/**
|
|
* Save the size of the largest used cell content.
|
|
*/
|
|
QRectF m_maxCell;
|
|
|
|
/**
|
|
* How many week rows we are to draw.
|
|
*/
|
|
int m_numWeekRows;
|
|
|
|
/**
|
|
* How many day columns we are to draw, i.e. days in a week.
|
|
*/
|
|
int m_numDayColumns;
|
|
|
|
/**
|
|
* The font size of the displayed text.
|
|
*/
|
|
int fontsize;
|
|
|
|
bool m_popupMenuEnabled;
|
|
bool m_useCustomColors;
|
|
|
|
struct DatePaintingMode {
|
|
QColor fgColor;
|
|
QColor bgColor;
|
|
BackgroundMode bgMode;
|
|
};
|
|
QHash<int, DatePaintingMode> m_customPaintingModes;
|
|
|
|
int m_hoveredPos;
|
|
};
|
|
|
|
KDateTable::KDateTable(const QDate &date, QWidget *parent)
|
|
: QWidget(parent)
|
|
, d(new KDateTablePrivate(this))
|
|
{
|
|
initWidget(date);
|
|
}
|
|
|
|
KDateTable::KDateTable(QWidget *parent)
|
|
: QWidget(parent)
|
|
, d(std::make_unique<KDateTablePrivate>(this))
|
|
{
|
|
initWidget(QDate::currentDate());
|
|
}
|
|
|
|
KDateTable::~KDateTable()
|
|
{
|
|
}
|
|
|
|
void KDateTable::initWidget(const QDate &date)
|
|
{
|
|
d->m_numWeekRows = 7;
|
|
|
|
setFontSize(10);
|
|
setFocusPolicy(Qt::StrongFocus);
|
|
setBackgroundRole(QPalette::Base);
|
|
setAutoFillBackground(true);
|
|
initAccels();
|
|
setAttribute(Qt::WA_Hover, true);
|
|
|
|
setDate(date);
|
|
}
|
|
|
|
void KDateTable::initAccels()
|
|
{
|
|
QAction *next = new QAction(this);
|
|
next->setObjectName(QStringLiteral("next"));
|
|
next->setShortcuts(QKeySequence::keyBindings(QKeySequence::Forward));
|
|
next->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
|
connect(next, &QAction::triggered, this, [this]() {
|
|
d->nextMonth();
|
|
});
|
|
|
|
QAction *prior = new QAction(this);
|
|
prior->setObjectName(QStringLiteral("prior"));
|
|
prior->setShortcuts(QKeySequence::keyBindings(QKeySequence::Back));
|
|
prior->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
|
connect(prior, &QAction::triggered, this, [this]() {
|
|
d->previousMonth();
|
|
});
|
|
|
|
QAction *beginMonth = new QAction(this);
|
|
beginMonth->setObjectName(QStringLiteral("beginMonth"));
|
|
beginMonth->setShortcuts(QKeySequence::keyBindings(QKeySequence::MoveToStartOfDocument));
|
|
beginMonth->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
|
connect(beginMonth, &QAction::triggered, this, [this]() {
|
|
d->beginningOfMonth();
|
|
});
|
|
|
|
QAction *endMonth = new QAction(this);
|
|
endMonth->setObjectName(QStringLiteral("endMonth"));
|
|
endMonth->setShortcuts(QKeySequence::keyBindings(QKeySequence::MoveToEndOfDocument));
|
|
endMonth->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
|
connect(endMonth, &QAction::triggered, this, [this]() {
|
|
d->endOfMonth();
|
|
});
|
|
|
|
QAction *beginWeek = new QAction(this);
|
|
beginWeek->setObjectName(QStringLiteral("beginWeek"));
|
|
beginWeek->setShortcuts(QKeySequence::keyBindings(QKeySequence::MoveToStartOfLine));
|
|
beginWeek->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
|
connect(beginWeek, &QAction::triggered, this, [this]() {
|
|
d->beginningOfWeek();
|
|
});
|
|
|
|
QAction *endWeek = new QAction(this);
|
|
endWeek->setObjectName(QStringLiteral("endWeek"));
|
|
endWeek->setShortcuts(QKeySequence::keyBindings(QKeySequence::MoveToEndOfLine));
|
|
endWeek->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
|
connect(endWeek, &QAction::triggered, this, [this]() {
|
|
d->endOfWeek();
|
|
});
|
|
}
|
|
|
|
int KDateTable::posFromDate(const QDate &date)
|
|
{
|
|
int initialPosition = date.day();
|
|
int offset = (d->m_weekDayFirstOfMonth - locale().firstDayOfWeek() + d->m_numDayColumns) % d->m_numDayColumns;
|
|
|
|
// make sure at least one day of the previous month is visible.
|
|
// adjust this < 1 if more days should be forced visible:
|
|
if (offset < 1) {
|
|
offset += d->m_numDayColumns;
|
|
}
|
|
|
|
return initialPosition + offset;
|
|
}
|
|
|
|
QDate KDateTable::dateFromPos(int position)
|
|
{
|
|
int offset = (d->m_weekDayFirstOfMonth - locale().firstDayOfWeek() + d->m_numDayColumns) % d->m_numDayColumns;
|
|
|
|
// make sure at least one day of the previous month is visible.
|
|
// adjust this < 1 if more days should be forced visible:
|
|
if (offset < 1) {
|
|
offset += d->m_numDayColumns;
|
|
}
|
|
|
|
return QDate(d->m_date.year(), d->m_date.month(), 1).addDays(position - offset);
|
|
}
|
|
|
|
void KDateTable::paintEvent(QPaintEvent *e)
|
|
{
|
|
QPainter p(this);
|
|
const QRect &rectToUpdate = e->rect();
|
|
double cellWidth = width() / (double)d->m_numDayColumns;
|
|
double cellHeight = height() / (double)d->m_numWeekRows;
|
|
int leftCol = (int)std::floor(rectToUpdate.left() / cellWidth);
|
|
int topRow = (int)std::floor(rectToUpdate.top() / cellHeight);
|
|
int rightCol = (int)std::ceil(rectToUpdate.right() / cellWidth);
|
|
int bottomRow = (int)std::ceil(rectToUpdate.bottom() / cellHeight);
|
|
bottomRow = qMin(bottomRow, d->m_numWeekRows - 1);
|
|
rightCol = qMin(rightCol, d->m_numDayColumns - 1);
|
|
if (layoutDirection() == Qt::RightToLeft) {
|
|
p.translate((d->m_numDayColumns - leftCol - 1) * cellWidth, topRow * cellHeight);
|
|
} else {
|
|
p.translate(leftCol * cellWidth, topRow * cellHeight);
|
|
}
|
|
for (int i = leftCol; i <= rightCol; ++i) {
|
|
for (int j = topRow; j <= bottomRow; ++j) {
|
|
paintCell(&p, j, i);
|
|
p.translate(0, cellHeight);
|
|
}
|
|
if (layoutDirection() == Qt::RightToLeft) {
|
|
p.translate(-cellWidth, 0);
|
|
} else {
|
|
p.translate(cellWidth, 0);
|
|
}
|
|
p.translate(0, -cellHeight * (bottomRow - topRow + 1));
|
|
}
|
|
}
|
|
|
|
void KDateTable::paintCell(QPainter *painter, int row, int col)
|
|
{
|
|
double w = (width() / (double)d->m_numDayColumns) - 1;
|
|
double h = (height() / (double)d->m_numWeekRows) - 1;
|
|
QRectF cell = QRectF(0, 0, w, h);
|
|
QString cellText;
|
|
QColor cellBackgroundColor;
|
|
QColor cellTextColor;
|
|
QFont cellFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
|
|
bool workingDay = false;
|
|
int cellWeekDay;
|
|
int pos;
|
|
|
|
// Calculate the position of the cell in the grid
|
|
pos = d->m_numDayColumns * (row - 1) + col;
|
|
|
|
// Calculate what day of the week the cell is
|
|
if (col + locale().firstDayOfWeek() <= d->m_numDayColumns) {
|
|
cellWeekDay = col + locale().firstDayOfWeek();
|
|
} else {
|
|
cellWeekDay = col + locale().firstDayOfWeek() - d->m_numDayColumns;
|
|
}
|
|
|
|
// FIXME This is wrong if the widget is not using the global!
|
|
// See if cell day is normally a working day
|
|
if (locale().weekdays().first() <= locale().weekdays().last()) {
|
|
if (cellWeekDay >= locale().weekdays().first() && cellWeekDay <= locale().weekdays().last()) {
|
|
workingDay = true;
|
|
}
|
|
} else {
|
|
if (cellWeekDay >= locale().weekdays().first() //
|
|
|| cellWeekDay <= locale().weekdays().last()) {
|
|
workingDay = true;
|
|
}
|
|
}
|
|
|
|
if (row == 0) {
|
|
// We are drawing a header cell
|
|
|
|
// If not a normal working day, then use "do not work today" color
|
|
if (workingDay) {
|
|
cellTextColor = palette().color(QPalette::WindowText);
|
|
} else {
|
|
cellTextColor = Qt::darkRed;
|
|
}
|
|
cellBackgroundColor = palette().color(QPalette::Window);
|
|
|
|
// Set the text to the short day name and bold it
|
|
cellFont.setBold(true);
|
|
cellText = locale().dayName(cellWeekDay, QLocale::ShortFormat);
|
|
|
|
} else {
|
|
// We are drawing a day cell
|
|
|
|
// Calculate the date the cell represents
|
|
QDate cellDate = dateFromPos(pos);
|
|
|
|
bool validDay = cellDate.isValid();
|
|
|
|
// Draw the day number in the cell, if the date is not valid then we don't want to show it
|
|
if (validDay) {
|
|
cellText = locale().toString(cellDate.day());
|
|
} else {
|
|
cellText = QString();
|
|
}
|
|
|
|
if (!validDay || cellDate.month() != d->m_date.month()) {
|
|
// we are either
|
|
// ° painting an invalid day
|
|
// ° painting a day of the previous month or
|
|
// ° painting a day of the following month or
|
|
cellBackgroundColor = palette().color(backgroundRole());
|
|
cellTextColor = palette().color(QPalette::Disabled, QPalette::Text);
|
|
} else {
|
|
// Paint a day of the current month
|
|
|
|
// Background Colour priorities will be (high-to-low):
|
|
// * Selected Day Background Colour
|
|
// * Customized Day Background Colour
|
|
// * Normal Day Background Colour
|
|
|
|
// Background Shape priorities will be (high-to-low):
|
|
// * Customized Day Shape
|
|
// * Normal Day Shape
|
|
|
|
// Text Colour priorities will be (high-to-low):
|
|
// * Customized Day Colour
|
|
// * Day of Pray Colour (Red letter)
|
|
// * Selected Day Colour
|
|
// * Normal Day Colour
|
|
|
|
// Determine various characteristics of the cell date
|
|
bool selectedDay = (cellDate == date());
|
|
bool currentDay = (cellDate == QDate::currentDate());
|
|
bool dayOfPray = (cellDate.dayOfWeek() == Qt::Sunday);
|
|
// TODO: Uncomment if QLocale ever gets the feature...
|
|
// bool dayOfPray = ( cellDate.dayOfWeek() == locale().dayOfPray() );
|
|
bool customDay = (d->m_useCustomColors && d->m_customPaintingModes.contains(cellDate.toJulianDay()));
|
|
|
|
// Default values for a normal cell
|
|
cellBackgroundColor = palette().color(backgroundRole());
|
|
cellTextColor = palette().color(foregroundRole());
|
|
|
|
// If we are drawing the current date, then draw it bold and active
|
|
if (currentDay) {
|
|
cellFont.setBold(true);
|
|
cellTextColor = palette().color(QPalette::LinkVisited);
|
|
}
|
|
|
|
// if we are drawing the day cell currently selected in the table
|
|
if (selectedDay) {
|
|
// set the background to highlighted
|
|
cellBackgroundColor = palette().color(QPalette::Highlight);
|
|
cellTextColor = palette().color(QPalette::HighlightedText);
|
|
}
|
|
|
|
// If custom colors or shape are required for this date
|
|
if (customDay) {
|
|
KDateTablePrivate::DatePaintingMode mode = d->m_customPaintingModes[cellDate.toJulianDay()];
|
|
if (mode.bgMode != NoBgMode) {
|
|
if (!selectedDay) {
|
|
cellBackgroundColor = mode.bgColor;
|
|
}
|
|
}
|
|
cellTextColor = mode.fgColor;
|
|
}
|
|
|
|
// If the cell day is the day of religious observance, then always color text red unless Custom overrides
|
|
if (!customDay && dayOfPray) {
|
|
cellTextColor = Qt::darkRed;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Draw the background
|
|
if (row == 0) {
|
|
painter->setPen(cellBackgroundColor);
|
|
painter->setBrush(cellBackgroundColor);
|
|
painter->drawRect(cell);
|
|
} else if (cellBackgroundColor != palette().color(backgroundRole()) || pos == d->m_hoveredPos) {
|
|
QStyleOptionViewItem opt;
|
|
opt.initFrom(this);
|
|
opt.rect = cell.toRect();
|
|
if (cellBackgroundColor != palette().color(backgroundRole())) {
|
|
opt.palette.setBrush(QPalette::Highlight, cellBackgroundColor);
|
|
opt.state |= QStyle::State_Selected;
|
|
}
|
|
if (pos == d->m_hoveredPos && opt.state & QStyle::State_Enabled) {
|
|
opt.state |= QStyle::State_MouseOver;
|
|
} else {
|
|
opt.state &= ~QStyle::State_MouseOver;
|
|
}
|
|
opt.showDecorationSelected = true;
|
|
opt.viewItemPosition = QStyleOptionViewItem::OnlyOne;
|
|
style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, this);
|
|
}
|
|
|
|
// Draw the text
|
|
painter->setPen(cellTextColor);
|
|
painter->setFont(cellFont);
|
|
painter->drawText(cell, Qt::AlignCenter, cellText, &cell);
|
|
|
|
// Draw the base line
|
|
if (row == 0) {
|
|
painter->setPen(palette().color(foregroundRole()));
|
|
painter->drawLine(QPointF(0, h), QPointF(w, h));
|
|
}
|
|
|
|
// If the day cell we just drew is bigger than the current max cell sizes,
|
|
// then adjust the max to the current cell
|
|
if (cell.width() > d->m_maxCell.width()) {
|
|
d->m_maxCell.setWidth(cell.width());
|
|
}
|
|
if (cell.height() > d->m_maxCell.height()) {
|
|
d->m_maxCell.setHeight(cell.height());
|
|
}
|
|
}
|
|
|
|
void KDateTable::KDateTablePrivate::nextMonth()
|
|
{
|
|
// setDate does validity checking for us
|
|
q->setDate(m_date.addMonths(1));
|
|
}
|
|
|
|
void KDateTable::KDateTablePrivate::previousMonth()
|
|
{
|
|
// setDate does validity checking for us
|
|
q->setDate(m_date.addMonths(-1));
|
|
}
|
|
|
|
void KDateTable::KDateTablePrivate::beginningOfMonth()
|
|
{
|
|
// setDate does validity checking for us
|
|
q->setDate(QDate(m_date.year(), m_date.month(), 1));
|
|
}
|
|
|
|
void KDateTable::KDateTablePrivate::endOfMonth()
|
|
{
|
|
// setDate does validity checking for us
|
|
q->setDate(QDate(m_date.year(), m_date.month() + 1, 0));
|
|
}
|
|
|
|
// JPL Do these make the assumption that first day of week is weekday 1? As it may not be.
|
|
void KDateTable::KDateTablePrivate::beginningOfWeek()
|
|
{
|
|
// setDate does validity checking for us
|
|
q->setDate(m_date.addDays(1 - m_date.dayOfWeek()));
|
|
}
|
|
|
|
// JPL Do these make the assumption that first day of week is weekday 1? As it may not be.
|
|
void KDateTable::KDateTablePrivate::endOfWeek()
|
|
{
|
|
// setDate does validity checking for us
|
|
q->setDate(m_date.addDays(7 - m_date.dayOfWeek()));
|
|
}
|
|
|
|
void KDateTable::keyPressEvent(QKeyEvent *e)
|
|
{
|
|
switch (e->key()) {
|
|
case Qt::Key_Up:
|
|
// setDate does validity checking for us
|
|
setDate(d->m_date.addDays(-d->m_numDayColumns));
|
|
break;
|
|
case Qt::Key_Down:
|
|
// setDate does validity checking for us
|
|
setDate(d->m_date.addDays(d->m_numDayColumns));
|
|
break;
|
|
case Qt::Key_Left:
|
|
// setDate does validity checking for us
|
|
setDate(d->m_date.addDays(-1));
|
|
break;
|
|
case Qt::Key_Right:
|
|
// setDate does validity checking for us
|
|
setDate(d->m_date.addDays(1));
|
|
break;
|
|
case Qt::Key_Minus:
|
|
// setDate does validity checking for us
|
|
setDate(d->m_date.addDays(-1));
|
|
break;
|
|
case Qt::Key_Plus:
|
|
// setDate does validity checking for us
|
|
setDate(d->m_date.addDays(1));
|
|
break;
|
|
case Qt::Key_N:
|
|
// setDate does validity checking for us
|
|
setDate(QDate::currentDate());
|
|
break;
|
|
case Qt::Key_Return:
|
|
case Qt::Key_Enter:
|
|
Q_EMIT tableClicked();
|
|
break;
|
|
case Qt::Key_Control:
|
|
case Qt::Key_Alt:
|
|
case Qt::Key_Meta:
|
|
case Qt::Key_Shift:
|
|
// Don't beep for modifiers
|
|
break;
|
|
default:
|
|
if (!e->modifiers()) { // hm
|
|
QApplication::beep();
|
|
}
|
|
}
|
|
}
|
|
|
|
void KDateTable::setFontSize(int size)
|
|
{
|
|
QFontMetricsF metrics(fontMetrics());
|
|
QRectF rect;
|
|
// ----- store rectangles:
|
|
d->fontsize = size;
|
|
// ----- find largest day name:
|
|
d->m_maxCell.setWidth(0);
|
|
d->m_maxCell.setHeight(0);
|
|
for (int weekday = 1; weekday <= 7; ++weekday) {
|
|
rect = metrics.boundingRect(locale().dayName(weekday, QLocale::ShortFormat));
|
|
d->m_maxCell.setWidth(qMax(d->m_maxCell.width(), rect.width()));
|
|
d->m_maxCell.setHeight(qMax(d->m_maxCell.height(), rect.height()));
|
|
}
|
|
// ----- compare with a real wide number and add some space:
|
|
rect = metrics.boundingRect(QStringLiteral("88"));
|
|
d->m_maxCell.setWidth(qMax(d->m_maxCell.width() + 2, rect.width()));
|
|
d->m_maxCell.setHeight(qMax(d->m_maxCell.height() + 4, rect.height()));
|
|
}
|
|
|
|
void KDateTable::wheelEvent(QWheelEvent *e)
|
|
{
|
|
setDate(d->m_date.addMonths(-(int)(e->angleDelta().y() / 120)));
|
|
e->accept();
|
|
}
|
|
|
|
bool KDateTable::event(QEvent *ev)
|
|
{
|
|
switch (ev->type()) {
|
|
case QEvent::HoverMove: {
|
|
QHoverEvent *e = static_cast<QHoverEvent *>(ev);
|
|
const int row = e->position().y() * d->m_numWeekRows / height();
|
|
int col;
|
|
if (layoutDirection() == Qt::RightToLeft) {
|
|
col = d->m_numDayColumns - (e->position().x() * d->m_numDayColumns / width()) - 1;
|
|
} else {
|
|
col = e->position().x() * d->m_numDayColumns / width();
|
|
}
|
|
|
|
const int pos = row < 1 ? -1 : (d->m_numDayColumns * (row - 1)) + col;
|
|
|
|
if (pos != d->m_hoveredPos) {
|
|
d->m_hoveredPos = pos;
|
|
update();
|
|
}
|
|
break;
|
|
}
|
|
case QEvent::HoverLeave:
|
|
if (d->m_hoveredPos != -1) {
|
|
d->m_hoveredPos = -1;
|
|
update();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return QWidget::event(ev);
|
|
}
|
|
|
|
void KDateTable::mousePressEvent(QMouseEvent *e)
|
|
{
|
|
if (e->type() != QEvent::MouseButtonPress) { // the KDatePicker only reacts on mouse press events:
|
|
return;
|
|
}
|
|
|
|
if (!isEnabled()) {
|
|
QApplication::beep();
|
|
return;
|
|
}
|
|
|
|
int row;
|
|
int col;
|
|
int pos;
|
|
|
|
QPoint mouseCoord = e->pos();
|
|
row = mouseCoord.y() * d->m_numWeekRows / height();
|
|
if (layoutDirection() == Qt::RightToLeft) {
|
|
col = d->m_numDayColumns - (mouseCoord.x() * d->m_numDayColumns / width()) - 1;
|
|
} else {
|
|
col = mouseCoord.x() * d->m_numDayColumns / width();
|
|
}
|
|
|
|
if (row < 1 || col < 0) { // the user clicked on the frame of the table
|
|
return;
|
|
}
|
|
|
|
// Rows and columns are zero indexed. The (row - 1) below is to avoid counting
|
|
// the row with the days of the week in the calculation.
|
|
|
|
// new position and date
|
|
pos = (d->m_numDayColumns * (row - 1)) + col;
|
|
QDate clickedDate = dateFromPos(pos);
|
|
|
|
// set the new date. If it is in the previous or next month, the month will
|
|
// automatically be changed, no need to do that manually...
|
|
// validity checking done inside setDate
|
|
setDate(clickedDate);
|
|
|
|
// This could be optimized to only call update over the regions
|
|
// of old and new cell, but 99% of times there is also a call to
|
|
// setDate that already calls update() so no need to optimize that
|
|
// much here
|
|
update();
|
|
|
|
Q_EMIT tableClicked();
|
|
|
|
if (e->button() == Qt::RightButton && d->m_popupMenuEnabled) {
|
|
QMenu *menu = new QMenu();
|
|
menu->addSection(locale().toString(d->m_date));
|
|
Q_EMIT aboutToShowContextMenu(menu, clickedDate);
|
|
menu->popup(e->globalPosition().toPoint());
|
|
}
|
|
}
|
|
|
|
void KDateTable::KDateTablePrivate::setDate(const QDate &date)
|
|
{
|
|
m_date = date;
|
|
m_weekDayFirstOfMonth = QDate(date.year(), date.month(), 1).dayOfWeek();
|
|
m_numDaysThisMonth = m_date.daysInMonth();
|
|
m_numDayColumns = 7;
|
|
}
|
|
|
|
bool KDateTable::setDate(const QDate &toDate)
|
|
{
|
|
if (!toDate.isValid()) {
|
|
return false;
|
|
}
|
|
|
|
if (toDate == date()) {
|
|
return true;
|
|
}
|
|
|
|
d->setDate(toDate);
|
|
Q_EMIT dateChanged(date());
|
|
update();
|
|
|
|
return true;
|
|
}
|
|
|
|
const QDate &KDateTable::date() const
|
|
{
|
|
return d->m_date;
|
|
}
|
|
|
|
void KDateTable::focusInEvent(QFocusEvent *e)
|
|
{
|
|
QWidget::focusInEvent(e);
|
|
}
|
|
|
|
void KDateTable::focusOutEvent(QFocusEvent *e)
|
|
{
|
|
QWidget::focusOutEvent(e);
|
|
}
|
|
|
|
QSize KDateTable::sizeHint() const
|
|
{
|
|
if (d->m_maxCell.height() > 0 && d->m_maxCell.width() > 0) {
|
|
return QSize(qRound(d->m_maxCell.width() * d->m_numDayColumns), (qRound(d->m_maxCell.height() + 2) * d->m_numWeekRows));
|
|
} else {
|
|
// qCDebug(KWidgetsAddonsLog) << "KDateTable::sizeHint: obscure failure - " << endl;
|
|
return QSize(-1, -1);
|
|
}
|
|
}
|
|
|
|
void KDateTable::setPopupMenuEnabled(bool enable)
|
|
{
|
|
d->m_popupMenuEnabled = enable;
|
|
}
|
|
|
|
bool KDateTable::popupMenuEnabled() const
|
|
{
|
|
return d->m_popupMenuEnabled;
|
|
}
|
|
|
|
void KDateTable::setCustomDatePainting(const QDate &date, const QColor &fgColor, BackgroundMode bgMode, const QColor &bgColor)
|
|
{
|
|
if (!fgColor.isValid()) {
|
|
unsetCustomDatePainting(date);
|
|
return;
|
|
}
|
|
|
|
KDateTablePrivate::DatePaintingMode mode;
|
|
mode.bgMode = bgMode;
|
|
mode.fgColor = fgColor;
|
|
mode.bgColor = bgColor;
|
|
|
|
d->m_customPaintingModes.insert(date.toJulianDay(), mode);
|
|
d->m_useCustomColors = true;
|
|
update();
|
|
}
|
|
|
|
void KDateTable::unsetCustomDatePainting(const QDate &date)
|
|
{
|
|
d->m_customPaintingModes.remove(date.toJulianDay());
|
|
if (d->m_customPaintingModes.isEmpty()) {
|
|
d->m_useCustomColors = false;
|
|
}
|
|
update();
|
|
}
|
|
|
|
#include "moc_kdatetable_p.cpp"
|