#include "WrapConfigs.h" #include #include #include #include using namespace configurations; WrapConfigs::WrapConfigs(std::shared_ptr _base, QWidget* p) : QWidget(p), _bind_base(_base), _alias_view(new QTableView(this)), _alias_model(new QStandardItemModel(this)), _configurations(new QStackedWidget(this)) { auto layout = new QVBoxLayout(this); auto split = new QSplitter(this); layout->addWidget(split); split->addWidget(_alias_view); split->addWidget(_configurations); _alias_view->setModel(_alias_model); _alias_model->setHorizontalHeaderLabels(QStringList() << u8"UnitType" << u8"UnitAlias" << u8"Content"); aliasReload(); _alias_view->setContextMenuPolicy(Qt::CustomContextMenu); _alias_view->setItemDelegateForColumn(1, new RuleSelectDelegate(_base)); connect(_alias_model, &QStandardItemModel::itemChanged, this, &WrapConfigs::dataChanged); connect(_alias_view, &QTableView::customContextMenuRequested, [=](const QPoint& pt) { QMenu menu; menu.addAction("Add Alias", this, &WrapConfigs::aliasAppend); menu.addAction("Remove", this, &WrapConfigs::aliasRemove); menu.exec(_alias_view->mapToGlobal(pt)); }); auto empty_panel = new EmptyConfiguration(this); auto count_panel = new CountWithinConfiguration(this); auto encode_panel = new EncodingConfiguration(this); auto bitcombine_panel = new BitCombineConfiguration(this); _configurations->addWidget(empty_panel); _configurations->addWidget(count_panel); _configurations->addWidget(encode_panel); _configurations->addWidget(bitcombine_panel); connect(count_panel, &CountWithinConfiguration::currentRuleChanged, this, &WrapConfigs::aliasReload); connect(encode_panel, &EncodingConfiguration::currentRuleChanged, this, &WrapConfigs::aliasReload); connect(bitcombine_panel, &BitCombineConfiguration::currentRuleChanged, this, &WrapConfigs::aliasReload); connect(_alias_view, &QTableView::clicked, [=](const QModelIndex& idx) { if (!idx.isValid()) return; auto alias_key = _bind_base->delegateAlias()[idx.row()]; auto delt_inst = _bind_base->operator[](alias_key); switch (delt_inst->outType()) { case DataType::Flt32: case DataType::Dbl64: case DataType::COMPLEX_RULESET: case DataType::LIST_COLLECTION: case DataType::UNION_COMBINATE: _configurations->setCurrentIndex(0); break; default: { if (typeid(*delt_inst) == typeid(extract::AsHex) || typeid(*delt_inst) == typeid(extract::AsInteger) || typeid(*delt_inst) == typeid(extract::AsUnsigned)) { _configurations->setCurrentIndex(1); count_panel->currentRuleAccept(delt_inst, idx); } else if (typeid(*delt_inst) == typeid(extract::AsBitCombine)) { _configurations->setCurrentIndex(3); bitcombine_panel->currentRuleAccept(delt_inst, idx); } else if (typeid(*delt_inst) == typeid(extract::AsString)) { _configurations->setCurrentIndex(2); encode_panel->currentRuleAccept(delt_inst, idx); } }break; } }); } #include void WrapConfigs::aliasReload() { auto row_cnt = _alias_model->rowCount(); _alias_model->removeRows(0, row_cnt); auto alias_keys = _bind_base->delegateAlias(); for (auto key_nm : alias_keys) { QList row; auto unit_ins = _bind_base->operator[](key_nm); row << new QStandardItem(key_nm); row << new QStandardItem(unit_ins->unitType()); QJsonObject content; unit_ins->saveTo(content); auto bytes = QJsonDocument(content).toJson(QJsonDocument::Compact); row << new QStandardItem(QString::fromUtf8(bytes)); switch (unit_ins->outType()) { case DataType::LIST_COLLECTION: case DataType::UNION_COMBINATE: throw new BaseException(u8"Invalid Alias BaseType!"); case DataType::COMPLEX_RULESET: for (auto it : row) it->setEditable(false); break; default: row.last()->setEditable(false); break; } _alias_model->appendRow(row); } _alias_view->resizeColumnsToContents(); } #include void WrapConfigs::aliasAppend() { auto name = QInputDialog::getText(this, "AliasName Input", "Name"); if (name == "") return; auto exists = _bind_base->delegateAlias(); while (exists.contains(name)) name += "#"; auto ins = _bind_base->defaultExtractUnit()->newDefault(); auto nins = std::dynamic_pointer_cast(ins); nins->setAlias(name); _bind_base->addDelegate(nins); aliasReload(); } void WrapConfigs::aliasRemove() { auto index = _alias_view->currentIndex(); if (!index.isValid()) return; auto origin_key = _bind_base->delegateAlias()[index.row()]; _bind_base->removeDelegate(origin_key); aliasReload(); } #include void WrapConfigs::dataChanged(QStandardItem* cell) { switch (cell->column()) { case 0: { // 修改alias-name auto cell_name = cell->text(); auto total_alias_set = _bind_base->delegateAlias(); auto origin_key = total_alias_set.at(cell->row()); auto appoint_unit = _bind_base->operator[](origin_key); // alias-name 名称重复处理 if (total_alias_set.contains(cell_name)) { QMessageBox::critical(this, "Alias Validate", "Alias Cant't Repeat."); QSignalBlocker v(_alias_model); cell->setText(origin_key); return; } appoint_unit->setAlias(cell_name); }break; case 1: { // 修改alias基础类型 auto total_alias_set = _bind_base->delegateAlias(); auto origin_key = total_alias_set.at(cell->row()); auto new_type = cell->text(); auto new_ins = _bind_base->basicExtractors()[new_type]->newDefault(); auto new_delegate = std::dynamic_pointer_cast(new_ins); new_delegate->setAlias(origin_key); _bind_base->replaceDelegate(origin_key, new_delegate); }break; default: break; } aliasReload(); } #include RuleSelectDelegate::RuleSelectDelegate(std::shared_ptr ins) :_kernel(ins) { } 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->basicExtractors().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); } void RuleSelectDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { editor->setGeometry(option.rect); } using namespace configurations; #include #include #include #include EmptyConfiguration::EmptyConfiguration(QWidget* p/*=nullptr*/) { auto layout = new QVBoxLayout(this); auto label = new QLabel(u8"Can't Configurate.", this); label->setAlignment(Qt::AlignCenter); layout->addWidget(label); } CountWithinConfiguration::CountWithinConfiguration(QWidget* p /*= nullptr*/) : QWidget(p), _bind_u(nullptr), _count_input(new QSpinBox(this)) { auto layout = new QGridLayout(this); layout->addWidget(new QLabel(tr("BytesCount:"))); layout->addWidget(_count_input, 0, 1); _count_input->setRange(1, 100); layout->setRowStretch(1, 1); layout->setColumnStretch(1, 1); connect(_count_input, QOverload::of(&QSpinBox::valueChanged), [=](int value) { if (this->_bind_u) { auto ptr = std::dynamic_pointer_cast(this->_bind_u); if (ptr) { ptr->setCountWithin(value); emit this->currentRuleChanged(_bind_index); } } }); } void CountWithinConfiguration::currentRuleAccept(std::shared_ptr u, const QModelIndex& i) { this->_bind_u = u; this->_bind_index = i; _count_input->setValue(u->countWithin()); } EncodingConfiguration::EncodingConfiguration(QWidget* p /*= nullptr*/) : QWidget(p), _bind_u(nullptr), _count_input(new QSpinBox(this)), _encoding_set(new QComboBox(this)) { auto layout = new QGridLayout(this); layout->addWidget(new QLabel(tr("BytesCount:"))); layout->addWidget(_count_input, 0, 1); layout->addWidget(new QLabel(tr("Encoding:")), 1, 0); layout->addWidget(_encoding_set, 1, 1); layout->setRowStretch(2, 1); layout->setColumnStretch(1, 1); connect(_count_input, QOverload::of(&QSpinBox::valueChanged), [=](int value) { if (this->_bind_u) { auto ptr = std::dynamic_pointer_cast(this->_bind_u); if (ptr) { ptr->setCountWithin(value); emit this->currentRuleChanged(_bind_index); } } }); auto codec_list = QTextCodec::availableCodecs(); for (auto codec : codec_list) _encoding_set->addItem(QString::fromLatin1(codec)); connect(_encoding_set, QOverload::of(&QComboBox::currentIndexChanged), [=](const QString& value) { if (this->_bind_u) { auto ptr = std::dynamic_pointer_cast(this->_bind_u); if (ptr) { auto insx = QTextCodec::codecForName(value.toUtf8()); ptr->setStrCodec(insx); emit this->currentRuleChanged(_bind_index); } } }); } void EncodingConfiguration::currentRuleAccept(std::shared_ptr u, const QModelIndex& i) { this->_bind_u = u; this->_bind_index = i; _count_input->setValue(u->countWithin()); auto codec_name = std::dynamic_pointer_cast(u)->codecName(); QSignalBlocker x(this->_encoding_set); this->_encoding_set->setCurrentText(codec_name); } BitCombineConfiguration::BitCombineConfiguration(QWidget* p /*= nullptr*/) : QWidget(p), _bind_u(nullptr), _count_input(new QSpinBox(this)), _bit_items(new QTableView(this)), _bit_model(new QStandardItemModel(this)), _index_appoint(new QSpinBox(this)), _bit_means(new QLineEdit(this)) { auto layout = new QGridLayout(this); layout->addWidget(new QLabel(tr("BytesCount:"))); layout->addWidget(_count_input, 0, 1, 1, 2); auto group_box = new QGroupBox(tr("BitsContent")); layout->addWidget(group_box, 1, 0, 3, 3); layout->setColumnStretch(1, 1); layout = new QGridLayout(group_box); layout->addWidget(_bit_items, 0, 0, 3, 3); layout->addWidget(new QLabel(tr("Bit Index:")), 3, 0); layout->addWidget(_index_appoint, 3, 1, 1, 2); layout->addWidget(new QLabel(tr("Bit Means:")), 4, 0); layout->addWidget(_bit_means, 4, 1, 1, 2); auto remove = new QPushButton(tr("RemoveItem")); layout->addWidget(remove, 5, 1); auto append = new QPushButton(tr("AppendNew")); layout->addWidget(append, 5, 2); layout->setColumnStretch(1, 1); layout->setColumnStretch(2, 1); _bit_items->setModel(this->_bit_model); this->_bit_model->setHorizontalHeaderLabels(QStringList() << tr("No.") << tr("Means")); this->_count_input->setRange(1, 100); connect(this->_count_input, QOverload::of(&QSpinBox::valueChanged), [=](int value) { this->_bind_u->setCountWithin(value); this->_index_appoint->setRange(0, value * 8); auto options = this->_bind_u->switchOptions(); this->_bind_u->clearOptions(); for (auto key : options.keys()) { if (key > value * 8) continue; this->_bind_u->setSwitchOption(key, options[key]); } emit this->currentRuleChanged(_bind_index); }); connect(append, &QPushButton::clicked, [=]() { this->_bind_u->setSwitchOption( this->_index_appoint->value(), this->_bit_means->text()); this->reloadContent(_bind_u); emit this->currentRuleChanged(this->_bind_index); }); connect(remove, &QPushButton::clicked, [=]() { }); } void BitCombineConfiguration::currentRuleAccept(std::shared_ptr u, const QModelIndex& i) { this->_bind_u = std::dynamic_pointer_cast(u);; this->_bind_index = i; this->reloadContent(this->_bind_u); } #include void BitCombineConfiguration::reloadContent(std::shared_ptr u) { this->_count_input->setValue(u->countWithin()); this->_index_appoint->setRange(0, u->countWithin() * 8); this->_bit_model->removeRows(0, this->_bit_model->rowCount()); auto items = this->_bind_u->switchOptions(); auto keys = items.keys(); std::sort(keys.begin(), keys.end()); for (auto index : keys) { auto content = items[index]; QList row; row << new QStandardItem(QString("%1").arg(index)); row << new QStandardItem(content); for (auto i : row) i->setEditable(false); this->_bit_model->appendRow(row); } this->_bit_items->resizeColumnsToContents(); this->_bit_items->verticalHeader()->setVisible(false); }