CANdevStudio
Development tool for CAN bus simulation
Loading...
Searching...
No Matches
canrawfilterguiimpl.h
Go to the documentation of this file.
1#ifndef CANRAWFILTERGUIIMPL_H
2#define CANRAWFILTERGUIIMPL_H
3
5#include "ui_canrawfilter.h"
6#include <QComboBox>
7#include <QItemDelegate>
8#include <QItemEditorFactory>
9#include <QLineEdit>
10#include <QStyledItemDelegate>
11#include <QWidget>
12#include <QtGui/QStandardItemModel>
13#include <log.h>
14
15class PolicyCB : public QComboBox {
16public:
17 PolicyCB(QWidget* parent = nullptr)
18 : QComboBox(parent)
19 {
20 setProperty("type", "nlmItem");
21
22 addItem("ACCEPT");
23 addItem("DROP");
24 }
25};
26
29 : _ui(new Ui::CanRawFilterPrivate)
30 , _widget(new QWidget)
31 {
32 _ui->setupUi(_widget);
33 initTv();
34
35 QObject::connect(
36 _ui->pbRxAdd, &QPushButton::pressed, std::bind(&CanRawFilterGuiImpl::handleListAdd, this, _ui->rxTv));
37 QObject::connect(
38 _ui->pbRxRemove, &QPushButton::pressed, std::bind(&CanRawFilterGuiImpl::handleListRemove, this, _ui->rxTv));
39 QObject::connect(
40 _ui->pbRxUp, &QPushButton::pressed, std::bind(&CanRawFilterGuiImpl::handleListUp, this, _ui->rxTv));
41 QObject::connect(
42 _ui->pbRxDown, &QPushButton::pressed, std::bind(&CanRawFilterGuiImpl::handleListDown, this, _ui->rxTv));
43 QObject::connect(_ui->rxPolicy, &QComboBox::currentTextChanged,
44 std::bind(&CanRawFilterGuiImpl::listUpdated, this, _ui->rxTv));
45
46 QObject::connect(
47 _ui->pbTxAdd, &QPushButton::pressed, std::bind(&CanRawFilterGuiImpl::handleListAdd, this, _ui->txTv));
48 QObject::connect(
49 _ui->pbTxRemove, &QPushButton::pressed, std::bind(&CanRawFilterGuiImpl::handleListRemove, this, _ui->txTv));
50 QObject::connect(
51 _ui->pbTxUp, &QPushButton::pressed, std::bind(&CanRawFilterGuiImpl::handleListUp, this, _ui->txTv));
52 QObject::connect(
53 _ui->pbTxDown, &QPushButton::pressed, std::bind(&CanRawFilterGuiImpl::handleListDown, this, _ui->txTv));
54 QObject::connect(_ui->rxPolicy, &QComboBox::currentTextChanged,
55 std::bind(&CanRawFilterGuiImpl::listUpdated, this, _ui->txTv));
56 }
57
58 virtual QWidget* mainWidget()
59 {
60 return _widget;
61 }
62
63 virtual void setTxListCbk(const ListUpdated_t& cb)
64 {
65 _txListUpdatedCbk = cb;
66
67 listUpdatedTx();
68 }
69
70 virtual void setRxListCbk(const ListUpdated_t& cb)
71 {
72 _rxListUpdatedCbk = cb;
73
74 listUpdatedRx();
75 }
76
77 virtual void setListRx(const AcceptList_t& list)
78 {
79 setList(list, _rxModel, "RX");
80 listUpdatedRx();
81 }
82
83 virtual void setListTx(const AcceptList_t& list)
84 {
85 setList(list, _txModel, "TX");
86 listUpdatedTx();
87 }
88
89private:
90 void setList(const AcceptList_t& list, QStandardItemModel& model, const QString& dir)
91 {
92 model.removeRows(0, model.rowCount());
93
94 if (list.size() >= 1) {
95 // Last element used as default policy
96 for (AcceptList_t::size_type i = 0; i < list.size() - 1; ++i) {
97 const auto& item = list[i];
98 model.appendRow(prepareRow(std::get<0>(item), std::get<1>(item), dir, std::get<2>(item)));
99 }
100
101 if (dir == "RX") {
102 const auto& item = list[list.size() - 1];
103 _ui->rxPolicy->setCurrentText(std::get<2>(item) ? "ACCEPT" : "DROP");
104 } else if (dir == "TX") {
105 const auto& item = list[list.size() - 1];
106 _ui->txPolicy->setCurrentText(std::get<2>(item) ? "ACCEPT" : "DROP");
107 } else {
108 cds_warn("Wrong direction ({})", dir.toStdString());
109 }
110
111 } else {
112 cds_warn("{} list expected to have at least 1 element", dir.toStdString());
113 }
114 }
115
116 QStandardItemModel& getItemModel(QTableView* tv)
117 {
118 if (tv == _ui->txTv) {
119 return _txModel;
120 } else {
121 return _rxModel;
122 }
123 }
124
125 void handleListDown(QTableView* tv)
126 {
127 auto& model = getItemModel(tv);
128 int currRow = tv->currentIndex().row();
129 int currCol = tv->currentIndex().column();
130
131 if (currRow < model.rowCount() - 1) {
132 const auto& row = model.takeRow(currRow);
133 model.insertRow(currRow + 1, row);
134 tv->setCurrentIndex(model.index(currRow + 1, currCol));
135
136 listUpdated(tv);
137 }
138 }
139
140 void handleListUp(QTableView* tv)
141 {
142 auto& model = getItemModel(tv);
143 int currRow = tv->currentIndex().row();
144 int currCol = tv->currentIndex().column();
145
146 if (currRow > 0) {
147 const auto& row = model.takeRow(currRow);
148 model.insertRow(currRow - 1, row);
149 tv->setCurrentIndex(model.index(currRow - 1, currCol));
150
151 listUpdated(tv);
152 }
153 }
154
155 void handleListRemove(QTableView* tv)
156 {
157 auto& model = getItemModel(tv);
158 model.removeRow(tv->currentIndex().row());
159
160 listUpdated(tv);
161 }
162
163 void handleListAdd(QTableView* tv)
164 {
165 auto& model = getItemModel(tv);
166
167 QString dir = "RX";
168 if (tv == _ui->txTv) {
169 dir = "TX";
170 }
171
172 auto&& list = prepareRow(".*", ".*", dir, true);
173 model.insertRow(0, list);
174
175 listUpdated(tv);
176 }
177
178 QList<QStandardItem*> prepareRow(const QString& id, const QString& payload, const QString& dir, bool policy)
179 {
180 QList<QStandardItem*> list;
181 list.append(new QStandardItem(id));
182 list.append(new QStandardItem(payload));
183 QStandardItem* item = new QStandardItem(dir);
184 item->setEditable(false);
185 list.append(item);
186 list.append(new QStandardItem(policy ? "ACCEPT" : "DROP"));
187
188 return list;
189 }
190
191 AcceptList_t getAcceptList(const QStandardItemModel& model, bool policy)
192 {
193 AcceptList_t list;
194
195 for (int i = 0; i < model.rowCount(); ++i) {
196 QString id = model.item(i, 0)->data(Qt::DisplayRole).toString();
197 QString payload = model.item(i, 1)->data(Qt::DisplayRole).toString();
198 bool policy = model.item(i, 3)->data(Qt::DisplayRole).toString() == "ACCEPT";
199
200 list.push_back(CanRawFilterGuiInt::AcceptListItem_t(id, payload, policy));
201 }
202
203 list.push_back(CanRawFilterGuiInt::AcceptListItem_t(".*", ".*", policy));
204
205 return list;
206 }
207
208 void listUpdated(const QTableView* tv)
209 {
210 const QStandardItemModel* model = nullptr;
211 const ListUpdated_t* cb = nullptr;
212 bool policy;
213
214 if (tv == _ui->txTv) {
215 model = &_txModel;
216 cb = &_txListUpdatedCbk;
217 policy = _ui->txPolicy->currentText() == "ACCEPT";
218 } else if (tv == _ui->rxTv) {
219 model = &_rxModel;
220 cb = &_rxListUpdatedCbk;
221 policy = _ui->rxPolicy->currentText() == "ACCEPT";
222 } else {
223 cds_error("Failed to recognized which list has been updated");
224 return;
225 }
226
227 AcceptList_t list = getAcceptList(*model, policy);
228
229 if (*cb) {
230 (*cb)(list);
231 } else {
232 cds_warn("List callback not defined");
233 }
234 }
235
236 void listUpdatedRx()
237 {
238 listUpdated(_ui->rxTv);
239 }
240
241 void listUpdatedTx()
242 {
243 listUpdated(_ui->txTv);
244 }
245
246 template <typename F>
247 void setRxDelegate(QTableView* tv, int col, QStyledItemDelegate& del, const std::function<void()>& cb)
248 {
249 QItemEditorFactory* factory = new QItemEditorFactory;
250 QItemEditorCreatorBase* editor = new QStandardItemEditorCreator<F>();
251 factory->registerEditor(QVariant::String, editor);
252 del.setItemEditorFactory(factory);
253 tv->setItemDelegateForColumn(col, &del);
254 QObject::connect(&del, &QAbstractItemDelegate::closeEditor, cb);
255 }
256
257 void initTv()
258 {
259 setRxDelegate<QLineEdit>(_ui->rxTv, 0, _rxIdDelegate, std::bind(&CanRawFilterGuiImpl::listUpdatedRx, this));
260 setRxDelegate<QLineEdit>(
261 _ui->rxTv, 1, _rxPayloadDelegate, std::bind(&CanRawFilterGuiImpl::listUpdatedRx, this));
262 setRxDelegate<PolicyCB>(_ui->rxTv, 3, _rxPolicyDelegate, std::bind(&CanRawFilterGuiImpl::listUpdatedRx, this));
263
264 _ui->rxTv->setModel(&_rxModel);
265 _rxModel.setHorizontalHeaderLabels(_tabList);
266 _ui->rxTv->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
267 _ui->rxTv->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
268
269 setRxDelegate<QLineEdit>(_ui->txTv, 0, _txIdDelegate, std::bind(&CanRawFilterGuiImpl::listUpdatedTx, this));
270 setRxDelegate<QLineEdit>(
271 _ui->txTv, 1, _txPayloadDelegate, std::bind(&CanRawFilterGuiImpl::listUpdatedTx, this));
272 setRxDelegate<PolicyCB>(_ui->txTv, 3, _txPolicyDelegate, std::bind(&CanRawFilterGuiImpl::listUpdatedTx, this));
273
274 _ui->txTv->setModel(&_txModel);
275 _txModel.setHorizontalHeaderLabels(_tabList);
276 _ui->txTv->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
277 _ui->txTv->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
278 }
279
280private:
281 QStandardItemModel _rxModel;
282 QStandardItemModel _txModel;
283 const QStringList _tabList = { "id", "payload", "dir", "policy" };
284 Ui::CanRawFilterPrivate* _ui;
285 QWidget* _widget;
286 QStyledItemDelegate _rxIdDelegate;
287 QStyledItemDelegate _rxPayloadDelegate;
288 QStyledItemDelegate _rxPolicyDelegate;
289 QStyledItemDelegate _txIdDelegate;
290 QStyledItemDelegate _txPayloadDelegate;
291 QStyledItemDelegate _txPolicyDelegate;
292 ListUpdated_t _rxListUpdatedCbk;
293 ListUpdated_t _txListUpdatedCbk;
294};
295
296#endif // CANRAWFILTERGUIIMPL_H
Definition canrawfilter_p.h:11
Definition canrawfilterguiimpl.h:15
PolicyCB(QWidget *parent=nullptr)
Definition canrawfilterguiimpl.h:17
#define cds_warn(fmt,...)
Definition log.h:17
#define cds_error(fmt,...)
Definition log.h:21
Definition canrawsender_p.h:13
Definition canrawfilterguiimpl.h:27
CanRawFilterGuiImpl()
Definition canrawfilterguiimpl.h:28
virtual void setTxListCbk(const ListUpdated_t &cb)
Definition canrawfilterguiimpl.h:63
virtual void setListRx(const AcceptList_t &list)
Definition canrawfilterguiimpl.h:77
virtual void setRxListCbk(const ListUpdated_t &cb)
Definition canrawfilterguiimpl.h:70
virtual QWidget * mainWidget()
Definition canrawfilterguiimpl.h:58
virtual void setListTx(const AcceptList_t &list)
Definition canrawfilterguiimpl.h:83
Definition canrawfilterguiint.h:11
std::tuple< QString, QString, bool > AcceptListItem_t
Definition canrawfilterguiint.h:12
std::function< void(AcceptList_t &list)> ListUpdated_t
Definition canrawfilterguiint.h:14
std::vector< AcceptListItem_t > AcceptList_t
Definition canrawfilterguiint.h:13