|  | @@ -0,0 +1,408 @@
 | 
	
		
			
				|  |  | +//qcustomcalendarwidget.cpp
 | 
	
		
			
				|  |  | +#include "calendarwidgetex.h"
 | 
	
		
			
				|  |  | +#include <QPainter>
 | 
	
		
			
				|  |  | +#include <QProxyStyle>
 | 
	
		
			
				|  |  | +#include <QTableView>
 | 
	
		
			
				|  |  | +#include <QHeaderView>
 | 
	
		
			
				|  |  | +#include <QLayout>
 | 
	
		
			
				|  |  | +#include <QPushButton>
 | 
	
		
			
				|  |  | +#include <QLabel>
 | 
	
		
			
				|  |  | +#include <QDebug>
 | 
	
		
			
				|  |  | +#include <QLayoutItem>
 | 
	
		
			
				|  |  | +#include <QKeyEvent>
 | 
	
		
			
				|  |  | +#include <QPainterPath>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include "scopeselectionmodel.h"
 | 
	
		
			
				|  |  | +#include "PaintHelper/painthelper.h"
 | 
	
		
			
				|  |  | +// #include "StyleManager/lhstylemanager.h"
 | 
	
		
			
				|  |  | +//#include "utility/utility.h"
 | 
	
		
			
				|  |  | +#include "UIStyleManager.h"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +CalendarWidgetEx::CalendarWidgetEx(QWidget *parent)
 | 
	
		
			
				|  |  | +    : QCalendarWidget(parent)
 | 
	
		
			
				|  |  | +    , m_modeSelection(Normal)
 | 
	
		
			
				|  |  | +    , m_pDateScopeModel(nullptr)
 | 
	
		
			
				|  |  | +    , m_nLineHeight(-1)
 | 
	
		
			
				|  |  | +    , m_hasTopSplitLine(false)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    setWindowFlag(Qt::NoDropShadowWindowHint);
 | 
	
		
			
				|  |  | +    setAttribute(Qt::WA_TranslucentBackground);
 | 
	
		
			
				|  |  | +    setWindowFlag(Qt::FramelessWindowHint);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //使用固定尺寸(无法通过resize控制日历大小, 日历整体大小由layout下的控件的fixSize决定)
 | 
	
		
			
				|  |  | +    //layout()->setSizeConstraint(QLayout::SetFixedSize);
 | 
	
		
			
				|  |  | +    //禁用原有的年月导航
 | 
	
		
			
				|  |  | +    setNavigationBarVisible(false);
 | 
	
		
			
				|  |  | +    //禁用横向纵向表头
 | 
	
		
			
				|  |  | +    setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
 | 
	
		
			
				|  |  | +    setHorizontalHeaderFormat(QCalendarWidget::NoHorizontalHeader);
 | 
	
		
			
				|  |  | +    //取消聚焦虚线框
 | 
	
		
			
				|  |  | +    setStyle(new NoFocusStyle(this));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    QVBoxLayout *vBodyLayout = qobject_cast<QVBoxLayout *>(layout());
 | 
	
		
			
				|  |  | +    if(vBodyLayout == nullptr) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    m_pNav = new CalendarNav(this);
 | 
	
		
			
				|  |  | +    m_pHeader = new CalendarHeader(this);
 | 
	
		
			
				|  |  | +    setFirstDayOfWeek(Qt::Sunday);
 | 
	
		
			
				|  |  | +    m_pHeader->SetFirstDayOfWeek(Qt::Sunday);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    vBodyLayout->insertWidget(0, m_pNav);
 | 
	
		
			
				|  |  | +    // 导航和星期标题间距
 | 
	
		
			
				|  |  | +    vBodyLayout->insertSpacing(1, 10);
 | 
	
		
			
				|  |  | +    vBodyLayout->insertWidget(2, m_pHeader);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    vBodyLayout->setSpacing(10);
 | 
	
		
			
				|  |  | +    vBodyLayout->setContentsMargins(10,0,10,10);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    m_nLineHeight = vBodyLayout->itemAt(4)->widget()->mapTo(this, QPoint(0,0)).y();
 | 
	
		
			
				|  |  | +    //qDebug()<<"m_nLineHeight"<<m_nLineHeight<<vBodyLayout->itemAt(3)->widget()->height();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //开启鼠标监测
 | 
	
		
			
				|  |  | +    QTableView *pCalendarView = dynamic_cast<QTableView*>(vBodyLayout->itemAt(4)->widget());
 | 
	
		
			
				|  |  | +    if (Q_NULLPTR != pCalendarView) {
 | 
	
		
			
				|  |  | +        pCalendarView->setMouseTracking(true);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //在构造函数里取消selectionChanged, clicked事件没用, 因为执行QDateTimeEdit的setCalendarWidget方法时, 会重新绑定
 | 
	
		
			
				|  |  | +    //所以必须等setCalendarWidget执行完后再取消事件
 | 
	
		
			
				|  |  | +    //calendarWidget->disconnect(calendarWidget, &QCalendarWidget::selectionChanged, 0, 0);
 | 
	
		
			
				|  |  | +    //calendarWidget->disconnect(calendarWidget, &QCalendarWidget::clicked, 0, 0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    setMouseTracking(true);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 设置默认字体后,修复单元格变得很宽的问题
 | 
	
		
			
				|  |  | +    for (QWidget* f : findChildren<QWidget*>()) {
 | 
	
		
			
				|  |  | +        if(f->objectName() != "qt_calendar_calendarview") continue;
 | 
	
		
			
				|  |  | +        QTableView* pView = reinterpret_cast<QTableView*>(f);
 | 
	
		
			
				|  |  | +        if (nullptr != pView && nullptr != pView->horizontalHeader()) {
 | 
	
		
			
				|  |  | +            pView->horizontalHeader()->setMaximumSectionSize(WINDOW_WIDTH / 8);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    connect(this, &QCalendarWidget::clicked, this, &CalendarWidgetEx::OnClicked);
 | 
	
		
			
				|  |  | +    // initSkinColor();
 | 
	
		
			
				|  |  | +    setUIStyle();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /* 设置对象名称,加载QSS */
 | 
	
		
			
				|  |  | +    // this->setObjectName("calendarWidget");
 | 
	
		
			
				|  |  | +    this->setStyleSheet("background-color:transparent;");
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void CalendarWidgetEx::SetSelectMode(SelectMode mode, ScopeSelectionModel *pDataModel)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    m_listMultiSelectDays.clear();
 | 
	
		
			
				|  |  | +    m_modeSelection = mode;
 | 
	
		
			
				|  |  | +    if(m_pDateScopeModel == nullptr)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        m_pDateScopeModel = pDataModel;
 | 
	
		
			
				|  |  | +        connect(m_pDateScopeModel, &ScopeSelectionModel::sig_Update, this, static_cast<void(QWidget::*)()>(&QWidget::update));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    update();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void CalendarWidgetEx::hideNavigatioinButton(bool bPreYear, bool bPreMon, bool bNextYear, bool bNextMon)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    QVBoxLayout *vBodyLayout = qobject_cast<QVBoxLayout *>(layout());
 | 
	
		
			
				|  |  | +    if(vBodyLayout == nullptr) return;
 | 
	
		
			
				|  |  | +    CalendarNav *pNav = qobject_cast<CalendarNav*>(vBodyLayout->itemAt(0)->widget());
 | 
	
		
			
				|  |  | +    if (nullptr != pNav) {
 | 
	
		
			
				|  |  | +        pNav->hideNextMonth(bNextMon);
 | 
	
		
			
				|  |  | +        pNav->hideNextYear(bNextYear);
 | 
	
		
			
				|  |  | +        pNav->hidePreMonth(bPreMon);
 | 
	
		
			
				|  |  | +        pNav->hidePreYear(bPreYear);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/* 设置UI样式,0亮色,1暗色 */
 | 
	
		
			
				|  |  | +void CalendarWidgetEx::setUIStyle()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    if(EPUIStyle.getUIStyle() == enum_UIStyle::UI_Light)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        m_style = 0;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else if(EPUIStyle.getUIStyle() == enum_UIStyle::UI_Dark)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        m_style = 1;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    initSkinColor();
 | 
	
		
			
				|  |  | +    m_pNav->setQSS(m_style);
 | 
	
		
			
				|  |  | +    m_pHeader->setQSS(m_style);
 | 
	
		
			
				|  |  | +    update();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void CalendarWidgetEx::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    PainterEx *painterEx = static_cast<PainterEx*>(painter);
 | 
	
		
			
				|  |  | +    painterEx->setRenderHint(QPainter::Antialiasing);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    QColor textColor;
 | 
	
		
			
				|  |  | +    {//正常
 | 
	
		
			
				|  |  | +        textColor = m_normalTextColor;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +#if 0
 | 
	
		
			
				|  |  | +    // 周六,周日特殊颜色
 | 
	
		
			
				|  |  | +    int nWeek = date.dayOfWeek();
 | 
	
		
			
				|  |  | +    if (6 == nWeek || 7 == nWeek) {
 | 
	
		
			
				|  |  | +        textColor = QColor(255,149,0);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +    //鼠标移入
 | 
	
		
			
				|  |  | +    if(date == m_dateMouseOver)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        QPoint center = rect.center();
 | 
	
		
			
				|  |  | +        QRect rc(center.x() - TEXT_WIDTH / 2, center.y() - TEXT_WIDTH / 2, TEXT_WIDTH, TEXT_WIDTH);
 | 
	
		
			
				|  |  | +        painterEx->DrawRoundedRect(rc, 2.0, m_hoverBlockColor);
 | 
	
		
			
				|  |  | +        textColor = m_normalTextColor;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    //当天
 | 
	
		
			
				|  |  | +    if(date == QDate::currentDate())
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        painter->save();
 | 
	
		
			
				|  |  | +        QPoint center = rect.center();
 | 
	
		
			
				|  |  | +        QRect rc(center.x() - TEXT_WIDTH / 2, center.y() - TEXT_WIDTH / 2, TEXT_WIDTH, TEXT_WIDTH);
 | 
	
		
			
				|  |  | +        painter->setPen(m_todayTextColor);
 | 
	
		
			
				|  |  | +        painter->setBrush(Qt::transparent);
 | 
	
		
			
				|  |  | +        painter->drawRoundedRect(rc, 2.0, 2.0);
 | 
	
		
			
				|  |  | +        textColor = m_todayTextColor;
 | 
	
		
			
				|  |  | +        painter->restore();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    //选中
 | 
	
		
			
				|  |  | +    if(m_modeSelection == Multi && m_listMultiSelectDays.contains(date))
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        //painterEx->DrawCircle(QRectF(rect).center(), 9, QColor(9,109,217));
 | 
	
		
			
				|  |  | +        QPoint center = rect.center();
 | 
	
		
			
				|  |  | +        QRect rc(center.x() - TEXT_WIDTH / 2, center.y() - TEXT_WIDTH / 2, TEXT_WIDTH, TEXT_WIDTH);
 | 
	
		
			
				|  |  | +        painterEx->DrawRoundedRect(rc, 2.0, m_selectBlockColor);
 | 
	
		
			
				|  |  | +        textColor = m_selectTextColor;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if(m_modeSelection == Normal && date == selectedDate())
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        //painterEx->DrawCircle(QRectF(rect).center(), 9, QColor(9, 109, 217));
 | 
	
		
			
				|  |  | +        QPoint center = rect.center();
 | 
	
		
			
				|  |  | +        QRect rc(center.x() - TEXT_WIDTH / 2, center.y() - TEXT_WIDTH / 2, TEXT_WIDTH, TEXT_WIDTH);
 | 
	
		
			
				|  |  | +        painterEx->DrawRoundedRect(rc, 2.0, m_selectBlockColor);
 | 
	
		
			
				|  |  | +        textColor = m_selectTextColor;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if(m_modeSelection == Scope && m_pDateScopeModel != nullptr && m_pDateScopeModel->dtFirst.isValid() && m_pDateScopeModel->dtSecond.isValid())
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        QDate scopeStart = qMin(m_pDateScopeModel->dtFirst, m_pDateScopeModel->dtSecond);
 | 
	
		
			
				|  |  | +        QDate scopeEnd = qMax(m_pDateScopeModel->dtFirst, m_pDateScopeModel->dtSecond);
 | 
	
		
			
				|  |  | +        if(date == qBound(scopeStart, date, scopeEnd) && date.month() == monthShown())
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            painterEx->SetBrushOnly(m_hoverBlockColor);
 | 
	
		
			
				|  |  | +            if(date == scopeStart || date == scopeEnd)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                textColor = m_selectTextColor;
 | 
	
		
			
				|  |  | +                QPoint center = rect.center();
 | 
	
		
			
				|  |  | +                QRect rc(center.x() - TEXT_WIDTH / 2, center.y() - TEXT_WIDTH / 2, TEXT_WIDTH, TEXT_WIDTH);
 | 
	
		
			
				|  |  | +                painterEx->DrawRoundedRect(rc, 2.0, m_selectBlockColor);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                QRect r(0, 0, rect.width(), TEXT_WIDTH);
 | 
	
		
			
				|  |  | +                r.moveCenter(rect.center());
 | 
	
		
			
				|  |  | +                painterEx->drawRect(r);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    //不可选的日期或非当月日期
 | 
	
		
			
				|  |  | +    if(date < minimumDate() || date > maximumDate() || date.month() != monthShown())
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        textColor = m_disableTextColor;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //当天且未选中, 加粗
 | 
	
		
			
				|  |  | +    bool isBold = (date == QDate::currentDate() && date != selectedDate());
 | 
	
		
			
				|  |  | +    QString strDay(QString("%1").arg(date.day(), 2, 10, QLatin1Char('0')));
 | 
	
		
			
				|  |  | +    painterEx->setFont(FontEx(font().family(), DEFAULT_FONT_SIZE, isBold));
 | 
	
		
			
				|  |  | +    QRect rc = rect.adjusted(-1, 0, 0, -3); // 矫正文字位置
 | 
	
		
			
				|  |  | +    painterEx->DrawText(rc, strDay, textColor, Qt::AlignCenter);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void CalendarWidgetEx::paintEvent(QPaintEvent *)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    PainterEx painter(this);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //边框和背景
 | 
	
		
			
				|  |  | +    painter.setPen(Qt::transparent);
 | 
	
		
			
				|  |  | +    painter.setBrush(m_bgBrushColor);
 | 
	
		
			
				|  |  | +    QRect rc(rect());
 | 
	
		
			
				|  |  | +    painter.DrawRoundedRect(rc, WINDOW_RADIUS);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    QVBoxLayout *vBodyLayout = qobject_cast<QVBoxLayout *>(layout());
 | 
	
		
			
				|  |  | +    if(vBodyLayout != nullptr) {
 | 
	
		
			
				|  |  | +        // 画导航栏,绘制上圆角
 | 
	
		
			
				|  |  | +        QPainterPath path;
 | 
	
		
			
				|  |  | +        path.setFillRule(Qt::WindingFill);
 | 
	
		
			
				|  |  | +        QRectF tmpRc(1, 0, WINDOW_WIDTH - WINDOW_RADIUS, 40);
 | 
	
		
			
				|  |  | +        path.addRoundedRect(tmpRc, WINDOW_RADIUS, WINDOW_RADIUS);
 | 
	
		
			
				|  |  | +        path.addRect(QRectF(tmpRc.x(), tmpRc.y() + WINDOW_RADIUS, tmpRc.width(), tmpRc.height()));
 | 
	
		
			
				|  |  | +        // painter.fillPath(path, QColor(255, 255, 255));
 | 
	
		
			
				|  |  | +        painter.fillPath(path, m_bgBrushColor);
 | 
	
		
			
				|  |  | +        //分割线
 | 
	
		
			
				|  |  | +        QWidget* pNav = vBodyLayout->itemAt(0)->widget();
 | 
	
		
			
				|  |  | +        if (nullptr != pNav) {
 | 
	
		
			
				|  |  | +            int h = pNav->mapTo(this, pNav->rect().bottomRight()).y() + 2;
 | 
	
		
			
				|  |  | +            // painter.SetPenOnly(QColor(0, 0, 0, 23));
 | 
	
		
			
				|  |  | +            painter.setPen(m_bgPenColor);
 | 
	
		
			
				|  |  | +            painter.drawLine(QPoint(0, h), QPoint(width(), h));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +QSize CalendarWidgetEx::minimumSizeHint() const
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    return QSize(WINDOW_WIDTH, WINDOW_HEIGHT);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void CalendarWidgetEx::mouseMoveEvent(QMouseEvent *event)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    QCalendarWidget::mouseMoveEvent(event);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    QVBoxLayout *vBodyLayout = qobject_cast<QVBoxLayout *>(layout());
 | 
	
		
			
				|  |  | +    if(vBodyLayout == nullptr) return;
 | 
	
		
			
				|  |  | +    QTableView *pCalendarView = dynamic_cast<QTableView*>(vBodyLayout->itemAt(4)->widget());
 | 
	
		
			
				|  |  | +    if(pCalendarView == nullptr) return;
 | 
	
		
			
				|  |  | +    QModelIndex index = pCalendarView->indexAt(pCalendarView->mapFromGlobal(event->globalPos()));
 | 
	
		
			
				|  |  | +    QDate dateMouseOver = dateForCell(index.row(), index.column());
 | 
	
		
			
				|  |  | +    if(m_dateMouseOver != dateMouseOver)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        m_dateMouseOver = dateMouseOver;
 | 
	
		
			
				|  |  | +        if(m_pDateScopeModel != nullptr && !m_pDateScopeModel->bLocked && m_pDateScopeModel->dtFirst.isValid())
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_pDateScopeModel->dtSecond = dateMouseOver;
 | 
	
		
			
				|  |  | +            m_pDateScopeModel->Update();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        update();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//仅适用于: 不显示纵向表头(第几周), 且不显示横向表头(周几)
 | 
	
		
			
				|  |  | +QDate CalendarWidgetEx::dateForCell(int row, int column) const
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    if (row < 0 || row > 5 || column < 0 || column > 6)
 | 
	
		
			
				|  |  | +        return QDate();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const QDate refDate = referenceDate();
 | 
	
		
			
				|  |  | +    if (!refDate.isValid())
 | 
	
		
			
				|  |  | +        return QDate();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const int columnForFirstOfShownMonth = columnForFirstOfMonth(refDate);
 | 
	
		
			
				|  |  | +    if (columnForFirstOfShownMonth - 0/*m_firstColumn*/ < 1)
 | 
	
		
			
				|  |  | +        row -= 1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const int requestedDay = 7 * (row - 0/*m_firstRow*/) + column - columnForFirstOfShownMonth - refDate.day() + 1;
 | 
	
		
			
				|  |  | +    return refDate.addDays(requestedDay);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +QDate CalendarWidgetEx::referenceDate() const
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    int refDay = 1;
 | 
	
		
			
				|  |  | +    while (refDay <= 31) {
 | 
	
		
			
				|  |  | +        QDate refDate(yearShown(), monthShown(), refDay);
 | 
	
		
			
				|  |  | +        if (refDate.isValid())
 | 
	
		
			
				|  |  | +            return refDate;
 | 
	
		
			
				|  |  | +        refDay += 1;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return QDate();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +int CalendarWidgetEx::columnForFirstOfMonth(const QDate &date) const
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    return (columnForDayOfWeek(date.dayOfWeek()) - (date.day() % 7) + 8) % 7;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +int CalendarWidgetEx::columnForDayOfWeek(int day) const
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    if (day < 1 || day > 7)
 | 
	
		
			
				|  |  | +        return -1;
 | 
	
		
			
				|  |  | +    int column = day - firstDayOfWeek();
 | 
	
		
			
				|  |  | +    if (column < 0)
 | 
	
		
			
				|  |  | +        column += 7;
 | 
	
		
			
				|  |  | +    return column;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void CalendarWidgetEx::initSkinColor()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    switch (m_style) 
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    case 0:
 | 
	
		
			
				|  |  | +        m_normalTextColor = NORMAL_TEXT_BRIGHT;
 | 
	
		
			
				|  |  | +        m_todayTextColor = TODAY_TEXT_BRIGHT;
 | 
	
		
			
				|  |  | +        m_selectTextColor = SELECT_TEXT_BRIGHT;
 | 
	
		
			
				|  |  | +        m_disableTextColor = DISABLE_TEXT_BRIGHT;
 | 
	
		
			
				|  |  | +        m_splitLineColor = SPLIT_LINE_BRIGHT;
 | 
	
		
			
				|  |  | +        m_selectBlockColor = SELECT_BRIGHT;
 | 
	
		
			
				|  |  | +        m_hoverBlockColor = HOVER_BRIGHT;
 | 
	
		
			
				|  |  | +        m_bgBrushColor = BG_BRUSH_BRIGHT;
 | 
	
		
			
				|  |  | +        m_bgPenColor = BG_PEN_BRIGHT;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +    case 1:
 | 
	
		
			
				|  |  | +        m_normalTextColor = NORMAL_TEXT_DEEP;
 | 
	
		
			
				|  |  | +        m_todayTextColor = TODAY_TEXT_DEEP;
 | 
	
		
			
				|  |  | +        m_selectTextColor = SELECT_TEXT_DEEP;
 | 
	
		
			
				|  |  | +        m_disableTextColor = DISABLE_TEXT_DEEP;
 | 
	
		
			
				|  |  | +        m_splitLineColor = SPLIT_LINE_DEEP;
 | 
	
		
			
				|  |  | +        m_selectBlockColor = SELECT_DEEP;
 | 
	
		
			
				|  |  | +        m_hoverBlockColor = HOVER_DEEP;
 | 
	
		
			
				|  |  | +        m_bgBrushColor = BG_BRUSH_DEEP;
 | 
	
		
			
				|  |  | +        m_bgPenColor = BG_PEN_DEEP;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +    default:
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void CalendarWidgetEx::OnClicked(const QDate &date)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    if(m_modeSelection == Multi)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        if(m_listMultiSelectDays.contains(date))
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_listMultiSelectDays.removeOne(date);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_listMultiSelectDays.append(date);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if(m_modeSelection == Scope && m_pDateScopeModel != nullptr)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        if(!m_pDateScopeModel->bLocked && m_pDateScopeModel->dtFirst.isValid())
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_pDateScopeModel->dtSecond = date;
 | 
	
		
			
				|  |  | +            m_pDateScopeModel->bLocked = true;
 | 
	
		
			
				|  |  | +            m_pDateScopeModel->Locked();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_pDateScopeModel->dtFirst = date;
 | 
	
		
			
				|  |  | +            m_pDateScopeModel->dtSecond = date;
 | 
	
		
			
				|  |  | +            m_pDateScopeModel->bLocked = false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        m_pDateScopeModel->Update();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    update();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void CalendarWidgetEx::leaveEvent(QEvent *)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    if(m_modeSelection != Scope)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        //离开日历时, 清空鼠标移入状态
 | 
	
		
			
				|  |  | +        m_dateMouseOver = QDate();
 | 
	
		
			
				|  |  | +        update();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void NoFocusStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    QStyleOption *viewOption = new QStyleOption(*option);
 | 
	
		
			
				|  |  | +    viewOption->state &= (~QStyle::State_HasFocus);
 | 
	
		
			
				|  |  | +    //if (element == PE_FrameFocusRect) return;
 | 
	
		
			
				|  |  | +    QProxyStyle::drawPrimitive(element, viewOption, painter, widget);
 | 
	
		
			
				|  |  | +    delete viewOption;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 |