1 /***************************************************************************
2 * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
4 * Based on the Itemviews NG project from Trolltech Labs: *
5 * http://qt.gitorious.org/qt-labs/itemviews-ng *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
21 ***************************************************************************/
23 #include "kitemlistwidget.h"
25 #include "kitemlistview.h"
26 #include "kitemmodelbase.h"
28 #include "private/kitemlistselectiontoggle.h"
32 #include <KGlobalSettings>
33 #include <QApplication>
35 #include <QPropertyAnimation>
36 #include <QStyleOption>
38 KItemListWidget::KItemListWidget(QGraphicsItem
* parent
) :
39 QGraphicsWidget(parent
, 0),
44 m_alternateBackground(false),
45 m_enabledSelectionToggle(false),
59 KItemListWidget::~KItemListWidget()
64 void KItemListWidget::setIndex(int index
)
66 if (m_index
!= index
) {
67 delete m_selectionToggle
;
68 m_selectionToggle
= 0;
70 if (m_hoverAnimation
) {
71 m_hoverAnimation
->stop();
80 int KItemListWidget::index() const
85 void KItemListWidget::setData(const QHash
<QByteArray
, QVariant
>& data
,
86 const QSet
<QByteArray
>& roles
)
89 if (roles
.isEmpty()) {
93 foreach (const QByteArray
& role
, roles
) {
94 m_data
[role
] = data
[role
];
96 dataChanged(m_data
, roles
);
101 QHash
<QByteArray
, QVariant
> KItemListWidget::data() const
106 void KItemListWidget::paint(QPainter
* painter
, const QStyleOptionGraphicsItem
* option
, QWidget
* widget
)
110 if (m_alternateBackground
) {
111 const QColor backgroundColor
= m_styleOption
.palette
.color(QPalette::AlternateBase
);
112 const QRectF
backgroundRect(0, 0, size().width(), size().height());
113 painter
->fillRect(backgroundRect
, backgroundColor
);
116 if (m_selected
&& m_editedRole
.isEmpty()) {
117 const QStyle::State
activeState(isActiveWindow() ? QStyle::State_Active
: 0);
118 drawItemStyleOption(painter
, widget
, activeState
|
119 QStyle::State_Enabled
|
120 QStyle::State_Selected
|
124 if (m_current
&& m_editedRole
.isEmpty()) {
125 QStyleOptionFocusRect focusRectOption
;
126 focusRectOption
.initFrom(widget
);
127 focusRectOption
.rect
= textFocusRect().toRect();
128 focusRectOption
.state
= QStyle::State_Enabled
| QStyle::State_Item
| QStyle::State_KeyboardFocusChange
;
130 focusRectOption
.state
|= QStyle::State_Selected
;
133 style()->drawPrimitive(QStyle::PE_FrameFocusRect
, &focusRectOption
, painter
, widget
);
136 if (m_hoverOpacity
> 0.0) {
138 // Initialize the m_hoverCache pixmap to improve the drawing performance
139 // when fading the hover background
140 m_hoverCache
= new QPixmap(size().toSize());
141 m_hoverCache
->fill(Qt::transparent
);
143 QPainter
pixmapPainter(m_hoverCache
);
144 const QStyle::State
activeState(isActiveWindow() ? QStyle::State_Active
: 0);
145 drawItemStyleOption(&pixmapPainter
, widget
, activeState
|
146 QStyle::State_Enabled
|
147 QStyle::State_MouseOver
|
151 const qreal opacity
= painter
->opacity();
152 painter
->setOpacity(m_hoverOpacity
* opacity
);
153 painter
->drawPixmap(0, 0, *m_hoverCache
);
154 painter
->setOpacity(opacity
);
158 void KItemListWidget::setVisibleRoles(const QList
<QByteArray
>& roles
)
160 const QList
<QByteArray
> previousRoles
= m_visibleRoles
;
161 m_visibleRoles
= roles
;
163 visibleRolesChanged(roles
, previousRoles
);
167 QList
<QByteArray
> KItemListWidget::visibleRoles() const
169 return m_visibleRoles
;
173 void KItemListWidget::setColumnWidth(const QByteArray
& role
, qreal width
)
175 if (m_columnWidths
.value(role
) != width
) {
176 const qreal previousWidth
= width
;
177 m_columnWidths
.insert(role
, width
);
178 columnWidthChanged(role
, width
, previousWidth
);
183 qreal
KItemListWidget::columnWidth(const QByteArray
& role
) const
185 return m_columnWidths
.value(role
);
188 void KItemListWidget::setStyleOption(const KItemListStyleOption
& option
)
190 const KItemListStyleOption previous
= m_styleOption
;
192 m_styleOption
= option
;
194 styleOptionChanged(option
, previous
);
198 const KItemListStyleOption
& KItemListWidget::styleOption() const
200 return m_styleOption
;
203 void KItemListWidget::setSelected(bool selected
)
205 if (m_selected
!= selected
) {
206 m_selected
= selected
;
207 if (m_selectionToggle
) {
208 m_selectionToggle
->setChecked(selected
);
210 selectedChanged(selected
);
215 bool KItemListWidget::isSelected() const
220 void KItemListWidget::setCurrent(bool current
)
222 if (m_current
!= current
) {
224 currentChanged(current
);
229 bool KItemListWidget::isCurrent() const
234 void KItemListWidget::setHovered(bool hovered
)
236 if (hovered
== m_hovered
) {
242 if (!m_hoverAnimation
) {
243 m_hoverAnimation
= new QPropertyAnimation(this, "hoverOpacity", this);
244 const int duration
= (KGlobalSettings::graphicEffectsLevel() == KGlobalSettings::NoEffects
) ? 1 : 200;
245 m_hoverAnimation
->setDuration(duration
);
246 connect(m_hoverAnimation
, SIGNAL(finished()), this, SLOT(slotHoverAnimationFinished()));
248 m_hoverAnimation
->stop();
251 const qreal startValue
= qMax(hoverOpacity(), qreal(0.1));
252 m_hoverAnimation
->setStartValue(startValue
);
253 m_hoverAnimation
->setEndValue(1.0);
254 if (m_enabledSelectionToggle
&& !(QApplication::mouseButtons() & Qt::LeftButton
)) {
255 initializeSelectionToggle();
258 m_hoverAnimation
->setStartValue(hoverOpacity());
259 m_hoverAnimation
->setEndValue(0.0);
262 m_hoverAnimation
->start();
264 hoveredChanged(hovered
);
268 bool KItemListWidget::isHovered() const
273 void KItemListWidget::setAlternateBackground(bool enable
)
275 if (m_alternateBackground
!= enable
) {
276 m_alternateBackground
= enable
;
277 alternateBackgroundChanged(enable
);
282 bool KItemListWidget::alternateBackground() const
284 return m_alternateBackground
;
287 void KItemListWidget::setEnabledSelectionToggle(bool enable
)
289 if (m_enabledSelectionToggle
!= enable
) {
290 m_enabledSelectionToggle
= enable
;
295 bool KItemListWidget::enabledSelectionToggle() const
297 return m_enabledSelectionToggle
;
300 void KItemListWidget::setSiblingsInformation(const QBitArray
& siblings
)
302 const QBitArray previous
= m_siblingsInfo
;
303 m_siblingsInfo
= siblings
;
304 siblingsInformationChanged(m_siblingsInfo
, previous
);
308 QBitArray
KItemListWidget::siblingsInformation() const
310 return m_siblingsInfo
;
313 void KItemListWidget::setEditedRole(const QByteArray
& role
)
315 if (m_editedRole
!= role
) {
316 const QByteArray previous
= m_editedRole
;
318 editedRoleChanged(role
, previous
);
322 QByteArray
KItemListWidget::editedRole() const
327 bool KItemListWidget::contains(const QPointF
& point
) const
329 if (!QGraphicsWidget::contains(point
)) {
333 return iconRect().contains(point
) ||
334 textRect().contains(point
) ||
335 expansionToggleRect().contains(point
) ||
336 selectionToggleRect().contains(point
);
339 QRectF
KItemListWidget::textFocusRect() const
344 QRectF
KItemListWidget::selectionToggleRect() const
349 QRectF
KItemListWidget::expansionToggleRect() const
354 void KItemListWidget::dataChanged(const QHash
<QByteArray
, QVariant
>& current
,
355 const QSet
<QByteArray
>& roles
)
361 void KItemListWidget::visibleRolesChanged(const QList
<QByteArray
>& current
,
362 const QList
<QByteArray
>& previous
)
368 void KItemListWidget::columnWidthChanged(const QByteArray
& role
,
377 void KItemListWidget::styleOptionChanged(const KItemListStyleOption
& current
,
378 const KItemListStyleOption
& previous
)
384 void KItemListWidget::currentChanged(bool current
)
389 void KItemListWidget::selectedChanged(bool selected
)
394 void KItemListWidget::hoveredChanged(bool hovered
)
399 void KItemListWidget::alternateBackgroundChanged(bool enabled
)
404 void KItemListWidget::siblingsInformationChanged(const QBitArray
& current
, const QBitArray
& previous
)
410 void KItemListWidget::editedRoleChanged(const QByteArray
& current
, const QByteArray
& previous
)
416 void KItemListWidget::resizeEvent(QGraphicsSceneResizeEvent
* event
)
418 QGraphicsWidget::resizeEvent(event
);
422 qreal
KItemListWidget::hoverOpacity() const
424 return m_hoverOpacity
;
427 void KItemListWidget::slotHoverAnimationFinished()
430 delete m_selectionToggle
;
431 m_selectionToggle
= 0;
435 void KItemListWidget::initializeSelectionToggle()
437 Q_ASSERT(m_enabledSelectionToggle
);
439 if (!m_selectionToggle
) {
440 m_selectionToggle
= new KItemListSelectionToggle(this);
443 const QRectF toggleRect
= selectionToggleRect();
444 m_selectionToggle
->setPos(toggleRect
.topLeft());
445 m_selectionToggle
->resize(toggleRect
.size());
447 m_selectionToggle
->setChecked(isSelected());
450 void KItemListWidget::setHoverOpacity(qreal opacity
)
452 m_hoverOpacity
= opacity
;
453 if (m_selectionToggle
) {
454 m_selectionToggle
->setOpacity(opacity
);
457 if (m_hoverOpacity
<= 0.0) {
465 void KItemListWidget::clearHoverCache()
471 void KItemListWidget::drawItemStyleOption(QPainter
* painter
, QWidget
* widget
, QStyle::State styleState
)
473 QStyleOptionViewItemV4 viewItemOption
;
474 viewItemOption
.initFrom(widget
);
475 viewItemOption
.state
= styleState
;
476 viewItemOption
.viewItemPosition
= QStyleOptionViewItemV4::OnlyOne
;
477 viewItemOption
.showDecorationSelected
= true;
478 viewItemOption
.rect
= textRect().toRect();
479 widget
->style()->drawPrimitive(QStyle::PE_PanelItemViewItem
, &viewItemOption
, painter
, widget
);
482 #include "kitemlistwidget.moc"