Add rule functions and classes.

This commit is contained in:
Nicholas Johnson 2024-10-28 19:15:40 -04:00
parent d759bd49c2
commit 8fd695d939
8 changed files with 1666 additions and 0 deletions

202
rule.cpp Normal file
View File

@ -0,0 +1,202 @@
#include "rule.h"
Rule::Rule() {
pName = "";
pType = TYPE_NONE;
pProps = QVariantMap();
pColor = pGenerateColor();
pByteOrder = BYTE_ORDER_NONE;
pLength = -1;
pValue = "";
pRepeatCount = 0;
pPreSkipCount = 0;
pPostSkipCount = 0;
}
Rule::Rule(const Rule &rule) {
pName = rule.Name();
pType = rule.Type();
pProps = rule.Properties();
pColor = rule.Color();
pByteOrder = rule.ByteOrder();
pLength = rule.Length();
pValue = rule.Value();
pRepeatCount = rule.RepeatCount();
pPreSkipCount = rule.PreSkipCount();
pPostSkipCount = rule.PostSkipCount();
}
Rule &Rule::operator=(const Rule &rule) {
if (this == &rule) {
return *this;
}
pName = rule.Name();
pType = rule.Type();
pProps = rule.Properties();
pColor = rule.Color();
pByteOrder = rule.ByteOrder();
pLength = rule.Length();
pValue = rule.Value();
pRepeatCount = rule.RepeatCount();
pPreSkipCount = rule.PreSkipCount();
pPostSkipCount = rule.PostSkipCount();
return *this;
}
bool Rule::operator==(const Rule &rule) const {
bool nameMatch = pName == rule.Name();
bool typeMatch = pType == rule.Type();
bool propsMatch = pProps == rule.Properties();
bool byteOrderMatch = pByteOrder == rule.ByteOrder();
bool lengthMatch = pLength == rule.Length();
bool valueMatch = pValue == rule.Value();
bool repeatMatch = pRepeatCount == rule.RepeatCount();
bool preSkipMatch = pPreSkipCount == rule.PreSkipCount();
bool postSkipMatch = pPostSkipCount == rule.PostSkipCount();
return nameMatch && typeMatch && propsMatch &&
byteOrderMatch && lengthMatch && valueMatch &&
repeatMatch && preSkipMatch && postSkipMatch;
}
bool Rule::operator!=(const Rule &rule) const {
return !operator==(rule);
}
void Rule::SetName(const QString name) {
pName = name;
}
QString Rule::Name() const {
return pName;
}
void Rule::SetType(RULE_TYPE type) {
pType = type;
if (pLength == -1) {
pLength = pGetTypeLength(type);
}
}
RULE_TYPE Rule::Type() const {
return pType;
}
void Rule::SetColor(const QColor color) {
pColor = color;
}
QColor Rule::Color() const {
return pColor;
}
void Rule::SetByteOrder(BYTE_ORDER byteOrder) {
pByteOrder = byteOrder;
}
BYTE_ORDER Rule::ByteOrder() const {
return pByteOrder;
}
void Rule::SetLength(int length) {
pLength = length;
}
int Rule::Length() const {
return pLength;
}
void Rule::SetValue(QString value) {
pValue = value;
}
QString Rule::Value() const {
return pValue;
}
QVariant Rule::GetProperty(QString propName) const {
return pProps[propName];
}
void Rule::SetProperties(QVariantMap props) {
pProps = props;
}
QVariantMap Rule::Properties() const {
return pProps;
}
void Rule::SetRepeatCount(int repeatCount) {
pRepeatCount = repeatCount;
}
int Rule::RepeatCount() const {
return pRepeatCount;
}
void Rule::SetPreSkipCount(int preSkipCount) {
pPreSkipCount = preSkipCount;
}
int Rule::PreSkipCount() const {
return pPreSkipCount;
}
void Rule::SetPostSkipCount(int postSkipCount) {
pPostSkipCount = postSkipCount;
}
int Rule::PostSkipCount() const {
return pPostSkipCount;
}
QColor Rule::pGenerateColor() {
QRandomGenerator64 *globalRand = QRandomGenerator64::global();
double rRand = globalRand->generateDouble();
double gRand = globalRand->generateDouble();
double bRand = globalRand->generateDouble();
return QColor(rRand * 255, gRand * 255, bRand * 255);
}
int Rule::pGetTypeLength(RULE_TYPE ruleType) {
int typeLength = 0;
switch ((int)ruleType) {
case 1: // TYPE_SKIP
typeLength = 0;
break;
case 2: // TYPE_INT_8
typeLength = 1;
break;
case 3: // TYPE_UINT_8
typeLength = 1;
break;
case 4: // TYPE_INT_16
typeLength = 2;
break;
case 5: // TYPE_UINT_16
typeLength = 2;
break;
case 6: // TYPE_INT_32
typeLength = 4;
break;
case 7: // TYPE_UINT_32
typeLength = 4;
break;
case 8: // TYPE_INT_64
typeLength = 8;
break;
case 9: // TYPE_UINT_64
typeLength = 8;
break;
default: // Unknown
typeLength = 0;
break;
}
return typeLength;
}
void Rule::SetProperty(QString propName, QVariant propData) {
pProps[propName] = propData;
}

