summaryrefslogtreecommitdiffstats
path: root/desktop-widgets/undocommands.cpp
blob: d58ac7a4be504d5726d583d7e88dec2639004411 (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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// SPDX-License-Identifier: GPL-2.0
#include "desktop-widgets/undocommands.h"
#include "desktop-widgets/mainwindow.h"
#include "core/divelist.h"
#include "core/subsurface-string.h"
#include "core/gettextfromc.h"

UndoDeleteDive::UndoDeleteDive(const QVector<struct dive*> &divesToDeleteIn) : divesToDelete(divesToDeleteIn)
{
	setText(tr("delete %n dive(s)", "", divesToDelete.size()));
}

void UndoDeleteDive::undo()
{
	// first bring back the trip(s)
	for (auto &trip: tripsToAdd) {
		dive_trip *t = trip.release();	// Give up ownership
		insert_trip(&t);		// Return ownership to backend
	}
	tripsToAdd.clear();

	for (DiveToAdd &d: divesToAdd) {
		if (d.trip)
			add_dive_to_trip(d.dive.get(), d.trip);
		divesToDelete.append(d.dive.get());		// Delete dive on redo
		add_single_dive(d.idx, d.dive.release());	// Return ownership to backend
	}
	mark_divelist_changed(true);
	divesToAdd.clear();

	// Finally, do the UI stuff:
	MainWindow::instance()->refreshDisplay();
}

void UndoDeleteDive::redo()
{
	for (dive *d: divesToDelete) {
		int idx = get_divenr(d);
		if (idx < 0) {
			qWarning() << "Deletion of unknown dive!";
			continue;
		}
		// remove dive from trip - if this is the last dive in the trip
		// remove the whole trip.
		dive_trip *trip = unregister_dive_from_trip(d, false);
		if (trip && trip->nrdives == 0) {
			unregister_trip(trip);			// Remove trip from backend
			tripsToAdd.emplace_back(trip);		// Take ownership of trip
		}

		unregister_dive(idx);			// Remove dive from backend
		divesToAdd.push_back({ OwningDivePtr(d), trip, idx });
							// Take ownership for dive
	}
	divesToDelete.clear();
	mark_divelist_changed(true);

	// Finally, do the UI stuff:
	MainWindow::instance()->refreshDisplay();
}


UndoShiftTime::UndoShiftTime(QVector<int> changedDives, int amount)
	: diveList(changedDives), timeChanged(amount)
{
	setText(tr("delete %n dive(s)", "", changedDives.size()));
}

void UndoShiftTime::undo()
{
	for (int i = 0; i < diveList.count(); i++) {
		dive *d = get_dive_by_uniq_id(diveList.at(i));
		d->when -= timeChanged;
	}
	// Changing times may have unsorted the dive table
	sort_table(&dive_table);
	mark_divelist_changed(true);

	// Negate the time-shift so that the next call does the reverse
	timeChanged = -timeChanged;

	// Finally, do the UI stuff:
	MainWindow::instance()->refreshDisplay();
}

void UndoShiftTime::redo()
{
	// Same as undo(), since after undo() we reversed the timeOffset
	undo();
}


UndoRenumberDives::UndoRenumberDives(const QVector<QPair<int, int>> &divesToRenumberIn) : divesToRenumber(divesToRenumberIn)
{
	setText(tr("renumber %n dive(s)", "", divesToRenumber.count()));
}

void UndoRenumberDives::undo()
{
	for (auto &pair: divesToRenumber) {
		dive *d = get_dive_by_uniq_id(pair.first);
		if (!d)
			continue;
		std::swap(d->number, pair.second);
	}
	mark_divelist_changed(true);

	// Finally, do the UI stuff:
	MainWindow::instance()->refreshDisplay();
}

void UndoRenumberDives::redo()
{
	// Redo and undo do the same thing!
	undo();
}

UndoRemoveDivesFromTrip::UndoRemoveDivesFromTrip(const QVector<dive *> &divesToRemoveIn) : divesToRemove(divesToRemoveIn)
{
	setText(tr("remove %n dive(s) from trip", "", divesToRemove.size()));
}

void UndoRemoveDivesFromTrip::undo()
{
	// first bring back the trip(s)
	for (auto &trip: tripsToAdd) {
		dive_trip *t = trip.release();	// Give up ownership
		insert_trip(&t);		// Return ownership to backend
	}
	tripsToAdd.clear();

	for (auto &pair: divesToAdd)
		add_dive_to_trip(pair.first, pair.second);
	divesToAdd.clear();

	// Finally, do the UI stuff:
	MainWindow::instance()->refreshDisplay();
}

void UndoRemoveDivesFromTrip::redo()
{
	for (dive *d: divesToRemove) {
		// remove dive from trip - if this is the last dive in the trip
		// remove the whole trip.
		dive_trip *trip = unregister_dive_from_trip(d, false);
		if (!trip)
			continue;				// This was not part of a trip
		if (trip->nrdives == 0) {
			unregister_trip(trip);			// Remove trip from backend
			tripsToAdd.emplace_back(trip);		// Take ownership of trip
		}
		divesToAdd.emplace_back(d, trip);
	}
	mark_divelist_changed(true);

	// Finally, do the UI stuff:
	MainWindow::instance()->refreshDisplay();
}