This commit is contained in:
codeboss 2025-08-04 09:27:04 +08:00
parent 094ac3347e
commit afff561478
9 changed files with 188 additions and 59 deletions

View File

@ -37,40 +37,46 @@ void IntDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewIt
void SequenceRulesView::currentRuleRefresh(const QModelIndex& idx)
{
auto rule_insv = _rule_v._rule_sequence.at(idx.row());
auto rule_insv = _view._ruleset->_rules[idx.row()];
auto offset_index = idx.sibling(idx.row(), 1);
auto offset_number = offset_index.data(Qt::DisplayRole).toInt();
rule_insv->setOffsetSpan(offset_number);
rule_insv.second->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);
_view._sequence_model->setData(offset_index, rule_insv.second->offsetSpan(), Qt::EditRole);
_view._sequence_model->setData(count_index, rule_insv.second->countWithin(), Qt::EditRole);
auto param_index = idx.sibling(idx.row(), 4);
QJsonObject obj;
rule_insv->saveTo(obj);
rule_insv.second->saveTo(obj);
auto bytes = QJsonDocument(obj).toJson(QJsonDocument::Compact);
_rule_v._sequence_model->setData(param_index, QString::fromUtf8(bytes));
_view._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<ExtractUnit>(rule_nm->newDefault());
_rule_v._rule_sequence.replace(idx.row(), new_inst);
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->_rules.replace(idx.row(), std::make_pair(field_name, new_inst));
// ¶ÔListUnitÖ´ÐÐÌØÊâ³õʼ»¯²½Öè
if (typeid(*new_inst.get()) == typeid(BytesAsList)) {
auto conv = std::dynamic_pointer_cast<BytesAsList>(new_inst);
if (!conv->elementRule()) {
conv->appendElementRule(this->_rule_v.base->defaultExtractUnit());
conv->appendElementRule(this->_view.base->defaultExtractUnit());
}
if (!conv->sizeProvider()) {
conv->setSizeProvider(this->_rule_v.base->defaultSizeProvider());
conv->setSizeProvider(this->_view.base->defaultSizeProvider());
}
}
@ -78,20 +84,21 @@ void SequenceRulesView::peersRuleChanged(const QModelIndex& idx)
}
#include <QItemSelectionModel>
SequenceRulesView::SequenceRulesView(QWidget* p /*= nullptr*/)
SequenceRulesView::SequenceRulesView(std::shared_ptr<extract::BytesAsRuleSet> rule_set, QWidget* p /*= nullptr*/)
:QTableView(p)
{
_rule_v._sequence_model = new QStandardItemModel();
_rule_v.base = std::make_shared<TranslateBasic>();
_view._ruleset = rule_set;
_view._sequence_model = new QStandardItemModel();
_view.base = std::make_shared<TranslateBasic>();
this->setModel(_rule_v._sequence_model);
_rule_v._sequence_model->setHorizontalHeaderLabels(QStringList()
this->setModel(_view._sequence_model);
_view._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);
auto rule_delegate = new RuleSelectDelegate(_view.base);
this->setItemDelegateForColumn(2, rule_delegate);
this->setContextMenuPolicy(Qt::CustomContextMenu);
@ -103,7 +110,7 @@ SequenceRulesView::SequenceRulesView(QWidget* p /*= nullptr*/)
if (!curr.isValid())
return;
emit this->currentRuleChanged(_rule_v._rule_sequence[curr.row()], curr);
emit this->currentRuleChanged(_view._ruleset->_rules[curr.row()].second, curr);
});
}
@ -118,17 +125,18 @@ void SequenceRulesView::customTranslateRuleEdit(const QPoint& pos)
void SequenceRulesView::addTranslateUnit()
{
auto row_cnt = this->_rule_v._sequence_model->rowCount();
auto row_cnt = this->_view._sequence_model->rowCount();
QList<QStandardItem*> 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(_view.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<AbstractExtractor>(curr_rule);
auto curr_rule = _view.base->defaultExtractUnit()->newDefault();
this->_view._ruleset->_rules.append(
new_row.first()->text(), std::static_pointer_cast<ExtractUnit>(curr_rule));
auto hex_rule = std::static_pointer_cast<BytesAsHex>(curr_rule);
hex_rule->setCountWithin(1);
@ -140,7 +148,7 @@ void SequenceRulesView::addTranslateUnit()
new_row << new QStandardItem(json_doc);
new_row.last()->setEditable(false);
this->_rule_v._sequence_model->appendRow(new_row);
this->_view._sequence_model->appendRow(new_row);
this->resizeColumnsToContents();
}
@ -150,8 +158,8 @@ void SequenceRulesView::removeTranslateUnit()
if (!idx_curr.isValid())
return;
_rule_v._rule_sequence.removeAt(idx_curr.row());
_rule_v._sequence_model->removeRow(idx_curr.row());
_view._ruleset->_rules.removeAt(idx_curr.row());
_view._sequence_model->removeRow(idx_curr.row());
}