134
rule.h Normal file
View File

@ -0,0 +1,134 @@
#ifndef RULE_H
#define RULE_H
#include <QString>
#include <QMap>
#include <QVariant>
#include <QRandomGenerator64>
#include <QColor>
enum RULE_TYPE {
TYPE_NONE = 0,
TYPE_SKIP = 1,
TYPE_INT_8 = 2,
TYPE_UINT_8 = 3,
TYPE_INT_16 = 4,
TYPE_UINT_16 = 5,
TYPE_INT_32 = 6,
TYPE_UINT_32 = 7,
TYPE_INT_64 = 8,
TYPE_UINT_64 = 9
};
enum BYTE_ORDER {
BYTE_ORDER_NONE = 0,
BYTE_ORDER_LE = 1,
BYTE_ORDER_BE = 2
};
class Rule : public QObject
{
Q_OBJECT
public:
Rule();
Rule(const Rule &rule);
Rule &operator=(const Rule &rule);
bool operator==(const Rule& rule) const;
bool operator!=(const Rule& rule) const;
friend QDataStream &operator<<(QDataStream &arch, const Rule &rule) {
arch << rule.Name();
arch << rule.Type();
arch << rule.Properties();
arch << rule.Color();
arch << rule.ByteOrder();
arch << rule.Length();
arch << rule.Value();
return arch;
}
friend QDataStream &operator>>(QDataStream &arch, Rule &rule) {
QString ruleName = "";
RULE_TYPE ruleType = TYPE_NONE;
QVariantMap ruleProps = QVariantMap();
QColor ruleColor = QColor();
BYTE_ORDER ruleByteOrder = BYTE_ORDER_NONE;
int ruleLength = 0;
QString ruleValue = "";
arch >> ruleName;
rule.SetName(ruleName);
arch >> ruleType;
rule.SetType(ruleType);
arch >> ruleProps;
rule.SetProperties(ruleProps);
arch >> ruleColor;
rule.SetColor(ruleColor);
arch >> ruleByteOrder;
rule.SetByteOrder(ruleByteOrder);
arch >> ruleLength;
rule.SetLength(ruleLength);
arch >> ruleValue;
rule.SetValue(ruleValue);
return arch;
}
void SetName(const QString name);
QString Name() const;
void SetType(RULE_TYPE type);
RULE_TYPE Type() const;
void SetColor(const QColor color);
QColor Color() const;
void SetByteOrder(BYTE_ORDER byteOrder);
BYTE_ORDER ByteOrder() const;
void SetLength(int length);
int Length() const;
void SetValue(QString value);
QString Value() const;
void SetProperty(QString propName, QVariant propData);
QVariant GetProperty(QString propName) const;
void SetProperties(QVariantMap props);
QVariantMap Properties() const;
void SetRepeatCount(int repeatCount);
int RepeatCount() const;
void SetPreSkipCount(int preSkipCount);
int PreSkipCount() const;
void SetPostSkipCount(int postSkipCount);
int PostSkipCount() const;
private:
QString pName;
RULE_TYPE pType;
QVariantMap pProps;
QColor pColor;
BYTE_ORDER pByteOrder;
int pLength;
QString pValue;
int pRepeatCount;
int pPreSkipCount;
int pPostSkipCount;
QColor pGenerateColor();
int pGetTypeLength(RULE_TYPE ruleType);
};
Q_DECLARE_METATYPE(Rule)
#endif // RULE_H

