2 Copyright 2007 by Alexis Ménard <darktears31@gmail.com>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library 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 GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
20 #include "notifierview.h"
24 #include <QtGui/QMouseEvent>
25 #include <QtGui/QPainter>
26 #include <QtGui/QPaintEvent>
27 #include <QtGui/QScrollBar>
28 #include <QtGui/QHeaderView>
29 #include <QtGui/QStandardItemModel>
33 #include <KIconLoader>
34 #include <KColorScheme>
35 #include <KGlobalSettings>
38 #include <Plasma/Delegate>
40 using namespace Notifier
;
42 NotifierView::NotifierView(QWidget
*parent
)
45 setIconSize(QSize(KIconLoader::SizeMedium
, KIconLoader::SizeMedium
));
46 setRootIsDecorated(true);
47 setHeaderHidden(true);
48 setMouseTracking(true);
51 NotifierView::~NotifierView()
56 QModelIndex
NotifierView::indexAt(const QPoint
& point
) const
58 // simple linear search through the item rects, this will
59 // be inefficient when the viewport is large
60 QHashIterator
<QModelIndex
,QRect
> iter(itemRects
);
61 while (iter
.hasNext()) {
63 if (iter
.value().contains(point
+ QPoint(0, verticalOffset()))) {
70 void NotifierView::resizeEvent(QResizeEvent
* event
)
72 //the columns after the first are squares KIconLoader::SizeMedium x KIconLoader::SizeMedium,
73 //the first column takes all the remaining space
76 if (header()->count() > 0) {
77 const int newWidth
= event
->size().width() -
78 (header()->count()-1)*(sizeHintForRow(0));
79 header()->resizeSection(0, newWidth
);
83 void NotifierView::mouseMoveEvent(QMouseEvent
*event
)
85 const QModelIndex itemUnderMouse
= indexAt(event
->pos());
86 if (itemUnderMouse
!= m_hoveredIndex
&& itemUnderMouse
.isValid() &&
88 update(itemUnderMouse
);
89 update(m_hoveredIndex
);
90 m_hoveredIndex
= itemUnderMouse
;
91 setCurrentIndex(m_hoveredIndex
);
92 } else if (!itemUnderMouse
.isValid()) {
93 m_hoveredIndex
= QModelIndex();
94 setCurrentIndex(m_hoveredIndex
);
97 QAbstractItemView::mouseMoveEvent(event
);
100 void NotifierView::mousePressEvent(QMouseEvent
*event
)
102 const QModelIndex itemUnderMouse
= indexAt(event
->pos());
103 //don't pass click for header
104 if (event
->button() != Qt::LeftButton
|| model()->hasChildren(itemUnderMouse
)) {
108 QAbstractItemView::mousePressEvent(event
);
111 void NotifierView::leaveEvent(QEvent
*event
)
114 if (m_hoveredIndex
.isValid()) {
115 const QModelIndex oldHoveredIndex
= m_hoveredIndex
;
116 m_hoveredIndex
= QModelIndex();
117 setCurrentIndex(m_hoveredIndex
);
118 update(oldHoveredIndex
);
122 QModelIndex
NotifierView::moveCursor(CursorAction cursorAction
,Qt::KeyboardModifiers modifiers
)
124 m_hoveredIndex
= QModelIndex();
126 return QTreeView::moveCursor(cursorAction
, modifiers
);
129 void NotifierView::calculateRects()
136 int verticalOffset
= TOP_OFFSET
;
138 const int rows
= model()->rowCount(rootIndex());
139 const int cols
= header()->count();
140 //kDebug() << "painting" << rows << "rows" << cols << "columns";
143 for (int i
= 0; i
< rows
; ++i
) {
144 for (int j
= 0; j
< cols
; ++j
) {
145 const QModelIndex index
= model()->index(i
, j
, rootIndex());
146 if (model()->hasChildren(index
)) {
147 QRect
itemRect(QPoint(HEADER_LEFT_MARGIN
, verticalOffset
),
148 QSize(width() - HEADER_LEFT_MARGIN
, HEADER_HEIGHT
));
149 verticalOffset
+= itemRect
.size().height();
150 itemRects
.insert(index
, itemRect
);
152 QStandardItemModel
* currentModel
= dynamic_cast<QStandardItemModel
*>(model());
153 QStandardItem
*currentItem
= currentModel
->itemFromIndex(index
);
154 // we display the children of this item
155 for (int k
= 0; k
< currentItem
->rowCount(); ++k
) {
156 for (int l
= 0; l
< currentItem
->columnCount(); ++l
) {
157 QStandardItem
*childItem
= currentItem
->child(k
, l
);
158 QModelIndex childIndex
= childItem
->index();
161 QSize
size(width() - COLUMN_EJECT_SIZE
,sizeHintForIndex(index
).height());
162 itemChildRect
= QRect(QPoint(HEADER_LEFT_MARGIN
, verticalOffset
), size
);
163 itemRects
.insert(childIndex
, itemChildRect
);
165 QSize
size(COLUMN_EJECT_SIZE
- style()->pixelMetric(QStyle::PM_ScrollBarExtent
) + 2,
166 sizeHintForIndex(index
).height());
167 itemChildRect
= QRect(QPoint(width() - (COLUMN_EJECT_SIZE
- COLUMN_EJECT_MARGIN
),
168 verticalOffset
), size
);
169 itemRects
.insert(childIndex
, itemChildRect
);
170 verticalOffset
+= itemChildRect
.size().height();
179 void NotifierView::paintEvent(QPaintEvent
*event
)
186 QPainter
painter(viewport());
187 painter
.setRenderHint(QPainter::Antialiasing
);
189 QHashIterator
<QModelIndex
, QRect
> it(itemRects
);
190 while (it
.hasNext()) {
192 QRect itemRect
= it
.value();
193 if (event
->region().contains(itemRect
)) {
194 QModelIndex index
= it
.key();
195 if (model()->hasChildren(index
)) {
196 //kDebug()<<"header"<<itemRect;
197 paintHeaderItem(painter
, itemRect
, index
);
199 paintItem(painter
, itemRect
, index
);
205 void NotifierView::paintHeaderItem(QPainter
&painter
, const QRect
&itemRect
, const QModelIndex
&index
)
207 QStyleOptionViewItem option
= viewOptions();
208 option
.rect
= itemRect
;
209 const int rightMargin
= style()->pixelMetric(QStyle::PM_ScrollBarExtent
) + 6;
210 const int dy
= HEADER_TOP_MARGIN
;
213 painter
.setRenderHint(QPainter::Antialiasing
, false);
215 QLinearGradient
gradient(option
.rect
.topLeft(), option
.rect
.topRight());
216 gradient
.setColorAt(0.0, Qt::transparent
);
217 gradient
.setColorAt(0.1, option
.palette
.midlight().color());
218 gradient
.setColorAt(0.5, option
.palette
.mid().color());
219 gradient
.setColorAt(0.9, option
.palette
.midlight().color());
220 gradient
.setColorAt(1.0, Qt::transparent
);
221 painter
.setPen(QPen(gradient
, 1));
223 painter
.drawLine(option
.rect
.x() + 6, option
.rect
.y() + dy
+ 2,
224 option
.rect
.right() - rightMargin
, option
.rect
.y() + dy
+ 2);
225 painter
.setFont(KGlobalSettings::smallestReadableFont());
226 painter
.setPen(QPen(KColorScheme(QPalette::Active
).foreground(KColorScheme::InactiveText
), 0));
227 QString text
= index
.data(Qt::DisplayRole
).value
<QString
>();
228 painter
.drawText(option
.rect
.adjusted(0, dy
, -rightMargin
, 0),
229 Qt::AlignVCenter
|Qt::AlignRight
, text
);
233 void NotifierView::paintItem(QPainter
&painter
, const QRect
&itemRect
, const QModelIndex
&index
)
235 QStyleOptionViewItem option
= viewOptions();
236 option
.rect
= itemRect
;
238 if (selectionModel()->isSelected(index
)) {
239 option
.state
|= QStyle::State_Selected
;
242 if (index
== m_hoveredIndex
) {
243 option
.state
|= QStyle::State_MouseOver
;
246 if (index
== currentIndex()) {
247 option
.state
|= QStyle::State_HasFocus
;
250 itemDelegate(index
)->paint(&painter
,option
,index
);
253 #include "notifierview.moc"