/****************************************************************************
**
** Copyright (C) 2011 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$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $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