298
ruledialog.cpp Normal file
View File

@ -0,0 +1,298 @@
#include "ruledialog.h"
#include "ui_ruledialog.h"
RuleDialog::RuleDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::RuleDialog) {
ui->setupUi(this);
pRuleNames = QStringList();
pVars = QMap<QString, BlockValue>();
pDefaultRuleCount = 1;
pRules = QVector<Rule>();
pHideLayout(ui->layout_Skip);
ui->groupBox_2->hide();
ui->groupBox_PreSkip->hide();
ui->groupBox_PostSkip->hide();
connect(ui->verticalScrollBar, &QScrollBar::valueChanged, ui->widget_RulePreview, &RulePreview::SetScrollValue);
connect(ui->widget_RulePreview, &RulePreview::ScrollMaxChanged, ui->verticalScrollBar, &QScrollBar::setMaximum);
connect(ui->pushButton_QueueRule, &QPushButton::clicked, this, &RuleDialog::pQueueRule);
connect(ui->pushButton_Cancel, &QPushButton::clicked, this, &RuleDialog::pCancelDialog);
connect(ui->pushButton_Clear, &QPushButton::clicked, this, &RuleDialog::pClearRules);
connect(ui->pushButton_PopFirstRule, &QPushButton::clicked, this, &RuleDialog::pPopFirstRule);
connect(ui->pushButton_PopLastRule, &QPushButton::clicked, this, &RuleDialog::pPopLastRule);
connect(ui->pushButton_Save, &QPushButton::clicked, this, &RuleDialog::pSaveRules);
connect(ui->comboBox_Type, &QComboBox::currentIndexChanged, this, &RuleDialog::pTypeChanged);
connect(this, &RuleDialog::RulesChanged, ui->widget_RulePreview, &RulePreview::SetRules);
connect(ui->groupBox_RepeatRule, &QGroupBox::toggled, this, &RuleDialog::pRepeatToggled);
ui->comboBox_Vars->hide();
connect(ui->radioButton_PrevVar, &QRadioButton::toggled, this, &RuleDialog::pPrevVarToggled);
connect(ui->radioButton_StaticVal, &QRadioButton::toggled, this, &RuleDialog::pStaticValToggled);
ui->comboBox_Pre_Vars->hide();
connect(ui->radioButton_Pre_StaticVal, &QRadioButton::toggled, this, &RuleDialog::pPre_StaticValToggled);
connect(ui->radioButton_Pre_PrevVar, &QRadioButton::toggled, this, &RuleDialog::pPre_PrevVarToggled);
ui->comboBox_Post_Vars->hide();
connect(ui->radioButton_Post_StaticVal, &QRadioButton::toggled, this, &RuleDialog::pPost_StaticValToggled);
connect(ui->radioButton_Post_PrevVar, &QRadioButton::toggled, this, &RuleDialog::pPost_PrevVarToggled);
}
RuleDialog::~RuleDialog() {
delete ui;
}
void RuleDialog::pQueueRule() {
int index = ui->comboBox_Type->currentIndex();
RULE_TYPE type = (RULE_TYPE)index;
if (type == TYPE_NONE) { return; }
int repeatCount = 0;
int preSkip = 0;
int postSkip = 0;
if (ui->groupBox_RepeatRule->isChecked()) {
if (ui->radioButton_PrevVar->isChecked()) {
QString itemText = ui->comboBox_Vars->currentText();
const QString leadingNumber = itemText.split('.').first() + ".";
const QString varText = itemText.replace(leadingNumber, "")
.split('(').first().trimmed();
BlockValue blockVal = pVars[varText];
repeatCount = blockVal.ValueToInt();
} else if (ui->radioButton_StaticVal->isChecked()) {
repeatCount = ui->spinBox_2->value();
}
}
QString name = ui->lineEdit_Name->text();
if (name == "") { return; }
if (ui->groupBox_PreSkip->isChecked()) {
if (ui->radioButton_Pre_StaticVal->isChecked()) {
preSkip = ui->spinBox_Pre_StaticVal->value();
} else {
QString itemText = ui->comboBox_Pre_Vars->currentText();
const QString leadingNumber = itemText.split('.').first() + ".";
const QString varText = itemText.replace(leadingNumber, "")
.split('(').first().trimmed();
BlockValue blockVal = pVars[varText];
preSkip = blockVal.ValueToInt();
}
}
if (ui->groupBox_PostSkip->isChecked()) {
if (ui->radioButton_Post_StaticVal->isChecked()) {
postSkip = ui->spinBox_Post_StaticVal->value();
} else {
QString itemText = ui->comboBox_Post_Vars->currentText();
const QString leadingNumber = itemText.split('.').first() + ".";
const QString varText = itemText.replace(leadingNumber, "")
.split('(').first().trimmed();
BlockValue blockVal = pVars[varText];
postSkip = blockVal.ValueToInt();
}
}
QString ruleName = name;
BYTE_ORDER byteOrder = BYTE_ORDER_NONE;
if (ui->radioButton_BE->isChecked()) {
byteOrder = BYTE_ORDER_BE;
} else {
byteOrder = BYTE_ORDER_LE;
}
Rule rule;
rule.SetName(ruleName);
rule.SetType(type);
rule.SetByteOrder(byteOrder);
rule.SetRepeatCount(repeatCount);
rule.SetPreSkipCount(preSkip);
rule.SetPostSkipCount(postSkip);
if (index == 1) { // skip
rule.SetLength(ui->spinBox->value());
}
pRules.push_back(rule);
ui->widget_RulePreview->SetRules(pRules);
}
void RuleDialog::pSaveRules() {
emit RulesChanged(pRules);
close();
}
void RuleDialog::pClearRules() {
pRules.clear();
ui->widget_RulePreview->SetRules(pRules);
}
void RuleDialog::pPopFirstRule() {
pRules.pop_front();
ui->widget_RulePreview->SetRules(pRules);
}
void RuleDialog::pPopLastRule() {
pRules.pop_back();
ui->widget_RulePreview->SetRules(pRules);
}
void RuleDialog::pCancelDialog() {
pDefaultRuleCount--;
close();
}
void RuleDialog::pHideLayout(QLayout* layout) {
if (!layout)
return;
for (int i = 0; i < layout->count(); ++i) {
QWidget *widget = layout->itemAt(i)->widget();
if (widget) {
widget->hide(); // Hide each widget in the layout
}
}
}
void RuleDialog::pShowLayout(QLayout* layout) {
if (!layout)
return;
for (int i = 0; i < layout->count(); ++i) {
QWidget *widget = layout->itemAt(i)->widget();
if (widget) {
widget->show(); // Hide each widget in the layout
}
}
}
void RuleDialog::pTypeChanged(int index) {
pHideLayout(ui->layout_Skip);
pShowLayout(ui->layout_ByteOrder);
switch (index) {
case 0: // none
break;
case 1: // skip
pShowLayout(ui->layout_Skip);
pHideLayout(ui->layout_ByteOrder);
break;
case 2: // int8 [1]
break;
case 3: // uint8 [1]
break;
case 4: // int16 [2]
break;
case 5: // uint16 [2]
break;
case 6: // int32 [3]
break;
case 7: // uint32 [3]
break;
case 8: // int64 [4]
break;
case 9: // uint64 [4]
break;
}
}
void RuleDialog::pRepeatToggled(bool toggled) {
ui->groupBox_PreSkip->setVisible(toggled);
ui->groupBox_PostSkip->setVisible(toggled);
}
void RuleDialog::pPrevVarToggled(bool toggled) {
ui->comboBox_Vars->setVisible(toggled);
ui->spinBox_2->setVisible(!toggled);
}
void RuleDialog::pStaticValToggled(bool toggled) {
ui->comboBox_Vars->setVisible(!toggled);
ui->spinBox_2->setVisible(toggled);
}
void RuleDialog::pPre_PrevVarToggled(bool toggled) {
ui->comboBox_Pre_Vars->setVisible(toggled);
ui->spinBox_Pre_StaticVal->setVisible(!toggled);
}
void RuleDialog::pPre_StaticValToggled(bool toggled) {
ui->comboBox_Pre_Vars->setVisible(!toggled);
ui->spinBox_Pre_StaticVal->setVisible(toggled);
}
void RuleDialog::pPost_PrevVarToggled(bool toggled) {
ui->comboBox_Post_Vars->setVisible(toggled);
ui->spinBox_Post_StaticVal->setVisible(!toggled);
}
void RuleDialog::pPost_StaticValToggled(bool toggled) {
ui->comboBox_Post_Vars->setVisible(!toggled);
ui->spinBox_Post_StaticVal->setVisible(toggled);
}
void RuleDialog::closeEvent(QCloseEvent *event) {
pDefaultRuleCount++;
const QString defaultName = QString("RULE %1").arg(pDefaultRuleCount);
ui->lineEdit_Name->setText(defaultName);
ui->comboBox_Type->setCurrentIndex(0);
ui->radioButton_LE->setChecked(true);
ui->spinBox->setValue(1);
ui->radioButton_StaticVal->setChecked(true);
ui->spinBox_2->setValue(1);
ui->comboBox_Vars->setCurrentIndex(0);
pRules.clear();
ui->widget_RulePreview->SetRules(pRules);
QDialog::closeEvent(event);
}
Rule RuleDialog::GetRule() {
return pRule;
}
void RuleDialog::SetRule(const Rule rule) {
ui->lineEdit_Name->setText(rule.Name());
if (rule.Type() == TYPE_SKIP) {
ui->spinBox->setValue(rule.Length());
}
}
void RuleDialog::SetRuleNames(QStringList ruleNames) {
pRuleNames = ruleNames;
}
void RuleDialog::SetVars(QMap<QString, BlockValue> vars) {
ui->comboBox_Vars->clear();
ui->comboBox_Vars->addItem("Select Variable");
ui->comboBox_Pre_Vars->clear();
ui->comboBox_Pre_Vars->addItem("Select Variable");
ui->comboBox_Post_Vars->clear();
ui->comboBox_Post_Vars->addItem("Select Variable");
int i = 0;
for (auto [key, value] : vars.asKeyValueRange()) {
i++;
QString varName = (QString)key;
BlockValue varVal = (BlockValue)value;
QString itemName = QString("%1. %2 (%3)")
.arg(QString::number(i), varName, varVal.Value().toString());
ui->comboBox_Vars->addItem(itemName);
ui->comboBox_Pre_Vars->addItem(itemName);
ui->comboBox_Post_Vars->addItem(itemName);
}
pVars = vars;
}

