File indexing completed on 2024-12-01 06:45:09
0001 /* 0002 SPDX-FileCopyrightText: 2007 Peter Penz <peter.penz@gmx.at> 0003 SPDX-FileCopyrightText: 2019 Méven Car <meven.car@kdemail.net> 0004 0005 SPDX-License-Identifier: LGPL-2.0-only 0006 */ 0007 0008 #include "kdiroperatoriconview_p.h" 0009 0010 #include <QApplication> 0011 #include <QDragEnterEvent> 0012 #include <QMimeData> 0013 #include <QScrollBar> 0014 0015 #include <KFileItemDelegate> 0016 #include <KIconLoader> 0017 0018 KDirOperatorIconView::KDirOperatorIconView(QWidget *parent, QStyleOptionViewItem::Position aDecorationPosition) 0019 : QListView(parent) 0020 { 0021 setViewMode(QListView::IconMode); 0022 setResizeMode(QListView::Adjust); 0023 setSpacing(0); 0024 setMovement(QListView::Static); 0025 setDragDropMode(QListView::DragOnly); 0026 setVerticalScrollMode(QListView::ScrollPerPixel); 0027 setHorizontalScrollMode(QListView::ScrollPerPixel); 0028 setEditTriggers(QAbstractItemView::NoEditTriggers); 0029 setWordWrap(true); 0030 setIconSize(QSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall)); 0031 0032 decorationPosition = aDecorationPosition; 0033 0034 const QFontMetrics metrics(viewport()->font()); 0035 const int singleStep = metrics.height() * QApplication::wheelScrollLines(); 0036 0037 verticalScrollBar()->setSingleStep(singleStep); 0038 horizontalScrollBar()->setSingleStep(singleStep); 0039 0040 updateLayout(); 0041 connect(this, &QListView::iconSizeChanged, this, &KDirOperatorIconView::updateLayout); 0042 } 0043 0044 KDirOperatorIconView::~KDirOperatorIconView() 0045 { 0046 } 0047 0048 void KDirOperatorIconView::resizeEvent(QResizeEvent *event) 0049 { 0050 Q_UNUSED(event); 0051 0052 updateLayout(); 0053 } 0054 0055 void KDirOperatorIconView::initViewItemOption(QStyleOptionViewItem *option) const 0056 { 0057 QListView::initViewItemOption(option); 0058 option->showDecorationSelected = true; 0059 option->textElideMode = Qt::ElideMiddle; 0060 option->decorationPosition = decorationPosition; 0061 if (option->decorationPosition == QStyleOptionViewItem::Left) { 0062 option->displayAlignment = Qt::AlignLeft | Qt::AlignVCenter; 0063 } else { 0064 option->displayAlignment = Qt::AlignCenter; 0065 } 0066 } 0067 0068 void KDirOperatorIconView::dragEnterEvent(QDragEnterEvent *event) 0069 { 0070 if (event->mimeData()->hasUrls()) { 0071 event->acceptProposedAction(); 0072 } 0073 } 0074 0075 void KDirOperatorIconView::mousePressEvent(QMouseEvent *event) 0076 { 0077 if (!indexAt(event->pos()).isValid()) { 0078 const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); 0079 if (!(modifiers & Qt::ShiftModifier) && !(modifiers & Qt::ControlModifier)) { 0080 clearSelection(); 0081 } 0082 } 0083 0084 QListView::mousePressEvent(event); 0085 } 0086 0087 void KDirOperatorIconView::wheelEvent(QWheelEvent *event) 0088 { 0089 QListView::wheelEvent(event); 0090 0091 // apply the vertical wheel event to the horizontal scrollbar, as 0092 // the items are aligned from left to right 0093 if (event->angleDelta().y() != 0) { 0094 QWheelEvent horizEvent(event->position(), 0095 event->globalPosition(), 0096 QPoint(event->pixelDelta().y(), 0), 0097 QPoint(event->angleDelta().y(), 0), 0098 event->buttons(), 0099 event->modifiers(), 0100 event->phase(), 0101 event->inverted(), 0102 event->source()); 0103 QApplication::sendEvent(horizontalScrollBar(), &horizEvent); 0104 } 0105 } 0106 0107 void KDirOperatorIconView::updateLayout() 0108 { 0109 if (decorationPosition == QStyleOptionViewItem::Position::Top) { 0110 // Icons view 0111 setFlow(QListView::LeftToRight); 0112 const QFontMetrics metrics(viewport()->font()); 0113 0114 const int height = iconSize().height() + metrics.height() * 2.5; 0115 const int minWidth = qMax(height, metrics.height() * 5); 0116 0117 const int scrollBarWidth = verticalScrollBar()->sizeHint().width(); 0118 0119 // Subtract 1 px to prevent flickering when resizing the window 0120 // For Oxygen a column is missing after showing the dialog without resizing it, 0121 // therefore subtract 4 more (scaled) pixels 0122 const int viewPortWidth = contentsRect().width() - scrollBarWidth - 1 - 4 * devicePixelRatioF(); 0123 const int itemsInRow = qMax(1, viewPortWidth / minWidth); 0124 const int remainingWidth = viewPortWidth - (minWidth * itemsInRow); 0125 const int width = minWidth + (remainingWidth / itemsInRow); 0126 0127 const QSize itemSize(width, height); 0128 0129 setGridSize(itemSize); 0130 KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate *>(itemDelegate()); 0131 if (delegate) { 0132 delegate->setMaximumSize(itemSize); 0133 } 0134 } else { 0135 // compact view 0136 setFlow(QListView::TopToBottom); 0137 setGridSize(QSize()); 0138 KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate *>(itemDelegate()); 0139 if (delegate) { 0140 delegate->setMaximumSize(QSize()); 0141 } 0142 } 0143 } 0144 void KDirOperatorIconView::setDecorationPosition(QStyleOptionViewItem::Position newDecorationPosition) 0145 { 0146 decorationPosition = newDecorationPosition; 0147 updateLayout(); 0148 } 0149 0150 #include "moc_kdiroperatoriconview_p.cpp"