Skip to content

Commit 1ee6a08

Browse files
claudejgeudens
authored andcommitted
Fix review comments from PR #16
- importmbcdialog: give Qt parent to MbcUpdateModel and MbcRegisterFilter; remove Qt parent from ActionButtonDelegate (unique_ptr owns it) to fix double-delete; call clearAllSelections() after import to deselect all source rows, not just proxy-visible ones; always reset update model and tab filter before handling new file load - mainwindow: use suffix() instead of completeSuffix() for extension matching; cache to local variable; use QStringLiteral - mbcheader: render tri-state checkbox correctly using toInt() + bitwise state ops; guard toggle on left-click only - mbcfileimporter: remove Util::showError() GUI calls (breaks GUILESS tests); store errors in _lastErrorMessage; caller shows them via Util::showError(); validate decimals fit in quint8 range - mbcregisterfilter: add missing Q_OBJECT macro; add override to filterAcceptsRow - mbcregistermodel: reset _selection in reset(); add clearAllSelections() - tst_mbcregistermodel: fix include guard to TST_MBCREGISTERMODEL_H - tst_mbcupdatemodel: replace raw new MbcUpdateModel with unique_ptr https://claude.ai/code/session_01KvuREfVMg7MnzkpLBg8NVz
1 parent 0c1df85 commit 1ee6a08

10 files changed

Lines changed: 101 additions & 42 deletions

