summaryrefslogtreecommitdiffstats
path: root/qt-models/divecomputermodel.cpp
blob: b83679a03167a44ce1d522a444a5216b3cee31f5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// SPDX-License-Identifier: GPL-2.0
#include "qt-models/divecomputermodel.h"
#include "commands/command.h"
#include "core/dive.h"
#include "core/divelist.h"
#include "core/subsurface-qt/divelistnotifier.h"

DiveComputerModel::DiveComputerModel(QObject *parent) : CleanerTableModel(parent)
{
	connect(&diveListNotifier, &DiveListNotifier::dataReset, this, &DiveComputerModel::update);
	connect(&diveListNotifier, &DiveListNotifier::deviceAdded, this, &DiveComputerModel::deviceAdded);
	connect(&diveListNotifier, &DiveListNotifier::deviceDeleted, this, &DiveComputerModel::deviceDeleted);
	connect(&diveListNotifier, &DiveListNotifier::deviceEdited, this, &DiveComputerModel::deviceEdited);
	setHeaderDataStrings(QStringList() << "" << tr("Model") << tr("Device ID") << tr("Nickname"));
	update();
}

void DiveComputerModel::update()
{
	beginResetModel();
	endResetModel();
}

QVariant DiveComputerModel::data(const QModelIndex &index, int role) const
{
	const device *dev = get_device(&device_table, index.row());
	if (dev == nullptr)
		return QVariant();
	const device &node = *dev;

	if (role == Qt::DisplayRole || role == Qt::EditRole) {
		switch (index.column()) {
		case ID:
			return QString("0x").append(QString::number(node.deviceId, 16));
		case MODEL:
			return QString::fromStdString(node.model);
		case NICKNAME:
			return QString::fromStdString(node.nickName);
		}
	}

	if (index.column() == REMOVE) {
		switch (role) {
		case Qt::DecorationRole:
			return trashIcon();
		case Qt::SizeHintRole:
			return trashIcon().size();
		case Qt::ToolTipRole:
			return tr("Clicking here will remove this dive computer.");
		}
	}
	return QVariant();
}

int DiveComputerModel::rowCount(const QModelIndex&) const
{
	return (int)device_table.devices.size();
}

void DiveComputerModel::deviceAdded(int idx)
{
	beginInsertRows(QModelIndex(), idx, idx);
	endInsertRows();
}

void DiveComputerModel::deviceDeleted(int idx)
{
	beginRemoveRows(QModelIndex(), idx, idx);
	endRemoveRows();
}

void DiveComputerModel::deviceEdited(int idx)
{
	dataChanged(index(idx, REMOVE), index(idx, NICKNAME));
}

Qt::ItemFlags DiveComputerModel::flags(const QModelIndex &index) const
{
	Qt::ItemFlags flags = QAbstractItemModel::flags(index);
	if (index.column() == NICKNAME)
		flags |= Qt::ItemIsEditable;
	return flags;
}

bool DiveComputerModel::setData(const QModelIndex &index, const QVariant &value, int)
{
	// We should test if the role == Qt::EditRole
	Command::editDeviceNickname(index.row(), value.toString());
	return true;
}

// Convenience function to access alternative columns
static QString getData(const QModelIndex &idx, int col)
{
	const QAbstractItemModel *model = idx.model();
	QModelIndex idx2 = model->index(idx.row(), col, idx.parent());
	return model->data(idx2).toString();
}

// Helper function: sort data pointed to by the given indexes.
// For equal data, sort by two alternative rows.
// All sorting is by case-insensitive string comparison.
static bool sortHelper(const QModelIndex &i1, const QModelIndex &i2, int altRow1, int altRow2)
{
	if(int cmp = i1.data().toString().compare(i2.data().toString()))
		return cmp < 0;
	if(int cmp = getData(i1, altRow1).compare(getData(i2, altRow1)))
		return cmp < 0;
	return getData(i1, altRow2).compare(getData(i2, altRow2)) < 0;
}

bool DiveComputerSortedModel::lessThan(const QModelIndex &i1, const QModelIndex &i2) const
{
	// We assume that i1.column() == i2.column()
	switch (i1.column()) {
		case DiveComputerModel::ID:
			return sortHelper(i1, i2, DiveComputerModel::MODEL, DiveComputerModel::NICKNAME);
		case DiveComputerModel::MODEL:
		default:
			return sortHelper(i1, i2, DiveComputerModel::ID, DiveComputerModel::NICKNAME);
		case DiveComputerModel::NICKNAME:
			return sortHelper(i1, i2, DiveComputerModel::MODEL, DiveComputerModel::ID);
	}
}

void DiveComputerSortedModel::remove(const QModelIndex &index)
{
	int row = mapToSource(index).row();
	if (row < 0 || row >= (int)device_table.devices.size())
		return;
	Command::removeDevice(row);
}