#include "SequenceView.h" #include #include #include 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); } #include "TranslateBasic.h" void SequenceView::tidyRuleAt(const QModelIndex& idx) { auto rule_idx = idx.sibling(idx.row(), 3); auto rule_nm = base->extactors()[rule_idx.data(Qt::DisplayRole).toString()]; auto new_inst = std::dynamic_pointer_cast(rule_nm->newDefault()); _rule_sequence.replace(idx.row(), new_inst); auto offset_index = idx.sibling(idx.row(), 1); auto offset_number = offset_index.data(Qt::DisplayRole).toInt(); auto count_index = idx.sibling(idx.row(), 2); auto count_number = count_index.data(Qt::DisplayRole).toInt(); auto rule_insv = std::dynamic_pointer_cast(new_inst); if (rule_insv) { rule_insv->setOffsetFromPrevious(offset_number); rule_insv->setCountWithinParse(count_number); } _sequence_model->setData(offset_index, new_inst->offsetFromPrevious(), Qt::EditRole); _sequence_model->setData(count_index, new_inst->countWithinParse(), Qt::EditRole); auto param_index = idx.sibling(idx.row(), 4); QJsonObject obj; rule_insv->saveTo(obj); auto bytes = QJsonDocument(obj).toJson(QJsonDocument::Compact); _sequence_model->setData(param_index, QString::fromUtf8(bytes)); this->resizeColumnsToContents(); } #include SequenceView::SequenceView(QWidget* p /*= nullptr*/) :QTableView(p), _sequence_model(new QStandardItemModel), base(std::make_shared()) { this->setModel(_sequence_model); _sequence_model->setHorizontalHeaderLabels(QStringList() << tr(u8"Field Name") << tr(u8"Bytes Offset") << tr(u8"Bytes Count") << tr(u8"Translate Rule") << tr(u8"Arguments")); auto int_delegate = new IntDelegate(0, INT_MAX); this->setItemDelegateForColumn(1, int_delegate); this->setItemDelegateForColumn(2, int_delegate); auto rule_delegate = new RuleSelectDelegate(base); this->setItemDelegateForColumn(3, rule_delegate); this->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &QTableView::customContextMenuRequested, this, &SequenceView::customTranslateRuleEdit); connect(rule_delegate, &RuleSelectDelegate::dataChanged, this, &SequenceView::tidyRuleAt); connect(int_delegate, &IntDelegate::valueChanged, this, &SequenceView::tidyRuleAt); auto select_model = this->selectionModel(); connect(select_model, &QItemSelectionModel::currentRowChanged, [=](const QModelIndex& curr) { if (!curr.isValid()) return; emit this->currentRuleChanged(_rule_sequence[curr.row()]); }); } #include void SequenceView::customTranslateRuleEdit(const QPoint& pos) { QMenu immediate; immediate.addAction(u8"Add Unit", this, &SequenceView::addTranslateUnit); immediate.addAction(u8"Remove Unit", this, &SequenceView::removeTranslateUnit); immediate.exec(this->mapToGlobal(pos)); } void SequenceView::addTranslateUnit() { auto row_cnt = this->_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(u8"1"); new_row << new QStandardItem(base->defaultRule()->name()); auto curr_rule = base->defaultRule()->newDefault(); this->_rule_sequence << std::static_pointer_cast(curr_rule); auto hex_rule = std::static_pointer_cast(curr_rule); hex_rule->setCountWithinParse(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); this->_sequence_model->appendRow(new_row); this->resizeColumnsToContents(); } void SequenceView::removeTranslateUnit() { auto idx_curr = this->currentIndex(); if (!idx_curr.isValid()) return; _rule_sequence.removeAt(idx_curr.row()); _sequence_model->removeRow(idx_curr.row()); } TranslateBasic::TranslateBasic() { std::shared_ptr u_ptr = std::make_shared(); _extractor_types[u_ptr->name()] = u_ptr; u_ptr = std::make_shared(); _extractor_types[u_ptr->name()] = u_ptr; u_ptr = std::make_shared(); _extractor_types[u_ptr->name()] = u_ptr; u_ptr = std::make_shared(); _extractor_types[u_ptr->name()] = u_ptr; this->_default_translate_rule = u_ptr; } std::shared_ptr TranslateBasic::defaultRule() const { return _default_translate_rule; } QHash> TranslateBasic::extactors() const { return _extractor_types; } 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->extactors().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); }