00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "notifierview.h"
00021
00022
00023
00024 #include <QtGui/QMouseEvent>
00025 #include <QtGui/QPainter>
00026 #include <QtGui/QPaintEvent>
00027 #include <QtGui/QScrollBar>
00028 #include <QtGui/QHeaderView>
00029 #include <QtGui/QStandardItemModel>
00030
00031
00032 #include <KDebug>
00033 #include <KIconLoader>
00034 #include <KColorScheme>
00035 #include <KGlobalSettings>
00036
00037
00038 #include <Plasma/Delegate>
00039
00040 using namespace Notifier;
00041
00042 NotifierView::NotifierView(QWidget *parent)
00043 : QTreeView(parent)
00044 {
00045 setIconSize(QSize(KIconLoader::SizeMedium, KIconLoader::SizeMedium));
00046 setRootIsDecorated(true);
00047 setHeaderHidden(true);
00048 setMouseTracking(true);
00049 }
00050
00051 NotifierView::~NotifierView()
00052 {
00053
00054 }
00055
00056 QModelIndex NotifierView::indexAt(const QPoint& point) const
00057 {
00058
00059
00060 QHashIterator<QModelIndex,QRect> iter(itemRects);
00061 while (iter.hasNext()) {
00062 iter.next();
00063 if (iter.value().contains(point + QPoint(0, verticalOffset()))) {
00064 return iter.key();
00065 }
00066 }
00067 return QModelIndex();
00068 }
00069
00070 void NotifierView::resizeEvent(QResizeEvent * event)
00071 {
00072
00073
00074 calculateRects();
00075
00076 if (header()->count() > 0) {
00077 const int newWidth = event->size().width() -
00078 (header()->count()-1)*(sizeHintForRow(0));
00079 header()->resizeSection(0, newWidth);
00080 }
00081 }
00082
00083 void NotifierView::mouseMoveEvent(QMouseEvent *event)
00084 {
00085 const QModelIndex itemUnderMouse = indexAt(event->pos());
00086 if (itemUnderMouse != m_hoveredIndex && itemUnderMouse.isValid() &&
00087 state() == NoState) {
00088 update(itemUnderMouse);
00089 update(m_hoveredIndex);
00090 m_hoveredIndex = itemUnderMouse;
00091 setCurrentIndex(m_hoveredIndex);
00092 } else if (!itemUnderMouse.isValid()) {
00093 m_hoveredIndex = QModelIndex();
00094 setCurrentIndex(m_hoveredIndex);
00095 }
00096
00097 QAbstractItemView::mouseMoveEvent(event);
00098 }
00099
00100 void NotifierView::mousePressEvent(QMouseEvent *event)
00101 {
00102 const QModelIndex itemUnderMouse = indexAt(event->pos());
00103
00104 if (event->button() != Qt::LeftButton || model()->hasChildren(itemUnderMouse)) {
00105 return;
00106 }
00107
00108 QAbstractItemView::mousePressEvent(event);
00109 }
00110
00111 void NotifierView::leaveEvent(QEvent *event)
00112 {
00113 Q_UNUSED(event)
00114 if (m_hoveredIndex.isValid()) {
00115 const QModelIndex oldHoveredIndex = m_hoveredIndex;
00116 m_hoveredIndex = QModelIndex();
00117 setCurrentIndex(m_hoveredIndex);
00118 update(oldHoveredIndex);
00119 }
00120 }
00121
00122 QModelIndex NotifierView::moveCursor(CursorAction cursorAction,Qt::KeyboardModifiers modifiers )
00123 {
00124 m_hoveredIndex = QModelIndex();
00125
00126 return QTreeView::moveCursor(cursorAction, modifiers );
00127 }
00128
00129 void NotifierView::calculateRects()
00130 {
00131 if (!model()) {
00132 return;
00133 }
00134
00135 itemRects.clear();
00136 int verticalOffset = TOP_OFFSET;
00137
00138 const int rows = model()->rowCount(rootIndex());
00139 const int cols = header()->count();
00140
00141
00142
00143 for (int i = 0; i < rows; ++i) {
00144 for (int j = 0; j < cols; ++j) {
00145 const QModelIndex index = model()->index(i, j, rootIndex());
00146 if (model()->hasChildren(index)) {
00147 QRect itemRect(QPoint(HEADER_LEFT_MARGIN, verticalOffset),
00148 QSize(width() - HEADER_LEFT_MARGIN, HEADER_HEIGHT));
00149 verticalOffset += itemRect.size().height();
00150 itemRects.insert(index, itemRect);
00151
00152 QStandardItemModel * currentModel = dynamic_cast<QStandardItemModel *>(model());
00153 QStandardItem *currentItem = currentModel->itemFromIndex(index);
00154
00155 for (int k = 0; k < currentItem->rowCount(); ++k) {
00156 for (int l = 0; l < currentItem->columnCount(); ++l) {
00157 QStandardItem *childItem = currentItem->child(k, l);
00158 QModelIndex childIndex = childItem->index();
00159 QRect itemChildRect;
00160 if (l % 2 == 0) {
00161 QSize size(width() - COLUMN_EJECT_SIZE,sizeHintForIndex(index).height());
00162 itemChildRect = QRect(QPoint(HEADER_LEFT_MARGIN, verticalOffset), size);
00163 itemRects.insert(childIndex, itemChildRect);
00164 } else {
00165 QSize size(COLUMN_EJECT_SIZE - style()->pixelMetric(QStyle::PM_ScrollBarExtent) + 2,
00166 sizeHintForIndex(index).height());
00167 itemChildRect = QRect(QPoint(width() - (COLUMN_EJECT_SIZE - COLUMN_EJECT_MARGIN ),
00168 verticalOffset), size);
00169 itemRects.insert(childIndex, itemChildRect);
00170 verticalOffset += itemChildRect.size().height();
00171 }
00172 }
00173 }
00174 }
00175 }
00176 }
00177 }
00178
00179 void NotifierView::paintEvent(QPaintEvent *event)
00180 {
00181 Q_UNUSED(event);
00182 if (!model()) {
00183 return;
00184 }
00185
00186 QPainter painter(viewport());
00187 painter.setRenderHint(QPainter::Antialiasing);
00188
00189 QHashIterator<QModelIndex, QRect> it(itemRects);
00190 while (it.hasNext()) {
00191 it.next();
00192 QRect itemRect = it.value();
00193 if (event->region().contains(itemRect)) {
00194 QModelIndex index = it.key();
00195 if (model()->hasChildren(index)) {
00196
00197 paintHeaderItem(painter, itemRect, index);
00198 } else {
00199 paintItem(painter, itemRect, index);
00200 }
00201 }
00202 }
00203 }
00204
00205 void NotifierView::paintHeaderItem(QPainter &painter, const QRect &itemRect, const QModelIndex &index)
00206 {
00207 QStyleOptionViewItem option = viewOptions();
00208 option.rect = itemRect;
00209 const int rightMargin = style()->pixelMetric(QStyle::PM_ScrollBarExtent) + 6;
00210 const int dy = HEADER_TOP_MARGIN;
00211
00212 painter.save();
00213 painter.setRenderHint(QPainter::Antialiasing, false);
00214
00215 QLinearGradient gradient(option.rect.topLeft(), option.rect.topRight());
00216 gradient.setColorAt(0.0, Qt::transparent);
00217 gradient.setColorAt(0.1, option.palette.midlight().color());
00218 gradient.setColorAt(0.5, option.palette.mid().color());
00219 gradient.setColorAt(0.9, option.palette.midlight().color());
00220 gradient.setColorAt(1.0, Qt::transparent);
00221 painter.setPen(QPen(gradient, 1));
00222
00223 painter.drawLine(option.rect.x() + 6, option.rect.y() + dy + 2,
00224 option.rect.right() - rightMargin , option.rect.y() + dy + 2);
00225 painter.setFont(KGlobalSettings::smallestReadableFont());
00226 painter.setPen(QPen(KColorScheme(QPalette::Active).foreground(KColorScheme::InactiveText), 0));
00227 QString text = index.data(Qt::DisplayRole).value<QString>();
00228 painter.drawText(option.rect.adjusted(0, dy, -rightMargin, 0),
00229 Qt::AlignVCenter|Qt::AlignRight, text);
00230 painter.restore();
00231 }
00232
00233 void NotifierView::paintItem(QPainter &painter, const QRect &itemRect, const QModelIndex &index)
00234 {
00235 QStyleOptionViewItem option = viewOptions();
00236 option.rect = itemRect;
00237
00238 if (selectionModel()->isSelected(index)) {
00239 option.state |= QStyle::State_Selected;
00240 }
00241
00242 if (index == m_hoveredIndex) {
00243 option.state |= QStyle::State_MouseOver;
00244 }
00245
00246 if (index == currentIndex()) {
00247 option.state |= QStyle::State_HasFocus;
00248 }
00249
00250 itemDelegate(index)->paint(&painter,option,index);
00251 }
00252
00253 #include "notifierview.moc"