mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
crash fix: Don't cast to CylindersModel or CylindersModelFiltered
The tank-info-delegate cast its model to CylindersModelFiltered, since this is what the equipment-tab uses since implementing the filtering of unused cylinders. However, the planner users the same delegate and still uses the unfiltered CylindersModel. This means that the (dynamic) cast returns a null pointer and crashes. One possibility would be to derive CylindersModelFiltered and CylindersModel from the same class that defines virtual functions and cast to that class. This is a different attempt: don't cast (i.e. stay with a QAbstractItemModel and play it via Qt's model-view system. Firstly, replace the passInData function by a role to setData(). Secondly, read the working-pressure and size via new columns using data(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
9214bdb3c5
commit
cb80ff746b
3 changed files with 44 additions and 40 deletions
|
@ -238,7 +238,7 @@ static struct RevertCylinderData {
|
||||||
|
|
||||||
void TankInfoDelegate::setModelData(QWidget*, QAbstractItemModel*, const QModelIndex&) const
|
void TankInfoDelegate::setModelData(QWidget*, QAbstractItemModel*, const QModelIndex&) const
|
||||||
{
|
{
|
||||||
CylindersModelFiltered *mymodel = qobject_cast<CylindersModelFiltered *>(currCombo.model);
|
QAbstractItemModel *mymodel = currCombo.model;
|
||||||
TankInfoModel *tanks = TankInfoModel::instance();
|
TankInfoModel *tanks = TankInfoModel::instance();
|
||||||
QModelIndexList matches = tanks->match(tanks->index(0, 0), Qt::DisplayRole, currCombo.activeText);
|
QModelIndexList matches = tanks->match(tanks->index(0, 0), Qt::DisplayRole, currCombo.activeText);
|
||||||
int row;
|
int row;
|
||||||
|
@ -255,8 +255,8 @@ void TankInfoDelegate::setModelData(QWidget*, QAbstractItemModel*, const QModelI
|
||||||
int tankPressure = tanks->data(tanks->index(row, TankInfoModel::BAR)).toInt();
|
int tankPressure = tanks->data(tanks->index(row, TankInfoModel::BAR)).toInt();
|
||||||
|
|
||||||
mymodel->setData(IDX(CylindersModel::TYPE), cylinderName, Qt::EditRole);
|
mymodel->setData(IDX(CylindersModel::TYPE), cylinderName, Qt::EditRole);
|
||||||
mymodel->passInData(IDX(CylindersModel::WORKINGPRESS), tankPressure);
|
mymodel->setData(IDX(CylindersModel::WORKINGPRESS), tankPressure, CylindersModel::PASS_IN_ROLE);
|
||||||
mymodel->passInData(IDX(CylindersModel::SIZE), tankSize);
|
mymodel->setData(IDX(CylindersModel::SIZE), tankSize, CylindersModel::PASS_IN_ROLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
TankInfoDelegate::TankInfoDelegate(QObject *parent) : ComboBoxDelegate(TankInfoModel::instance(), parent, true)
|
TankInfoDelegate::TankInfoDelegate(QObject *parent) : ComboBoxDelegate(TankInfoModel::instance(), parent, true)
|
||||||
|
@ -277,10 +277,10 @@ void TankInfoDelegate::editorClosed(QWidget*, QAbstractItemDelegate::EndEditHint
|
||||||
{
|
{
|
||||||
if (hint == QAbstractItemDelegate::NoHint ||
|
if (hint == QAbstractItemDelegate::NoHint ||
|
||||||
hint == QAbstractItemDelegate::RevertModelCache) {
|
hint == QAbstractItemDelegate::RevertModelCache) {
|
||||||
CylindersModelFiltered *mymodel = qobject_cast<CylindersModelFiltered *>(currCombo.model);
|
QAbstractItemModel *mymodel = currCombo.model;
|
||||||
mymodel->setData(IDX(CylindersModel::TYPE), currCylinderData.type, Qt::EditRole);
|
mymodel->setData(IDX(CylindersModel::TYPE), currCylinderData.type, Qt::EditRole);
|
||||||
mymodel->passInData(IDX(CylindersModel::WORKINGPRESS), currCylinderData.pressure);
|
mymodel->setData(IDX(CylindersModel::WORKINGPRESS), currCylinderData.pressure, CylindersModel::PASS_IN_ROLE);
|
||||||
mymodel->passInData(IDX(CylindersModel::SIZE), currCylinderData.size);
|
mymodel->setData(IDX(CylindersModel::SIZE), currCylinderData.size, CylindersModel::PASS_IN_ROLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,11 +289,11 @@ QWidget *TankInfoDelegate::createEditor(QWidget *parent, const QStyleOptionViewI
|
||||||
// ncreate editor needs to be called before because it will populate a few
|
// ncreate editor needs to be called before because it will populate a few
|
||||||
// things in the currCombo global var.
|
// things in the currCombo global var.
|
||||||
QWidget *delegate = ComboBoxDelegate::createEditor(parent, option, index);
|
QWidget *delegate = ComboBoxDelegate::createEditor(parent, option, index);
|
||||||
CylindersModelFiltered *mymodel = qobject_cast<CylindersModelFiltered *>(currCombo.model);
|
QAbstractItemModel *model = currCombo.model;
|
||||||
cylinder_t *cyl = mymodel->cylinderAt(index);
|
int row = index.row();
|
||||||
currCylinderData.type = cyl->type.description;
|
currCylinderData.type = model->data(model->index(row, CylindersModel::TYPE)).value<QString>();
|
||||||
currCylinderData.pressure = cyl->type.workingpressure.mbar;
|
currCylinderData.pressure = model->data(model->index(row, CylindersModel::WORKINGPRESS_INT)).value<int>();
|
||||||
currCylinderData.size = cyl->type.size.mliter;
|
currCylinderData.size = model->data(model->index(row, CylindersModel::SIZE_INT)).value<int>();
|
||||||
MainWindow::instance()->graphics->setReplot(false);
|
MainWindow::instance()->graphics->setReplot(false);
|
||||||
return delegate;
|
return delegate;
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,10 @@ QVariant CylindersModel::data(const QModelIndex &index, int role) const
|
||||||
break;
|
break;
|
||||||
case USE:
|
case USE:
|
||||||
return gettextFromC::tr(cylinderuse_text[cyl->cylinder_use]);
|
return gettextFromC::tr(cylinderuse_text[cyl->cylinder_use]);
|
||||||
|
case WORKINGPRESS_INT:
|
||||||
|
return static_cast<int>(cyl->type.workingpressure.mbar);
|
||||||
|
case SIZE_INT:
|
||||||
|
return static_cast<int>(cyl->type.size.mliter);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::DecorationRole:
|
case Qt::DecorationRole:
|
||||||
|
@ -283,33 +287,35 @@ cylinder_t *CylindersModel::cylinderAt(const QModelIndex &index)
|
||||||
return get_cylinder(&displayed_dive, index.row());
|
return get_cylinder(&displayed_dive, index.row());
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is our magic 'pass data in' function that allows the delegate to get
|
|
||||||
// the data here without silly unit conversions;
|
|
||||||
// so we only implement the two columns we care about
|
|
||||||
void CylindersModel::passInData(const QModelIndex &index, const QVariant &value)
|
|
||||||
{
|
|
||||||
cylinder_t *cyl = cylinderAt(index);
|
|
||||||
switch (index.column()) {
|
|
||||||
case SIZE:
|
|
||||||
if (cyl->type.size.mliter != value.toInt()) {
|
|
||||||
cyl->type.size.mliter = value.toInt();
|
|
||||||
dataChanged(index, index);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WORKINGPRESS:
|
|
||||||
if (cyl->type.workingpressure.mbar != value.toInt()) {
|
|
||||||
cyl->type.workingpressure.mbar = value.toInt();
|
|
||||||
dataChanged(index, index);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CylindersModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
bool CylindersModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
{
|
{
|
||||||
QString vString;
|
QString vString;
|
||||||
|
|
||||||
cylinder_t *cyl = cylinderAt(index);
|
cylinder_t *cyl = cylinderAt(index);
|
||||||
|
if (!cyl)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (role == PASS_IN_ROLE) {
|
||||||
|
// this is our magic 'pass data in' function that allows the delegate to get
|
||||||
|
// the data here without silly unit conversions;
|
||||||
|
// so we only implement the two columns we care about
|
||||||
|
switch (index.column()) {
|
||||||
|
case SIZE:
|
||||||
|
if (cyl->type.size.mliter != value.toInt()) {
|
||||||
|
cyl->type.size.mliter = value.toInt();
|
||||||
|
dataChanged(index, index);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case WORKINGPRESS:
|
||||||
|
if (cyl->type.workingpressure.mbar != value.toInt()) {
|
||||||
|
cyl->type.workingpressure.mbar = value.toInt();
|
||||||
|
dataChanged(index, index);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case TYPE:
|
case TYPE:
|
||||||
if (!value.isNull()) {
|
if (!value.isNull()) {
|
||||||
|
@ -641,11 +647,6 @@ void CylindersModelFiltered::remove(QModelIndex index)
|
||||||
source.remove(mapToSource(index));
|
source.remove(mapToSource(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CylindersModelFiltered::passInData(const QModelIndex &index, const QVariant &value)
|
|
||||||
{
|
|
||||||
source.passInData(mapToSource(index), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
cylinder_t *CylindersModelFiltered::cylinderAt(const QModelIndex &index)
|
cylinder_t *CylindersModelFiltered::cylinderAt(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
return source.cylinderAt(mapToSource(index));
|
return source.cylinderAt(mapToSource(index));
|
||||||
|
|
|
@ -25,16 +25,20 @@ public:
|
||||||
MOD,
|
MOD,
|
||||||
MND,
|
MND,
|
||||||
USE,
|
USE,
|
||||||
|
WORKINGPRESS_INT,
|
||||||
|
SIZE_INT,
|
||||||
COLUMNS
|
COLUMNS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Roles {
|
||||||
|
PASS_IN_ROLE = Qt::UserRole + 1 // For setting data: don't do any conversions
|
||||||
|
};
|
||||||
explicit CylindersModel(QObject *parent = 0);
|
explicit CylindersModel(QObject *parent = 0);
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||||
|
|
||||||
void passInData(const QModelIndex &index, const QVariant &value);
|
|
||||||
void add();
|
void add();
|
||||||
void clear();
|
void clear();
|
||||||
void updateDive();
|
void updateDive();
|
||||||
|
@ -67,7 +71,6 @@ public:
|
||||||
void add();
|
void add();
|
||||||
void updateDive();
|
void updateDive();
|
||||||
cylinder_t *cylinderAt(const QModelIndex &index);
|
cylinder_t *cylinderAt(const QModelIndex &index);
|
||||||
void passInData(const QModelIndex &index, const QVariant &value);
|
|
||||||
public
|
public
|
||||||
slots:
|
slots:
|
||||||
void remove(QModelIndex index);
|
void remove(QModelIndex index);
|
||||||
|
|
Loading…
Add table
Reference in a new issue