X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/8d44ebc1487b9dc714b085ee8d3733a187abf8bb..e57f6215659ee36877c7c36c9e3fcba0ba5d03a0:/src/kitemviews/kitemlistheader.cpp diff --git a/src/kitemviews/kitemlistheader.cpp b/src/kitemviews/kitemlistheader.cpp index 96f868aad..97d0cdfbf 100644 --- a/src/kitemviews/kitemlistheader.cpp +++ b/src/kitemviews/kitemlistheader.cpp @@ -1,349 +1,97 @@ -/*************************************************************************** - * Copyright (C) 2011 by Peter Penz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ +/* + * SPDX-FileCopyrightText: 2012 Peter Penz + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ -#include "kitemlistheader_p.h" - -#include -#include -#include "kitemmodelbase.h" - -#include -#include -#include -#include - -#include - -KItemListHeader::KItemListHeader(QGraphicsWidget* parent) : - QGraphicsWidget(parent), - m_model(0), - m_visibleRoles(), - m_visibleRolesWidths(), - m_hoveredRoleIndex(-1), - m_pressedRoleIndex(-1), - m_roleOperation(NoRoleOperation), - m_pressedMousePos() -{ - setAcceptHoverEvents(true); - - QStyleOptionHeader option; - const QSize headerSize = style()->sizeFromContents(QStyle::CT_HeaderSection, &option, QSize()); - resize(0, headerSize.height()); -} +#include "kitemlistheader.h" +#include "kitemlistview.h" +#include "private/kitemlistheaderwidget.h" KItemListHeader::~KItemListHeader() { } -void KItemListHeader::setModel(KItemModelBase* model) +void KItemListHeader::setAutomaticColumnResizing(bool automatic) { - if (m_model == model) { - return; - } - - if (m_model) { - disconnect(m_model, SIGNAL(sortRoleChanged(QByteArray,QByteArray)), - this, SLOT(slotSortRoleChanged(QByteArray,QByteArray))); - disconnect(m_model, SIGNAL(sortOrderChanged(Qt::SortOrder,Qt::SortOrder)), - this, SLOT(slotSortOrderChanged(Qt::SortOrder,Qt::SortOrder))); - } - - m_model = model; - - if (m_model) { - connect(m_model, SIGNAL(sortRoleChanged(QByteArray,QByteArray)), - this, SLOT(slotSortRoleChanged(QByteArray,QByteArray))); - connect(m_model, SIGNAL(sortOrderChanged(Qt::SortOrder,Qt::SortOrder)), - this, SLOT(slotSortOrderChanged(Qt::SortOrder,Qt::SortOrder))); - } -} - -KItemModelBase* KItemListHeader::model() const -{ - return m_model; -} - -void KItemListHeader::setVisibleRoles(const QList& roles) -{ - m_visibleRoles = roles; - update(); -} - -QList KItemListHeader::visibleRoles() const -{ - return m_visibleRoles; -} - -void KItemListHeader::setVisibleRolesWidths(const QHash rolesWidths) -{ - m_visibleRolesWidths = rolesWidths; - - // Assure that no width is smaller than the minimum allowed width - const qreal minWidth = minimumRoleWidth(); - QMutableHashIterator it(m_visibleRolesWidths); - while (it.hasNext()) { - it.next(); - if (it.value() < minWidth) { - m_visibleRolesWidths.insert(it.key(), minWidth); + if (m_headerWidget->automaticColumnResizing() != automatic) { + m_headerWidget->setAutomaticColumnResizing(automatic); + if (automatic) { + m_view->applyAutomaticColumnWidths(); + m_view->doLayout(KItemListView::NoAnimation); } } - - update(); } -QHash KItemListHeader::visibleRolesWidths() const +bool KItemListHeader::automaticColumnResizing() const { - return m_visibleRolesWidths; + return m_headerWidget->automaticColumnResizing(); } -qreal KItemListHeader::minimumRoleWidth() const +void KItemListHeader::setColumnWidth(const QByteArray &role, qreal width) { - QFontMetricsF fontMetrics(font()); - return fontMetrics.height() * 4; -} - -void KItemListHeader::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) -{ - Q_UNUSED(option); - Q_UNUSED(widget); - - if (!m_model) { - return; + if (!m_headerWidget->automaticColumnResizing()) { + m_headerWidget->setColumnWidth(role, width); + m_view->applyColumnWidthsFromHeader(); + m_view->doLayout(KItemListView::NoAnimation); } - - // Draw roles - painter->setFont(font()); - painter->setPen(palette().text().color()); - - qreal x = 0; - int orderIndex = 0; - foreach (const QByteArray& role, m_visibleRoles) { - const qreal roleWidth = m_visibleRolesWidths.value(role); - const QRectF rect(x, 0, roleWidth, size().height()); - paintRole(painter, role, rect, orderIndex); - x += roleWidth; - ++orderIndex; - } - - // Draw background without roles - QStyleOption opt; - opt.init(widget); - opt.rect = QRect(x, 0, size().width() - x, size().height()); - opt.state |= QStyle::State_Horizontal; - style()->drawControl(QStyle::CE_HeaderEmptyArea, &opt, painter); } -void KItemListHeader::mousePressEvent(QGraphicsSceneMouseEvent* event) +qreal KItemListHeader::columnWidth(const QByteArray &role) const { - if (event->button() & Qt::LeftButton) { - updatePressedRoleIndex(event->pos()); - m_pressedMousePos = event->pos(); - m_roleOperation = isAboveRoleGrip(m_pressedMousePos, m_pressedRoleIndex) ? - ResizeRoleOperation : NoRoleOperation; - event->accept(); - } else { - event->ignore(); - } + return m_headerWidget->columnWidth(role); } -void KItemListHeader::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) +void KItemListHeader::setColumnWidths(const QHash &columnWidths) { - QGraphicsWidget::mouseReleaseEvent(event); - - if (m_pressedRoleIndex == -1) { - return; - } - - if (m_roleOperation == NoRoleOperation) { - // Only a click has been done and no moving or resizing has been started - const QByteArray sortRole = m_model->sortRole(); - const int sortRoleIndex = m_visibleRoles.indexOf(sortRole); - if (m_pressedRoleIndex == sortRoleIndex) { - // Toggle the sort order - const Qt::SortOrder toggled = (m_model->sortOrder() == Qt::AscendingOrder) ? - Qt::DescendingOrder : Qt::AscendingOrder; - m_model->setSortOrder(toggled); - } else { - // Change the sort role - const QByteArray sortRole = m_visibleRoles.at(m_pressedRoleIndex); - m_model->setSortRole(sortRole); + if (!m_headerWidget->automaticColumnResizing()) { + const auto visibleRoles = m_view->visibleRoles(); + for (const QByteArray &role : visibleRoles) { + const qreal width = columnWidths.value(role); + m_headerWidget->setColumnWidth(role, width); } - } - m_pressedRoleIndex = -1; - m_roleOperation = NoRoleOperation; - update(); -} - -void KItemListHeader::mouseMoveEvent(QGraphicsSceneMouseEvent* event) -{ - QGraphicsWidget::mouseMoveEvent(event); - - if (m_roleOperation == ResizeRoleOperation) { - const QByteArray pressedRole = m_visibleRoles.at(m_pressedRoleIndex); - - qreal previousWidth = m_visibleRolesWidths.value(pressedRole); - qreal currentWidth = previousWidth; - currentWidth += event->pos().x() - event->lastPos().x(); - currentWidth = qMax(minimumRoleWidth(), currentWidth); - - m_visibleRolesWidths.insert(pressedRole, currentWidth); - update(); - - emit visibleRoleWidthChanged(pressedRole, currentWidth, previousWidth); - } else if ((event->pos() - m_pressedMousePos).manhattanLength() >= QApplication::startDragDistance()) { - kDebug() << "Moving of role not supported yet"; - m_roleOperation = MoveRoleOperation; - } -} - -void KItemListHeader::hoverEnterEvent(QGraphicsSceneHoverEvent* event) -{ - QGraphicsWidget::hoverEnterEvent(event); - updateHoveredRoleIndex(event->pos()); -} - -void KItemListHeader::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) -{ - QGraphicsWidget::hoverLeaveEvent(event); - if (m_hoveredRoleIndex != -1) { - m_hoveredRoleIndex = -1; - update(); - } -} - -void KItemListHeader::hoverMoveEvent(QGraphicsSceneHoverEvent* event) -{ - QGraphicsWidget::hoverMoveEvent(event); - - const QPointF& pos = event->pos(); - updateHoveredRoleIndex(pos); - if (m_hoveredRoleIndex >= 0 && isAboveRoleGrip(pos, m_hoveredRoleIndex)) { - setCursor(Qt::SplitHCursor); - } else { - unsetCursor(); + m_view->applyColumnWidthsFromHeader(); + m_view->doLayout(KItemListView::NoAnimation); } } -void KItemListHeader::slotSortRoleChanged(const QByteArray& current, const QByteArray& previous) -{ - Q_UNUSED(current); - Q_UNUSED(previous); - update(); -} - -void KItemListHeader::slotSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous) +qreal KItemListHeader::preferredColumnWidth(const QByteArray &role) const { - Q_UNUSED(current); - Q_UNUSED(previous); - update(); -} - -void KItemListHeader::paintRole(QPainter* painter, - const QByteArray& role, - const QRectF& rect, - int orderIndex) -{ - // The following code is based on the code from QHeaderView::paintSection(). - // Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). - QStyleOptionHeader option; - option.section = orderIndex; - option.state = QStyle::State_None | QStyle::State_Raised | QStyle::State_Horizontal; - if (isEnabled()) { - option.state |= QStyle::State_Enabled; - } - if (window() && window()->isActiveWindow()) { - option.state |= QStyle::State_Active; - } - if (m_hoveredRoleIndex == orderIndex) { - option.state |= QStyle::State_MouseOver; - } - if (m_pressedRoleIndex == orderIndex) { - option.state |= QStyle::State_Sunken; - } - if (m_model->sortRole() == role) { - option.sortIndicator = (m_model->sortOrder() == Qt::AscendingOrder) ? - QStyleOptionHeader::SortDown : QStyleOptionHeader::SortUp; - } - option.rect = rect.toRect(); - - if (m_visibleRoles.count() == 1) { - option.position = QStyleOptionHeader::OnlyOneSection; - } else if (orderIndex == 0) { - option.position = QStyleOptionHeader::Beginning; - } else if (orderIndex == m_visibleRoles.count() - 1) { - option.position = QStyleOptionHeader::End; - } else { - option.position = QStyleOptionHeader::Middle; - } - - option.orientation = Qt::Horizontal; - option.selectedPosition = QStyleOptionHeader::NotAdjacent; - option.text = m_model->roleDescription(role); - - style()->drawControl(QStyle::CE_Header, &option, painter); + return m_headerWidget->preferredColumnWidth(role); } -void KItemListHeader::updatePressedRoleIndex(const QPointF& pos) +void KItemListHeader::setSidePadding(qreal leftPaddingWidth, qreal rightPaddingWidth) { - const int pressedIndex = roleIndexAt(pos); - if (m_pressedRoleIndex != pressedIndex) { - m_pressedRoleIndex = pressedIndex; - update(); + if (m_headerWidget->leftPadding() != leftPaddingWidth || m_headerWidget->rightPadding() != rightPaddingWidth) { + m_headerWidget->setSidePadding(leftPaddingWidth, rightPaddingWidth); + if (m_headerWidget->automaticColumnResizing()) { + m_view->applyAutomaticColumnWidths(); + } + m_view->doLayout(KItemListView::NoAnimation); } } -void KItemListHeader::updateHoveredRoleIndex(const QPointF& pos) +qreal KItemListHeader::leftPadding() const { - const int hoverIndex = roleIndexAt(pos); - if (m_hoveredRoleIndex != hoverIndex) { - m_hoveredRoleIndex = hoverIndex; - update(); - } + return m_headerWidget->leftPadding(); } -int KItemListHeader::roleIndexAt(const QPointF& pos) const +qreal KItemListHeader::rightPadding() const { - int index = -1; - - qreal x = 0; - foreach (const QByteArray& role, m_visibleRoles) { - ++index; - x += m_visibleRolesWidths.value(role); - if (pos.x() <= x) { - break; - } - } - - return index; + return m_headerWidget->rightPadding(); } -bool KItemListHeader::isAboveRoleGrip(const QPointF& pos, int roleIndex) const +KItemListHeader::KItemListHeader(KItemListView *listView) + : QObject(listView) + , m_view(listView) { - qreal x = 0; - for (int i = 0; i <= roleIndex; ++i) { - const QByteArray role = m_visibleRoles.at(i); - x += m_visibleRolesWidths.value(role); - } + m_headerWidget = m_view->m_headerWidget; + Q_ASSERT(m_headerWidget); - const int grip = style()->pixelMetric(QStyle::PM_HeaderGripMargin); - return pos.x() >= (x - grip) && pos.x() <= x; + connect(m_headerWidget, &KItemListHeaderWidget::columnWidthChanged, this, &KItemListHeader::columnWidthChanged); + connect(m_headerWidget, &KItemListHeaderWidget::columnWidthChangeFinished, this, &KItemListHeader::columnWidthChangeFinished); + connect(m_headerWidget, &KItemListHeaderWidget::sidePaddingChanged, this, &KItemListHeader::sidePaddingChanged); } -#include "kitemlistheader_p.moc" +#include "moc_kitemlistheader.cpp"