QBinaryTranslate/TranslateUI/SequenceView.cpp

209 lines
6.7 KiB
C++
Raw Normal View History

2025-07-17 16:17:39 +00:00
#include "SequenceView.h"
2025-08-05 12:55:43 +00:00
#include "TranslateBasic.h"
2025-07-17 16:17:39 +00:00
#include <QSpinBox>
2025-07-18 14:41:36 +00:00
#include <QJsonDocument>
#include <QJsonObject>
2025-08-05 12:55:43 +00:00
#include <QMenu>
#include <QComboBox>
#include <QItemSelectionModel>
using namespace extract;
2025-08-05 11:26:19 +00:00
using namespace unit_func;
2025-07-17 16:17:39 +00:00
IntDelegate::IntDelegate(int min, int max)
2025-07-18 14:41:36 +00:00
: _min_value(min), _max_value(max) {
2025-07-17 16:17:39 +00:00
}
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
{
2025-07-18 14:41:36 +00:00
auto spin = dynamic_cast<QSpinBox*>(editor);
spin->setRange(_min_value, _max_value);
spin->setValue(index.data(Qt::DisplayRole).toInt());
2025-07-17 16:17:39 +00:00
}
void IntDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
auto value = dynamic_cast<QSpinBox*>(editor);
2025-07-18 14:41:36 +00:00
model->setData(index, value->value(), Qt::EditRole);
2025-07-17 16:17:39 +00:00
}
void IntDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
editor->setGeometry(option.rect);
}
2025-08-05 10:52:25 +00:00
void RuleSetCustom::targetRuleRefresh(const QModelIndex& idx)
2025-07-18 14:41:36 +00:00
{
2025-08-05 14:48:54 +00:00
if (idx.column() == 2) {
auto field_idx = idx.sibling(idx.row(), 0);
auto field_name = field_idx.data(Qt::DisplayRole).toString();
auto rule_idx = idx.sibling(idx.row(), 2);
auto rule_name = rule_idx.data(Qt::DisplayRole).toString();
auto rule_nm = _view.base->extractUnitList()[rule_name];
auto new_inst = std::dynamic_pointer_cast<ExtractUnit>(rule_nm->newDefault());
_view._ruleset->replace(idx.row(), std::make_pair(field_name, new_inst));
// <20><>ListUnitִ<74><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (typeid(*new_inst.get()) == typeid(AsList)) {
auto conv = std::dynamic_pointer_cast<AsList>(new_inst);
if (!conv->elementRule()) {
conv->setElementRule(this->_view.base->defaultExtractUnit());
}
if (!conv->sizeProvider()) {
conv->setSizeProvider(this->_view.base->defaultSizeProvider());
}
}
}
2025-08-05 12:51:12 +00:00
auto rule_insv = (*_view._ruleset)[idx.row()];
2025-07-18 14:41:36 +00:00
auto offset_index = idx.sibling(idx.row(), 1);
2025-08-01 23:06:42 +00:00
auto offset_number = offset_index.data(Qt::DisplayRole).toInt();
2025-08-04 01:27:04 +00:00
rule_insv.second->setOffsetSpan(offset_number);
2025-07-18 14:41:36 +00:00
2025-08-01 07:03:35 +00:00
auto count_index = idx.sibling(idx.row(), 3);
2025-08-05 10:30:24 +00:00
_view._seqs_model->setData(offset_index, rule_insv.second->offsetSpan(), Qt::EditRole);
_view._seqs_model->setData(count_index, rule_insv.second->countWithin(), Qt::EditRole);
2025-07-18 14:41:36 +00:00
auto param_index = idx.sibling(idx.row(), 4);
QJsonObject obj;
2025-08-04 01:27:04 +00:00
rule_insv.second->saveTo(obj);
2025-07-18 14:41:36 +00:00
auto bytes = QJsonDocument(obj).toJson(QJsonDocument::Compact);
2025-08-05 10:30:24 +00:00
_view._seqs_model->setData(param_index, QString::fromUtf8(bytes));
2025-07-18 14:58:49 +00:00
this->resizeColumnsToContents();
2025-07-18 14:41:36 +00:00
}
2025-08-05 10:52:25 +00:00
void RuleSetCustom::showEvent(QShowEvent* e)
2025-08-05 10:30:24 +00:00
{
QTableView::showEvent(e);
membersPresent(this->_view._ruleset, this->_view._seqs_model);
}
2025-08-05 10:52:25 +00:00
RuleSetCustom::RuleSetCustom(std::shared_ptr<TranslateBasic> base,
2025-08-05 14:00:41 +00:00
std::shared_ptr<extract::AsRuleSet> rule_set, QWidget* p /*= nullptr*/)
2025-08-03 09:26:53 +00:00
:QTableView(p)
2025-07-17 16:17:39 +00:00
{
2025-08-04 01:27:04 +00:00
_view._ruleset = rule_set;
2025-08-05 10:30:24 +00:00
_view._seqs_model = new QStandardItemModel();
2025-08-04 01:27:04 +00:00
_view.base = std::make_shared<TranslateBasic>();
2025-08-03 09:26:53 +00:00
2025-08-05 10:30:24 +00:00
this->setModel(_view._seqs_model);
_view._seqs_model->setHorizontalHeaderLabels(QStringList()
2025-08-01 23:06:42 +00:00
<< tr(u8"Field Name") << tr(u8"Bytes Offset") << tr(u8"Translate Rule")
2025-08-01 07:03:35 +00:00
<< tr(u8"Bytes Count") << tr(u8"Arguments"));
2025-07-17 16:17:39 +00:00
2025-07-18 14:41:36 +00:00
auto int_delegate = new IntDelegate(0, INT_MAX);
this->setItemDelegateForColumn(1, int_delegate);
2025-08-04 01:27:04 +00:00
auto rule_delegate = new RuleSelectDelegate(_view.base);
2025-08-01 07:03:35 +00:00
this->setItemDelegateForColumn(2, rule_delegate);
2025-07-17 16:17:39 +00:00
this->setContextMenuPolicy(Qt::CustomContextMenu);
2025-08-05 10:52:25 +00:00
connect(this, &QTableView::customContextMenuRequested, this, &RuleSetCustom::customTranslateRuleEdit);
2025-08-05 11:35:02 +00:00
connect(_view._seqs_model, &QAbstractItemModel::dataChanged, this, &RuleSetCustom::targetRuleRefresh);
2025-07-18 14:58:49 +00:00
2025-07-19 02:58:46 +00:00
connect(this, &QTableView::clicked, [=](const QModelIndex& curr) {
2025-07-18 15:12:48 +00:00
if (!curr.isValid())
return;
2025-08-05 12:51:12 +00:00
emit this->currentRuleChanged(_view._ruleset->operator[](curr.row()).second, curr);
2025-08-01 23:06:42 +00:00
});
2025-07-17 16:17:39 +00:00
}
2025-08-05 10:52:25 +00:00
void RuleSetCustom::customTranslateRuleEdit(const QPoint& pos)
2025-07-17 16:17:39 +00:00
{
QMenu immediate;
2025-08-05 10:52:25 +00:00
immediate.addAction(u8"Add Unit", this, &RuleSetCustom::addTranslateUnit);
immediate.addAction(u8"Remove Unit", this, &RuleSetCustom::removeTranslateUnit);
2025-07-17 16:17:39 +00:00
immediate.exec(this->mapToGlobal(pos));
}
2025-08-05 10:52:25 +00:00
void RuleSetCustom::addTranslateUnit()
2025-07-17 16:17:39 +00:00
{
2025-08-04 01:27:04 +00:00
auto curr_rule = _view.base->defaultExtractUnit()->newDefault();
2025-08-05 12:51:12 +00:00
this->_view._ruleset->append(
QString(u8"rule_%1").arg(_view._ruleset->memberCount()),
2025-08-05 10:30:24 +00:00
std::static_pointer_cast<ExtractUnit>(curr_rule));
2025-07-17 16:17:39 +00:00
2025-08-05 14:00:41 +00:00
auto hex_rule = std::static_pointer_cast<AsHex>(curr_rule);
2025-07-30 16:39:26 +00:00
hex_rule->setCountWithin(1);
2025-07-17 16:17:39 +00:00
2025-08-05 10:30:24 +00:00
membersPresent(this->_view._ruleset, this->_view._seqs_model);
2025-07-17 16:17:39 +00:00
}
2025-08-05 10:52:25 +00:00
void RuleSetCustom::removeTranslateUnit()
2025-07-17 16:17:39 +00:00
{
2025-07-18 15:12:48 +00:00
auto idx_curr = this->currentIndex();
if (!idx_curr.isValid())
return;
2025-07-17 16:17:39 +00:00
2025-08-05 12:51:12 +00:00
_view._ruleset->removeAt(idx_curr.row());
2025-08-05 10:30:24 +00:00
_view._seqs_model->removeRow(idx_curr.row());
2025-07-17 16:17:39 +00:00
}
2025-08-05 14:00:41 +00:00
void RuleSetCustom::membersPresent(std::shared_ptr<extract::AsRuleSet> ruleset, QStandardItemModel* model)
2025-08-05 10:30:24 +00:00
{
model->removeRows(0, model->rowCount());
2025-08-05 12:51:12 +00:00
for (auto uidx = 0; uidx < ruleset->memberCount(); ++uidx) {
auto u_pair = ruleset->operator[](uidx);
2025-08-05 10:30:24 +00:00
QList<QStandardItem*> new_row;
new_row << new QStandardItem(u_pair.first);
new_row << new QStandardItem(QString("%1").arg(u_pair.second->offsetSpan()));
new_row << new QStandardItem(_view.base->defaultExtractUnit()->name());
new_row << new QStandardItem(QString("%1").arg(u_pair.second->countWithin()));
new_row.last()->setEditable(false);
QJsonObject obj;
u_pair.second->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->_view._seqs_model->appendRow(new_row);
}
this->resizeColumnsToContents();
}
2025-08-01 23:06:42 +00:00
2025-07-18 14:41:36 +00:00
RuleSelectDelegate::RuleSelectDelegate(std::shared_ptr<TranslateBasic> ins)
:_kernel(ins) {
2025-07-17 16:17:39 +00:00
}
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
{
2025-08-02 07:02:35 +00:00
auto rule_names = this->_kernel->extractUnitList().keys();
2025-07-17 16:17:39 +00:00
std::sort(rule_names.begin(), rule_names.end());
2025-07-18 14:41:36 +00:00
auto combo = dynamic_cast<QComboBox*>(editor);
combo->addItems(rule_names);
combo->setCurrentText(index.data(Qt::DisplayRole).toString());
2025-07-17 16:17:39 +00:00
}
void RuleSelectDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
auto rule_name = dynamic_cast<QComboBox*>(editor)->currentText();
model->setData(index, rule_name, Qt::EditRole);
}
void RuleSelectDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
editor->setGeometry(option.rect);
}