qcalendarwidget.cpp
来自「QT 开发环境里面一个很重要的文件」· C++ 代码 · 共 2,019 行 · 第 1/4 页
CPP
2,019 行
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.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 GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#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>enum { RowCount = 6, ColumnCount = 7, HeaderColumn = 0, HeaderRow = 0, MinimumDayOffset = 1};class QCalendarView;class QCalendarModel : public QAbstractTableModel{ Q_OBJECTpublic: 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; int dayOfWeekForColumn(int section) const; int columnForDayOfWeek(int day) const; QDate dateForCell(int row, int column) const; void cellForDate(const QDate &date, int *row, int *column) const; QString dayName(int day) const; void setView(QCalendarView *view) { m_view = view; } void internalUpdate(); int m_firstColumn; int m_firstRow; QDate date; QDate minimumDate; QDate maximumDate; int shownYear; int shownMonth; Qt::DayOfWeek m_firstDay; QCalendarWidget::HorizontalHeaderFormat 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_OBJECTpublic: QCalendarView(QWidget *parent = 0); void internalUpdate() { updateGeometries(); } void setReadOnly(bool enable);signals: 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); void keyPressEvent(QKeyEvent *event); bool event(QEvent *event); QDate handleMouseEvent(QMouseEvent *event);public: bool readOnly;private: bool validDateClicked;};QCalendarModel::QCalendarModel(QObject *parent) : QAbstractTableModel(parent){ date = QDate::currentDate(); minimumDate = QDate::fromJulianDay(0); maximumDate = QDate(7999, 12, 31); shownYear = date.year(); shownMonth = date.month(); m_firstDay = Qt::Sunday; horizontalHeaderFormat = QCalendarWidget::ShortDayNames; m_weekNumbersShown = true; m_firstColumn = 1; m_firstRow = 1; m_view = 0;}int QCalendarModel::dayOfWeekForColumn(int column) const{ int col = column - m_firstColumn; if (col < 0 || col > 6) return 0; int day = m_firstDay + col; if (day > 7) day -= 7; return Qt::DayOfWeek(day);}int QCalendarModel::columnForDayOfWeek(int 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;}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(); QDate firstDate(shownYear, shownMonth, 15); if (!firstDate.isValid()) { return QDate(); } int columnForFirstOfShownMonth = columnForDayOfWeek(firstDate.dayOfWeek()); if (columnForFirstOfShownMonth - m_firstColumn < MinimumDayOffset) row -= 1; int daysInShownMonth = firstDate.daysInMonth(); int requestedDay = 7 * (row - m_firstRow) + column - columnForFirstOfShownMonth + 1; if (requestedDay > daysInShownMonth) { QDate nextMonth = firstDate.addMonths(1); if (!nextMonth.isValid()) { return QDate(); } return QDate(nextMonth.year(), nextMonth.month(), requestedDay - daysInShownMonth); } else if (requestedDay <= 0) { QDate previousMonth = firstDate.addMonths(-1); if (!previousMonth.isValid()) { return QDate(); } int daysInMonth = previousMonth.daysInMonth(); return QDate(previousMonth.year(), previousMonth.month(), daysInMonth + requestedDay); } return QDate(shownYear, shownMonth, requestedDay);}void QCalendarModel::cellForDate(const QDate &date, int *row, int *column) const{ int day = date.day(); QDate firstDate(shownYear, shownMonth, 15); int columnForFirstOfShownMonth = columnForDayOfWeek(firstDate.dayOfWeek()); int daysInShownMonth = firstDate.daysInMonth(); QDate previousMonth = firstDate.addMonths(-1); QDate nextMonth = firstDate.addMonths(1); if (date.year() == shownYear && date.month() == shownMonth) { *column = (day + columnForFirstOfShownMonth - m_firstColumn - 1) % 7; *row = (day + columnForFirstOfShownMonth - m_firstColumn - 1) / 7; } else if (previousMonth.isValid() && date.year() == previousMonth.year() && date.month() == previousMonth.month()) { int daysInMonth = previousMonth.daysInMonth(); *column = (day - daysInMonth + columnForFirstOfShownMonth - m_firstColumn - 1) % 7; *row = (day - daysInMonth + columnForFirstOfShownMonth - m_firstColumn - 1) / 7; if (*column < 0) { *column += 7; *row -= 1; } } else if (nextMonth.isValid() && date.year() == nextMonth.year() && date.month() == nextMonth.month()) { *column = (day + daysInShownMonth + columnForFirstOfShownMonth - m_firstColumn - 1) % 7; *row = (day + daysInShownMonth + columnForFirstOfShownMonth - m_firstColumn - 1) / 7; } else { *row = -1; *column = -1; return; } if (columnForFirstOfShownMonth - m_firstColumn < MinimumDayOffset) *row += 1; if (*row < 0 || *row > RowCount - 1 || *column < 0 || *column > ColumnCount - 1) { *row = -1; *column = -1; return; } *row += m_firstRow; *column += m_firstColumn;}QString QCalendarModel::dayName(int day) const{ switch (horizontalHeaderFormat) { case QCalendarWidget::SingleLetterDayNames: return QDate::shortDayName(day).left(1); case QCalendarWidget::ShortDayNames: return QDate::shortDayName(day); case QCalendarWidget::LongDayNames: return QDate::longDayName(day); 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) || (horizontalHeaderFormat != QCalendarWidget::NoHorizontalHeader && row == HeaderRow); format.setBackground(pal.brush(cg, header ? QPalette::AlternateBase : QPalette::Base)); if (header) { format.merge(m_headerFormat); } if (col >= m_firstColumn && col < m_firstColumn + ColumnCount) { Qt::DayOfWeek dayOfWeek = Qt::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 < minimumDate || date > maximumDate) format.setBackground(pal.brush(cg, QPalette::Window)); if (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 (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(); 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 < minimumDate) return 0; if (date > maximumDate) return 0; return QAbstractTableModel::flags(index);}void QCalendarModel::setDate(const QDate &d){ date = d; if (date < minimumDate) date = minimumDate; else if (date > maximumDate) date = maximumDate;}void QCalendarModel::showMonth(int year, int month){ if (shownYear == year && shownMonth == month) return; shownYear = year; shownMonth = month; internalUpdate();}void QCalendarModel::setMinimumDate(const QDate &d){ if (!d.isValid() || d == minimumDate) return; minimumDate = d; if (maximumDate < minimumDate) maximumDate = minimumDate; if (date < minimumDate) date = minimumDate; internalUpdate();}void QCalendarModel::setMaximumDate(const QDate &d){ if (!d.isValid() || d == maximumDate) return; maximumDate = d; if (minimumDate > maximumDate) minimumDate = maximumDate; if (date > maximumDate) date = maximumDate; internalUpdate();}void QCalendarModel::setRange(const QDate &min, const QDate &max){ minimumDate = min; maximumDate = max; if(minimumDate > maximumDate) qSwap(minimumDate, maximumDate); if (date < minimumDate) date = minimumDate; if (date > maximumDate) date = 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 (horizontalHeaderFormat == format) return; int oldFormat = horizontalHeaderFormat; horizontalHeaderFormat = format; if (oldFormat == QCalendarWidget::NoHorizontalHeader) { m_firstRow = 1; insertRow(0); } else if (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);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?