3#include <QStandardItemModel>
6#include <QStyleOptionButton>
9#include <QLoggingCategory>
10#include "CheckBoxHeader.h"
12static Q_LOGGING_CATEGORY(log,
"CCheckBoxHeader")
14 : QHeaderView(orientation, parent)
17 setSectionsClickable(
true);
22 QStandardItemModel* pModel = qobject_cast<QStandardItemModel*>(this->model());
24 QStandardItem* item =
nullptr;
25 if(orientation() == Qt::Horizontal)
26 item = pModel->horizontalHeaderItem(index);
28 item = pModel->verticalHeaderItem(index);
29 if(item && item->isCheckable()) {
30 item->setCheckState(state);
36 if(!m_CheckableSections.contains(index)) {
37 qCritical(log) <<
"Please call SetCheckable first to enable the checkbox";
40 if (m_CheckableSections[index] == state)
return;
41 m_CheckableSections[index] = state;
45Qt::CheckState CCheckBoxHeader::GetCheckState(
int index)
const
47 QStandardItemModel* pModel = qobject_cast<QStandardItemModel*>(this->model());
49 QStandardItem* item =
nullptr;
50 if(orientation() == Qt::Horizontal)
51 item = pModel->horizontalHeaderItem(index);
53 item = pModel->verticalHeaderItem(index);
54 if(item && item->isCheckable()) {
55 return item->checkState();
59 auto it = m_CheckableSections.find(index);
60 if(m_CheckableSections.end() == it)
67 QStandardItemModel* pModel = qobject_cast<QStandardItemModel*>(this->model());
69 QStandardItem* item =
nullptr;
70 if(orientation() == Qt::Horizontal)
71 item = pModel->horizontalHeaderItem(index);
73 item = pModel->verticalHeaderItem(index);
75 item->setCheckable(checkable);
76 item->setCheckState(state);
82 m_CheckableSections.insert(index, state);
84 m_CheckableSections.remove(index);
88bool CCheckBoxHeader::isCheckable(
int index)
const
90 QStandardItemModel* pModel = qobject_cast<QStandardItemModel*>(this->model());
92 QStandardItem* item =
nullptr;
93 if(orientation() == Qt::Horizontal)
94 item = pModel->horizontalHeaderItem(index);
96 item = pModel->verticalHeaderItem(index);
97 return item && item->isCheckable();
100 return m_CheckableSections.contains(index);
103QRect CCheckBoxHeader::CheckboxRect(
const QRect §ionRect)
const
105 int size = style()->pixelMetric(QStyle::PM_IndicatorWidth,
nullptr,
this);
106 if (size <= 0) size = 16;
110 x = sectionRect.left() + 4;
111 y = sectionRect.center().y() - size / 2;
112 return QRect(x, y, size, size);
115void CCheckBoxHeader::paintSection(QPainter *painter,
const QRect &rect,
int logicalIndex)
const
117 if (!isCheckable(logicalIndex) || isSectionHidden(logicalIndex)) {
118 QHeaderView::paintSection(painter, rect, logicalIndex);
124 QStyleOptionHeader option;
125 option.initFrom(
this);
127 option.section = logicalIndex;
128 option.orientation = this->orientation();
129 style()->drawControl(QStyle::CE_Header, &option, painter,
this);
133 QRect cbRect = CheckboxRect(rect);
134 DrawCheckBox(painter, cbRect, GetCheckState(logicalIndex),
true);
139 QVariant v = model()->headerData(logicalIndex, Qt::Horizontal, Qt::DisplayRole);
140 text = v.isValid() ? v.toString() : QString();
142 if (!text.isEmpty()) {
144 int textLeft = cbRect.right() + 4;
145 QRect textRect(textLeft, rect.top(), rect.width() - (textLeft - rect.left()), rect.height());
147 QVariant vAlign = model() ? model()->headerData(
148 logicalIndex, orientation(),
149 Qt::TextAlignmentRole)
151 Qt::Alignment alignment = Qt::AlignCenter;
153 alignment = (Qt::Alignment)vAlign.toInt();
154 this->DrawText(painter, textRect, text, alignment);
160void CCheckBoxHeader::DrawCheckBox(QPainter* painter,
const QRect& rect,
161 Qt::CheckState state,
bool enabled)
const
163 QStyleOptionButton option;
165 option.state = QStyle::State_Enabled | QStyle::State_Active;
168 option.state |= QStyle::State_Enabled;
173 option.state |= QStyle::State_On;
175 case Qt::PartiallyChecked:
176 option.state |= QStyle::State_NoChange;
179 option.state |= QStyle::State_Off;
184 style()->drawControl(QStyle::CE_CheckBox, &option, painter,
this);
187void CCheckBoxHeader::DrawText(QPainter* painter,
const QRect& rect,
188 const QString& text, Qt::Alignment alignment)
const
190 if (text.isEmpty())
return;
195 QFontMetrics fm = painter->fontMetrics();
196 QString elided = fm.elidedText(text, Qt::ElideRight, rect.width());
198 QPalette palette = this->palette();
199 painter->setPen(palette.color(QPalette::Text));
202 painter->drawText(rect, alignment, elided);
207void CCheckBoxHeader::mousePressEvent(QMouseEvent *event)
209 int logical = logicalIndexAt(event->pos());
210 if (logical >= 0 && isCheckable(logical)) {
212 int x = sectionViewportPosition(logical);
213 int w = sectionSize(logical);
215 sectionRect = QRect(x, 0, w, height());
216 if (CheckboxRect(sectionRect).contains(event->pos())) {
217 Qt::CheckState state = GetCheckState(logical);
220 state = Qt::PartiallyChecked;
222 case Qt::PartiallyChecked:
226 state = Qt::Unchecked;
230 emit sigCheckStateChanged(logical, state);
237 QHeaderView::mousePressEvent(event);