diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | device.c | 113 | ||||
-rw-r--r-- | device.h | 19 | ||||
-rw-r--r-- | dive.h | 1 | ||||
-rw-r--r-- | divelist.c | 2 | ||||
-rw-r--r-- | helpers.h | 4 | ||||
-rw-r--r-- | libdivecomputer.c | 19 | ||||
-rw-r--r-- | parse-xml.c | 13 | ||||
-rw-r--r-- | qt-gui.cpp | 67 | ||||
-rw-r--r-- | qt-ui/divecomputermanagementdialog.cpp | 32 | ||||
-rw-r--r-- | qt-ui/divecomputermanagementdialog.h | 5 | ||||
-rw-r--r-- | qt-ui/divecomputermanagementdialog.ui | 47 | ||||
-rw-r--r-- | qt-ui/mainwindow.cpp | 1 | ||||
-rw-r--r-- | qt-ui/models.cpp | 65 | ||||
-rw-r--r-- | qt-ui/models.h | 18 | ||||
-rw-r--r-- | qt-ui/profilegraphics.cpp | 3 | ||||
-rw-r--r-- | qthelper.cpp | 82 | ||||
-rw-r--r-- | qthelper.h | 35 | ||||
-rw-r--r-- | save-xml.c | 27 |
19 files changed, 302 insertions, 252 deletions
@@ -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 \ @@ -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]; @@ -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 } @@ -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; @@ -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"); |