View File

@ -61,8 +61,8 @@ public:
struct __Private {
QStandardItemModel* _sequence_model;
std::shared_ptr<TranslateBasic> base = nullptr;
QList<std::shared_ptr<ExtractUnit>> _rule_sequence;
} _rule_v;
std::shared_ptr<extract::BytesAsRuleSet> _ruleset = nullptr;
} _view;
signals:
void currentRuleChanged(std::shared_ptr<ExtractUnit> u, const QModelIndex& i) const;
@ -72,7 +72,7 @@ public:
void peersRuleChanged(const QModelIndex& idx_rule);
public:
SequenceRulesView(QWidget* p = nullptr);
SequenceRulesView(std::shared_ptr<extract::BytesAsRuleSet> rule_set, QWidget* p = nullptr);
void customTranslateRuleEdit(const QPoint& pos);
void addTranslateUnit();

View File

@ -8,11 +8,14 @@
#include <QTabWidget>
#include "TranslateBasic.h"
StructuralRuleView::StructuralRuleView(QWidget* p /*= nullptr*/)
:QWidget(p),
_sequence_view(new SequenceRulesView(this)),
StructuralRuleView::StructuralRuleView(
std::shared_ptr<extract::BytesAsRuleSet> inst_r, QWidget* p /*= nullptr*/)
: QWidget(p),
_sequence_view(new SequenceRulesView(inst_r, this)),
_configs_stack(new QStackedWidget(this))
{
this->_current_fields_cache = std::make_shared<FieldManagerLayer>("", nullptr);
auto layout = new QVBoxLayout(this);
auto split = new QSplitter(Qt::Horizontal, this);
layout->addWidget(split);
@ -27,7 +30,7 @@ StructuralRuleView::StructuralRuleView(QWidget* p /*= nullptr*/)
_configs_stack->addWidget(encode_config);
auto combine_config = new BitCombineConfiguration(this);
_configs_stack->addWidget(combine_config);
auto list_config = new ListUnitConfiguration(this->_sequence_view->_rule_v.base, this);
auto list_config = new ListUnitConfiguration(this->_sequence_view->_view.base, this);
_configs_stack->addWidget(list_config);
connect(count_span, &CountWithinConfiguration::currentRuleChanged,
@ -58,6 +61,7 @@ StructuralRuleView::StructuralRuleView(QWidget* p /*= nullptr*/)
break;
case DataType::LIST_COLLECTION:
_configs_stack->setCurrentIndex(4);
cacheRefresh(i, list_config);
break;
default:
_configs_stack->setCurrentIndex(0);
@ -66,6 +70,24 @@ StructuralRuleView::StructuralRuleView(QWidget* p /*= nullptr*/)
});
}
void StructuralRuleView::cacheRefresh(const QModelIndex& curr, ListUnitConfiguration* t)
{
if (!curr.isValid())
return;
this->_current_fields_cache->clear();
this->_sequence_view->_view._ruleset->registSubField(this->_current_fields_cache);
auto field_idx = curr.sibling(curr.row(), 0);
this->_current_fields_cache->bindCurrent(field_idx.data(Qt::DisplayRole).toString());
auto ins = this->_sequence_view->_view._ruleset->_rules[curr.row()];
auto conv = std::dynamic_pointer_cast<extract::BytesAsList>(ins.second);
if (conv) {
t->currentRuleAccept(conv, curr, this->_current_fields_cache);
}
}
EmptyConfiguration::EmptyConfiguration(QWidget* p/*=nullptr*/)
{
auto layout = new QVBoxLayout(this);
@ -311,6 +333,11 @@ void ListUnitConfiguration::reloadContent(
QSignalBlocker m(_size_layout_select);
_size_layout_select->setCurrentText(u->sizeProvider()->name());
QSignalBlocker vll(_prev_field_refer);
auto item_list = getter->prevFields();
this->_prev_field_refer->clear();
this->_prev_field_refer->addItems(item_list.keys());
if (typeid(*u->sizeProvider().get()) == typeid(ConstNumberProvider)) {
_configs_stack->setCurrentIndex(0);
QSignalBlocker v(_const_number_input);
@ -320,10 +347,6 @@ void ListUnitConfiguration::reloadContent(
else if (typeid(*u->sizeProvider().get()) == typeid(InterpretedNumberPrivider)) {
_configs_stack->setCurrentIndex(1);
auto conv = std::dynamic_pointer_cast<InterpretedNumberPrivider>(u->sizeProvider());
QSignalBlocker v(_prev_field_refer);
auto item_list = getter->prevFields();
this->_prev_field_refer->clear();
this->_prev_field_refer->addItems(item_list.keys());
this->_prev_field_refer->setCurrentText(conv->name());
}
}

View File

@ -119,8 +119,11 @@ private:
SequenceRulesView* const _sequence_view;
QStackedWidget* const _configs_stack;
public:
StructuralRuleView(QWidget* p = nullptr);
std::shared_ptr<FieldManagerLayer> _current_fields_cache = nullptr;
public:
StructuralRuleView(std::shared_ptr<extract::BytesAsRuleSet> inst_r, QWidget* p = nullptr);
void cacheRefresh(const QModelIndex &curr, ListUnitConfiguration* t);
};

View File

@ -93,7 +93,7 @@ QHash<QString, std::shared_ptr<RuleMatch>> TranslateBasic::ruleMatchList() const
void ConstNumberProvider::bindInput(std::shared_ptr<DataAccessContext> inst)
{
}
QString ConstNumberProvider::name() const
@ -208,13 +208,49 @@ QVariant ValueAccess::get(const QString& unique_key) const
return QVariant();
}
FieldSetterLayer::FieldSetterLayer(const QString& self, std::shared_ptr<ScopeFieldsSetter> instp)
bool FieldManagerLayer::bindCurrent(const QString& unique_key)
{
for (auto index = 0; index < __Private::_fields_map.size(); ++index) {
auto pair = __Private::_fields_map[index];
if (pair.first == unique_key) {
__Private::_fields_map = __Private::_fields_map.mid(0, index);
return true;
}
}
return false;
}
QHash<QString, DataType> FieldManagerLayer::prevFields() const
{
QHash<QString, DataType> fields;
for(auto pair : __Private::_fields_map)
fields[pair.first] = pair.second;
return fields;
}
void FieldManagerLayer::clear()
{
__Private::_fields_map.clear();
}
FieldManagerLayer::FieldManagerLayer(const QString& self, std::shared_ptr<ScopeFieldsSetter> instp)
{
_setter._rule_name = self;
_setter._parent_setter = instp;
}
void FieldSetterLayer::setField(const QString& name, DataType type)
#include <stdexcept>
void FieldManagerLayer::setField(const QString& name, DataType type)
{
_setter._parent_setter->setField(QString("%1.%2").arg(_setter._rule_name, name), type);
if (_setter._parent_setter)
_setter._parent_setter->setField(QString("%1.%2").arg(_setter._rule_name, name), type);
else {
for (auto pair : __Private::_fields_map) {
if (pair.first == name)
throw new std::invalid_argument("×Ö¶ÎÃû³ÆÖظ´");
}
__Private::_fields_map << std::make_pair(name, type);
}
}
QList<std::pair<QString, DataType>> FieldManagerLayer::__Private::_fields_map;

View File

@ -34,6 +34,8 @@ public:
/// <param name="name"></param>
/// <param name="type"></param>
virtual void setField(const QString& name, DataType type) = 0;
virtual void clear() = 0;
};
// ================================================================
@ -199,15 +201,21 @@ public:
QVariant get(const QString& unique_key) const override;
};
class FieldSetterLayer : public ScopeFieldsSetter {
class FieldManagerLayer : public ScopeFieldsSetter, public ScopeFieldsGetter {
public:
struct __Private {
QString _rule_name;
std::shared_ptr<ScopeFieldsSetter> _parent_setter;
std::shared_ptr<ScopeFieldsSetter> _parent_setter = nullptr;
static QList<std::pair<QString, DataType>> _fields_map;
}_setter;
bool bindCurrent(const QString& unique_key) override;
QHash<QString, DataType> prevFields() const override;
void clear() override;
public:
FieldSetterLayer(const QString& self, std::shared_ptr<ScopeFieldsSetter> instp);
FieldManagerLayer(const QString& self, std::shared_ptr<ScopeFieldsSetter> instp);
void setField(const QString& name, DataType type) override;
};
};

