KIO

kdiroperatoriconview.cpp
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#include "kfileitemselectionemblem.h"
10
11#include <QApplication>
12#include <QDragEnterEvent>
13#include <QMimeData>
14#include <QScrollBar>
15
16#include <KFileItemDelegate>
17#include <KIconLoader>
18
19KDirOperatorIconView::KDirOperatorIconView(KDirOperator *dirOperator, QWidget *parent, QStyleOptionViewItem::Position aDecorationPosition)
20 : QListView(parent)
21 , m_isEmblemClicked(false)
22 , m_dirOperator(dirOperator)
23{
24 setViewMode(QListView::IconMode);
25 setResizeMode(QListView::Adjust);
26 setSpacing(0);
27 setMovement(QListView::Static);
28 setDragDropMode(QListView::DragOnly);
29 setVerticalScrollMode(QListView::ScrollPerPixel);
30 setHorizontalScrollMode(QListView::ScrollPerPixel);
31 setEditTriggers(QAbstractItemView::NoEditTriggers);
32 setWordWrap(true);
34
35 decorationPosition = aDecorationPosition;
36
37 const QFontMetrics metrics(viewport()->font());
38 const int singleStep = metrics.height() * QApplication::wheelScrollLines();
39
40 verticalScrollBar()->setSingleStep(singleStep);
41 horizontalScrollBar()->setSingleStep(singleStep);
42
43 updateLayout();
44 connect(this, &QListView::iconSizeChanged, this, &KDirOperatorIconView::updateLayout);
45}
46
47KDirOperatorIconView::~KDirOperatorIconView()
48{
49}
50
51void KDirOperatorIconView::resizeEvent(QResizeEvent *event)
52{
53 Q_UNUSED(event);
54
55 updateLayout();
56}
57
58void KDirOperatorIconView::initViewItemOption(QStyleOptionViewItem *option) const
59{
61 option->showDecorationSelected = true;
62 option->textElideMode = Qt::ElideMiddle;
63 option->decorationPosition = decorationPosition;
64 if (option->decorationPosition == QStyleOptionViewItem::Left) {
65 option->displayAlignment = Qt::AlignLeft | Qt::AlignVCenter;
66 } else {
67 option->displayAlignment = Qt::AlignCenter;
68 }
69}
70
71void KDirOperatorIconView::dragEnterEvent(QDragEnterEvent *event)
72{
73 if (event->mimeData()->hasUrls()) {
74 event->acceptProposedAction();
75 }
76}
77
78void KDirOperatorIconView::mousePressEvent(QMouseEvent *event)
79{
80 const QModelIndex index = indexAt(event->pos());
81
82 // When selection emblem is clicked, select it and don't do anything else
83 m_isEmblemClicked = KFileItemSelectionEmblem(this, index, m_dirOperator).handleMousePressEvent(event->pos());
84 if (m_isEmblemClicked) {
85 return;
86 }
87
88 if (!index.isValid()) {
90 if (!(modifiers & Qt::ShiftModifier) && !(modifiers & Qt::ControlModifier)) {
91 clearSelection();
92 }
93 }
94
96}
97
98void KDirOperatorIconView::mouseMoveEvent(QMouseEvent *event)
99{
100 // Disallow selection dragging when emblem is clicked
101 if (m_isEmblemClicked) {
102 return;
103 }
105}
106
107void KDirOperatorIconView::mouseReleaseEvent(QMouseEvent *event)
108{
109 // Reset the emblem selection
110 if (m_isEmblemClicked) {
111 m_isEmblemClicked = false;
112 }
114}
115
116void KDirOperatorIconView::wheelEvent(QWheelEvent *event)
117{
119
120 // apply the vertical wheel event to the horizontal scrollbar, as
121 // the items are aligned from left to right
122 if (event->angleDelta().y() != 0) {
123 QWheelEvent horizEvent(event->position(),
124 event->globalPosition(),
125 QPoint(event->pixelDelta().y(), 0),
126 QPoint(event->angleDelta().y(), 0),
127 event->buttons(),
128 event->modifiers(),
129 event->phase(),
130 event->inverted(),
131 event->source());
132 QApplication::sendEvent(horizontalScrollBar(), &horizEvent);
133 }
134}
135
136void KDirOperatorIconView::updateLayout()
137{
138 if (decorationPosition == QStyleOptionViewItem::Position::Top) {
139 // Icons view
140 setFlow(QListView::LeftToRight);
141 const QFontMetrics metrics(viewport()->font());
142
143 const int height = iconSize().height() + metrics.height() * 2.5;
144 const int minWidth = qMax(height, metrics.height() * 5);
145
146 const int scrollBarWidth = verticalScrollBar()->sizeHint().width();
147
148 // Subtract 1 px to prevent flickering when resizing the window
149 // For Oxygen a column is missing after showing the dialog without resizing it,
150 // therefore subtract 4 more (scaled) pixels
151 const int viewPortWidth = contentsRect().width() - scrollBarWidth - 1 - 4 * devicePixelRatioF();
152 const int itemsInRow = qMax(1, viewPortWidth / minWidth);
153 const int remainingWidth = viewPortWidth - (minWidth * itemsInRow);
154 const int width = minWidth + (remainingWidth / itemsInRow);
155
156 const QSize itemSize(width, height);
157
158 setGridSize(itemSize);
159 KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate *>(itemDelegate());
160 if (delegate) {
161 delegate->setMaximumSize(itemSize);
162 }
163 } else {
164 // compact view
165 setFlow(QListView::TopToBottom);
166 setGridSize(QSize());
167 KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate *>(itemDelegate());
168 if (delegate) {
169 delegate->setMaximumSize(QSize());
170 }
171 }
172}
173void KDirOperatorIconView::setDecorationPosition(QStyleOptionViewItem::Position newDecorationPosition)
174{
175 decorationPosition = newDecorationPosition;
176 updateLayout();
177}
178
179#include "moc_kdiroperatoriconview_p.cpp"
This widget works as a network transparent filebrowser.
KFileItemDelegate is intended to be used to provide a KDE file system view, when using one of the sta...
void setMaximumSize(const QSize &size)
Sets the maximum size for KFileItemDelegate::sizeHint().
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
void iconSizeChanged(const QSize &size)
virtual void mousePressEvent(QMouseEvent *event) override
bool sendEvent(QObject *receiver, QEvent *event)
Qt::KeyboardModifiers keyboardModifiers()
virtual void initViewItemOption(QStyleOptionViewItem *option) const const override
virtual void mouseMoveEvent(QMouseEvent *e) override
virtual void mouseReleaseEvent(QMouseEvent *e) override
virtual void wheelEvent(QWheelEvent *e) override
bool isValid() const const
AlignLeft
typedef KeyboardModifiers
ElideMiddle
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 11 2025 11:51:43 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.