1 /***************************************************************************
2 * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
20 #include "kitemlistheader_p.h"
22 #include "kitemmodelbase.h"
24 #include <QFontMetricsF>
25 #include <QGraphicsSceneHoverEvent>
27 #include <QStyleOptionHeader>
31 KItemListHeader::KItemListHeader(QGraphicsWidget
* parent
) :
32 QGraphicsWidget(parent
),
35 m_visibleRolesWidths(),
36 m_hoveredRoleIndex(-1),
37 m_pressedRoleIndex(-1),
38 m_resizePressedRole(false)
40 setAcceptHoverEvents(true);
42 QStyleOptionHeader option
;
43 const QSize headerSize
= style()->sizeFromContents(QStyle::CT_HeaderSection
, &option
, QSize());
44 resize(0, headerSize
.height());
47 KItemListHeader::~KItemListHeader()
51 void KItemListHeader::setModel(KItemModelBase
* model
)
53 if (m_model
== model
) {
58 disconnect(m_model
, SIGNAL(sortRoleChanged(QByteArray
,QByteArray
)),
59 this, SLOT(slotSortRoleChanged(QByteArray
,QByteArray
)));
60 disconnect(m_model
, SIGNAL(sortOrderChanged(Qt::SortOrder
,Qt::SortOrder
)),
61 this, SLOT(slotSortOrderChanged(Qt::SortOrder
,Qt::SortOrder
)));
67 connect(m_model
, SIGNAL(sortRoleChanged(QByteArray
,QByteArray
)),
68 this, SLOT(slotSortRoleChanged(QByteArray
,QByteArray
)));
69 connect(m_model
, SIGNAL(sortOrderChanged(Qt::SortOrder
,Qt::SortOrder
)),
70 this, SLOT(slotSortOrderChanged(Qt::SortOrder
,Qt::SortOrder
)));
74 KItemModelBase
* KItemListHeader::model() const
79 void KItemListHeader::setVisibleRoles(const QList
<QByteArray
>& roles
)
81 m_visibleRoles
= roles
;
85 QList
<QByteArray
> KItemListHeader::visibleRoles() const
87 return m_visibleRoles
;
90 void KItemListHeader::setVisibleRolesWidths(const QHash
<QByteArray
, qreal
> rolesWidths
)
92 m_visibleRolesWidths
= rolesWidths
;
96 QHash
<QByteArray
, qreal
> KItemListHeader::visibleRolesWidths() const
98 return m_visibleRolesWidths
;
101 void KItemListHeader::paint(QPainter
* painter
, const QStyleOptionGraphicsItem
* option
, QWidget
* widget
)
111 painter
->setFont(font());
112 painter
->setPen(palette().text().color());
116 foreach (const QByteArray
& role
, m_visibleRoles
) {
117 const qreal roleWidth
= m_visibleRolesWidths
.value(role
);
118 const QRectF
rect(x
, 0, roleWidth
, size().height());
119 paintRole(painter
, role
, rect
, orderIndex
);
124 // Draw background without roles
127 opt
.rect
= QRect(x
, 0, size().width() - x
, size().height());
128 opt
.state
|= QStyle::State_Horizontal
;
129 style()->drawControl(QStyle::CE_HeaderEmptyArea
, &opt
, painter
);
132 void KItemListHeader::mousePressEvent(QGraphicsSceneMouseEvent
* event
)
135 updatePressedRoleIndex(event
->pos());
138 void KItemListHeader::mouseReleaseEvent(QGraphicsSceneMouseEvent
* event
)
140 QGraphicsWidget::mouseReleaseEvent(event
);
141 if (m_pressedRoleIndex
!= -1) {
142 m_pressedRoleIndex
= -1;
147 void KItemListHeader::mouseMoveEvent(QGraphicsSceneMouseEvent
* event
)
149 QGraphicsWidget::mouseMoveEvent(event
);
150 updatePressedRoleIndex(event
->pos());
153 void KItemListHeader::hoverEnterEvent(QGraphicsSceneHoverEvent
* event
)
155 QGraphicsWidget::hoverEnterEvent(event
);
156 updateHoveredRoleIndex(event
->pos());
159 void KItemListHeader::hoverLeaveEvent(QGraphicsSceneHoverEvent
* event
)
161 QGraphicsWidget::hoverLeaveEvent(event
);
162 if (m_hoveredRoleIndex
!= -1) {
163 m_hoveredRoleIndex
= -1;
168 void KItemListHeader::hoverMoveEvent(QGraphicsSceneHoverEvent
* event
)
170 QGraphicsWidget::hoverMoveEvent(event
);
172 const QPointF
& pos
= event
->pos();
173 updateHoveredRoleIndex(pos
);
174 if (m_hoveredRoleIndex
>= 0 && isAboveRoleGrip(pos
, m_hoveredRoleIndex
)) {
175 setCursor(Qt::SplitHCursor
);
181 void KItemListHeader::slotSortRoleChanged(const QByteArray
& current
, const QByteArray
& previous
)
187 void KItemListHeader::slotSortOrderChanged(Qt::SortOrder current
, Qt::SortOrder previous
)
193 void KItemListHeader::paintRole(QPainter
* painter
,
194 const QByteArray
& role
,
198 // The following code is based on the code from QHeaderView::paintSection().
199 // Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
200 QStyleOptionHeader option
;
201 option
.section
= orderIndex
;
202 option
.state
= QStyle::State_None
| QStyle::State_Raised
;
204 option
.state
|= QStyle::State_Enabled
;
206 if (window() && window()->isActiveWindow()) {
207 option
.state
|= QStyle::State_Active
;
209 if (m_hoveredRoleIndex
== orderIndex
) {
210 option
.state
|= QStyle::State_MouseOver
;
212 if (m_pressedRoleIndex
== orderIndex
) {
213 option
.state
|= QStyle::State_Sunken
;
215 /*if (m_model->sortRole() == role) {
216 option.sortIndicator = (m_model->sortOrder() == Qt::AscendingOrder) ?
217 QStyleOptionHeader::SortDown : QStyleOptionHeader::SortUp;
219 option
.rect
= rect
.toRect();
221 if (m_visibleRoles
.count() == 1) {
222 option
.position
= QStyleOptionHeader::OnlyOneSection
;
223 } else if (orderIndex
== 0) {
224 option
.position
= QStyleOptionHeader::Beginning
;
225 } else if (orderIndex
== m_visibleRoles
.count() - 1) {
226 option
.position
= QStyleOptionHeader::End
;
228 option
.position
= QStyleOptionHeader::Middle
;
231 option
.selectedPosition
= QStyleOptionHeader::NotAdjacent
;
233 const QString text
= m_model
->roleDescription(role
);
234 const int grip
= style()->pixelMetric(QStyle::PM_HeaderGripMargin
);
235 option
.text
= option
.fontMetrics
.elidedText(text
, Qt::ElideRight
, option
.rect
.width() - grip
);
237 style()->drawControl(QStyle::CE_Header
, &option
, painter
);
240 void KItemListHeader::updatePressedRoleIndex(const QPointF
& pos
)
242 const int pressedIndex
= roleIndexAt(pos
);
243 if (m_pressedRoleIndex
!= pressedIndex
) {
244 m_pressedRoleIndex
= pressedIndex
;
249 void KItemListHeader::updateHoveredRoleIndex(const QPointF
& pos
)
251 const int hoverIndex
= roleIndexAt(pos
);
252 if (m_hoveredRoleIndex
!= hoverIndex
) {
253 m_hoveredRoleIndex
= hoverIndex
;
258 int KItemListHeader::roleIndexAt(const QPointF
& pos
) const
263 foreach (const QByteArray
& role
, m_visibleRoles
) {
265 x
+= m_visibleRolesWidths
.value(role
);
274 bool KItemListHeader::isAboveRoleGrip(const QPointF
& pos
, int roleIndex
) const
277 for (int i
= 0; i
<= roleIndex
; ++i
) {
278 const QByteArray role
= m_visibleRoles
.at(i
);
279 x
+= m_visibleRolesWidths
.value(role
);
282 const int grip
= style()->pixelMetric(QStyle::PM_HeaderGripMargin
);
283 return pos
.x() >= (x
- grip
) && pos
.x() <= x
;
286 #include "kitemlistheader_p.moc"