X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/f23e9496f303995557b744c03178f5dbd9b35016..ebfcb5e19b345a0fbb2425f537232f45d3b3d62a:/src/kitemviews/kitemlistwidget.cpp diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 3f08d9f7a..6a7111ad7 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -25,38 +25,62 @@ #include "kitemlistview.h" #include "kitemmodelbase.h" +#include "private/kitemlistselectiontoggle.h" + #include +#include +#include #include #include -#include +#include -KItemListWidget::KItemListWidget(QGraphicsItem* parent) : +KItemListWidgetInformant::KItemListWidgetInformant() +{ +} + +KItemListWidgetInformant::~KItemListWidgetInformant() +{ +} + +KItemListWidget::KItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) : QGraphicsWidget(parent, 0), + m_informant(informant), m_index(-1), + m_selected(false), + m_current(false), + m_hovered(false), + m_alternateBackground(false), + m_enabledSelectionToggle(false), m_data(), m_visibleRoles(), - m_visibleRolesSizes(), + m_columnWidths(), m_styleOption(), + m_siblingsInfo(), m_hoverOpacity(0), m_hoverCache(0), - m_hoverAnimation(0) + m_hoverAnimation(0), + m_selectionToggle(0), + m_editedRole() { } KItemListWidget::~KItemListWidget() { - clearCache(); + clearHoverCache(); } void KItemListWidget::setIndex(int index) { if (m_index != index) { + delete m_selectionToggle; + m_selectionToggle = 0; + if (m_hoverAnimation) { m_hoverAnimation->stop(); m_hoverOpacity = 0; } - clearCache(); + clearHoverCache(); m_index = index; } @@ -70,7 +94,7 @@ int KItemListWidget::index() const void KItemListWidget::setData(const QHash& data, const QSet& roles) { - clearCache(); + clearHoverCache(); if (roles.isEmpty()) { m_data = data; dataChanged(m_data); @@ -80,6 +104,7 @@ void KItemListWidget::setData(const QHash& data, } dataChanged(m_data, roles); } + update(); } QHash KItemListWidget::data() const @@ -90,106 +115,239 @@ QHash KItemListWidget::data() const void KItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { Q_UNUSED(option); - if (m_hoverOpacity <= 0.0) { - return; - } - const QRect hoverBounds = hoverBoundingRect().toRect(); - if (!m_hoverCache) { - m_hoverCache = new QPixmap(hoverBounds.size()); - m_hoverCache->fill(Qt::transparent); + if (m_alternateBackground) { + const QColor backgroundColor = m_styleOption.palette.color(QPalette::AlternateBase); + const QRectF backgroundRect(0, 0, size().width(), size().height()); + painter->fillRect(backgroundRect, backgroundColor); + } - QPainter pixmapPainter(m_hoverCache); + if (m_selected && m_editedRole.isEmpty()) { + const QStyle::State activeState(isActiveWindow() ? QStyle::State_Active : 0); + drawItemStyleOption(painter, widget, activeState | + QStyle::State_Enabled | + QStyle::State_Selected | + QStyle::State_Item); + } - QStyleOptionViewItemV4 viewItemOption; - viewItemOption.initFrom(widget); - viewItemOption.rect = QRect(0, 0, hoverBounds.width(), hoverBounds.height()); - viewItemOption.state = QStyle::State_Enabled | QStyle::State_MouseOver; - viewItemOption.viewItemPosition = QStyleOptionViewItemV4::OnlyOne; + if (m_current && m_editedRole.isEmpty()) { + QStyleOptionFocusRect focusRectOption; + focusRectOption.initFrom(widget); + focusRectOption.rect = textFocusRect().toRect(); + focusRectOption.state = QStyle::State_Enabled | QStyle::State_Item | QStyle::State_KeyboardFocusChange; + if (m_selected) { + focusRectOption.state |= QStyle::State_Selected; + } - widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, &pixmapPainter, widget); + style()->drawPrimitive(QStyle::PE_FrameFocusRect, &focusRectOption, painter, widget); } - const qreal opacity = painter->opacity(); - painter->setOpacity(m_hoverOpacity * opacity); - painter->drawPixmap(hoverBounds.topLeft(), *m_hoverCache); - painter->setOpacity(opacity); + if (m_hoverOpacity > 0.0) { + if (!m_hoverCache) { + // Initialize the m_hoverCache pixmap to improve the drawing performance + // when fading the hover background + m_hoverCache = new QPixmap(size().toSize()); + m_hoverCache->fill(Qt::transparent); + + QPainter pixmapPainter(m_hoverCache); + const QStyle::State activeState(isActiveWindow() ? QStyle::State_Active : 0); + drawItemStyleOption(&pixmapPainter, widget, activeState | + QStyle::State_Enabled | + QStyle::State_MouseOver | + QStyle::State_Item); + } + + const qreal opacity = painter->opacity(); + painter->setOpacity(m_hoverOpacity * opacity); + painter->drawPixmap(0, 0, *m_hoverCache); + painter->setOpacity(opacity); + } } -void KItemListWidget::setVisibleRoles(const QHash& roles) +void KItemListWidget::setVisibleRoles(const QList& roles) { - const QHash previousRoles = m_visibleRoles; + const QList previousRoles = m_visibleRoles; m_visibleRoles = roles; + visibleRolesChanged(roles, previousRoles); + update(); } -QHash KItemListWidget::visibleRoles() const +QList KItemListWidget::visibleRoles() const { return m_visibleRoles; } -void KItemListWidget::setVisibleRolesSizes(const QHash rolesSizes) + +void KItemListWidget::setColumnWidth(const QByteArray& role, qreal width) { - const QHash previousRolesSizes = m_visibleRolesSizes; - m_visibleRolesSizes = rolesSizes; - visibleRolesSizesChanged(rolesSizes, previousRolesSizes); + if (m_columnWidths.value(role) != width) { + const qreal previousWidth = width; + m_columnWidths.insert(role, width); + columnWidthChanged(role, width, previousWidth); + update(); + } } -QHash KItemListWidget::visibleRolesSizes() const +qreal KItemListWidget::columnWidth(const QByteArray& role) const { - return m_visibleRolesSizes; + return m_columnWidths.value(role); } void KItemListWidget::setStyleOption(const KItemListStyleOption& option) { const KItemListStyleOption previous = m_styleOption; - if (m_index >= 0) { - clearCache(); - - const bool wasHovered = (previous.state & QStyle::State_MouseOver); - m_styleOption = option; - const bool isHovered = (m_styleOption.state & QStyle::State_MouseOver); - - if (wasHovered != isHovered) { - // The hovering state has been changed. Assure that a fade-animation - // is done to the new state. - if (!m_hoverAnimation) { - m_hoverAnimation = new QPropertyAnimation(this, "hoverOpacity", this); - m_hoverAnimation->setDuration(200); - } - m_hoverAnimation->stop(); + clearHoverCache(); + m_styleOption = option; + + styleOptionChanged(option, previous); + update(); +} - if (!wasHovered && isHovered) { - m_hoverAnimation->setEndValue(1.0); - } else { - Q_ASSERT(wasHovered && !isHovered); - m_hoverAnimation->setEndValue(0.0); - } +const KItemListStyleOption& KItemListWidget::styleOption() const +{ + return m_styleOption; +} - m_hoverAnimation->start(); +void KItemListWidget::setSelected(bool selected) +{ + if (m_selected != selected) { + m_selected = selected; + if (m_selectionToggle) { + m_selectionToggle->setChecked(selected); + } + selectedChanged(selected); + update(); + } +} + +bool KItemListWidget::isSelected() const +{ + return m_selected; +} + +void KItemListWidget::setCurrent(bool current) +{ + if (m_current != current) { + m_current = current; + currentChanged(current); + update(); + } +} + +bool KItemListWidget::isCurrent() const +{ + return m_current; +} + +void KItemListWidget::setHovered(bool hovered) +{ + if (hovered == m_hovered) { + return; + } + + m_hovered = hovered; + + if (!m_hoverAnimation) { + m_hoverAnimation = new QPropertyAnimation(this, "hoverOpacity", this); + const int duration = (KGlobalSettings::graphicEffectsLevel() == KGlobalSettings::NoEffects) ? 1 : 200; + m_hoverAnimation->setDuration(duration); + connect(m_hoverAnimation, SIGNAL(finished()), this, SLOT(slotHoverAnimationFinished())); + } + m_hoverAnimation->stop(); + + if (hovered) { + const qreal startValue = qMax(hoverOpacity(), qreal(0.1)); + m_hoverAnimation->setStartValue(startValue); + m_hoverAnimation->setEndValue(1.0); + if (m_enabledSelectionToggle && !(QApplication::mouseButtons() & Qt::LeftButton)) { + initializeSelectionToggle(); } } else { - m_styleOption = option; + m_hoverAnimation->setStartValue(hoverOpacity()); + m_hoverAnimation->setEndValue(0.0); } - styleOptionChanged(option, previous); + m_hoverAnimation->start(); + + hoveredChanged(hovered); + update(); } -const KItemListStyleOption& KItemListWidget::styleOption() const +bool KItemListWidget::isHovered() const { - return m_styleOption; + return m_hovered; +} + +void KItemListWidget::setAlternateBackground(bool enable) +{ + if (m_alternateBackground != enable) { + m_alternateBackground = enable; + alternateBackgroundChanged(enable); + update(); + } +} + +bool KItemListWidget::alternateBackground() const +{ + return m_alternateBackground; +} + +void KItemListWidget::setEnabledSelectionToggle(bool enable) +{ + if (m_enabledSelectionToggle != enable) { + m_enabledSelectionToggle = enable; + update(); + } +} + +bool KItemListWidget::enabledSelectionToggle() const +{ + return m_enabledSelectionToggle; +} + +void KItemListWidget::setSiblingsInformation(const QBitArray& siblings) +{ + const QBitArray previous = m_siblingsInfo; + m_siblingsInfo = siblings; + siblingsInformationChanged(m_siblingsInfo, previous); + update(); +} + +QBitArray KItemListWidget::siblingsInformation() const +{ + return m_siblingsInfo; +} + +void KItemListWidget::setEditedRole(const QByteArray& role) +{ + if (m_editedRole != role) { + const QByteArray previous = m_editedRole; + m_editedRole = role; + editedRoleChanged(role, previous); + } +} + +QByteArray KItemListWidget::editedRole() const +{ + return m_editedRole; } bool KItemListWidget::contains(const QPointF& point) const { - return hoverBoundingRect().contains(point) || + if (!QGraphicsWidget::contains(point)) { + return false; + } + + return iconRect().contains(point) || + textRect().contains(point) || expansionToggleRect().contains(point) || selectionToggleRect().contains(point); } -QRectF KItemListWidget::hoverBoundingRect() const +QRectF KItemListWidget::textFocusRect() const { - return QRectF(QPointF(0, 0), size()); + return textRect(); } QRectF KItemListWidget::selectionToggleRect() const @@ -202,28 +360,52 @@ QRectF KItemListWidget::expansionToggleRect() const return QRectF(); } +QPixmap KItemListWidget::createDragPixmap(const QStyleOptionGraphicsItem* option, + QWidget* widget) +{ + QPixmap pixmap(size().toSize()); + pixmap.fill(Qt::transparent); + + QPainter painter(&pixmap); + + const bool oldAlternateBackground = m_alternateBackground; + const bool wasSelected = m_selected; + const bool wasHovered = m_hovered; + + setAlternateBackground(false); + setSelected(false); + setHovered(false); + + paint(&painter, option, widget); + + setAlternateBackground(oldAlternateBackground); + setSelected(wasSelected); + setHovered(wasHovered); + + return pixmap; +} + void KItemListWidget::dataChanged(const QHash& current, const QSet& roles) { Q_UNUSED(current); Q_UNUSED(roles); - update(); } -void KItemListWidget::visibleRolesChanged(const QHash& current, - const QHash& previous) +void KItemListWidget::visibleRolesChanged(const QList& current, + const QList& previous) { Q_UNUSED(current); Q_UNUSED(previous); - update(); } -void KItemListWidget::visibleRolesSizesChanged(const QHash& current, - const QHash& previous) +void KItemListWidget::columnWidthChanged(const QByteArray& role, + qreal current, + qreal previous) { + Q_UNUSED(role); Q_UNUSED(current); Q_UNUSED(previous); - update(); } void KItemListWidget::styleOptionChanged(const KItemListStyleOption& current, @@ -231,13 +413,44 @@ void KItemListWidget::styleOptionChanged(const KItemListStyleOption& current, { Q_UNUSED(current); Q_UNUSED(previous); - update(); +} + +void KItemListWidget::currentChanged(bool current) +{ + Q_UNUSED(current); +} + +void KItemListWidget::selectedChanged(bool selected) +{ + Q_UNUSED(selected); +} + +void KItemListWidget::hoveredChanged(bool hovered) +{ + Q_UNUSED(hovered); +} + +void KItemListWidget::alternateBackgroundChanged(bool enabled) +{ + Q_UNUSED(enabled); +} + +void KItemListWidget::siblingsInformationChanged(const QBitArray& current, const QBitArray& previous) +{ + Q_UNUSED(current); + Q_UNUSED(previous); +} + +void KItemListWidget::editedRoleChanged(const QByteArray& current, const QByteArray& previous) +{ + Q_UNUSED(current); + Q_UNUSED(previous); } void KItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event) { QGraphicsWidget::resizeEvent(event); - clearCache(); + clearHoverCache(); } qreal KItemListWidget::hoverOpacity() const @@ -245,16 +458,59 @@ qreal KItemListWidget::hoverOpacity() const return m_hoverOpacity; } +void KItemListWidget::slotHoverAnimationFinished() +{ + if (!m_hovered) { + delete m_selectionToggle; + m_selectionToggle = 0; + } +} + +void KItemListWidget::initializeSelectionToggle() +{ + Q_ASSERT(m_enabledSelectionToggle); + + if (!m_selectionToggle) { + m_selectionToggle = new KItemListSelectionToggle(this); + } + + const QRectF toggleRect = selectionToggleRect(); + m_selectionToggle->setPos(toggleRect.topLeft()); + m_selectionToggle->resize(toggleRect.size()); + + m_selectionToggle->setChecked(isSelected()); +} + void KItemListWidget::setHoverOpacity(qreal opacity) { m_hoverOpacity = opacity; + if (m_selectionToggle) { + m_selectionToggle->setOpacity(opacity); + } + + if (m_hoverOpacity <= 0.0) { + delete m_hoverCache; + m_hoverCache = 0; + } + update(); } -void KItemListWidget::clearCache() +void KItemListWidget::clearHoverCache() { delete m_hoverCache; m_hoverCache = 0; } +void KItemListWidget::drawItemStyleOption(QPainter* painter, QWidget* widget, QStyle::State styleState) +{ + QStyleOptionViewItemV4 viewItemOption; + viewItemOption.initFrom(widget); + viewItemOption.state = styleState; + viewItemOption.viewItemPosition = QStyleOptionViewItemV4::OnlyOne; + viewItemOption.showDecorationSelected = true; + viewItemOption.rect = textRect().toRect(); + widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, painter, widget); +} + #include "kitemlistwidget.moc"