1 /*
2 This file is part of the Okteta Kasten module, made within the KDE community.
3
4 SPDX-FileCopyrightText: 2009 Friedrich W. H. Kossebau <kossebau@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7 */
8
9 #include "poddelegate.hpp"
10
11 // tool
12 #include "typeeditors/binary8editor.hpp"
13 #include "typeeditors/octal8editor.hpp"
14 #include "typeeditors/hexadecimal8editor.hpp"
15 #include "typeeditors/float32editor.hpp"
16 #include "typeeditors/float64editor.hpp"
17 #include "typeeditors/char8editor.hpp"
18 #include "typeeditors/utf8editor.hpp"
19 #include "typeeditors/sintspinbox.hpp"
20 #include "typeeditors/uintspinbox.hpp"
21 #include "poddecodertool.hpp"
22 #include "types/sint8.hpp"
23 #include "types/sint16.hpp"
24 #include "types/sint32.hpp"
25 #include "types/sint64.hpp"
26 #include "types/uint8.hpp"
27 #include "types/uint16.hpp"
28 #include "types/uint32.hpp"
29 #include "types/uint64.hpp"
30
31 // TODO: Stranger that you are reading this: please help out and show how to add QVariant::Types for custom datatypes,
32 // so that instead of this unflexible maintanance mess^WWWunlooped code QItemEditorCreator can be used!
33
34 namespace Kasten {
35
PODDelegate(PODDecoderTool * tool,QObject * parent)36 PODDelegate::PODDelegate(PODDecoderTool* tool, QObject* parent)
37 : QStyledItemDelegate(parent)
38 , mTool(tool)
39 {
40 qRegisterMetaType<Binary8>();
41 qRegisterMetaType<Octal8>();
42 qRegisterMetaType<Hexadecimal8>();
43 qRegisterMetaType<SInt8>();
44 qRegisterMetaType<SInt16>();
45 qRegisterMetaType<SInt32>();
46 qRegisterMetaType<SInt64>();
47 qRegisterMetaType<UInt8>();
48 qRegisterMetaType<UInt16>();
49 qRegisterMetaType<UInt32>();
50 qRegisterMetaType<UInt64>();
51 qRegisterMetaType<Float32>();
52 qRegisterMetaType<Float64>();
53 qRegisterMetaType<Char8>();
54 qRegisterMetaType<Utf8>();
55
56 connect(mTool, &PODDecoderTool::readOnlyChanged, this, &PODDelegate::onReadOnlyChanged);
57 }
58
59 PODDelegate::~PODDelegate() = default;
60
61 // make sure only editors are created which have a readOnly property
62 // also beware that for subclasses of QLineEdit (all float editors) the signal
63 // editingFinished() is only emitted if validator() returns QValidator::Acceptable
64 // so onEditorDone() is not reached if QValidator::Intermediate
createEditor(QWidget * parent,const QStyleOptionViewItem & option,const QModelIndex & index) const65 QWidget* PODDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
66 {
67 QWidget* result;
68
69 QVariant data = index.data();
70 if (data.canConvert<Binary8>()) {
71 auto* editor = new Binary8Editor(parent);
72 connect(editor, &Binary8Editor::editingFinished,
73 this, &PODDelegate::onEditorDone);
74 result = editor;
75 } else if (data.canConvert<Octal8>()) {
76 auto* editor = new Octal8Editor(parent);
77 connect(editor, &Octal8Editor::editingFinished,
78 this, &PODDelegate::onEditorDone);
79 result = editor;
80 } else if (data.canConvert<Hexadecimal8>()) {
81 auto* editor = new Hexadecimal8Editor(parent);
82 connect(editor, &Hexadecimal8Editor::editingFinished,
83 this, &PODDelegate::onEditorDone);
84 result = editor;
85 } else if (data.canConvert<SInt8>()) {
86 SIntSpinBox* editor = SIntSpinBox::createSInt8Spinbox(parent);
87 connect(editor, &SIntSpinBox::editingFinished,
88 this, &PODDelegate::onEditorDone);
89 result = editor;
90 } else if (data.canConvert<SInt16>()) {
91 SIntSpinBox* editor = SIntSpinBox::createSInt16Spinbox(parent);
92 connect(editor, &SIntSpinBox::editingFinished,
93 this, &PODDelegate::onEditorDone);
94 result = editor;
95 } else if (data.canConvert<SInt32>()) {
96 SIntSpinBox* editor = SIntSpinBox::createSInt32Spinbox(parent);
97 connect(editor, &SIntSpinBox::editingFinished,
98 this, &PODDelegate::onEditorDone);
99 result = editor;
100 } else if (data.canConvert<SInt64>()) {
101 SIntSpinBox* editor = SIntSpinBox::createSInt64Spinbox(parent);
102 connect(editor, &SIntSpinBox::editingFinished,
103 this, &PODDelegate::onEditorDone);
104 result = editor;
105 } else if (data.canConvert<UInt8>()) {
106 UIntSpinBox* editor = UIntSpinBox::createUInt8Spinbox(parent);
107 editor->setBase(mTool->isUnsignedAsHex() ? 16 : 10);
108 connect(editor, &UIntSpinBox::editingFinished,
109 this, &PODDelegate::onEditorDone);
110 result = editor;
111 } else if (data.canConvert<UInt16>()) {
112 UIntSpinBox* editor = UIntSpinBox::createUInt16Spinbox(parent);
113 editor->setBase(mTool->isUnsignedAsHex() ? 16 : 10);
114 connect(editor, &UIntSpinBox::editingFinished,
115 this, &PODDelegate::onEditorDone);
116 result = editor;
117 } else if (data.canConvert<UInt32>()) {
118 UIntSpinBox* editor = UIntSpinBox::createUInt32Spinbox(parent);
119 editor->setBase(mTool->isUnsignedAsHex() ? 16 : 10);
120 connect(editor, &UIntSpinBox::editingFinished,
121 this, &PODDelegate::onEditorDone);
122 result = editor;
123 } else if (data.canConvert<UInt64>()) {
124 UIntSpinBox* editor = UIntSpinBox::createUInt64Spinbox(parent);
125 editor->setBase(mTool->isUnsignedAsHex() ? 16 : 10);
126 connect(editor, &UIntSpinBox::editingFinished,
127 this, &PODDelegate::onEditorDone);
128 result = editor;
129 } else if (data.canConvert<Float32>()) {
130 auto* editor = new Float32Editor(parent);
131 connect(editor, &Float32Editor::editingFinished,
132 this, &PODDelegate::onEditorDone);
133 result = editor;
134 } else if (data.canConvert<Float64>()) {
135 auto* editor = new Float64Editor(parent);
136 connect(editor, &Float64Editor::editingFinished,
137 this, &PODDelegate::onEditorDone);
138 result = editor;
139 } else if (data.canConvert<Char8>()) {
140 auto* editor = new Char8Editor(mTool->charCodec(), parent);
141 connect(editor, &Char8Editor::editingFinished,
142 this, &PODDelegate::onEditorDone);
143 result = editor;
144 } else if (data.canConvert<Utf8>()) {
145 auto* editor = new Utf8Editor(parent);
146 connect(editor, &Utf8Editor::editingFinished,
147 this, &PODDelegate::onEditorDone);
148 result = editor;
149 } else {
150 result = QStyledItemDelegate::createEditor(parent, option, index);
151 }
152
153 mEditor = result;
154 onReadOnlyChanged(mTool->isReadOnly());
155
156 return result;
157 }
158
setEditorData(QWidget * editor,const QModelIndex & index) const159 void PODDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
160 {
161 QVariant data = index.data();
162
163 if (data.canConvert<Binary8>()) {
164 Binary8 binary8 = data.value<Binary8>();
165 auto* binary8Editor = qobject_cast<Binary8Editor*>(editor);
166 binary8Editor->setData(binary8);
167 } else if (data.canConvert<Octal8>()) {
168 Octal8 octal8 = data.value<Octal8>();
169 auto* octal8Editor = qobject_cast<Octal8Editor*>(editor);
170 octal8Editor->setData(octal8);
171 } else if (data.canConvert<Hexadecimal8>()) {
172 Hexadecimal8 hexadecimal8 = data.value<Hexadecimal8>();
173 auto* hexadecimal8Editor = qobject_cast<Hexadecimal8Editor*>(editor);
174 hexadecimal8Editor->setData(hexadecimal8);
175 } else if (data.canConvert<SInt8>()) {
176 SInt8 sInt8 = data.value<SInt8>();
177 auto* sInt8Editor = qobject_cast<SIntSpinBox*>(editor);
178 sInt8Editor->setValue(sInt8.value);
179 } else if (data.canConvert<SInt16>()) {
180 SInt16 sInt16 = data.value<SInt16>();
181 auto* sInt16Editor = qobject_cast<SIntSpinBox*>(editor);
182 sInt16Editor->setValue(sInt16.value);
183 } else if (data.canConvert<SInt32>()) {
184 SInt32 sInt32 = data.value<SInt32>();
185 auto* sInt32Editor = qobject_cast<SIntSpinBox*>(editor);
186 sInt32Editor->setValue(sInt32.value);
187 } else if (data.canConvert<SInt64>()) {
188 SInt64 sInt64 = data.value<SInt64>();
189 auto* sInt64Editor = qobject_cast<SIntSpinBox*>(editor);
190 sInt64Editor->setValue(sInt64.value);
191 } else if (data.canConvert<UInt8>()) {
192 UInt8 uInt8 = data.value<UInt8>();
193 auto* uInt8Editor = qobject_cast<UIntSpinBox*>(editor);
194 uInt8Editor->setValue(uInt8.value);
195 } else if (data.canConvert<UInt16>()) {
196 UInt16 uInt16 = data.value<UInt16>();
197 auto* uInt16Editor = qobject_cast<UIntSpinBox*>(editor);
198 uInt16Editor->setValue(uInt16.value);
199 } else if (data.canConvert<UInt32>()) {
200 UInt32 uInt32 = data.value<UInt32>();
201 auto* uInt32Editor = qobject_cast<UIntSpinBox*>(editor);
202 uInt32Editor->setValue(uInt32.value);
203 } else if (data.canConvert<UInt64>()) {
204 UInt64 uInt64 = data.value<UInt64>();
205 auto* uInt64Editor = qobject_cast<UIntSpinBox*>(editor);
206 uInt64Editor->setValue(uInt64.value);
207 } else if (data.canConvert<Float32>()) {
208 Float32 float32 = data.value<Float32>();
209 auto* float32Editor = qobject_cast<Float32Editor*>(editor);
210 float32Editor->setData(float32);
211 } else if (data.canConvert<Float64>()) {
212 Float64 float64 = data.value<Float64>();
213 auto* float64Editor = qobject_cast<Float64Editor*>(editor);
214 float64Editor->setData(float64);
215 } else if (data.canConvert<Char8>()) {
216 Char8 char8 = data.value<Char8>();
217 auto* char8Editor = qobject_cast<Char8Editor*>(editor);
218 char8Editor->setData(char8);
219 } else if (data.canConvert<Utf8>()) {
220 Utf8 utf8 = data.value<Utf8>();
221 auto* utf8Editor = qobject_cast<Utf8Editor*>(editor);
222 utf8Editor->setData(utf8);
223 } else {
224 QStyledItemDelegate::setEditorData(editor, index);
225 }
226 }
227
setModelData(QWidget * editor,QAbstractItemModel * model,const QModelIndex & index) const228 void PODDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
229 {
230 if (mTool->isReadOnly()) {
231 return;
232 }
233
234 QVariant data = index.data();
235
236 if (data.canConvert<Binary8>()) {
237 auto* binary8Editor = qobject_cast<Binary8Editor*>(editor);
238 model->setData(index, QVariant::fromValue(binary8Editor->data()));
239 } else if (data.canConvert<Octal8>()) {
240 auto* octal8Editor = qobject_cast<Octal8Editor*>(editor);
241 model->setData(index, QVariant::fromValue(octal8Editor->data()));
242 } else if (data.canConvert<Hexadecimal8>()) {
243 auto* hexadecimal8Editor = qobject_cast<Hexadecimal8Editor*>(editor);
244 model->setData(index, QVariant::fromValue(hexadecimal8Editor->data()));
245 } else if (data.canConvert<SInt8>()) {
246 auto* sintEditor = qobject_cast<SIntSpinBox*>(editor);
247 model->setData(index, QVariant::fromValue(SInt8(sintEditor->value())));
248 } else if (data.canConvert<SInt16>()) {
249 auto* sintEditor = qobject_cast<SIntSpinBox*>(editor);
250 model->setData(index, QVariant::fromValue(SInt16(sintEditor->value())));
251 } else if (data.canConvert<SInt32>()) {
252 auto* sintEditor = qobject_cast<SIntSpinBox*>(editor);
253 model->setData(index, QVariant::fromValue(SInt32(sintEditor->value())));
254 } else if (data.canConvert<SInt64>()) {
255 auto* sintEditor = qobject_cast<SIntSpinBox*>(editor);
256 model->setData(index, QVariant::fromValue(SInt64(sintEditor->value())));
257 } else if (data.canConvert<UInt8>()) {
258 auto* uintEditor = qobject_cast<UIntSpinBox*>(editor);
259 model->setData(index, QVariant::fromValue(UInt8(uintEditor->value())));
260 } else if (data.canConvert<UInt16>()) {
261 auto* uintEditor = qobject_cast<UIntSpinBox*>(editor);
262 model->setData(index, QVariant::fromValue(UInt16(uintEditor->value())));
263 } else if (data.canConvert<UInt32>()) {
264 auto* uintEditor = qobject_cast<UIntSpinBox*>(editor);
265 model->setData(index, QVariant::fromValue(UInt32(uintEditor->value())));
266 } else if (data.canConvert<UInt64>()) {
267 auto* uintEditor = qobject_cast<UIntSpinBox*>(editor);
268 model->setData(index, QVariant::fromValue(UInt64(uintEditor->value())));
269 } else if (data.canConvert<Float32>()) {
270 auto* float32Editor = qobject_cast<Float32Editor*>(editor);
271 model->setData(index, QVariant::fromValue(float32Editor->data()));
272 } else if (data.canConvert<Float64>()) {
273 auto* float64Editor = qobject_cast<Float64Editor*>(editor);
274 model->setData(index, QVariant::fromValue(float64Editor->data()));
275 } else if (data.canConvert<Char8>()) {
276 auto* char8Editor = qobject_cast<Char8Editor*>(editor);
277 model->setData(index, QVariant::fromValue(char8Editor->data()));
278 } else if (data.canConvert<Utf8>()) {
279 auto* utf8Editor = qobject_cast<Utf8Editor*>(editor);
280 model->setData(index, QVariant::fromValue(utf8Editor->data()));
281 } else {
282 QStyledItemDelegate::setModelData(editor, model, index);
283 }
284 }
285
displayText(const QVariant & data,const QLocale & locale) const286 QString PODDelegate::displayText(const QVariant& data, const QLocale& locale) const
287 {
288 QString result;
289
290 if (data.canConvert<Binary8>()) {
291 Binary8 binary8 = data.value<Binary8>();
292 result = binary8.toString();
293 } else if (data.canConvert<Octal8>()) {
294 Octal8 octal8 = data.value<Octal8>();
295 result = octal8.toString();
296 } else if (data.canConvert<Hexadecimal8>()) {
297 Hexadecimal8 hexadecimal8 = data.value<Hexadecimal8>();
298 result = hexadecimal8.toString();
299 } else if (data.canConvert<SInt8>()) {
300 SInt8 sInt8 = data.value<SInt8>();
301 result = sInt8.toString();
302 } else if (data.canConvert<SInt16>()) {
303 SInt16 sInt16 = data.value<SInt16>();
304 result = sInt16.toString();
305 } else if (data.canConvert<SInt32>()) {
306 SInt32 sInt32 = data.value<SInt32>();
307 result = sInt32.toString();
308 } else if (data.canConvert<SInt64>()) {
309 SInt64 sInt64 = data.value<SInt64>();
310 result = sInt64.toString();
311 } else if (data.canConvert<UInt8>()) {
312 UInt8 uInt8 = data.value<UInt8>();
313 result = uInt8.toString(mTool->isUnsignedAsHex());
314 } else if (data.canConvert<UInt16>()) {
315 UInt16 uInt16 = data.value<UInt16>();
316 result = uInt16.toString(mTool->isUnsignedAsHex());
317 } else if (data.canConvert<UInt32>()) {
318 UInt32 uInt32 = data.value<UInt32>();
319 result = uInt32.toString(mTool->isUnsignedAsHex());
320 } else if (data.canConvert<UInt64>()) {
321 UInt64 uInt64 = data.value<UInt64>();
322 result = uInt64.toString(mTool->isUnsignedAsHex());
323 } else if (data.canConvert<Float32>()) {
324 Float32 float32 = data.value<Float32>();
325 result = float32.toString();
326 } else if (data.canConvert<Float64>()) {
327 Float64 float64 = data.value<Float64>();
328 result = float64.toString();
329 } else if (data.canConvert<Char8>()) {
330 Char8 char8 = data.value<Char8>();
331 result = char8.toString();
332 } else if (data.canConvert<Utf8>()) {
333 Utf8 utf8 = data.value<Utf8>();
334 result = utf8.toString();
335 } else {
336 result = QStyledItemDelegate::displayText(data, locale);
337 }
338
339 return result;
340 }
341
342 // QSize PODDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const
343 // {
344 // editor->setGeometry(option.rect);
345 // }
346
onEditorDone()347 void PODDelegate::onEditorDone()
348 {
349 QWidget* editor = qobject_cast<QWidget*>(sender());
350 mEditor = nullptr;
351 emit commitData(editor);
352 emit closeEditor(editor);
353 }
354
onReadOnlyChanged(bool isReadOnly) const355 void PODDelegate::onReadOnlyChanged(bool isReadOnly) const
356 {
357 if (mEditor) {
358 // going by property is slower, but saves writing this call for every widget
359 mEditor->setProperty("readOnly", isReadOnly);
360 }
361 }
362
363 }
364