src/dialogs/importmbcdialog.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ ImportMbcDialog::ImportMbcDialog(GuiModel* pGuiModel, GraphDataModel* pGraphData
2525
{
2626
_pUi->setupUi(this);
2727

28-
_pMbcUpdateModel = new MbcUpdateModel(_pGraphDataModel);
28+
_pMbcUpdateModel = new MbcUpdateModel(_pGraphDataModel, this);
2929

30-
_pTabProxyFilter = new MbcRegisterFilter();
30+
_pTabProxyFilter = new MbcRegisterFilter(this);
3131
_pTabProxyFilter->setSourceModel(&_mbcRegisterModel);
3232

3333
/* Disable question mark button */
@@ -69,7 +69,7 @@ ImportMbcDialog::ImportMbcDialog(GuiModel* pGuiModel, GraphDataModel* pGraphData
6969

7070
_pUi->tblMbcUpdate->setFocusPolicy(Qt::NoFocus);
7171

72-
_pUpdateDelegate = std::make_unique<ActionButtonDelegate>(_pUi->tblMbcUpdate);
72+
_pUpdateDelegate = std::make_unique<ActionButtonDelegate>();
7373
_pUpdateDelegate->setCharacter(QChar(0x2190));
7474
connect(_pUpdateDelegate.get(), &ActionButtonDelegate::clicked, this, &ImportMbcDialog::handleAcceptUpdate);
7575

@@ -152,7 +152,7 @@ void ImportMbcDialog::importSelectedRegisters()
152152
_pGraphDataModel->add(regList);
153153
}
154154

155-
setSelectedSelectionstate(Qt::Unchecked);
155+
_mbcRegisterModel.clearAllSelections();
156156
}
157157

158158
void ImportMbcDialog::visibleItemsDataChanged()
@@ -287,18 +287,23 @@ void ImportMbcDialog::updateMbcRegisters(QString filePath)
287287

288288
/* Clear data from table widget */
289289
_mbcRegisterModel.reset();
290+
_pMbcUpdateModel->setMbcRegisters(QList<MbcRegisterData>());
291+
_pUi->cmbTabFilter->clear();
292+
_pUi->cmbTabFilter->addItem(MbcRegisterFilter::cTabNoFilter);
290293
registerDataChanged();
291294

292-
if (registerList.size() > 0)
295+
if (!registerList.isEmpty())
293296
{
294297
_mbcRegisterModel.fill(registerList, tabList);
295298
_pMbcUpdateModel->setMbcRegisters(registerList);
296299

297300
/* Update combo box */
298-
_pUi->cmbTabFilter->clear();
299-
_pUi->cmbTabFilter->addItem(MbcRegisterFilter::cTabNoFilter);
300301
_pUi->cmbTabFilter->addItems(tabList);
301302
}
303+
else if (!fileImporter.lastErrorMessage().isEmpty())
304+
{
305+
Util::showError(fileImporter.lastErrorMessage());
306+
}
302307
}
303308
else
304309
{

src/dialogs/mainwindow.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -866,11 +866,12 @@ void MainWindow::handleFileOpen(QString filename)
866866
{
867867
QFileInfo fileInfo(filename);
868868
_pGuiModel->setLastDir(fileInfo.dir().absolutePath());
869-
if (fileInfo.completeSuffix().toLower() == QString("mbs"))
869+
const QString suffix = fileInfo.suffix().toLower();
870+
if (suffix == QStringLiteral("mbs"))
870871
{
871872
_pProjectFileHandler->openProjectFile(filename);
872873
}
873-
else if (fileInfo.completeSuffix().toLower() == QString("mbc"))
874+
else if (suffix == QStringLiteral("mbc"))
874875
{
875876
_pGuiModel->setLastMbcImportedFile(filename);
876877
showMbcImportDialog();

src/dialogs/mbcheader.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,23 @@ class MbcHeader : public QHeaderView
3232
QRect checkbox_rect = style()->subElementRect(QStyle::SubElement::SE_CheckBoxIndicator, &option, this);
3333
checkbox_rect.moveCenter(rect.center());
3434

35-
bool checked = model()->headerData(logicalIndex, orientation(), Qt::CheckStateRole).toBool();
35+
const auto headerState = static_cast<Qt::CheckState>(
36+
model()->headerData(logicalIndex, orientation(), Qt::CheckStateRole).toInt());
3637

3738
option.rect = checkbox_rect;
38-
option.state = checked ? QStyle::State_On : QStyle::State_Off;
39+
option.state &= ~(QStyle::State_On | QStyle::State_Off | QStyle::State_NoChange);
40+
if (headerState == Qt::Checked)
41+
{
42+
option.state |= QStyle::State_On;
43+
}
44+
else if (headerState == Qt::PartiallyChecked)
45+
{
46+
option.state |= QStyle::State_NoChange;
47+
}
48+
else
49+
{
50+
option.state |= QStyle::State_Off;
51+
}
3952

4053
style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
4154
}
@@ -44,7 +57,7 @@ class MbcHeader : public QHeaderView
4457
void mouseReleaseEvent(QMouseEvent* event) override
4558
{
4659
QHeaderView::mouseReleaseEvent(event);
47-
if (model())
60+
if (model() && event->button() == Qt::LeftButton)
4861
{
4962
int section = logicalIndexAt(event->pos());
5063
if (section == 0)

src/importexport/mbcfileimporter.cpp

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#include "mbcfileimporter.h"
22

33
#include "importexport/mbcregisterdata.h"
4-
#include "util/util.h"
4+
5+
#include <limits>
56

67
/*!
78
* \brief Constructs the importer and immediately parses the given MBC file content.
@@ -28,13 +29,22 @@ QStringList MbcFileImporter::tabList()
2829
return _tabList;
2930
}
3031

32+
/*!
33+
* \brief Returns the error message from the last parse attempt, or an empty string on success.
34+
*/
35+
QString MbcFileImporter::lastErrorMessage()
36+
{
37+
return _lastErrorMessage;
38+
}
39+
3140
void MbcFileImporter::parseRegisters(QString* pMbcFileContent)
3241
{
3342
bool bRet = true;
3443

3544
/* Clear register and tab list */
3645
_registerList.clear();
3746
_tabList.clear();
47+
_lastErrorMessage.clear();
3848

3949
QDomDocument domDocument;
4050
QDomDocument::ParseResult result =
@@ -65,16 +75,16 @@ void MbcFileImporter::parseRegisters(QString* pMbcFileContent)
6575
}
6676
else
6777
{
68-
Util::showError(tr("The file is not a valid ModbusControl project file."));
78+
_lastErrorMessage = tr("The file is not a valid ModbusControl project file.");
6979
bRet = false;
7080
}
7181
}
7282
else
7383
{
74-
Util::showError(tr("Parse error at line %1, column %2:\n%3")
75-
.arg(result.errorLine)
76-
.arg(result.errorColumn)
77-
.arg(result.errorMessage));
84+
_lastErrorMessage = tr("Parse error at line %1, column %2:\n%3")
85+
.arg(result.errorLine)
86+
.arg(result.errorColumn)
87+
.arg(result.errorMessage);
7888
bRet = false;
7989
}
8090

@@ -112,7 +122,7 @@ bool MbcFileImporter::parseTabTag(const QDomElement &element)
112122
}
113123
else
114124
{
115-
Util::showError(tr("No name tag in tab tag"));
125+
_lastErrorMessage = tr("No name tag in tab tag");
116126
bRet = false;
117127
break;
118128
}
@@ -252,7 +262,15 @@ bool MbcFileImporter::parseVarTag(const QDomElement &element, qint32 tabIdx)
252262
{
253263
if (!decimals.isEmpty())
254264
{
255-
modbusRegister.setDecimals(static_cast<quint16>(decimals.toUInt(&bRet)));
265+
const auto parsedDecimals = decimals.toUInt(&bRet);
266+
if (bRet && parsedDecimals <= std::numeric_limits<quint8>::max())
267+
{
268+
modbusRegister.setDecimals(static_cast<quint8>(parsedDecimals));
269+
}
270+
else
271+
{
272+
bRet = false;
273+
}
256274
}
257275
}
258276

@@ -274,9 +292,9 @@ bool MbcFileImporter::parseVarTag(const QDomElement &element, qint32 tabIdx)
274292
}
275293
else
276294
{
277-
Util::showError(tr("A tag is not present or value is not valid.\n\nName: %1\nRegister address: %2\nType: %3\nDecimals: %4")
278-
.arg(name, addr, strType, decimals)
279-
);
295+
_lastErrorMessage =
296+
tr("A tag is not present or value is not valid.\n\nName: %1\nRegister address: %2\nType: %3\nDecimals: %4")
297+
.arg(name, addr, strType, decimals);
280298
}
281299

282300
}

