diff --git a/src/filewidgets/kdiroperatordetailview.cpp b/src/filewidgets/kdiroperatordetailview.cpp index 192b3817..e987d8c5 100644 --- a/src/filewidgets/kdiroperatordetailview.cpp +++ b/src/filewidgets/kdiroperatordetailview.cpp @@ -1,139 +1,145 @@ /***************************************************************************** * Copyright (C) 2007 by Peter Penz * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License version 2 as published by the Free Software Foundation. * * * * This library 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 * * Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public License * * along with this library; see the file COPYING.LIB. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * *****************************************************************************/ #include "kdiroperatordetailview_p.h" #include #include #include #include #include #include #include #include #include KDirOperatorDetailView::KDirOperatorDetailView(QWidget *parent) : QTreeView(parent), m_hideDetailColumns(false) { setRootIsDecorated(false); setSortingEnabled(true); setUniformRowHeights(true); setDragDropMode(QListView::DragOnly); setSelectionBehavior(QAbstractItemView::SelectRows); setEditTriggers(QAbstractItemView::NoEditTriggers); setVerticalScrollMode(QListView::ScrollPerPixel); setHorizontalScrollMode(QListView::ScrollPerPixel); + + const QFontMetrics metrics(viewport()->font()); + const int singleStep = metrics.height() * QApplication::wheelScrollLines(); + + verticalScrollBar()->setSingleStep(singleStep); + horizontalScrollBar()->setSingleStep(singleStep); } KDirOperatorDetailView::~KDirOperatorDetailView() { } bool KDirOperatorDetailView::setViewMode(KFile::FileView viewMode) { bool tree = false; if (KFile::isDetailView(viewMode)) { m_hideDetailColumns = false; setAlternatingRowColors(true); } else if (KFile::isTreeView(viewMode)) { m_hideDetailColumns = true; setAlternatingRowColors(false); tree = true; } else if (KFile::isDetailTreeView(viewMode)) { m_hideDetailColumns = false; setAlternatingRowColors(true); tree = true; } else { return false; } setRootIsDecorated(tree); setItemsExpandable(tree); // This allows to have a horizontal scrollbar in case this view is used as // a plain treeview instead of cutting off filenames, especially useful when // using KDirOperator in horizontally limited parts of an app. if (tree && m_hideDetailColumns) { header()->setSectionResizeMode(QHeaderView::ResizeToContents); } else { header()->setSectionResizeMode(QHeaderView::Interactive); } return true; } QStyleOptionViewItem KDirOperatorDetailView::viewOptions() const { QStyleOptionViewItem viewOptions = QTreeView::viewOptions(); viewOptions.textElideMode = Qt::ElideMiddle; return viewOptions; } bool KDirOperatorDetailView::event(QEvent *event) { if (event->type() == QEvent::Polish) { QHeaderView *headerView = header(); headerView->setSectionResizeMode(0, QHeaderView::Stretch); headerView->setSectionResizeMode(1, QHeaderView::ResizeToContents); headerView->setSectionResizeMode(2, QHeaderView::ResizeToContents); headerView->setStretchLastSection(false); headerView->setSectionsMovable(false); setColumnHidden(KDirModel::Size, m_hideDetailColumns); setColumnHidden(KDirModel::ModifiedTime, m_hideDetailColumns); hideColumn(KDirModel::Type); hideColumn(KDirModel::Permissions); hideColumn(KDirModel::Owner); hideColumn(KDirModel::Group); } else if (event->type() == QEvent::UpdateRequest) { // A wheel movement will scroll 4 items if (model()->rowCount()) { verticalScrollBar()->setSingleStep((sizeHintForRow(0) / 3) * 4); } } return QTreeView::event(event); } void KDirOperatorDetailView::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasUrls()) { event->acceptProposedAction(); } } void KDirOperatorDetailView::mousePressEvent(QMouseEvent *event) { QTreeView::mousePressEvent(event); const QModelIndex index = indexAt(event->pos()); if (!index.isValid() || (index.column() != KDirModel::Name)) { const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); if (!(modifiers & Qt::ShiftModifier) && !(modifiers & Qt::ControlModifier)) { clearSelection(); } } } void KDirOperatorDetailView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { QTreeView::currentChanged(current, previous); } diff --git a/src/filewidgets/kdiroperatoriconview.cpp b/src/filewidgets/kdiroperatoriconview.cpp index e9ad0760..92d38c08 100644 --- a/src/filewidgets/kdiroperatoriconview.cpp +++ b/src/filewidgets/kdiroperatoriconview.cpp @@ -1,162 +1,168 @@ /***************************************************************************** * Copyright (C) 2007 by Peter Penz * * Copyright (C) 2019 by Méven Car * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License version 2 as published by the Free Software Foundation. * * * * This library 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 * * Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public License * * along with this library; see the file COPYING.LIB. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * *****************************************************************************/ #include "kdiroperatoriconview_p.h" #include #include #include #include #include #include KDirOperatorIconView::KDirOperatorIconView(QWidget *parent, QStyleOptionViewItem::Position aDecorationPosition) : QListView(parent) { setViewMode(QListView::IconMode); setResizeMode(QListView::Adjust); setSpacing(0); setMovement(QListView::Static); setDragDropMode(QListView::DragOnly); setVerticalScrollMode(QListView::ScrollPerPixel); setHorizontalScrollMode(QListView::ScrollPerPixel); setEditTriggers(QAbstractItemView::NoEditTriggers); setWordWrap(true); setIconSize(QSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall)); decorationPosition = aDecorationPosition; + const QFontMetrics metrics(viewport()->font()); + const int singleStep = metrics.height() * QApplication::wheelScrollLines(); + + verticalScrollBar()->setSingleStep(singleStep); + horizontalScrollBar()->setSingleStep(singleStep); + updateLayout(); connect(this, &QListView::iconSizeChanged, this, &KDirOperatorIconView::updateLayout); } KDirOperatorIconView::~KDirOperatorIconView() { } void KDirOperatorIconView::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); updateLayout(); } QStyleOptionViewItem KDirOperatorIconView::viewOptions() const { QStyleOptionViewItem viewOptions = QListView::viewOptions(); viewOptions.showDecorationSelected = true; viewOptions.textElideMode = Qt::ElideMiddle; viewOptions.decorationPosition = decorationPosition; if (viewOptions.decorationPosition == QStyleOptionViewItem::Left) { viewOptions.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter; } else { viewOptions.displayAlignment = Qt::AlignCenter; } return viewOptions; } void KDirOperatorIconView::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasUrls()) { event->acceptProposedAction(); } } void KDirOperatorIconView::mousePressEvent(QMouseEvent *event) { if (!indexAt(event->pos()).isValid()) { const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); if (!(modifiers & Qt::ShiftModifier) && !(modifiers & Qt::ControlModifier)) { clearSelection(); } } QListView::mousePressEvent(event); } void KDirOperatorIconView::wheelEvent(QWheelEvent *event) { QListView::wheelEvent(event); // apply the vertical wheel event to the horizontal scrollbar, as // the items are aligned from left to right if (event->angleDelta().y() != 0) { #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) QWheelEvent horizEvent(event->pos(), event->angleDelta().y(), event->buttons(), event->modifiers(), Qt::Horizontal); #else QWheelEvent horizEvent(event->position(), event->globalPosition(), QPoint(event->pixelDelta().y(), 0), QPoint(event->angleDelta().y(), 0), event->buttons(), event->modifiers(), event->phase(), event->inverted(), event->source()); #endif QApplication::sendEvent(horizontalScrollBar(), &horizEvent); } } void KDirOperatorIconView::updateLayout() { if (decorationPosition == QStyleOptionViewItem::Position::Top) { // Icons view setFlow(QListView::LeftToRight); const QFontMetrics metrics(viewport()->font()); const int height = iconSize().height() + metrics.height() * 2.5; const int minWidth = qMax(height, metrics.height() * 5); const int scrollBarWidth = verticalScrollBar()->sizeHint().width(); // Subtract 1 px to prevent flickering when resizing the window // For Oxygen a column is missing after showing the dialog without resizing it, // therefore subtract 4 more (scaled) pixels const int viewPortWidth = contentsRect().width() - scrollBarWidth - 1 - 4 * devicePixelRatioF(); const int itemsInRow = qMax(1, viewPortWidth / minWidth); const int remainingWidth = viewPortWidth - (minWidth * itemsInRow); const int width = minWidth + (remainingWidth / itemsInRow); const QSize itemSize(width, height); setGridSize(itemSize); KFileItemDelegate *delegate = qobject_cast(itemDelegate()); if (delegate) { delegate->setMaximumSize(itemSize); } } else { // compact view setFlow(QListView::TopToBottom); setGridSize(QSize()); KFileItemDelegate *delegate = qobject_cast(itemDelegate()); if (delegate) { delegate->setMaximumSize(QSize()); } } } void KDirOperatorIconView::setDecorationPosition(QStyleOptionViewItem::Position newDecorationPosition) { decorationPosition = newDecorationPosition; updateLayout(); }