File indexing completed on 2024-12-01 09:53:05
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 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0056 void KDirOperatorIconView::initViewItemOption(QStyleOptionViewItem *option) const 0057 { 0058 QListView::initViewItemOption(option); 0059 option->showDecorationSelected = true; 0060 option->textElideMode = Qt::ElideMiddle; 0061 option->decorationPosition = decorationPosition; 0062 if (option->decorationPosition == QStyleOptionViewItem::Left) { 0063 option->displayAlignment = Qt::AlignLeft | Qt::AlignVCenter; 0064 } else { 0065 option->displayAlignment = Qt::AlignCenter; 0066 } 0067 } 0068 #else 0069 QStyleOptionViewItem KDirOperatorIconView::viewOptions() const 0070 { 0071 QStyleOptionViewItem viewOptions = QListView::viewOptions(); 0072 viewOptions.showDecorationSelected = true; 0073 viewOptions.textElideMode = Qt::ElideMiddle; 0074 viewOptions.decorationPosition = decorationPosition; 0075 if (viewOptions.decorationPosition == QStyleOptionViewItem::Left) { 0076 viewOptions.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter; 0077 } else { 0078 viewOptions.displayAlignment = Qt::AlignCenter; 0079 } 0080 0081 return viewOptions; 0082 } 0083 #endif 0084 0085 void KDirOperatorIconView::dragEnterEvent(QDragEnterEvent *event) 0086 { 0087 if (event->mimeData()->hasUrls()) { 0088 event->acceptProposedAction(); 0089 } 0090 } 0091 0092 void KDirOperatorIconView::mousePressEvent(QMouseEvent *event) 0093 { 0094 if (!indexAt(event->pos()).isValid()) { 0095 const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); 0096 if (!(modifiers & Qt::ShiftModifier) && !(modifiers & Qt::ControlModifier)) { 0097 clearSelection(); 0098 } 0099 } 0100 0101 QListView::mousePressEvent(event); 0102 } 0103 0104 void KDirOperatorIconView::wheelEvent(QWheelEvent *event) 0105 { 0106 QListView::wheelEvent(event); 0107 0108 // apply the vertical wheel event to the horizontal scrollbar, as 0109 // the items are aligned from left to right 0110 if (event->angleDelta().y() != 0) { 0111 QWheelEvent horizEvent(event->position(), 0112 event->globalPosition(), 0113 QPoint(event->pixelDelta().y(), 0), 0114 QPoint(event->angleDelta().y(), 0), 0115 event->buttons(), 0116 event->modifiers(), 0117 event->phase(), 0118 event->inverted(), 0119 event->source()); 0120 QApplication::sendEvent(horizontalScrollBar(), &horizEvent); 0121 } 0122 } 0123 0124 void KDirOperatorIconView::updateLayout() 0125 { 0126 if (decorationPosition == QStyleOptionViewItem::Position::Top) { 0127 // Icons view 0128 setFlow(QListView::LeftToRight); 0129 const QFontMetrics metrics(viewport()->font()); 0130 0131 const int height = iconSize().height() + metrics.height() * 2.5; 0132 const int minWidth = qMax(height, metrics.height() * 5); 0133 0134 const int scrollBarWidth = verticalScrollBar()->sizeHint().width(); 0135 0136 // Subtract 1 px to prevent flickering when resizing the window 0137 // For Oxygen a column is missing after showing the dialog without resizing it, 0138 // therefore subtract 4 more (scaled) pixels 0139 const int viewPortWidth = contentsRect().width() - scrollBarWidth - 1 - 4 * devicePixelRatioF(); 0140 const int itemsInRow = qMax(1, viewPortWidth / minWidth); 0141 const int remainingWidth = viewPortWidth - (minWidth * itemsInRow); 0142 const int width = minWidth + (remainingWidth / itemsInRow); 0143 0144 const QSize itemSize(width, height); 0145 0146 setGridSize(itemSize); 0147 KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate *>(itemDelegate()); 0148 if (delegate) { 0149 delegate->setMaximumSize(itemSize); 0150 } 0151 } else { 0152 // compact view 0153 setFlow(QListView::TopToBottom); 0154 setGridSize(QSize()); 0155 KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate *>(itemDelegate()); 0156 if (delegate) { 0157 delegate->setMaximumSize(QSize()); 0158 } 0159 } 0160 } 0161 void KDirOperatorIconView::setDecorationPosition(QStyleOptionViewItem::Position newDecorationPosition) 0162 { 0163 decorationPosition = newDecorationPosition; 0164 updateLayout(); 0165 } 0166 0167 #include "moc_kdiroperatoriconview_p.cpp"