src/importexport/mbcfileimporter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class MbcFileImporter : public QObject
3131

3232
QList <MbcRegisterData> registerList();
3333
QStringList tabList();
34+
QString lastErrorMessage();
3435

3536
signals:
3637

@@ -45,6 +46,7 @@ public slots:
4546

4647
QList <MbcRegisterData> _registerList;
4748
QStringList _tabList;
49+
QString _lastErrorMessage;
4850
};
4951

5052
#endif // MBCFILEIMPORTER_H

src/models/mbcregisterfilter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55

66
class MbcRegisterFilter : public QSortFilterProxyModel
77
{
8+
Q_OBJECT
89

910
public:
1011
MbcRegisterFilter(QObject* parent = nullptr);
11-
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
12+
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
1213

1314
static const QString cTabNoFilter;
1415

src/models/mbcregistermodel.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ void MbcRegisterModel::reset()
257257

258258
_mbcRegisterList.clear();
259259
_tabList.clear();
260+
_selection = Qt::Unchecked;
260261

261262
endResetModel();
262263
}
@@ -363,3 +364,19 @@ quint32 MbcRegisterModel::selectedRegisterCount()
363364

364365
return cnt;
365366
}
367+
368+
/*!
369+
* \brief Unchecks every row in the source model regardless of current filter state.
370+
*/
371+
void MbcRegisterModel::clearAllSelections()
372+
{
373+
for (MbcRegister& row : _mbcRegisterList)
374+
{
375+
row.bSelected = false;
376+
}
377+
378+
if (!_mbcRegisterList.isEmpty())
379+
{
380+
emit dataChanged(this->index(0, 0), this->index(rowCount() - 1, 0));
381+
}
382+
}

src/models/mbcregistermodel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class MbcRegisterModel : public QAbstractTableModel
3030
bool setData(const QModelIndex & index, const QVariant & value, int role) override;
3131

3232
void setSelectionstate(QList<QModelIndex>& indexList, Qt::CheckState state);
33+
void clearAllSelections();
3334

3435
void reset();
3536

tests/models/tst_mbcregistermodel.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef TEST_MBCREGISTERMODEL_H
2-
#define TEST_MBCREGISTERMODEL_H
1+
#ifndef TST_MBCREGISTERMODEL_H
2+
#define TST_MBCREGISTERMODEL_H
33

44
#include <QObject>
55

@@ -46,4 +46,4 @@ private slots:
4646

4747
};
4848

49-
#endif /* TEST_MBCREGISTERMODEL_H */
49+
#endif /* TST_MBCREGISTERMODEL_H */

0 commit comments

Comments
 (0)