fix(cpn): crash when creating a new model on Windows (#6869)
This commit is contained in:
@@ -29,22 +29,23 @@
|
||||
|
||||
ZoneOptionValue::ZoneOptionValue()
|
||||
{
|
||||
memset((void*)this, 0, sizeof(ZoneOptionValue));
|
||||
unsignedValue = 0;
|
||||
signedValue = 0;
|
||||
boolValue = 0;
|
||||
stringValue.clear();
|
||||
sourceValue.clear();
|
||||
colorValue = 0;
|
||||
}
|
||||
|
||||
bool ZoneOptionValue::isEmpty() const
|
||||
{
|
||||
return unsignedValue == 0 && signedValue == 0 && boolValue == 0 && colorValue == 0 &&
|
||||
stringValue.empty() && sourceValue.toValue() == 0;
|
||||
}
|
||||
|
||||
ZoneOptionValueTyped::ZoneOptionValueTyped()
|
||||
{
|
||||
memset((void*)this, 0, sizeof(ZoneOptionValueTyped));
|
||||
}
|
||||
|
||||
WidgetPersistentData::WidgetPersistentData()
|
||||
{
|
||||
memset((void*)this, 0, sizeof(WidgetPersistentData));
|
||||
}
|
||||
|
||||
ZonePersistentData::ZonePersistentData()
|
||||
{
|
||||
memset((void*)this, 0, sizeof(ZonePersistentData));
|
||||
type = ZOV_Unsigned;
|
||||
}
|
||||
|
||||
inline void setZoneOptionValue(ZoneOptionValue& zov, bool value)
|
||||
@@ -57,9 +58,9 @@ inline void setZoneOptionValue(ZoneOptionValue& zov, int value)
|
||||
zov.signedValue = value;
|
||||
}
|
||||
|
||||
inline void setZoneOptionValue(ZoneOptionValue& zov, char value)
|
||||
inline void setZoneOptionValue(ZoneOptionValue& zov, const char* value)
|
||||
{
|
||||
memset(&zov.stringValue, value, LEN_ZONE_OPTION_STRING);
|
||||
zov.stringValue = value;
|
||||
}
|
||||
|
||||
inline void setZoneOptionValue(ZoneOptionValue& zov, unsigned int value)
|
||||
@@ -110,22 +111,17 @@ static const ZoneOptionValueTyped zero_widget_option = {};
|
||||
|
||||
bool ZoneOptionValueTyped::isEmpty() const
|
||||
{
|
||||
return !memcmp((void*)this, &zero_widget_option, sizeof(zero_widget_option));
|
||||
return type == ZOV_Unsigned && value.isEmpty();
|
||||
}
|
||||
|
||||
bool ZonePersistentData::isEmpty() const
|
||||
{
|
||||
return strlen(widgetName) == 0;
|
||||
}
|
||||
|
||||
RadioLayout::CustomScreenData::CustomScreenData()
|
||||
{
|
||||
memset((void*)this, 0, sizeof(RadioLayout::CustomScreenData));
|
||||
return widgetName.empty();
|
||||
}
|
||||
|
||||
bool RadioLayout::CustomScreenData::isEmpty() const
|
||||
{
|
||||
return strlen(layoutId) == 0;
|
||||
return layoutId.empty();
|
||||
}
|
||||
|
||||
void RadioLayout::CustomScreens::clear()
|
||||
@@ -141,7 +137,7 @@ void RadioLayout::init(const char* layoutId, CustomScreens& customScreens)
|
||||
|
||||
for (int i = 0; i < MAX_CUSTOM_SCREENS; i++) {
|
||||
if (i == 0)
|
||||
strncpy(customScreens.customScreenData[i].layoutId, layoutId, LAYOUT_ID_LEN);
|
||||
customScreens.customScreenData[i].layoutId = layoutId;
|
||||
|
||||
LayoutPersistentData& persistentData =
|
||||
customScreens.customScreenData[i].layoutPersistentData;
|
||||
|
||||
@@ -33,14 +33,11 @@
|
||||
|
||||
constexpr int MAX_CUSTOM_SCREENS {10};
|
||||
constexpr int MAX_THEME_OPTIONS {5};
|
||||
constexpr int LEN_ZONE_OPTION_STRING {255}; // TODO: use std::string instead of fixed length char array
|
||||
constexpr int MAX_LAYOUT_ZONES {10};
|
||||
constexpr int MAX_LAYOUT_OPTIONS {10};
|
||||
constexpr int WIDGET_NAME_LEN {255}; // TODO: use std::string instead of fixed length char array
|
||||
constexpr int MAX_WIDGET_OPTIONS {50};
|
||||
constexpr int MAX_TOPBAR_ZONES {7}; // 4 for portrait LCD, 6 for standard LCD, 7 for wide screen LCD
|
||||
constexpr int MAX_TOPBAR_OPTIONS {1};
|
||||
constexpr int LAYOUT_ID_LEN {255}; // TODO: use std::string instead of fixed length char array
|
||||
|
||||
// Common 'ZoneOptionValue's among all layouts
|
||||
enum {
|
||||
@@ -58,11 +55,12 @@ struct ZoneOptionValue // union in radio/src/datastructs.h
|
||||
unsigned int unsignedValue;
|
||||
int signedValue;
|
||||
unsigned int boolValue;
|
||||
char stringValue[LEN_ZONE_OPTION_STRING + 1];
|
||||
std::string stringValue;
|
||||
RawSource sourceValue;
|
||||
unsigned int colorValue;
|
||||
|
||||
ZoneOptionValue();
|
||||
bool isEmpty() const;
|
||||
};
|
||||
|
||||
enum ZoneOptionValueEnum {
|
||||
@@ -119,14 +117,14 @@ struct ZoneOptionValueTyped
|
||||
struct WidgetPersistentData {
|
||||
ZoneOptionValueTyped options[MAX_WIDGET_OPTIONS];
|
||||
|
||||
WidgetPersistentData();
|
||||
WidgetPersistentData() {}
|
||||
};
|
||||
|
||||
struct ZonePersistentData {
|
||||
char widgetName[WIDGET_NAME_LEN + 1];
|
||||
std::string widgetName;
|
||||
WidgetPersistentData widgetData;
|
||||
|
||||
ZonePersistentData();
|
||||
ZonePersistentData() {}
|
||||
bool isEmpty() const;
|
||||
};
|
||||
|
||||
@@ -135,9 +133,7 @@ struct WidgetsContainerPersistentData {
|
||||
ZonePersistentData zones[N];
|
||||
ZoneOptionValueTyped options[O];
|
||||
|
||||
WidgetsContainerPersistentData() {
|
||||
memset((void*)this, 0, sizeof(WidgetsContainerPersistentData));
|
||||
}
|
||||
WidgetsContainerPersistentData() {}
|
||||
};
|
||||
|
||||
typedef WidgetsContainerPersistentData<MAX_LAYOUT_ZONES, MAX_LAYOUT_OPTIONS>
|
||||
@@ -152,10 +148,10 @@ class RadioLayout
|
||||
|
||||
public:
|
||||
struct CustomScreenData {
|
||||
char layoutId[LAYOUT_ID_LEN + 1];
|
||||
std::string layoutId;
|
||||
LayoutPersistentData layoutPersistentData;
|
||||
|
||||
CustomScreenData();
|
||||
CustomScreenData() {}
|
||||
bool isEmpty() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ struct convert<WidgetsContainerPersistentData<N,O> > {
|
||||
{
|
||||
Node node;
|
||||
for (int i=0; i<N; i++) {
|
||||
if (strlen(rhs.zones[i].widgetName) > 0) {
|
||||
if (!rhs.zones[i].widgetName.empty()) {
|
||||
node["zones"][std::to_string(i)] = rhs.zones[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ UserInterfacePanel::UserInterfacePanel(QWidget * parent, ModelData & model, Gene
|
||||
|
||||
for (int i = 0; i < firmware->getCapability(TopBarZones); i++) {
|
||||
ZonePersistentData & zpd = model.topBarData.zones[i];
|
||||
QPushButton * btn = new QPushButton(zpd.widgetName, this);
|
||||
QPushButton * btn = new QPushButton(zpd.widgetName.c_str(), this);
|
||||
btn->setProperty("index", i);
|
||||
btn->setFixedSize(QSize(180, 50));
|
||||
widgetbtns.append(btn);
|
||||
@@ -165,7 +165,7 @@ UserInterfacePanel::UserInterfacePanel(QWidget * parent, ModelData & model, Gene
|
||||
optswidgets.append(wgt);
|
||||
|
||||
QGridLayout * layout = new QGridLayout(wgt); // must be owned by QWidget so visibility can be set
|
||||
layout->addLayout(addOptionsLayout<WidgetPersistentData>(zpd.widgetData, MAX_WIDGET_OPTIONS, zpd.widgetName), 0, 0);
|
||||
layout->addLayout(addOptionsLayout<WidgetPersistentData>(zpd.widgetData, MAX_WIDGET_OPTIONS, zpd.widgetName.c_str()), 0, 0);
|
||||
optsgrids.append(layout);
|
||||
|
||||
connect(btn, &QPushButton::clicked, this, [&]() {
|
||||
@@ -239,7 +239,7 @@ CustomScreenPanel::CustomScreenPanel(QWidget * parent, ModelData & model, int in
|
||||
addGridLabel(grid, tr("Layout:"), row, col++);
|
||||
|
||||
// currently no point continuing if no layout but will change if editing becomes possible
|
||||
if (model.customScreens.customScreenData[index].layoutId[0] == '\0') {
|
||||
if (model.customScreens.customScreenData[index].layoutId.empty()) {
|
||||
addGridLabel(grid, tr("None"), row, col);
|
||||
addHSpring(grid, grid->columnCount(), 0);
|
||||
addVSpring(grid, 0, grid->rowCount());
|
||||
@@ -248,7 +248,7 @@ CustomScreenPanel::CustomScreenPanel(QWidget * parent, ModelData & model, int in
|
||||
|
||||
QLabel * img = new QLabel(this);
|
||||
|
||||
QString path(QString(":/layouts/mask_%1.png").arg(QString(scrns.customScreenData[index].layoutId).toLower()));
|
||||
QString path(QString(":/layouts/mask_%1.png").arg(QString(scrns.customScreenData[index].layoutId.c_str()).toLower()));
|
||||
QFile f(path);
|
||||
|
||||
if (f.exists()) {
|
||||
@@ -278,7 +278,7 @@ CustomScreenPanel::CustomScreenPanel(QWidget * parent, ModelData & model, int in
|
||||
|
||||
for (int i = 0; i < MAX_LAYOUT_ZONES; i++) {
|
||||
ZonePersistentData & zpd = lpd.zones[i];
|
||||
QPushButton * btn = new QPushButton(zpd.widgetName, this);
|
||||
QPushButton * btn = new QPushButton(zpd.widgetName.c_str(), this);
|
||||
btn->setProperty("index", i);
|
||||
btn->setFixedSize(QSize(180, 50));
|
||||
widgetbtns.append(btn);
|
||||
@@ -294,7 +294,7 @@ CustomScreenPanel::CustomScreenPanel(QWidget * parent, ModelData & model, int in
|
||||
optswidgets.append(wgt);
|
||||
|
||||
QGridLayout * layout = new QGridLayout(wgt); // must be owned by QWidget so visibility can be set
|
||||
layout->addLayout(addOptionsLayout<WidgetPersistentData>(zpd.widgetData, MAX_WIDGET_OPTIONS, zpd.widgetName), 0, 0, Qt::AlignTop);
|
||||
layout->addLayout(addOptionsLayout<WidgetPersistentData>(zpd.widgetData, MAX_WIDGET_OPTIONS, zpd.widgetName.c_str()), 0, 0, Qt::AlignTop);
|
||||
optsgrids.append(layout);
|
||||
|
||||
connect(btn, &QPushButton::clicked, this, [&]() {
|
||||
@@ -369,7 +369,7 @@ CustomScreenPanel::CustomScreenPanel(QWidget * parent, ModelData & model, int in
|
||||
break;
|
||||
case ZOV_String:
|
||||
lbl = new QLabel(this);
|
||||
lbl->setText(lpd.options[i].value.stringValue);
|
||||
lbl->setText(lpd.options[i].value.stringValue.c_str());
|
||||
break;
|
||||
default:
|
||||
lbl = new QLabel(this);
|
||||
|
||||
Reference in New Issue
Block a user