Dive site: pass pointer-to-dive_site via QVariant

There was this ugly pattern of passing pointers-to-dive_site via
a QVariant of void * type. This is of course inherently unsafe.

Pass these pointers using their proper types instead. This makes
it necessary to register them in Qt's meta-type system. Doing so,
fixes a bug: QML couldn't call into updateDiveSiteCoordinates()
because it didn't know the type and thus the coordinates of
the moved flag were not reflected in the divesite-dialog.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2018-10-28 21:16:42 +01:00 committed by Dirk Hohndel
parent e8b3fdb4a6
commit 920eb7576f
5 changed files with 11 additions and 8 deletions

View file

@ -78,6 +78,9 @@ void merge_dive_sites(struct dive_site *ref, struct dive_site *dive_sites[], int
} }
QString constructLocationTags(struct taxonomy_data *taxonomy, bool for_maintab); QString constructLocationTags(struct taxonomy_data *taxonomy, bool for_maintab);
/* Make pointer-to-dive_site a "Qt metatype" so that we can pass it through QVariants */
Q_DECLARE_METATYPE(dive_site *);
#endif #endif
#endif // DIVESITE_H #endif // DIVESITE_H

View file

@ -82,7 +82,7 @@ void LocationInformationWidget::mergeSelectedDiveSites()
std::vector<struct dive_site *> selected_dive_sites; std::vector<struct dive_site *> selected_dive_sites;
selected_dive_sites.reserve(selection.count()); selected_dive_sites.reserve(selection.count());
Q_FOREACH (const QModelIndex &idx, selection) { Q_FOREACH (const QModelIndex &idx, selection) {
struct dive_site *ds = (struct dive_site *)idx.data(LocationInformationModel::DIVESITE_ROLE).value<void *>(); dive_site *ds = idx.data(LocationInformationModel::DIVESITE_ROLE).value<dive_site *>();
if (ds) if (ds)
selected_dive_sites.push_back(ds); selected_dive_sites.push_back(ds);
} }
@ -507,7 +507,7 @@ void DiveLocationLineEdit::itemActivated(const QModelIndex &index)
if (index.column() == LocationInformationModel::DIVESITE) if (index.column() == LocationInformationModel::DIVESITE)
idx = index.model()->index(index.row(), LocationInformationModel::NAME); idx = index.model()->index(index.row(), LocationInformationModel::NAME);
dive_site *ds = (dive_site *)index.model()->index(index.row(), LocationInformationModel::DIVESITE).data().value<void *>(); dive_site *ds = index.model()->index(index.row(), LocationInformationModel::DIVESITE).data().value<dive_site *>();
currType = ds == RECENTLY_ADDED_DIVESITE ? NEW_DIVE_SITE : EXISTING_DIVE_SITE; currType = ds == RECENTLY_ADDED_DIVESITE ? NEW_DIVE_SITE : EXISTING_DIVE_SITE;
currDs = ds; currDs = ds;
setText(idx.data().toString()); setText(idx.data().toString());

View file

@ -67,7 +67,7 @@ void MapWidget::centerOnDiveSite(struct dive_site *ds)
void MapWidget::centerOnIndex(const QModelIndex& idx) void MapWidget::centerOnIndex(const QModelIndex& idx)
{ {
CHECK_IS_READY_RETURN_VOID(); CHECK_IS_READY_RETURN_VOID();
struct dive_site *ds = (struct dive_site *)idx.model()->index(idx.row(), LocationInformationModel::DIVESITE).data().value<void *>(); dive_site *ds = idx.model()->index(idx.row(), LocationInformationModel::DIVESITE).data().value<dive_site *>();
if (!ds || ds == RECENTLY_ADDED_DIVESITE || !dive_site_has_gps_location(ds)) if (!ds || ds == RECENTLY_ADDED_DIVESITE || !dive_site_has_gps_location(ds))
centerOnSelectedDiveSite(); centerOnSelectedDiveSite();
else else

View file

@ -453,8 +453,8 @@ void LocationFilterDelegate::paint(QPainter *painter, const QStyleOptionViewItem
QString diveSiteName = index.data().toString(); QString diveSiteName = index.data().toString();
QString bottomText; QString bottomText;
QIcon icon = index.data(Qt::DecorationRole).value<QIcon>(); QIcon icon = index.data(Qt::DecorationRole).value<QIcon>();
struct dive_site *ds = (struct dive_site *) struct dive_site *ds =
index.model()->data(index.model()->index(index.row(), LocationInformationModel::DIVESITE)).value<void *>(); index.model()->data(index.model()->index(index.row(), LocationInformationModel::DIVESITE)).value<dive_site *>();
struct dive_site *currentDiveSite = current_dive ? get_dive_site_for_dive(current_dive) : nullptr; struct dive_site *currentDiveSite = current_dive ? get_dive_site_for_dive(current_dive) : nullptr;
bool currentDiveSiteHasGPS = currentDiveSite && dive_site_has_gps_location(currentDiveSite); bool currentDiveSiteHasGPS = currentDiveSite && dive_site_has_gps_location(currentDiveSite);
//Special case: do not show name, but instead, show //Special case: do not show name, but instead, show

View file

@ -41,7 +41,7 @@ QVariant LocationInformationModel::getDiveSiteData(const struct dive_site *ds, i
case Qt::EditRole: case Qt::EditRole:
case Qt::DisplayRole : case Qt::DisplayRole :
switch(column) { switch(column) {
case DIVESITE: return QVariant::fromValue<void*>((void *)ds); // Not nice: casting away const case DIVESITE: return QVariant::fromValue<dive_site *>((dive_site *)ds); // Not nice: casting away const
case NAME: return ds->name; case NAME: return ds->name;
case LATITUDE: return ds->location.lat.udeg; case LATITUDE: return ds->location.lat.udeg;
case LONGITUDE: return ds->location.lon.udeg; case LONGITUDE: return ds->location.lon.udeg;
@ -60,7 +60,7 @@ QVariant LocationInformationModel::getDiveSiteData(const struct dive_site *ds, i
return QVariant(); return QVariant();
} }
case DIVESITE_ROLE: case DIVESITE_ROLE:
return QVariant::fromValue<void *>((void *)ds); // Not nice: casting away const return QVariant::fromValue<dive_site *>((dive_site *)ds); // Not nice: casting away const
} }
return QVariant(); return QVariant();
} }
@ -119,7 +119,7 @@ GeoReferencingOptionsModel::GeoReferencingOptionsModel(QObject *parent) : QStrin
bool GPSLocationInformationModel::filterAcceptsRow(int sourceRow, const QModelIndex &parent) const bool GPSLocationInformationModel::filterAcceptsRow(int sourceRow, const QModelIndex &parent) const
{ {
struct dive_site *ds = (struct dive_site *)sourceModel()->index(sourceRow, LocationInformationModel::DIVESITE, parent).data().value<void *>(); struct dive_site *ds = sourceModel()->index(sourceRow, LocationInformationModel::DIVESITE, parent).data().value<dive_site *>();
if (ds == ignoreDs || ds == RECENTLY_ADDED_DIVESITE) if (ds == ignoreDs || ds == RECENTLY_ADDED_DIVESITE)
return false; return false;