File indexing completed on 2024-06-16 05:24:55

0001 /*
0002     This file is part of the Okteta Kasten module, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2009, 2ß23 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "poddelegate.hpp"
0010 
0011 // tool
0012 #include "typeeditors/binary8editor.hpp"
0013 #include "typeeditors/octal8editor.hpp"
0014 #include "typeeditors/hexadecimal8editor.hpp"
0015 #include "typeeditors/float32editor.hpp"
0016 #include "typeeditors/float64editor.hpp"
0017 #include "typeeditors/char8editor.hpp"
0018 #include "typeeditors/utf8editor.hpp"
0019 #include "typeeditors/utf16editor.hpp"
0020 #include "typeeditors/sintspinbox.hpp"
0021 #include "typeeditors/uintspinbox.hpp"
0022 #include "poddecodertool.hpp"
0023 #include "types/sint8.hpp"
0024 #include "types/sint16.hpp"
0025 #include "types/sint32.hpp"
0026 #include "types/sint64.hpp"
0027 #include "types/uint8.hpp"
0028 #include "types/uint16.hpp"
0029 #include "types/uint32.hpp"
0030 #include "types/uint64.hpp"
0031 
0032 // TODO: Stranger that you are reading this: please help out and show how to add QVariant::Types for custom datatypes,
0033 // so that instead of this unflexible maintanance mess^WWWunlooped code QItemEditorCreator can be used!
0034 
0035 namespace Kasten {
0036 
0037 PODDelegate::PODDelegate(PODDecoderTool* tool, QObject* parent)
0038     : QStyledItemDelegate(parent)
0039     , mTool(tool)
0040 {
0041     qRegisterMetaType<Binary8>();
0042     qRegisterMetaType<Octal8>();
0043     qRegisterMetaType<Hexadecimal8>();
0044     qRegisterMetaType<SInt8>();
0045     qRegisterMetaType<SInt16>();
0046     qRegisterMetaType<SInt32>();
0047     qRegisterMetaType<SInt64>();
0048     qRegisterMetaType<UInt8>();
0049     qRegisterMetaType<UInt16>();
0050     qRegisterMetaType<UInt32>();
0051     qRegisterMetaType<UInt64>();
0052     qRegisterMetaType<Float32>();
0053     qRegisterMetaType<Float64>();
0054     qRegisterMetaType<Char8>();
0055     qRegisterMetaType<Utf8>();
0056     qRegisterMetaType<Utf16>();
0057 
0058     connect(mTool, &PODDecoderTool::readOnlyChanged, this, &PODDelegate::onReadOnlyChanged);
0059 }
0060 
0061 PODDelegate::~PODDelegate() = default;
0062 
0063 // make sure only editors are created which have a readOnly property
0064 // also beware that for subclasses of QLineEdit (all float editors) the signal
0065 // editingFinished() is only emitted if validator() returns QValidator::Acceptable
0066 // so onEditorDone() is not reached if QValidator::Intermediate
0067 QWidget* PODDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
0068 {
0069     QWidget* result;
0070 
0071     QVariant data = index.data(Qt::EditRole);
0072     if (data.canConvert<Binary8>()) {
0073         auto* editor = new Binary8Editor(parent);
0074         connect(editor, &Binary8Editor::editingFinished,
0075                 this, &PODDelegate::onEditorDone);
0076         result = editor;
0077     } else if (data.canConvert<Octal8>()) {
0078         auto* editor = new Octal8Editor(parent);
0079         connect(editor, &Octal8Editor::editingFinished,
0080                 this, &PODDelegate::onEditorDone);
0081         result = editor;
0082     } else if (data.canConvert<Hexadecimal8>()) {
0083         auto* editor = new Hexadecimal8Editor(parent);
0084         connect(editor, &Hexadecimal8Editor::editingFinished,
0085                 this, &PODDelegate::onEditorDone);
0086         result = editor;
0087     } else if (data.canConvert<SInt8>()) {
0088         SIntSpinBox* editor = SIntSpinBox::createSInt8Spinbox(parent);
0089         connect(editor, &SIntSpinBox::editingFinished,
0090                 this, &PODDelegate::onEditorDone);
0091         result = editor;
0092     } else if (data.canConvert<SInt16>()) {
0093         SIntSpinBox* editor = SIntSpinBox::createSInt16Spinbox(parent);
0094         connect(editor, &SIntSpinBox::editingFinished,
0095                 this, &PODDelegate::onEditorDone);
0096         result = editor;
0097     } else if (data.canConvert<SInt32>()) {
0098         SIntSpinBox* editor = SIntSpinBox::createSInt32Spinbox(parent);
0099         connect(editor, &SIntSpinBox::editingFinished,
0100                 this, &PODDelegate::onEditorDone);
0101         result = editor;
0102     } else if (data.canConvert<SInt64>()) {
0103         SIntSpinBox* editor = SIntSpinBox::createSInt64Spinbox(parent);
0104         connect(editor, &SIntSpinBox::editingFinished,
0105                 this, &PODDelegate::onEditorDone);
0106         result = editor;
0107     } else if (data.canConvert<UInt8>()) {
0108         UIntSpinBox* editor = UIntSpinBox::createUInt8Spinbox(parent);
0109         editor->setBase(mTool->isUnsignedAsHex() ? 16 : 10);
0110         connect(editor, &UIntSpinBox::editingFinished,
0111                 this, &PODDelegate::onEditorDone);
0112         result = editor;
0113     } else if (data.canConvert<UInt16>()) {
0114         UIntSpinBox* editor = UIntSpinBox::createUInt16Spinbox(parent);
0115         editor->setBase(mTool->isUnsignedAsHex() ? 16 : 10);
0116         connect(editor, &UIntSpinBox::editingFinished,
0117                 this, &PODDelegate::onEditorDone);
0118         result = editor;
0119     } else if (data.canConvert<UInt32>()) {
0120         UIntSpinBox* editor = UIntSpinBox::createUInt32Spinbox(parent);
0121         editor->setBase(mTool->isUnsignedAsHex() ? 16 : 10);
0122         connect(editor, &UIntSpinBox::editingFinished,
0123                 this, &PODDelegate::onEditorDone);
0124         result = editor;
0125     } else if (data.canConvert<UInt64>()) {
0126         UIntSpinBox* editor = UIntSpinBox::createUInt64Spinbox(parent);
0127         editor->setBase(mTool->isUnsignedAsHex() ? 16 : 10);
0128         connect(editor, &UIntSpinBox::editingFinished,
0129                 this, &PODDelegate::onEditorDone);
0130         result = editor;
0131     } else if (data.canConvert<Float32>()) {
0132         auto* editor = new Float32Editor(parent);
0133         connect(editor, &Float32Editor::editingFinished,
0134                 this, &PODDelegate::onEditorDone);
0135         result = editor;
0136     } else if (data.canConvert<Float64>()) {
0137         auto* editor = new Float64Editor(parent);
0138         connect(editor, &Float64Editor::editingFinished,
0139                 this, &PODDelegate::onEditorDone);
0140         result = editor;
0141     } else if (data.canConvert<Char8>()) {
0142         auto* editor = new Char8Editor(mTool->charCodec(), parent);
0143         connect(editor, &Char8Editor::editingFinished,
0144                 this, &PODDelegate::onEditorDone);
0145         result = editor;
0146     } else if (data.canConvert<Utf8>()) {
0147         auto* editor = new Utf8Editor(parent);
0148         connect(editor, &Utf8Editor::editingFinished,
0149                 this, &PODDelegate::onEditorDone);
0150         result = editor;
0151     } else if (data.canConvert<Utf16>()) {
0152         auto* editor = new Utf16Editor(parent);
0153         connect(editor, &Utf16Editor::editingFinished,
0154                 this, &PODDelegate::onEditorDone);
0155         result = editor;
0156     } else {
0157         result = QStyledItemDelegate::createEditor(parent, option, index);
0158     }
0159 
0160     mEditor = result;
0161     onReadOnlyChanged(mTool->isReadOnly());
0162 
0163     return result;
0164 }
0165 
0166 void PODDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
0167 {
0168     QVariant data = index.data(Qt::EditRole);
0169 
0170     if (data.canConvert<Binary8>()) {
0171         Binary8 binary8 = data.value<Binary8>();
0172         auto* binary8Editor = qobject_cast<Binary8Editor*>(editor);
0173         binary8Editor->setData(binary8);
0174     } else if (data.canConvert<Octal8>()) {
0175         Octal8 octal8 = data.value<Octal8>();
0176         auto* octal8Editor = qobject_cast<Octal8Editor*>(editor);
0177         octal8Editor->setData(octal8);
0178     } else if (data.canConvert<Hexadecimal8>()) {
0179         Hexadecimal8 hexadecimal8 = data.value<Hexadecimal8>();
0180         auto* hexadecimal8Editor = qobject_cast<Hexadecimal8Editor*>(editor);
0181         hexadecimal8Editor->setData(hexadecimal8);
0182     } else if (data.canConvert<SInt8>()) {
0183         SInt8 sInt8 = data.value<SInt8>();
0184         auto* sInt8Editor = qobject_cast<SIntSpinBox*>(editor);
0185         sInt8Editor->setValue(sInt8.value);
0186     } else if (data.canConvert<SInt16>()) {
0187         SInt16 sInt16 = data.value<SInt16>();
0188         auto* sInt16Editor = qobject_cast<SIntSpinBox*>(editor);
0189         sInt16Editor->setValue(sInt16.value);
0190     } else if (data.canConvert<SInt32>()) {
0191         SInt32 sInt32 = data.value<SInt32>();
0192         auto* sInt32Editor = qobject_cast<SIntSpinBox*>(editor);
0193         sInt32Editor->setValue(sInt32.value);
0194     } else if (data.canConvert<SInt64>()) {
0195         SInt64 sInt64 = data.value<SInt64>();
0196         auto* sInt64Editor = qobject_cast<SIntSpinBox*>(editor);
0197         sInt64Editor->setValue(sInt64.value);
0198     } else if (data.canConvert<UInt8>()) {
0199         UInt8 uInt8 = data.value<UInt8>();
0200         auto* uInt8Editor = qobject_cast<UIntSpinBox*>(editor);
0201         uInt8Editor->setValue(uInt8.value);
0202     } else if (data.canConvert<UInt16>()) {
0203         UInt16 uInt16 = data.value<UInt16>();
0204         auto* uInt16Editor = qobject_cast<UIntSpinBox*>(editor);
0205         uInt16Editor->setValue(uInt16.value);
0206     } else if (data.canConvert<UInt32>()) {
0207         UInt32 uInt32 = data.value<UInt32>();
0208         auto* uInt32Editor = qobject_cast<UIntSpinBox*>(editor);
0209         uInt32Editor->setValue(uInt32.value);
0210     } else if (data.canConvert<UInt64>()) {
0211         UInt64 uInt64 = data.value<UInt64>();
0212         auto* uInt64Editor = qobject_cast<UIntSpinBox*>(editor);
0213         uInt64Editor->setValue(uInt64.value);
0214     } else if (data.canConvert<Float32>()) {
0215         Float32 float32 = data.value<Float32>();
0216         auto* float32Editor = qobject_cast<Float32Editor*>(editor);
0217         float32Editor->setData(float32);
0218     } else if (data.canConvert<Float64>()) {
0219         Float64 float64 = data.value<Float64>();
0220         auto* float64Editor = qobject_cast<Float64Editor*>(editor);
0221         float64Editor->setData(float64);
0222     } else if (data.canConvert<Char8>()) {
0223         Char8 char8 = data.value<Char8>();
0224         auto* char8Editor = qobject_cast<Char8Editor*>(editor);
0225         char8Editor->setData(char8);
0226     } else if (data.canConvert<Utf8>()) {
0227         Utf8 utf8 = data.value<Utf8>();
0228         auto* utf8Editor = qobject_cast<Utf8Editor*>(editor);
0229         utf8Editor->setData(utf8);
0230     } else if (data.canConvert<Utf16>()) {
0231         Utf16 utf16 = data.value<Utf16>();
0232         auto* utf16Editor = qobject_cast<Utf16Editor*>(editor);
0233         utf16Editor->setData(utf16);
0234     } else {
0235         QStyledItemDelegate::setEditorData(editor, index);
0236     }
0237 }
0238 
0239 void PODDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
0240 {
0241     if (mTool->isReadOnly()) {
0242         return;
0243     }
0244 
0245     QVariant data = index.data(Qt::EditRole);
0246 
0247     if (data.canConvert<Binary8>()) {
0248         auto* binary8Editor = qobject_cast<Binary8Editor*>(editor);
0249         model->setData(index, QVariant::fromValue(binary8Editor->data()));
0250     } else if (data.canConvert<Octal8>()) {
0251         auto* octal8Editor = qobject_cast<Octal8Editor*>(editor);
0252         model->setData(index, QVariant::fromValue(octal8Editor->data()));
0253     } else if (data.canConvert<Hexadecimal8>()) {
0254         auto* hexadecimal8Editor = qobject_cast<Hexadecimal8Editor*>(editor);
0255         model->setData(index, QVariant::fromValue(hexadecimal8Editor->data()));
0256     } else if (data.canConvert<SInt8>()) {
0257         auto* sintEditor = qobject_cast<SIntSpinBox*>(editor);
0258         model->setData(index, QVariant::fromValue(SInt8(sintEditor->value())));
0259     } else if (data.canConvert<SInt16>()) {
0260         auto* sintEditor = qobject_cast<SIntSpinBox*>(editor);
0261         model->setData(index, QVariant::fromValue(SInt16(sintEditor->value())));
0262     } else if (data.canConvert<SInt32>()) {
0263         auto* sintEditor = qobject_cast<SIntSpinBox*>(editor);
0264         model->setData(index, QVariant::fromValue(SInt32(sintEditor->value())));
0265     } else if (data.canConvert<SInt64>()) {
0266         auto* sintEditor = qobject_cast<SIntSpinBox*>(editor);
0267         model->setData(index, QVariant::fromValue(SInt64(sintEditor->value())));
0268     } else if (data.canConvert<UInt8>()) {
0269         auto* uintEditor = qobject_cast<UIntSpinBox*>(editor);
0270         model->setData(index, QVariant::fromValue(UInt8(uintEditor->value())));
0271     } else if (data.canConvert<UInt16>()) {
0272         auto* uintEditor = qobject_cast<UIntSpinBox*>(editor);
0273         model->setData(index, QVariant::fromValue(UInt16(uintEditor->value())));
0274     } else if (data.canConvert<UInt32>()) {
0275         auto* uintEditor = qobject_cast<UIntSpinBox*>(editor);
0276         model->setData(index, QVariant::fromValue(UInt32(uintEditor->value())));
0277     } else if (data.canConvert<UInt64>()) {
0278         auto* uintEditor = qobject_cast<UIntSpinBox*>(editor);
0279         model->setData(index, QVariant::fromValue(UInt64(uintEditor->value())));
0280     } else if (data.canConvert<Float32>()) {
0281         auto* float32Editor = qobject_cast<Float32Editor*>(editor);
0282         model->setData(index, QVariant::fromValue(float32Editor->data()));
0283     } else if (data.canConvert<Float64>()) {
0284         auto* float64Editor = qobject_cast<Float64Editor*>(editor);
0285         model->setData(index, QVariant::fromValue(float64Editor->data()));
0286     } else if (data.canConvert<Char8>()) {
0287         auto* char8Editor = qobject_cast<Char8Editor*>(editor);
0288         model->setData(index, QVariant::fromValue(char8Editor->data()));
0289     } else if (data.canConvert<Utf8>()) {
0290         auto* utf8Editor = qobject_cast<Utf8Editor*>(editor);
0291         model->setData(index, QVariant::fromValue(utf8Editor->data()));
0292     } else if (data.canConvert<Utf16>()) {
0293         auto* utf16Editor = qobject_cast<Utf16Editor*>(editor);
0294         model->setData(index, QVariant::fromValue(utf16Editor->data()));
0295     } else {
0296         QStyledItemDelegate::setModelData(editor, model, index);
0297     }
0298 }
0299 
0300 // QSize PODDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const
0301 // {
0302 //      editor->setGeometry(option.rect);
0303 // }
0304 
0305 void PODDelegate::onEditorDone()
0306 {
0307     QWidget* editor = qobject_cast<QWidget*>(sender());
0308     mEditor = nullptr;
0309     Q_EMIT commitData(editor);
0310     Q_EMIT closeEditor(editor);
0311 }
0312 
0313 void PODDelegate::onReadOnlyChanged(bool isReadOnly) const
0314 {
0315     if (mEditor) {
0316         // going by property is slower, but saves writing this call for every widget
0317         mEditor->setProperty("readOnly", isReadOnly);
0318     }
0319 }
0320 
0321 }
0322 
0323 #include "moc_poddelegate.cpp"