subsurface/desktop-widgets/locationinformation.h
Berthold Stoeger e3cd0891d3 Dive site: close dive site edit widget when dive site is deleted
The application could be crashed by
1) Create dive site
2) Edit dive site
3) Undo until dive site is removed
4) Continue editing now non-existing dive site

Therefore, hook into the dive-site-deleted signal and if the
currently edited dive site is deleted, close the widget.

When closing the widget, make sure that the potentially
dangling pointer is reset to zero so that there is no
other potential use-after-free bug.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-07 08:28:29 -07:00

116 lines
3.4 KiB
C++

// SPDX-License-Identifier: GPL-2.0
#ifndef LOCATIONINFORMATION_H
#define LOCATIONINFORMATION_H
#include "core/units.h"
#include "core/divesite.h"
#include "ui_locationinformation.h"
#include "modeldelegates.h"
#include "qt-models/divelocationmodel.h"
#include <stdint.h>
#include <QAbstractListModel>
#include <QSortFilterProxyModel>
class LocationInformationWidget : public QGroupBox {
Q_OBJECT
public:
LocationInformationWidget(QWidget *parent = 0);
bool eventFilter(QObject*, QEvent*) override;
void initFields(dive_site *ds);
protected:
void enableLocationButtons(bool enable);
public slots:
void acceptChanges();
void on_diveSiteCountry_editingFinished();
void on_diveSiteCoordinates_editingFinished();
void on_diveSiteDescription_editingFinished();
void on_diveSiteName_editingFinished();
void on_diveSiteNotes_editingFinished();
void on_diveSiteDistance_textChanged(const QString &s);
void reverseGeocode();
void mergeSelectedDiveSites();
private slots:
void updateLabels();
void diveSiteChanged(struct dive_site *ds, int field);
void diveSiteDeleted(struct dive_site *ds, int);
void unitsChanged();
private:
void keyPressEvent(QKeyEvent *e) override;
void clearLabels();
Ui::LocationInformation ui;
GPSLocationInformationModel filter_model;
dive_site *diveSite;
int64_t closeDistance; // Distance of "close" dive sites in mm
};
class DiveLocationFilterProxyModel : public QSortFilterProxyModel {
Q_OBJECT
QString filter;
public:
DiveLocationFilterProxyModel(QObject *parent = 0);
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const override;
void setFilter(const QString &filter);
void setCurrentLocation(location_t loc);
private:
location_t currentLocation; // Sort by distance to that location
};
class DiveLocationModel : public QAbstractTableModel {
Q_OBJECT
public:
DiveLocationModel(QObject *o = 0);
void resetModel();
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
int rowCount(const QModelIndex& parent = QModelIndex()) const;
int columnCount(const QModelIndex& parent = QModelIndex()) const;
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
private:
QString new_ds_value[2];
};
class DiveLocationListView : public QListView {
Q_OBJECT
public:
DiveLocationListView(QWidget *parent = 0);
protected:
void currentChanged(const QModelIndex& current, const QModelIndex& previous) override;
signals:
void currentIndexChanged(const QModelIndex& current);
};
class DiveLocationLineEdit : public QLineEdit {
Q_OBJECT
public:
DiveLocationLineEdit(QWidget *parent =0 );
void refreshDiveSiteCache();
void setTemporaryDiveSiteName(const QString& s);
bool eventFilter(QObject*, QEvent*);
void itemActivated(const QModelIndex& index);
struct dive_site *currDiveSite() const;
void fixPopupPosition();
void setCurrentDiveSite(struct dive *d);
void showAllSites();
signals:
void diveSiteSelected();
void entered(const QModelIndex& index);
void currentChanged(const QModelIndex& index);
protected:
void keyPressEvent(QKeyEvent *ev);
void focusOutEvent(QFocusEvent *ev);
void showPopup();
private:
using QLineEdit::setText;
DiveLocationFilterProxyModel *proxy;
DiveLocationModel *model;
DiveLocationListView *view;
LocationFilterDelegate delegate;
struct dive_site *currDs;
};
#endif