]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kitemlistroleeditor.cpp
When renaming files, move to next file using tab key or up/down
[dolphin.git] / src / kitemviews / private / kitemlistroleeditor.cpp
1 /*
2 * SPDX-FileCopyrightText: 2012 Peter Penz <peter.penz19@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "kitemlistroleeditor.h"
8
9 #include <KIO/Global>
10
11 KItemListRoleEditor::KItemListRoleEditor(QWidget *parent) :
12 KTextEdit(parent),
13 m_role(),
14 m_blockFinishedSignal(false)
15 {
16 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
17 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
18 setAcceptRichText(false);
19 enableFindReplace(false);
20 document()->setDocumentMargin(0);
21
22 if (parent) {
23 parent->installEventFilter(this);
24 }
25
26 connect(this, &KItemListRoleEditor::textChanged, this, &KItemListRoleEditor::autoAdjustSize);
27 }
28
29 KItemListRoleEditor::~KItemListRoleEditor()
30 {
31 }
32
33 void KItemListRoleEditor::setRole(const QByteArray& role)
34 {
35 m_role = role;
36 }
37
38 QByteArray KItemListRoleEditor::role() const
39 {
40 return m_role;
41 }
42
43 void KItemListRoleEditor::setAllowUpDownKeyChainEdit(bool allowChainEdit)
44 {
45 m_allowUpDownKeyChainEdit = allowChainEdit;
46 }
47
48 bool KItemListRoleEditor::eventFilter(QObject* watched, QEvent* event)
49 {
50 if (watched == parentWidget() && event->type() == QEvent::Resize) {
51 emitRoleEditingFinished();
52 }
53
54 return KTextEdit::eventFilter(watched, event);
55 }
56
57 bool KItemListRoleEditor::event(QEvent* event)
58 {
59 if (event->type() == QEvent::FocusOut) {
60 QFocusEvent* focusEvent = static_cast<QFocusEvent*>(event);
61 if (focusEvent->reason() != Qt::PopupFocusReason) {
62 emitRoleEditingFinished();
63 }
64 }
65 return KTextEdit::event(event);
66 }
67
68 void KItemListRoleEditor::keyPressEvent(QKeyEvent* event)
69 {
70 switch (event->key()) {
71 case Qt::Key_Escape:
72 // Emitting the signal roleEditingCanceled might result
73 // in losing the focus. Per default losing the focus emits
74 // a roleEditingFinished signal (see KItemListRoleEditor::event),
75 // which is not wanted in this case.
76 m_blockFinishedSignal = true;
77 Q_EMIT roleEditingCanceled(m_role, KIO::encodeFileName(toPlainText()));
78 m_blockFinishedSignal = false;
79 event->accept();
80 return;
81 case Qt::Key_Enter:
82 case Qt::Key_Return:
83 emitRoleEditingFinished();
84 event->accept();
85 return;
86 case Qt::Key_Tab:
87 case Qt::Key_Down:
88 if (m_allowUpDownKeyChainEdit || event->key() == Qt::Key_Tab) {
89 emitRoleEditingFinished(EditNext);
90 event->accept();
91 return;
92 }
93 case Qt::Key_Backtab:
94 case Qt::Key_Up:
95 if (m_allowUpDownKeyChainEdit || event->key() == Qt::Key_Backtab) {
96 emitRoleEditingFinished(EditPrevious);
97 event->accept();
98 return;
99 }
100 case Qt::Key_Left:
101 case Qt::Key_Right: {
102 QTextCursor cursor = textCursor();
103 if (event->modifiers() == Qt::NoModifier && cursor.hasSelection()) {
104 if (event->key() == Qt::Key_Left) {
105 cursor.setPosition(cursor.selectionStart());
106 } else {
107 cursor.setPosition(cursor.selectionEnd());
108 }
109 cursor.clearSelection();
110 setTextCursor(cursor);
111 event->accept();
112 return;
113 }
114 break;
115 }
116 case Qt::Key_Home:
117 case Qt::Key_End: {
118 if (event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::ShiftModifier) {
119 const QTextCursor::MoveOperation op = event->key() == Qt::Key_Home
120 ? QTextCursor::Start
121 : QTextCursor::End;
122 const QTextCursor::MoveMode mode = event->modifiers() == Qt::NoModifier
123 ? QTextCursor::MoveAnchor
124 : QTextCursor::KeepAnchor;
125 QTextCursor cursor = textCursor();
126 cursor.movePosition(op, mode);
127 setTextCursor(cursor);
128 event->accept();
129 return;
130 }
131 break;
132 }
133 default:
134 break;
135 }
136
137 KTextEdit::keyPressEvent(event);
138 }
139
140 void KItemListRoleEditor::autoAdjustSize()
141 {
142 const qreal frameBorder = 2 * frameWidth();
143
144 const qreal requiredWidth = document()->size().width();
145 const qreal availableWidth = size().width() - frameBorder;
146 if (requiredWidth > availableWidth) {
147 qreal newWidth = requiredWidth + frameBorder;
148 if (parentWidget() && pos().x() + newWidth > parentWidget()->width()) {
149 newWidth = parentWidget()->width() - pos().x();
150 }
151 resize(newWidth, size().height());
152 }
153
154 const qreal requiredHeight = document()->size().height();
155 const qreal availableHeight = size().height() - frameBorder;
156 if (requiredHeight > availableHeight) {
157 qreal newHeight = requiredHeight + frameBorder;
158 if (parentWidget() && pos().y() + newHeight > parentWidget()->height()) {
159 newHeight = parentWidget()->height() - pos().y();
160 }
161 resize(size().width(), newHeight);
162 }
163 }
164
165 void KItemListRoleEditor::emitRoleEditingFinished(EditResultDirection direction)
166 {
167 QVariant ret;
168 ret.setValue(EditResult {KIO::encodeFileName(toPlainText()), direction});
169
170 if (!m_blockFinishedSignal) {
171 Q_EMIT roleEditingFinished(m_role, ret);
172 }
173 }
174