/****************************************************************************+ −
**+ −
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).+ −
** All rights reserved.+ −
** Contact: Nokia Corporation (qt-info@nokia.com)+ −
**+ −
** This file is part of the QtGui module of the Qt Toolkit.+ −
**+ −
** $QT_BEGIN_LICENSE:LGPL$+ −
** No Commercial Usage+ −
** This file contains pre-release code and may not be distributed.+ −
** You may use this file in accordance with the terms and conditions+ −
** contained in the Technology Preview License Agreement accompanying+ −
** this package.+ −
**+ −
** GNU Lesser General Public License Usage+ −
** Alternatively, this file may be used under the terms of the GNU Lesser+ −
** General Public License version 2.1 as published by the Free Software+ −
** Foundation and appearing in the file LICENSE.LGPL included in the+ −
** packaging of this file. Please review the following information to+ −
** ensure the GNU Lesser General Public License version 2.1 requirements+ −
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.+ −
**+ −
** In addition, as a special exception, Nokia gives you certain additional+ −
** rights. These rights are described in the Nokia Qt LGPL Exception+ −
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.+ −
**+ −
** If you have questions regarding the use of this file, please contact+ −
** Nokia at qt-info@nokia.com.+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
** $QT_END_LICENSE$+ −
**+ −
****************************************************************************/+ −
+ −
#include "qcalendarwidget.h"+ −
+ −
#ifndef QT_NO_CALENDARWIDGET+ −
+ −
#include <qabstractitemmodel.h>+ −
#include <qitemdelegate.h>+ −
#include <qdatetime.h>+ −
#include <qtableview.h>+ −
#include <qlayout.h>+ −
#include <qevent.h>+ −
#include <qtextformat.h>+ −
#include <qheaderview.h>+ −
#include <private/qwidget_p.h>+ −
#include <qpushbutton.h>+ −
#include <qtoolbutton.h>+ −
#include <qlabel.h>+ −
#include <qspinbox.h>+ −
#include <qmenu.h>+ −
#include <qapplication.h>+ −
#include <qbasictimer.h>+ −
#include <qstylepainter.h>+ −
#include <private/qcalendartextnavigator_p.h>+ −
+ −
QT_BEGIN_NAMESPACE+ −
+ −
enum {+ −
RowCount = 6,+ −
ColumnCount = 7,+ −
HeaderColumn = 0,+ −
HeaderRow = 0,+ −
MinimumDayOffset = 1+ −
};+ −
+ −
class QCalendarDateSectionValidator+ −
{+ −
public:+ −
+ −
enum Section {+ −
NextSection,+ −
ThisSection,+ −
PrevSection+ −
};+ −
+ −
QCalendarDateSectionValidator() {}+ −
virtual ~QCalendarDateSectionValidator() {}+ −
virtual Section handleKey(int key) = 0;+ −
virtual QDate applyToDate(const QDate &date) const = 0;+ −
virtual void setDate(const QDate &date) = 0;+ −
virtual QString text() const = 0;+ −
virtual QString text(const QDate &date, int repeat) const = 0;+ −
+ −
QLocale m_locale;+ −
+ −
protected:+ −
QString highlightString(const QString &str, int pos) const;+ −
private:+ −
};+ −
+ −
QString QCalendarDateSectionValidator::highlightString(const QString &str, int pos) const+ −
{+ −
if (pos == 0)+ −
return QLatin1String("<b>") + str + QLatin1String("</b>");+ −
int startPos = str.length() - pos;+ −
return str.mid(0, startPos) + QLatin1String("<b>") + str.mid(startPos, pos) + QLatin1String("</b>");+ −
+ −
}+ −
+ −
class QCalendarDayValidator : public QCalendarDateSectionValidator+ −
{+ −
+ −
public:+ −
QCalendarDayValidator();+ −
virtual Section handleKey(int key);+ −
virtual QDate applyToDate(const QDate &date) const;+ −
virtual void setDate(const QDate &date);+ −
virtual QString text() const;+ −
virtual QString text(const QDate &date, int repeat) const;+ −
private:+ −
int m_pos;+ −
int m_day;+ −
int m_oldDay;+ −
};+ −
+ −
QCalendarDayValidator::QCalendarDayValidator()+ −
: QCalendarDateSectionValidator(), m_pos(0), m_day(1), m_oldDay(1)+ −
{+ −
}+ −
+ −
QCalendarDateSectionValidator::Section QCalendarDayValidator::handleKey(int key)+ −
{+ −
if (key == Qt::Key_Right || key == Qt::Key_Left) {+ −
m_pos = 0;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
} else if (key == Qt::Key_Up) {+ −
m_pos = 0;+ −
++m_day;+ −
if (m_day > 31)+ −
m_day = 1;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
} else if (key == Qt::Key_Down) {+ −
m_pos = 0;+ −
--m_day;+ −
if (m_day < 1)+ −
m_day = 31;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
} else if (key == Qt::Key_Back || key == Qt::Key_Backspace) {+ −
--m_pos;+ −
if (m_pos < 0)+ −
m_pos = 1;+ −
+ −
if (m_pos == 0)+ −
m_day = m_oldDay;+ −
else+ −
m_day = m_day / 10;+ −
//m_day = m_oldDay / 10 * 10 + m_day / 10;+ −
+ −
if (m_pos == 0)+ −
return QCalendarDateSectionValidator::PrevSection;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
}+ −
if (key < Qt::Key_0 || key > Qt::Key_9)+ −
return QCalendarDateSectionValidator::ThisSection;+ −
int pressedKey = key - Qt::Key_0;+ −
if (m_pos == 0)+ −
m_day = pressedKey;+ −
else+ −
m_day = m_day % 10 * 10 + pressedKey;+ −
if (m_day > 31)+ −
m_day = 31;+ −
++m_pos;+ −
if (m_pos > 1) {+ −
m_pos = 0;+ −
return QCalendarDateSectionValidator::NextSection;+ −
}+ −
return QCalendarDateSectionValidator::ThisSection;+ −
}+ −
+ −
QDate QCalendarDayValidator::applyToDate(const QDate &date) const+ −
{+ −
int day = m_day;+ −
if (day < 1)+ −
day = 1;+ −
else if (day > 31)+ −
day = 31;+ −
if (day > date.daysInMonth())+ −
day = date.daysInMonth();+ −
return QDate(date.year(), date.month(), day);+ −
}+ −
+ −
void QCalendarDayValidator::setDate(const QDate &date)+ −
{+ −
m_day = m_oldDay = date.day();+ −
m_pos = 0;+ −
}+ −
+ −
QString QCalendarDayValidator::text() const+ −
{+ −
QString str;+ −
if (m_day / 10 == 0)+ −
str += QLatin1Char('0');+ −
str += QString::number(m_day);+ −
return highlightString(str, m_pos);+ −
}+ −
+ −
QString QCalendarDayValidator::text(const QDate &date, int repeat) const+ −
{+ −
if (repeat <= 1) {+ −
return QString::number(date.day());+ −
} else if (repeat == 2) {+ −
QString str;+ −
if (date.day() / 10 == 0)+ −
str += QLatin1Char('0');+ −
return str + QString::number(date.day());+ −
} else if (repeat == 3) {+ −
return m_locale.dayName(date.dayOfWeek(), QLocale::ShortFormat);+ −
} else if (repeat >= 4) {+ −
return m_locale.dayName(date.dayOfWeek(), QLocale::LongFormat);+ −
}+ −
return QString();+ −
}+ −
+ −
//////////////////////////////////+ −
+ −
class QCalendarMonthValidator : public QCalendarDateSectionValidator+ −
{+ −
+ −
public:+ −
QCalendarMonthValidator();+ −
virtual Section handleKey(int key);+ −
virtual QDate applyToDate(const QDate &date) const;+ −
virtual void setDate(const QDate &date);+ −
virtual QString text() const;+ −
virtual QString text(const QDate &date, int repeat) const;+ −
private:+ −
int m_pos;+ −
int m_month;+ −
int m_oldMonth;+ −
};+ −
+ −
QCalendarMonthValidator::QCalendarMonthValidator()+ −
: QCalendarDateSectionValidator(), m_pos(0), m_month(1), m_oldMonth(1)+ −
{+ −
}+ −
+ −
QCalendarDateSectionValidator::Section QCalendarMonthValidator::handleKey(int key)+ −
{+ −
if (key == Qt::Key_Right || key == Qt::Key_Left) {+ −
m_pos = 0;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
} else if (key == Qt::Key_Up) {+ −
m_pos = 0;+ −
++m_month;+ −
if (m_month > 12)+ −
m_month = 1;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
} else if (key == Qt::Key_Down) {+ −
m_pos = 0;+ −
--m_month;+ −
if (m_month < 1)+ −
m_month = 12;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
} else if (key == Qt::Key_Back || key == Qt::Key_Backspace) {+ −
--m_pos;+ −
if (m_pos < 0)+ −
m_pos = 1;+ −
+ −
if (m_pos == 0)+ −
m_month = m_oldMonth;+ −
else+ −
m_month = m_month / 10;+ −
//m_month = m_oldMonth / 10 * 10 + m_month / 10;+ −
+ −
if (m_pos == 0)+ −
return QCalendarDateSectionValidator::PrevSection;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
}+ −
if (key < Qt::Key_0 || key > Qt::Key_9)+ −
return QCalendarDateSectionValidator::ThisSection;+ −
int pressedKey = key - Qt::Key_0;+ −
if (m_pos == 0)+ −
m_month = pressedKey;+ −
else+ −
m_month = m_month % 10 * 10 + pressedKey;+ −
if (m_month > 12)+ −
m_month = 12;+ −
++m_pos;+ −
if (m_pos > 1) {+ −
m_pos = 0;+ −
return QCalendarDateSectionValidator::NextSection;+ −
}+ −
return QCalendarDateSectionValidator::ThisSection;+ −
}+ −
+ −
QDate QCalendarMonthValidator::applyToDate(const QDate &date) const+ −
{+ −
int month = m_month;+ −
if (month < 1)+ −
month = 1;+ −
else if (month > 12)+ −
month = 12;+ −
QDate newDate(date.year(), m_month, 1);+ −
int day = date.day();+ −
if (day > newDate.daysInMonth())+ −
day = newDate.daysInMonth();+ −
return QDate(date.year(), month, day);+ −
}+ −
+ −
void QCalendarMonthValidator::setDate(const QDate &date)+ −
{+ −
m_month = m_oldMonth = date.month();+ −
m_pos = 0;+ −
}+ −
+ −
QString QCalendarMonthValidator::text() const+ −
{+ −
QString str;+ −
if (m_month / 10 == 0)+ −
str += QLatin1Char('0');+ −
str += QString::number(m_month);+ −
return highlightString(str, m_pos);+ −
}+ −
+ −
QString QCalendarMonthValidator::text(const QDate &date, int repeat) const+ −
{+ −
if (repeat <= 1) {+ −
return QString::number(date.month());+ −
} else if (repeat == 2) {+ −
QString str;+ −
if (date.month() / 10 == 0)+ −
str += QLatin1Char('0');+ −
return str + QString::number(date.month());+ −
} else if (repeat == 3) {+ −
return m_locale.standaloneMonthName(date.month(), QLocale::ShortFormat);+ −
} else /*if (repeat >= 4)*/ {+ −
return m_locale.standaloneMonthName(date.month(), QLocale::LongFormat);+ −
}+ −
}+ −
+ −
//////////////////////////////////+ −
+ −
class QCalendarYearValidator : public QCalendarDateSectionValidator+ −
{+ −
+ −
public:+ −
QCalendarYearValidator();+ −
virtual Section handleKey(int key);+ −
virtual QDate applyToDate(const QDate &date) const;+ −
virtual void setDate(const QDate &date);+ −
virtual QString text() const;+ −
virtual QString text(const QDate &date, int repeat) const;+ −
private:+ −
int pow10(int n);+ −
int m_pos;+ −
int m_year;+ −
int m_oldYear;+ −
};+ −
+ −
QCalendarYearValidator::QCalendarYearValidator()+ −
: QCalendarDateSectionValidator(), m_pos(0), m_year(2000), m_oldYear(2000)+ −
{+ −
}+ −
+ −
int QCalendarYearValidator::pow10(int n)+ −
{+ −
int power = 1;+ −
for (int i = 0; i < n; i++)+ −
power *= 10;+ −
return power;+ −
}+ −
+ −
QCalendarDateSectionValidator::Section QCalendarYearValidator::handleKey(int key)+ −
{+ −
if (key == Qt::Key_Right || key == Qt::Key_Left) {+ −
m_pos = 0;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
} else if (key == Qt::Key_Up) {+ −
m_pos = 0;+ −
++m_year;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
} else if (key == Qt::Key_Down) {+ −
m_pos = 0;+ −
--m_year;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
} else if (key == Qt::Key_Back || key == Qt::Key_Backspace) {+ −
--m_pos;+ −
if (m_pos < 0)+ −
m_pos = 3;+ −
+ −
int pow = pow10(m_pos);+ −
m_year = m_oldYear / pow * pow + m_year % (pow * 10) / 10;+ −
+ −
if (m_pos == 0)+ −
return QCalendarDateSectionValidator::PrevSection;+ −
return QCalendarDateSectionValidator::ThisSection;+ −
}+ −
if (key < Qt::Key_0 || key > Qt::Key_9)+ −
return QCalendarDateSectionValidator::ThisSection;+ −
int pressedKey = key - Qt::Key_0;+ −
int pow = pow10(m_pos);+ −
m_year = m_year / (pow * 10) * (pow * 10) + m_year % pow * 10 + pressedKey;+ −
++m_pos;+ −
if (m_pos > 3) {+ −
m_pos = 0;+ −
return QCalendarDateSectionValidator::NextSection;+ −
}+ −
return QCalendarDateSectionValidator::ThisSection;+ −
}+ −
+ −
QDate QCalendarYearValidator::applyToDate(const QDate &date) const+ −
{+ −
int year = m_year;+ −
if (year < 1)+ −
year = 1;+ −
QDate newDate(year, date.month(), 1);+ −
int day = date.day();+ −
if (day > newDate.daysInMonth())+ −
day = newDate.daysInMonth();+ −
return QDate(year, date.month(), day);+ −
}+ −
+ −
void QCalendarYearValidator::setDate(const QDate &date)+ −
{+ −
m_year = m_oldYear = date.year();+ −
m_pos = 0;+ −
}+ −
+ −
QString QCalendarYearValidator::text() const+ −
{+ −
QString str;+ −
int pow = 10;+ −
for (int i = 0; i < 3; i++) {+ −
if (m_year / pow == 0)+ −
str += QLatin1Char('0');+ −
pow *= 10;+ −
}+ −
str += QString::number(m_year);+ −
return highlightString(str, m_pos);+ −
}+ −
+ −
QString QCalendarYearValidator::text(const QDate &date, int repeat) const+ −
{+ −
if (repeat < 4) {+ −
QString str;+ −
int year = date.year() % 100;+ −
if (year / 10 == 0)+ −
str = QLatin1Char('0');+ −
return str + QString::number(year);+ −
}+ −
return QString::number(date.year());+ −
}+ −
+ −
///////////////////////////////////+ −
+ −
class QCalendarDateValidator+ −
{+ −
public:+ −
QCalendarDateValidator();+ −
~QCalendarDateValidator();+ −
+ −
void handleKeyEvent(QKeyEvent *keyEvent);+ −
QString currentText() const;+ −
QDate currentDate() const { return m_currentDate; }+ −
void setFormat(const QString &format);+ −
void setInitialDate(const QDate &date);+ −
+ −
void setLocale(const QLocale &locale);+ −
+ −
private:+ −
+ −
struct SectionToken {+ −
SectionToken(QCalendarDateSectionValidator *val, int rep) : validator(val), repeat(rep) {}+ −
QCalendarDateSectionValidator *validator;+ −
int repeat;+ −
};+ −
+ −
void toNextToken();+ −
void toPreviousToken();+ −
void applyToDate();+ −
+ −
int countRepeat(const QString &str, int index) const;+ −
void clear();+ −
+ −
QStringList m_separators;+ −
QList<SectionToken *> m_tokens;+ −
QCalendarDateSectionValidator *m_yearValidator;+ −
QCalendarDateSectionValidator *m_monthValidator;+ −
QCalendarDateSectionValidator *m_dayValidator;+ −
+ −
SectionToken *m_currentToken;+ −
+ −
QDate m_initialDate;+ −
QDate m_currentDate;+ −
+ −
QCalendarDateSectionValidator::Section m_lastSectionMove;+ −
};+ −
+ −
QCalendarDateValidator::QCalendarDateValidator()+ −
: m_currentToken(0), m_lastSectionMove(QCalendarDateSectionValidator::ThisSection)+ −
{+ −
m_initialDate = m_currentDate = QDate::currentDate();+ −
m_yearValidator = new QCalendarYearValidator();+ −
m_monthValidator = new QCalendarMonthValidator();+ −
m_dayValidator = new QCalendarDayValidator();+ −
}+ −
+ −
void QCalendarDateValidator::setLocale(const QLocale &locale)+ −
{+ −
m_yearValidator->m_locale = locale;+ −
m_monthValidator->m_locale = locale;+ −
m_dayValidator->m_locale = locale;+ −
}+ −
+ −
QCalendarDateValidator::~QCalendarDateValidator()+ −
{+ −
delete m_yearValidator;+ −
delete m_monthValidator;+ −
delete m_dayValidator;+ −
clear();+ −
}+ −
+ −
// from qdatetime.cpp+ −
int QCalendarDateValidator::countRepeat(const QString &str, int index) const+ −
{+ −
Q_ASSERT(index >= 0 && index < str.size());+ −
int count = 1;+ −
const QChar ch = str.at(index);+ −
while (index + count < str.size() && str.at(index + count) == ch)+ −
++count;+ −
return count;+ −
}+ −
+ −
void QCalendarDateValidator::setInitialDate(const QDate &date)+ −
{+ −
m_yearValidator->setDate(date);+ −
m_monthValidator->setDate(date);+ −
m_dayValidator->setDate(date);+ −
m_initialDate = date;+ −
m_currentDate = date;+ −
m_lastSectionMove = QCalendarDateSectionValidator::ThisSection;+ −
}+ −
+ −
QString QCalendarDateValidator::currentText() const+ −
{+ −
QString str;+ −
QStringListIterator itSep(m_separators);+ −
QListIterator<SectionToken *> itTok(m_tokens);+ −
while (itSep.hasNext()) {+ −
str += itSep.next();+ −
if (itTok.hasNext()) {+ −
SectionToken *token = itTok.next();+ −
QCalendarDateSectionValidator *validator = token->validator;+ −
if (m_currentToken == token)+ −
str += validator->text();+ −
else+ −
str += validator->text(m_currentDate, token->repeat);+ −
}+ −
}+ −
return str;+ −
}+ −
+ −
void QCalendarDateValidator::clear()+ −
{+ −
QListIterator<SectionToken *> it(m_tokens);+ −
while (it.hasNext())+ −
delete it.next();+ −
+ −
m_tokens.clear();+ −
m_separators.clear();+ −
+ −
m_currentToken = 0;+ −
}+ −
+ −
void QCalendarDateValidator::setFormat(const QString &format)+ −
{+ −
clear();+ −
+ −
int pos = 0;+ −
const QLatin1Char quote('\'');+ −
bool quoting = false;+ −
QString separator;+ −
while (pos < format.size()) {+ −
QString mid = format.mid(pos);+ −
int offset = 1;+ −
+ −
if (mid.startsWith(quote)) {+ −
quoting = !quoting;+ −
} else {+ −
const QChar nextChar = format.at(pos);+ −
if (quoting) {+ −
separator += nextChar;+ −
} else {+ −
SectionToken *token = 0;+ −
if (nextChar == QLatin1Char('d')) {+ −
offset = qMin(4, countRepeat(format, pos));+ −
token = new SectionToken(m_dayValidator, offset);+ −
} else if (nextChar == QLatin1Char('M')) {+ −
offset = qMin(4, countRepeat(format, pos));+ −
token = new SectionToken(m_monthValidator, offset);+ −
} else if (nextChar == QLatin1Char('y')) {+ −
offset = qMin(4, countRepeat(format, pos));+ −
token = new SectionToken(m_yearValidator, offset);+ −
} else {+ −
separator += nextChar;+ −
}+ −
if (token) {+ −
m_tokens.append(token);+ −
m_separators.append(separator);+ −
separator = QString();+ −
if (!m_currentToken)+ −
m_currentToken = token;+ −
+ −
}+ −
}+ −
}+ −
pos += offset;+ −
}+ −
m_separators += separator;+ −
}+ −
+ −
void QCalendarDateValidator::applyToDate()+ −
{+ −
m_currentDate = m_yearValidator->applyToDate(m_currentDate);+ −
m_currentDate = m_monthValidator->applyToDate(m_currentDate);+ −
m_currentDate = m_dayValidator->applyToDate(m_currentDate);+ −
}+ −
+ −
void QCalendarDateValidator::toNextToken()+ −
{+ −
const int idx = m_tokens.indexOf(m_currentToken);+ −
if (idx == -1)+ −
return;+ −
if (idx + 1 >= m_tokens.count())+ −
m_currentToken = m_tokens.first();+ −
else+ −
m_currentToken = m_tokens.at(idx + 1);+ −
}+ −
+ −
void QCalendarDateValidator::toPreviousToken()+ −
{+ −
const int idx = m_tokens.indexOf(m_currentToken);+ −
if (idx == -1)+ −
return;+ −
if (idx - 1 < 0)+ −
m_currentToken = m_tokens.last();+ −
else+ −
m_currentToken = m_tokens.at(idx - 1);+ −
}+ −
+ −
void QCalendarDateValidator::handleKeyEvent(QKeyEvent *keyEvent)+ −
{+ −
if (!m_currentToken)+ −
return;+ −
+ −
int key = keyEvent->key();+ −
if (m_lastSectionMove == QCalendarDateSectionValidator::NextSection) {+ −
if (key == Qt::Key_Back || key == Qt::Key_Backspace)+ −
toPreviousToken();+ −
}+ −
if (key == Qt::Key_Right)+ −
toNextToken();+ −
else if (key == Qt::Key_Left)+ −
toPreviousToken();+ −
+ −
m_lastSectionMove = m_currentToken->validator->handleKey(key);+ −
+ −
applyToDate();+ −
if (m_lastSectionMove == QCalendarDateSectionValidator::NextSection)+ −
toNextToken();+ −
else if (m_lastSectionMove == QCalendarDateSectionValidator::PrevSection)+ −
toPreviousToken();+ −
}+ −
+ −
QWidget *QCalendarTextNavigator::widget() const+ −
{+ −
return m_widget;+ −
}+ −
+ −
void QCalendarTextNavigator::setWidget(QWidget *widget)+ −
{+ −
m_widget = widget;+ −
}+ −
+ −
QDate QCalendarTextNavigator::date() const+ −
{+ −
return m_date;+ −
}+ −
+ −
void QCalendarTextNavigator::setDate(const QDate &date)+ −
{+ −
m_date = date;+ −
}+ −
+ −
void QCalendarTextNavigator::updateDateLabel()+ −
{+ −
if (!m_widget)+ −
return;+ −
+ −
m_acceptTimer.start(m_editDelay, this);+ −
+ −
m_dateText->setText(m_dateValidator->currentText());+ −
+ −
QSize s = m_dateFrame->sizeHint();+ −
QRect r = m_widget->geometry(); // later, just the table section+ −
QRect newRect((r.width() - s.width()) / 2, (r.height() - s.height()) / 2, s.width(), s.height());+ −
m_dateFrame->setGeometry(newRect);+ −
// need to set palette after geometry update as phonestyle sets transparency+ −
// effect in move event.+ −
QPalette p = m_dateFrame->palette();+ −
p.setBrush(QPalette::Window, m_dateFrame->window()->palette().brush(QPalette::Window));+ −
m_dateFrame->setPalette(p);+ −
+ −
m_dateFrame->raise();+ −
m_dateFrame->show();+ −
}+ −
+ −
void QCalendarTextNavigator::applyDate()+ −
{+ −
QDate date = m_dateValidator->currentDate();+ −
if (m_date == date)+ −
return;+ −
+ −
m_date = date;+ −
emit dateChanged(date);+ −
}+ −
+ −
void QCalendarTextNavigator::createDateLabel()+ −
{+ −
if (m_dateFrame)+ −
return;+ −
m_dateFrame = new QFrame(m_widget);+ −
QVBoxLayout *vl = new QVBoxLayout;+ −
m_dateText = new QLabel;+ −
vl->addWidget(m_dateText);+ −
m_dateFrame->setLayout(vl);+ −
m_dateFrame->setFrameShadow(QFrame::Plain);+ −
m_dateFrame->setFrameShape(QFrame::Box);+ −
m_dateValidator = new QCalendarDateValidator();+ −
m_dateValidator->setLocale(m_widget->locale());+ −
m_dateValidator->setFormat(m_widget->locale().dateFormat(QLocale::ShortFormat));+ −
m_dateValidator->setInitialDate(m_date);+ −
+ −
m_dateFrame->setAutoFillBackground(true);+ −
m_dateFrame->setBackgroundRole(QPalette::Window);+ −
}+ −
+ −
void QCalendarTextNavigator::removeDateLabel()+ −
{+ −
if (!m_dateFrame)+ −
return;+ −
m_acceptTimer.stop();+ −
m_dateFrame->hide();+ −
m_dateFrame->deleteLater();+ −
delete m_dateValidator;+ −
m_dateFrame = 0;+ −
m_dateText = 0;+ −
m_dateValidator = 0;+ −
}+ −
+ −
bool QCalendarTextNavigator::eventFilter(QObject *o, QEvent *e)+ −
{+ −
if (m_widget) {+ −
if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) {+ −
QKeyEvent* ke = (QKeyEvent*)e;+ −
if ((ke->text().length() > 0 && ke->text()[0].isPrint()) || m_dateFrame) {+ −
if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Select) {+ −
applyDate();+ −
emit editingFinished();+ −
removeDateLabel();+ −
} else if (ke->key() == Qt::Key_Escape) {+ −
removeDateLabel();+ −
} else if (e->type() == QEvent::KeyPress) {+ −
createDateLabel();+ −
m_dateValidator->handleKeyEvent(ke);+ −
updateDateLabel();+ −
}+ −
ke->accept();+ −
return true;+ −
}+ −
// If we are navigating let the user finish his date in old locate.+ −
// If we change our mind and want it to update immediately simply uncomment below+ −
/*+ −
} else if (e->type() == QEvent::LocaleChange) {+ −
if (m_dateValidator) {+ −
m_dateValidator->setLocale(m_widget->locale());+ −
m_dateValidator->setFormat(m_widget->locale().dateFormat(QLocale::ShortFormat));+ −
updateDateLabel();+ −
}+ −
*/+ −
}+ −
}+ −
return QObject::eventFilter(o,e);+ −
}+ −
+ −
void QCalendarTextNavigator::timerEvent(QTimerEvent *e)+ −
{+ −
if (e->timerId() == m_acceptTimer.timerId()) {+ −
applyDate();+ −
removeDateLabel();+ −
}+ −
}+ −
+ −
int QCalendarTextNavigator::dateEditAcceptDelay() const+ −
{+ −
return m_editDelay;+ −
}+ −
+ −
void QCalendarTextNavigator::setDateEditAcceptDelay(int delay)+ −
{+ −
m_editDelay = delay;+ −
}+ −
+ −
class QCalendarView;+ −
+ −
class QCalendarModel : public QAbstractTableModel+ −
{+ −
Q_OBJECT+ −
public:+ −
QCalendarModel(QObject *parent = 0);+ −
+ −
int rowCount(const QModelIndex &) const+ −
{ return RowCount + m_firstRow; }+ −
int columnCount(const QModelIndex &) const+ −
{ return ColumnCount + m_firstColumn; }+ −
QVariant data(const QModelIndex &index, int role) const;+ −
Qt::ItemFlags flags(const QModelIndex &index) const;+ −
+ −
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex())+ −
{+ −
beginInsertRows(parent, row, row + count - 1);+ −
endInsertRows();+ −
return true;+ −
}+ −
bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex())+ −
{+ −
beginInsertColumns(parent, column, column + count - 1);+ −
endInsertColumns();+ −
return true;+ −
}+ −
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex())+ −
{+ −
beginRemoveRows(parent, row, row + count - 1);+ −
endRemoveRows();+ −
return true;+ −
}+ −
bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex())+ −
{+ −
beginRemoveColumns(parent, column, column + count - 1);+ −
endRemoveColumns();+ −
return true;+ −
}+ −
+ −
void showMonth(int year, int month);+ −
void setDate(const QDate &d);+ −
+ −
void setMinimumDate(const QDate &date);+ −
void setMaximumDate(const QDate &date);+ −
+ −
void setRange(const QDate &min, const QDate &max);+ −
+ −
void setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat format);+ −
+ −
void setFirstColumnDay(Qt::DayOfWeek dayOfWeek);+ −
Qt::DayOfWeek firstColumnDay() const;+ −
+ −
bool weekNumbersShown() const;+ −
void setWeekNumbersShown(bool show);+ −
+ −
QTextCharFormat formatForCell(int row, int col) const;+ −
Qt::DayOfWeek dayOfWeekForColumn(int section) const;+ −
int columnForDayOfWeek(Qt::DayOfWeek day) const;+ −
QDate dateForCell(int row, int column) const;+ −
void cellForDate(const QDate &date, int *row, int *column) const;+ −
QString dayName(Qt::DayOfWeek day) const;+ −
+ −
void setView(QCalendarView *view)+ −
{ m_view = view; }+ −
+ −
void internalUpdate();+ −
QDate referenceDate() const;+ −
int columnForFirstOfMonth(const QDate &date) const;+ −
+ −
int m_firstColumn;+ −
int m_firstRow;+ −
QDate m_date;+ −
QDate m_minimumDate;+ −
QDate m_maximumDate;+ −
int m_shownYear;+ −
int m_shownMonth;+ −
Qt::DayOfWeek m_firstDay;+ −
QCalendarWidget::HorizontalHeaderFormat m_horizontalHeaderFormat;+ −
bool m_weekNumbersShown;+ −
QMap<Qt::DayOfWeek, QTextCharFormat> m_dayFormats;+ −
QMap<QDate, QTextCharFormat> m_dateFormats;+ −
QTextCharFormat m_headerFormat;+ −
QCalendarView *m_view;+ −
};+ −
+ −
class QCalendarView : public QTableView+ −
{+ −
Q_OBJECT+ −
public:+ −
QCalendarView(QWidget *parent = 0);+ −
+ −
void internalUpdate() { updateGeometries(); }+ −
void setReadOnly(bool enable);+ −
virtual void keyboardSearch(const QString & search) { Q_UNUSED(search) }+ −
+ −
signals:+ −
void showDate(const QDate &date);+ −
void changeDate(const QDate &date, bool changeMonth);+ −
void clicked(const QDate &date);+ −
void editingFinished();+ −
protected:+ −
QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);+ −
void mouseDoubleClickEvent(QMouseEvent *event);+ −
void mousePressEvent(QMouseEvent *event);+ −
void mouseMoveEvent(QMouseEvent *event);+ −
void mouseReleaseEvent(QMouseEvent *event);+ −
#ifndef QT_NO_WHEELEVENT+ −
void wheelEvent(QWheelEvent *event);+ −
#endif+ −
void keyPressEvent(QKeyEvent *event);+ −
bool event(QEvent *event);+ −
+ −
QDate handleMouseEvent(QMouseEvent *event);+ −
public:+ −
bool readOnly;+ −
private:+ −
bool validDateClicked;+ −
#ifdef QT_KEYPAD_NAVIGATION+ −
QDate origDate;+ −
#endif+ −
};+ −
+ −
QCalendarModel::QCalendarModel(QObject *parent)+ −
: QAbstractTableModel(parent)+ −
{+ −
m_date = QDate::currentDate();+ −
m_minimumDate = QDate::fromJulianDay(1);+ −
m_maximumDate = QDate(7999, 12, 31);+ −
m_shownYear = m_date.year();+ −
m_shownMonth = m_date.month();+ −
m_firstDay = Qt::Sunday;+ −
m_horizontalHeaderFormat = QCalendarWidget::ShortDayNames;+ −
m_weekNumbersShown = true;+ −
m_firstColumn = 1;+ −
m_firstRow = 1;+ −
m_view = 0;+ −
}+ −
+ −
Qt::DayOfWeek QCalendarModel::dayOfWeekForColumn(int column) const+ −
{+ −
int col = column - m_firstColumn;+ −
if (col < 0 || col > 6)+ −
return Qt::Sunday;+ −
int day = m_firstDay + col;+ −
if (day > 7)+ −
day -= 7;+ −
return Qt::DayOfWeek(day);+ −
}+ −
+ −
int QCalendarModel::columnForDayOfWeek(Qt::DayOfWeek day) const+ −
{+ −
if (day < 1 || day > 7)+ −
return -1;+ −
int column = (int)day - (int)m_firstDay;+ −
if (column < 0)+ −
column += 7;+ −
return column + m_firstColumn;+ −
}+ −
+ −
/*+ −
This simple algorithm tries to generate a valid date from the month shown.+ −
Some months don't contain a first day (e.g. Jan of -4713 year,+ −
so QDate (-4713, 1, 1) would be invalid). In that case we try to generate+ −
another valid date for that month. Later, returned date's day is the number of cells+ −
calendar widget will reserve for days before referenceDate. (E.g. if returned date's+ −
day is 16, that day will be placed in 3rd or 4th row, not in the 1st or 2nd row).+ −
Depending on referenceData we can change behaviour of Oct 1582. If referenceDate is 1st+ −
of Oct we render 1 Oct in 1st or 2nd row. If referenceDate is 17 of Oct we show always 16+ −
dates before 17 of Oct, and since this month contains the hole 5-14 Oct, the first of Oct+ −
will be rendered in 2nd or 3rd row, showing more dates from previous month.+ −
*/+ −
QDate QCalendarModel::referenceDate() const+ −
{+ −
int refDay = 1;+ −
while (refDay <= 31) {+ −
QDate refDate(m_shownYear, m_shownMonth, refDay);+ −
if (refDate.isValid())+ −
return refDate;+ −
refDay += 1;+ −
}+ −
return QDate();+ −
}+ −
+ −
int QCalendarModel::columnForFirstOfMonth(const QDate &date) const+ −
{+ −
return (columnForDayOfWeek(static_cast<Qt::DayOfWeek>(date.dayOfWeek())) - (date.day() % 7) + 8) % 7;+ −
}+ −
+ −
QDate QCalendarModel::dateForCell(int row, int column) const+ −
{+ −
if (row < m_firstRow || row > m_firstRow + RowCount - 1 ||+ −
column < m_firstColumn || column > m_firstColumn + ColumnCount - 1)+ −
return QDate();+ −
const QDate refDate = referenceDate();+ −
if (!refDate.isValid())+ −
return QDate();+ −
+ −
const int columnForFirstOfShownMonth = columnForFirstOfMonth(refDate);+ −
if (columnForFirstOfShownMonth - m_firstColumn < MinimumDayOffset)+ −
row -= 1;+ −
+ −
const int requestedDay = 7 * (row - m_firstRow) + column - columnForFirstOfShownMonth - refDate.day() + 1;+ −
return refDate.addDays(requestedDay);+ −
}+ −
+ −
void QCalendarModel::cellForDate(const QDate &date, int *row, int *column) const+ −
{+ −
if (!row && !column)+ −
return;+ −
+ −
if (row)+ −
*row = -1;+ −
if (column)+ −
*column = -1;+ −
+ −
const QDate refDate = referenceDate();+ −
if (!refDate.isValid())+ −
return;+ −
+ −
const int columnForFirstOfShownMonth = columnForFirstOfMonth(refDate);+ −
const int requestedPosition = refDate.daysTo(date) - m_firstColumn + columnForFirstOfShownMonth + refDate.day() - 1;+ −
+ −
int c = requestedPosition % 7;+ −
int r = requestedPosition / 7;+ −
if (c < 0) {+ −
c += 7;+ −
r -= 1;+ −
}+ −
+ −
if (columnForFirstOfShownMonth - m_firstColumn < MinimumDayOffset)+ −
r += 1;+ −
+ −
if (r < 0 || r > RowCount - 1 || c < 0 || c > ColumnCount - 1)+ −
return;+ −
+ −
if (row)+ −
*row = r + m_firstRow;+ −
if (column)+ −
*column = c + m_firstColumn;+ −
}+ −
+ −
QString QCalendarModel::dayName(Qt::DayOfWeek day) const+ −
{+ −
switch (m_horizontalHeaderFormat) {+ −
case QCalendarWidget::SingleLetterDayNames: {+ −
QString standaloneDayName = m_view->locale().standaloneDayName(day, QLocale::NarrowFormat);+ −
if (standaloneDayName == m_view->locale().dayName(day, QLocale::NarrowFormat))+ −
return standaloneDayName.left(1);+ −
return standaloneDayName;+ −
}+ −
case QCalendarWidget::ShortDayNames:+ −
return m_view->locale().dayName(day, QLocale::ShortFormat);+ −
case QCalendarWidget::LongDayNames:+ −
return m_view->locale().dayName(day, QLocale::LongFormat);+ −
default:+ −
break;+ −
}+ −
return QString();+ −
}+ −
+ −
QTextCharFormat QCalendarModel::formatForCell(int row, int col) const+ −
{+ −
QPalette pal;+ −
QPalette::ColorGroup cg = QPalette::Active;+ −
if (m_view) {+ −
pal = m_view->palette();+ −
if (!m_view->isEnabled())+ −
cg = QPalette::Disabled;+ −
else if (!m_view->isActiveWindow())+ −
cg = QPalette::Inactive;+ −
}+ −
+ −
QTextCharFormat format;+ −
format.setFont(m_view->font());+ −
bool header = (m_weekNumbersShown && col == HeaderColumn)+ −
|| (m_horizontalHeaderFormat != QCalendarWidget::NoHorizontalHeader && row == HeaderRow);+ −
format.setBackground(pal.brush(cg, header ? QPalette::AlternateBase : QPalette::Base));+ −
format.setForeground(pal.brush(cg, QPalette::Text));+ −
if (header) {+ −
format.merge(m_headerFormat);+ −
}+ −
+ −
if (col >= m_firstColumn && col < m_firstColumn + ColumnCount) {+ −
Qt::DayOfWeek dayOfWeek = dayOfWeekForColumn(col);+ −
if (m_dayFormats.contains(dayOfWeek))+ −
format.merge(m_dayFormats.value(dayOfWeek));+ −
}+ −
+ −
if (!header) {+ −
QDate date = dateForCell(row, col);+ −
format.merge(m_dateFormats.value(date));+ −
if(date < m_minimumDate || date > m_maximumDate)+ −
format.setBackground(pal.brush(cg, QPalette::Window));+ −
if (m_shownMonth != date.month())+ −
format.setForeground(pal.brush(QPalette::Disabled, QPalette::Text));+ −
}+ −
return format;+ −
}+ −
+ −
QVariant QCalendarModel::data(const QModelIndex &index, int role) const+ −
{+ −
if (role == Qt::TextAlignmentRole)+ −
return (int) Qt::AlignCenter;+ −
+ −
int row = index.row();+ −
int column = index.column();+ −
+ −
if(role == Qt::DisplayRole) {+ −
if (m_weekNumbersShown && column == HeaderColumn+ −
&& row >= m_firstRow && row < m_firstRow + RowCount) {+ −
QDate date = dateForCell(row, columnForDayOfWeek(Qt::Monday));+ −
if (date.isValid())+ −
return date.weekNumber();+ −
}+ −
if (m_horizontalHeaderFormat != QCalendarWidget::NoHorizontalHeader && row == HeaderRow+ −
&& column >= m_firstColumn && column < m_firstColumn + ColumnCount)+ −
return dayName(dayOfWeekForColumn(column));+ −
QDate date = dateForCell(row, column);+ −
if (date.isValid())+ −
return date.day();+ −
return QString();+ −
}+ −
+ −
QTextCharFormat fmt = formatForCell(row, column);+ −
if (role == Qt::BackgroundColorRole)+ −
return fmt.background().color();+ −
if (role == Qt::TextColorRole)+ −
return fmt.foreground().color();+ −
if (role == Qt::FontRole)+ −
return fmt.font();+ −
if (role == Qt::ToolTipRole)+ −
return fmt.toolTip();+ −
return QVariant();+ −
}+ −
+ −
Qt::ItemFlags QCalendarModel::flags(const QModelIndex &index) const+ −
{+ −
QDate date = dateForCell(index.row(), index.column());+ −
if (!date.isValid())+ −
return QAbstractTableModel::flags(index);+ −
if (date < m_minimumDate)+ −
return 0;+ −
if (date > m_maximumDate)+ −
return 0;+ −
return QAbstractTableModel::flags(index);+ −
}+ −
+ −
void QCalendarModel::setDate(const QDate &d)+ −
{+ −
m_date = d;+ −
if (m_date < m_minimumDate)+ −
m_date = m_minimumDate;+ −
else if (m_date > m_maximumDate)+ −
m_date = m_maximumDate;+ −
}+ −
+ −
void QCalendarModel::showMonth(int year, int month)+ −
{+ −
if (m_shownYear == year && m_shownMonth == month)+ −
return;+ −
+ −
m_shownYear = year;+ −
m_shownMonth = month;+ −
+ −
internalUpdate();+ −
}+ −
+ −
void QCalendarModel::setMinimumDate(const QDate &d)+ −
{+ −
if (!d.isValid() || d == m_minimumDate)+ −
return;+ −
+ −
m_minimumDate = d;+ −
if (m_maximumDate < m_minimumDate)+ −
m_maximumDate = m_minimumDate;+ −
if (m_date < m_minimumDate)+ −
m_date = m_minimumDate;+ −
internalUpdate();+ −
}+ −
+ −
void QCalendarModel::setMaximumDate(const QDate &d)+ −
{+ −
if (!d.isValid() || d == m_maximumDate)+ −
return;+ −
+ −
m_maximumDate = d;+ −
if (m_minimumDate > m_maximumDate)+ −
m_minimumDate = m_maximumDate;+ −
if (m_date > m_maximumDate)+ −
m_date = m_maximumDate;+ −
internalUpdate();+ −
}+ −
+ −
void QCalendarModel::setRange(const QDate &min, const QDate &max)+ −
{+ −
m_minimumDate = min;+ −
m_maximumDate = max;+ −
if (m_minimumDate > m_maximumDate)+ −
qSwap(m_minimumDate, m_maximumDate);+ −
if (m_date < m_minimumDate)+ −
m_date = m_minimumDate;+ −
if (m_date > m_maximumDate)+ −
m_date = m_maximumDate;+ −
internalUpdate();+ −
}+ −
+ −
void QCalendarModel::internalUpdate()+ −
{+ −
QModelIndex begin = index(0, 0);+ −
QModelIndex end = index(m_firstRow + RowCount - 1, m_firstColumn + ColumnCount - 1);+ −
emit dataChanged(begin, end);+ −
emit headerDataChanged(Qt::Vertical, 0, m_firstRow + RowCount - 1);+ −
emit headerDataChanged(Qt::Horizontal, 0, m_firstColumn + ColumnCount - 1);+ −
}+ −
+ −
void QCalendarModel::setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat format)+ −
{+ −
if (m_horizontalHeaderFormat == format)+ −
return;+ −
+ −
int oldFormat = m_horizontalHeaderFormat;+ −
m_horizontalHeaderFormat = format;+ −
if (oldFormat == QCalendarWidget::NoHorizontalHeader) {+ −
m_firstRow = 1;+ −
insertRow(0);+ −
} else if (m_horizontalHeaderFormat == QCalendarWidget::NoHorizontalHeader) {+ −
m_firstRow = 0;+ −
removeRow(0);+ −
}+ −
internalUpdate();+ −
}+ −
+ −
void QCalendarModel::setFirstColumnDay(Qt::DayOfWeek dayOfWeek)+ −
{+ −
if (m_firstDay == dayOfWeek)+ −
return;+ −
+ −
m_firstDay = dayOfWeek;+ −
internalUpdate();+ −
}+ −
+ −
Qt::DayOfWeek QCalendarModel::firstColumnDay() const+ −
{+ −
return m_firstDay;+ −
}+ −
+ −
bool QCalendarModel::weekNumbersShown() const+ −
{+ −
return m_weekNumbersShown;+ −
}+ −
+ −
void QCalendarModel::setWeekNumbersShown(bool show)+ −
{+ −
if (m_weekNumbersShown == show)+ −
return;+ −
+ −
m_weekNumbersShown = show;+ −
if (show) {+ −
m_firstColumn = 1;+ −
insertColumn(0);+ −
} else {+ −
m_firstColumn = 0;+ −
removeColumn(0);+ −
}+ −
internalUpdate();+ −
}+ −
+ −
QCalendarView::QCalendarView(QWidget *parent)+ −
: QTableView(parent),+ −
readOnly(false),+ −
validDateClicked(false)+ −
{+ −
setTabKeyNavigation(false);+ −
setShowGrid(false);+ −
verticalHeader()->setVisible(false);+ −
horizontalHeader()->setVisible(false);+ −
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);+ −
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);+ −
}+ −
+ −
QModelIndex QCalendarView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)+ −
{+ −
QCalendarModel *calendarModel = qobject_cast<QCalendarModel *>(model());+ −
if (!calendarModel)+ −
return QTableView::moveCursor(cursorAction, modifiers);+ −
+ −
if (readOnly)+ −
return currentIndex();+ −
+ −
QModelIndex index = currentIndex();+ −
QDate currentDate = static_cast<QCalendarModel*>(model())->dateForCell(index.row(), index.column());+ −
switch (cursorAction) {+ −
case QAbstractItemView::MoveUp:+ −
currentDate = currentDate.addDays(-7);+ −
break;+ −
case QAbstractItemView::MoveDown:+ −
currentDate = currentDate.addDays(7);+ −
break;+ −
case QAbstractItemView::MoveLeft:+ −
currentDate = currentDate.addDays(isRightToLeft() ? 1 : -1);+ −
break;+ −
case QAbstractItemView::MoveRight:+ −
currentDate = currentDate.addDays(isRightToLeft() ? -1 : 1);+ −
break;+ −
case QAbstractItemView::MoveHome:+ −
currentDate = QDate(currentDate.year(), currentDate.month(), 1);+ −
break;+ −
case QAbstractItemView::MoveEnd:+ −
currentDate = QDate(currentDate.year(), currentDate.month(), currentDate.daysInMonth());+ −
break;+ −
case QAbstractItemView::MovePageUp:+ −
currentDate = currentDate.addMonths(-1);+ −
break;+ −
case QAbstractItemView::MovePageDown:+ −
currentDate = currentDate.addMonths(1);+ −
break;+ −
case QAbstractItemView::MoveNext:+ −
case QAbstractItemView::MovePrevious:+ −
return currentIndex();+ −
default:+ −
break;+ −
}+ −
emit changeDate(currentDate, true);+ −
return currentIndex();+ −
}+ −
+ −
void QCalendarView::keyPressEvent(QKeyEvent *event)+ −
{+ −
#ifdef QT_KEYPAD_NAVIGATION+ −
if (event->key() == Qt::Key_Select) {+ −
if (QApplication::keypadNavigationEnabled()) {+ −
if (!hasEditFocus()) {+ −
setEditFocus(true);+ −
return;+ −
}+ −
}+ −
} else if (event->key() == Qt::Key_Back) {+ −
if (QApplication::keypadNavigationEnabled() && hasEditFocus()) {+ −
if (qobject_cast<QCalendarModel *>(model())) {+ −
emit changeDate(origDate, true); //changes selection back to origDate, but doesn't activate+ −
setEditFocus(false);+ −
return;+ −
}+ −
}+ −
}+ −
#endif+ −
+ −
if (!readOnly) {+ −
switch (event->key()) {+ −
case Qt::Key_Return:+ −
case Qt::Key_Enter:+ −
case Qt::Key_Select:+ −
emit editingFinished();+ −
return;+ −
default:+ −
break;+ −
}+ −
}+ −
QTableView::keyPressEvent(event);+ −
}+ −
+ −
#ifndef QT_NO_WHEELEVENT+ −
void QCalendarView::wheelEvent(QWheelEvent *event)+ −
{+ −
const int numDegrees = event->delta() / 8;+ −
const int numSteps = numDegrees / 15;+ −
const QModelIndex index = currentIndex();+ −
QDate currentDate = static_cast<QCalendarModel*>(model())->dateForCell(index.row(), index.column());+ −
currentDate = currentDate.addMonths(-numSteps);+ −
emit showDate(currentDate);+ −
}+ −
#endif+ −
+ −
bool QCalendarView::event(QEvent *event)+ −
{+ −
#ifdef QT_KEYPAD_NAVIGATION+ −
if (event->type() == QEvent::FocusIn) {+ −
if (QCalendarModel *calendarModel = qobject_cast<QCalendarModel *>(model())) {+ −
origDate = calendarModel->m_date;+ −
}+ −
}+ −
#endif+ −
+ −
return QTableView::event(event);+ −
}+ −
+ −
QDate QCalendarView::handleMouseEvent(QMouseEvent *event)+ −
{+ −
QCalendarModel *calendarModel = qobject_cast<QCalendarModel *>(model());+ −
if (!calendarModel)+ −
return QDate();+ −
+ −
QPoint pos = event->pos();+ −
QModelIndex index = indexAt(pos);+ −
QDate date = calendarModel->dateForCell(index.row(), index.column());+ −
if (date.isValid() && date >= calendarModel->m_minimumDate+ −
&& date <= calendarModel->m_maximumDate) {+ −
return date;+ −
}+ −
return QDate();+ −
}+ −
+ −
void QCalendarView::mouseDoubleClickEvent(QMouseEvent *event)+ −
{+ −
QCalendarModel *calendarModel = qobject_cast<QCalendarModel *>(model());+ −
if (!calendarModel) {+ −
QTableView::mouseDoubleClickEvent(event);+ −
return;+ −
}+ −
+ −
if (readOnly)+ −
return;+ −
+ −
QDate date = handleMouseEvent(event);+ −
validDateClicked = false;+ −
if (date == calendarModel->m_date && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)) {+ −
emit editingFinished();+ −
}+ −
}+ −
+ −
void QCalendarView::mousePressEvent(QMouseEvent *event)+ −
{+ −
QCalendarModel *calendarModel = qobject_cast<QCalendarModel *>(model());+ −
if (!calendarModel) {+ −
QTableView::mousePressEvent(event);+ −
return;+ −
}+ −
+ −
if (readOnly)+ −
return;+ −
+ −
if (event->button() != Qt::LeftButton)+ −
return;+ −
+ −
QDate date = handleMouseEvent(event);+ −
if (date.isValid()) {+ −
validDateClicked = true;+ −
int row = -1, col = -1;+ −
static_cast<QCalendarModel *>(model())->cellForDate(date, &row, &col);+ −
if (row != -1 && col != -1) {+ −
selectionModel()->setCurrentIndex(model()->index(row, col), QItemSelectionModel::NoUpdate);+ −
}+ −
} else {+ −
validDateClicked = false;+ −
event->ignore();+ −
}+ −
}+ −
+ −
void QCalendarView::mouseMoveEvent(QMouseEvent *event)+ −
{+ −
QCalendarModel *calendarModel = qobject_cast<QCalendarModel *>(model());+ −
if (!calendarModel) {+ −
QTableView::mouseMoveEvent(event);+ −
return;+ −
}+ −
+ −
if (readOnly)+ −
return;+ −
+ −
if (validDateClicked) {+ −
QDate date = handleMouseEvent(event);+ −
if (date.isValid()) {+ −
int row = -1, col = -1;+ −
static_cast<QCalendarModel *>(model())->cellForDate(date, &row, &col);+ −
if (row != -1 && col != -1) {+ −
selectionModel()->setCurrentIndex(model()->index(row, col), QItemSelectionModel::NoUpdate);+ −
}+ −
}+ −
} else {+ −
event->ignore();+ −
}+ −
}+ −
+ −
void QCalendarView::mouseReleaseEvent(QMouseEvent *event)+ −
{+ −
QCalendarModel *calendarModel = qobject_cast<QCalendarModel *>(model());+ −
if (!calendarModel) {+ −
QTableView::mouseReleaseEvent(event);+ −
return;+ −
}+ −
+ −
if (event->button() != Qt::LeftButton)+ −
return;+ −
+ −
if (readOnly)+ −
return;+ −
+ −
if (validDateClicked) {+ −
QDate date = handleMouseEvent(event);+ −
if (date.isValid()) {+ −
emit changeDate(date, true);+ −
emit clicked(date);+ −
if (style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick))+ −
emit editingFinished();+ −
}+ −
validDateClicked = false;+ −
} else {+ −
event->ignore();+ −
}+ −
}+ −
+ −
class QCalendarDelegate : public QItemDelegate+ −
{+ −
Q_OBJECT+ −
public:+ −
QCalendarDelegate(QCalendarWidgetPrivate *w, QObject *parent = 0)+ −
: QItemDelegate(parent), calendarWidgetPrivate(w)+ −
{ }+ −
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option,+ −
const QModelIndex &index) const;+ −
void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const;+ −
+ −
private:+ −
QCalendarWidgetPrivate *calendarWidgetPrivate;+ −
mutable QStyleOptionViewItemV4 storedOption;+ −
};+ −
+ −
//Private tool button class+ −
class QCalToolButton: public QToolButton+ −
{+ −
public:+ −
QCalToolButton(QWidget * parent)+ −
: QToolButton(parent)+ −
{ }+ −
protected:+ −
void paintEvent(QPaintEvent *e)+ −
{+ −
Q_UNUSED(e)+ −
+ −
#ifndef Q_WS_MAC+ −
QStyleOptionToolButton opt;+ −
initStyleOption(&opt);+ −
+ −
if (opt.state & QStyle::State_MouseOver || isDown()) {+ −
//act as normal button+ −
setPalette(QPalette());+ −
} else {+ −
//set the highlight color for button text+ −
QPalette toolPalette = palette();+ −
toolPalette.setColor(QPalette::ButtonText, toolPalette.color(QPalette::HighlightedText));+ −
setPalette(toolPalette);+ −
}+ −
#endif+ −
QToolButton::paintEvent(e);+ −
}+ −
};+ −
+ −
class QPrevNextCalButton : public QToolButton+ −
{+ −
Q_OBJECT+ −
public:+ −
QPrevNextCalButton(QWidget *parent) : QToolButton(parent) {}+ −
protected:+ −
void paintEvent(QPaintEvent *) {+ −
QStylePainter painter(this);+ −
QStyleOptionToolButton opt;+ −
initStyleOption(&opt);+ −
opt.state &= ~QStyle::State_HasFocus;+ −
painter.drawComplexControl(QStyle::CC_ToolButton, opt);+ −
}+ −
};+ −
+ −
class QCalendarWidgetPrivate : public QWidgetPrivate+ −
{+ −
Q_DECLARE_PUBLIC(QCalendarWidget)+ −
public:+ −
QCalendarWidgetPrivate();+ −
+ −
void showMonth(int year, int month);+ −
void update();+ −
void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const;+ −
+ −
void _q_slotShowDate(const QDate &date);+ −
void _q_slotChangeDate(const QDate &date);+ −
void _q_slotChangeDate(const QDate &date, bool changeMonth);+ −
void _q_editingFinished();+ −
void _q_monthChanged(QAction*);+ −
void _q_prevMonthClicked();+ −
void _q_nextMonthClicked();+ −
void _q_yearEditingFinished();+ −
void _q_yearClicked();+ −
+ −
void createNavigationBar(QWidget *widget);+ −
void updateButtonIcons();+ −
void updateMonthMenu();+ −
void updateMonthMenuNames();+ −
void updateNavigationBar();+ −
void updateCurrentPage(const QDate &newDate);+ −
inline QDate getCurrentDate();+ −
void setNavigatorEnabled(bool enable);+ −
+ −
QCalendarModel *m_model;+ −
QCalendarView *m_view;+ −
QCalendarDelegate *m_delegate;+ −
QItemSelectionModel *m_selection;+ −
QCalendarTextNavigator *m_navigator;+ −
bool m_dateEditEnabled;+ −
+ −
QToolButton *nextMonth;+ −
QToolButton *prevMonth;+ −
QCalToolButton *monthButton;+ −
QMenu *monthMenu;+ −
QMap<int, QAction *> monthToAction;+ −
QCalToolButton *yearButton;+ −
QSpinBox *yearEdit;+ −
QWidget *navBarBackground;+ −
QSpacerItem *spaceHolder;+ −
+ −
bool navBarVisible;+ −
mutable QSize cachedSizeHint;+ −
Qt::FocusPolicy oldFocusPolicy;+ −
};+ −
+ −
void QCalendarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,+ −
const QModelIndex &index) const+ −
{+ −
QDate date = calendarWidgetPrivate->m_model->dateForCell(index.row(), index.column());+ −
if (date.isValid()) {+ −
storedOption = option;+ −
QRect rect = option.rect;+ −
calendarWidgetPrivate->paintCell(painter, rect, date);+ −
} else {+ −
QItemDelegate::paint(painter, option, index);+ −
}+ −
}+ −
+ −
void QCalendarDelegate::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const+ −
{+ −
storedOption.rect = rect;+ −
int row = -1;+ −
int col = -1;+ −
calendarWidgetPrivate->m_model->cellForDate(date, &row, &col);+ −
QModelIndex idx = calendarWidgetPrivate->m_model->index(row, col);+ −
QItemDelegate::paint(painter, storedOption, idx);+ −
}+ −
+ −
QCalendarWidgetPrivate::QCalendarWidgetPrivate()+ −
: QWidgetPrivate()+ −
{+ −
m_model = 0;+ −
m_view = 0;+ −
m_delegate = 0;+ −
m_selection = 0;+ −
m_navigator = 0;+ −
m_dateEditEnabled = false;+ −
navBarVisible = true;+ −
oldFocusPolicy = Qt::StrongFocus;+ −
}+ −
+ −
void QCalendarWidgetPrivate::setNavigatorEnabled(bool enable)+ −
{+ −
Q_Q(QCalendarWidget);+ −
+ −
bool navigatorEnabled = (m_navigator->widget() != 0);+ −
if (enable == navigatorEnabled)+ −
return;+ −
+ −
if (enable) {+ −
m_navigator->setWidget(q);+ −
q->connect(m_navigator, SIGNAL(dateChanged(QDate)),+ −
q, SLOT(_q_slotChangeDate(QDate)));+ −
q->connect(m_navigator, SIGNAL(editingFinished()),+ −
q, SLOT(_q_editingFinished()));+ −
m_view->installEventFilter(m_navigator);+ −
} else {+ −
m_navigator->setWidget(0);+ −
q->disconnect(m_navigator, SIGNAL(dateChanged(QDate)),+ −
q, SLOT(_q_slotChangeDate(QDate)));+ −
q->disconnect(m_navigator, SIGNAL(editingFinished()),+ −
q, SLOT(_q_editingFinished()));+ −
m_view->removeEventFilter(m_navigator);+ −
}+ −
}+ −
+ −
void QCalendarWidgetPrivate::createNavigationBar(QWidget *widget)+ −
{+ −
Q_Q(QCalendarWidget);+ −
navBarBackground = new QWidget(widget);+ −
navBarBackground->setObjectName(QLatin1String("qt_calendar_navigationbar"));+ −
navBarBackground->setAutoFillBackground(true);+ −
navBarBackground->setBackgroundRole(QPalette::Highlight);+ −
+ −
prevMonth = new QPrevNextCalButton(navBarBackground);+ −
nextMonth = new QPrevNextCalButton(navBarBackground);+ −
prevMonth->setAutoRaise(true);+ −
nextMonth->setAutoRaise(true);+ −
prevMonth->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);+ −
nextMonth->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);+ −
nextMonth->setAutoRaise(true);+ −
updateButtonIcons();+ −
prevMonth->setAutoRepeat(true);+ −
nextMonth->setAutoRepeat(true);+ −
+ −
monthButton = new QCalToolButton(navBarBackground);+ −
monthButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);+ −
monthButton->setAutoRaise(true);+ −
monthButton->setPopupMode(QToolButton::InstantPopup);+ −
monthMenu = new QMenu(monthButton);+ −
for (int i = 1; i <= 12; i++) {+ −
QString monthName(q->locale().standaloneMonthName(i, QLocale::LongFormat));+ −
QAction *act = monthMenu->addAction(monthName);+ −
act->setData(i);+ −
monthToAction[i] = act;+ −
}+ −
monthButton->setMenu(monthMenu);+ −
yearButton = new QCalToolButton(navBarBackground);+ −
yearButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);+ −
yearButton->setAutoRaise(true);+ −
yearEdit = new QSpinBox(navBarBackground);+ −
+ −
QFont font = q->font();+ −
font.setBold(true);+ −
monthButton->setFont(font);+ −
yearButton->setFont(font);+ −
yearEdit->setFrame(false);+ −
yearEdit->setMinimum(m_model->m_minimumDate.year());+ −
yearEdit->setMaximum(m_model->m_maximumDate.year());+ −
yearEdit->hide();+ −
spaceHolder = new QSpacerItem(0,0);+ −
+ −
QHBoxLayout *headerLayout = new QHBoxLayout;+ −
headerLayout->setMargin(0);+ −
headerLayout->setSpacing(0);+ −
headerLayout->addWidget(prevMonth);+ −
headerLayout->insertStretch(headerLayout->count());+ −
headerLayout->addWidget(monthButton);+ −
headerLayout->addItem(spaceHolder);+ −
headerLayout->addWidget(yearButton);+ −
headerLayout->insertStretch(headerLayout->count());+ −
headerLayout->addWidget(nextMonth);+ −
navBarBackground->setLayout(headerLayout);+ −
+ −
yearEdit->setFocusPolicy(Qt::StrongFocus);+ −
prevMonth->setFocusPolicy(Qt::NoFocus);+ −
nextMonth->setFocusPolicy(Qt::NoFocus);+ −
yearButton->setFocusPolicy(Qt::NoFocus);+ −
monthButton->setFocusPolicy(Qt::NoFocus);+ −
+ −
//set names for the header controls.+ −
prevMonth->setObjectName(QLatin1String("qt_calendar_prevmonth"));+ −
nextMonth->setObjectName(QLatin1String("qt_calendar_nextmonth"));+ −
monthButton->setObjectName(QLatin1String("qt_calendar_monthbutton"));+ −
yearButton->setObjectName(QLatin1String("qt_calendar_yearbutton"));+ −
yearEdit->setObjectName(QLatin1String("qt_calendar_yearedit"));+ −
+ −
updateMonthMenu();+ −
showMonth(m_model->m_date.year(), m_model->m_date.month());+ −
}+ −
+ −
void QCalendarWidgetPrivate::updateButtonIcons()+ −
{+ −
Q_Q(QCalendarWidget);+ −
prevMonth->setIcon(q->style()->standardIcon(q->isRightToLeft() ? QStyle::SP_ArrowRight : QStyle::SP_ArrowLeft, 0, q));+ −
nextMonth->setIcon(q->style()->standardIcon(q->isRightToLeft() ? QStyle::SP_ArrowLeft : QStyle::SP_ArrowRight, 0, q));+ −
}+ −
+ −
void QCalendarWidgetPrivate::updateMonthMenu()+ −
{+ −
int beg = 1, end = 12;+ −
bool prevEnabled = true;+ −
bool nextEnabled = true;+ −
if (m_model->m_shownYear == m_model->m_minimumDate.year()) {+ −
beg = m_model->m_minimumDate.month();+ −
if (m_model->m_shownMonth == m_model->m_minimumDate.month())+ −
prevEnabled = false;+ −
}+ −
if (m_model->m_shownYear == m_model->m_maximumDate.year()) {+ −
end = m_model->m_maximumDate.month();+ −
if (m_model->m_shownMonth == m_model->m_maximumDate.month())+ −
nextEnabled = false;+ −
}+ −
prevMonth->setEnabled(prevEnabled);+ −
nextMonth->setEnabled(nextEnabled);+ −
for (int i = 1; i <= 12; i++) {+ −
bool monthEnabled = true;+ −
if (i < beg || i > end)+ −
monthEnabled = false;+ −
monthToAction[i]->setEnabled(monthEnabled);+ −
}+ −
}+ −
+ −
void QCalendarWidgetPrivate::updateMonthMenuNames()+ −
{+ −
Q_Q(QCalendarWidget);+ −
+ −
for (int i = 1; i <= 12; i++) {+ −
QString monthName(q->locale().standaloneMonthName(i, QLocale::LongFormat));+ −
monthToAction[i]->setText(monthName);+ −
}+ −
}+ −
+ −
void QCalendarWidgetPrivate::updateCurrentPage(const QDate &date)+ −
{+ −
Q_Q(QCalendarWidget);+ −
+ −
QDate newDate = date;+ −
QDate minDate = q->minimumDate();+ −
QDate maxDate = q->maximumDate();+ −
if (minDate.isValid()&& minDate.daysTo(newDate) < 0)+ −
newDate = minDate;+ −
if (maxDate.isValid()&& maxDate.daysTo(newDate) > 0)+ −
newDate = maxDate;+ −
showMonth(newDate.year(), newDate.month());+ −
int row = -1, col = -1;+ −
m_model->cellForDate(newDate, &row, &col);+ −
if (row != -1 && col != -1)+ −
{+ −
m_view->selectionModel()->setCurrentIndex(m_model->index(row, col),+ −
QItemSelectionModel::NoUpdate);+ −
}+ −
}+ −
+ −
void QCalendarWidgetPrivate::_q_monthChanged(QAction *act)+ −
{+ −
monthButton->setText(act->text());+ −
QDate currentDate = getCurrentDate();+ −
QDate newDate = currentDate.addMonths(act->data().toInt()-currentDate.month());+ −
updateCurrentPage(newDate);+ −
}+ −
+ −
QDate QCalendarWidgetPrivate::getCurrentDate()+ −
{+ −
QModelIndex index = m_view->currentIndex();+ −
return m_model->dateForCell(index.row(), index.column());+ −
}+ −
+ −
void QCalendarWidgetPrivate::_q_prevMonthClicked()+ −
{+ −
QDate currentDate = getCurrentDate().addMonths(-1);+ −
updateCurrentPage(currentDate);+ −
}+ −
+ −
void QCalendarWidgetPrivate::_q_nextMonthClicked()+ −
{+ −
QDate currentDate = getCurrentDate().addMonths(1);+ −
updateCurrentPage(currentDate);+ −
}+ −
+ −
void QCalendarWidgetPrivate::_q_yearEditingFinished()+ −
{+ −
Q_Q(QCalendarWidget);+ −
yearButton->setText(yearEdit->text());+ −
yearEdit->hide();+ −
q->setFocusPolicy(oldFocusPolicy);+ −
qApp->removeEventFilter(q);+ −
spaceHolder->changeSize(0, 0);+ −
yearButton->show();+ −
QDate currentDate = getCurrentDate();+ −
currentDate = currentDate.addYears(yearEdit->text().toInt() - currentDate.year());+ −
updateCurrentPage(currentDate);+ −
}+ −
+ −
void QCalendarWidgetPrivate::_q_yearClicked()+ −
{+ −
Q_Q(QCalendarWidget);+ −
//show the spinbox on top of the button+ −
yearEdit->setGeometry(yearButton->x(), yearButton->y(),+ −
yearEdit->sizeHint().width(), yearButton->height());+ −
spaceHolder->changeSize(yearButton->width(), 0);+ −
yearButton->hide();+ −
oldFocusPolicy = q->focusPolicy();+ −
q->setFocusPolicy(Qt::NoFocus);+ −
yearEdit->show();+ −
qApp->installEventFilter(q);+ −
yearEdit->raise();+ −
yearEdit->selectAll();+ −
yearEdit->setFocus(Qt::MouseFocusReason);+ −
}+ −
+ −
void QCalendarWidgetPrivate::showMonth(int year, int month)+ −
{+ −
if (m_model->m_shownYear == year && m_model->m_shownMonth == month)+ −
return;+ −
Q_Q(QCalendarWidget);+ −
m_model->showMonth(year, month);+ −
updateNavigationBar();+ −
emit q->currentPageChanged(year, month);+ −
m_view->internalUpdate();+ −
cachedSizeHint = QSize();+ −
update();+ −
updateMonthMenu();+ −
}+ −
+ −
void QCalendarWidgetPrivate::updateNavigationBar()+ −
{+ −
Q_Q(QCalendarWidget);+ −
+ −
QString monthName = q->locale().standaloneMonthName(m_model->m_shownMonth, QLocale::LongFormat);+ −
+ −
monthButton->setText(monthName);+ −
yearButton->setText(QString::number(m_model->m_shownYear));+ −
yearEdit->setValue(m_model->m_shownYear);+ −
}+ −
+ −
void QCalendarWidgetPrivate::update()+ −
{+ −
QDate currentDate = m_model->m_date;+ −
int row, column;+ −
m_model->cellForDate(currentDate, &row, &column);+ −
QModelIndex idx;+ −
m_selection->clear();+ −
if (row != -1 && column != -1) {+ −
idx = m_model->index(row, column);+ −
m_selection->setCurrentIndex(idx, QItemSelectionModel::SelectCurrent);+ −
}+ −
}+ −
+ −
void QCalendarWidgetPrivate::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const+ −
{+ −
Q_Q(const QCalendarWidget);+ −
q->paintCell(painter, rect, date);+ −
}+ −
+ −
void QCalendarWidgetPrivate::_q_slotShowDate(const QDate &date)+ −
{+ −
updateCurrentPage(date);+ −
}+ −
+ −
void QCalendarWidgetPrivate::_q_slotChangeDate(const QDate &date)+ −
{+ −
_q_slotChangeDate(date, true);+ −
}+ −
+ −
void QCalendarWidgetPrivate::_q_slotChangeDate(const QDate &date, bool changeMonth)+ −
{+ −
QDate oldDate = m_model->m_date;+ −
m_model->setDate(date);+ −
QDate newDate = m_model->m_date;+ −
if (changeMonth)+ −
showMonth(newDate.year(), newDate.month());+ −
if (oldDate != newDate) {+ −
update();+ −
Q_Q(QCalendarWidget);+ −
m_navigator->setDate(newDate);+ −
emit q->selectionChanged();+ −
}+ −
}+ −
+ −
void QCalendarWidgetPrivate::_q_editingFinished()+ −
{+ −
Q_Q(QCalendarWidget);+ −
emit q->activated(m_model->m_date);+ −
}+ −
+ −
/*!+ −
\class QCalendarWidget+ −
\brief The QCalendarWidget class provides a monthly based+ −
calendar widget allowing the user to select a date.+ −
\since 4.2+ −
+ −
\ingroup advanced+ −
+ −
\image cleanlooks-calendarwidget.png+ −
+ −
The widget is initialized with the current month and year, but+ −
QCalendarWidget provides several public slots to change the year+ −
and month that is shown.+ −
+ −
By default, today's date is selected, and the user can select a+ −
date using both mouse and keyboard. The currently selected date+ −
can be retrieved using the selectedDate() function. It is+ −
possible to constrain the user selection to a given date range by+ −
setting the minimumDate and maximumDate properties.+ −
Alternatively, both properties can be set in one go using the+ −
setDateRange() convenience slot. Set the \l selectionMode+ −
property to NoSelection to prohibit the user from selecting at+ −
all. Note that a date also can be selected programmatically using+ −
the setSelectedDate() slot.+ −
+ −
The currently displayed month and year can be retrieved using the+ −
monthShown() and yearShown() functions, respectively.+ −
+ −
A newly created calendar widget uses abbreviated day names, and+ −
both Saturdays and Sundays are marked in red. The calendar grid is+ −
not visible. The week numbers are displayed, and the first column+ −
day is Sunday.+ −
+ −
The notation of the days can be altered to a single letter+ −
abbreviations ("M" for "Monday") by setting the+ −
horizontalHeaderFormat property to+ −
QCalendarWidget::SingleLetterDayNames. Setting the same property+ −
to QCalendarWidget::LongDayNames makes the header display the+ −
complete day names. The week numbers can be removed by setting+ −
the verticalHeaderFormat property to+ −
QCalendarWidget::NoVerticalHeader. The calendar grid can be+ −
turned on by setting the gridVisible property to true using the+ −
setGridVisible() function:+ −
+ −
\table+ −
\row \o+ −
\image qcalendarwidget-grid.png+ −
\row \o+ −
\snippet doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp 0+ −
\endtable+ −
+ −
Finally, the day in the first column can be altered using the+ −
setFirstDayOfWeek() function.+ −
+ −
The QCalendarWidget class also provides three signals,+ −
selectionChanged(), activated() and currentPageChanged() making it+ −
possible to respond to user interaction.+ −
+ −
The rendering of the headers, weekdays or single days can be+ −
largely customized by setting QTextCharFormat's for some special+ −
weekday, a special date or for the rendering of the headers.+ −
+ −
Only a subset of the properties in QTextCharFormat are used by the+ −
calendar widget. Currently, the foreground, background and font+ −
properties are used to determine the rendering of individual cells+ −
in the widget.+ −
+ −
\sa QDate, QDateEdit, QTextCharFormat+ −
*/+ −
+ −
/*!+ −
\enum QCalendarWidget::SelectionMode+ −
+ −
This enum describes the types of selection offered to the user for+ −
selecting dates in the calendar.+ −
+ −
\value NoSelection Dates cannot be selected.+ −
\value SingleSelection Single dates can be selected.+ −
+ −
\sa selectionMode+ −
*/+ −
+ −
/*!+ −
Constructs a calendar widget with the given \a parent.+ −
+ −
The widget is initialized with the current month and year, and the+ −
currently selected date is today.+ −
+ −
\sa setCurrentPage()+ −
*/+ −
QCalendarWidget::QCalendarWidget(QWidget *parent)+ −
: QWidget(*new QCalendarWidgetPrivate, parent, 0)+ −
{+ −
Q_D(QCalendarWidget);+ −
+ −
setAutoFillBackground(true);+ −
setBackgroundRole(QPalette::Window);+ −
+ −
QVBoxLayout *layoutV = new QVBoxLayout(this);+ −
layoutV->setMargin(0);+ −
d->m_model = new QCalendarModel(this);+ −
QTextCharFormat fmt;+ −
fmt.setForeground(QBrush(Qt::red));+ −
d->m_model->m_dayFormats.insert(Qt::Saturday, fmt);+ −
d->m_model->m_dayFormats.insert(Qt::Sunday, fmt);+ −
d->m_view = new QCalendarView(this);+ −
d->m_view->setObjectName(QLatin1String("qt_calendar_calendarview"));+ −
d->m_view->setModel(d->m_model);+ −
d->m_model->setView(d->m_view);+ −
d->m_view->setSelectionBehavior(QAbstractItemView::SelectItems);+ −
d->m_view->setSelectionMode(QAbstractItemView::SingleSelection);+ −
d->m_view->horizontalHeader()->setResizeMode(QHeaderView::Stretch);+ −
d->m_view->horizontalHeader()->setClickable(false);+ −
d->m_view->verticalHeader()->setResizeMode(QHeaderView::Stretch);+ −
d->m_view->verticalHeader()->setClickable(false);+ −
d->m_selection = d->m_view->selectionModel();+ −
d->createNavigationBar(this);+ −
d->m_view->setFrameStyle(QFrame::NoFrame);+ −
d->m_delegate = new QCalendarDelegate(d, this);+ −
d->m_view->setItemDelegate(d->m_delegate);+ −
d->update();+ −
d->updateNavigationBar();+ −
setFocusPolicy(Qt::StrongFocus);+ −
setFocusProxy(d->m_view);+ −
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);+ −
+ −
connect(d->m_view, SIGNAL(showDate(QDate)),+ −
this, SLOT(_q_slotShowDate(QDate)));+ −
connect(d->m_view, SIGNAL(changeDate(QDate,bool)),+ −
this, SLOT(_q_slotChangeDate(QDate,bool)));+ −
connect(d->m_view, SIGNAL(clicked(QDate)),+ −
this, SIGNAL(clicked(QDate)));+ −
connect(d->m_view, SIGNAL(editingFinished()),+ −
this, SLOT(_q_editingFinished()));+ −
+ −
connect(d->prevMonth, SIGNAL(clicked(bool)),+ −
this, SLOT(_q_prevMonthClicked()));+ −
connect(d->nextMonth, SIGNAL(clicked(bool)),+ −
this, SLOT(_q_nextMonthClicked()));+ −
connect(d->yearButton, SIGNAL(clicked(bool)),+ −
this, SLOT(_q_yearClicked()));+ −
connect(d->monthMenu, SIGNAL(triggered(QAction*)),+ −
this, SLOT(_q_monthChanged(QAction*)));+ −
connect(d->yearEdit, SIGNAL(editingFinished()),+ −
this, SLOT(_q_yearEditingFinished()));+ −
+ −
layoutV->setMargin(0);+ −
layoutV->setSpacing(0);+ −
layoutV->addWidget(d->navBarBackground);+ −
layoutV->addWidget(d->m_view);+ −
+ −
d->m_navigator = new QCalendarTextNavigator(this);+ −
setDateEditEnabled(true);+ −
}+ −
+ −
/*!+ −
Destroys the calendar widget.+ −
*/+ −
QCalendarWidget::~QCalendarWidget()+ −
{+ −
}+ −
+ −
/*!+ −
\reimp+ −
*/+ −
QSize QCalendarWidget::sizeHint() const+ −
{+ −
return minimumSizeHint();+ −
}+ −
+ −
/*!+ −
\reimp+ −
*/+ −
QSize QCalendarWidget::minimumSizeHint() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
if (d->cachedSizeHint.isValid())+ −
return d->cachedSizeHint;+ −
+ −
ensurePolished();+ −
+ −
int w = 0;+ −
int h = 0;+ −
+ −
int end = 53;+ −
int rows = 7;+ −
int cols = 8;+ −
+ −
const int marginH = (style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1) * 2;+ −
+ −
if (horizontalHeaderFormat() == QCalendarWidget::NoHorizontalHeader) {+ −
rows = 6;+ −
} else {+ −
for (int i = 1; i <= 7; i++) {+ −
QFontMetrics fm(d->m_model->formatForCell(0, i).font());+ −
w = qMax(w, fm.width(d->m_model->dayName(d->m_model->dayOfWeekForColumn(i))) + marginH);+ −
h = qMax(h, fm.height());+ −
}+ −
}+ −
+ −
if (verticalHeaderFormat() == QCalendarWidget::NoVerticalHeader) {+ −
cols = 7;+ −
} else {+ −
for (int i = 1; i <= 6; i++) {+ −
QFontMetrics fm(d->m_model->formatForCell(i, 0).font());+ −
for (int j = 1; j < end; j++)+ −
w = qMax(w, fm.width(QString::number(j)) + marginH);+ −
h = qMax(h, fm.height());+ −
}+ −
}+ −
+ −
QFontMetrics fm(d->m_model->formatForCell(1, 1).font());+ −
for (int i = 1; i <= end; i++) {+ −
w = qMax(w, fm.width(QString::number(i)) + marginH);+ −
h = qMax(h, fm.height());+ −
}+ −
+ −
if (d->m_view->showGrid()) {+ −
// hardcoded in tableview+ −
w += 1;+ −
h += 1;+ −
}+ −
+ −
w += 1; // default column span+ −
+ −
h = qMax(h, d->m_view->verticalHeader()->minimumSectionSize());+ −
w = qMax(w, d->m_view->horizontalHeader()->minimumSectionSize());+ −
+ −
//add the size of the header.+ −
QSize headerSize(0, 0);+ −
if (d->navBarVisible) {+ −
int headerH = d->navBarBackground->sizeHint().height();+ −
int headerW = 0;+ −
+ −
headerW += d->prevMonth->sizeHint().width();+ −
headerW += d->nextMonth->sizeHint().width();+ −
+ −
QFontMetrics fm = d->monthButton->fontMetrics();+ −
int monthW = 0;+ −
for (int i = 1; i < 12; i++) {+ −
QString monthName = locale().standaloneMonthName(i, QLocale::LongFormat);+ −
monthW = qMax(monthW, fm.boundingRect(monthName).width());+ −
}+ −
const int buttonDecoMargin = d->monthButton->sizeHint().width() - fm.boundingRect(d->monthButton->text()).width();+ −
headerW += monthW + buttonDecoMargin;+ −
+ −
fm = d->yearButton->fontMetrics();+ −
headerW += fm.boundingRect(QLatin1String("5555")).width() + buttonDecoMargin;+ −
+ −
headerSize = QSize(headerW, headerH);+ −
}+ −
w *= cols;+ −
w = qMax(headerSize.width(), w);+ −
h = (h * rows) + headerSize.height();+ −
d->cachedSizeHint = QSize(w, h);+ −
return d->cachedSizeHint;+ −
}+ −
+ −
/*!+ −
Paints the cell specified by the given \a date, using the given \a painter and \a rect.+ −
*/+ −
+ −
void QCalendarWidget::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const+ −
{+ −
Q_D(const QCalendarWidget);+ −
d->m_delegate->paintCell(painter, rect, date);+ −
}+ −
+ −
/*!+ −
\property QCalendarWidget::selectedDate+ −
\brief the currently selected date.+ −
+ −
The selected date must be within the date range specified by the+ −
minimumDate and maximumDate properties. By default, the selected+ −
date is the current date.+ −
+ −
\sa setDateRange()+ −
*/+ −
+ −
QDate QCalendarWidget::selectedDate() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_model->m_date;+ −
}+ −
+ −
void QCalendarWidget::setSelectedDate(const QDate &date)+ −
{+ −
Q_D(QCalendarWidget);+ −
if (d->m_model->m_date == date && date == d->getCurrentDate())+ −
return;+ −
+ −
if (!date.isValid())+ −
return;+ −
+ −
d->m_model->setDate(date);+ −
d->update();+ −
QDate newDate = d->m_model->m_date;+ −
d->showMonth(newDate.year(), newDate.month());+ −
emit selectionChanged();+ −
}+ −
+ −
/*!+ −
Returns the year of the currently displayed month. Months are+ −
numbered from 1 to 12.+ −
+ −
\sa monthShown(), setCurrentPage()+ −
*/+ −
+ −
int QCalendarWidget::yearShown() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_model->m_shownYear;+ −
}+ −
+ −
/*!+ −
Returns the currently displayed month. Months are numbered from 1 to+ −
12.+ −
+ −
\sa yearShown(), setCurrentPage()+ −
*/+ −
+ −
int QCalendarWidget::monthShown() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_model->m_shownMonth;+ −
}+ −
+ −
/*!+ −
Displays the given \a month of the given \a year without changing+ −
the selected date. Use the setSelectedDate() function to alter the+ −
selected date.+ −
+ −
The currently displayed month and year can be retrieved using the+ −
monthShown() and yearShown() functions respectively.+ −
+ −
\sa yearShown(), monthShown(), showPreviousMonth(), showNextMonth(),+ −
showPreviousYear(), showNextYear()+ −
*/+ −
+ −
void QCalendarWidget::setCurrentPage(int year, int month)+ −
{+ −
Q_D(QCalendarWidget);+ −
QDate currentDate = d->getCurrentDate();+ −
int day = currentDate.day();+ −
int daysInMonths = QDate(year, month, 1).daysInMonth();+ −
if (day > daysInMonths)+ −
day = daysInMonths;+ −
+ −
d->showMonth(year, month);+ −
+ −
QDate newDate(year, month, day);+ −
int row = -1, col = -1;+ −
d->m_model->cellForDate(newDate, &row, &col);+ −
if (row != -1 && col != -1) {+ −
d->m_view->selectionModel()->setCurrentIndex(d->m_model->index(row, col),+ −
QItemSelectionModel::NoUpdate);+ −
}+ −
}+ −
+ −
/*!+ −
Shows the next month relative to the currently displayed+ −
month. Note that the selected date is not changed.+ −
+ −
\sa showPreviousMonth(), setCurrentPage(), setSelectedDate()+ −
*/+ −
+ −
void QCalendarWidget::showNextMonth()+ −
{+ −
int year = yearShown();+ −
int month = monthShown();+ −
if (month == 12) {+ −
++year;+ −
month = 1;+ −
} else {+ −
++month;+ −
}+ −
setCurrentPage(year, month);+ −
}+ −
+ −
/*!+ −
Shows the previous month relative to the currently displayed+ −
month. Note that the selected date is not changed.+ −
+ −
\sa showNextMonth(), setCurrentPage(), setSelectedDate()+ −
*/+ −
+ −
void QCalendarWidget::showPreviousMonth()+ −
{+ −
int year = yearShown();+ −
int month = monthShown();+ −
if (month == 1) {+ −
--year;+ −
month = 12;+ −
} else {+ −
--month;+ −
}+ −
setCurrentPage(year, month);+ −
}+ −
+ −
/*!+ −
Shows the currently displayed month in the \e next year relative+ −
to the currently displayed year. Note that the selected date is+ −
not changed.+ −
+ −
\sa showPreviousYear(), setCurrentPage(), setSelectedDate()+ −
*/+ −
+ −
void QCalendarWidget::showNextYear()+ −
{+ −
int year = yearShown();+ −
int month = monthShown();+ −
++year;+ −
setCurrentPage(year, month);+ −
}+ −
+ −
/*!+ −
Shows the currently displayed month in the \e previous year+ −
relative to the currently displayed year. Note that the selected+ −
date is not changed.+ −
+ −
\sa showNextYear(), setCurrentPage(), setSelectedDate()+ −
*/+ −
+ −
void QCalendarWidget::showPreviousYear()+ −
{+ −
int year = yearShown();+ −
int month = monthShown();+ −
--year;+ −
setCurrentPage(year, month);+ −
}+ −
+ −
/*!+ −
Shows the month of the selected date.+ −
+ −
\sa selectedDate(), setCurrentPage()+ −
*/+ −
void QCalendarWidget::showSelectedDate()+ −
{+ −
QDate currentDate = selectedDate();+ −
setCurrentPage(currentDate.year(), currentDate.month());+ −
}+ −
+ −
/*!+ −
Shows the month of the today's date.+ −
+ −
\sa selectedDate(), setCurrentPage()+ −
*/+ −
void QCalendarWidget::showToday()+ −
{+ −
QDate currentDate = QDate::currentDate();+ −
setCurrentPage(currentDate.year(), currentDate.month());+ −
}+ −
+ −
/*!+ −
\property QCalendarWidget::minimumDate+ −
\brief the minimum date of the currently specified date range.+ −
+ −
The user will not be able to select a date that is before the+ −
currently set minimum date.+ −
+ −
\table+ −
\row+ −
\o \image qcalendarwidget-minimum.png+ −
\row+ −
\o+ −
\snippet doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp 1+ −
\endtable+ −
+ −
By default, the minimum date is the earliest date that the QDate+ −
class can handle.+ −
+ −
When setting a minimum date, the maximumDate and selectedDate+ −
properties are adjusted if the selection range becomes invalid. If+ −
the provided date is not a valid QDate object, the+ −
setMinimumDate() function does nothing.+ −
+ −
\sa setDateRange()+ −
*/+ −
+ −
QDate QCalendarWidget::minimumDate() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_model->m_minimumDate;+ −
}+ −
+ −
void QCalendarWidget::setMinimumDate(const QDate &date)+ −
{+ −
Q_D(QCalendarWidget);+ −
if (!date.isValid() || d->m_model->m_minimumDate == date)+ −
return;+ −
+ −
QDate oldDate = d->m_model->m_date;+ −
d->m_model->setMinimumDate(date);+ −
d->yearEdit->setMinimum(d->m_model->m_minimumDate.year());+ −
d->updateMonthMenu();+ −
QDate newDate = d->m_model->m_date;+ −
if (oldDate != newDate) {+ −
d->update();+ −
d->showMonth(newDate.year(), newDate.month());+ −
d->m_navigator->setDate(newDate);+ −
emit selectionChanged();+ −
}+ −
}+ −
+ −
/*!+ −
\property QCalendarWidget::maximumDate+ −
\brief the maximum date of the currently specified date range.+ −
+ −
The user will not be able to select a date which is after the+ −
currently set maximum date.+ −
+ −
\table+ −
\row+ −
\o \image qcalendarwidget-maximum.png+ −
\row+ −
\o+ −
\snippet doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp 2+ −
\endtable+ −
+ −
By default, the maximum date is the last day the QDate class can+ −
handle.+ −
+ −
When setting a maximum date, the minimumDate and selectedDate+ −
properties are adjusted if the selection range becomes invalid. If+ −
the provided date is not a valid QDate object, the+ −
setMaximumDate() function does nothing.+ −
+ −
\sa setDateRange()+ −
*/+ −
+ −
QDate QCalendarWidget::maximumDate() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_model->m_maximumDate;+ −
}+ −
+ −
void QCalendarWidget::setMaximumDate(const QDate &date)+ −
{+ −
Q_D(QCalendarWidget);+ −
if (!date.isValid() || d->m_model->m_maximumDate == date)+ −
return;+ −
+ −
QDate oldDate = d->m_model->m_date;+ −
d->m_model->setMaximumDate(date);+ −
d->yearEdit->setMaximum(d->m_model->m_maximumDate.year());+ −
d->updateMonthMenu();+ −
QDate newDate = d->m_model->m_date;+ −
if (oldDate != newDate) {+ −
d->update();+ −
d->showMonth(newDate.year(), newDate.month());+ −
d->m_navigator->setDate(newDate);+ −
emit selectionChanged();+ −
}+ −
}+ −
+ −
/*!+ −
Defines a date range by setting the minimumDate and maximumDate+ −
properties.+ −
+ −
The date range restricts the user selection, i.e. the user can+ −
only select dates within the specified date range. Note that+ −
+ −
\snippet doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp 3+ −
+ −
is analogous to+ −
+ −
\snippet doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp 4+ −
+ −
If either the \a min or \a max parameters are not valid QDate+ −
objects, this function does nothing.+ −
+ −
\sa setMinimumDate(), setMaximumDate()+ −
*/+ −
+ −
void QCalendarWidget::setDateRange(const QDate &min, const QDate &max)+ −
{+ −
Q_D(QCalendarWidget);+ −
if (d->m_model->m_minimumDate == min && d->m_model->m_maximumDate == max)+ −
return;+ −
if (!min.isValid() || !max.isValid())+ −
return;+ −
+ −
QDate oldDate = d->m_model->m_date;+ −
d->m_model->setRange(min, max);+ −
d->yearEdit->setMinimum(d->m_model->m_minimumDate.year());+ −
d->yearEdit->setMaximum(d->m_model->m_maximumDate.year());+ −
d->updateMonthMenu();+ −
QDate newDate = d->m_model->m_date;+ −
if (oldDate != newDate) {+ −
d->update();+ −
d->showMonth(newDate.year(), newDate.month());+ −
d->m_navigator->setDate(newDate);+ −
emit selectionChanged();+ −
}+ −
}+ −
+ −
+ −
/*! \enum QCalendarWidget::HorizontalHeaderFormat+ −
+ −
This enum type defines the various formats the horizontal header can display.+ −
+ −
\value SingleLetterDayNames The header displays a single letter abbreviation for day names (e.g. M for Monday).+ −
\value ShortDayNames The header displays a short abbreviation for day names (e.g. Mon for Monday).+ −
\value LongDayNames The header displays complete day names (e.g. Monday).+ −
\value NoHorizontalHeader The header is hidden.+ −
+ −
\sa horizontalHeaderFormat(), VerticalHeaderFormat+ −
*/+ −
+ −
/*!+ −
\property QCalendarWidget::horizontalHeaderFormat+ −
\brief the format of the horizontal header.+ −
+ −
The default value is QCalendarWidget::ShortDayNames.+ −
*/+ −
+ −
void QCalendarWidget::setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat format)+ −
{+ −
Q_D(QCalendarWidget);+ −
if (d->m_model->m_horizontalHeaderFormat == format)+ −
return;+ −
+ −
d->m_model->setHorizontalHeaderFormat(format);+ −
d->cachedSizeHint = QSize();+ −
d->m_view->viewport()->update();+ −
d->m_view->updateGeometry();+ −
}+ −
+ −
QCalendarWidget::HorizontalHeaderFormat QCalendarWidget::horizontalHeaderFormat() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_model->m_horizontalHeaderFormat;+ −
}+ −
+ −
+ −
/*! + −
\enum QCalendarWidget::VerticalHeaderFormat+ −
+ −
This enum type defines the various formats the vertical header can display.+ −
+ −
\value ISOWeekNumbers The header displays ISO week numbers as described by \l QDate::weekNumber().+ −
\value NoVerticalHeader The header is hidden.+ −
+ −
\sa verticalHeaderFormat(), HorizontalHeaderFormat+ −
*/+ −
+ −
/*!+ −
\property QCalendarWidget::verticalHeaderFormat+ −
\brief the format of the vertical header.+ −
+ −
The default value is QCalendarWidget::ISOWeekNumber.+ −
*/+ −
+ −
QCalendarWidget::VerticalHeaderFormat QCalendarWidget::verticalHeaderFormat() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
bool shown = d->m_model->weekNumbersShown();+ −
if (shown)+ −
return QCalendarWidget::ISOWeekNumbers;+ −
return QCalendarWidget::NoVerticalHeader;+ −
}+ −
+ −
void QCalendarWidget::setVerticalHeaderFormat(QCalendarWidget::VerticalHeaderFormat format)+ −
{+ −
Q_D(QCalendarWidget);+ −
bool show = false;+ −
if (format == QCalendarWidget::ISOWeekNumbers)+ −
show = true;+ −
if (d->m_model->weekNumbersShown() == show)+ −
return;+ −
d->m_model->setWeekNumbersShown(show);+ −
d->cachedSizeHint = QSize();+ −
d->m_view->viewport()->update();+ −
d->m_view->updateGeometry();+ −
}+ −
+ −
/*!+ −
\property QCalendarWidget::gridVisible+ −
\brief whether the table grid is displayed.+ −
+ −
\table+ −
\row+ −
\o \inlineimage qcalendarwidget-grid.png+ −
\row+ −
\o+ −
\snippet doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp 5+ −
\endtable+ −
+ −
The default value is false.+ −
*/+ −
+ −
bool QCalendarWidget::isGridVisible() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_view->showGrid();+ −
}+ −
+ −
void QCalendarWidget::setGridVisible(bool show)+ −
{+ −
Q_D(QCalendarWidget);+ −
d->m_view->setShowGrid(show);+ −
d->cachedSizeHint = QSize();+ −
d->m_view->viewport()->update();+ −
d->m_view->updateGeometry();+ −
}+ −
+ −
/*!+ −
\property QCalendarWidget::selectionMode+ −
\brief the type of selection the user can make in the calendar+ −
+ −
When this property is set to SingleSelection, the user can select a date+ −
within the minimum and maximum allowed dates, using either the mouse or+ −
the keyboard.+ −
+ −
When the property is set to NoSelection, the user will be unable to select+ −
dates, but they can still be selected programmatically. Note that the date+ −
that is selected when the property is set to NoSelection will still be+ −
the selected date of the calendar.+ −
+ −
The default value is SingleSelection.+ −
*/+ −
+ −
QCalendarWidget::SelectionMode QCalendarWidget::selectionMode() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_view->readOnly ? QCalendarWidget::NoSelection : QCalendarWidget::SingleSelection;+ −
}+ −
+ −
void QCalendarWidget::setSelectionMode(SelectionMode mode)+ −
{+ −
Q_D(QCalendarWidget);+ −
d->m_view->readOnly = (mode == QCalendarWidget::NoSelection);+ −
d->setNavigatorEnabled(isDateEditEnabled() && (selectionMode() != QCalendarWidget::NoSelection));+ −
d->update();+ −
}+ −
+ −
/*!+ −
\property QCalendarWidget::firstDayOfWeek+ −
\brief a value identifying the day displayed in the first column.+ −
+ −
By default, the day displayed in the first column is Sunday+ −
*/+ −
+ −
void QCalendarWidget::setFirstDayOfWeek(Qt::DayOfWeek dayOfWeek)+ −
{+ −
Q_D(QCalendarWidget);+ −
if ((Qt::DayOfWeek)d->m_model->firstColumnDay() == dayOfWeek)+ −
return;+ −
+ −
d->m_model->setFirstColumnDay(dayOfWeek);+ −
d->update();+ −
}+ −
+ −
Qt::DayOfWeek QCalendarWidget::firstDayOfWeek() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return (Qt::DayOfWeek)d->m_model->firstColumnDay();+ −
}+ −
+ −
/*!+ −
Returns the text char format for rendering the header.+ −
*/+ −
QTextCharFormat QCalendarWidget::headerTextFormat() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_model->m_headerFormat;+ −
}+ −
+ −
/*!+ −
Sets the text char format for rendering the header to \a format.+ −
If you also set a weekday text format, this format's foreground and+ −
background color will take precedence over the header's format.+ −
The other formatting information will still be decided by+ −
the header's format.+ −
*/+ −
void QCalendarWidget::setHeaderTextFormat(const QTextCharFormat &format)+ −
{+ −
Q_D(QCalendarWidget);+ −
d->m_model->m_headerFormat = format;+ −
d->cachedSizeHint = QSize();+ −
d->m_view->viewport()->update();+ −
d->m_view->updateGeometry();+ −
}+ −
+ −
/*!+ −
Returns the text char format for rendering of day in the week \a dayOfWeek.+ −
+ −
\sa headerTextFormat()+ −
*/+ −
QTextCharFormat QCalendarWidget::weekdayTextFormat(Qt::DayOfWeek dayOfWeek) const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_model->m_dayFormats.value(dayOfWeek);+ −
}+ −
+ −
/*!+ −
Sets the text char format for rendering of day in the week \a dayOfWeek to \a format.+ −
The format will take precedence over the header format in case of foreground+ −
and background color. Other text formatting information is taken from the headers format.+ −
+ −
\sa setHeaderTextFormat()+ −
*/+ −
void QCalendarWidget::setWeekdayTextFormat(Qt::DayOfWeek dayOfWeek, const QTextCharFormat &format)+ −
{+ −
Q_D(QCalendarWidget);+ −
d->m_model->m_dayFormats[dayOfWeek] = format;+ −
d->cachedSizeHint = QSize();+ −
d->m_view->viewport()->update();+ −
d->m_view->updateGeometry();+ −
}+ −
+ −
/*!+ −
Returns a QMap from QDate to QTextCharFormat showing all dates+ −
that use a special format that alters their rendering.+ −
*/+ −
QMap<QDate, QTextCharFormat> QCalendarWidget::dateTextFormat() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_model->m_dateFormats;+ −
}+ −
+ −
/*!+ −
Returns a QTextCharFormat for \a date. The char format can be be+ −
empty if the date is not renderd specially.+ −
*/+ −
QTextCharFormat QCalendarWidget::dateTextFormat(const QDate &date) const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_model->m_dateFormats.value(date);+ −
}+ −
+ −
/*!+ −
Sets the format used to render the given \a date to that specified by \a format.+ −
+ −
If \a date is null, all date formats are cleared.+ −
*/+ −
void QCalendarWidget::setDateTextFormat(const QDate &date, const QTextCharFormat &format)+ −
{+ −
Q_D(QCalendarWidget);+ −
if (date.isNull())+ −
d->m_model->m_dateFormats.clear();+ −
else+ −
d->m_model->m_dateFormats[date] = format;+ −
d->m_view->viewport()->update();+ −
d->m_view->updateGeometry();+ −
}+ −
+ −
/*!+ −
\property QCalendarWidget::dateEditEnabled+ −
\brief whether the date edit popup is enabled+ −
\since 4.3+ −
+ −
If this property is enabled, pressing a non-modifier key will cause a+ −
date edit to popup if the calendar widget has focus, allowing the user+ −
to specify a date in the form specified by the current locale.+ −
+ −
By default, this property is enabled.+ −
+ −
The date edit is simpler in appearance than QDateEdit, but allows the+ −
user to navigate between fields using the left and right cursor keys,+ −
increment and decrement individual fields using the up and down cursor+ −
keys, and enter values directly using the number keys.+ −
+ −
\sa QCalendarWidget::dateEditAcceptDelay+ −
*/+ −
bool QCalendarWidget::isDateEditEnabled() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_dateEditEnabled;+ −
}+ −
+ −
void QCalendarWidget::setDateEditEnabled(bool enable)+ −
{+ −
Q_D(QCalendarWidget);+ −
if (isDateEditEnabled() == enable)+ −
return;+ −
+ −
d->m_dateEditEnabled = enable;+ −
+ −
d->setNavigatorEnabled(enable && (selectionMode() != QCalendarWidget::NoSelection));+ −
}+ −
+ −
/*!+ −
\property QCalendarWidget::dateEditAcceptDelay+ −
\brief the time an inactive date edit is shown before its contents are accepted+ −
\since 4.3+ −
+ −
If the calendar widget's \l{dateEditEnabled}{date edit is enabled}, this+ −
property specifies the amount of time (in millseconds) that the date edit+ −
remains open after the most recent user input. Once this time has elapsed,+ −
the date specified in the date edit is accepted and the popup is closed.+ −
+ −
By default, the delay is defined to be 1500 milliseconds (1.5 seconds).+ −
*/+ −
int QCalendarWidget::dateEditAcceptDelay() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->m_navigator->dateEditAcceptDelay();+ −
}+ −
+ −
void QCalendarWidget::setDateEditAcceptDelay(int delay)+ −
{+ −
Q_D(QCalendarWidget);+ −
d->m_navigator->setDateEditAcceptDelay(delay);+ −
}+ −
+ −
/*!+ −
\since 4.4+ −
+ −
Updates the cell specified by the given \a date unless updates+ −
are disabled or the cell is hidden.+ −
+ −
\sa updateCells(), yearShown(), monthShown()+ −
*/+ −
void QCalendarWidget::updateCell(const QDate &date)+ −
{+ −
if (!date.isValid()) {+ −
qWarning("QCalendarWidget::updateCell: Invalid date");+ −
return;+ −
}+ −
+ −
if (!isVisible())+ −
return;+ −
+ −
Q_D(QCalendarWidget);+ −
int row, column;+ −
d->m_model->cellForDate(date, &row, &column);+ −
if (row == -1 || column == -1)+ −
return;+ −
+ −
QModelIndex modelIndex = d->m_model->index(row, column);+ −
if (!modelIndex.isValid())+ −
return;+ −
+ −
d->m_view->viewport()->update(d->m_view->visualRect(modelIndex));+ −
}+ −
+ −
/*!+ −
\since 4.4+ −
+ −
Updates all visible cells unless updates are disabled.+ −
+ −
\sa updateCell()+ −
*/+ −
void QCalendarWidget::updateCells()+ −
{+ −
Q_D(QCalendarWidget);+ −
if (isVisible())+ −
d->m_view->viewport()->update();+ −
}+ −
+ −
/*!+ −
\fn void QCalendarWidget::selectionChanged()+ −
+ −
This signal is emitted when the currently selected date is+ −
changed.+ −
+ −
The currently selected date can be changed by the user using the+ −
mouse or keyboard, or by the programmer using setSelectedDate().+ −
+ −
\sa selectedDate()+ −
*/+ −
+ −
/*!+ −
\fn void QCalendarWidget::currentPageChanged(int year, int month)+ −
+ −
This signal is emitted when the currently shown month is changed.+ −
The new \a year and \a month are passed as parameters.+ −
+ −
\sa setCurrentPage()+ −
*/+ −
+ −
/*!+ −
\fn void QCalendarWidget::activated(const QDate &date)+ −
+ −
This signal is emitted whenever the user presses the Return or+ −
Enter key or double-clicks a \a date in the calendar+ −
widget.+ −
*/+ −
+ −
/*!+ −
\fn void QCalendarWidget::clicked(const QDate &date)+ −
+ −
This signal is emitted when a mouse button is clicked. The date+ −
the mouse was clicked on is specified by \a date. The signal is+ −
only emitted when clicked on a valid date, e.g., dates are not+ −
outside the minimumDate() and maximumDate(). If the selection mode+ −
is NoSelection, this signal will not be emitted.+ −
+ −
*/+ −
+ −
/*!+ −
\property QCalendarWidget::headerVisible+ −
\brief whether the navigation bar is shown or not+ −
+ −
\obsolete+ −
+ −
Use navigationBarVisible() instead.+ −
+ −
By default, this property is true.+ −
*/+ −
+ −
/*!+ −
\obsolete+ −
+ −
Use setNavigationBarVisible() instead.+ −
*/+ −
bool QCalendarWidget::isHeaderVisible() const+ −
{+ −
Q_D(const QCalendarWidget);+ −
return d->navBarVisible;+ −
}+ −
+ −
/*!+ −
\obsolete+ −
+ −
Use setNavigationBarVisible() instead.+ −
+ −
*/+ −
void QCalendarWidget::setHeaderVisible(bool visible)+ −
{+ −
setNavigationBarVisible(visible);+ −
}+ −
+ −
/*!+ −
\property QCalendarWidget::navigationBarVisible+ −
\brief whether the navigation bar is shown or not+ −
+ −
\since 4.3+ −
+ −
When this property is true (the default), the next month,+ −
previous month, month selection, year selection controls are+ −
shown on top.+ −
+ −
When the property is set to false, these controls are hidden.+ −
*/+ −
+ −
void QCalendarWidget::setNavigationBarVisible(bool visible)+ −
{+ −
Q_D(QCalendarWidget);+ −
d->navBarVisible = visible;+ −
d->cachedSizeHint = QSize();+ −
d->navBarBackground->setVisible(visible);+ −
updateGeometry();+ −
}+ −
+ −
/*!+ −
\reimp+ −
*/+ −
bool QCalendarWidget::event(QEvent *event)+ −
{+ −
Q_D(QCalendarWidget);+ −
switch (event->type()) {+ −
case QEvent::LayoutDirectionChange:+ −
d->updateButtonIcons();+ −
case QEvent::LocaleChange:+ −
d->cachedSizeHint = QSize();+ −
d->updateMonthMenuNames();+ −
d->updateNavigationBar();+ −
d->m_view->updateGeometry();+ −
break;+ −
case QEvent::FontChange:+ −
case QEvent::ApplicationFontChange:+ −
d->cachedSizeHint = QSize();+ −
d->m_view->updateGeometry();+ −
break;+ −
case QEvent::StyleChange:+ −
d->cachedSizeHint = QSize();+ −
d->m_view->updateGeometry();+ −
default:+ −
break;+ −
}+ −
return QWidget::event(event);+ −
}+ −
+ −
/*!+ −
\reimp+ −
*/+ −
bool QCalendarWidget::eventFilter(QObject *watched, QEvent *event)+ −
{+ −
Q_D(QCalendarWidget);+ −
if (event->type() == QEvent::MouseButtonPress && d->yearEdit->hasFocus()) {+ −
QWidget *tlw = window();+ −
QWidget *widget = static_cast<QWidget*>(watched);+ −
//as we have a event filter on the whole application we first make sure that the top level widget+ −
//of both this and the watched widget are the same to decide if we should finish the year edition.+ −
if (widget->window() == tlw) {+ −
QPoint mousePos = widget->mapTo(tlw, static_cast<QMouseEvent *>(event)->pos());+ −
QRect geom = QRect(d->yearEdit->mapTo(tlw, QPoint(0, 0)), d->yearEdit->size());+ −
if (!geom.contains(mousePos)) {+ −
event->accept();+ −
d->_q_yearEditingFinished();+ −
setFocus();+ −
return true;+ −
}+ −
}+ −
}+ −
return QWidget::eventFilter(watched, event);+ −
}+ −
+ −
/*!+ −
\reimp+ −
*/+ −
void QCalendarWidget::mousePressEvent(QMouseEvent *event)+ −
{+ −
setAttribute(Qt::WA_NoMouseReplay);+ −
QWidget::mousePressEvent(event);+ −
setFocus();+ −
}+ −
+ −
/*!+ −
\reimp+ −
*/+ −
void QCalendarWidget::resizeEvent(QResizeEvent * event)+ −
{+ −
Q_D(QCalendarWidget);+ −
+ −
// XXX Should really use a QWidgetStack for yearEdit and yearButton,+ −
// XXX here we hide the year edit when the layout is likely to break+ −
// XXX the manual positioning of the yearEdit over the yearButton.+ −
if(d->yearEdit->isVisible() && event->size().width() != event->oldSize().width())+ −
d->_q_yearEditingFinished();+ −
+ −
QWidget::resizeEvent(event);+ −
}+ −
+ −
/*!+ −
\reimp+ −
*/+ −
void QCalendarWidget::keyPressEvent(QKeyEvent * event)+ −
{+ −
Q_D(QCalendarWidget);+ −
if(d->yearEdit->isVisible()&& event->key() == Qt::Key_Escape)+ −
{+ −
d->yearEdit->setValue(yearShown());+ −
d->_q_yearEditingFinished();+ −
return;+ −
}+ −
QWidget::keyPressEvent(event);+ −
}+ −
+ −
QT_END_NAMESPACE+ −
+ −
#include "qcalendarwidget.moc"+ −
#include "moc_qcalendarwidget.cpp"+ −
+ −
#endif //QT_NO_CALENDARWIDGET+ −