View File

@ -435,7 +435,7 @@ std::shared_ptr<Serializable> BytesAsList::newDefault() const
void BytesAsList::registSubField(std::shared_ptr<ScopeFieldsSetter> inst)
{
inst->setField("ls", this->_list._bind_unit->outType());
auto layer = std::make_shared<FieldSetterLayer>("ls", inst);
auto layer = std::make_shared<FieldManagerLayer>("ls", inst);
this->_list._bind_unit->registSubField(layer);
}
@ -552,17 +552,17 @@ void BytesAsUnion::registSubField(std::shared_ptr<ScopeFieldsSetter> inst)
{
for (auto rl : this->_union._rule_list) {
inst->setField(rl->name(), rl->bindRule()->outType());
auto layer = std::make_shared<FieldSetterLayer>(rl->name(), inst);
auto layer = std::make_shared<FieldManagerLayer>(rl->name(), inst);
rl->bindRule()->registSubField(layer);
}
}
void BytesAsRuleSet::registSubField(std::shared_ptr<ScopeFieldsSetter> inst)
{
for (auto rl_key : this->_rules._sub_rules.keys()){
auto rlinst = this->_rules._sub_rules[rl_key];
for (auto rl_key : this->_rules.fieldNames()){
auto rlinst = this->_rules[rl_key];
inst->setField(rl_key, rlinst->outType());
auto layer = std::make_shared<FieldSetterLayer>(rl_key, inst);
auto layer = std::make_shared<FieldManagerLayer>(rl_key, inst);
rlinst->registSubField(layer);
}
}
@ -570,11 +570,11 @@ void BytesAsRuleSet::registSubField(std::shared_ptr<ScopeFieldsSetter> inst)
void BytesAsRuleSet::parse(const QByteArray& bytes, std::shared_ptr<DataAccessContext> out) const
{
auto bufx = bytes;
for (auto keym : this->_rules._sub_rules.keys()) {
for (auto keym : this->_rules.fieldNames()) {
auto rule_context = std::make_shared<ValueAccess>();
rule_context->init(keym, out);
auto rule = this->_rules._sub_rules[keym];
auto rule = this->_rules[keym];
bufx = bufx.mid(rule->offsetSpan());
auto count = rule->countWithin();
auto secx = bufx.mid(0, count);
@ -627,7 +627,7 @@ void BytesAsRuleSet::loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonO
auto xdev = core->extractUnitList()[match_name]->newDefault();
xdev->loadFrom(core, match_obj);
_rules._sub_rules[key] = std::dynamic_pointer_cast<ExtractUnit>(xdev);
_rules._sub_rules << std::make_pair(key, std::dynamic_pointer_cast<ExtractUnit>(xdev));
}
}
@ -637,10 +637,11 @@ void BytesAsRuleSet::saveTo(QJsonObject& obj) const
INT32_SAVE(_rules._byte_offset, obj);
QJsonArray array;
for (auto key : _rules._sub_rules.keys()) {
for (auto pairk : _rules._sub_rules) {
QJsonObject rule_obj, match_obj;
auto info = _rules._sub_rules[key];
auto key = pairk.first;
auto info = pairk.second;
STRING_SAVE(key, rule_obj);
QString match_name = info->name();
STRING_SAVE(match_name, rule_obj);
@ -656,3 +657,43 @@ std::shared_ptr<Serializable> BytesAsRuleSet::newDefault() const
{
return std::make_shared<BytesAsRuleSet>();
}
std::pair<QString, std::shared_ptr<ExtractUnit>> BytesAsRuleSet::__Private::operator[](int index) const
{
return this->_sub_rules[index];
}
void BytesAsRuleSet::__Private::replace(int index, std::pair<QString, std::shared_ptr<ExtractUnit>> inst)
{
this->_sub_rules.replace(index, inst);
}
extract::BytesAsRuleSet::__Private& BytesAsRuleSet::__Private::append(const QString& nm, std::shared_ptr<ExtractUnit> u)
{
this->_sub_rules.append(std::make_pair(nm, u));
return *this;
}
void BytesAsRuleSet::__Private::removeAt(int index)
{
this->_sub_rules.removeAt(index);
}
QList<QString> BytesAsRuleSet::__Private::fieldNames() const
{
QList<QString> fields_store;
for (auto fpair : this->_sub_rules) {
fields_store << fpair.first;
}
return fields_store;;
}
std::shared_ptr<ExtractUnit> BytesAsRuleSet::__Private::operator[](const QString& field) const
{
for (auto pair : this->_sub_rules) {
if(pair.first == field)
return pair.second;
}
return std::shared_ptr<ExtractUnit>();
}

View File

@ -255,7 +255,16 @@ namespace extract {
public:
struct __Private {
int _byte_offset = 0, _byte_count = 1;
QHash<QString, std::shared_ptr<ExtractUnit>> _sub_rules;
QList<std::pair<QString, std::shared_ptr<ExtractUnit>>> _sub_rules;
QList<QString> fieldNames() const;
std::shared_ptr<ExtractUnit> operator[](const QString &field) const;
std::pair<QString, std::shared_ptr<ExtractUnit>> operator[](int index) const;
void replace(int index, std::pair<QString, std::shared_ptr<ExtractUnit>> inst);
void removeAt(int index);
__Private& append(const QString& nm, std::shared_ptr<ExtractUnit> u);
}_rules;
public:

View File

@ -10,7 +10,8 @@ int main(int argc, char *argv[])
{
QApplication app(argc, argv);
StructuralRuleView v;
auto vx = std::make_shared< extract::BytesAsRuleSet>();
StructuralRuleView v(vx);
v.show();
return app.exec();