20
20
#include "kfileitemlistwidget.h"
22
#include "kfileitemclipboard_p.h"
23
#include "kfileitemmodel.h"
24
#include "kitemlistview.h"
25
#include "kpixmapmodifier_p.h"
28
#include <KIconEffect>
29
#include <KIconLoader>
31
#include <KStringHandler>
34
#include <QFontMetricsF>
35
#include <QGraphicsSceneResizeEvent>
37
#include <QStyleOption>
38
#include <QTextLayout>
41
// #define KFILEITEMLISTWIDGET_DEBUG
43
KFileItemListWidget::KFileItemListWidget(QGraphicsItem* parent) :
44
KItemListWidget(parent),
47
m_isExpandable(false),
48
m_supportsItemExpanding(false),
51
m_dirtyContentRoles(),
52
m_layout(IconsLayout),
61
m_sortedVisibleRoles(),
64
m_additionalInfoTextColor(),
67
for (int i = 0; i < TextIdCount; ++i) {
68
m_text[i].setTextFormat(Qt::PlainText);
69
m_text[i].setPerformanceHint(QStaticText::AggressiveCaching);
73
KFileItemListWidget::~KFileItemListWidget()
77
void KFileItemListWidget::setLayout(Layout layout)
79
if (m_layout != layout) {
82
updateAdditionalInfoTextColor();
87
KFileItemListWidget::Layout KFileItemListWidget::layout() const
92
void KFileItemListWidget::setSupportsItemExpanding(bool supportsItemExpanding)
94
if (m_supportsItemExpanding != supportsItemExpanding) {
95
m_supportsItemExpanding = supportsItemExpanding;
101
bool KFileItemListWidget::supportsItemExpanding() const
103
return m_supportsItemExpanding;
106
void KFileItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
108
const_cast<KFileItemListWidget*>(this)->triggerCacheRefreshing();
110
KItemListWidget::paint(painter, option, widget);
112
if (!m_expansionArea.isEmpty()) {
113
drawSiblingsInformation(painter);
116
const KItemListStyleOption& itemListStyleOption = styleOption();
118
// Blend the unhovered and hovered pixmap if the hovering
119
// animation is ongoing
120
if (hoverOpacity() < 1.0) {
121
drawPixmap(painter, m_pixmap);
124
const qreal opacity = painter->opacity();
125
painter->setOpacity(hoverOpacity() * opacity);
126
drawPixmap(painter, m_hoverPixmap);
127
painter->setOpacity(opacity);
129
drawPixmap(painter, m_pixmap);
132
painter->setFont(itemListStyleOption.font);
133
painter->setPen(textColor());
134
painter->drawStaticText(m_textPos[Name], m_text[Name]);
136
bool clipAdditionalInfoBounds = false;
137
if (m_supportsItemExpanding) {
138
// Prevent a possible overlapping of the additional-information texts
139
// with the icon. This can happen if the user has minimized the width
140
// of the name-column to a very small value.
141
const qreal minX = m_pixmapPos.x() + m_pixmap.width() + 4 * itemListStyleOption.padding;
142
if (m_textPos[Name + 1].x() < minX) {
143
clipAdditionalInfoBounds = true;
145
painter->setClipRect(minX, 0, size().width() - minX, size().height(), Qt::IntersectClip);
149
painter->setPen(m_additionalInfoTextColor);
150
painter->setFont(itemListStyleOption.font);
151
for (int i = Name + 1; i < TextIdCount; ++i) {
152
painter->drawStaticText(m_textPos[i], m_text[i]);
155
if (clipAdditionalInfoBounds) {
159
#ifdef KFILEITEMLISTWIDGET_DEBUG
160
painter->setBrush(Qt::NoBrush);
161
painter->setPen(Qt::green);
162
painter->drawRect(m_iconRect);
164
painter->setPen(Qt::red);
165
painter->drawText(QPointF(0, itemListStyleOption.fontMetrics.height()), QString::number(index()));
166
painter->drawRect(rect());
170
QRectF KFileItemListWidget::iconRect() const
172
const_cast<KFileItemListWidget*>(this)->triggerCacheRefreshing();
176
QRectF KFileItemListWidget::textRect() const
178
const_cast<KFileItemListWidget*>(this)->triggerCacheRefreshing();
182
QRectF KFileItemListWidget::expansionToggleRect() const
184
const_cast<KFileItemListWidget*>(this)->triggerCacheRefreshing();
185
return m_isExpandable ? m_expansionArea : QRectF();
188
QRectF KFileItemListWidget::selectionToggleRect() const
190
const_cast<KFileItemListWidget*>(this)->triggerCacheRefreshing();
192
const int iconHeight = styleOption().iconSize;
194
int toggleSize = KIconLoader::SizeSmall;
195
if (iconHeight >= KIconLoader::SizeEnormous) {
196
toggleSize = KIconLoader::SizeMedium;
197
} else if (iconHeight >= KIconLoader::SizeLarge) {
198
toggleSize = KIconLoader::SizeSmallMedium;
201
QPointF pos = iconRect().topLeft();
203
// If the selection toggle has a very small distance to the
204
// widget borders, the size of the selection toggle will get
205
// increased to prevent an accidental clicking of the item
206
// when trying to hit the toggle.
207
const int widgetHeight = size().height();
208
const int widgetWidth = size().width();
209
const int minMargin = 2;
211
if (toggleSize + minMargin * 2 >= widgetHeight) {
212
pos.rx() -= (widgetHeight - toggleSize) / 2;
213
toggleSize = widgetHeight;
216
if (toggleSize + minMargin * 2 >= widgetWidth) {
217
pos.ry() -= (widgetWidth - toggleSize) / 2;
218
toggleSize = widgetWidth;
222
return QRectF(pos, QSizeF(toggleSize, toggleSize));
225
QString KFileItemListWidget::roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values)
25
#include <KIO/MetaData>
28
KFileItemListWidgetInformant::KFileItemListWidgetInformant() :
29
KStandardItemListWidgetInformant()
33
KFileItemListWidgetInformant::~KFileItemListWidgetInformant()
37
QString KFileItemListWidgetInformant::roleText(const QByteArray& role,
38
const QHash<QByteArray, QVariant>& values) const
228
41
const QVariant roleValue = values.value(role);
230
switch (roleTextId(role)) {
238
text = roleValue.toString();
43
// Implementation note: In case if more roles require a custom handling
44
// use a hash + switch for a linear runtime.
242
47
if (values.value("isDir").toBool()) {
243
48
// The item represents a directory. Show the number of sub directories
244
49
// instead of the file size of the directory.
254
59
const KIO::filesize_t size = roleValue.value<KIO::filesize_t>();
255
60
text = KGlobal::locale()->formatByteSize(size);
62
} else if (role == "date") {
261
63
const QDateTime dateTime = roleValue.toDateTime();
262
64
text = KGlobal::locale()->formatDateTime(dateTime);
66
text = KStandardItemListWidgetInformant::roleText(role, values);
274
void KFileItemListWidget::invalidateCache()
276
m_dirtyLayout = true;
277
m_dirtyContent = true;
280
void KFileItemListWidget::refreshCache()
284
void KFileItemListWidget::setTextColor(const QColor& color)
286
if (color != m_customTextColor) {
287
m_customTextColor = color;
288
updateAdditionalInfoTextColor();
293
QColor KFileItemListWidget::textColor() const
295
if (m_customTextColor.isValid() && !isSelected()) {
296
return m_customTextColor;
299
const QPalette::ColorGroup group = isActiveWindow() ? QPalette::Active : QPalette::Inactive;
300
const QPalette::ColorRole role = isSelected() ? QPalette::HighlightedText : QPalette::Text;
301
return styleOption().palette.brush(group, role).color();
304
void KFileItemListWidget::setOverlay(const QPixmap& overlay)
307
m_dirtyContent = true;
311
QPixmap KFileItemListWidget::overlay() const
316
void KFileItemListWidget::dataChanged(const QHash<QByteArray, QVariant>& current,
317
const QSet<QByteArray>& roles)
321
m_dirtyContent = true;
323
QSet<QByteArray> dirtyRoles;
324
if (roles.isEmpty()) {
325
dirtyRoles = visibleRoles().toSet();
326
dirtyRoles.insert("iconPixmap");
327
dirtyRoles.insert("iconName");
332
QSetIterator<QByteArray> it(dirtyRoles);
333
while (it.hasNext()) {
334
const QByteArray& role = it.next();
335
m_dirtyContentRoles.insert(role);
339
void KFileItemListWidget::visibleRolesChanged(const QList<QByteArray>& current,
340
const QList<QByteArray>& previous)
343
m_sortedVisibleRoles = current;
344
m_dirtyLayout = true;
347
void KFileItemListWidget::visibleRolesSizesChanged(const QHash<QByteArray, QSizeF>& current,
348
const QHash<QByteArray, QSizeF>& previous)
352
m_dirtyLayout = true;
355
void KFileItemListWidget::styleOptionChanged(const KItemListStyleOption& current,
356
const KItemListStyleOption& previous)
360
updateAdditionalInfoTextColor();
361
m_dirtyLayout = true;
364
void KFileItemListWidget::hoveredChanged(bool hovered)
367
m_dirtyLayout = true;
370
void KFileItemListWidget::selectedChanged(bool selected)
373
updateAdditionalInfoTextColor();
376
void KFileItemListWidget::siblingsInformationChanged(const QBitArray& current, const QBitArray& previous)
380
m_dirtyLayout = true;
384
void KFileItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event)
386
KItemListWidget::resizeEvent(event);
387
m_dirtyLayout = true;
390
void KFileItemListWidget::showEvent(QShowEvent* event)
392
KItemListWidget::showEvent(event);
394
// Listen to changes of the clipboard to mark the item as cut/uncut
395
KFileItemClipboard* clipboard = KFileItemClipboard::instance();
397
const KUrl itemUrl = data().value("url").value<KUrl>();
398
m_isCut = clipboard->isCut(itemUrl);
400
connect(clipboard, SIGNAL(cutItemsChanged()),
401
this, SLOT(slotCutItemsChanged()));
404
void KFileItemListWidget::hideEvent(QHideEvent* event)
406
disconnect(KFileItemClipboard::instance(), SIGNAL(cutItemsChanged()),
407
this, SLOT(slotCutItemsChanged()));
409
KItemListWidget::hideEvent(event);
412
void KFileItemListWidget::slotCutItemsChanged()
414
const KUrl itemUrl = data().value("url").value<KUrl>();
415
const bool isCut = KFileItemClipboard::instance()->isCut(itemUrl);
416
if (m_isCut != isCut) {
418
m_pixmap = QPixmap();
419
m_dirtyContent = true;
424
void KFileItemListWidget::triggerCacheRefreshing()
426
if ((!m_dirtyContent && !m_dirtyLayout) || index() < 0) {
432
const QHash<QByteArray, QVariant> values = data();
433
m_isExpandable = m_supportsItemExpanding && values["isExpandable"].toBool();
434
m_isHidden = values["name"].toString().startsWith(QLatin1Char('.'));
436
updateExpansionArea();
440
m_dirtyLayout = false;
441
m_dirtyContent = false;
442
m_dirtyContentRoles.clear();
445
void KFileItemListWidget::updateExpansionArea()
447
if (m_supportsItemExpanding) {
448
const QHash<QByteArray, QVariant> values = data();
449
Q_ASSERT(values.contains("expandedParentsCount"));
450
const int expandedParentsCount = values.value("expandedParentsCount", 0).toInt();
451
if (expandedParentsCount >= 0) {
452
const qreal widgetHeight = size().height();
453
const qreal inc = (widgetHeight - KIconLoader::SizeSmall) / 2;
454
const qreal x = expandedParentsCount * widgetHeight + inc;
456
m_expansionArea = QRectF(x, y, KIconLoader::SizeSmall, KIconLoader::SizeSmall);
461
m_expansionArea = QRectF();
464
void KFileItemListWidget::updatePixmapCache()
466
// Precondition: Requires already updated m_textPos values to calculate
467
// the remaining height when the alignment is vertical.
469
const QSizeF widgetSize = size();
470
const bool iconOnTop = (m_layout == IconsLayout);
471
const KItemListStyleOption& option = styleOption();
472
const qreal padding = option.padding;
474
const int maxIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : option.iconSize;
475
const int maxIconHeight = option.iconSize;
477
const QHash<QByteArray, QVariant> values = data();
479
bool updatePixmap = (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight);
480
if (!updatePixmap && m_dirtyContent) {
481
updatePixmap = m_dirtyContentRoles.isEmpty()
482
|| m_dirtyContentRoles.contains("iconPixmap")
483
|| m_dirtyContentRoles.contains("iconName")
484
|| m_dirtyContentRoles.contains("iconOverlays");
488
m_pixmap = values["iconPixmap"].value<QPixmap>();
489
if (m_pixmap.isNull()) {
490
// Use the icon that fits to the MIME-type
491
QString iconName = values["iconName"].toString();
492
if (iconName.isEmpty()) {
493
// The icon-name has not been not resolved by KFileItemModelRolesUpdater,
494
// use a generic icon as fallback
495
iconName = QLatin1String("unknown");
497
m_pixmap = pixmapForIcon(iconName, maxIconHeight);
498
} else if (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight) {
499
// A custom pixmap has been applied. Assure that the pixmap
500
// is scaled to the maximum available size.
501
KPixmapModifier::scale(m_pixmap, QSize(maxIconWidth, maxIconHeight));
504
const QStringList overlays = values["iconOverlays"].toStringList();
506
// Strangely KFileItem::overlays() returns empty string-values, so
507
// we need to check first whether an overlay must be drawn at all.
508
// It is more efficient to do it here, as KIconLoader::drawOverlays()
509
// assumes that an overlay will be drawn and has some additional
511
foreach (const QString& overlay, overlays) {
512
if (!overlay.isEmpty()) {
513
// There is at least one overlay, draw all overlays above m_pixmap
514
// and cancel the check
515
KIconLoader::global()->drawOverlays(overlays, m_pixmap, KIconLoader::Desktop);
521
applyCutEffect(m_pixmap);
525
applyHiddenEffect(m_pixmap);
529
if (!m_overlay.isNull()) {
530
QPainter painter(&m_pixmap);
531
painter.drawPixmap(0, m_pixmap.height() - m_overlay.height(), m_overlay);
534
int scaledIconSize = 0;
536
scaledIconSize = static_cast<int>(m_textPos[Name].y() - 2 * padding);
538
const int textRowsCount = (m_layout == CompactLayout) ? visibleRoles().count() : 1;
539
const qreal requiredTextHeight = textRowsCount * option.fontMetrics.height();
540
scaledIconSize = (requiredTextHeight < maxIconHeight) ?
541
widgetSize.height() - 2 * padding : maxIconHeight;
544
const int maxScaledIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : scaledIconSize;
545
const int maxScaledIconHeight = scaledIconSize;
547
m_scaledPixmapSize = m_pixmap.size();
548
m_scaledPixmapSize.scale(maxScaledIconWidth, maxScaledIconHeight, Qt::KeepAspectRatio);
551
// Center horizontally and align on bottom within the icon-area
552
m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2);
553
m_pixmapPos.setY(padding + scaledIconSize - m_scaledPixmapSize.height());
555
// Center horizontally and vertically within the icon-area
556
m_pixmapPos.setX(m_textPos[Name].x() - 2 * padding
557
- (scaledIconSize + m_scaledPixmapSize.width()) / 2);
558
m_pixmapPos.setY(padding
559
+ (scaledIconSize - m_scaledPixmapSize.height()) / 2);
562
m_iconRect = QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize));
564
// Prepare the pixmap that is used when the item gets hovered
566
m_hoverPixmap = m_pixmap;
567
KIconEffect* effect = KIconLoader::global()->iconEffect();
568
// In the KIconLoader terminology, active = hover.
569
if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
570
m_hoverPixmap = effect->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::ActiveState);
572
m_hoverPixmap = m_pixmap;
574
} else if (hoverOpacity() <= 0.0) {
575
// No hover animation is ongoing. Clear m_hoverPixmap to save memory.
576
m_hoverPixmap = QPixmap();
580
void KFileItemListWidget::updateTextsCache()
582
QTextOption textOption;
585
textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
586
textOption.setAlignment(Qt::AlignHCenter);
590
textOption.setAlignment(Qt::AlignLeft);
591
textOption.setWrapMode(QTextOption::NoWrap);
598
for (int i = 0; i < TextIdCount; ++i) {
599
m_text[i].setText(QString());
600
m_text[i].setTextOption(textOption);
604
case IconsLayout: updateIconsLayoutTextCache(); break;
605
case CompactLayout: updateCompactLayoutTextCache(); break;
606
case DetailsLayout: updateDetailsLayoutTextCache(); break;
607
default: Q_ASSERT(false); break;
611
void KFileItemListWidget::updateIconsLayoutTextCache()
618
// might get wrapped above
623
const QHash<QByteArray, QVariant> values = data();
625
const KItemListStyleOption& option = styleOption();
626
const qreal padding = option.padding;
627
const qreal maxWidth = size().width() - 2 * padding;
628
const qreal widgetHeight = size().height();
629
const qreal fontHeight = option.fontMetrics.height();
631
// Initialize properties for the "name" role. It will be used as anchor
632
// for initializing the position of the other roles.
633
m_text[Name].setText(KStringHandler::preProcessWrap(values["name"].toString()));
635
// Calculate the number of lines required for the name and the required width
636
int textLinesCountForName = 0;
637
qreal requiredWidthForName = 0;
640
QTextLayout layout(m_text[Name].text(), option.font);
641
layout.setTextOption(m_text[Name].textOption());
642
layout.beginLayout();
643
while ((line = layout.createLine()).isValid()) {
644
line.setLineWidth(maxWidth);
645
requiredWidthForName = qMax(requiredWidthForName, line.naturalTextWidth());
646
++textLinesCountForName;
650
// Use one line for each additional information
651
int textLinesCount = textLinesCountForName;
652
const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
653
textLinesCount += additionalRolesCount;
655
m_text[Name].setTextWidth(maxWidth);
656
m_textPos[Name] = QPointF(padding, widgetHeight - textLinesCount * fontHeight - padding);
657
m_textRect = QRectF(padding + (maxWidth - requiredWidthForName) / 2,
659
requiredWidthForName,
660
textLinesCountForName * fontHeight);
662
// Calculate the position for each additional information
663
qreal y = m_textPos[Name].y() + textLinesCountForName * fontHeight;
664
foreach (const QByteArray& role, m_sortedVisibleRoles) {
665
const TextId textId = roleTextId(role);
666
if (textId == Name) {
670
const QString text = roleText(role, values);
671
m_text[textId].setText(text);
673
qreal requiredWidth = 0;
675
QTextLayout layout(text, option.font);
676
layout.setTextOption(m_text[textId].textOption());
677
layout.beginLayout();
678
QTextLine textLine = layout.createLine();
679
if (textLine.isValid()) {
680
textLine.setLineWidth(maxWidth);
681
requiredWidth = textLine.naturalTextWidth();
682
if (textLine.textLength() < text.length()) {
683
// TODO: QFontMetrics::elidedText() works different regarding the given width
684
// in comparison to QTextLine::setLineWidth(). It might happen that the text does
685
// not get elided although it does not fit into the given width. As workaround
686
// the padding is substracted.
687
const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth - padding);
688
m_text[textId].setText(elidedText);
693
m_textPos[textId] = QPointF(padding, y);
694
m_text[textId].setTextWidth(maxWidth);
696
const QRectF textRect(padding + (maxWidth - requiredWidth) / 2, y, requiredWidth, fontHeight);
697
m_textRect |= textRect;
702
// Add a padding to the text rectangle
703
m_textRect.adjust(-padding, -padding, padding, padding);
706
void KFileItemListWidget::updateCompactLayoutTextCache()
708
// +------+ Name role
709
// | Icon | Additional role 1
710
// +------+ Additional role 2
712
const QHash<QByteArray, QVariant> values = data();
714
const KItemListStyleOption& option = styleOption();
715
const qreal widgetHeight = size().height();
716
const qreal fontHeight = option.fontMetrics.height();
717
const qreal textLinesHeight = qMax(visibleRoles().count(), 1) * fontHeight;
718
const int scaledIconSize = (textLinesHeight < option.iconSize) ? widgetHeight - 2 * option.padding : option.iconSize;
720
qreal maximumRequiredTextWidth = 0;
721
const qreal x = option.padding * 3 + scaledIconSize;
722
qreal y = (widgetHeight - textLinesHeight) / 2;
723
const qreal maxWidth = size().width() - x - option.padding;
724
foreach (const QByteArray& role, m_sortedVisibleRoles) {
725
const TextId textId = roleTextId(role);
727
const QString text = roleText(role, values);
728
m_text[textId].setText(text);
730
qreal requiredWidth = option.fontMetrics.width(text);
731
if (requiredWidth > maxWidth) {
732
requiredWidth = maxWidth;
733
const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth);
734
m_text[textId].setText(elidedText);
737
m_textPos[textId] = QPointF(x, y);
738
m_text[textId].setTextWidth(maxWidth);
740
maximumRequiredTextWidth = qMax(maximumRequiredTextWidth, requiredWidth);
745
m_textRect = QRectF(x - option.padding, 0, maximumRequiredTextWidth + 2 * option.padding, widgetHeight);
748
void KFileItemListWidget::updateDetailsLayoutTextCache()
750
// Precondition: Requires already updated m_expansionArea
751
// to determine the left position.
754
// | Icon | Name role Additional role 1 Additional role 2
756
m_textRect = QRectF();
758
const KItemListStyleOption& option = styleOption();
759
const QHash<QByteArray, QVariant> values = data();
761
const qreal widgetHeight = size().height();
762
const int scaledIconSize = widgetHeight - 2 * option.padding;
763
const int fontHeight = option.fontMetrics.height();
765
const qreal columnPadding = option.padding * 3;
766
qreal firstColumnInc = scaledIconSize;
767
if (m_supportsItemExpanding) {
768
firstColumnInc += (m_expansionArea.left() + m_expansionArea.right() + widgetHeight) / 2;
770
firstColumnInc += option.padding;
773
qreal x = firstColumnInc;
774
const qreal y = qMax(qreal(option.padding), (widgetHeight - fontHeight) / 2);
776
foreach (const QByteArray& role, m_sortedVisibleRoles) {
777
const TextId textId = roleTextId(role);
779
QString text = roleText(role, values);
781
// Elide the text in case it does not fit into the available column-width
782
qreal requiredWidth = option.fontMetrics.width(text);
783
const qreal columnWidth = visibleRolesSizes().value(role, QSizeF(0, 0)).width();
784
qreal availableTextWidth = columnWidth - 2 * columnPadding;
785
if (textId == Name) {
786
availableTextWidth -= firstColumnInc;
789
if (requiredWidth > availableTextWidth) {
790
text = option.fontMetrics.elidedText(text, Qt::ElideRight, availableTextWidth);
791
requiredWidth = option.fontMetrics.width(text);
794
m_text[textId].setText(text);
795
m_textPos[textId] = QPointF(x + columnPadding, y);
800
const qreal textWidth = option.extendedSelectionRegion
801
? size().width() - m_textPos[textId].x()
802
: requiredWidth + 2 * option.padding;
803
m_textRect = QRectF(m_textPos[textId].x() - option.padding, 0,
804
textWidth, size().height());
806
// The column after the name should always be aligned on the same x-position independent
807
// from the expansion-level shown in the name column
812
// The values for the size should be right aligned
813
m_textPos[textId].rx() += columnWidth - requiredWidth - 2 * columnPadding;
822
void KFileItemListWidget::updateAdditionalInfoTextColor()
825
if (m_customTextColor.isValid()) {
826
c1 = m_customTextColor;
827
} else if (isSelected() && m_layout != DetailsLayout) {
828
c1 = styleOption().palette.highlightedText().color();
830
c1 = styleOption().palette.text().color();
833
// For the color of the additional info the inactive text color
834
// is not used as this might lead to unreadable text for some color schemes. Instead
835
// the text color c1 is slightly mixed with the background color.
836
const QColor c2 = styleOption().palette.base().color();
838
const int p2 = 100 - p1;
839
m_additionalInfoTextColor = QColor((c1.red() * p1 + c2.red() * p2) / 100,
840
(c1.green() * p1 + c2.green() * p2) / 100,
841
(c1.blue() * p1 + c2.blue() * p2) / 100);
844
void KFileItemListWidget::drawPixmap(QPainter* painter, const QPixmap& pixmap)
846
if (m_scaledPixmapSize != pixmap.size()) {
847
QPixmap scaledPixmap = pixmap;
848
KPixmapModifier::scale(scaledPixmap, m_scaledPixmapSize);
849
painter->drawPixmap(m_pixmapPos, scaledPixmap);
851
#ifdef KFILEITEMLISTWIDGET_DEBUG
852
painter->setPen(Qt::blue);
853
painter->drawRect(QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize)));
856
painter->drawPixmap(m_pixmapPos, pixmap);
860
void KFileItemListWidget::drawSiblingsInformation(QPainter* painter)
862
const int siblingSize = size().height();
863
const int x = (m_expansionArea.left() + m_expansionArea.right() - siblingSize) / 2;
864
QRect siblingRect(x, 0, siblingSize, siblingSize);
867
bool isItemSibling = true;
869
const QBitArray siblings = siblingsInformation();
870
for (int i = siblings.count() - 1; i >= 0; --i) {
871
option.rect = siblingRect;
872
option.state = siblings.at(i) ? QStyle::State_Sibling : QStyle::State_None;
875
option.state |= QStyle::State_Item;
876
if (m_isExpandable) {
877
option.state |= QStyle::State_Children;
879
if (data()["isExpanded"].toBool()) {
880
option.state |= QStyle::State_Open;
882
isItemSibling = false;
885
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &option, painter);
887
siblingRect.translate(-siblingRect.width(), 0);
891
QPixmap KFileItemListWidget::pixmapForIcon(const QString& name, int size)
893
const KIcon icon(name);
896
if (size <= KIconLoader::SizeSmall) {
897
requestedSize = KIconLoader::SizeSmall;
898
} else if (size <= KIconLoader::SizeSmallMedium) {
899
requestedSize = KIconLoader::SizeSmallMedium;
900
} else if (size <= KIconLoader::SizeMedium) {
901
requestedSize = KIconLoader::SizeMedium;
902
} else if (size <= KIconLoader::SizeLarge) {
903
requestedSize = KIconLoader::SizeLarge;
904
} else if (size <= KIconLoader::SizeHuge) {
905
requestedSize = KIconLoader::SizeHuge;
906
} else if (size <= KIconLoader::SizeEnormous) {
907
requestedSize = KIconLoader::SizeEnormous;
908
} else if (size <= KIconLoader::SizeEnormous * 2) {
909
requestedSize = KIconLoader::SizeEnormous * 2;
911
requestedSize = size;
914
QPixmap pixmap = icon.pixmap(requestedSize, requestedSize);
915
if (requestedSize != size) {
916
KPixmapModifier::scale(pixmap, QSize(size, size));
922
KFileItemListWidget::TextId KFileItemListWidget::roleTextId(const QByteArray& role)
924
static QHash<QByteArray, TextId> rolesHash;
925
if (rolesHash.isEmpty()) {
926
rolesHash.insert("name", Name);
927
rolesHash.insert("size", Size);
928
rolesHash.insert("date", Date);
929
rolesHash.insert("permissions", Permissions);
930
rolesHash.insert("owner", Owner);
931
rolesHash.insert("group", Group);
932
rolesHash.insert("type", Type);
933
rolesHash.insert("destination", Destination);
934
rolesHash.insert("path", Path);
937
return rolesHash.value(role);
940
void KFileItemListWidget::applyCutEffect(QPixmap& pixmap)
942
KIconEffect* effect = KIconLoader::global()->iconEffect();
943
pixmap = effect->apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
946
void KFileItemListWidget::applyHiddenEffect(QPixmap& pixmap)
948
KIconEffect::semiTransparent(pixmap);
72
KFileItemListWidget::KFileItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
73
KStandardItemListWidget(informant, parent)
77
KFileItemListWidget::~KFileItemListWidget()
81
KItemListWidgetInformant* KFileItemListWidget::createInformant()
83
return new KFileItemListWidgetInformant();
86
bool KFileItemListWidget::isRoleRightAligned(const QByteArray& role) const
88
return role == "size";
91
bool KFileItemListWidget::isHidden() const
93
return data().value("text").toString().startsWith(QLatin1Char('.'));
96
QFont KFileItemListWidget::customizedFont(const QFont& baseFont) const
98
// The customized font should be italic if the file is a symbolic link.
100
font.setItalic(data().value("isLink").toBool());
951
104
#include "kfileitemlistwidget.moc"