diff options
-rw-r--r-- | README | 15 | ||||
-rw-r--r-- | dive.h | 13 | ||||
-rw-r--r-- | equipment.c | 7 | ||||
-rw-r--r-- | qt-gui.cpp | 6 | ||||
-rw-r--r-- | qt-ui/maintab.cpp | 21 | ||||
-rw-r--r-- | qt-ui/maintab.h | 4 | ||||
-rw-r--r-- | qt-ui/maintab.ui | 4 | ||||
-rw-r--r-- | qt-ui/mainwindow.cpp | 23 | ||||
-rw-r--r-- | qt-ui/modeldelegates.cpp | 98 | ||||
-rw-r--r-- | qt-ui/modeldelegates.h | 11 | ||||
-rw-r--r-- | qt-ui/models.cpp | 237 | ||||
-rw-r--r-- | qt-ui/models.h | 33 | ||||
-rw-r--r-- | trash.png | bin | 4870 -> 4649 bytes |
13 files changed, 400 insertions, 72 deletions
@@ -26,7 +26,18 @@ actual release. On Fedora you need qt-devel, marble-devel, libzip-devel. +Building the Qt version under MacOSX +------------------------------------ +You might have built MacPorts packages with +quartz dependencies to +build the previous Subsurface/Gtk version. Switch to the +x11 +dependencies and prepare your system for Subsurface/Qt by doing: + +sudo port uninstall gtk-osx-application subsurface libdivecomputer +sudo port install cairo +x11 pango +x11 py27-pygtk +x11 gtk2 +x11 +sudo port install qt4-mac marble libzip libtool libusb + +Then build libdivecomputer and Subsurface as described below. Subsurface - an Open Source Divelog =================================== @@ -155,8 +166,8 @@ sh packaging/Windows/mingw-make.sh create-windows-installer Building subsurface on a Mac ---------------------------- Install MacPorts and install the dependencies from MacPorts: -sudo port install gtk2 +quartz py27-pygtk +quartz libusb gtk-osx-application \ - automake autoconf libtool libsoup osm-gps-map libzip + +sudo port install libusb libtool libzip qt4-mac marble Install libdivecomputer: git clone git://git.libdivecomputer.org/libdivecomputer @@ -726,9 +726,9 @@ void get_gas_string(int o2, int he, char *buf, int len); struct event *get_next_event(struct event *event, char *name); -/* this struct holds the information that - * describes the cylinders of air. - * it is a global variable initialized in equipment.c +/* these structs holds the information that + * describes the cylinders / weight systems. + * they are global variables initialized in equipment.c * used to fill the combobox in the add/edit cylinder * dialog */ @@ -737,6 +737,13 @@ struct tank_info { const char *name; int cuft, ml, psi, bar; }; +extern struct tank_info tank_info[100]; + +struct ws_info { + const char *name; + int grams; +}; +extern struct ws_info ws_info[100]; extern bool cylinder_nodata(cylinder_t *cyl); extern bool cylinder_none(void *_data); diff --git a/equipment.c b/equipment.c index 2c17b985e..cd3984c86 100644 --- a/equipment.c +++ b/equipment.c @@ -909,15 +909,13 @@ bad_tank_info: fprintf(stderr, "Bad tank info for '%s'\n", info->name); } } +#endif /* USE_GTK_UI */ /* * We hardcode the most common weight system types * This is a bit odd as the weight system types don't usually encode weight */ -static struct ws_info { - const char *name; - int grams; -} ws_info[100] = { +struct ws_info ws_info[100] = { { N_("integrated"), 0 }, { N_("belt"), 0 }, { N_("ankle"), 0 }, @@ -925,6 +923,7 @@ static struct ws_info { { N_("clip-on"), 0 }, }; +#if USE_GTK_UI static void fill_ws_list(GtkListStore *store) { GtkTreeIter iter; diff --git a/qt-gui.cpp b/qt-gui.cpp index 38038bf61..2b9f97d82 100644 --- a/qt-gui.cpp +++ b/qt-gui.cpp @@ -71,14 +71,12 @@ void init_qt_ui(int *argcp, char ***argvp, char *errormessage) window->show(); } -const char *getSetting(QSettings &s, char *name) +const char *getSetting(QSettings &s, QString name) { QVariant v; - QString text; v = s.value(name); if (v.isValid()) { - text = v.toString(); - return strdup(text.toUtf8()); + return strdup(v.toString().toUtf8().constData()); } return NULL; } diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp index 6c3b61173..4710c048a 100644 --- a/qt-ui/maintab.cpp +++ b/qt-ui/maintab.cpp @@ -83,7 +83,8 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent), ui->cylinders->horizontalHeader()->setResizeMode (CylindersModel::REMOVE , QHeaderView::Fixed); ui->cylinders->setItemDelegateForColumn(CylindersModel::TYPE, new TankInfoDelegate()); ui->weights->setColumnWidth(WeightModel::REMOVE, 24); - ui->cylinders->horizontalHeader()->setResizeMode (WeightModel::REMOVE , QHeaderView::Fixed); + ui->weights->horizontalHeader()->setResizeMode (WeightModel::REMOVE , QHeaderView::Fixed); + ui->weights->setItemDelegateForColumn(WeightModel::TYPE, new WSInfoDelegate()); } // We need to manually position the 'plus' on cylinder and weight. @@ -292,27 +293,11 @@ void MainTab::addCylinder_clicked() cylindersModel->add(); } -void MainTab::on_editCylinder_clicked() -{ -} - -void MainTab::on_delCylinder_clicked() -{ -} - void MainTab::addWeight_clicked() { weightModel->add(); } -void MainTab::on_editWeight_clicked() -{ -} - -void MainTab::on_delWeight_clicked() -{ -} - void MainTab::reload() { } @@ -330,7 +315,7 @@ void MainTab::on_editAccept_clicked(bool edit) mainWindow()->dive_list()->setEnabled(!edit); if (edit) { - ui->diveNotesMessage->setText(tr("This dive is being edited. click on finish / reset when ready.")); + ui->diveNotesMessage->setText(tr("This dive is being edited. Select Save or Undo when ready.")); ui->diveNotesMessage->animatedShow(); notesBackup.buddy = ui->buddy->text(); notesBackup.suit = ui->suit->text(); diff --git a/qt-ui/maintab.h b/qt-ui/maintab.h index e835b6366..38d01e806 100644 --- a/qt-ui/maintab.h +++ b/qt-ui/maintab.h @@ -43,11 +43,7 @@ public: public Q_SLOTS: void addCylinder_clicked(); - void on_editCylinder_clicked(); - void on_delCylinder_clicked(); void addWeight_clicked(); - void on_editWeight_clicked(); - void on_delWeight_clicked(); void updateDiveInfo(int dive); void on_editAccept_clicked(bool edit); void on_editReset_clicked(); diff --git a/qt-ui/maintab.ui b/qt-ui/maintab.ui index 0784980eb..24ca69946 100644 --- a/qt-ui/maintab.ui +++ b/qt-ui/maintab.ui @@ -122,14 +122,14 @@ <item row="10" column="1"> <widget class="QPushButton" name="editReset"> <property name="text"> - <string>reset</string> + <string>Undo</string> </property> </widget> </item> <item row="10" column="0"> <widget class="QPushButton" name="editAccept"> <property name="text"> - <string>OK</string> + <string>Save</string> </property> <property name="checkable"> <bool>true</bool> diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index cff62db48..53138f5a1 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -289,19 +289,26 @@ QString MainWindow::filter() bool MainWindow::askSaveChanges() { QString message; - QMessageBox::StandardButton response; + QMessageBox response; if (existing_filename) - message = tr("You have unsaved changes to file: %1\nDo you really want to close the file without saving?").arg(existing_filename); + message = tr("Do you want to save the changes you made in the file %1?").arg(existing_filename); else - message = tr("You have unsaved changes\nDo you really want to close the datafile without saving?"); - - response = QMessageBox::question(this, tr("Save Changes?"), message, - QMessageBox::Save | QMessageBox::Cancel | QMessageBox::Ok, QMessageBox::Save); - if (response == QMessageBox::Save) { + message = tr("Do you want to save the changes you made in the datafile?"); + + response.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + response.setDefaultButton(QMessageBox::Save); + response.setText(message); + response.setWindowTitle(tr("Save Changes?")); // Not displayed on MacOSX as described in Qt API + response.setInformativeText(tr("Changes will be lost if you don't save them.")); + response.setIcon(QMessageBox::Warning); + int ret = response.exec(); + + switch (ret) { + case QMessageBox::Save: file_save(); return true; - } else if (response == QMessageBox::Ok) { + case QMessageBox::Discard: return true; } return false; diff --git a/qt-ui/modeldelegates.cpp b/qt-ui/modeldelegates.cpp index ea27ed253..c90a1e8e1 100644 --- a/qt-ui/modeldelegates.cpp +++ b/qt-ui/modeldelegates.cpp @@ -10,6 +10,8 @@ #include <QStyle> #include <QStyleOption> #include <QComboBox> +#include <QCompleter> +#include <QLineEdit> StarWidgetsDelegate::StarWidgetsDelegate(QWidget* parent): QStyledItemDelegate(parent), @@ -52,19 +54,97 @@ QSize StarWidgetsDelegate::sizeHint(const QStyleOptionViewItem& option, const QM QWidget* TankInfoDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { QComboBox *comboDelegate = new QComboBox(parent); - TankInfoModel *model = new TankInfoModel; - QString data = index.model()->data(index, Qt::DisplayRole).toString(); + TankInfoModel *model = TankInfoModel::instance(); comboDelegate->setModel(model); - int i; - for (i = 0; i < model->rowCount(); i++) { - if (model->data(model->index(i,0), Qt::DisplayRole).toString() == data) - break; - } - if (i != model->rowCount()) - comboDelegate->setCurrentIndex(i); + comboDelegate->setEditable(true); + comboDelegate->setAutoCompletion(true); + comboDelegate->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive); + comboDelegate->completer()->setCompletionMode(QCompleter::PopupCompletion); return comboDelegate; } +void TankInfoDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const +{ + QComboBox *c = qobject_cast<QComboBox*>(editor); + QString data = index.model()->data(index, Qt::DisplayRole).toString(); + int i = c->findText(data); + if (i != -1) + c->setCurrentIndex(i); + else + c->setEditText(data); +} + +void TankInfoDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& thisindex) const +{ + QComboBox *c = qobject_cast<QComboBox*>(editor); + CylindersModel *mymodel = qobject_cast<CylindersModel *>(model); + TankInfoModel *tanks = TankInfoModel::instance(); + QModelIndexList matches = tanks->match(tanks->index(0,0), Qt::DisplayRole, c->currentText()); + int row; + if (matches.isEmpty()) { + // we need to add this + tanks->insertRows(tanks->rowCount(), 1); + tanks->setData(tanks->index(tanks->rowCount() -1, 0), c->currentText()); + row = tanks->rowCount() - 1; + } else { + row = matches.first().row(); + } + int tankSize = tanks->data(tanks->index(row, TankInfoModel::ML)).toInt(); + int tankPressure = tanks->data(tanks->index(row, TankInfoModel::BAR)).toInt(); + + mymodel->setData(model->index(thisindex.row(), CylindersModel::TYPE), c->currentText(), Qt::EditRole); + mymodel->passInData(model->index(thisindex.row(), CylindersModel::WORKINGPRESS), tankPressure); + mymodel->passInData(model->index(thisindex.row(), CylindersModel::SIZE), tankSize); +} + TankInfoDelegate::TankInfoDelegate(QObject* parent): QStyledItemDelegate(parent) { } + +QWidget* WSInfoDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + QComboBox *comboDelegate = new QComboBox(parent); + WSInfoModel *model = WSInfoModel::instance(); + comboDelegate->setModel(model); + comboDelegate->setEditable(true); + comboDelegate->setAutoCompletion(true); + comboDelegate->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive); + comboDelegate->completer()->setCompletionMode(QCompleter::PopupCompletion); + return comboDelegate; +} + +void WSInfoDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const +{ + QComboBox *c = qobject_cast<QComboBox*>(editor); + QString data = index.model()->data(index, Qt::DisplayRole).toString(); + int i = c->findText(data); + if (i != -1) + c->setCurrentIndex(i); + else + c->setEditText(data); +} + +void WSInfoDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& thisindex) const +{ + QComboBox *c = qobject_cast<QComboBox*>(editor); + WeightModel *mymodel = qobject_cast<WeightModel *>(model); + WSInfoModel *wsim = WSInfoModel::instance(); + QModelIndexList matches = wsim->match(wsim->index(0,0), Qt::DisplayRole, c->currentText()); + int row; + if (matches.isEmpty()) { + // we need to add this puppy + wsim->insertRows(wsim->rowCount(), 1); + wsim->setData(wsim->index(wsim->rowCount() - 1, 0), c->currentText()); + row = wsim->rowCount() - 1; + } else { + row = matches.first().row(); + } + int grams = wsim->data(wsim->index(row, WSInfoModel::GR)).toInt(); + QVariant v = QString(c->currentText()); + mymodel->setData(model->index(thisindex.row(), WeightModel::TYPE), v, Qt::EditRole); + mymodel->passInData(model->index(thisindex.row(), WeightModel::WEIGHT), grams); +} + +WSInfoDelegate::WSInfoDelegate(QObject* parent): QStyledItemDelegate(parent) +{ +} diff --git a/qt-ui/modeldelegates.h b/qt-ui/modeldelegates.h index baf7d50c3..79fbe297b 100644 --- a/qt-ui/modeldelegates.h +++ b/qt-ui/modeldelegates.h @@ -18,6 +18,17 @@ class TankInfoDelegate : public QStyledItemDelegate{ public: explicit TankInfoDelegate(QObject* parent = 0); virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual void setEditorData(QWidget* editor, const QModelIndex& index) const; + virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; +}; + +class WSInfoDelegate : public QStyledItemDelegate{ + Q_OBJECT +public: + explicit WSInfoDelegate(QObject* parent = 0); + virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual void setEditorData(QWidget* editor, const QModelIndex& index) const; + virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; }; #endif diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp index 7ccbe1e49..6c6d0b133 100644 --- a/qt-ui/models.cpp +++ b/qt-ui/models.cpp @@ -14,8 +14,6 @@ #include <QFont> #include <QIcon> -extern struct tank_info tank_info[100]; - CylindersModel::CylindersModel(QObject* parent): QAbstractTableModel(parent), current(0), rows(0) { } @@ -111,6 +109,28 @@ QVariant CylindersModel::data(const QModelIndex& index, int role) const return ret; } +// this is our magic 'pass data in' function that allows the delegate to get +// the data here without silly unit conversions; +// so we only implement the two columns we care about +void CylindersModel::passInData(const QModelIndex& index, const QVariant& value) +{ + cylinder_t *cyl = ¤t->cylinder[index.row()]; + switch(index.column()) { + case SIZE: + if (cyl->type.size.mliter != value.toInt()) { + cyl->type.size.mliter = value.toInt(); + mark_divelist_changed(TRUE); + } + break; + case WORKINGPRESS: + if (cyl->type.workingpressure.mbar != value.toInt()) { + cyl->type.workingpressure.mbar = value.toInt(); + mark_divelist_changed(TRUE); + } + break; + } +} + #define CHANGED(_t,_u1,_u2) value._t() != data(index, role).toString().replace(_u1,"").replace(_u2,"")._t() bool CylindersModel::setData(const QModelIndex& index, const QVariant& value, int role) @@ -119,7 +139,8 @@ bool CylindersModel::setData(const QModelIndex& index, const QVariant& value, in switch(index.column()) { case TYPE: if (!value.isNull()) { - char *text = value.toByteArray().data(); + QByteArray ba = value.toByteArray(); + const char *text = ba.constData(); if (!cyl->type.description || strcmp(cyl->type.description, text)) { cyl->type.description = strdup(text); mark_divelist_changed(TRUE); @@ -130,20 +151,29 @@ bool CylindersModel::setData(const QModelIndex& index, const QVariant& value, in if (CHANGED(toDouble, "cuft", "l")) { // if units are CUFT then this value is meaningless until we have working pressure if (value.toDouble() != 0.0) { + TankInfoModel *tanks = TankInfoModel::instance(); + QModelIndexList matches = tanks->match(tanks->index(0,0), Qt::DisplayRole, cyl->type.description); if (prefs.units.volume == prefs.units.CUFT) { - if (cyl->type.workingpressure.mbar == 0) + if (cyl->type.workingpressure.mbar == 0) { // this is a hack as we can't store a wet size // without working pressure in cuft mode // so we assume it's an aluminum tank at 3000psi cyl->type.workingpressure.mbar = psi_to_mbar(3000); + if (!matches.isEmpty()) + tanks->setData(tanks->index(matches.first().row(), TankInfoModel::BAR), cyl->type.workingpressure.mbar / 1000.0); + } if (cyl->type.size.mliter != wet_volume(value.toDouble(), cyl->type.workingpressure)) { mark_divelist_changed(TRUE); cyl->type.size.mliter = wet_volume(value.toDouble(), cyl->type.workingpressure); + if (!matches.isEmpty()) + tanks->setData(tanks->index(matches.first().row(), TankInfoModel::ML), cyl->type.size.mliter); } } else { if (cyl->type.size.mliter != value.toDouble() * 1000.0) { mark_divelist_changed(TRUE); cyl->type.size.mliter = value.toDouble() * 1000.0; + if (!matches.isEmpty()) + tanks->setData(tanks->index(matches.first().row(), TankInfoModel::ML), cyl->type.size.mliter); } } } @@ -152,10 +182,14 @@ bool CylindersModel::setData(const QModelIndex& index, const QVariant& value, in case WORKINGPRESS: if (CHANGED(toDouble, "psi", "bar")) { if (value.toDouble() != 0.0) { + TankInfoModel *tanks = TankInfoModel::instance(); + QModelIndexList matches = tanks->match(tanks->index(0,0), Qt::DisplayRole, cyl->type.description); if (prefs.units.pressure == prefs.units.PSI) cyl->type.workingpressure.mbar = psi_to_mbar(value.toDouble()); else cyl->type.workingpressure.mbar = value.toDouble() * 1000; + if (!matches.isEmpty()) + tanks->setData(tanks->index(matches.first().row(), TankInfoModel::BAR), cyl->type.workingpressure.mbar / 1000.0); mark_divelist_changed(TRUE); } } @@ -267,6 +301,10 @@ void CylindersModel::remove(const QModelIndex& index) endRemoveRows(); } +WeightModel::WeightModel(QObject* parent): QAbstractTableModel(parent), current(0), rows(0) +{ +} + void WeightModel::remove(const QModelIndex& index) { if (index.column() != REMOVE) { @@ -298,7 +336,7 @@ QVariant WeightModel::data(const QModelIndex& index, int role) const if (!index.isValid() || index.row() >= MAX_WEIGHTSYSTEMS) return ret; - weightsystem_t *ws = ¤t_dive->weightsystem[index.row()]; + weightsystem_t *ws = ¤t->weightsystem[index.row()]; if (role == Qt::DisplayRole || role == Qt::EditRole) { switch(index.column()) { @@ -316,19 +354,49 @@ QVariant WeightModel::data(const QModelIndex& index, int role) const return ret; } +// this is our magic 'pass data in' function that allows the delegate to get +// the data here without silly unit conversions; +// so we only implement the two columns we care about +void WeightModel::passInData(const QModelIndex& index, const QVariant& value) +{ + weightsystem_t *ws = ¤t->weightsystem[index.row()]; + if (index.column() == WEIGHT) { + if (ws->weight.grams != value.toInt()) { + ws->weight.grams = value.toInt(); + mark_divelist_changed(TRUE); + } + } +} + bool WeightModel::setData(const QModelIndex& index, const QVariant& value, int role) { - weightsystem_t *ws = ¤t_dive->weightsystem[index.row()]; + weightsystem_t *ws = ¤t->weightsystem[index.row()]; switch(index.column()) { - case TYPE:{ - QByteArray desc = value.toByteArray(); - ws->description = strdup(desc.data()); + case TYPE: + if (!value.isNull()) { + QByteArray ba = value.toString().toUtf8(); + const char *text = ba.constData(); + if (!ws->description || strcmp(ws->description, text)) { + ws->description = strdup(text); + mark_divelist_changed(TRUE); + } + } break; - } case WEIGHT: - ws->weight.grams = value.toInt() *1000; + if (CHANGED(toDouble, "kg", "lbs")) { + if (prefs.units.weight == prefs.units.LBS) + ws->weight.grams = lbs_to_grams(value.toDouble()); + else + ws->weight.grams = value.toDouble() * 1000.0; + // now update the ws_info + WSInfoModel *wsim = WSInfoModel::instance(); + QModelIndexList matches = wsim->match(wsim->index(0,0), Qt::DisplayRole, ws->description); + if (!matches.isEmpty()) + wsim->setData(wsim->index(matches.first().row(), WSInfoModel::GR), ws->weight.grams); + } break; } + return QAbstractItemModel::setData(index, value, role); } Qt::ItemFlags WeightModel::flags(const QModelIndex& index) const @@ -398,10 +466,147 @@ void WeightModel::setDive(dive* d) endInsertRows(); } -void TankInfoModel::add(const QString& description) +WSInfoModel* WSInfoModel::instance() +{ + static WSInfoModel *self = new WSInfoModel(); + return self; +} + +bool WSInfoModel::insertRows(int row, int count, const QModelIndex& parent) +{ + beginInsertRows(parent, rowCount(), rowCount()); + rows += count; + endInsertRows(); + return true; +} + +bool WSInfoModel::setData(const QModelIndex& index, const QVariant& value, int role) +{ + struct ws_info *info = &ws_info[index.row()]; + switch(index.column()) { + case DESCRIPTION: + info->name = strdup(value.toByteArray().data()); + break; + case GR: + info->grams = value.toInt(); + break; + } + return TRUE; +} + +void WSInfoModel::clear() +{ +} + +int WSInfoModel::columnCount(const QModelIndex& parent) const +{ + return 2; +} + +QVariant WSInfoModel::data(const QModelIndex& index, int role) const +{ + QVariant ret; + if (!index.isValid()) { + return ret; + } + struct ws_info *info = &ws_info[index.row()]; + + int gr = info->grams; + + if (role == Qt::DisplayRole || role == Qt::EditRole) { + switch(index.column()) { + case GR: + ret = gr; + break; + case DESCRIPTION: + ret = QString(info->name); + break; + } + } + return ret; +} + +QVariant WSInfoModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + QVariant ret; + + if (orientation != Qt::Horizontal) + return ret; + + if (role == Qt::DisplayRole) { + switch(section) { + case GR: + ret = tr("kg"); + break; + case DESCRIPTION: + ret = tr("Description"); + break; + } + } + return ret; +} + +int WSInfoModel::rowCount(const QModelIndex& parent) const +{ + return rows+1; +} + +WSInfoModel::WSInfoModel() : QAbstractTableModel(), rows(-1) +{ + struct ws_info *info = ws_info; + for (info = ws_info; info->name; info++, rows++); + + if (rows > -1) { + beginInsertRows(QModelIndex(), 0, rows); + endInsertRows(); + } +} + +void WSInfoModel::update() +{ + if (rows > -1) { + beginRemoveRows(QModelIndex(), 0, rows); + endRemoveRows(); + rows = -1; + } + struct ws_info *info = ws_info; + for (info = ws_info; info->name; info++, rows++); + + if (rows > -1) { + beginInsertRows(QModelIndex(), 0, rows); + endInsertRows(); + } +} + +TankInfoModel* TankInfoModel::instance() +{ + static TankInfoModel *self = new TankInfoModel(); + return self; +} + +bool TankInfoModel::insertRows(int row, int count, const QModelIndex& parent) +{ + beginInsertRows(parent, rowCount(), rowCount()); + rows += count; + endInsertRows(); + return true; +} + +bool TankInfoModel::setData(const QModelIndex& index, const QVariant& value, int role) { - // When the user `creates` a new one on the combobox. - // for now, empty till dirk cleans the GTK code. + struct tank_info *info = &tank_info[index.row()]; + switch(index.column()) { + case DESCRIPTION: + info->name = strdup(value.toByteArray().data()); + break; + case ML: + info->ml = value.toInt(); + break; + case BAR: + info->bar = value.toInt(); + break; + } + return TRUE; } void TankInfoModel::clear() @@ -430,7 +635,7 @@ QVariant TankInfoModel::data(const QModelIndex& index, int role) const p.mbar = psi_to_mbar(info->psi); ml = wet_volume(info->cuft, p); } - if (role == Qt::DisplayRole) { + if (role == Qt::DisplayRole || role == Qt::EditRole) { switch(index.column()) { case BAR: ret = bar; @@ -478,7 +683,6 @@ TankInfoModel::TankInfoModel() : QAbstractTableModel(), rows(-1) { struct tank_info *info = tank_info; for (info = tank_info; info->name; info++, rows++); - if (rows > -1) { beginInsertRows(QModelIndex(), 0, rows); endInsertRows(); @@ -490,6 +694,7 @@ void TankInfoModel::update() if (rows > -1) { beginRemoveRows(QModelIndex(), 0, rows); endRemoveRows(); + rows = -1; } struct tank_info *info = tank_info; for (info = tank_info; info->name; info++, rows++); diff --git a/qt-ui/models.h b/qt-ui/models.h index 5fa97eb56..ad909abe1 100644 --- a/qt-ui/models.h +++ b/qt-ui/models.h @@ -9,6 +9,7 @@ #include <QAbstractTableModel> #include <QCoreApplication> +#include <QStringList> #include "../dive.h" #include "../divelist.h" @@ -18,19 +19,43 @@ class TankInfoModel : public QAbstractTableModel { Q_OBJECT public: - enum Column { DESCRIPTION, ML, BAR}; + static TankInfoModel* instance(); + + enum Column {DESCRIPTION, ML, BAR}; TankInfoModel(); /*reimp*/ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; /*reimp*/ int columnCount(const QModelIndex& parent = QModelIndex()) const; /*reimp*/ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; /*reimp*/ int rowCount(const QModelIndex& parent = QModelIndex()) const; + /*reimp*/ bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()); + /*reimp*/ bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); + void clear(); + void update(); +private: + int rows; +}; + +/* Encapsulate ws_info */ +class WSInfoModel : public QAbstractTableModel { +Q_OBJECT +public: + static WSInfoModel* instance(); + + enum Column {DESCRIPTION, GR}; + WSInfoModel(); - void add(const QString& description); + /*reimp*/ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + /*reimp*/ int columnCount(const QModelIndex& parent = QModelIndex()) const; + /*reimp*/ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; + /*reimp*/ int rowCount(const QModelIndex& parent = QModelIndex()) const; + /*reimp*/ bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()); + /*reimp*/ bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); void clear(); void update(); private: int rows; + }; /* Encapsulation of the Cylinder Model, that presents the @@ -48,6 +73,7 @@ public: /*reimp*/ Qt::ItemFlags flags(const QModelIndex& index) const; /*reimp*/ bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); + void passInData(const QModelIndex& index, const QVariant& value); void add(); void clear(); void update(); @@ -66,6 +92,8 @@ class WeightModel : public QAbstractTableModel { Q_OBJECT public: enum Column {REMOVE, TYPE, WEIGHT, COLUMNS}; + + explicit WeightModel(QObject *parent = 0); /*reimp*/ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; /*reimp*/ int columnCount(const QModelIndex& parent = QModelIndex()) const; /*reimp*/ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; @@ -73,6 +101,7 @@ public: /*reimp*/ Qt::ItemFlags flags(const QModelIndex& index) const; /*reimp*/ bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); + void passInData(const QModelIndex& index, const QVariant& value); void add(); void clear(); void update(); Binary files differ |