aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--device.c113
-rw-r--r--device.h19
-rw-r--r--dive.h1
-rw-r--r--divelist.c2
-rw-r--r--helpers.h4
-rw-r--r--libdivecomputer.c19
-rw-r--r--parse-xml.c13
-rw-r--r--qt-gui.cpp67
-rw-r--r--qt-ui/divecomputermanagementdialog.cpp32
-rw-r--r--qt-ui/divecomputermanagementdialog.h5
-rw-r--r--qt-ui/divecomputermanagementdialog.ui47
-rw-r--r--qt-ui/mainwindow.cpp1
-rw-r--r--qt-ui/models.cpp65
-rw-r--r--qt-ui/models.h18
-rw-r--r--qt-ui/profilegraphics.cpp3
-rw-r--r--qthelper.cpp82
-rw-r--r--qthelper.h35
-rw-r--r--save-xml.c27
19 files changed, 302 insertions, 252 deletions
diff --git a/Makefile b/Makefile
index 870c832bb..f8770d344 100644
--- a/Makefile
+++ b/Makefile
@@ -69,6 +69,7 @@ SOURCES = \
time.c \
libdivecomputer.c \
qt-gui.cpp \
+ qthelper.cpp \
qt-ui/divelistview.cpp \
qt-ui/maintab.cpp \
qt-ui/mainwindow.cpp \
diff --git a/device.c b/device.c
index 2baa2e03a..6244e4117 100644
--- a/device.c
+++ b/device.c
@@ -2,119 +2,6 @@
#include "dive.h"
#include "device.h"
-static struct device_info *device_info_list;
-
-struct device_info *head_of_device_info_list(void)
-{
- return device_info_list;
-}
-
-void remove_dive_computer(const char *model, uint32_t deviceid)
-{
- free(remove_device_info(model, deviceid));
-}
-
-static int match_device_info(struct device_info *entry, const char *model, uint32_t deviceid)
-{
- return !strcmp(entry->model, model) && entry->deviceid == deviceid;
-}
-
-/* just find the entry for this divecomputer */
-struct device_info *get_device_info(const char *model, uint32_t deviceid)
-{
- struct device_info *known = device_info_list;
-
- /* a 0 deviceid doesn't get a nickname - those come from development
- * versions of Subsurface that didn't store the deviceid in the divecomputer entries */
- if (!deviceid || !model)
- return NULL;
- while (known) {
- if (match_device_info(known, model, deviceid))
- return known;
- known = known->next;
- }
- return NULL;
-}
-
-/*
- * Sort the device_info list, so that we write it out
- * in a stable order. Otherwise we'll end up having the
- * XML file have the devices listed in some arbitrary
- * order, which is annoying.
- */
-static void add_entry_sorted(struct device_info *entry)
-{
- struct device_info *p, **pp = &device_info_list;
-
- while ((p = *pp) != NULL) {
- int cmp = strcmp(p->model, entry->model);
- if (cmp > 0)
- break;
- if (!cmp && p->deviceid > entry->deviceid)
- break;
- pp = &p->next;
- }
-
- entry->next = p;
- *pp = entry;
-}
-
-/* Get an existing device info model or create a new one if valid */
-struct device_info *create_device_info(const char *model, uint32_t deviceid)
-{
- struct device_info *entry;
-
- if (!deviceid || !model || !*model)
- return NULL;
- entry = get_device_info(model, deviceid);
- if (entry)
- return entry;
- entry = calloc(1, sizeof(*entry));
- if (entry) {
- entry->model = strdup(model);
- entry->deviceid = deviceid;
- add_entry_sorted(entry);
- }
- return entry;
-}
-
-/* do we have a DIFFERENT divecomputer of the same model? */
-struct device_info *get_different_device_info(const char *model, uint32_t deviceid)
-{
- struct device_info *known = device_info_list;
-
- /* a 0 deviceid matches any DC of the same model - those come from development
- * versions of Subsurface that didn't store the deviceid in the divecomputer entries */
- if (!deviceid)
- return NULL;
- if (!model)
- model = "";
- while (known) {
- if (known->model && !strcmp(known->model, model) &&
- known->deviceid != deviceid)
- return known;
- known = known->next;
- }
- return NULL;
-}
-
-struct device_info *remove_device_info(const char *model, uint32_t deviceid)
-{
- struct device_info *entry, **p;
-
- if (!deviceid || !model || !*model)
- return NULL;
- p = &device_info_list;
- while ((entry = *p) != NULL) {
- if (match_device_info(entry, model, deviceid)) {
- *p = entry->next;
- break;
- }
- p = &entry->next;
- }
- return entry;
-}
-
struct divecomputer* fake_dc(struct divecomputer* dc)
{
static struct sample fake[4];
diff --git a/device.h b/device.h
index 59969473a..3067f009e 100644
--- a/device.h
+++ b/device.h
@@ -6,23 +6,10 @@
extern "C" {
#endif
-struct device_info {
- const char *model;
- uint32_t deviceid;
-
- const char *serial_nr;
- const char *firmware;
- const char *nickname;
- struct device_info *next;
-};
-
-extern struct device_info *get_device_info(const char *model, uint32_t deviceid);
-extern struct device_info *get_different_device_info(const char *model, uint32_t deviceid);
-extern struct device_info *create_device_info(const char *model, uint32_t deviceid);
-extern struct device_info *remove_device_info(const char *model, uint32_t deviceid);
-extern struct device_info *head_of_device_info_list(void);
extern struct divecomputer *fake_dc(struct divecomputer* dc);
-extern void remove_dive_computer(const char *model, uint32_t deviceid);
+extern void create_device_node(const char *model, uint32_t deviceid, const char *serial, const char *firmware, const char *nickname);
+extern void call_for_each_dc(FILE *f, void (*callback)(FILE *, const char *, uint32_t,
+ const char *, const char *, const char *));
#ifdef __cplusplus
}
diff --git a/dive.h b/dive.h
index 3a46eb2d4..39943d6c6 100644
--- a/dive.h
+++ b/dive.h
@@ -653,7 +653,6 @@ extern void dive_list_update_dives(void);
extern void flush_divelist(struct dive *dive);
extern void set_dc_nickname(struct dive *dive);
-extern const char *get_dc_nickname(const char *model, uint32_t deviceid);
extern void set_autogroup(gboolean value);
extern int total_weight(struct dive *);
diff --git a/divelist.c b/divelist.c
index 606c30e01..6e3fc598e 100644
--- a/divelist.c
+++ b/divelist.c
@@ -1059,7 +1059,7 @@ static void try_to_renumber(struct dive *last, int preexisting)
void process_dives(bool is_imported, bool prefer_imported)
{
- int i;
+ int i;
int preexisting = dive_table.preexisting;
struct dive *last;
diff --git a/helpers.h b/helpers.h
index 57b5aa6f7..81fddbd5e 100644
--- a/helpers.h
+++ b/helpers.h
@@ -9,6 +9,7 @@
#include <QString>
#include "dive.h"
+#include "qthelper.h"
QString get_depth_string(depth_t depth, bool showunit);
QString get_weight_string(weight_t weight, bool showunit);
@@ -18,5 +19,8 @@ QString get_pressure_string(pressure_t pressure, bool showunit);
void set_default_dive_computer(const char *vendor, const char *product);
void set_default_dive_computer_device(const char *name);
QString getSubsurfaceDataPath(QString folderToFind);
+extern const QString get_dc_nickname(const char *model, uint32_t deviceid);
+
+extern DiveComputerList dcList;
#endif /* HELPER_H */
diff --git a/libdivecomputer.c b/libdivecomputer.c
index 6397018a3..2638376b8 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -578,36 +578,29 @@ static unsigned int undo_libdivecomputer_suunto_nr_changes(unsigned int serial)
static unsigned int fixup_suunto_versions(device_data_t *devdata, const dc_event_devinfo_t *devinfo)
{
- struct device_info *info;
unsigned int serial = devinfo->serial;
+ char serial_nr[13] = "";
+ char firmware[13] = "";
first_temp_is_air = 1;
serial = undo_libdivecomputer_suunto_nr_changes(serial);
- info = create_device_info(devdata->model, devdata->deviceid);
- if (!info)
- return serial;
-
- if (!info->serial_nr && serial) {
- char serial_nr[13];
-
+ if (serial) {
snprintf(serial_nr, sizeof(serial_nr), "%02d%02d%02d%02d",
(devinfo->serial >> 24) & 0xff,
(devinfo->serial >> 16) & 0xff,
(devinfo->serial >> 8) & 0xff,
(devinfo->serial >> 0) & 0xff);
- info->serial_nr = strdup(serial_nr);
}
-
- if (!info->firmware && devinfo->firmware) {
- char firmware[13];
+ if (devinfo->firmware) {
snprintf(firmware, sizeof(firmware), "%d.%d.%d",
(devinfo->firmware >> 16) & 0xff,
(devinfo->firmware >> 8) & 0xff,
(devinfo->firmware >> 0) & 0xff);
- info->firmware = strdup(firmware);
}
+ create_device_node(devdata->model, devdata->deviceid, serial_nr, firmware, "");
+
return serial;
}
diff --git a/parse-xml.c b/parse-xml.c
index ba952957f..aa2f737ec 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -1222,17 +1222,8 @@ static void dc_settings_start(void)
static void dc_settings_end(void)
{
- struct device_info *info;
-
- info = create_device_info(cur_settings.dc.model, cur_settings.dc.deviceid);
- if (info) {
- if (!info->serial_nr && cur_settings.dc.serial_nr)
- info->serial_nr = strdup(cur_settings.dc.serial_nr);
- if (!info->firmware && cur_settings.dc.firmware)
- info->firmware = strdup(cur_settings.dc.firmware);
- if (!info->nickname && cur_settings.dc.nickname)
- info->nickname = strdup(cur_settings.dc.nickname);
- }
+ create_device_node(cur_settings.dc.model, cur_settings.dc.deviceid, cur_settings.dc.serial_nr,
+ cur_settings.dc.firmware, cur_settings.dc.nickname);
reset_dc_settings();
}
diff --git a/qt-gui.cpp b/qt-gui.cpp
index e15e4128e..10b7d8086 100644
--- a/qt-gui.cpp
+++ b/qt-gui.cpp
@@ -21,6 +21,7 @@
#include "libdivecomputer.h"
#include "qt-ui/mainwindow.h"
#include "helpers.h"
+#include "qthelper.h"
#include <QApplication>
#include <QFileDialog>
@@ -32,10 +33,13 @@
#include <QDesktopWidget>
#include <QStyle>
#include <QDebug>
+#include <QMap>
+#include <QMultiMap>
const char *default_dive_computer_vendor;
const char *default_dive_computer_product;
const char *default_dive_computer_device;
+DiveComputerList dcList;
class Translator: public QTranslator
{
@@ -142,30 +146,15 @@ void set_filename(const char *filename, gboolean force)
existing_filename = NULL;
}
-const char *get_dc_nickname(const char *model, uint32_t deviceid)
+const QString get_dc_nickname(const char *model, uint32_t deviceid)
{
- struct device_info *known = get_device_info(model, deviceid);
- if (known) {
- if (known->nickname && *known->nickname)
- return known->nickname;
- else
- return known->model;
- }
- return NULL;
-}
-
-void remember_dc(const char *model, uint32_t deviceid, const char *nickname)
-{
- struct device_info *nn_entry;
-
- nn_entry = create_device_info(model, deviceid);
- if (!nn_entry)
- return;
- if (!nickname || !*nickname) {
- nn_entry->nickname = NULL;
- return;
- }
- nn_entry->nickname = strdup(nickname);
+ const DiveComputerNode *existNode = dcList.getExact(model, deviceid);
+ if (!existNode)
+ return QString("");
+ if (existNode->nickName != "")
+ return existNode->nickName;
+ else
+ return model;
}
void set_dc_nickname(struct dive *dive)
@@ -176,16 +165,20 @@ void set_dc_nickname(struct dive *dive)
struct divecomputer *dc = &dive->dc;
while (dc) {
- if (get_dc_nickname(dc->model, dc->deviceid) == NULL) {
+ if (dc->model && *dc->model && dc->deviceid &&
+ !dcList.getExact(dc->model, dc->deviceid)) {
// we don't have this one, yet
- struct device_info *nn_entry = get_different_device_info(dc->model, dc->deviceid);
- if (nn_entry) {
+ const DiveComputerNode *existNode = dcList.get(dc->model);
+ if (existNode) {
// we already have this model but a different deviceid
QString simpleNick(dc->model);
- simpleNick.append(" (").append(QString::number(dc->deviceid, 16)).append(")");
- remember_dc(dc->model, dc->deviceid, simpleNick.toUtf8().data());
+ if (dc->deviceid == 0)
+ simpleNick.append(" (unknown deviceid)");
+ else
+ simpleNick.append(" (").append(QString::number(dc->deviceid, 16)).append(")");
+ dcList.addDC(dc->model, dc->deviceid, simpleNick);
} else {
- remember_dc(dc->model, dc->deviceid, NULL);
+ dcList.addDC(dc->model, dc->deviceid);
}
}
dc = dc->next;
@@ -330,4 +323,20 @@ QString getSubsurfaceDataPath(QString folderToFind)
return QString("");
}
+void create_device_node(const char *model, uint32_t deviceid, const char *serial, const char *firmware, const char *nickname)
+{
+ dcList.addDC(model, deviceid, nickname, serial, firmware);
+}
+
+void call_for_each_dc(FILE *f, void (*callback)(FILE *, const char *, uint32_t,
+ const char *, const char *, const char *))
+{
+ QList<DiveComputerNode> values = dcList.dcMap.values();
+ for (int i = 0; i < values.size(); i++) {
+ const DiveComputerNode *node = &values.at(i);
+ callback(f, node->model.toUtf8().data(), node->deviceId, node->nickName.toUtf8().data(),
+ node->serialNumber.toUtf8().data(), node->firmware.toUtf8().data());
+ }
+}
+
#include "qt-gui.moc"
diff --git a/qt-ui/divecomputermanagementdialog.cpp b/qt-ui/divecomputermanagementdialog.cpp
index 4d9770a4d..2a1bb8bff 100644
--- a/qt-ui/divecomputermanagementdialog.cpp
+++ b/qt-ui/divecomputermanagementdialog.cpp
@@ -3,16 +3,26 @@
#include "ui_divecomputermanagementdialog.h"
#include "mainwindow.h"
#include <QMessageBox>
+#include "../qthelper.h"
+#include "../helpers.h"
-DiveComputerManagementDialog::DiveComputerManagementDialog(QWidget* parent, Qt::WindowFlags f): QDialog(parent, f)
-, ui( new Ui::DiveComputerManagementDialog())
+DiveComputerManagementDialog::DiveComputerManagementDialog(QWidget* parent, Qt::WindowFlags f): QDialog(parent, f),
+ ui( new Ui::DiveComputerManagementDialog()),
+ model(0)
{
ui->setupUi(this);
- model = new DiveComputerModel();
- ui->tableView->setModel(model);
+ init();
connect(ui->tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(tryRemove(QModelIndex)));
}
+void DiveComputerManagementDialog::init()
+{
+ if (model)
+ delete model;
+ model = new DiveComputerModel(dcList.dcMap);
+ ui->tableView->setModel(model);
+}
+
DiveComputerManagementDialog* DiveComputerManagementDialog::instance()
{
static DiveComputerManagementDialog *self = new DiveComputerManagementDialog();
@@ -44,3 +54,17 @@ void DiveComputerManagementDialog::tryRemove(const QModelIndex& index)
model->remove(index);
}
}
+
+void DiveComputerManagementDialog::accept()
+{
+ model->keepWorkingList();
+ hide();
+ close();
+}
+
+void DiveComputerManagementDialog::reject()
+{
+ model->dropWorkingList();
+ hide();
+ close();
+}
diff --git a/qt-ui/divecomputermanagementdialog.h b/qt-ui/divecomputermanagementdialog.h
index e10a96db2..72d48cd2a 100644
--- a/qt-ui/divecomputermanagementdialog.h
+++ b/qt-ui/divecomputermanagementdialog.h
@@ -14,9 +14,12 @@ Q_OBJECT
public:
static DiveComputerManagementDialog *instance();
void update();
+ void init();
public slots:
void tryRemove(const QModelIndex& index);
+ void accept();
+ void reject();
private:
explicit DiveComputerManagementDialog(QWidget* parent = 0, Qt::WindowFlags f = 0);
@@ -24,4 +27,4 @@ private:
DiveComputerModel *model;
};
-#endif \ No newline at end of file
+#endif
diff --git a/qt-ui/divecomputermanagementdialog.ui b/qt-ui/divecomputermanagementdialog.ui
index ae011fc9c..8b916f925 100644
--- a/qt-ui/divecomputermanagementdialog.ui
+++ b/qt-ui/divecomputermanagementdialog.ui
@@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
- <string>Dialog</string>
+ <string>Edit Dive Computer Nicknames</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@@ -21,8 +21,51 @@
</attribute>
</widget>
</item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<resources/>
- <connections/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>DiveComputerManagementDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>DiveComputerManagementDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
</ui>
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index ca6fa4113..26f4d864d 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -207,6 +207,7 @@ void MainWindow::on_actionDownloadWeb_triggered()
void MainWindow::on_actionEditDeviceNames_triggered()
{
+ DiveComputerManagementDialog::instance()->init();
DiveComputerManagementDialog::instance()->update();
DiveComputerManagementDialog::instance()->show();
}
diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index 2de8ababa..485015379 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -8,8 +8,8 @@
#include "../helpers.h"
#include "../dive.h"
#include "../device.h"
-#include "../statistics.h"
-
+#include "../statistics.h"
+#include "../qthelper.h"
#include <QCoreApplication>
#include <QDebug>
@@ -1172,9 +1172,10 @@ void DiveTripModel::setLayout(DiveTripModel::Layout layout)
*####################################################################
*/
-DiveComputerModel::DiveComputerModel(QObject* parent): QAbstractTableModel(parent)
+DiveComputerModel::DiveComputerModel(QMultiMap<QString, DiveComputerNode> &dcMap, QObject* parent): QAbstractTableModel(parent)
{
-
+ dcWorkingMap = dcMap;
+ numRows = 0;
}
int DiveComputerModel::columnCount(const QModelIndex& parent) const
@@ -1198,17 +1199,15 @@ QVariant DiveComputerModel::headerData(int section, Qt::Orientation orientation,
QVariant DiveComputerModel::data(const QModelIndex& index, int role) const
{
- struct device_info *device = head_of_device_info_list();
- for(int i = 0; i < index.row(); i++){
- device = device->next;
- }
+ QList<DiveComputerNode> values = dcWorkingMap.values();
+ DiveComputerNode node = values.at(index.row());
QVariant ret;
if (role == Qt::DisplayRole || role == Qt::EditRole){
switch(index.column()){
- case ID: ret = QString("0x").append(QString::number(device->deviceid, 16)); break;
- case MODEL: ret = device->model; break;
- case NICKNAME: ret = device->nickname; break;
+ case ID: ret = QString("0x").append(QString::number(node.deviceId, 16)); break;
+ case MODEL: ret = node.model; break;
+ case NICKNAME: ret = node.nickName; break;
}
}
@@ -1225,12 +1224,8 @@ int DiveComputerModel::rowCount(const QModelIndex& parent) const
void DiveComputerModel::update()
{
- int count = 0;
- struct device_info *nnl = head_of_device_info_list();
- while (nnl) {
- nnl = nnl->next;
- count++;
- }
+ QList<DiveComputerNode> values = dcWorkingMap.values();
+ int count = values.count();
if(numRows){
beginRemoveRows(QModelIndex(), 0, numRows-1);
@@ -1255,25 +1250,19 @@ Qt::ItemFlags DiveComputerModel::flags(const QModelIndex& index) const
bool DiveComputerModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
- struct device_info *nnl = head_of_device_info_list();
-
- for(int i = 0; i < index.row(); i++){
- nnl = nnl->next;
- }
-
-
- QByteArray v = value.toByteArray();
- nnl->nickname = strdup(v.data()); // how should I free this before setting a new one?
- // set_dc_nickname(dive); -> should this be used instead?
-
+ QList<DiveComputerNode> values = dcWorkingMap.values();
+ DiveComputerNode node = values.at(index.row());
+ dcWorkingMap.remove(node.model, node);
+ node.nickName = value.toString();
+ dcWorkingMap.insert(node.model, node);
return true;
}
-void DiveComputerModel::remove(const QModelIndex& i)
+void DiveComputerModel::remove(const QModelIndex& index)
{
- QByteArray model = data(index(i.row(), (int)MODEL)).toByteArray();
- uint32_t deviceid = data(index(i.row(), (int) ID)).toUInt();
- remove_dive_computer(model.data(), deviceid);
+ QList<DiveComputerNode> values = dcWorkingMap.values();
+ DiveComputerNode node = values.at(index.row());
+ dcWorkingMap.remove(node.model, node);
update();
}
@@ -1396,3 +1385,15 @@ void YearlyStatisticsModel::update_yearly_stats()
rootItem->children.append(item);
}
}
+
+void DiveComputerModel::dropWorkingList()
+{
+ // how do I prevent the memory leak ?
+}
+
+void DiveComputerModel::keepWorkingList()
+{
+ if (dcList.dcMap != dcWorkingMap)
+ mark_divelist_changed(TRUE);
+ dcList.dcMap = dcWorkingMap;
+}
diff --git a/qt-ui/models.h b/qt-ui/models.h
index 30d4b3a17..35ed529e3 100644
--- a/qt-ui/models.h
+++ b/qt-ui/models.h
@@ -13,6 +13,7 @@
#include "../dive.h"
#include "../divelist.h"
+#include "../qthelper.h"
QFont defaultModelFont();
@@ -181,19 +182,22 @@ class DiveComputerModel : public QAbstractTableModel
Q_OBJECT
public:
enum {REMOVE, MODEL, ID, NICKNAME, COLUMNS};
- explicit DiveComputerModel(QObject* parent = 0);
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
- virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
- virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
- virtual Qt::ItemFlags flags(const QModelIndex& index) const;
- virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
+ DiveComputerModel(QMultiMap<QString, DiveComputerNode> &dcMap, QObject *parent = 0);
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ virtual Qt::ItemFlags flags(const QModelIndex& index) const;
+ virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
void update();
+ void keepWorkingList();
+ void dropWorkingList();
public slots:
void remove(const QModelIndex& index);
private:
int numRows;
+ QMultiMap<QString, DiveComputerNode> dcWorkingMap;
};
class YearlyStatisticsModel : public TreeModel {
diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp
index 126690750..e580a2b44 100644
--- a/qt-ui/profilegraphics.cpp
+++ b/qt-ui/profilegraphics.cpp
@@ -21,6 +21,7 @@
#include "../dive.h"
#include "../profile.h"
#include "../device.h"
+#include "../helpers.h"
#include <libdivecomputer/parser.h>
#include <libdivecomputer/version.h>
@@ -273,7 +274,7 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
dc = fake_dc(dc);
}
- QString nick(get_dc_nickname(dc->model, dc->deviceid));
+ QString nick = get_dc_nickname(dc->model, dc->deviceid);
if (nick.isEmpty())
nick = QString(dc->model);
diff --git a/qthelper.cpp b/qthelper.cpp
new file mode 100644
index 000000000..9c74a74cf
--- /dev/null
+++ b/qthelper.cpp
@@ -0,0 +1,82 @@
+#include "qthelper.h"
+
+DiveComputerList::DiveComputerList()
+{
+
+}
+
+DiveComputerList::~DiveComputerList()
+{
+ dcMap.~QMap();
+}
+
+bool DiveComputerNode::operator == (const DiveComputerNode &a) const {
+ return this->model == a.model &&
+ this->deviceId == a.deviceId &&
+ this->firmware == a.firmware &&
+ this->serialNumber == a.serialNumber &&
+ this->nickName == a.nickName;
+}
+
+bool DiveComputerNode::operator !=(const DiveComputerNode &a) const {
+ return !(*this == a);
+}
+
+bool DiveComputerNode::changesValues(const DiveComputerNode &b) const
+{
+ if (this->model != b.model || this->deviceId != b.deviceId) {
+ qDebug("DiveComputerNodes were not for the same DC");
+ return false;
+ }
+ return (b.firmware != "" && this->firmware != b.firmware) ||
+ (b.serialNumber != "" && this->serialNumber != b.serialNumber) ||
+ (b.nickName != "" && this->nickName != b.nickName);
+}
+
+const DiveComputerNode *DiveComputerList::getExact(QString m, uint32_t d)
+{
+ if (dcMap.contains(m)) {
+ QList<DiveComputerNode> values = dcMap.values(m);
+ for (int i = 0; i < values.size(); i++)
+ if (values.at(i).deviceId == d)
+ return &values.at(i);
+ }
+ return NULL;
+}
+
+const DiveComputerNode *DiveComputerList::get(QString m)
+{
+ if (dcMap.contains(m)) {
+ QList<DiveComputerNode> values = dcMap.values(m);
+ return &values.at(0);
+ }
+ return NULL;
+}
+
+void DiveComputerList::addDC(QString m, uint32_t d, QString n, QString s, QString f)
+{
+ if (m == "" || d == 0)
+ return;
+ const DiveComputerNode *existNode = this->getExact(m, d);
+ DiveComputerNode newNode(m, d, s, f, n);
+ if (existNode) {
+ if (newNode.changesValues(*existNode)) {
+ if (n != "" && existNode->nickName != n)
+ qDebug("new nickname %s for DC model %s deviceId 0x%x", n.toUtf8().data(), m.toUtf8().data(), d);
+ if (f != "" && existNode->firmware != f)
+ qDebug("new firmware version %s for DC model %s deviceId 0x%x", f.toUtf8().data(), m.toUtf8().data(), d);
+ if (s != "" && existNode->serialNumber != s)
+ qDebug("new serial number %s for DC model %s deviceId 0x%x", s.toUtf8().data(), m.toUtf8().data(), d);
+ } else {
+ return;
+ }
+ dcMap.remove(m, *existNode);
+ }
+ dcMap.insert(m, newNode);
+}
+
+void DiveComputerList::rmDC(QString m, uint32_t d)
+{
+ const DiveComputerNode *existNode = this->getExact(m, d);
+ dcMap.remove(m, *existNode);
+}
diff --git a/qthelper.h b/qthelper.h
new file mode 100644
index 000000000..fcbcbff9a
--- /dev/null
+++ b/qthelper.h
@@ -0,0 +1,35 @@
+#ifndef QTHELPER_H
+#define QTHELPER_H
+
+#include <QMultiMap>
+#include <QString>
+#include <stdint.h>
+
+class DiveComputerNode {
+public:
+ DiveComputerNode(QString m, uint32_t d, QString s, QString f, QString n) : model(m), deviceId(d), serialNumber(s), firmware(f), nickName(n) {};
+ bool operator ==(const DiveComputerNode &a) const;
+ bool operator !=(const DiveComputerNode &a) const;
+ bool changesValues(const DiveComputerNode &b) const;
+ QString model;
+ uint32_t deviceId;
+ QString serialNumber;
+ QString firmware;
+ QString nickName;
+};
+
+class DiveComputerList {
+public:
+ DiveComputerList();
+ ~DiveComputerList();
+ const DiveComputerNode *getExact(QString m, uint32_t d);
+ const DiveComputerNode *get(QString m);
+ void addDC(QString m, uint32_t d, QString n = "", QString s = "", QString f = "");
+ void rmDC(QString m, uint32_t d);
+ DiveComputerNode matchDC(QString m, uint32_t d);
+ DiveComputerNode matchModel(QString m);
+ QMultiMap<QString, struct DiveComputerNode> dcMap;
+ QMultiMap<QString, struct DiveComputerNode> dcWorkingMap;
+};
+
+#endif // QTHELPER_H
diff --git a/save-xml.c b/save-xml.c
index 0e770ec62..454da8484 100644
--- a/save-xml.c
+++ b/save-xml.c
@@ -512,24 +512,20 @@ static void save_trip(FILE *f, dive_trip_t *trip)
fprintf(f, "</trip>\n");
}
-static void save_one_device(FILE *f, struct device_info *info)
+static void save_one_device(FILE *f, const char * model, uint32_t deviceid,
+ const char *nickname, const char *serial_nr, const char *firmware)
{
- const char *nickname, *serial_nr, *firmware;
-
/* Nicknames that are empty or the same as the device model are not interesting */
- nickname = info->nickname;
if (nickname) {
- if (!*nickname || !strcmp(info->model, nickname))
+ if (!*nickname || !strcmp(model, nickname))
nickname = NULL;
}
/* Serial numbers that are empty are not interesting */
- serial_nr = info->serial_nr;
if (serial_nr && !*serial_nr)
serial_nr = NULL;
/* Firmware strings that are empty are not interesting */
- firmware = info->firmware;
if (firmware && !*firmware)
firmware = NULL;
@@ -538,25 +534,14 @@ static void save_one_device(FILE *f, struct device_info *info)
return;
fprintf(f, "<divecomputerid");
- show_utf8(f, info->model, " model='", "'", 1);
- fprintf(f, " deviceid='%08x'", info->deviceid);
+ show_utf8(f, model, " model='", "'", 1);
+ fprintf(f, " deviceid='%08x'", deviceid);
show_utf8(f, serial_nr, " serial='", "'", 1);
show_utf8(f, firmware, " firmware='", "'", 1);
show_utf8(f, nickname, " nickname='", "'", 1);
fprintf(f, "/>\n");
}
-static void save_device_info(FILE *f)
-{
- struct device_info *info;
-
- info = head_of_device_info_list();
- while (info) {
- save_one_device(f, info);
- info = info->next;
- }
-}
-
#define VERSION 2
void save_dives(const char *filename)
@@ -578,7 +563,7 @@ void save_dives_logic(const char *filename, const gboolean select_only)
fprintf(f, "<divelog program='subsurface' version='%d'>\n<settings>\n", VERSION);
/* save the dive computer nicknames, if any */
- save_device_info(f);
+ call_for_each_dc(f, save_one_device);
if (autogroup)
fprintf(f, "<autogroup state='1' />\n");
fprintf(f, "</settings>\n<dives>\n");