| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 | 
							- //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;
 
- }
 
 
  |