]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kitemlistroleeditor.cpp
GIT_SILENT Sync po/docbooks with svn
[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 setCheckSpellingEnabled(false);
22
23 if (parent) {
24 parent->installEventFilter(this);
25 }
26
27 connect(this, &KItemListRoleEditor::textChanged, this, &KItemListRoleEditor::autoAdjustSize);
28 }
29
30 KItemListRoleEditor::~KItemListRoleEditor()
31 {
32 }
33
34 void KItemListRoleEditor::setRole(const QByteArray &role)
35 {
36 m_role = role;
37 }
38
39 QByteArray KItemListRoleEditor::role() const
40 {
41 return m_role;
42 }
43
44 void KItemListRoleEditor::setAllowUpDownKeyChainEdit(bool allowChainEdit)
45 {
46 m_allowUpDownKeyChainEdit = allowChainEdit;
47 }
48
49 bool KItemListRoleEditor::eventFilter(QObject *watched, QEvent *event)
50 {
51 if (watched == parentWidget() && event->type() == QEvent::Resize) {
52 emitRoleEditingFinished();
53 }
54
55 return KTextEdit::eventFilter(watched, event);
56 }
57
58 bool KItemListRoleEditor::event(QEvent *event)
59 {
60 if (event->type() == QEvent::FocusOut) {
61 QFocusEvent *focusEvent = static_cast<QFocusEvent *>(event);
62 if (focusEvent->reason() != Qt::PopupFocusReason) {
63 emitRoleEditingFinished();
64 }
65 }
66 return KTextEdit::event(event);
67 }
68
69 void KItemListRoleEditor::keyPressEvent(QKeyEvent *event)
70 {
71 switch (event->key()) {
72 case Qt::Key_Escape:
73 // Emitting the signal roleEditingCanceled might result
74 // in losing the focus. Per default losing the focus emits
75 // a roleEditingFinished signal (see KItemListRoleEditor::event),
76 // which is not wanted in this case.
77 m_blockFinishedSignal = true;
78 Q_EMIT roleEditingCanceled(m_role, KIO::encodeFileName(toPlainText()));
79 m_blockFinishedSignal = false;
80 event->accept();
81 return;
82 case Qt::Key_Enter:
83 case Qt::Key_Return:
84 emitRoleEditingFinished();
85 event->accept();
86 return;
87 case Qt::Key_Tab:
88 case Qt::Key_Down:
89 if (m_allowUpDownKeyChainEdit || event->key() == Qt::Key_Tab) {
90 emitRoleEditingFinished(EditNext);
91 event->accept();
92 return;
93 }
94 break;
95 case Qt::Key_Backtab:
96 case Qt::Key_Up:
97 if (m_allowUpDownKeyChainEdit || event->key() == Qt::Key_Backtab) {
98 emitRoleEditingFinished(EditPrevious);
99 event->accept();
100 return;
101 }
102 break;
103 case Qt::Key_Left:
104 case Qt::Key_Right: {
105 QTextCursor cursor = textCursor();
106 if (event->modifiers() == Qt::NoModifier && cursor.hasSelection()) {
107 if (event->key() == Qt::Key_Left) {
108 cursor.setPosition(cursor.selectionStart());
109 } else {
110 cursor.setPosition(cursor.selectionEnd());
111 }
112 cursor.clearSelection();
113 setTextCursor(cursor);
114 event->accept();
115 return;
116 }
117 break;
118 }
119 case Qt::Key_Home:
120 case Qt::Key_End: {
121 if (event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::ShiftModifier) {
122 const QTextCursor::MoveOperation op = event->key() == Qt::Key_Home ? QTextCursor::Start : QTextCursor::End;
123 const QTextCursor::MoveMode mode = event->modifiers() == Qt::NoModifier ? QTextCursor::MoveAnchor : QTextCursor::KeepAnchor;
124 QTextCursor cursor = textCursor();
125 cursor.movePosition(op, mode);
126 setTextCursor(cursor);
127 event->accept();
128 return;
129 }
130 break;
131 }
132 default:
133 break;
134 }
135
136 KTextEdit::keyPressEvent(event);
137 }
138
139 void KItemListRoleEditor::autoAdjustSize()
140 {
141 const qreal frameBorder = 2 * frameWidth();
142
143 const auto originalSize = size();
144 auto newSize = originalSize;
145
146 document()->adjustSize();
147 const qreal requiredWidth = document()->size().width();
148 const qreal availableWidth = size().width() - frameBorder;
149 if (requiredWidth > availableWidth) {
150 qreal newWidth = requiredWidth + frameBorder;
151 if (parentWidget() && pos().x() + newWidth > parentWidget()->width()) {
152 newWidth = parentWidget()->width() - pos().x();
153 }
154 newSize.setWidth(newWidth);
155 }
156
157 const qreal requiredHeight = document()->size().height();
158 const qreal availableHeight = size().height() - frameBorder;
159 if (requiredHeight > availableHeight) {
160 qreal newHeight = requiredHeight + frameBorder;
161 if (parentWidget() && pos().y() + newHeight > parentWidget()->height()) {
162 newHeight = parentWidget()->height() - pos().y();
163 }
164 newSize.setHeight(newHeight);
165 }
166
167 if (originalSize != newSize) {
168 resize(newSize);
169 }
170 // reset the document width to the widget width
171 // to allow alignment to be properly rendered
172 document()->setTextWidth(newSize.width());
173 }
174
175 void KItemListRoleEditor::emitRoleEditingFinished(EditResultDirection direction)
176 {
177 QVariant ret;
178 ret.setValue(EditResult{KIO::encodeFileName(toPlainText()), direction});
179
180 if (!m_blockFinishedSignal) {
181 Q_EMIT roleEditingFinished(m_role, ret);
182 }
183 }
184
185 #include "moc_kitemlistroleeditor.cpp"