-#include <QFontMetricsF>
-#include <QGraphicsSceneResizeEvent>
-#include <QPainter>
-#include <QStyleOption>
-#include <QTextLayout>
-#include <QTextLine>
-
-//#define KFILEITEMLISTWIDGET_DEBUG
-
-KFileItemListWidget::KFileItemListWidget(QGraphicsItem* parent) :
- KItemListWidget(parent),
- m_isDir(false),
- m_dirtyLayout(true),
- m_dirtyContent(true),
- m_dirtyContentRoles(),
- m_layout(IconsLayout),
- m_pixmapPos(),
- m_pixmap(),
- m_scaledPixmapSize(),
- m_hoverPixmapRect(),
- m_hoverPixmap(),
- m_textPos(),
- m_text(),
- m_textsBoundingRect(),
- m_sortedVisibleRoles(),
- m_expansionArea(),
- m_additionalInfoTextColor()
-{
- for (int i = 0; i < TextIdCount; ++i) {
- m_text[i].setTextFormat(Qt::PlainText);
- m_text[i].setPerformanceHint(QStaticText::AggressiveCaching);
- }
-}
-
-KFileItemListWidget::~KFileItemListWidget()
-{
-}
-
-void KFileItemListWidget::setLayout(Layout layout)
-{
- if (m_layout != layout) {
- m_layout = layout;
- m_dirtyLayout = true;
- update();
- }
-}
-
-KFileItemListWidget::Layout KFileItemListWidget::layout() const
-{
- return m_layout;
-}
-
-void KFileItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
-{
- KItemListWidget::paint(painter, option, widget);
-
- painter->setRenderHint(QPainter::Antialiasing);
-
- if (m_dirtyContent || m_dirtyLayout) {
- const_cast<KFileItemListWidget*>(this)->updateCache();
- }
-
- // Draw expansion toggle '>' or 'V'
- if (m_isDir && !m_expansionArea.isEmpty()) {
- QStyleOption arrowOption;
- arrowOption.rect = m_expansionArea.toRect();
- const QStyle::PrimitiveElement arrow = data()["isExpanded"].toBool()
- ? QStyle::PE_IndicatorArrowDown : QStyle::PE_IndicatorArrowRight;
- style()->drawPrimitive(arrow, &arrowOption, painter);
- }
-
- const KItemListStyleOption& itemListStyleOption = styleOption();
- if (isHovered()) {
- // Blend the unhovered and hovered pixmap if the hovering
- // animation is ongoing
- if (hoverOpacity() < 1.0) {
- drawPixmap(painter, m_pixmap);
- }
-
- const qreal opacity = painter->opacity();
- painter->setOpacity(hoverOpacity() * opacity);
- drawPixmap(painter, m_hoverPixmap);
-
- // Draw the hover background for the text
- QRectF textsBoundingRect = m_textsBoundingRect;
- const qreal marginDiff = itemListStyleOption.margin / 2;
- textsBoundingRect.adjust(marginDiff, marginDiff, -marginDiff, -marginDiff);
- painter->setOpacity(hoverOpacity() * opacity * 0.1);
- painter->setPen(Qt::NoPen);
- painter->setBrush(itemListStyleOption.palette.text());
- painter->drawRoundedRect(textsBoundingRect, 4, 4);
-
- painter->setOpacity(opacity);
- } else {
- drawPixmap(painter, m_pixmap);
- }
-
- if (isCurrent()) {
- drawFocusIndicator(painter);
- }
-
- painter->setFont(itemListStyleOption.font);
- painter->setPen(itemListStyleOption.palette.text().color());
- painter->drawStaticText(m_textPos[Name], m_text[Name]);
-
- painter->setPen(m_additionalInfoTextColor);
- painter->setFont(itemListStyleOption.font);
- for (int i = Name + 1; i < TextIdCount; ++i) {
- painter->drawStaticText(m_textPos[i], m_text[i]);
- }
-
-#ifdef KFILEITEMLISTWIDGET_DEBUG
- painter->setPen(Qt::red);
- painter->setBrush(Qt::NoBrush);
- painter->drawText(QPointF(0, itemListStyleOption.fontMetrics.height()), QString::number(index()));
- painter->drawRect(rect());
-#endif
-}
-
-bool KFileItemListWidget::contains(const QPointF& point) const
-{
- return KItemListWidget::contains(point) || m_textsBoundingRect.contains(point);
-}
-
-QRectF KFileItemListWidget::hoverBoundingRect() const
-{
- QRectF bounds = m_hoverPixmapRect;
- const qreal margin = styleOption().margin;
- bounds.adjust(-margin, -margin, margin, margin);
- return bounds;
-}
-
-QRectF KFileItemListWidget::expansionToggleRect() const
-{
- return m_isDir ? m_expansionArea : QRectF();
-}
-
-void KFileItemListWidget::dataChanged(const QHash<QByteArray, QVariant>& current,
- const QSet<QByteArray>& roles)
-{
- KItemListWidget::dataChanged(current, roles);
- m_dirtyContent = true;
-
- QSet<QByteArray> dirtyRoles;
- if (roles.isEmpty()) {
- dirtyRoles = visibleRoles().keys().toSet();
- dirtyRoles.insert("iconPixmap");
- dirtyRoles.insert("iconName");
- } else {
- dirtyRoles = roles;
- }
-
- QSetIterator<QByteArray> it(dirtyRoles);
- while (it.hasNext()) {
- const QByteArray& role = it.next();
- m_dirtyContentRoles.insert(role);
- }
-}
-
-void KFileItemListWidget::visibleRolesChanged(const QHash<QByteArray, int>& current,
- const QHash<QByteArray, int>& previous)
-{
- KItemListWidget::visibleRolesChanged(current, previous);
- m_dirtyLayout = true;
-
- // Cache the roles sorted into m_sortedVisibleRoles:
- const int visibleRolesCount = current.count();
- m_sortedVisibleRoles.clear();
- m_sortedVisibleRoles.reserve(visibleRolesCount);
- for (int i = 0; i < visibleRolesCount; ++i) {
- m_sortedVisibleRoles.append(QByteArray());
- }
-
- QHashIterator<QByteArray, int> it(current);
- while (it.hasNext()) {
- it.next();
-
- const int index = it.value();
- if (index < 0 || index >= visibleRolesCount || !m_sortedVisibleRoles.at(index).isEmpty()) {
- kWarning() << "The visible roles have an invalid sort order.";
- break;
- }
-
- const QByteArray& role = it.key();
- m_sortedVisibleRoles[index] = role;
- }
-}
-
-void KFileItemListWidget::visibleRolesSizesChanged(const QHash<QByteArray, QSizeF>& current,
- const QHash<QByteArray, QSizeF>& previous)
-{
- KItemListWidget::visibleRolesSizesChanged(current, previous);
- m_dirtyLayout = true;
-}
-
-void KFileItemListWidget::styleOptionChanged(const KItemListStyleOption& current,
- const KItemListStyleOption& previous)
-{
- KItemListWidget::styleOptionChanged(current, previous);
-
- // For the color of the additional info the inactive text color
- // is not used as this might lead to unreadable text for some color schemes. Instead
- // the text color is slightly mixed with the background color.
- const QColor c1 = current.palette.text().color();
- const QColor c2 = current.palette.background().color();
- const int p1 = 70;
- const int p2 = 100 - p1;
- m_additionalInfoTextColor = QColor((c1.red() * p1 + c2.red() * p2) / 100,
- (c1.green() * p1 + c2.green() * p2) / 100,
- (c1.blue() * p1 + c2.blue() * p2) / 100);
-
- m_dirtyLayout = true;
-}
-
-void KFileItemListWidget::hoveredChanged(bool hovered)