add more spacing
[personal-kdebase.git] / workspace / plasma / applets / devicenotifier / notifierview.cpp
blobe0aa86512243cfdff4db168870e6e62fb6865711
1 /*
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"
22 // Qt
24 #include <QtGui/QMouseEvent>
25 #include <QtGui/QPainter>
26 #include <QtGui/QPaintEvent>
27 #include <QtGui/QScrollBar>
28 #include <QtGui/QHeaderView>
29 #include <QtGui/QStandardItemModel>
31 //KDE
32 #include <KDebug>
33 #include <KIconLoader>
34 #include <KColorScheme>
35 #include <KGlobalSettings>
37 //Plasma
38 #include <Plasma/Delegate>
40 using namespace Notifier;
42 NotifierView::NotifierView(QWidget *parent)
43 : QTreeView(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()) {
62 iter.next();
63 if (iter.value().contains(point + QPoint(0, verticalOffset()))) {
64 return iter.key();
67 return QModelIndex();
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
74 calculateRects();
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() &&
87 state() == NoState) {
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)) {
105 return;
108 QAbstractItemView::mousePressEvent(event);
111 void NotifierView::leaveEvent(QEvent *event)
113 Q_UNUSED(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()
131 if (!model()) {
132 return;
135 itemRects.clear();
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();
159 QRect itemChildRect;
160 if (l % 2 == 0) {
161 QSize size(width() - COLUMN_EJECT_SIZE,sizeHintForIndex(index).height());
162 itemChildRect = QRect(QPoint(HEADER_LEFT_MARGIN, verticalOffset), size);
163 itemRects.insert(childIndex, itemChildRect);
164 } else {
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)
181 Q_UNUSED(event);
182 if (!model()) {
183 return;
186 QPainter painter(viewport());
187 painter.setRenderHint(QPainter::Antialiasing);
189 QHashIterator<QModelIndex, QRect> it(itemRects);
190 while (it.hasNext()) {
191 it.next();
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);
198 } else {
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;
212 painter.save();
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);
230 painter.restore();
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"