64
ruledialog.h Normal file
View File

@ -0,0 +1,64 @@
#ifndef RULEDIALOG_H
#define RULEDIALOG_H
#include "rule.h"
#include "blockvalue.h"
#include "rulepreview.h"
#include <QDialog>
#include <QQueue>
namespace Ui {
class RuleDialog;
}
class RuleDialog : public QDialog
{
Q_OBJECT
public:
explicit RuleDialog(QWidget *parent = nullptr);
~RuleDialog();
Rule GetRule();
void SetRule(const Rule rule);
void SetRuleNames(QStringList ruleNames);
void SetVars(QMap<QString, BlockValue> vars);
private slots:
void pQueueRule();
void pClearRules();
void pSaveRules();
void pPopFirstRule();
void pPopLastRule();
void pCancelDialog();
void pTypeChanged(int index);
void pRepeatToggled(bool toggled);
void pPrevVarToggled(bool toggled);
void pStaticValToggled(bool toggled);
void pPre_PrevVarToggled(bool toggled);
void pPre_StaticValToggled(bool toggled);
void pPost_PrevVarToggled(bool toggled);
void pPost_StaticValToggled(bool toggled);
signals:
void RuleChanged(Rule rule);
void RulesChanged(QVector<Rule> rules);
protected:
void closeEvent(QCloseEvent *event) override;
private:
Ui::RuleDialog *ui;
Rule pRule;
QStringList pRuleNames;
QMap<QString, BlockValue> pVars;
int pDefaultRuleCount;
QVector<Rule> pRules;
void pHideLayout(QLayout *layout);
void pShowLayout(QLayout *layout);
};
#endif // RULEDIALOG_H

