1/*
2 SPDX-FileCopyrightText: 2007 Peter Penz <peter.penz@gmx.at>
3 SPDX-FileCopyrightText: 2019 Méven Car <meven.car@kdemail.net>
4
5 SPDX-License-Identifier: LGPL-2.0-only
6*/
7
8#include "kdiroperatoriconview_p.h"
9
10#include <QApplication>
11#include <QDragEnterEvent>
12#include <QMimeData>
13#include <QScrollBar>
14
15#include <KFileItemDelegate>
16#include <KIconLoader>
17
18KDirOperatorIconView::KDirOperatorIconView(QWidget *parent, QStyleOptionViewItem::Position aDecorationPosition)
19 : QListView(parent)
20{
21 setViewMode(QListView::IconMode);
22 setResizeMode(QListView::Adjust);
23 setSpacing(0);
24 setMovement(QListView::Static);
25 setDragDropMode(QListView::DragOnly);
26 setVerticalScrollMode(QListView::ScrollPerPixel);
27 setHorizontalScrollMode(QListView::ScrollPerPixel);
28 setEditTriggers(QAbstractItemView::NoEditTriggers);
29 setWordWrap(true);
30 setIconSize(QSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall));
31
32 decorationPosition = aDecorationPosition;
33
34 const QFontMetrics metrics(viewport()->font());
35 const int singleStep = metrics.height() * QApplication::wheelScrollLines();
36
37 verticalScrollBar()->setSingleStep(singleStep);
38 horizontalScrollBar()->setSingleStep(singleStep);
39
40 updateLayout();
41 connect(sender: this, signal: &QListView::iconSizeChanged, context: this, slot: &KDirOperatorIconView::updateLayout);
42}
43
44KDirOperatorIconView::~KDirOperatorIconView()
45{
46}
47
48void KDirOperatorIconView::resizeEvent(QResizeEvent *event)
49{
50 Q_UNUSED(event);
51
52 updateLayout();
53}
54
55void KDirOperatorIconView::initViewItemOption(QStyleOptionViewItem *option) const
56{
57 QListView::initViewItemOption(option);
58 option->showDecorationSelected = true;
59 option->textElideMode = Qt::ElideMiddle;
60 option->decorationPosition = decorationPosition;
61 if (option->decorationPosition == QStyleOptionViewItem::Left) {
62 option->displayAlignment = Qt::AlignLeft | Qt::AlignVCenter;
63 } else {
64 option->displayAlignment = Qt::AlignCenter;
65 }
66}
67
68void KDirOperatorIconView::dragEnterEvent(QDragEnterEvent *event)
69{
70 if (event->mimeData()->hasUrls()) {
71 event->acceptProposedAction();
72 }
73}
74
75void KDirOperatorIconView::mousePressEvent(QMouseEvent *event)
76{
77 if (!indexAt(p: event->pos()).isValid()) {
78 const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
79 if (!(modifiers & Qt::ShiftModifier) && !(modifiers & Qt::ControlModifier)) {
80 clearSelection();
81 }
82 }
83
84 QListView::mousePressEvent(event);
85}
86
87void KDirOperatorIconView::wheelEvent(QWheelEvent *event)
88{
89 QListView::wheelEvent(e: event);
90
91 // apply the vertical wheel event to the horizontal scrollbar, as
92 // the items are aligned from left to right
93 if (event->angleDelta().y() != 0) {
94 QWheelEvent horizEvent(event->position(),
95 event->globalPosition(),
96 QPoint(event->pixelDelta().y(), 0),
97 QPoint(event->angleDelta().y(), 0),
98 event->buttons(),
99 event->modifiers(),
100 event->phase(),
101 event->inverted(),
102 event->source());
103 QApplication::sendEvent(receiver: horizontalScrollBar(), event: &horizEvent);
104 }
105}
106
107void KDirOperatorIconView::updateLayout()
108{
109 if (decorationPosition == QStyleOptionViewItem::Position::Top) {
110 // Icons view
111 setFlow(QListView::LeftToRight);
112 const QFontMetrics metrics(viewport()->font());
113
114 const int height = iconSize().height() + metrics.height() * 2.5;
115 const int minWidth = qMax(a: height, b: metrics.height() * 5);
116
117 const int scrollBarWidth = verticalScrollBar()->sizeHint().width();
118
119 // Subtract 1 px to prevent flickering when resizing the window
120 // For Oxygen a column is missing after showing the dialog without resizing it,
121 // therefore subtract 4 more (scaled) pixels
122 const int viewPortWidth = contentsRect().width() - scrollBarWidth - 1 - 4 * devicePixelRatioF();
123 const int itemsInRow = qMax(a: 1, b: viewPortWidth / minWidth);
124 const int remainingWidth = viewPortWidth - (minWidth * itemsInRow);
125 const int width = minWidth + (remainingWidth / itemsInRow);
126
127 const QSize itemSize(width, height);
128
129 setGridSize(itemSize);
130 KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate *>(object: itemDelegate());
131 if (delegate) {
132 delegate->setMaximumSize(itemSize);
133 }
134 } else {
135 // compact view
136 setFlow(QListView::TopToBottom);
137 setGridSize(QSize());
138 KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate *>(object: itemDelegate());
139 if (delegate) {
140 delegate->setMaximumSize(QSize());
141 }
142 }
143}
144void KDirOperatorIconView::setDecorationPosition(QStyleOptionViewItem::Position newDecorationPosition)
145{
146 decorationPosition = newDecorationPosition;
147 updateLayout();
148}
149
150#include "moc_kdiroperatoriconview_p.cpp"
151

source code of kio/src/filewidgets/kdiroperatoriconview.cpp