#include "SequenceView.h" #include #include #include #include "TranslateBasic.h" using namespace extract; IntDelegate::IntDelegate(int min, int max) : _min_value(min), _max_value(max) { } QWidget* IntDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { return new QSpinBox(parent); } void IntDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { auto spin = dynamic_cast(editor); spin->setRange(_min_value, _max_value); spin->setValue(index.data(Qt::DisplayRole).toInt()); } void IntDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { auto value = dynamic_cast(editor); model->setData(index, value->value(), Qt::EditRole); emit this->valueChanged(index); } void IntDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { editor->setGeometry(option.rect); } void SequenceRulesView::currentRuleRefresh(const QModelIndex& idx) { auto rule_insv = _rule_v._rule_sequence.at(idx.row()); auto offset_index = idx.sibling(idx.row(), 1); auto offset_number = offset_index.data(Qt::DisplayRole).toInt(); rule_insv->setOffsetSpan(offset_number); auto count_index = idx.sibling(idx.row(), 3); _rule_v._sequence_model->setData(offset_index, rule_insv->offsetSpan(), Qt::EditRole); _rule_v._sequence_model->setData(count_index, rule_insv->countWithin(), Qt::EditRole); auto param_index = idx.sibling(idx.row(), 4); QJsonObject obj; rule_insv->saveTo(obj); auto bytes = QJsonDocument(obj).toJson(QJsonDocument::Compact); _rule_v._sequence_model->setData(param_index, QString::fromUtf8(bytes)); this->resizeColumnsToContents(); } void SequenceRulesView::peersRuleChanged(const QModelIndex& idx) { auto rule_idx = idx.sibling(idx.row(), 2); auto rule_nm = _rule_v.base->extractUnitList()[rule_idx.data(Qt::DisplayRole).toString()]; auto new_inst = std::dynamic_pointer_cast(rule_nm->newDefault()); _rule_v._rule_sequence.replace(idx.row(), new_inst); if (typeid(*new_inst.get()) == typeid(BytesAsList)) { auto conv = std::dynamic_pointer_cast(new_inst); if (!conv->elementRule()) { conv->appendElementRule(this->_rule_v.base->defaultExtractUnit()); } if (!conv->sizeProvider()) { conv->setSizeProvider(this->_rule_v.base->defaultSizeProvider()); } } currentRuleRefresh(idx); } #include SequenceRulesView::SequenceRulesView(QWidget* p /*= nullptr*/) :QTableView(p) { _rule_v._sequence_model = new QStandardItemModel(); _rule_v.base = std::make_shared(); this->setModel(_rule_v._sequence_model); _rule_v._sequence_model->setHorizontalHeaderLabels(QStringList() << tr(u8"Field Name") << tr(u8"Bytes Offset") << tr(u8"Translate Rule") << tr(u8"Bytes Count") << tr(u8"Arguments")); auto int_delegate = new IntDelegate(0, INT_MAX); this->setItemDelegateForColumn(1, int_delegate); auto rule_delegate = new RuleSelectDelegate(_rule_v.base); this->setItemDelegateForColumn(2, rule_delegate); this->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &QTableView::customContextMenuRequested, this, &SequenceRulesView::customTranslateRuleEdit); connect(rule_delegate, &RuleSelectDelegate::dataChanged, this, &SequenceRulesView::peersRuleChanged); connect(int_delegate, &IntDelegate::valueChanged, this, &SequenceRulesView::currentRuleRefresh); connect(this, &QTableView::clicked, [=](const QModelIndex& curr) { if (!curr.isValid()) return; emit this->currentRuleChanged(_rule_v._rule_sequence[curr.row()], curr); }); } #include void SequenceRulesView::customTranslateRuleEdit(const QPoint& pos) { QMenu immediate; immediate.addAction(u8"Add Unit", this, &SequenceRulesView::addTranslateUnit); immediate.addAction(u8"Remove Unit", this, &SequenceRulesView::removeTranslateUnit); immediate.exec(this->mapToGlobal(pos)); } void SequenceRulesView::addTranslateUnit() { auto row_cnt = this->_rule_v._sequence_model->rowCount(); QList new_row; new_row << new QStandardItem(QString(u8"rule_%1").arg(row_cnt)); new_row << new QStandardItem(u8"0"); new_row << new QStandardItem(_rule_v.base->defaultExtractUnit()->name()); new_row << new QStandardItem(u8"1"); new_row.last()->setEditable(false); auto curr_rule = _rule_v.base->defaultExtractUnit()->newDefault(); this->_rule_v._rule_sequence << std::static_pointer_cast(curr_rule); auto hex_rule = std::static_pointer_cast(curr_rule); hex_rule->setCountWithin(1); QJsonObject obj; curr_rule->saveTo(obj); auto bytes = QJsonDocument(obj).toJson(QJsonDocument::Compact); auto json_doc = QString::fromUtf8(bytes); new_row << new QStandardItem(json_doc); new_row.last()->setEditable(false); this->_rule_v._sequence_model->appendRow(new_row); this->resizeColumnsToContents(); } void SequenceRulesView::removeTranslateUnit() { auto idx_curr = this->currentIndex(); if (!idx_curr.isValid()) return; _rule_v._rule_sequence.removeAt(idx_curr.row()); _rule_v._sequence_model->removeRow(idx_curr.row()); } RuleSelectDelegate::RuleSelectDelegate(std::shared_ptr ins) :_kernel(ins) { } #include QWidget* RuleSelectDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { return new QComboBox(parent); } void RuleSelectDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { auto rule_names = this->_kernel->extractUnitList().keys(); std::sort(rule_names.begin(), rule_names.end()); auto combo = dynamic_cast(editor); combo->addItems(rule_names); combo->setCurrentText(index.data(Qt::DisplayRole).toString()); } void RuleSelectDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { auto rule_name = dynamic_cast(editor)->currentText(); model->setData(index, rule_name, Qt::EditRole); emit this->dataChanged(index); } void RuleSelectDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { editor->setGeometry(option.rect); }