2 Copyright 2007 Robert Knight <robertknight@gmail.com>
3 Copyright 2007 Kevin Ottens <ervin@kde.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
22 #include "ui/itemdelegate.h"
25 #include <QApplication>
26 #include <QFontMetrics>
28 #include <QModelIndex>
30 #include <QStyleOptionViewItem>
33 #include <KColorUtils>
36 #include <KGlobalSettings>
39 #include <plasma/plasma.h>
41 using namespace Kickoff
;
43 ItemDelegate::ItemDelegate()
47 void ItemDelegate::paint(QPainter
*painter
, const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
49 const bool hover
= option
.state
& (QStyle::State_Selected
|QStyle::State_MouseOver
|QStyle::State_HasFocus
);
50 QRect contentRect
= option
.rect
;
51 contentRect
.setBottom(contentRect
.bottom() - 1);
52 QRect decorationRect
= QStyle::alignedRect(option
.direction
,
53 option
.decorationPosition
== QStyleOptionViewItem::Left
? Qt::AlignLeft
: Qt::AlignRight
,
54 option
.decorationSize
,
56 QSize
textSize(option
.rect
.width() - decorationRect
.width() - ICON_TEXT_MARGIN
,
57 option
.rect
.height() - 2);
61 if (!index
.data(DiskFreeSpaceRole
).isNull()) {
62 freeSpace
= index
.data(DiskFreeSpaceRole
).value
<int>()/1024.0/1024.0;
63 usedSpace
= index
.data(DiskUsedSpaceRole
).value
<int>()/1024.0/1024.0;
66 Qt::Alignment textAlignment
= option
.decorationAlignment
& Qt::AlignRight
? Qt::AlignLeft
: Qt::AlignRight
;
68 QRect textRect
= QStyle::alignedRect(option
.direction
,
71 contentRect
.adjusted(0, 2, 0, 0));
72 QString titleText
= index
.data(Qt::DisplayRole
).value
<QString
>();
73 QString subTitleText
= index
.data(SubTitleRole
).value
<QString
>();
74 bool uniqueTitle
= !index
.data(SubTitleMandatoryRole
).value
<bool>();// true;
76 QModelIndex sib
= index
.sibling(index
.row() + 1, index
.column());
78 uniqueTitle
= sib
.data(Qt::DisplayRole
).value
<QString
>() != titleText
;
82 sib
= index
.sibling(index
.row() + -1, index
.column());
84 uniqueTitle
= sib
.data(Qt::DisplayRole
).value
<QString
>() != titleText
;
89 QRect titleRect
= textRect
;
91 if (subTitleText
== titleText
) {
92 subTitleText
= QString();
95 titleRect
.setHeight(titleRect
.height() / 2);
96 QRect subTitleRect
= titleRect
;
97 subTitleRect
.translate(0, subTitleRect
.height());
98 QFont subTitleFont
= fontForSubTitle(option
.font
);
100 QFont
titleFont(option
.font
);
104 painter
->setPen(Qt::NoPen
);
105 QColor backgroundColor
= option
.palette
.color(QPalette::Highlight
);
106 QFontMetrics
titleMetrics(titleFont
);
107 QFontMetrics
subTitleMetrics(subTitleFont
);
108 QRect textAreaRect
= contentRect
;
109 int actualTextWidth
= qMax(titleMetrics
.width(titleText
), subTitleMetrics
.width(" " + subTitleText
));
110 if (option
.direction
== Qt::LeftToRight
) {
111 textAreaRect
.adjust(decorationRect
.width() + ICON_TEXT_MARGIN
- 3, 0,
112 -(titleRect
.width() - actualTextWidth
) + 3, 1);
114 textAreaRect
.adjust((titleRect
.width() - actualTextWidth
) - 3, 1,
115 - decorationRect
.width() - ICON_TEXT_MARGIN
+ 3, 0);
117 // use a slightly translucent version of the palette's highlight color
118 // for the background
119 backgroundColor
.setAlphaF(0.5);
120 painter
->setBrush(QBrush(backgroundColor
));
121 painter
->drawPath(Plasma::roundedRectangle(textAreaRect
, 5));
126 QIcon decorationIcon
= index
.data(Qt::DecorationRole
).value
<QIcon
>();
127 decorationIcon
.paint(painter
, decorationRect
, option
.decorationAlignment
);
132 painter
->setFont(titleFont
);
133 painter
->drawText(titleRect
, Qt::AlignLeft
|Qt::AlignVCenter
, titleText
);
135 if (hover
|| !uniqueTitle
) {
137 painter
->setPen(QPen(option
.palette
.dark(), 1));
138 painter
->setFont(subTitleFont
);
139 painter
->drawText(subTitleRect
, Qt::AlignLeft
|Qt::AlignVCenter
, " " + subTitleText
);
144 // draw free space information (for drive icons)
145 if (usedSpace
>= 0) {
148 QFontMetrics
titleMetrics(option
.font
);
149 QFontMetrics
subTitleMetrics(subTitleFont
);
151 qreal actualTextWidth
= qMax(titleMetrics
.width(titleText
), subTitleMetrics
.width(subTitleText
));
153 QSize spaceSize
= option
.rect
.size();
154 //kDebug() << "space size is" << spaceSize.rwidth() << "and we're going to lop off"
155 // << (actualTextWidth + decorationRect.width() + ICON_TEXT_MARGIN + 3);
156 spaceSize
.rwidth() /= 3; //-= (spaceSize.width() * 2.0 / 3.0) /*actualTextWidth +*/ + decorationRect.width() + (ICON_TEXT_MARGIN * 2) + 3;
157 spaceSize
.rheight() -= 20;
159 // check if there is enough space to draw the bar
160 qreal textBarGap
= (titleRect
.width() - actualTextWidth
) - (spaceSize
.width() + ICON_TEXT_MARGIN
);
161 //kDebug() << "text bar gap is" << textBarGap;
163 if (textBarGap
> 0) {
164 // if the item view is gradually resized smaller or larger, make the bar fade out/in
165 // as enough space for it becomes available
166 if (textBarGap
< 20.0) {
167 painter
->setOpacity(textBarGap
/20.0);
170 QRectF spaceRect
= QStyle::alignedRect(option
.direction
,
171 Qt::AlignRight
, spaceSize
, contentRect
);
173 // add spacing between item text and free-space bar and tweak the position slightly
174 // to give a sharp outline when drawn with anti-aliasing enabled
175 spaceRect
.translate(0.5, 3.5);
177 QColor fillBrush
= KColorUtils::mix(Qt::green
, Qt::yellow
, (usedSpace
/ (freeSpace
+usedSpace
)));
178 QColor penColor
= option
.palette
.mid().color();
180 fillBrush
.setAlpha(75);
181 penColor
.setAlpha(75);
184 qreal width
= (usedSpace
/ (freeSpace
+ usedSpace
)) * spaceRect
.width();
185 painter
->setPen(QPen(penColor
, 0));
186 painter
->fillRect(QRectF(spaceRect
.left(), spaceRect
.top(), width
, spaceRect
.height()), fillBrush
);
187 painter
->setBrush(QBrush(Qt::NoBrush
));
188 painter
->drawRect(spaceRect
);
190 // -- Removed the free space text because it added too much 'visual noise' to the item
192 // some precision is lost here, but it is acceptible given that the disk-free bar
193 // is only shown as a guide
194 // QString freeSpaceString = KGlobal::locale()->formatByteSize(freeSpace*1024*1024*1024);
195 // painter->drawText(spaceRect,Qt::AlignCenter,i18n("%1 free",freeSpaceString));
202 QFont
ItemDelegate::fontForSubTitle(const QFont
& titleFont
) const
204 QFont subTitleFont
= titleFont
;
205 subTitleFont
.setPointSize(qMax(subTitleFont
.pointSize() - 2,
206 KGlobalSettings::smallestReadableFont().pointSize()));
210 QSize
ItemDelegate::sizeHint(const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
213 QSize size
= option
.rect
.size();
215 QFontMetrics
metrics(option
.font
);
217 /* size.rwidth() += ICON_TEXT_MARGIN +
218 qMax(metrics.width(index.data(Qt::DisplayRole).value<QString>()),
219 metrics.width(index.data(SubTitleRole).value<QString>()));*/
220 QFont subTitleFont
= option
.font
;
221 subTitleFont
.setPointSize(qMax(subTitleFont
.pointSize() - 2,
222 KGlobalSettings::smallestReadableFont().pointSize()));
223 QFontMetrics
subMetrics(subTitleFont
);
224 size
.setHeight(qMax(option
.decorationSize
.height(), qMax(size
.height(), metrics
.height() + subMetrics
.ascent()) + 3) + 4);
225 // kDebug() << "size hint is" << size << (metrics.height() + subMetrics.ascent());
230 bool ItemDelegate::isVisible(const QModelIndex
& index
) const
232 Q_ASSERT(index
.isValid());
234 if (index
.model()->hasChildren(index
)) {
235 int childCount
= index
.model()->rowCount(index
);
236 for (int i
=0; i
<childCount
; ++i
) {
237 QModelIndex child
= index
.model()->index(i
, 0, index
);
238 if (!child
.data(UrlRole
).isNull()) {
245 return !index
.data(UrlRole
).isNull();