Undo: make editing of dive number undoable

When pressing F2 in the dive list, the number can be edited.
Make this action undoable by implementing a EditNumber command.

This command is differs from the other undo commands, as not the
currently selected dives are changed. This means that the EditCommand
needs an alternative constructor taking a single dive. This constructor
was implemented in the base class so that all edit commands can now
be called with a single dive.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2019-07-17 15:49:45 +02:00 committed by Dirk Hohndel
parent 658ac2bb78
commit 726d08c2f7
5 changed files with 55 additions and 2 deletions

View file

@ -163,6 +163,11 @@ int editMode(int index, int newValue, bool currentDiveOnly)
return execute_edit(new EditMode(index, newValue, currentDiveOnly)); return execute_edit(new EditMode(index, newValue, currentDiveOnly));
} }
int editNumber(int newValue, bool currentDiveOnly)
{
return execute_edit(new EditNumber(newValue, currentDiveOnly));
}
int editSuit(const QString &newValue, bool currentDiveOnly) int editSuit(const QString &newValue, bool currentDiveOnly)
{ {
return execute_edit(new EditSuit(newValue, currentDiveOnly)); return execute_edit(new EditSuit(newValue, currentDiveOnly));

View file

@ -60,6 +60,7 @@ void purgeUnusedDiveSites();
int editNotes(const QString &newValue, bool currentDiveOnly); int editNotes(const QString &newValue, bool currentDiveOnly);
int editSuit(const QString &newValue, bool currentDiveOnly); int editSuit(const QString &newValue, bool currentDiveOnly);
int editMode(int index, int newValue, bool currentDiveOnly); int editMode(int index, int newValue, bool currentDiveOnly);
int editNumber(int newValue, bool currentDiveOnly);
int editRating(int newValue, bool currentDiveOnly); int editRating(int newValue, bool currentDiveOnly);
int editVisibility(int newValue, bool currentDiveOnly); int editVisibility(int newValue, bool currentDiveOnly);
int editAirTemp(int newValue, bool currentDiveOnly); int editAirTemp(int newValue, bool currentDiveOnly);

View file

@ -33,6 +33,13 @@ EditDivesBase::EditDivesBase(bool currentDiveOnly) :
{ {
} }
EditDivesBase::EditDivesBase(dive *d) :
dives({ d }),
selectedDives(getDiveSelection()),
current(current_dive)
{
}
int EditDivesBase::numDives() const int EditDivesBase::numDives() const
{ {
return dives.size(); return dives.size();
@ -45,6 +52,13 @@ EditBase<T>::EditBase(T newValue, bool currentDiveOnly) :
{ {
} }
template<typename T>
EditBase<T>::EditBase(T newValue, dive *d) :
EditDivesBase(d),
value(std::move(newValue))
{
}
// This is quite hackish: we can't use virtual functions in the constructor and // This is quite hackish: we can't use virtual functions in the constructor and
// therefore can't initialize the list of dives [the values of the dives are // therefore can't initialize the list of dives [the values of the dives are
// accessed by virtual functions]. Therefore, we (mis)use the fact that workToBeDone() // accessed by virtual functions]. Therefore, we (mis)use the fact that workToBeDone()
@ -445,6 +459,28 @@ DiveField EditMode::fieldId() const
return DiveField::MODE; return DiveField::MODE;
} }
// ***** Number *****
void EditNumber::set(struct dive *d, int number) const
{
d->number = number;
}
int EditNumber::data(struct dive *d) const
{
return d->number;
}
QString EditNumber::fieldName() const
{
return tr("number");
}
DiveField EditNumber::fieldId() const
{
return DiveField::NR;
}
// ***** Tag based commands ***** // ***** Tag based commands *****
EditTagsBase::EditTagsBase(const QStringList &newListIn, bool currentDiveOnly) : EditTagsBase::EditTagsBase(const QStringList &newListIn, bool currentDiveOnly) :
EditDivesBase(currentDiveOnly), EditDivesBase(currentDiveOnly),

View file

@ -29,6 +29,7 @@ namespace Command {
class EditDivesBase : public Base { class EditDivesBase : public Base {
protected: protected:
EditDivesBase(bool currentDiveOnly); EditDivesBase(bool currentDiveOnly);
EditDivesBase(dive *d);
std::vector<dive *> dives; // Dives to be edited. std::vector<dive *> dives; // Dives to be edited.
// On undo, we set the selection and current dive at the time of the operation. // On undo, we set the selection and current dive at the time of the operation.
@ -50,6 +51,7 @@ protected:
public: public:
EditBase(T newValue, bool currentDiveOnly); EditBase(T newValue, bool currentDiveOnly);
EditBase(T newValue, dive *d);
protected: protected:
// Get and set functions to be overriden by sub-classes. // Get and set functions to be overriden by sub-classes.
@ -174,6 +176,15 @@ public:
DiveField fieldId() const override; DiveField fieldId() const override;
}; };
class EditNumber : public EditBase<int> {
public:
using EditBase<int>::EditBase; // Use constructor of base class.
void set(struct dive *d, int number) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
DiveField fieldId() const override;
};
// Fields that work with tag-lists (tags, buddies, divemasters) work differently and therefore // Fields that work with tag-lists (tags, buddies, divemasters) work differently and therefore
// have their own base class. In this case, it's not a template, as all these lists are base // have their own base class. In this case, it's not a template, as all these lists are base
// on strings. // on strings.

View file

@ -7,6 +7,7 @@
#include "core/qthelper.h" #include "core/qthelper.h"
#include "core/subsurface-string.h" #include "core/subsurface-string.h"
#include "core/tag.h" #include "core/tag.h"
#include "desktop-widgets/command.h"
#include <QIcon> #include <QIcon>
#include <QDebug> #include <QDebug>
#include <memory> #include <memory>
@ -412,8 +413,7 @@ bool DiveTripModelBase::setData(const QModelIndex &index, const QVariant &value,
if (dive->number == v) if (dive->number == v)
return false; return false;
} }
d->number = v; Command::editNumber(v, d);
mark_divelist_changed(true);
return true; return true;
} }