756
ruledialog.ui Normal file
View File

@ -0,0 +1,756 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RuleDialog</class>
<widget class="QDialog" name="RuleDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>546</width>
<height>595</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>546</width>
<height>538</height>
</size>
</property>
<property name="windowTitle">
<string>Add Rule</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="title">
<string>Preview</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QToolButton" name="toolButton_2">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="Resources.qrc">
<normaloff>:/icons/delete.png</normaloff>:/icons/delete.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="RulePreview" name="widget_RulePreview" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QScrollBar" name="verticalScrollBar">
<property name="maximum">
<number>0</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="pageStep">
<number>250</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="title">
<string>Rule Options</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label_6">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_Name">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>RULE</string>
</property>
<property name="maxLength">
<number>10</number>
</property>
<property name="placeholderText">
<string>Rule Name</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_Type">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<item>
<property name="text">
<string>Select Input</string>
</property>
</item>
<item>
<property name="text">
<string>Skip n Bytes</string>
</property>
</item>
<item>
<property name="text">
<string>int8 [1]</string>
</property>
</item>
<item>
<property name="text">
<string>uint8 [1]</string>
</property>
</item>
<item>
<property name="text">
<string>int16 [2]</string>
</property>
</item>
<item>
<property name="text">
<string>uint16 [2]</string>
</property>
</item>
<item>
<property name="text">
<string>int32 [3]</string>
</property>
</item>
<item>
<property name="text">
<string>uint32 [3]</string>
</property>
</item>
<item>
<property name="text">
<string>int64 [4]</string>
</property>
</item>
<item>
<property name="text">
<string>uint64 [4]</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_ByteOrder">
<item>
<widget class="QRadioButton" name="radioButton_LE">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Little Endian</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_BE">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Big Endian</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_Skip">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Skip:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="suffix">
<string> bytes</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_RepeatRule">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="title">
<string>Repeat Rule</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QRadioButton" name="radioButton_StaticVal">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Static Value</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_PrevVar">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Previous Var</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_Skip_2">
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Repeat #:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_2">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="suffix">
<string> times</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_Vars">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<item>
<property name="text">
<string>Select Variable</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_PreSkip">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="title">
<string>Pre-Repeat Skip</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QRadioButton" name="radioButton_Pre_StaticVal">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Static Value</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_Pre_PrevVar">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Previous Var</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_Skip_3">
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Skip:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_Pre_StaticVal">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="suffix">
<string> bytes</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_Pre_Vars">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<item>
<property name="text">
<string>Select Variable</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_PostSkip">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="title">
<string>Post-Repeat Skip</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QRadioButton" name="radioButton_Post_StaticVal">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Static Value</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_Post_PrevVar">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Previous Var</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_Skip_4">
<item>
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Skip:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_Post_StaticVal">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="suffix">
<string> bytes</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_Post_Vars">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<item>
<property name="text">
<string>Select Variable</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QPushButton" name="pushButton_QueueRule">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Queue Rule</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_PopFirstRule">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Pop First</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_PopLastRule">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Pop Last</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_Clear">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="title">
<string>GroupBox</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QPushButton" name="pushButton_Save">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Save Rule</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_Import">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Import Snippet</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_Export">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Export Snippet</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton_Cancel">
<property name="font">
<font>
<family>CommitMono</family>
</font>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RulePreview</class>
<extends>QWidget</extends>
<header>rulepreview.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="Resources.qrc"/>
</resources>
<connections/>
</ui>

