summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2014-01-07 11:57:20 +0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2014-01-07 12:10:19 +0800
commitc3fe1a9e9f79c77c533642df4f986238ef08452b (patch)
tree38236bef570eb5e955a6b8470e62a2917b706b34
parent9c617534a050ec0a0afd84ef578d7c6d0e800a59 (diff)
downloadsubsurface-c3fe1a9e9f79c77c533642df4f986238ef08452b.tar.gz
Get rid of pointers to dive structures in the UI
The assumption that the pointer will keep pointing to a valid structure is fundamentally flawed. And even if that is true today, it might change in the future - just don't do it. Use the diveId instead. The exception is when you own the structure and use it within one UI interaction during which any way to change the dive_table is disabled (e.g., while adding / editing a dive). Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--qt-ui/models.cpp61
-rw-r--r--qt-ui/models.h8
-rw-r--r--qt-ui/printlayout.cpp2
-rw-r--r--qt-ui/profilegraphics.cpp25
-rw-r--r--qt-ui/profilegraphics.h2
5 files changed, 72 insertions, 26 deletions
diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index aa9db450b..b39ad89e2 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -62,7 +62,7 @@ void CleanerTableModel::setHeaderDataStrings(const QStringList& newHeaders)
headers = newHeaders;
}
-CylindersModel::CylindersModel(QObject* parent): current(0), rows(0)
+CylindersModel::CylindersModel(QObject* parent): currentId(0), rows(0)
{
// enum{REMOVE, TYPE, SIZE, WORKINGPRESS, START, END, O2, HE, DEPTH};
setHeaderDataStrings( QStringList() << "" << tr("Type") << tr("Size") << tr("WorkPress") << tr("StartPress") << tr("EndPress") << trUtf8("O" UTF8_SUBSCRIPT_2 "%") << tr("He%") << tr("Switch at"));
@@ -90,6 +90,8 @@ QVariant CylindersModel::data(const QModelIndex& index, int role) const
if (!index.isValid() || index.row() >= MAX_CYLINDERS)
return ret;
+ struct dive *current = getDiveById(currentId);
+ Q_ASSERT(current != NULL);
cylinder_t *cyl = &current->cylinder[index.row()];
switch (role) {
case Qt::FontRole: {
@@ -157,6 +159,8 @@ QVariant CylindersModel::data(const QModelIndex& index, int role) const
cylinder_t* CylindersModel::cylinderAt(const QModelIndex& index)
{
+ struct dive *current = getDiveById(currentId);
+ Q_ASSERT(current != NULL);
return &current->cylinder[index.row()];
}
@@ -314,6 +318,8 @@ void CylindersModel::add()
}
int row = rows;
+ struct dive *current = getDiveById(currentId);
+ Q_ASSERT(current != NULL);
fill_default_cylinder(&current->cylinder[row]);
beginInsertRows(QModelIndex(), row, row);
rows++;
@@ -323,6 +329,8 @@ void CylindersModel::add()
void CylindersModel::update()
{
+ struct dive *current = getDiveById(currentId);
+ Q_ASSERT(current != NULL);
setDive(current);
}
@@ -336,6 +344,7 @@ void CylindersModel::clear()
void CylindersModel::setDive(dive* d)
{
+ struct dive *current = getDiveById(currentId);
if (current)
clear();
if (!d)
@@ -346,7 +355,7 @@ void CylindersModel::setDive(dive* d)
rows = i+1;
}
}
- current = d;
+ currentId = d->id;
changed = false;
if (rows > 0) {
beginInsertRows(QModelIndex(), 0, rows-1);
@@ -366,6 +375,8 @@ void CylindersModel::remove(const QModelIndex& index)
if (index.column() != REMOVE) {
return;
}
+ struct dive *current = getDiveById(currentId);
+ Q_ASSERT(current != NULL);
cylinder_t *cyl = &current->cylinder[index.row()];
if (DivePlannerPointsModel::instance()->tankInUse(cyl->gasmix.o2.permille, cyl->gasmix.he.permille)) {
QMessageBox::warning(mainWindow(), TITLE_OR_TEXT(
@@ -381,7 +392,7 @@ void CylindersModel::remove(const QModelIndex& index)
endRemoveRows();
}
-WeightModel::WeightModel(QObject* parent): current(0), rows(0)
+WeightModel::WeightModel(QObject* parent): currentId(0), rows(0)
{
//enum Column {REMOVE, TYPE, WEIGHT};
setHeaderDataStrings(QStringList() << tr("") << tr("Type") << tr("Weight"));
@@ -389,6 +400,8 @@ WeightModel::WeightModel(QObject* parent): current(0), rows(0)
weightsystem_t* WeightModel::weightSystemAt(const QModelIndex& index)
{
+ struct dive *current = getDiveById(currentId);
+ Q_ASSERT(current != NULL);
return &current->weightsystem[index.row()];
}
@@ -397,6 +410,8 @@ void WeightModel::remove(const QModelIndex& index)
if (index.column() != REMOVE) {
return;
}
+ struct dive *current = getDiveById(currentId);
+ Q_ASSERT(current != NULL);
beginRemoveRows(QModelIndex(), index.row(), index.row()); // yah, know, ugly.
rows--;
remove_weightsystem(current, index.row());
@@ -418,6 +433,8 @@ QVariant WeightModel::data(const QModelIndex& index, int role) const
if (!index.isValid() || index.row() >= MAX_WEIGHTSYSTEMS)
return ret;
+ struct dive *current = getDiveById(currentId);
+ Q_ASSERT(current != NULL);
weightsystem_t *ws = &current->weightsystem[index.row()];
switch (role) {
@@ -455,6 +472,8 @@ QVariant WeightModel::data(const QModelIndex& index, int role) const
// so we only implement the two columns we care about
void WeightModel::passInData(const QModelIndex& index, const QVariant& value)
{
+ struct dive *current = getDiveById(currentId);
+ Q_ASSERT(current != NULL);
weightsystem_t *ws = &current->weightsystem[index.row()];
if (index.column() == WEIGHT) {
if (ws->weight.grams != value.toInt()) {
@@ -488,6 +507,8 @@ lbs:
bool WeightModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
QString vString = value.toString();
+ struct dive *current = getDiveById(currentId);
+ Q_ASSERT(current != NULL);
weightsystem_t *ws = &current->weightsystem[index.row()];
switch(index.column()) {
case TYPE:
@@ -549,11 +570,14 @@ void WeightModel::add()
void WeightModel::update()
{
+ struct dive *current = getDiveById(currentId);
+ Q_ASSERT(current != NULL);
setDive(current);
}
void WeightModel::setDive(dive* d)
{
+ struct dive *current = getDiveById(currentId);
if (current)
clear();
rows = 0;
@@ -562,7 +586,7 @@ void WeightModel::setDive(dive* d)
rows = i+1;
}
}
- current = d;
+ currentId = d->id;
changed = false;
if (rows > 0) {
beginInsertRows(QModelIndex(), 0, rows-1);
@@ -960,6 +984,8 @@ static int nitrox_sort_value(struct dive *dive)
QVariant DiveItem::data(int column, int role) const
{
QVariant retVal;
+ struct dive *dive = getDiveById(diveId);
+ Q_ASSERT(dive != NULL);
switch (role) {
case Qt::TextAlignmentRole:
@@ -1048,21 +1074,26 @@ bool DiveItem::setData(const QModelIndex& index, const QVariant& value, int role
if (d->number == v)
return false;
}
-
- dive->number = value.toInt();
+ d = getDiveById(diveId);
+ Q_ASSERT(d != NULL);
+ d->number = value.toInt();
mark_divelist_changed(TRUE);
return true;
}
QString DiveItem::displayDate() const
{
+ struct dive *dive = getDiveById(diveId);
+ Q_ASSERT(dive != NULL);
return get_dive_date_string(dive->when);
}
QString DiveItem::displayDepth() const
{
- const int scale = 1000;
QString fract, str;
+ const int scale = 1000;
+ struct dive *dive = getDiveById(diveId);
+ Q_ASSERT(dive != NULL);
if (get_units()->length == units::METERS) {
fract = QString::number((unsigned)(dive->maxdepth.mm % scale) / 100);
str = QString("%1.%2").arg((unsigned)(dive->maxdepth.mm / scale)).arg(fract, 1, QChar('0'));
@@ -1076,6 +1107,8 @@ QString DiveItem::displayDepth() const
QString DiveItem::displayDuration() const
{
int hrs, mins, secs;
+ struct dive *dive = getDiveById(diveId);
+ Q_ASSERT(dive != NULL);
secs = dive->duration.seconds % 60;
mins = dive->duration.seconds / 60;
hrs = mins / 60;
@@ -1093,6 +1126,8 @@ QString DiveItem::displayDuration() const
QString DiveItem::displayTemperature() const
{
QString str;
+ struct dive *dive = getDiveById(diveId);
+ Q_ASSERT(dive != NULL);
if (!dive->watertemp.mkelvin)
return str;
if (get_units()->temperature == units::CELSIUS)
@@ -1105,6 +1140,8 @@ QString DiveItem::displayTemperature() const
QString DiveItem::displaySac() const
{
QString str;
+ struct dive *dive = getDiveById(diveId);
+ Q_ASSERT(dive != NULL);
if (get_units()->volume == units::LITER)
str = QString::number(dive->sac / 1000.0, 'f', 1).append(tr(" l/min"));
else
@@ -1120,6 +1157,8 @@ QString DiveItem::displayWeight() const
int DiveItem::weight() const
{
+ struct dive *dive = getDiveById(diveId);
+ Q_ASSERT(dive != 0);
weight_t tw = { total_weight(dive) };
return tw.grams;
}
@@ -1187,7 +1226,7 @@ void DiveTripModel::setupModelData()
dive_trip_t* trip = dive->divetrip;
DiveItem* diveItem = new DiveItem();
- diveItem->dive = dive;
+ diveItem->diveId = dive->id;
if (!trip || currentLayout == LIST) {
diveItem->parent = rootItem;
@@ -1594,7 +1633,7 @@ ProfilePrintModel::ProfilePrintModel(QObject *parent)
void ProfilePrintModel::setDive(struct dive *divePtr)
{
- dive = divePtr;
+ diveId = divePtr->id;
// reset();
}
@@ -1615,8 +1654,10 @@ QVariant ProfilePrintModel::data(const QModelIndex &index, int role) const
switch (role) {
case Qt::DisplayRole: {
+ struct dive *dive = getDiveById(diveId);
+ Q_ASSERT(dive != NULL);
struct DiveItem di;
- di.dive = dive;
+ di.diveId = diveId;
const QString unknown = tr("unknown");
diff --git a/qt-ui/models.h b/qt-ui/models.h
index baa7b32c4..1f1641e16 100644
--- a/qt-ui/models.h
+++ b/qt-ui/models.h
@@ -101,7 +101,7 @@ public slots:
void remove(const QModelIndex& index);
private:
- struct dive *current;
+ int currentId;
int rows;
};
@@ -130,7 +130,7 @@ public slots:
void remove(const QModelIndex& index);
private:
- struct dive *current;
+ int currentId;
int rows;
};
@@ -157,7 +157,7 @@ struct DiveItem : public TreeItem {
SUIT, CYLINDER, NITROX, SAC, OTU, MAXCNS, LOCATION, COLUMNS };
virtual QVariant data(int column, int role) const;
- struct dive* dive;
+ int diveId;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex& index) const;
QString displayDate() const;
@@ -291,7 +291,7 @@ class ProfilePrintModel : public QAbstractTableModel
Q_OBJECT
private:
- struct dive *dive;
+ int diveId;
QString truncateString(char *str, const int maxlen) const;
public:
diff --git a/qt-ui/printlayout.cpp b/qt-ui/printlayout.cpp
index dad940fbb..e60a3189f 100644
--- a/qt-ui/printlayout.cpp
+++ b/qt-ui/printlayout.cpp
@@ -391,7 +391,7 @@ void PrintLayout::printTable()
void PrintLayout::addTablePrintDataRow(TablePrintModel *model, int row, struct dive *dive) const
{
struct DiveItem di;
- di.dive = dive;
+ di.diveId = dive->id;
model->insertRow();
model->setData(model->index(row, 0), QString::number(dive->number), Qt::DisplayRole);
model->setData(model->index(row, 1), di.displayDate(), Qt::DisplayRole);
diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp
index 76eb64b84..5bb55d11b 100644
--- a/qt-ui/profilegraphics.cpp
+++ b/qt-ui/profilegraphics.cpp
@@ -52,7 +52,7 @@ extern int evn_used;
QPoint(viewport()->geometry().width() - toolBarProxy->boundingRect().width(), \
viewport()->geometry().height() - toolBarProxy->boundingRect().height() )
-ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent), toolTip(0) , dive(0), diveDC(0), rulerItem(0), toolBarProxy(0)
+ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent), toolTip(0) , diveId(0), diveDC(0), rulerItem(0), toolBarProxy(0)
{
printMode = false;
isGrayscale = false;
@@ -313,8 +313,8 @@ void ProfileGraphicsView::showEvent(QShowEvent* event)
// but the dive was not ploted.
// force a replot by modifying the dive
// hold by the view, and issuing a plot.
- if (dive && !scene()->items().count()) {
- dive = 0;
+ if (diveId && !scene()->items().count()) {
+ diveId = 0;
plot(get_dive(selected_dive));
}
if (toolBarProxy)
@@ -369,14 +369,14 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
if (d)
dc = select_dc(&d->dc);
- if (!forceRedraw && dive == d && (d && dc == diveDC))
+ if (!forceRedraw && getDiveById(diveId) == d && (d && dc == diveDC))
return;
clear();
- dive = d;
+ diveId = d ? d->id : 0;
diveDC = d ? dc : NULL;
- if (!isVisible() || !dive || !mainWindow()) {
+ if (!isVisible() || !d || !mainWindow()) {
return;
}
setBackgroundBrush(getColor(BACKGROUND));
@@ -415,14 +415,14 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
* Set up limits that are independent of
* the dive computer
*/
- calculate_max_limits(dive, dc, &gc);
+ calculate_max_limits(d, dc, &gc);
QRectF profile_grid_area = scene()->sceneRect();
gc.maxx = (profile_grid_area.width() - 2 * profile_grid_area.x());
gc.maxy = (profile_grid_area.height() - 2 * profile_grid_area.y());
/* This is per-dive-computer */
- gc.pi = *create_plot_info(dive, dc, &gc, printMode);
+ gc.pi = *create_plot_info(d, dc, &gc, printMode);
/* Bounding box */
QPen pen = defaultPen;
@@ -483,7 +483,7 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
if(mode == PLAN){
timeEditor = new GraphicsTextEditor();
- timeEditor->setPlainText( dive->duration.seconds ? QString::number(dive->duration.seconds/60) : tr("Set Duration: 10 minutes"));
+ timeEditor->setPlainText(d->duration.seconds ? QString::number(d->duration.seconds/60) : tr("Set Duration: 10 minutes"));
timeEditor->setPos(profile_grid_area.width() - timeEditor->boundingRect().width(), timeMarkers->y());
timeEditor->document();
connect(timeEditor, SIGNAL(editingFinished(QString)), this, SLOT(edit_dive_time(QString)));
@@ -720,6 +720,8 @@ void ProfileGraphicsView::plot_cylinder_pressure_text()
int last_time[MAX_CYLINDERS] = { 0, };
struct plot_data *entry;
struct plot_info *pi = &gc.pi;
+ struct dive *dive = getDiveById(diveId);
+ Q_ASSERT(dive != NULL);
if (!get_cylinder_pressure_range(&gc))
return;
@@ -888,6 +890,8 @@ void ProfileGraphicsView::plot_cylinder_pressure()
if (!get_cylinder_pressure_range(&gc))
return;
+ struct dive *dive = getDiveById(diveId);
+ Q_ASSERT(dive != NULL);
QPointF from, to;
for (i = 0; i < gc.pi.nr; i++) {
int mbar;
@@ -1006,7 +1010,8 @@ void ProfileGraphicsView::plot_one_event(struct event *ev)
int x = SCALEXGC(ev->time.seconds);
int y = SCALEYGC(entry->depth);
-
+ struct dive *dive = getDiveById(diveId);
+ Q_ASSERT(dive != NULL);
EventItem *item = new EventItem(ev, 0, isGrayscale);
item->setPos(x, y);
scene()->addItem(item);
diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h
index 064b4478d..b8e939ff8 100644
--- a/qt-ui/profilegraphics.h
+++ b/qt-ui/profilegraphics.h
@@ -190,7 +190,7 @@ private:
QBrush defaultBrush;
ToolTipItem *toolTip;
graphics_context gc;
- struct dive *dive;
+ int diveId;
struct divecomputer *diveDC;
int zoomLevel;