summaryrefslogtreecommitdiffstats
path: root/qt-models/models.cpp
diff options
context:
space:
mode:
authorGravatar Tomaz Canabrava <tomaz.canabrava@intel.com>2015-05-28 16:23:49 -0300
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-05-29 14:09:13 -0700
commitf432b764e78ac3d66f5ab1bfc7c18fbdb75624e5 (patch)
treec2ec5c81660d22bf986968808bd4ecb7256623ae /qt-models/models.cpp
parent6e4aa7d044a344527e61f17c2254851ba799c4bd (diff)
downloadsubsurface-f432b764e78ac3d66f5ab1bfc7c18fbdb75624e5.tar.gz
Move DivePlannerModel and CylinderModel to qt-models
Still trying to make it easier for the Mobile Port: This patch is a bit bigger than I hopped, but it was the smallest that I could get. A lot of TODO items where added where I broke the code because the current implementation would break the QML implementtion on the designer. I'll most probably fix those myself when I finish the transition to the models to the new folder. I only moved both models at once because there's an interdependency between them (seems inevitable, tough, but I'll take a better look at it later). Signed-off-by: Tomaz Canabrava <tomaz.canabrava@intel.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'qt-models/models.cpp')
-rw-r--r--qt-models/models.cpp391
1 files changed, 9 insertions, 382 deletions
diff --git a/qt-models/models.cpp b/qt-models/models.cpp
index 637a2d3b1..3bc0f74a2 100644
--- a/qt-models/models.cpp
+++ b/qt-models/models.cpp
@@ -28,387 +28,12 @@
#include <QMessageBox>
#include <QStringListModel>
-static QPixmap *trashIconPixmap;
-
// initialize the trash icon if necessary
-static void initTrashIcon()
-{
- if (!trashIconPixmap)
- trashIconPixmap = new QPixmap(QIcon(":trash").pixmap(defaultIconMetrics().sz_small));
-}
const QPixmap &trashIcon()
{
- return *trashIconPixmap;
-}
-
-CylindersModel::CylindersModel(QObject *parent) : changed(false),
- rows(0)
-{
- // enum {REMOVE, TYPE, SIZE, WORKINGPRESS, START, END, O2, HE, DEPTH};
- setHeaderDataStrings(QStringList() << "" << tr("Type") << tr("Size") << tr("Work press.") << tr("Start press.") << tr("End press.") << tr("O₂%") << tr("He%")
- << tr("Switch at") << tr("Use"));
-
- initTrashIcon();
-}
-
-CylindersModel *CylindersModel::instance()
-{
-
- static QScopedPointer<CylindersModel> self(new CylindersModel());
- return self.data();
-}
-
-static QVariant percent_string(fraction_t fraction)
-{
- int permille = fraction.permille;
-
- if (!permille)
- return QVariant();
- return QString("%1%").arg(permille / 10.0, 0, 'f', 1);
-}
-
-QVariant CylindersModel::data(const QModelIndex &index, int role) const
-{
- QVariant ret;
-
- if (!index.isValid() || index.row() >= MAX_CYLINDERS)
- return ret;
-
- cylinder_t *cyl = &displayed_dive.cylinder[index.row()];
- switch (role) {
- case Qt::BackgroundRole: {
- switch (index.column()) {
- // mark the cylinder start / end pressure in red if the values
- // seem implausible
- case START:
- case END:
- if ((cyl->start.mbar && !cyl->end.mbar) ||
- (cyl->end.mbar && cyl->start.mbar <= cyl->end.mbar))
- ret = REDORANGE1_HIGH_TRANS;
- break;
- }
- break;
- }
- case Qt::FontRole: {
- QFont font = defaultModelFont();
- switch (index.column()) {
- case START:
- font.setItalic(!cyl->start.mbar);
- break;
- case END:
- font.setItalic(!cyl->end.mbar);
- break;
- }
- ret = font;
- break;
- }
- case Qt::TextAlignmentRole:
- ret = Qt::AlignCenter;
- break;
- case Qt::DisplayRole:
- case Qt::EditRole:
- switch (index.column()) {
- case TYPE:
- ret = QString(cyl->type.description);
- break;
- case SIZE:
- if (cyl->type.size.mliter)
- ret = get_volume_string(cyl->type.size, true, cyl->type.workingpressure.mbar);
- break;
- case WORKINGPRESS:
- if (cyl->type.workingpressure.mbar)
- ret = get_pressure_string(cyl->type.workingpressure, true);
- break;
- case START:
- if (cyl->start.mbar)
- ret = get_pressure_string(cyl->start, true);
- else if (cyl->sample_start.mbar)
- ret = get_pressure_string(cyl->sample_start, true);
- break;
- case END:
- if (cyl->end.mbar)
- ret = get_pressure_string(cyl->end, true);
- else if (cyl->sample_end.mbar)
- ret = get_pressure_string(cyl->sample_end, true);
- break;
- case O2:
- ret = percent_string(cyl->gasmix.o2);
- break;
- case HE:
- ret = percent_string(cyl->gasmix.he);
- break;
- case DEPTH:
- ret = get_depth_string(cyl->depth, true);
- break;
- case USE:
- ret = gettextFromC::instance()->trGettext(cylinderuse_text[cyl->cylinder_use]);
- break;
- }
- break;
- case Qt::DecorationRole:
- if (index.column() == REMOVE)
- ret = trashIcon();
- break;
- case Qt::SizeHintRole:
- if (index.column() == REMOVE)
- ret = trashIcon().size();
- break;
-
- case Qt::ToolTipRole:
- if (index.column() == REMOVE)
- ret = tr("Clicking here will remove this cylinder.");
- break;
- }
-
- return ret;
-}
-
-cylinder_t *CylindersModel::cylinderAt(const QModelIndex &index)
-{
- return &displayed_dive.cylinder[index.row()];
-}
-
-// 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 = cylinderAt(index);
- switch (index.column()) {
- case SIZE:
- if (cyl->type.size.mliter != value.toInt()) {
- cyl->type.size.mliter = value.toInt();
- dataChanged(index, index);
- }
- break;
- case WORKINGPRESS:
- if (cyl->type.workingpressure.mbar != value.toInt()) {
- cyl->type.workingpressure.mbar = value.toInt();
- dataChanged(index, index);
- }
- break;
- }
-}
-
-/* Has the string value changed */
-#define CHANGED() \
- (vString = value.toString()) != data(index, role).toString()
-
-bool CylindersModel::setData(const QModelIndex &index, const QVariant &value, int role)
-{
- QString vString;
- bool addDiveMode = DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING;
- if (addDiveMode)
- DivePlannerPointsModel::instance()->rememberTanks();
-
- cylinder_t *cyl = cylinderAt(index);
- switch (index.column()) {
- case TYPE:
- if (!value.isNull()) {
- QByteArray ba = value.toByteArray();
- const char *text = ba.constData();
- if (!cyl->type.description || strcmp(cyl->type.description, text)) {
- cyl->type.description = strdup(text);
- changed = true;
- }
- }
- break;
- case SIZE:
- if (CHANGED()) {
- TankInfoModel *tanks = TankInfoModel::instance();
- QModelIndexList matches = tanks->match(tanks->index(0, 0), Qt::DisplayRole, cyl->type.description);
-
- cyl->type.size = string_to_volume(vString.toUtf8().data(), cyl->type.workingpressure);
- mark_divelist_changed(true);
- if (!matches.isEmpty())
- tanks->setData(tanks->index(matches.first().row(), TankInfoModel::ML), cyl->type.size.mliter);
- changed = true;
- }
- break;
- case WORKINGPRESS:
- if (CHANGED()) {
- TankInfoModel *tanks = TankInfoModel::instance();
- QModelIndexList matches = tanks->match(tanks->index(0, 0), Qt::DisplayRole, cyl->type.description);
- cyl->type.workingpressure = string_to_pressure(vString.toUtf8().data());
- if (!matches.isEmpty())
- tanks->setData(tanks->index(matches.first().row(), TankInfoModel::BAR), cyl->type.workingpressure.mbar / 1000.0);
- changed = true;
- }
- break;
- case START:
- if (CHANGED()) {
- cyl->start = string_to_pressure(vString.toUtf8().data());
- changed = true;
- }
- break;
- case END:
- if (CHANGED()) {
- //&& (!cyl->start.mbar || string_to_pressure(vString.toUtf8().data()).mbar <= cyl->start.mbar)) {
- cyl->end = string_to_pressure(vString.toUtf8().data());
- changed = true;
- }
- break;
- case O2:
- if (CHANGED()) {
- cyl->gasmix.o2 = string_to_fraction(vString.toUtf8().data());
- pressure_t modpO2;
- if (displayed_dive.dc.divemode == PSCR)
- modpO2.mbar = prefs.decopo2 + (1000 - get_o2(&cyl->gasmix)) * SURFACE_PRESSURE *
- prefs.o2consumption / prefs.decosac / prefs.pscr_ratio;
- else
- modpO2.mbar = prefs.decopo2;
- cyl->depth = gas_mod(&cyl->gasmix, modpO2, M_OR_FT(3, 10));
- changed = true;
- }
- break;
- case HE:
- if (CHANGED()) {
- cyl->gasmix.he = string_to_fraction(vString.toUtf8().data());
- changed = true;
- }
- break;
- case DEPTH:
- if (CHANGED()) {
- cyl->depth = string_to_depth(vString.toUtf8().data());
- changed = true;
- }
- break;
- case USE:
- if (CHANGED()) {
- cyl->cylinder_use = (enum cylinderuse)vString.toInt();
- changed = true;
- }
- break;
- }
- if (addDiveMode)
- DivePlannerPointsModel::instance()->tanksUpdated();
- dataChanged(index, index);
- return true;
-}
-
-int CylindersModel::rowCount(const QModelIndex &parent) const
-{
- return rows;
-}
-
-void CylindersModel::add()
-{
- if (rows >= MAX_CYLINDERS) {
- return;
- }
-
- int row = rows;
- fill_default_cylinder(&displayed_dive.cylinder[row]);
- displayed_dive.cylinder[row].manually_added = true;
- beginInsertRows(QModelIndex(), row, row);
- rows++;
- changed = true;
- endInsertRows();
-}
-
-void CylindersModel::clear()
-{
- if (rows > 0) {
- beginRemoveRows(QModelIndex(), 0, rows - 1);
- endRemoveRows();
- }
-}
-
-void CylindersModel::updateDive()
-{
- clear();
- rows = 0;
- for (int i = 0; i < MAX_CYLINDERS; i++) {
- if (!cylinder_none(&displayed_dive.cylinder[i]) &&
- (prefs.display_unused_tanks ||
- is_cylinder_used(&displayed_dive, i) ||
- displayed_dive.cylinder[i].manually_added))
- rows = i + 1;
- }
- if (rows > 0) {
- beginInsertRows(QModelIndex(), 0, rows - 1);
- endInsertRows();
- }
-}
-
-void CylindersModel::copyFromDive(dive *d)
-{
- if (!d)
- return;
- rows = 0;
- for (int i = 0; i < MAX_CYLINDERS; i++) {
- if (!cylinder_none(&d->cylinder[i]) &&
- (is_cylinder_used(d, i) || prefs.display_unused_tanks)) {
- rows = i + 1;
- }
- }
- if (rows > 0) {
- beginInsertRows(QModelIndex(), 0, rows - 1);
- endInsertRows();
- }
-}
-
-Qt::ItemFlags CylindersModel::flags(const QModelIndex &index) const
-{
- if (index.column() == REMOVE)
- return Qt::ItemIsEnabled;
- return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
-}
-
-void CylindersModel::remove(const QModelIndex &index)
-{
- int mapping[MAX_CYLINDERS];
- if (index.column() != REMOVE) {
- return;
- }
- int same_gas = -1;
- cylinder_t *cyl = &displayed_dive.cylinder[index.row()];
- struct gasmix *mygas = &cyl->gasmix;
- for (int i = 0; i < MAX_CYLINDERS; i++) {
- mapping[i] = i;
- if (i == index.row() || cylinder_none(&displayed_dive.cylinder[i]))
- continue;
- struct gasmix *gas2 = &displayed_dive.cylinder[i].gasmix;
- if (gasmix_distance(mygas, gas2) == 0)
- same_gas = i;
- }
- if (same_gas == -1 &&
- ((DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING &&
- DivePlannerPointsModel::instance()->tankInUse(cyl->gasmix)) ||
- (DivePlannerPointsModel::instance()->currentMode() == DivePlannerPointsModel::NOTHING &&
- is_cylinder_used(&displayed_dive, index.row())))) {
- QMessageBox::warning(MainWindow::instance(), TITLE_OR_TEXT(
- tr("Cylinder cannot be removed"),
- tr("This gas is in use. Only cylinders that are not used in the dive can be removed.")),
- QMessageBox::Ok);
- return;
- }
- beginRemoveRows(QModelIndex(), index.row(), index.row()); // yah, know, ugly.
- rows--;
- if (index.row() == 0) {
- // first gas - we need to make sure that the same gas ends up
- // as first gas
- memmove(cyl, &displayed_dive.cylinder[same_gas], sizeof(*cyl));
- remove_cylinder(&displayed_dive, same_gas);
- mapping[same_gas] = 0;
- for (int i = same_gas + 1; i < MAX_CYLINDERS; i++)
- mapping[i] = i - 1;
- } else {
- remove_cylinder(&displayed_dive, index.row());
- if (same_gas > index.row())
- same_gas--;
- mapping[index.row()] = same_gas;
- for (int i = index.row() + 1; i < MAX_CYLINDERS; i++)
- mapping[i] = i - 1;
- }
- changed = true;
- endRemoveRows();
- struct divecomputer *dc = &displayed_dive.dc;
- while (dc) {
- dc_cylinder_renumber(&displayed_dive, dc, mapping);
- dc = dc->next;
- }
+ static QPixmap trash = QPixmap(":trash").scaledToHeight(defaultIconMetrics().sz_small);
+ return trash;
}
WeightModel::WeightModel(QObject *parent) : CleanerTableModel(parent),
@@ -417,8 +42,6 @@ WeightModel::WeightModel(QObject *parent) : CleanerTableModel(parent),
{
//enum Column {REMOVE, TYPE, WEIGHT};
setHeaderDataStrings(QStringList() << tr("") << tr("Type") << tr("Weight"));
-
- initTrashIcon();
}
weightsystem_t *WeightModel::weightSystemAt(const QModelIndex &index)
@@ -1592,7 +1215,6 @@ bool DiveTripModel::setData(const QModelIndex &index, const QVariant &value, int
return diveItem->setData(index, value, role);
}
-
/*####################################################################
*
* Dive Computer Model
@@ -1605,8 +1227,6 @@ DiveComputerModel::DiveComputerModel(QMultiMap<QString, DiveComputerNode> &dcMap
setHeaderDataStrings(QStringList() << "" << tr("Model") << tr("Device ID") << tr("Nickname"));
dcWorkingMap = dcMap;
numRows = 0;
-
- initTrashIcon();
}
QVariant DiveComputerModel::data(const QModelIndex &index, int role) const
@@ -2213,8 +1833,15 @@ GasSelectionModel *GasSelectionModel::instance()
return self.data();
}
+//TODO: Remove this #include here when the issue below is fixed.
+#include "diveplannermodel.h"
void GasSelectionModel::repopulate()
{
+ /* TODO:
+ * getGasList shouldn't be a member of DivePlannerPointsModel,
+ * it has nothing to do with the current plain being calculated:
+ * it's internal to the current_dive.
+ */
setStringList(DivePlannerPointsModel::instance()->getGasList());
}