diff --git a/CMakeLists.txt b/CMakeLists.txt index a57b9ede..b8497bae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -261,11 +261,11 @@ qt5_wrap_ui(UI src/mainwindow.ui src/cdlgmdfregister.ui src/cdlgmdfregisterlist.ui - src/cdlgmdfregisterbitlist.ui src/cdlgmdfregisterbit.ui - src/cdlgmdfregistervaluelist.ui + src/cdlgmdfregisterbitlist.ui src/cdlgmdfregistervalue.ui - + src/cdlgmdfregistervaluelist.ui + src/cdlgmdfregistermapping.ui src/cdlgmdfremotevar.ui @@ -583,6 +583,16 @@ add_executable(${PROJECT_NAME} src/cdlgmdfregisterlist.cpp src/cdlgmdfregisterlist.h + build/ui_cdlgmdfregisterbit.h + src/cdlgmdfregisterbit.ui + src/cdlgmdfregisterbit.cpp + src/cdlgmdfregisterbit.h + + build/ui_cdlgmdfregisterbitlist.h + src/cdlgmdfregisterbitlist.ui + src/cdlgmdfregisterbitlist.cpp + src/cdlgmdfregisterbitlist.h + ${VSCP_PATH}/src/vscp/common/version.h ${VSCP_PATH}/src/vscp/common/vscp.h ${VSCP_PATH}/src/vscp/common/vscpremotetcpif.h diff --git a/src/cdlgmdfregister.cpp b/src/cdlgmdfregister.cpp index e745193d..28140dc7 100644 --- a/src/cdlgmdfregister.cpp +++ b/src/cdlgmdfregister.cpp @@ -67,6 +67,7 @@ CDlgMdfRegister::CDlgMdfRegister(QWidget* parent) vscpworks* pworks = (vscpworks*)QCoreApplication::instance(); setInitialFocus(); + this->setFixedSize(this->size()); } /////////////////////////////////////////////////////////////////////////////// @@ -201,6 +202,19 @@ CDlgMdfRegister::initDialogData(CMDF* pmdf, CMDF_Register* preg, int index) ui->editName->setFocus(); break; } + + this->setFixedSize(this->size()); +} + +/////////////////////////////////////////////////////////////////////////////// +// setReadOnly +// + +void +CDlgMdfRegister::setReadOnly(void) +{ + ui->comboPage->setEnabled(false); + ui->editOffset->setEnabled(false); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/cdlgmdfregister.h b/src/cdlgmdfregister.h index 8edbcf93..c6e0e12a 100644 --- a/src/cdlgmdfregister.h +++ b/src/cdlgmdfregister.h @@ -77,6 +77,12 @@ class CDlgMdfRegister : public QDialog { */ void initDialogData(CMDF *pmdf, CMDF_Register* preg, int index = 0); + /*! + Prevent page and offset from being edited + */ + void setReadOnly(void); + + // ---------------------------------------------------------------------------- // Getters & Setters diff --git a/src/cdlgmdfregister.ui b/src/cdlgmdfregister.ui index f9ac2d52..6678d8cd 100644 --- a/src/cdlgmdfregister.ui +++ b/src/cdlgmdfregister.ui @@ -42,6 +42,9 @@ + + QLayout::SetDefaultConstraint + diff --git a/src/cdlgmdfregisterbit.cpp b/src/cdlgmdfregisterbit.cpp new file mode 100644 index 00000000..5d84a16e --- /dev/null +++ b/src/cdlgmdfregisterbit.cpp @@ -0,0 +1,286 @@ +// cdlgmdfregisterbit.cpp +// +// This file is part of the VSCP (https://www.vscp.org) +// +// The MIT License (MIT) +// +// Copyright © 2000-2023 Ake Hedman, Grodans Paradis AB +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#ifdef WIN32 +#include +#endif + +#include +#include + +#include + +#include "cdlgmdfregisterbit.h" +#include "ui_cdlgmdfregisterbit.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +const char CDlgMdfRegisterBit::pre_str_registerbit[] = "Register bit: "; + +/////////////////////////////////////////////////////////////////////////////// +// CTor +// + +CDlgMdfRegisterBit::CDlgMdfRegisterBit(QWidget* parent) + : QDialog(parent) + , ui(new Ui::CDlgMdfRegisterBit) +{ + ui->setupUi(this); + + // m_type = mdf_type_unknown; + m_pbit = nullptr; + + vscpworks* pworks = (vscpworks*)QCoreApplication::instance(); + + setInitialFocus(); + this->setFixedSize(this->size()); +} + +/////////////////////////////////////////////////////////////////////////////// +// DTor +// + +CDlgMdfRegisterBit::~CDlgMdfRegisterBit() +{ + delete ui; +} + +/////////////////////////////////////////////////////////////////////////////// +// initDialogData +// + +void +CDlgMdfRegisterBit::initDialogData(CMDF* pmdf, CMDF_Bit* pbit, int index) +{ + QString str; + + if (nullptr == pmdf) { + spdlog::error("MDF register bit information - Invalid MDF object (initDialogData)"); + return; + } + + m_pmdf = pmdf; + + if (nullptr == pbit) { + spdlog::error("MDF register bit information - Invalid MDF register bit object (initDialogData)"); + return; + } + + m_pbit = pbit; + + setName(pbit->getName().c_str()); + setPos(pbit->getPos()); + setWidth(pbit->getWidth()); + setDefault(pbit->getDefault()); + setMin(pbit->getMin()); + setMax(pbit->getMax()); + setAccess(pbit->getAccess()); + + switch (index) { + case index_name: + ui->editName->setFocus(); + break; + + case index_pos: + ui->spinPos->setFocus(); + break; + + case index_width: + ui->spinWidth->setFocus(); + break; + + case index_default: + ui->spinDefault->setFocus(); + break; + + case index_min: + ui->spinMin->setFocus(); + break; + + case index_max: + ui->spinMax->setFocus(); + break; + + case index_access: + ui->spinMin->setFocus(); + break; + + default: + ui->editName->setFocus(); + break; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// setInitialFocus +// + +void +CDlgMdfRegisterBit::setInitialFocus(void) +{ + // ui->editName->setFocus(); +} + +// ---------------------------------------------------------------------------- +// Getters & Setters +// ---------------------------------------------------------------------------- + +QString +CDlgMdfRegisterBit::getName(void) +{ + return ui->editName->text(); +}; + +void +CDlgMdfRegisterBit::setName(const QString& name) +{ + ui->editName->setText(name); +}; + +// ----------------------------------------------------------------------- + +uint8_t +CDlgMdfRegisterBit::getPos(void) +{ + return ui->spinPos->value(); +} + +void +CDlgMdfRegisterBit::setPos(uint8_t span) +{ + ui->spinPos->setValue(span); +} + + +// ----------------------------------------------------------------------- + +uint8_t +CDlgMdfRegisterBit::getWidth(void) +{ + return ui->spinWidth->value(); +} + +void +CDlgMdfRegisterBit::setWidth(uint8_t span) +{ + ui->spinWidth->setValue(span); +} + +// ----------------------------------------------------------------------- + +uint8_t +CDlgMdfRegisterBit::getDefault(void) +{ + return ui->spinDefault->value(); +} + +void +CDlgMdfRegisterBit::setDefault(uint8_t span) +{ + ui->spinDefault->setValue(span); +} + +// ----------------------------------------------------------------------- + +uint8_t +CDlgMdfRegisterBit::getMin(void) +{ + return ui->spinMin->value(); +} + +void +CDlgMdfRegisterBit::setMin(uint8_t min) +{ + ui->spinMin->setValue(min); +} + +// ----------------------------------------------------------------------- + +uint8_t +CDlgMdfRegisterBit::getMax(void) +{ + return ui->spinMax->value(); +} + +void +CDlgMdfRegisterBit::setMax(uint8_t span) +{ + ui->spinMax->setValue(span); +} + +// ----------------------------------------------------------------------- + +mdf_access_mode +CDlgMdfRegisterBit::getAccess(void) +{ + return static_cast(ui->comboAccess->currentIndex()); +} + +void +CDlgMdfRegisterBit::setAccess(uint8_t access) +{ + if (access <= MDF_REG_ACCESS_READ_WRITE) { + ui->comboAccess->setCurrentIndex(access); + } +} + + + +/////////////////////////////////////////////////////////////////////////////// +// accept +// + +void +CDlgMdfRegisterBit::accept() +{ + std::string str; + if (nullptr != m_pbit) { + m_pbit->setName(getName().toStdString()); + m_pbit->setName(getName().toStdString().c_str()); + m_pbit->setPos(getPos()); + m_pbit->setWidth(getWidth()); + m_pbit->setMin(getMin()); + m_pbit->setMax(getMax()); + m_pbit->setAccess(getAccess()); + m_pbit->setDefault(getDefault()); + } + else { + spdlog::error("MDF module information - Invalid MDF object (accept)"); + } + + QDialog::accept(); +} diff --git a/src/cdlgmdfregisterbit.h b/src/cdlgmdfregisterbit.h new file mode 100644 index 00000000..cd98bc73 --- /dev/null +++ b/src/cdlgmdfregisterbit.h @@ -0,0 +1,122 @@ +// cdlgmdfregisterbit.h +// +// This file is part of the VSCP (https://www.vscp.org) +// +// The MIT License (MIT) +// +// Copyright © 2000-2023 Ake Hedman, Grodans Paradis AB +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#ifndef CDLGMDFREGISTERBIT_H +#define CDLGMDFREGISTERBIT_H + +#include +#include + +#include + +namespace Ui { +class CDlgMdfRegisterBit; +} + +class CDlgMdfRegisterBit : public QDialog { + Q_OBJECT + +public: +public: + explicit CDlgMdfRegisterBit(QWidget* parent = nullptr); + ~CDlgMdfRegisterBit(); + + static const int index_name = 0; + static const int index_pos = 1; + static const int index_width = 2; + static const int index_default = 3; + static const int index_min = 4; + static const int index_max = 5; + static const int index_access = 6; + + static const char pre_str_registerbit[]; + + /*! + Set inital focus to description + */ + void setInitialFocus(void); + + /*! + Init dialog data + @param CMDF *pmdf Pointer to MDF + @param pmdfobject Pointer to MDF object + @param index Selected file item + + */ + void initDialogData(CMDF* pmdf, CMDF_Bit* pbit, int index = 0); + + // ---------------------------------------------------------------------------- + // Getters & Setters + // ---------------------------------------------------------------------------- + + // name + QString getName(void); + void setName(const QString& name); + + // pos + uint8_t getPos(void); + void setPos(uint8_t page); + + // width + uint8_t getWidth(void); + void setWidth(uint8_t offset); + + // default + uint8_t getDefault(void); + void setDefault(uint8_t value); + + // min + uint8_t getMin(void); + void setMin(uint8_t min); + + // max + uint8_t getMax(void); + void setMax(uint8_t max); + + // access + mdf_access_mode getAccess(void); + void setAccess(uint8_t access); + +public slots: + + /*! + Accept dialog data and write to register + */ + void accept(void); + +private: + Ui::CDlgMdfRegisterBit* ui; + + /// Pointer to MDF + CMDF* m_pmdf; + + /// Pointer to bit information + CMDF_Bit* m_pbit; +}; + +#endif // CDLGMDFREGISTERBIT_H diff --git a/src/cdlgmdfregisterbit.ui b/src/cdlgmdfregisterbit.ui index 007f85dd..191e6da7 100644 --- a/src/cdlgmdfregisterbit.ui +++ b/src/cdlgmdfregisterbit.ui @@ -7,35 +7,19 @@ 0 0 692 - 257 + 285 Dialog - - - - 10 - 220 - 671 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok - - 9 19 671 - 191 + 221 @@ -64,7 +48,11 @@ - + + + 7 + + @@ -74,7 +62,14 @@ - + + + 1 + + + 8 + + @@ -83,6 +78,9 @@ + + + @@ -90,6 +88,9 @@ + + + @@ -97,17 +98,65 @@ - - + + + + 255 + + - - + + + + Access + + - - + + + + Access right for register + + + + None + + + + + Write Only + + + + + Read Only + + + + + Read/Write + + + + + + + 10 + 250 + 671 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok + + @@ -118,12 +167,12 @@ accept() - 248 - 254 + 345 + 255 - 157 - 274 + 345 + 136 @@ -134,12 +183,12 @@ reject() - 316 - 260 + 345 + 255 - 286 - 274 + 345 + 136 diff --git a/src/cdlgmdfregisterbitlist.cpp b/src/cdlgmdfregisterbitlist.cpp new file mode 100644 index 00000000..bfc7f264 --- /dev/null +++ b/src/cdlgmdfregisterbitlist.cpp @@ -0,0 +1,401 @@ +// cdlgmdfregisterbitlist.cpp +// +// This file is part of the VSCP (https://www.vscp.org) +// +// The MIT License (MIT) +// +// Copyright © 2000-2023 Ake Hedman, Grodans Paradis AB +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#ifdef WIN32 +#include +#endif + +#include +#include + +#include + +#include "cdlgmdfregisterbit.h" +#include "cdlgmdfregisterbitlist.h" +#include "ui_cdlgmdfregisterbitlist.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// CTor +// + +CDlgMdfRegisterBitList::CDlgMdfRegisterBitList(QWidget* parent) + : QDialog(parent) + , ui(new Ui::CDlgMdfRegisterBitList) +{ + m_pmdf = nullptr; + m_page = 0; + + ui->setupUi(this); + + vscpworks* pworks = (vscpworks*)QCoreApplication::instance(); + + connect(ui->btnAddRegisterBit, &QToolButton::clicked, this, &CDlgMdfRegisterBitList::addRegisterBit); + connect(ui->btnEditRegisterBit, &QToolButton::clicked, this, &CDlgMdfRegisterBitList::editRegisterBit); + connect(ui->btnDupRegisterBit, &QToolButton::clicked, this, &CDlgMdfRegisterBitList::dupRegisterBit); + connect(ui->btnDelRegisterBit, &QToolButton::clicked, this, &CDlgMdfRegisterBitList::deleteRegisterBit); + + connect(ui->listRegisterBit, &QListWidget::doubleClicked, this, &CDlgMdfRegisterBitList::editRegisterBit); + + + setInitialFocus(); + this->setFixedSize(this->size()); +} + +/////////////////////////////////////////////////////////////////////////////// +// DTor +// + +CDlgMdfRegisterBitList::~CDlgMdfRegisterBitList() +{ + delete ui; +} + +/////////////////////////////////////////////////////////////////////////////// +// initDialogData +// + +void +CDlgMdfRegisterBitList::initDialogData(CMDF* pmdf, uint16_t page) +{ + QString str; + + if (nullptr == pmdf) { + QMessageBox::critical(this, tr("MDF contact information"), tr("Invalid MDF manufacturing object")); + spdlog::error("MDF contact information - Invalid MDF manufacturing object"); + return; + } + + // Save MDF and page + m_pmdf = pmdf; + m_page = page; + + // m_pmdf->getRegisterMap(m_page, pages); + + +} + + + +/////////////////////////////////////////////////////////////////////////////// +// renderRegisterItems +// + +void +CDlgMdfRegisterBitList::renderRegisterItems(void) +{ + std::map pages; + + if (nullptr == m_pmdf) { + return; + } + + ui->listRegisterBit->clear(); + + // Make sorted set of registers on this page + std::deque* regset = m_pmdf->getRegisterObjList(); + for (auto it = regset->cbegin(); it != regset->cend(); ++it) { + if (m_page == (*it)->getPage()) { + m_registersSet.insert((*it)->getOffset()); + } + } + + m_pmdf->getRegisterMap(m_page, pages); + + std::deque* regs = m_pmdf->getRegisterObjList(); + + for (auto it = m_registersSet.cbegin(); it != m_registersSet.cend(); ++it) { + // m_registersSet.insert((*it)->getOffset()); + CMDF_Register* preg = m_pmdf->getRegister(*it, m_page); + if (nullptr != preg) { + QString str = QString("Register %1 -- %2").arg(preg->getOffset()).arg(preg->getName().c_str()); + ui->listRegisterBit->addItem(str); + // Set data to register index + ui->listRegisterBit->item(ui->listRegisterBit->count() - 1)->setData(Qt::UserRole, preg->getOffset()); + } + } + + // for (auto it = regs->cbegin(); it != regs->cend(); ++it) { + // m_registersSet.insert((*it)->getOffset()); + // if ((*it)->getPage() == m_page) { + // QString str = QString("Register %1 -- %2").arg((*it)->getOffset()).arg((*it)->getName().c_str()); + // ui->listRegisterBit->addItem(str); + // // Set data to register index + // ui->listRegisterBit->item(ui->listRegisterBit->count() - 1)->setData(Qt::UserRole, (*it)->getOffset()); + // } + // } +} + +/////////////////////////////////////////////////////////////////////////////// +// setInitialFocus +// + +void +CDlgMdfRegisterBitList::setInitialFocus(void) +{ + //ui->editName->setFocus(); +} + + + +/////////////////////////////////////////////////////////////////////////////// +// addRegisterBit +// + +void +CDlgMdfRegisterBitList::addRegisterBit(void) +{ + bool ok; + CMDF_Register* pregnew = new CMDF_Register(); + pregnew->setPage(m_page); + + // Save the selected row + int idx = ui->listRegisterBit->currentRow(); + + CDlgMdfRegister dlg(this); + dlg.initDialogData(m_pmdf, pregnew); +addregdlg: + if (QDialog::Accepted == dlg.exec()) { + // Check if register is already defined + CMDF_Register* preg = m_pmdf->getRegister(pregnew->getOffset(), pregnew->getPage()); + if (nullptr != preg) { + QMessageBox::warning(this, tr("MDF add new register"), tr("Register page=%1 offset=%2 is already define. Must be unique.").arg(pregnew->getPage()).arg(pregnew->getOffset())); + goto addregdlg; + } + qDebug() << "Page=" << pregnew->getPage() << " Offset=" << pregnew->getOffset(); + m_pmdf->getRegisterObjList()->push_back(pregnew); + if (m_page == pregnew->getPage()) { + m_registersSet.insert(pregnew->getOffset()); + } + ui->listRegisterBit->clear(); + renderRegisterItems(); + if (-1 != idx) { + ui->listRegisterBit->setCurrentRow(idx); + } + + // Warn if page is not the same as for dialog + if (pregnew->getPage() != m_page) { + QMessageBox::information(this, + tr("MDF duplicate register"), + tr("Register page=%1 offset=%2 is not on same page [%3] as registers and will be added but not shown.").arg(pregnew->getPage()).arg(pregnew->getOffset()).arg(m_page)); + } + } + else { + delete pregnew; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// editRegisterBit +// + +void +CDlgMdfRegisterBitList::editRegisterBit(void) +{ + bool ok; + + if (-1 != ui->listRegisterBit->currentRow()) { + + // Save the selected row + int idx = ui->listRegisterBit->currentRow(); + + QListWidgetItem* pitem = ui->listRegisterBit->currentItem(); + CMDF_Register* preg = m_pmdf->getRegister(pitem->data(Qt::UserRole).toUInt(), m_page); + + CDlgMdfRegister dlg(this); + dlg.initDialogData(m_pmdf, preg); + // Don't allow editing of page and offset + dlg.setReadOnly(); + if (QDialog::Accepted == dlg.exec()) { + ui->listRegisterBit->clear(); + renderRegisterItems(); + ui->listRegisterBit->setCurrentRow(idx); + } + } + else { + QMessageBox::warning(this, tr(APPNAME), tr("An item must be selected"), QMessageBox::Ok); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// dupRegisterBit +// + +void +CDlgMdfRegisterBitList::dupRegisterBit(void) +{ + if (-1 != ui->listRegisterBit->currentRow()) { + + // Save the selected row + int idx = ui->listRegisterBit->currentRow(); + + QListWidgetItem* pitem = ui->listRegisterBit->currentItem(); + CMDF_Register* preg = m_pmdf->getRegister(pitem->data(Qt::UserRole).toUInt(), m_page); + + CMDF_Register* pregnew = new CMDF_Register(); + pregnew->setPage(m_page); + + // Make copy + *pregnew = *preg; + + CDlgMdfRegister dlg(this); + dlg.initDialogData(m_pmdf, pregnew); + dupregdlg: + if (QDialog::Accepted == dlg.exec()) { + // Check if register is already defined + CMDF_Register* pregold = m_pmdf->getRegister(pregnew->getOffset(), pregnew->getPage()); + if (nullptr != pregold) { + QMessageBox::warning(this, tr("MDF duplicate register"), tr("Register page=%1 offset=%2 is already define. Must be unique.").arg(pregnew->getPage()).arg(pregnew->getOffset())); + goto dupregdlg; + } + qDebug() << "Page=" << pregnew->getPage() << " Offset=" << pregnew->getOffset(); + m_pmdf->getRegisterObjList()->push_back(pregnew); + if (m_page == pregnew->getPage()) { + m_registersSet.insert(pregnew->getOffset()); + } + ui->listRegisterBit->clear(); + renderRegisterItems(); + if (-1 != idx) { + ui->listRegisterBit->setCurrentRow(idx); + } + // Warn if page is not the same as for dialog + if (pregnew->getPage() != m_page) { + QMessageBox::information(this, + tr("MDF duplicate register"), + tr("Register page=%1 offset=%2 is not on same page [%3] as registers and will be added but not shown.").arg(pregnew->getPage()).arg(pregnew->getOffset()).arg(m_page)); + } + } + else { + delete pregnew; + } + } + else { + QMessageBox::warning(this, tr(APPNAME), tr("An item must be selected"), QMessageBox::Ok); + } + + // if (-1 != ui->listContact->currentRow()) { + + // // Save the selected row + // int idx = ui->listContact->currentRow(); + + // QListWidgetItem* pitem = ui->listContact->currentItem(); + // QString selstr = pitem->text().split('_').first().left(2); + + // std::string str = QInputDialog::getText(this, + // tr("Edit contact item"), + // tr("Contact value:"), + // QLineEdit::Normal, + // pitem->text(), + // &ok) + // .toStdString(); + + // if (ok && str.length()) { + + // CMDF_Item* pitem = new CMDF_Item(); + // if (nullptr != pitem) { + // pitem->setValue(str); + // m_pContactList->push_back(pitem); + // ui->listContact->clear(); + // fillContactItems(); + // } + // else { + // QMessageBox::warning(this, tr(APPNAME), tr("Memory problem could not add item"), QMessageBox::Ok); + // } + // } + // } + // else { + // QMessageBox::warning(this, tr("vscpworks+"), tr("An item must be selected"), QMessageBox::Ok); + // } +} + +/////////////////////////////////////////////////////////////////////////////// +// deleteRegisterBit +// + +void +CDlgMdfRegisterBitList::deleteRegisterBit(void) +{ + if (-1 != ui->listRegisterBit->currentRow()) { + + // Save the row + int idx = ui->listRegisterBit->currentRow(); + + QListWidgetItem* pitem = ui->listRegisterBit->currentItem(); + CMDF_Register* preg = m_pmdf->getRegister(pitem->data(Qt::UserRole).toUInt(), m_page); + m_pmdf->deleteRegister(preg); + delete preg; + ui->listRegisterBit->removeItemWidget(pitem); + renderRegisterItems(); + ui->listRegisterBit->setCurrentRow(idx); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// accept +// + +void +CDlgMdfRegisterBitList::accept() +{ + std::string str; + if (nullptr != m_pmdf) { + + // str = ui->editName->text().toStdString(); + // m_pmdf->setName(str); + + // str = ui->editModel->text().toStdString(); + // m_pmdf->setModuleModel(str); + + // m_pmdf->setModuleLevel(ui->comboModuleLevel->currentIndex()); + + // str = ui->editVersion->text().toStdString(); + // m_pmdf->setModuleVersion(str); + + // str = ui->editDate->text().toStdString(); + // m_pmdf->setModuleChangeDate(str); + + // m_pmdf->setModuleBufferSize(ui->editBufferSize->value()); + + // str = ui->editCopyright->text().toStdString(); + // m_pmdf->setModuleCopyright(str); + } + else { + spdlog::error("MDF module information - Invalid MDF object (accept)"); + } + + QDialog::accept(); +} diff --git a/src/cdlgmdfregisterbitlist.h b/src/cdlgmdfregisterbitlist.h new file mode 100644 index 00000000..5c55defb --- /dev/null +++ b/src/cdlgmdfregisterbitlist.h @@ -0,0 +1,113 @@ +// cdlgmdfregisterbitlist.h +// +// This file is part of the VSCP (https://www.vscp.org) +// +// The MIT License (MIT) +// +// Copyright © 2000-2023 Ake Hedman, Grodans Paradis AB +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#ifndef CDLGMDFREGISTERBITLIST_H +#define CDLGMDFREGISTERBITLIST_H + +#include +#include + +#include "cdlgmdfregister.h" + +#include + + + + +namespace Ui { +class CDlgMdfRegisterBitList; +} + +class CDlgMdfRegisterBitList : public QDialog { + Q_OBJECT + +public: + explicit CDlgMdfRegisterBitList(QWidget* parent = nullptr); + ~CDlgMdfRegisterBitList(); + + /*! + Set inital focus to description + */ + void setInitialFocus(void); + + /*! + Set edit mode. + GUID will be READ ONLY + */ + void setEditMode(); + + /*! + Init dialog data + @param pmdf Pointer to MDF object + */ + void initDialogData(CMDF *pmdf, uint16_t page=0); + + /*! + Fill page combo box with page information + */ + void renderComboPage(void); + + /*! + Fill in contact items + */ + void renderRegisterItems(void); + + + // ---------------------------------------------------------------------------- + // Getters & Setters + // ---------------------------------------------------------------------------- + + /*! + Name getter/setters + */ + // void setValue(const QString& name); + // QString getValue(void); + +public slots: + void accept(void); + + // Description buttons + void addRegisterBit(void); + void editRegisterBit(void); + void dupRegisterBit(void); + void deleteRegisterBit(void); + +private: + Ui::CDlgMdfRegisterBitList* ui; + + // MDF + CMDF *m_pmdf; + + // Register page + uint16_t m_page; + + // Used to get a sorted list of registers + std::set m_registersSet ; +}; + +#endif // CDLGMDFREGISTERBITLIST_H diff --git a/src/cdlgmdfregisterbitlist.ui b/src/cdlgmdfregisterbitlist.ui index cb35b768..93c403d5 100644 --- a/src/cdlgmdfregisterbitlist.ui +++ b/src/cdlgmdfregisterbitlist.ui @@ -47,12 +47,12 @@ - + - + Add description item @@ -69,7 +69,7 @@ - + Edit description item @@ -86,7 +86,7 @@ - + Duplicate description item @@ -103,7 +103,7 @@ - + Delete Description item diff --git a/src/cdlgmdfregisterlist.cpp b/src/cdlgmdfregisterlist.cpp index 6e56afeb..419e24bc 100644 --- a/src/cdlgmdfregisterlist.cpp +++ b/src/cdlgmdfregisterlist.cpp @@ -36,6 +36,7 @@ #include #include "cdlgmdfcontact.h" +#include "cdlgmdfregister.h" #include "cdlgmdfregisterlist.h" #include "ui_cdlgmdfregisterlist.h" @@ -57,7 +58,7 @@ CDlgMdfRegisterList::CDlgMdfRegisterList(QWidget* parent) : QDialog(parent) , ui(new Ui::CDlgMdfRegisterList) { - m_pmdf = nullptr; + m_pmdf = nullptr; m_page = 0; ui->setupUi(this); @@ -69,7 +70,11 @@ CDlgMdfRegisterList::CDlgMdfRegisterList(QWidget* parent) connect(ui->btnDupRegister, &QToolButton::clicked, this, &CDlgMdfRegisterList::dupRegister); connect(ui->btnDelRegister, &QToolButton::clicked, this, &CDlgMdfRegisterList::deleteRegister); + connect(ui->listRegister, &QListWidget::doubleClicked, this, &CDlgMdfRegisterList::editRegister); + + setInitialFocus(); + this->setFixedSize(this->size()); } /////////////////////////////////////////////////////////////////////////////// @@ -100,10 +105,38 @@ CDlgMdfRegisterList::initDialogData(CMDF* pmdf, uint16_t page) m_pmdf = pmdf; m_page = page; - setWindowTitle(tr("Registers on page %1").arg(page)); + // m_pmdf->getRegisterMap(m_page, pages); // Fill in defined register items renderRegisterItems(); + + // Fill the page combo with page information + renderComboPage(); + + connect(ui->comboPage, SIGNAL(currentIndexChanged(int)), this, SLOT(onPageComboChange(int))); +} + +/////////////////////////////////////////////////////////////////////////////// +// renderComboPage +// + +void +CDlgMdfRegisterList::renderComboPage(void) +{ + setWindowTitle(tr("Registers for %1").arg(m_page)); + + // Fill available pages in combo + std::set pages; + uint32_t cnt = m_pmdf->getPages(pages); + ui->comboPage->clear(); + int pos = 0; + for (std::set::iterator it = pages.begin(); it != pages.end(); ++it) { + ui->comboPage->addItem(QString("Page %1").arg(*it), *it); + if (m_page == *it) { + ui->comboPage->setCurrentIndex(pos); + } + pos++; + } } /////////////////////////////////////////////////////////////////////////////// @@ -113,20 +146,46 @@ CDlgMdfRegisterList::initDialogData(CMDF* pmdf, uint16_t page) void CDlgMdfRegisterList::renderRegisterItems(void) { - std::map pages; + std::map pages; if (nullptr == m_pmdf) { return; } + ui->listRegister->clear(); + + // Make sorted set of registers on this page + std::deque* regset = m_pmdf->getRegisterObjList(); + for (auto it = regset->cbegin(); it != regset->cend(); ++it) { + if (m_page == (*it)->getPage()) { + m_registersSet.insert((*it)->getOffset()); + } + } + m_pmdf->getRegisterMap(m_page, pages); std::deque* regs = m_pmdf->getRegisterObjList(); - for (auto it = regs->cbegin(); it != regs->cend(); ++it) { - QString str = QString("Register %1 %2").arg((*it)->getOffset()).arg((*it)->getName().c_str()); - ui->listRegister->addItem(str); + for (auto it = m_registersSet.cbegin(); it != m_registersSet.cend(); ++it) { + // m_registersSet.insert((*it)->getOffset()); + CMDF_Register* preg = m_pmdf->getRegister(*it, m_page); + if (nullptr != preg) { + QString str = QString("Register %1 -- %2").arg(preg->getOffset()).arg(preg->getName().c_str()); + ui->listRegister->addItem(str); + // Set data to register index + ui->listRegister->item(ui->listRegister->count() - 1)->setData(Qt::UserRole, preg->getOffset()); + } } + + // for (auto it = regs->cbegin(); it != regs->cend(); ++it) { + // m_registersSet.insert((*it)->getOffset()); + // if ((*it)->getPage() == m_page) { + // QString str = QString("Register %1 -- %2").arg((*it)->getOffset()).arg((*it)->getName().c_str()); + // ui->listRegister->addItem(str); + // // Set data to register index + // ui->listRegister->item(ui->listRegister->count() - 1)->setData(Qt::UserRole, (*it)->getOffset()); + // } + // } } /////////////////////////////////////////////////////////////////////////////// @@ -139,10 +198,18 @@ CDlgMdfRegisterList::setInitialFocus(void) // ui->editGuid->setFocus(); } -// ---------------------------------------------------------------------------- -// Getters & Setters -// ---------------------------------------------------------------------------- +/////////////////////////////////////////////////////////////////////////////// +// onPageComboChange +// +void +CDlgMdfRegisterList::onPageComboChange(int idx) +{ + m_page = ui->comboPage->currentData().toInt(); + renderRegisterItems(); + setWindowTitle(tr("Registers for %1").arg(m_page)); + ui->listRegister->setCurrentRow(0); +} /////////////////////////////////////////////////////////////////////////////// // addRegister @@ -152,26 +219,43 @@ void CDlgMdfRegisterList::addRegister(void) { bool ok; - std::string str = QInputDialog::getText(this, - tr("Add contact item"), - tr("Contact value:"), - QLineEdit::Normal, - "", - &ok) - .toStdString(); - - if (ok && str.length()) { - CMDF_Item* pitem = new CMDF_Item(); - if (nullptr != pitem) { - pitem->setValue(str); - // m_pContactList->push_back(pitem); - // ui->listContact->clear(); - // fillContactItems(); + CMDF_Register* pregnew = new CMDF_Register(); + pregnew->setPage(m_page); + + // Save the selected row + int idx = ui->listRegister->currentRow(); + + CDlgMdfRegister dlg(this); + dlg.initDialogData(m_pmdf, pregnew); +addregdlg: + if (QDialog::Accepted == dlg.exec()) { + // Check if register is already defined + CMDF_Register* preg = m_pmdf->getRegister(pregnew->getOffset(), pregnew->getPage()); + if (nullptr != preg) { + QMessageBox::warning(this, tr("MDF add new register"), tr("Register page=%1 offset=%2 is already define. Must be unique.").arg(pregnew->getPage()).arg(pregnew->getOffset())); + goto addregdlg; } - else { - QMessageBox::warning(this, tr(APPNAME), tr("Memory problem could not add item"), QMessageBox::Ok); + qDebug() << "Page=" << pregnew->getPage() << " Offset=" << pregnew->getOffset(); + m_pmdf->getRegisterObjList()->push_back(pregnew); + if (m_page == pregnew->getPage()) { + m_registersSet.insert(pregnew->getOffset()); + } + ui->listRegister->clear(); + renderRegisterItems(); + if (-1 != idx) { + ui->listRegister->setCurrentRow(idx); + } + + // Warn if page is not the same as for dialog + if (pregnew->getPage() != m_page) { + QMessageBox::information(this, + tr("MDF duplicate register"), + tr("Register page=%1 offset=%2 is not on same page [%3] as registers and will be added but not shown.").arg(pregnew->getPage()).arg(pregnew->getOffset()).arg(m_page)); } } + else { + delete pregnew; + } } /////////////////////////////////////////////////////////////////////////////// @@ -183,38 +267,27 @@ CDlgMdfRegisterList::editRegister(void) { bool ok; - // if (-1 != ui->listContact->currentRow()) { + if (-1 != ui->listRegister->currentRow()) { - // // Save the selected row - // int idx = ui->listContact->currentRow(); + // Save the selected row + int idx = ui->listRegister->currentRow(); - // QListWidgetItem* pitem = ui->listContact->currentItem(); + QListWidgetItem* pitem = ui->listRegister->currentItem(); + CMDF_Register* preg = m_pmdf->getRegister(pitem->data(Qt::UserRole).toUInt(), m_page); - // std::string str = QInputDialog::getText(this, - // tr("Edit contact item"), - // tr("Contact value:"), - // QLineEdit::Normal, - // pitem->text(), - // &ok) - // .toStdString(); - - // if (ok && str.length()) { - // pitem->setText(str.c_str()); - // CMDF_Item* pitem = m_pContactList->at(idx); - // if (nullptr != pitem) { - // pitem->setValue(str); - // } - // else { - // QMessageBox::warning(this, tr(APPNAME), tr("Contact item was not found"), QMessageBox::Ok); - // } - // ui->listContact->clear(); - // fillContactItems(); - // ui->listContact->setCurrentRow(idx); - // } - // } - // else { - // QMessageBox::warning(this, tr(APPNAME), tr("An item must be selected"), QMessageBox::Ok); - // } + CDlgMdfRegister dlg(this); + dlg.initDialogData(m_pmdf, preg); + // Don't allow editing of page and offset + dlg.setReadOnly(); + if (QDialog::Accepted == dlg.exec()) { + ui->listRegister->clear(); + renderRegisterItems(); + ui->listRegister->setCurrentRow(idx); + } + } + else { + QMessageBox::warning(this, tr(APPNAME), tr("An item must be selected"), QMessageBox::Ok); + } } /////////////////////////////////////////////////////////////////////////////// @@ -224,7 +297,54 @@ CDlgMdfRegisterList::editRegister(void) void CDlgMdfRegisterList::dupRegister(void) { - bool ok; + if (-1 != ui->listRegister->currentRow()) { + + // Save the selected row + int idx = ui->listRegister->currentRow(); + + QListWidgetItem* pitem = ui->listRegister->currentItem(); + CMDF_Register* preg = m_pmdf->getRegister(pitem->data(Qt::UserRole).toUInt(), m_page); + + CMDF_Register* pregnew = new CMDF_Register(); + pregnew->setPage(m_page); + + // Make copy + *pregnew = *preg; + + CDlgMdfRegister dlg(this); + dlg.initDialogData(m_pmdf, pregnew); + dupregdlg: + if (QDialog::Accepted == dlg.exec()) { + // Check if register is already defined + CMDF_Register* pregold = m_pmdf->getRegister(pregnew->getOffset(), pregnew->getPage()); + if (nullptr != pregold) { + QMessageBox::warning(this, tr("MDF duplicate register"), tr("Register page=%1 offset=%2 is already define. Must be unique.").arg(pregnew->getPage()).arg(pregnew->getOffset())); + goto dupregdlg; + } + qDebug() << "Page=" << pregnew->getPage() << " Offset=" << pregnew->getOffset(); + m_pmdf->getRegisterObjList()->push_back(pregnew); + if (m_page == pregnew->getPage()) { + m_registersSet.insert(pregnew->getOffset()); + } + ui->listRegister->clear(); + renderRegisterItems(); + if (-1 != idx) { + ui->listRegister->setCurrentRow(idx); + } + // Warn if page is not the same as for dialog + if (pregnew->getPage() != m_page) { + QMessageBox::information(this, + tr("MDF duplicate register"), + tr("Register page=%1 offset=%2 is not on same page [%3] as registers and will be added but not shown.").arg(pregnew->getPage()).arg(pregnew->getOffset()).arg(m_page)); + } + } + else { + delete pregnew; + } + } + else { + QMessageBox::warning(this, tr(APPNAME), tr("An item must be selected"), QMessageBox::Ok); + } // if (-1 != ui->listContact->currentRow()) { @@ -268,18 +388,19 @@ CDlgMdfRegisterList::dupRegister(void) void CDlgMdfRegisterList::deleteRegister(void) { - // if (-1 != ui->listContact->currentRow()) { - - // // Save the row - // int idx = ui->listContact->currentRow(); - - // QListWidgetItem* pitem = ui->listContact->currentItem(); - // ui->listContact->removeItemWidget(pitem); - // m_pContactList->erase(m_pContactList->cbegin()+idx); - - // ui->listContact->clear(); - // fillContactItems(); - // } + if (-1 != ui->listRegister->currentRow()) { + + // Save the row + int idx = ui->listRegister->currentRow(); + + QListWidgetItem* pitem = ui->listRegister->currentItem(); + CMDF_Register* preg = m_pmdf->getRegister(pitem->data(Qt::UserRole).toUInt(), m_page); + m_pmdf->deleteRegister(preg); + delete preg; + ui->listRegister->removeItemWidget(pitem); + renderRegisterItems(); + ui->listRegister->setCurrentRow(idx); + } } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/cdlgmdfregisterlist.h b/src/cdlgmdfregisterlist.h index 59054ec6..9b4b0af8 100644 --- a/src/cdlgmdfregisterlist.h +++ b/src/cdlgmdfregisterlist.h @@ -67,6 +67,11 @@ class CDlgMdfRegisterList : public QDialog { */ void initDialogData(CMDF *pmdf, uint16_t page=0); + /*! + Fill page combo box with page information + */ + void renderComboPage(void); + /*! Fill in contact items */ @@ -86,6 +91,9 @@ class CDlgMdfRegisterList : public QDialog { public slots: void accept(void); + // Called wehen page combo changes + void onPageComboChange(int idx); + // Description buttons void addRegister(void); void editRegister(void); @@ -100,6 +108,9 @@ public slots: // Register page uint16_t m_page; + + // Used to get a sorted list of registers + std::set m_registersSet ; }; #endif // CDLGMDFREGISTERLIST_H diff --git a/src/cdlgmdfregisterlist.ui b/src/cdlgmdfregisterlist.ui index ae1364ab..bfce0736 100644 --- a/src/cdlgmdfregisterlist.ui +++ b/src/cdlgmdfregisterlist.ui @@ -42,6 +42,9 @@ + + + diff --git a/src/cfrmmdf.cpp b/src/cfrmmdf.cpp index c7a8e0b4..6619870f 100644 --- a/src/cfrmmdf.cpp +++ b/src/cfrmmdf.cpp @@ -62,6 +62,8 @@ #include "cdlgmdfmanufacturer.h" #include "cdlgmdfmodule.h" #include "cdlgmdfregister.h" +#include "cdlgmdfregisterbit.h" +#include "cdlgmdfregisterbitlist.h" #include "cdlgmdfregisterlist.h" #include @@ -196,6 +198,8 @@ CFrmMdf::CFrmMdf(QWidget* parent, const char* path) &QTreeWidget::itemDoubleClicked, this, &CFrmMdf::onItemDoubleClicked); + + this->setFixedSize(this->size()); } /////////////////////////////////////////////////////////////////////////////// @@ -332,18 +336,6 @@ CFrmMdf::showMdfContextMenu(const QPoint& pos) menu->addAction(QString(tr("Edit")), this, SLOT(editModuleData())); break; - case mdf_type_value: - menu->addAction(QString(tr("Value")), this, SLOT(loadSelectedMdf())); - break; - - case mdf_type_bit: - menu->addAction(QString(tr("Bit")), this, SLOT(loadSelectedMdf())); - break; - - case mdf_type_bit_item: - menu->addAction(QString(tr("Bit item")), this, SLOT(loadSelectedMdf())); - break; - case mdf_type_register_page: menu->addAction(QString(tr("Register list for page")), this, SLOT(editRegister())); break; @@ -362,6 +354,34 @@ CFrmMdf::showMdfContextMenu(const QPoint& pos) menu->addAction(QString(tr("Delete register")), this, SLOT(deleteRegister())); break; + case mdf_type_value: + menu->addAction(QString(tr("Open list of register bits")), this, SLOT(editRegisterValue())); + break; + + case mdf_type_value_item: + menu->addAction(QString(tr("Edit register value item")), this, SLOT(editRegisterValue())); + menu->addAction(QString(tr("Delete register value item")), this, SLOT(deleteRegisterValue())); + break; + + case mdf_type_value_sub_item: + menu->addAction(QString(tr("Edit register value item")), this, SLOT(editRegisterValue())); + menu->addAction(QString(tr("Delete register value item")), this, SLOT(deleteRegisterValue())); + break; + + case mdf_type_bit: + menu->addAction(QString(tr("Open list of register bits")), this, SLOT(editRegisterBit())); + break; + + case mdf_type_bit_item: + menu->addAction(QString(tr("Edit register bit item")), this, SLOT(editRegisterBit())); + menu->addAction(QString(tr("Delete register bit item")), this, SLOT(deleteRegisterBit())); + break; + + case mdf_type_bit_sub_item: + menu->addAction(QString(tr("Edit register bit item")), this, SLOT(editRegisterBit())); + menu->addAction(QString(tr("Delete register bit item")), this, SLOT(deleteRegisterBit())); + break; + case mdf_type_remotevar: menu->addAction(QString(tr("Edit remote variable")), this, SLOT(loadSelectedMdf())); break; @@ -402,10 +422,6 @@ CFrmMdf::showMdfContextMenu(const QPoint& pos) menu->addAction(QString(tr("Event item")), this, SLOT(loadSelectedMdf())); break; - case mdf_type_value_item: - menu->addAction(QString(tr("Value Item")), this, SLOT(loadSelectedMdf())); - break; - case mdf_type_bootloader: // menu->addAction(QString(tr("Bootloader")), this, SLOT(editBootlLoader())); menu->addAction(QString(tr("Edit bootloader")), this, SLOT(editBootLoader())); @@ -719,11 +735,11 @@ CFrmMdf::renderInfoUrlItems(QTreeWidgetItem* pParent, } /////////////////////////////////////////////////////////////////////////////// -// renderRegisterInfo +// renderBits // void -CFrmMdf::renderBitInfo(QTreeWidgetItem* pParent, std::deque& dequebits) +CFrmMdf::renderBits(QTreeWidgetItem* pParent, std::deque& dequebits) { QString str; QMdfTreeWidgetItem* pItem; @@ -746,72 +762,85 @@ CFrmMdf::renderBitInfo(QTreeWidgetItem* pParent, std::deque& dequebit CMDF_Bit* pbit = dequebits[i]; - str = QString("Bitfield no %1 Bits:{").arg(/*dequebits.size()-*/ i); + str = QString("Bitfield %1 Bits:{").arg(pbit->getName().c_str()); for (int j = pbit->getPos(); j < qMin(8, pbit->getPos() + pbit->getWidth()); j++) { str += QString(" %1 ").arg(j); } str += "}"; - QMdfTreeWidgetItem* pItemParent = new QMdfTreeWidgetItem(pItemBitDefs, mdf_type_bit_item); + QMdfTreeWidgetItem* pItemParent = new QMdfTreeWidgetItem(pItemBitDefs, pbit, mdf_type_bit_item); pItemParent->setText(0, str); pItemBitDefs->addChild(pItemParent); - str = QString("Name: %1").arg(pbit->getName().c_str()); - pItem = new QMdfTreeWidgetItem(pItemParent, mdf_type_generic_string); - pItem->setText(0, str); - pItemBitDefs->addChild(pItem); - - str = QString("Pos: %1").arg(pbit->getPos()); - pItem = new QMdfTreeWidgetItem(pItemParent, mdf_type_generic_number); - pItem->setText(0, str); - pItemBitDefs->addChild(pItem); + renderBitInfo(pItemParent, pbit); + } +} - str = QString("Width: %1").arg(pbit->getWidth()); - pItem = new QMdfTreeWidgetItem(pItemParent, mdf_type_generic_number); - pItem->setText(0, str); - pItemBitDefs->addChild(pItem); +/////////////////////////////////////////////////////////////////////////////// +// renderBitInfo +// - str = QString("Default: %1").arg(pbit->getDefault()); - pItem = new QMdfTreeWidgetItem(pItemParent, mdf_type_generic_number); - pItem->setText(0, str); - pItemBitDefs->addChild(pItem); +void +CFrmMdf::renderBitInfo(QMdfTreeWidgetItem* pItemParent, CMDF_Bit* pbit) +{ + QString str; + QMdfTreeWidgetItem* pItem; - str = QString("Min: %1").arg(pbit->getMin()); - pItem = new QMdfTreeWidgetItem(pItemParent, mdf_type_generic_number); - pItem->setText(0, str); - pItemBitDefs->addChild(pItem); + str = QString("Name: %1").arg(pbit->getName().c_str()); + pItem = new QMdfTreeWidgetItem(pItemParent, pbit, mdf_type_bit_sub_item, CDlgMdfRegisterBit::index_name); + pItem->setText(0, str); + pItemParent->addChild(pItem); - str = QString("Max: %1").arg(pbit->getMax()); - pItem = new QMdfTreeWidgetItem(pItemParent, mdf_type_generic_number); - pItem->setText(0, str); - pItemBitDefs->addChild(pItem); + str = QString("Pos: %1").arg(pbit->getPos()); + pItem = new QMdfTreeWidgetItem(pItemParent, pbit, mdf_type_bit_sub_item, CDlgMdfRegisterBit::index_pos); + pItem->setText(0, str); + pItemParent->addChild(pItem); - // str = QString("Access rights: %1").arg(pbit->getAccess()); - str = QString("Access: %1 (").arg(pbit->getAccess()); - if (2 & pbit->getAccess()) { - str += "r"; - } - if (1 & pbit->getAccess()) { - str += "w"; - } - str += ")"; - pItem = new QMdfTreeWidgetItem(pItemParent, mdf_type_generic_access); - pItem->setText(0, str); - pItemParent->addChild(pItem); + str = QString("Width: %1").arg(pbit->getWidth()); + pItem = new QMdfTreeWidgetItem(pItemParent, pbit, mdf_type_bit_sub_item, CDlgMdfRegisterBit::index_width); + pItem->setText(0, str); + pItemParent->addChild(pItem); - str = QString("Mask: 0b%1").arg(pbit->getMask(), 1, 2); - pItem = new QMdfTreeWidgetItem(pItemParent, mdf_type_generic_string); - pItem->setText(0, str); - pItemParent->addChild(pItem); + str = QString("Default: %1").arg(pbit->getDefault()); + pItem = new QMdfTreeWidgetItem(pItemParent, pbit, mdf_type_bit_sub_item, CDlgMdfRegisterBit::index_default); + pItem->setText(0, str); + pItemParent->addChild(pItem); - // Valid values - renderValueInfo(pItemParent, *pbit->getListValues()); + str = QString("Min: %1").arg(pbit->getMin()); + pItem = new QMdfTreeWidgetItem(pItemParent, pbit, mdf_type_bit_sub_item, CDlgMdfRegisterBit::index_min); + pItem->setText(0, str); + pItemParent->addChild(pItem); - // Descriptions - renderDescriptionItems(pItemParent, pbit, pbit->getMapDescription()); + str = QString("Max: %1").arg(pbit->getMax()); + pItem = new QMdfTreeWidgetItem(pItemParent, pbit, mdf_type_bit_sub_item, CDlgMdfRegisterBit::index_max); + pItem->setText(0, str); + pItemParent->addChild(pItem); - // Info URL's - renderInfoUrlItems(pItemParent, pbit, pbit->getMapDescription()); + // str = QString("Access rights: %1").arg(pbit->getAccess()); + str = QString("Access: %1 (").arg(pbit->getAccess()); + if (2 & pbit->getAccess()) { + str += "r"; + } + if (1 & pbit->getAccess()) { + str += "w"; } + str += ")"; + pItem = new QMdfTreeWidgetItem(pItemParent, pbit, mdf_type_bit_sub_item, CDlgMdfRegisterBit::index_access); + pItem->setText(0, str); + pItemParent->addChild(pItem); + + str = QString("Mask: 0b%1").arg(pbit->getMask(), 1, 2); + pItem = new QMdfTreeWidgetItem(pItemParent, pbit, mdf_type_bit_sub_item, 0); + pItem->setText(0, str); + pItemParent->addChild(pItem); + + // Valid values + renderValueInfo(pItemParent, *pbit->getListValues()); + + // Descriptions + renderDescriptionItems(pItemParent, pbit, pbit->getMapDescription()); + + // Info URL's + renderInfoUrlItems(pItemParent, pbit, pbit->getMapDescription()); } /////////////////////////////////////////////////////////////////////////////// @@ -847,17 +876,17 @@ CFrmMdf::renderValueInfo(QTreeWidgetItem* pParent, std::deque& dequ // str += QString(" %1 ").arg(j); // } // str += "}"; - QMdfTreeWidgetItem* pItemParent = new QMdfTreeWidgetItem(pItemValue, mdf_type_value_item); + QMdfTreeWidgetItem* pItemParent = new QMdfTreeWidgetItem(pItemValue, pvalue, mdf_type_value_item); pItemParent->setText(0, str); pItemValue->addChild(pItemParent); str = QString("Name: %1").arg(pvalue->getName().c_str()); - pItem = new QMdfTreeWidgetItem(pItemParent, mdf_type_generic_string); + pItem = new QMdfTreeWidgetItem(pItemParent, pvalue, mdf_type_value_sub_item); pItem->setText(0, str); pItemValue->addChild(pItem); str = QString("Value: %1").arg(pvalue->getValue().c_str()); - pItem = new QMdfTreeWidgetItem(pItemParent, mdf_type_generic_number); + pItem = new QMdfTreeWidgetItem(pItemParent, pvalue, mdf_type_value_sub_item); pItem->setText(0, str); pItemValue->addChild(pItem); @@ -998,7 +1027,7 @@ CFrmMdf::renderRegisterInfo(QTreeWidgetItem* pParent, CMDF_Register* preg) } // Fill in bit field info - renderBitInfo(pParent, *preg->getListBits()); + renderBits(pParent, *preg->getListBits()); // Fill in valid values renderValueInfo(pParent, *preg->getListValues()); @@ -1010,6 +1039,74 @@ CFrmMdf::renderRegisterInfo(QTreeWidgetItem* pParent, CMDF_Register* preg) renderInfoUrlItems(pParent, preg, preg->getMapDescription()); } +/////////////////////////////////////////////////////////////////////////////// +// renderRegisters +// + +void +CFrmMdf::renderRegisters(QTreeWidgetItem* pParent) +{ + uint32_t nPages; + std::set pages; + QMdfTreeWidgetItem* pSubItem; + QMdfTreeWidgetItem* pItem; + + // Check pointers + if (nullptr == pParent) { + return; + } + + // Fetch number of pages and pages + nPages = m_mdf.getPages(pages); + std::deque* regs = m_mdf.getRegisterObjList(); + + // If we have pages separate registers in pages + if (nPages > 1) { + for (auto itr : pages) { + + pItem = new QMdfTreeWidgetItem(pParent, &m_mdf, mdf_type_register_page, itr); + if (nullptr != pItem) { + + QString str = QString("Register page: %1").arg(itr); + pItem->setText(0, str); + pParent->addChild(pItem); + + // Add registers for page + for (auto it = regs->cbegin(); it != regs->cend(); ++it) { + if (itr == (*it)->getPage()) { + pSubItem = new QMdfTreeWidgetItem(pItem, (*it), mdf_type_register_item); + if (nullptr != pSubItem) { + str = QString("Register %1 %2").arg((*it)->getOffset()).arg((*it)->getName().c_str()); + pSubItem->setText(0, str); + pItem->addChild(pSubItem); + renderRegisterInfo(pSubItem, *it); + } + } + } + } + } + } + // We only have one page + else { + std::map mapRegs; + m_mdf.getRegisterMap(0, mapRegs); + renderRegisterInfo(pItem, mapRegs[0]); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// renderRegisters +// + +void +CFrmMdf::renderRemoteVariables(QTreeWidgetItem* pParent) +{ + // Check pointers + if (nullptr == pParent) { + return; + } +} + /////////////////////////////////////////////////////////////////////////////// // renderManufacturerEmail // @@ -2107,42 +2204,7 @@ CFrmMdf::loadMdf(void) pItemRegister->setText(0, tr("Registers")); ui->treeMDF->addTopLevelItem(pItemRegister); - // Fetch number of pages and pages - nPages = m_mdf.getPages(pages); - std::deque* regs = m_mdf.getRegisterObjList(); - - // If we have pages separate registers in pages - if (nPages > 1) { - for (auto itr : pages) { - - pItem = new QMdfTreeWidgetItem(pItemRegister, &m_mdf, mdf_type_register_page, itr); - if (nullptr != pItem) { - - str = QString("Register page: %1").arg(itr); - pItem->setText(0, str); - pItemRegister->addChild(pItem); - - // Add registers for page - for (auto it = regs->cbegin(); it != regs->cend(); ++it) { - if (itr == (*it)->getPage()) { - pSubItem = new QMdfTreeWidgetItem(pItem, (*it), mdf_type_register_item); - if (nullptr != pSubItem) { - str = QString("Register %1 %2").arg((*it)->getOffset()).arg((*it)->getName().c_str()); - pSubItem->setText(0, str); - pItem->addChild(pSubItem); - renderRegisterInfo(pSubItem, *it); - } - } - } - } - } - } - // We only have one page - else { - std::map mapRegs; - m_mdf.getRegisterMap(0, mapRegs); - renderRegisterInfo(pItem, mapRegs[0]); - } + renderRegisters(pItemRegister); // * * * Remote variables * * * @@ -2246,7 +2308,7 @@ CFrmMdf::loadMdf(void) } // Fill in bit field info - renderBitInfo(pSubItem, *pvar->getListBits()); + renderBits(pSubItem, *pvar->getListBits()); // Fill in valid values renderValueInfo(pSubItem, *pvar->getListValues()); @@ -2272,7 +2334,7 @@ CFrmMdf::loadMdf(void) std::deque* palarm = m_mdf.getAlarmList(); // Fill in bit field info - renderBitInfo(pItemAlarm, *palarm); + renderBits(pItemAlarm, *palarm); // * * * Decision Matrix * * * @@ -2404,7 +2466,7 @@ CFrmMdf::loadMdf(void) } // Fill in bit field info - renderBitInfo(pActionParamItem, *pactionparam->getListBits()); + renderBits(pActionParamItem, *pactionparam->getListBits()); // Fill in valid values renderValueInfo(pActionParamItem, *pactionparam->getListValues()); @@ -2528,7 +2590,7 @@ CFrmMdf::loadMdf(void) } // Fill in bit field info - renderBitInfo(pEventSubItem, *pEventData->getListBits()); + renderBits(pEventSubItem, *pEventData->getListBits()); // Fill in valid values renderValueInfo(pEventSubItem, *pEventData->getListValues()); @@ -2939,12 +3001,19 @@ CFrmMdf::editItem() break; case mdf_type_value: + editRegisterValue(); + break; + + case mdf_type_value_item: + editRegisterValue(); break; case mdf_type_bit: + editRegisterBit(); break; case mdf_type_bit_item: + editRegisterBit(); break; case mdf_type_register_page: @@ -2993,9 +3062,6 @@ CFrmMdf::editItem() case mdf_type_event_item: break; - case mdf_type_value_item: - break; - case mdf_type_bootloader: break; @@ -5190,6 +5256,15 @@ CFrmMdf::editRegister(void) CDlgMdfRegisterList dlg(this); dlg.initDialogData(&m_mdf, selectedIndex); if (QDialog::Accepted == dlg.exec()) { + // Redraw all register items - We do not know changes + QList childrenList = m_headRegister->takeChildren(); + // Remove children + for (qsizetype i = 0; i < childrenList.size(); ++i) { + QMdfTreeWidgetItem* item = (QMdfTreeWidgetItem*)childrenList.at(i); + delete item; + } + childrenList.clear(); + renderRegisters(m_headRegister); } } break; @@ -5288,7 +5363,7 @@ CFrmMdf::deleteRegister(void) delete item; } childrenList.clear(); - std::deque *pregisters = m_mdf.getRegisterObjList(); + std::deque* pregisters = m_mdf.getRegisterObjList(); // Find element and delete it for (std::deque::iterator it = m_mdf.getRegisterObjList()->begin(); it != m_mdf.getRegisterObjList()->end();) { if (*it == pItem->getObject()) { @@ -5304,7 +5379,7 @@ CFrmMdf::deleteRegister(void) } break; case mdf_type_register_sub_item: { - QMdfTreeWidgetItem* pItemHeadHead = (QMdfTreeWidgetItem*)pItemHead->parent(); + QMdfTreeWidgetItem* pItemHeadHead = (QMdfTreeWidgetItem*)pItemHead->parent(); QList childrenList = pItemHead->takeChildren(); // Remove children for (qsizetype i = 0; i < childrenList.size(); ++i) { @@ -5313,7 +5388,7 @@ CFrmMdf::deleteRegister(void) } childrenList.clear(); - std::deque *pregisters = m_mdf.getRegisterObjList(); + std::deque* pregisters = m_mdf.getRegisterObjList(); // Find element and delete it for (std::deque::iterator it = m_mdf.getRegisterObjList()->begin(); it != m_mdf.getRegisterObjList()->end();) { if (*it == pItem->getObject()) { @@ -5326,11 +5401,226 @@ CFrmMdf::deleteRegister(void) } pItemHeadHead->removeChild(pItemHead); - }break; + } break; case mdf_type_register_page: break; } - //m_headFileSetupScript->removeChild(pItemHead); + // m_headFileSetupScript->removeChild(pItemHead); +} + +/////////////////////////////////////////////////////////////////////////////// +// editRegisterBit +// + +void +CFrmMdf::editRegisterBit(void) +{ + QMdfTreeWidgetItem* pItem = (QMdfTreeWidgetItem*)ui->treeMDF->currentItem(); + QMdfTreeWidgetItem* pItemHead = (QMdfTreeWidgetItem*)pItem->parent(); + uint16_t selectedIndex = pItem->getElementIndex(); + + // Item must be selected + if (nullptr == pItem) { + int ret = QMessageBox::critical(this, tr("MDF register edit"), tr("No MDF register item selected")); + return; + } + + // Must have an object + if (nullptr == pItem->getObject()) { + int ret = QMessageBox::critical(this, tr("MDF register edit"), tr("Internal error: Invalid register object")); + spdlog::error("MDF register edit - object has nullptr"); + return; + } + + switch (pItem->getObjectType()) { + + case mdf_type_bit: { + // CDlgMdfRegisterBitList dlg(this); + // dlg.initDialogData(&m_mdf, selectedIndex); + // if (QDialog::Accepted == dlg.exec()) { + // // Redraw all register items - We do not know changes + // QList childrenList = m_headRegister->takeChildren(); + // // Remove children + // for (qsizetype i = 0; i < childrenList.size(); ++i) { + // QMdfTreeWidgetItem* item = (QMdfTreeWidgetItem*)childrenList.at(i); + // delete item; + // } + // childrenList.clear(); + // renderRegisters(m_headRegister); + // } + } break; + + case mdf_type_bit_item: { + // CMDF_Bit* pbit = (CMDF_Bit*)pItem->getObject(); + // if (nullptr == pbit) { + // int ret = QMessageBox::critical(this, tr("APPNAME"), tr("Internal error: Invalid firmware object")); + // spdlog::error("MDF register edit - object has nullptr"); + // return; + // } + // CDlgMdfRegisterBitList dlg(this); + // dlg.initDialogData(&m_mdf, pbit, selectedIndex); + // if (QDialog::Accepted == dlg.exec()) { + // pItem->setExpanded(true); + // QList childrenList = pItem->takeChildren(); + // // Remove children + // for (qsizetype i = 0; i < childrenList.size(); ++i) { + // QMdfTreeWidgetItem* item = (QMdfTreeWidgetItem*)childrenList.at(i); + // delete item; + // } + // childrenList.clear(); + // pItem->setText(0, QString("Bitfield %1 Bits:{").arg(pbit->getName().c_str())); + // renderRegisterInfo(pItem, preg); + // } + } break; + + case mdf_type_bit_sub_item: { + CMDF_Bit* pbit = (CMDF_Bit*)pItem->getObject(); + if (nullptr == pbit) { + int ret = QMessageBox::critical(this, tr("APPNAME"), tr("Internal error: Invalid firmware object")); + spdlog::error("MDF register bit edit - object has nullptr"); + return; + } + CDlgMdfRegisterBit dlg(this); + dlg.initDialogData(&m_mdf, pbit, selectedIndex); + if (QDialog::Accepted == dlg.exec()) { + pItemHead->setExpanded(true); + QList childrenList = pItemHead->takeChildren(); + // Remove children + for (qsizetype i = 0; i < childrenList.size(); ++i) { + QMdfTreeWidgetItem* item = (QMdfTreeWidgetItem*)childrenList.at(i); + // qDebug() << item->text(0); + delete item; + } + childrenList.clear(); + QString str = str = QString("Bitfield %1 Bits:{").arg(pbit->getName().c_str()); + for (int j = pbit->getPos(); j < qMin(8, pbit->getPos() + pbit->getWidth()); j++) { + str += QString(" %1 ").arg(j); + } + str += "}"; + pItemHead->setText(0, str); + renderBitInfo(pItemHead, pbit); + } + } break; + + default: + break; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// deleteRegisterBit +// + +void +CFrmMdf::deleteRegisterBit(void) +{ + QMdfTreeWidgetItem* pItem = (QMdfTreeWidgetItem*)ui->treeMDF->currentItem(); + QMdfTreeWidgetItem* pItemHead = (QMdfTreeWidgetItem*)pItem->parent(); + uint16_t selectedIndex = pItem->getElementIndex(); + + // Item must be selected + if (nullptr == pItem) { + int ret = QMessageBox::critical(this, tr("MDF file edit"), tr("No MDF file item selected")); + return; + } + + // Must have an object + if (nullptr == pItem->getObject()) { + int ret = QMessageBox::critical(this, tr("MDF file edit"), tr("Internal error: Invalid file object")); + spdlog::error("MDF file edit - object has nullptr"); + return; + } + + if (QMessageBox::Yes != QMessageBox::question(this, tr("MDF module item delete"), tr("Are you sure?"))) { + return; + } + + switch (pItem->getObjectType()) { + + case mdf_type_register: + // Nothing to do and should not come here :) + break; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// editRegisterValue +// + +void +CFrmMdf::editRegisterValue(void) +{ + QMdfTreeWidgetItem* pItem = (QMdfTreeWidgetItem*)ui->treeMDF->currentItem(); + QMdfTreeWidgetItem* pItemHead = (QMdfTreeWidgetItem*)pItem->parent(); + uint16_t selectedIndex = pItem->getElementIndex(); + + // Item must be selected + if (nullptr == pItem) { + int ret = QMessageBox::critical(this, tr("MDF register edit"), tr("No MDF register item selected")); + return; + } + + // Must have an object + if (nullptr == pItem->getObject()) { + int ret = QMessageBox::critical(this, tr("MDF register edit"), tr("Internal error: Invalid register object")); + spdlog::error("MDF register edit - object has nullptr"); + return; + } + + switch (pItem->getObjectType()) { + + case mdf_type_register_page: { + CDlgMdfRegisterList dlg(this); + dlg.initDialogData(&m_mdf, selectedIndex); + if (QDialog::Accepted == dlg.exec()) { + // Redraw all register items - We do not know changes + QList childrenList = m_headRegister->takeChildren(); + // Remove children + for (qsizetype i = 0; i < childrenList.size(); ++i) { + QMdfTreeWidgetItem* item = (QMdfTreeWidgetItem*)childrenList.at(i); + delete item; + } + childrenList.clear(); + renderRegisters(m_headRegister); + } + } break; + } } + +/////////////////////////////////////////////////////////////////////////////// +// deleteRegisterValue +// + +void +CFrmMdf::deleteRegisterValue(void) +{ + QMdfTreeWidgetItem* pItem = (QMdfTreeWidgetItem*)ui->treeMDF->currentItem(); + QMdfTreeWidgetItem* pItemHead = (QMdfTreeWidgetItem*)pItem->parent(); + uint16_t selectedIndex = pItem->getElementIndex(); + + // Item must be selected + if (nullptr == pItem) { + int ret = QMessageBox::critical(this, tr("MDF file edit"), tr("No MDF file item selected")); + return; + } + + // Must have an object + if (nullptr == pItem->getObject()) { + int ret = QMessageBox::critical(this, tr("MDF file edit"), tr("Internal error: Invalid file object")); + spdlog::error("MDF file edit - object has nullptr"); + return; + } + + if (QMessageBox::Yes != QMessageBox::question(this, tr("MDF module item delete"), tr("Are you sure?"))) { + return; + } + + switch (pItem->getObjectType()) { + + case mdf_type_register: + // Nothing to do and should not come here :) + break; + } +} \ No newline at end of file diff --git a/src/cfrmmdf.h b/src/cfrmmdf.h index 0e50a2e7..3787e190 100644 --- a/src/cfrmmdf.h +++ b/src/cfrmmdf.h @@ -234,10 +234,22 @@ public slots: void deleteFile(void); /// Edit register info - void editRegister(); + void editRegister(void); /// Delete register item - void deleteRegister(); + void deleteRegister(void); + + /// Edit register info + void editRegisterBit(void); + + /// Delete register item + void deleteRegisterBit(void); + + /// Edit register info + void editRegisterValue(void); + + /// Delete register item + void deleteRegisterValue(void); /*! Fill in data from info map as children to parent item @@ -273,7 +285,15 @@ public slots: @param dequebits Reference for std:deque holding bit infor objects */ void - renderBitInfo(QTreeWidgetItem* pParent, std::deque& dequebits); + renderBits(QTreeWidgetItem* pParent, std::deque& dequebits); + + /*! + Render info for one bit + @param pItemParent Pointer to parent item for bit + @param pbit Object holding bit info + */ + void + renderBitInfo(QMdfTreeWidgetItem* pItemParent, CMDF_Bit* pbit); /*! Fill value list info @@ -293,6 +313,21 @@ public slots: void renderRegisterInfo(QTreeWidgetItem* pParent, CMDF_Register* preg); + /*! + Render all registers + @param Header item to draw them as subitems under + */ + void + renderRegisters(QTreeWidgetItem* pParent); + + +/*! + Render all remote variables + @param Header item to draw them as subitems under + */ + void + renderRemoteVariables(QTreeWidgetItem* pParent); + /*! Remove all subitems of a head item that have a speciified type. @param pItem Pointer to head item