29 #include <QApplication>
30 #include <QFontMetrics>
32 #include <QModelIndex>
34 #include <QStyleOptionViewItem>
37 #include <kcolorutils.h>
40 #include <kglobalsettings.h>
41 #include <kcolorscheme.h>
55 ~DelegatePrivate() { }
57 QFont fontForSubTitle(
const QFont &titleFont)
const;
58 QRect titleRect(
const QStyleOptionViewItem &option,
const QModelIndex &index)
const;
59 QRect subTitleRect(
const QStyleOptionViewItem &option,
const QModelIndex &index)
const;
63 static const int ICON_TEXT_MARGIN = 10;
64 static const int TEXT_RIGHT_MARGIN = 5;
65 static const int ACTION_ICON_SIZE = 22;
67 static const int ITEM_LEFT_MARGIN = 5;
68 static const int ITEM_RIGHT_MARGIN = 5;
69 static const int ITEM_TOP_MARGIN = 5;
70 static const int ITEM_BOTTOM_MARGIN = 5;
76 QFont DelegatePrivate::fontForSubTitle(
const QFont &titleFont)
const
78 QFont subTitleFont = titleFont;
79 subTitleFont.setPointSize(qMax(subTitleFont.pointSize() - 2,
80 KGlobalSettings::smallestReadableFont().pointSize()));
84 QRect DelegatePrivate::titleRect(
const QStyleOptionViewItem &option,
const QModelIndex &index)
const
86 QFont font(option.font);
88 QFontMetrics fm(font);
90 Qt::Alignment textAlignment =
91 option.decorationAlignment & Qt::AlignRight ? Qt::AlignRight : Qt::AlignLeft;
94 if (option.direction == Qt::LeftToRight) {
95 emptyRect = option.rect.adjusted(
96 option.decorationSize.width() + ICON_TEXT_MARGIN + ITEM_LEFT_MARGIN,
97 ITEM_TOP_MARGIN, -ITEM_RIGHT_MARGIN, -ITEM_BOTTOM_MARGIN);
99 emptyRect = option.rect.adjusted(
100 ITEM_LEFT_MARGIN, ITEM_TOP_MARGIN,
101 -ITEM_RIGHT_MARGIN - option.decorationSize.width() - ICON_TEXT_MARGIN, -ITEM_BOTTOM_MARGIN);
104 if (emptyRect.width() < 0) {
105 emptyRect.setWidth(0);
109 QRect textRect = QStyle::alignedRect(
112 fm.boundingRect(index.data(Qt::DisplayRole).toString()).size(),
115 textRect.setWidth(textRect.width() + TEXT_RIGHT_MARGIN);
116 textRect.setHeight(emptyRect.height() / 2);
120 QRect DelegatePrivate::subTitleRect(
const QStyleOptionViewItem &option,
121 const QModelIndex &index)
const
125 QFontMetrics fm(fontForSubTitle(option.font));
127 QRect textRect = titleRect(option, index);
128 int right = textRect.right();
131 if (subTitle != index.data(Qt::DisplayRole).toString()) {
132 textRect.setWidth(fm.width(
" " + subTitle) + TEXT_RIGHT_MARGIN);
134 textRect.setWidth(0);
136 textRect.translate(0, textRect.height());
138 if (option.direction == Qt::RightToLeft) {
139 textRect.moveRight(right);
147 d(new DelegatePrivate)
150 d->svg->setImagePath(
"widgets/viewitem");
151 d->svg->setElementPrefix(
"hover");
161 d->roles[role] = actual;
166 return d->roles[role];
171 QRect textRect = d->titleRect(option, index);
173 QRect
emptyRect(0, textRect.top(), option.rect.width() - textRect.width() - DelegatePrivate::ITEM_LEFT_MARGIN - DelegatePrivate::ITEM_RIGHT_MARGIN - option.decorationSize.width() - DelegatePrivate::ICON_TEXT_MARGIN, textRect.height());
175 if (option.direction == Qt::LeftToRight) {
176 emptyRect.moveLeft(textRect.right());
178 emptyRect.moveRight(textRect.left());
181 if (emptyRect.width() < 0) {
182 emptyRect.setWidth(0);
190 QRect textRect = d->subTitleRect(option, index);
192 QRect
emptyRect(0, textRect.top(), option.rect.width() - textRect.width() - DelegatePrivate::ITEM_LEFT_MARGIN - DelegatePrivate::ITEM_RIGHT_MARGIN - option.decorationSize.width() - DelegatePrivate::ICON_TEXT_MARGIN, textRect.height());
194 if (option.direction == Qt::LeftToRight) {
195 emptyRect.moveLeft(textRect.right());
197 emptyRect.moveRight(textRect.left());
200 if (emptyRect.width() < 0) {
201 emptyRect.setWidth(0);
212 afterTitleRect.setHeight(afterTitleRect.height() * 2);
213 afterSubTitleRect.setTop(afterTitleRect.top());
215 return afterTitleRect.intersected(afterSubTitleRect);
219 const QModelIndex &index)
const
221 const bool hover = option.state & (QStyle::State_MouseOver | QStyle::State_Selected);
223 QRect contentRect = option.rect;
224 contentRect.setBottom(contentRect.bottom() - 1);
226 QRect decorationRect =
227 QStyle::alignedRect(option.direction,
229 Qt::AlignLeft : Qt::AlignRight,
230 option.decorationSize,
231 contentRect.adjusted(DelegatePrivate::ITEM_LEFT_MARGIN, DelegatePrivate::ITEM_TOP_MARGIN, -DelegatePrivate::ITEM_RIGHT_MARGIN, -DelegatePrivate::ITEM_BOTTOM_MARGIN));
232 decorationRect.moveTop(contentRect.top() + qMax(0, (contentRect.height() - decorationRect.height())) / 2);
234 QString titleText = index.data(Qt::DisplayRole).value<QString>();
235 QString subTitleText = index.data(d->roles[
SubTitleRole]).value<QString>();
238 QRect titleRect = d->titleRect(option, index);
239 titleRect.moveTopLeft(titleRect.topLeft()-option.rect.topLeft());
240 QRect subTitleRect = d->subTitleRect(option, index);
241 subTitleRect.moveTopLeft(subTitleRect.topLeft()-option.rect.topLeft());
243 if (subTitleText == titleText) {
244 subTitleText.clear();
247 QFont titleFont(option.font);
250 QIcon decorationIcon = index.data(Qt::DecorationRole).value<QIcon>();
255 const int delta = floor((qreal)(option.decorationSize.width() - DelegatePrivate::ACTION_ICON_SIZE) / 2.0);
256 decorationRect.adjust(delta, delta-1, -delta-1, -delta);
257 decorationIcon.paint(painter, decorationRect, option.decorationAlignment);
261 decorationIcon.paint(painter, decorationRect, option.decorationAlignment);
264 QPixmap buffer(option.rect.size());
265 buffer.fill(Qt::transparent);
268 p.setFont(titleFont);
269 if (option.palette.color(QPalette::Base).alpha() > 0) {
270 p.setPen(QPen(KColorScheme(QPalette::Active).foreground(KColorScheme::NormalText), 1));
274 p.drawText(titleRect, Qt::AlignLeft|Qt::AlignVCenter, titleText);
287 bool drawSubTitle = !subTitleText.isEmpty();
289 if (drawSubTitle && !hover) {
296 if (mandatoryRoleData.isValid()) {
297 drawSubTitle = mandatoryRoleData.value<
bool>();
299 bool uniqueTitle =
true;
300 QModelIndex sib = index.sibling(index.row() + 1, index.column());
302 uniqueTitle = sib.data(Qt::DisplayRole).value<QString>() != titleText;
306 sib = index.sibling(index.row() + -1, index.column());
308 uniqueTitle = sib.data(Qt::DisplayRole).value<QString>() != titleText;
312 drawSubTitle = !uniqueTitle;
318 if (option.palette.color(QPalette::Base).alpha() > 0) {
319 p.setPen(QPen(KColorScheme(QPalette::Active).foreground(KColorScheme::InactiveText), 1));
322 textColor.setAlphaF(0.6);
326 const QFont subTitleFont = d->fontForSubTitle(option.font);
327 p.setFont(subTitleFont);
328 p.drawText(subTitleRect, Qt::AlignLeft|Qt::AlignVCenter, subTitleText);
333 d->m_showToolTip =
false;
335 const QColor gradientColor = KColorScheme(QPalette::Active).background(KColorScheme::NormalBackground).color();
337 if (option.direction == Qt::LeftToRight) {
338 if (((titleRect.width() + decorationRect.width() + 10) > option.rect.width() ||
339 (subTitleRect.width() + decorationRect.width() + 15) > option.rect.width()) &&
340 (titleRect.width() > 120 || subTitleRect.width() > 120)) {
342 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
345 QRect gradientRect(option.rect.width() - 60, titleRect.y(),
346 80, titleRect.height() + subTitleRect.height());
348 gr.setStart(gradientRect.topLeft());
349 gr.setFinalStop(gradientRect.topRight());
350 gr.setColorAt(0.0, Qt::transparent);
351 gr.setColorAt(0.7, gradientColor);
352 p.setBrush(QBrush(gr));
353 p.drawRect(gradientRect);
354 d->m_showToolTip =
true;
359 if (((titleRect.width() + decorationRect.width() + 10) > option.rect.width() ||
360 (subTitleRect.width() + decorationRect.width() + 15 )> option.rect.width()) &&
361 (titleRect.width() > 120 || subTitleRect.width() > 120)) {
362 buffer.fill(Qt::transparent);
364 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
367 QRect gradientRect(option.rect.x() - 55, titleRect.y(),
368 60, titleRect.height() + subTitleRect.height());
369 gr.setStart(gradientRect.topRight());
370 gr.setFinalStop(gradientRect.topLeft());
371 gr.setColorAt(0.0, Qt::transparent);
372 gr.setColorAt(0.6, gradientColor);
373 p.setBrush(QBrush(gr));
374 p.drawRect(gradientRect);
376 d->m_showToolTip =
true;
381 painter->drawPixmap(option.rect, buffer, buffer.rect());
385 painter->setRenderHint(QPainter::Antialiasing);
387 const int column = index.column();
388 const int columns = index.model()->columnCount();
389 int roundedRadius = 5;
390 const bool useSvg = option.palette.color(QPalette::Base).alpha() == 0;
394 QColor backgroundColor = option.palette.color(QPalette::Highlight);
395 backgroundColor.setAlphaF(0.2);
397 QColor backgroundColor2 = option.palette.color(QPalette::Highlight);
398 backgroundColor2.setAlphaF(0.5);
400 QRect highlightRect = option.rect;
402 highlightRect.adjust(2, 2, -2, -2);
405 QPen outlinePen(backgroundColor, 2);
413 painter->setClipRect(option.rect);
414 highlightRect.adjust(0, 0, roundedRadius, 0);
417 QLinearGradient gradient(highlightRect.topLeft(), highlightRect.topRight());
420 if (option.direction == Qt::RightToLeft) {
421 gradient.setStart(highlightRect.topRight());
422 gradient.setFinalStop(highlightRect.topLeft());
425 gradient.setColorAt(0, backgroundColor);
426 gradient.setColorAt(((qreal)titleRect.width()/3.0) / (qreal)highlightRect.width(), backgroundColor2);
427 gradient.setColorAt(0.7, backgroundColor);
428 outlinePen.setBrush(gradient);
430 }
else if (column == columns-1) {
434 painter->setClipRect(option.rect);
435 highlightRect.adjust(-roundedRadius, 0, 0, 0);
442 painter->setClipRect(option.rect);
443 highlightRect.adjust(-roundedRadius, 0, +roundedRadius, 0);
448 d->svg->resizeFrame(highlightRect.size());
449 d->svg->paintFrame(painter, highlightRect.topLeft());
451 painter->setPen(outlinePen);
464 QSize size = option.rect.size();
466 QFontMetrics metrics(option.font);
468 QFontMetrics subMetrics(d->fontForSubTitle(option.font));
469 size.setHeight(qMax(option.decorationSize.height(), qMax(size.height(), metrics.height() + subMetrics.ascent()) + 3) + 4);
472 const bool useSvg = option.palette.color(QPalette::Base).alpha() == 0;
475 qreal left, top, right, bottom;
476 d->svg->getMargins(left, top, right, bottom);
477 size += QSize(left+right, top+bottom);
487 return d->m_showToolTip;
492 #include "delegate.moc"
QRect rectAfterTitle(const QStyleOptionViewItem &option, const QModelIndex &index) const
Returns the empty area after the title.
int roleMapping(SpecificRoles role) const
void setRoleMapping(SpecificRoles role, int actual)
Maps an arbitrary role to a role belonging to SpecificRoles.
the text color to be used by items resting on the background
Delegate(QObject *parent=0)
Provides an SVG with borders.
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
QPainterPath roundedRectangle(const QRectF &rect, qreal radius)
Returns a nicely rounded rectanglular path for painting.
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
QRect rectAfterSubTitle(const QStyleOptionViewItem &option, const QModelIndex &index) const
Returns the empty area after the subtitle.
static Theme * defaultTheme()
Singleton pattern accessor.
Q_INVOKABLE QColor color(ColorRole role) const
Returns the text color to be used by items resting on the background.
QRect emptyRect(const QStyleOptionViewItem &option, const QModelIndex &index) const
Returns the empty area after both the title and the subtitle.