140
rulepreview.cpp Normal file
View File

@ -0,0 +1,140 @@
#include "rulepreview.h"
#include "ui_rulepreview.h"
RulePreview::RulePreview(QWidget *parent) :
QWidget(parent),
ui(new Ui::RulePreview)
{
ui->setupUi(this);
pRules = QQueue<Rule>();
pScrollValue = 0;
pScrollMax = 0;
}
RulePreview::~RulePreview() {
delete ui;
}
void RulePreview::AddRule(const Rule rule) {
pRules.enqueue(rule);
update();
}
void RulePreview::AddRules(const QVector<Rule> rules) {
for (int i = 0; i < rules.size(); i++) {
pRules.enqueue(rules[i]);
}
update();
}
void RulePreview::DeleteRule(const Rule rule) {
if (!pRules.contains(rule)) { return; }
if (pRules.size() == 0) { return; }
for (int i = 0; i < pRules.size(); i++) {
Rule currentRule = pRules.dequeue();
if (currentRule != rule) {
pRules.enqueue(currentRule);
}
}
update();
}
void RulePreview::DeleteRuleByName(const QString ruleName) {
if (pRules.size() == 0) { return; }
for (int i = 0; i < pRules.size(); i++) {
Rule currentRule = pRules.dequeue();
if (currentRule.Name() != ruleName) {
pRules.enqueue(currentRule);
}
}
update();
}
void RulePreview::SetRules(const QVector<Rule> rules) {
pRules.clear();
AddRules(rules);
}
void RulePreview::SetScrollValue(int scrollValue) {
pScrollValue = scrollValue;
update();
}
void RulePreview::paintEvent(QPaintEvent *event) {
Q_UNUSED(event);
QPainter painter(this);
int ruleIndex = 1;
QRectF rulesRect = event->rect();
painter.setBrush(Qt::white);
painter.drawRect(rulesRect);
painter.setFont(QFont("CommitMono", 7));
QRectF clipRect(0, rulesRect.top(), width(), rulesRect.height());
painter.setClipRect(clipRect);
foreach (Rule rule, pRules) {
painter.setPen(QPen(rule.Color(), 1));
QString typeText = "";
QColor ruleBackground(rule.Color());
ruleBackground.setAlpha(75);
painter.setBrush(ruleBackground);
// Draw the rule information in the rule stack on the right side
QRectF ruleBackgroundRect(rulesRect.left(), -pScrollValue + rulesRect.top() + 1 + (QFontMetrics(painter.font()).height() * 3) * (ruleIndex - 1),
rulesRect.width(), QFontMetrics(painter.font()).height() * 3);
QRectF ruleRect(rulesRect.left() + 1, -pScrollValue + rulesRect.top() + 2 + (QFontMetrics(painter.font()).height() * 3) * (ruleIndex - 1),
rulesRect.width() - 2, QFontMetrics(painter.font()).height() * 3);
painter.drawRect(ruleBackgroundRect);
pScrollMax = qMax(pScrollMax, (int)ruleRect.bottom());
bool isSkip = false;
switch ((int)rule.Type()) {
case 1: // TYPE_SKIP
typeText = QString("Skip %1 byte(s)").arg(rule.Length());
isSkip = true;
break;
case 2: // TYPE_INT_8
case 3: // TYPE_UINT_8
case 4: // TYPE_INT_16
case 5: // TYPE_UINT_16
case 6: // TYPE_INT_32
case 7: // TYPE_UINT_32
case 8: // TYPE_INT_64
case 9: // TYPE_UINT_64
typeText = QString("%1-BIT %2 INTEGER").arg(rule.Length() * 8).arg(rule.Type() % 2 == 0 ? "" : "US");
break;
default:
typeText = "UH-OH";
break;
}
painter.setPen(Qt::black);
QString paddedIndex = QString::number(ruleIndex).rightJustified(2, '0');
QString ruleName = rule.Name().toUpper();
QString ruleText = QString("%1. %2\n%3\nN/A\n").arg(paddedIndex, ruleName, typeText);
painter.drawText(ruleRect, Qt::TextWrapAnywhere, ruleText);
QString ruleByteOrder = QString(rule.ByteOrder() == BYTE_ORDER_BE ? "BE" : "LE") + "\n\n";
if (!isSkip) {
painter.drawText(ruleRect, Qt::AlignRight, ruleByteOrder);
}
ruleIndex++;
}
emit ScrollMaxChanged(qMax(0, static_cast<int>(pScrollMax - rulesRect.height())));
}
QSize RulePreview::sizeHint() const {
return parentWidget()->size();
}

