CANdevStudio
Development tool for CAN bus simulation
Loading...
Searching...
No Matches
cansignalsenderguiimpl.h
Go to the documentation of this file.
1#ifndef CANSIGNALSENDERGUIIMPL_H
2#define CANSIGNALSENDERGUIIMPL_H
3
5#include "ui_cansignalsender.h"
6#include <QComboBox>
7#include <QJsonObject>
8#include <QLineEdit>
9#include <QMouseEvent>
10#include <QRegExpValidator>
11#include <QStandardItemModel>
12#include <QStyledItemDelegate>
13#include <QWidget>
14#include <candbhandler.h>
15#include <log.h>
16
17class SigIdDelegate : public QStyledItemDelegate {
18public:
19 SigIdDelegate(QAbstractItemModel* model, const CanDbHandler& db, QObject* parent = nullptr)
20 : QStyledItemDelegate(parent)
21 , _model(model)
22 , _db(db)
23 {
24 }
25
26 virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex& index) const override
27 {
28 QComboBox* cb = new QComboBox(parent);
29
30 cb->setProperty("type", "listItem");
31
32 for (const auto& msg : _db.getDb()) {
33 if (msg.first.id > 0x7ff) {
34 cb->addItem(fmt::format("0x{:08x}", msg.first.id).c_str());
35 } else {
36 cb->addItem(fmt::format("0x{:03x}", msg.first.id).c_str());
37 }
38 }
39
40 cb->setCurrentText(_model->data(index).toString());
41
42 connect(cb, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
43 [cb](int) { cb->clearFocus(); });
44
45 // QOverload is not supported by MSVC 2015
46 connect(cb, static_cast<void (QComboBox::*)(const QString&)>(&QComboBox::currentTextChanged),
47 [index, this](const QString& text) {
48 uint32_t id = text.toUInt(nullptr, 16);
49
50 if (_db.getDb().count(id)) {
51 auto ndx = _model->index(index.row(), 1);
52 auto& sigVec = _db.getDb().at(id);
53
54 if (sigVec.size()) {
55 _model->setData(ndx, sigVec.front().signal_name.c_str(), Qt::EditRole);
56 } else {
57 _model->setData(ndx, "", Qt::EditRole);
58 cds_error("No signals found for message {}", text.toStdString());
59 }
60 } else {
61 cds_error("No signals for selected id 0x{:03x}", id);
62 }
63 });
64
65 return cb;
66 }
67
68 void setEditorData(QWidget* editor, const QModelIndex& index) const override
69 {
70 Q_UNUSED(index);
71 QComboBox* cb = qobject_cast<QComboBox*>(editor);
72 cb->showPopup();
73 }
74
75private:
76 QAbstractItemModel* _model;
77 const CanDbHandler& _db;
78};
79
80class SigNameDelegate : public QStyledItemDelegate {
81public:
82 SigNameDelegate(QAbstractItemModel* model, const CanDbHandler& db, QObject* parent = nullptr)
83 : QStyledItemDelegate(parent)
84 , _model(model)
85 , _db(db)
86 {
87 }
88
89 virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex& index) const override
90 {
91 QComboBox* cb = new QComboBox(parent);
92 QString idStr = _model->data(_model->index(index.row(), 0)).toString();
93 uint32_t id = idStr.toUInt(nullptr, 16);
94
95 cb->setProperty("type", "listItem");
96
97 if (_db.getDb().count(id)) {
98 for (auto&& sig : _db.getDb().at(id)) {
99 cb->addItem(sig.signal_name.c_str());
100 }
101 } else if (idStr.length() > 0) {
102 cds_error("No signals for selected id 0x{:03x}", id);
103 }
104
105 cb->setCurrentText(_model->data(index).toString());
106
107 connect(cb, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
108 [cb](int) { cb->clearFocus(); });
109
110 return cb;
111 }
112
113 void setEditorData(QWidget* editor, const QModelIndex& index) const override
114 {
115 Q_UNUSED(index);
116 QComboBox* cb = qobject_cast<QComboBox*>(editor);
117 cb->showPopup();
118 }
119
120private:
121 QAbstractItemModel* _model;
122 const CanDbHandler& _db;
123};
124
125class SigValDelegate : public QStyledItemDelegate {
126public:
127 SigValDelegate(QAbstractItemModel* model, const CanDbHandler& db, QObject* parent = nullptr)
128 : QStyledItemDelegate(parent)
129 , _model(model)
130 , _db(db)
131 {
132 }
133
134 virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex& index) const override
135 {
136 QString idStr = _model->data(_model->index(index.row(), 0)).toString();
137 uint32_t id = idStr.toUInt(nullptr, 16);
138 QString sigName = _model->data(_model->index(index.row(), 1)).toString();
139
140 QLineEdit* le = new QLineEdit(parent);
141 le->setProperty("type", "nlmItem");
142 QRegExp qRegExp("-?([0-9]+[.])?[0-9]+");
143 auto v = new QRegExpValidator(qRegExp, le);
144 float min = 0, max = 0;
145 le->setValidator(v);
146
147 if (_db.getDb().count(id)) {
148 for (auto&& sig : _db.getDb().at(id)) {
149 if (QString(sig.signal_name.c_str()) == sigName) {
150 min = sig.min;
151 max = sig.max;
152 }
153 }
154 } else if (idStr.length() > 0) {
155 cds_error("No signals for selected id 0x{:03x}", id);
156 }
157
158 le->setPlaceholderText(QString("min: %1, max: %2").arg(min).arg(max));
159
160 return le;
161 }
162
163private:
164 QAbstractItemModel* _model;
165 const CanDbHandler& _db;
166};
167
170 : _ui(new Ui::CanSignalSenderPrivate)
171 , _widget(new QWidget)
172 {
173 _ui->setupUi(_widget);
174 _ui->tv->setSelectionMode(QAbstractItemView::ExtendedSelection);
175 _ui->tv->setSelectionBehavior(QAbstractItemView::SelectRows);
176
177 // QOverload is not supported by MSVC 2015
178 QObject::connect(_ui->tv, &QAbstractItemView::clicked, _ui->tv,
179 static_cast<void (QAbstractItemView::*)(const QModelIndex&)>(&QAbstractItemView::edit));
180 }
181
182 virtual QWidget* mainWidget() override
183 {
184 return _widget;
185 }
186
187 virtual void initTv(QStandardItemModel& tvModel, const CanDbHandler* db) override
188 {
189 _model = &tvModel;
190 _ui->tv->setModel((QAbstractItemModel*)&tvModel);
191 _ui->tv->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
192 _ui->tv->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
193 _ui->tv->horizontalHeader()->setSectionsMovable(true);
194 _ui->tv->horizontalHeader()->setHighlightSections(false);
195
196 _db = db;
197
198 _idDelegate = new SigIdDelegate(&tvModel, *_db, _ui->tv);
199 _ui->tv->setItemDelegateForColumn(0, _idDelegate);
200
201 _nameDelegate = new SigNameDelegate(&tvModel, *_db, _ui->tv);
202 _ui->tv->setItemDelegateForColumn(1, _nameDelegate);
203
204 _valDelegate = new SigValDelegate(&tvModel, *_db, _ui->tv);
205 _ui->tv->setItemDelegateForColumn(2, _valDelegate);
206 }
207
208 virtual void setDockUndockCbk(const dockUndock_t& cb) override
209 {
210 QObject::connect(_ui->pbDockUndock, &QPushButton::toggled, cb);
211 }
212
213 virtual void setAddCbk(const add_t& cb) override
214 {
215 QObject::connect(_ui->pbAdd, &QPushButton::pressed, cb);
216 }
217
218 virtual void setSendCbk(const send_t& cbk) override
219 {
220 _sendCbk = cbk;
221 }
222
223 virtual void setRemoveCbk(const remove_t& cb) override
224 {
225 QObject::connect(_ui->pbRemove, &QPushButton::pressed, cb);
226 }
227
228 virtual void addRow(const QString& id = "", const QString& sig = "", const QString& val = "") override
229 {
230 if (!_model) {
231 cds_error("_model is NULL");
232 return;
233 }
234
235 QStandardItem* idItem = nullptr;
236 QStandardItem* sigItem = nullptr;
237 QStandardItem* valItem = nullptr;
238
239 if (id.length() > 0 && sig.length() > 0) {
240 idItem = new QStandardItem(id);
241 sigItem = new QStandardItem(sig);
242 valItem = new QStandardItem(val);
243 } else if (_db->getDb().size() > 0) {
244 uint32_t tmpId = _db->getDb().begin()->first.id;
245
246 if (tmpId > 0x7ff) {
247 idItem = new QStandardItem(fmt::format("0x{:08x}", tmpId).c_str());
248 } else {
249 idItem = new QStandardItem(fmt::format("0x{:03x}", tmpId).c_str());
250 }
251
252 if (_db->getDb().at(tmpId).size() > 0) {
253 sigItem = new QStandardItem(_db->getDb().at(tmpId).front().signal_name.c_str());
254 } else {
255 cds_warn("Signal list for 0x{:x} is empty", tmpId);
256
257 sigItem = new QStandardItem();
258 }
259 } else {
260 idItem = new QStandardItem();
261 sigItem = new QStandardItem();
262 valItem = new QStandardItem();
263 }
264
265 QList<QStandardItem*> list{ idItem, sigItem, valItem };
266
267 _model->appendRow(list);
268
269 QPushButton* bt = new QPushButton("Send");
270 bt->setProperty("type", "nlmItem");
271 bt->setFlat(true);
272
273 uint32_t row = _model->rowCount() - 1;
274 QObject::connect(bt, &QPushButton::pressed, [this, row] {
275 if (_sendCbk) {
276 auto id = _model->data(_model->index(row, 0)).toString();
277 auto sig = _model->data(_model->index(row, 1)).toString();
278 auto val = _model->data(_model->index(row, 2)).toString();
279
280 if (id.length() > 0 && sig.length() > 0 && val.length() > 0) {
281 _sendCbk(id, sig, QVariant(val));
282 }
283 }
284 });
285
286 auto pbNdx = _model->index(_model->rowCount() - 1, _model->columnCount() - 1);
287 _ui->tv->setIndexWidget(pbNdx, bt);
288 }
289
290 QJsonArray getRows() override
291 {
292 QJsonArray ret;
293 QJsonObject item;
294
295 for (int i = 0; i < _model->rowCount(); ++i) {
296 auto id = _model->data(_model->index(i, 0));
297 auto sig = _model->data(_model->index(i, 1));
298 auto val = _model->data(_model->index(i, 2));
299
300 item["id"] = id.toString();
301 item["sig"] = sig.toString();
302 item["val"] = val.toString();
303
304 ret.append(item);
305 }
306
307 return ret;
308 }
309
310 QModelIndexList getSelectedRows() override
311 {
312 return _ui->tv->selectionModel()->selectedRows();
313 }
314
315private:
316 send_t _sendCbk{ nullptr };
317 QStandardItemModel* _model;
318 const CanDbHandler* _db;
319 Ui::CanSignalSenderPrivate* _ui;
320 QWidget* _widget;
321 SigIdDelegate* _idDelegate;
322 SigNameDelegate* _nameDelegate;
323 SigValDelegate* _valDelegate;
324};
325
326#endif // CANSIGNALSENDERGUIIMPL_H
Definition candbhandler.h:14
const CANmessages_t & getDb() const
Definition candbhandler.cpp:70
Definition cansignalsender_p.h:16
Definition cansignalsenderguiimpl.h:17
void setEditorData(QWidget *editor, const QModelIndex &index) const override
Definition cansignalsenderguiimpl.h:68
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const override
Definition cansignalsenderguiimpl.h:26
SigIdDelegate(QAbstractItemModel *model, const CanDbHandler &db, QObject *parent=nullptr)
Definition cansignalsenderguiimpl.h:19
Definition cansignalsenderguiimpl.h:80
void setEditorData(QWidget *editor, const QModelIndex &index) const override
Definition cansignalsenderguiimpl.h:113
SigNameDelegate(QAbstractItemModel *model, const CanDbHandler &db, QObject *parent=nullptr)
Definition cansignalsenderguiimpl.h:82
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const override
Definition cansignalsenderguiimpl.h:89
Definition cansignalsenderguiimpl.h:125
SigValDelegate(QAbstractItemModel *model, const CanDbHandler &db, QObject *parent=nullptr)
Definition cansignalsenderguiimpl.h:127
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const override
Definition cansignalsenderguiimpl.h:134
#define cds_warn(fmt,...)
Definition log.h:17
#define cds_error(fmt,...)
Definition log.h:21
Definition canrawsender_p.h:13
Definition cansignalsenderguiimpl.h:168
virtual void addRow(const QString &id="", const QString &sig="", const QString &val="") override
Definition cansignalsenderguiimpl.h:228
QJsonArray getRows() override
Definition cansignalsenderguiimpl.h:290
QModelIndexList getSelectedRows() override
Definition cansignalsenderguiimpl.h:310
virtual QWidget * mainWidget() override
Definition cansignalsenderguiimpl.h:182
virtual void setRemoveCbk(const remove_t &cb) override
Definition cansignalsenderguiimpl.h:223
virtual void setDockUndockCbk(const dockUndock_t &cb) override
Definition cansignalsenderguiimpl.h:208
CanSignalSenderGuiImpl()
Definition cansignalsenderguiimpl.h:169
virtual void setAddCbk(const add_t &cb) override
Definition cansignalsenderguiimpl.h:213
virtual void setSendCbk(const send_t &cbk) override
Definition cansignalsenderguiimpl.h:218
virtual void initTv(QStandardItemModel &tvModel, const CanDbHandler *db) override
Definition cansignalsenderguiimpl.h:187
Definition cansignalsenderguiint.h:13
std::function< void()> remove_t
Definition cansignalsenderguiint.h:15
std::function< void(const QString &, const QString &, const QVariant &)> send_t
Definition cansignalsenderguiint.h:17
std::function< void()> add_t
Definition cansignalsenderguiint.h:16
std::function< void()> dockUndock_t
Definition cansignalsenderguiint.h:14