qcalendarwidget.cpp

来自「QT 开发环境里面一个很重要的文件」· C++ 代码 · 共 2,019 行 · 第 1/4 页

CPP
2,019
字号
}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(-1);            break;        case QAbstractItemView::MoveRight:            currentDate = currentDate.addDays(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){    if (!readOnly) {        switch (event->key()) {            case Qt::Key_Return:            case Qt::Key_Enter:            case Qt::Key_Space:            case Qt::Key_Select:                emit editingFinished();                break;            default:                break;        }    }    QTableView::keyPressEvent(event);}bool QCalendarView::event(QEvent *event){    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->minimumDate            && date <= calendarModel->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->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_OBJECTpublic:    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 QStyleOptionViewItem storedOption;};//Private tool button classclass QCalToolButton: public QToolButton{public:    QCalToolButton(QWidget * parent)        :QToolButton(parent), hover(false) ,oldState(false)         {  }private:    bool hover, oldState;protected:    void enterEvent(QEvent * e)    {        hover = true;        QToolButton::enterEvent(e);    }    void leaveEvent(QEvent * e)    {        hover = false;        QToolButton::leaveEvent(e);    }    void mousePressEvent(QMouseEvent * e)    {        hover = true;        QToolButton::mousePressEvent(e);    }    void mouseReleaseEvent(QMouseEvent * e)    {        hover = true;        QToolButton::mouseReleaseEvent(e);    }    void paintEvent(QPaintEvent *e)    {        QPalette toolPalette = parentWidget()->palette();        bool newState = (menu()) ? menu()->isVisible():isDown();#ifndef Q_WS_MAC        if (newState || hover) //act as normal button            setPalette(toolPalette);        else {            //set the highlight color for button text            toolPalette.setColor(QPalette::ButtonText, toolPalette.color(QPalette::HighlightedText));            setPalette(toolPalette);        }#endif        if (newState != oldState) {            //update the hover if the button is released            hover = oldState ? false : hover;            oldState = newState;        }        QToolButton::paintEvent(e);    }};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_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 createHeader(QWidget *widget);    void updateMonthMenu();    void updateHeader();    void updateCurrentPage(QDate &newDate);    inline QDate getCurrentDate();    QCalendarModel *m_model;    QCalendarView *m_view;    QCalendarDelegate *m_delegate;    QItemSelectionModel *m_selection;    QToolButton *nextMonth;    QToolButton *prevMonth;    QCalToolButton *monthButton;    QMenu *monthMenu;    QMap<int, QAction *> monthToAction;    QCalToolButton *yearButton;    QSpinBox *yearEdit;    QWidget *headerBackground;    QSpacerItem *spaceHolder;    bool headerVisible;};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;    headerVisible = true;}void QCalendarWidgetPrivate::createHeader(QWidget *widget){    Q_Q(QCalendarWidget);    headerBackground = new QWidget(widget);    headerBackground->setAutoFillBackground(true);    headerBackground->setBackgroundRole(QPalette::Highlight);    prevMonth = new QToolButton(headerBackground);    nextMonth = new QToolButton(headerBackground);    prevMonth->setAutoRaise(true);    nextMonth->setAutoRaise(true);    prevMonth->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);    nextMonth->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);    nextMonth->setAutoRaise(true);    prevMonth->setIcon(q->style()->standardPixmap(QStyle::SP_ArrowLeft));    nextMonth->setIcon(q->style()->standardPixmap(QStyle::SP_ArrowRight));    prevMonth->setAutoRepeat(true);    nextMonth->setAutoRepeat(true);    prevMonth->setFocusProxy(m_view);    nextMonth->setFocusProxy(m_view);    monthButton = new QCalToolButton(headerBackground);    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(QDate::longMonthName(i));        QAction *act = monthMenu->addAction(monthName);        act->setData(i);        monthToAction[i] = act;    }    monthButton->setMenu(monthMenu);    yearButton = new QCalToolButton(headerBackground);    yearButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);    yearButton->setAutoRaise(true);    yearEdit = new QSpinBox(headerBackground);    QFont font = q->font();    font.setBold(true);    monthButton->setFont(font);    yearButton->setFont(font);    yearEdit->setFrame(false);    yearEdit->setMinimum(m_model->minimumDate.year());    yearEdit->setMaximum(m_model->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);    headerBackground->setLayout(headerLayout);    yearEdit->setFocusPolicy(Qt::StrongFocus);    prevMonth->setFocusPolicy(Qt::StrongFocus);    nextMonth->setFocusPolicy(Qt::StrongFocus);    //set names for the header controls.    prevMonth->setObjectName("qt_calendar_prevmonth");    nextMonth->setObjectName("qt_calendar_nextmonth");    monthButton->setObjectName("qt_calendar_monthbutton");    yearButton->setObjectName("qt_calendar_yearbutton");    yearEdit->setObjectName("qt_calendar_yearedit");    updateMonthMenu();    showMonth(m_model->date.year(),m_model->date.month());}void QCalendarWidgetPrivate::updateMonthMenu(){    int beg = 1, end = 12;    bool prevEnabled = true;    bool nextEnabled = true;    if (m_model->shownYear == m_model->minimumDate.year()) {        beg = m_model->minimumDate.month();        if (m_model->shownMonth == m_model->minimumDate.month())            prevEnabled = false;    }    if (m_model->shownYear == m_model->maximumDate.year()) {        end = m_model->maximumDate.month();        if (m_model->shownMonth == m_model->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::updateCurrentPage(QDate &newDate){    Q_Q(QCalendarWidget);    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(){    yearButton->setText(yearEdit->text());    yearEdit->hide();    spaceHolder->changeSize(0, 0);    yearButton->show();    QDate currentDate(yearEdit->text().toInt(), getCurrentDate().month(), getCurrentDate().day());    updateCurrentPage(currentDate);}void QCalendarWidgetPrivate::_q_yearClicked(){    //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();    yearEdit->show();    yearEdit->raise();    yearEdit->selectAll();    yearEdit->setFocus(Qt::MouseFocusReason);}void QCalendarWidgetPrivate::showMonth(int year, int month){    if (m_model->shownYear == year && m_model->shownMonth == month)        return;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?