53
rulepreview.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef RULEPREVIEW_H
#define RULEPREVIEW_H
#include "rule.h"
#include <QWidget>
#include <QFile>
#include <QFileDialog>
#include <QDebug>
#include <QSettings>
#include <QPaintEvent>
#include <QScrollBar>
#include <QQueue>
#include <QPainter>
namespace Ui {
class RulePreview;
}
class RuleDialog;
class RulePreview : public QWidget
{
Q_OBJECT
public:
explicit RulePreview(QWidget *parent = nullptr);
~RulePreview();
public slots:
void AddRule(const Rule rule);
void AddRules(const QVector<Rule> rules);
void DeleteRule(const Rule rule);
void DeleteRuleByName(const QString ruleName);
void SetRules(const QVector<Rule> rules);
void SetScrollValue(int scrollValue);
signals:
void ScrollMaxChanged(int scrollMax);
protected:
void paintEvent(QPaintEvent *event) override;
QSize sizeHint() const override;
private:
Ui::RulePreview *ui;
QQueue<Rule> pRules;
int pScrollValue;
int pScrollMax;
};
#endif // RULEPREVIEW_H

19
rulepreview.ui Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RulePreview</class>
<widget class="QWidget" name="RulePreview">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
</widget>
<resources/>
<connections/>
</ui>