summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2020-03-21 17:36:58 +0100
committerGravatar bstoeger <32835590+bstoeger@users.noreply.github.com>2020-03-31 21:53:19 +0200
commitad540ce5e8f928c69ba8061dd9886bdb2936ed61 (patch)
tree285ed2e4c6f5c4d399db04cb7fc1ecfd58524742
parentd13f73001b83501a0596bb6cdf7cc998d910134d (diff)
downloadsubsurface-ad540ce5e8f928c69ba8061dd9886bdb2936ed61.tar.gz
undo: generate fieldId() virtual functions by templates
Most edit commands derive from a common base class EditBase, which declares a fieldId() virtual function that has to be defined by the child classes. This is tedious. For some reason the C++ makers refuse to allow "virtual member constants". To make the code somewhat less verbose, create these functions by a template. Of course, we could introduce the template parameter directly in the EditBase class. However, that would mean that the code in this base class is generated for every single undo command. I'm not sure we want that. This should als make it somewhat less tedious to create new edit commands by copy & paste. We could do the same for the fieldName. However, that is more complicated for two reasons: 1) For historic reasons(?) C++ doesn't allow for string literals as template parameters. Therefore, arrays-of-string would have to be defined, which is not very nice. 2) We would have to make sure that these strings are recognized by Qt's translation machinery and use the QT_TRANSLATE_NOOP macro, which makes the whole thing even less attractive. Maybe later. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r--commands/command_edit.cpp114
-rw-r--r--commands/command_edit.h119
2 files changed, 73 insertions, 160 deletions
diff --git a/commands/command_edit.cpp b/commands/command_edit.cpp
index c5f0e6a7a..999396db2 100644
--- a/commands/command_edit.cpp
+++ b/commands/command_edit.cpp
@@ -14,6 +14,18 @@
namespace Command {
+template <typename T, DiveField::Flags ID>
+DiveField EditTemplate<T, ID>::fieldId() const
+{
+ return ID;
+}
+
+template <DiveField::Flags ID>
+DiveField EditTagsTemplate<ID>::fieldId() const
+{
+ return ID;
+}
+
static std::vector<dive *> getDives(bool currentDiveOnly)
{
if (currentDiveOnly)
@@ -166,11 +178,6 @@ QString EditNotes::fieldName() const
return Command::Base::tr("notes");
}
-DiveField EditNotes::fieldId() const
-{
- return DiveField::NOTES;
-}
-
// ***** Suit *****
void EditSuit::set(struct dive *d, QString s) const
{
@@ -188,11 +195,6 @@ QString EditSuit::fieldName() const
return Command::Base::tr("suit");
}
-DiveField EditSuit::fieldId() const
-{
- return DiveField::SUIT;
-}
-
// ***** Rating *****
void EditRating::set(struct dive *d, int value) const
{
@@ -209,11 +211,6 @@ QString EditRating::fieldName() const
return Command::Base::tr("rating");
}
-DiveField EditRating::fieldId() const
-{
- return DiveField::RATING;
-}
-
// ***** Visibility *****
void EditVisibility::set(struct dive *d, int value) const
{
@@ -230,11 +227,6 @@ QString EditVisibility::fieldName() const
return Command::Base::tr("visibility");
}
-DiveField EditVisibility::fieldId() const
-{
- return DiveField::VISIBILITY;
-}
-
// ***** WaveSize *****
void EditWaveSize::set(struct dive *d, int value) const
{
@@ -251,11 +243,6 @@ QString EditWaveSize::fieldName() const
return Command::Base::tr("wavesize");
}
-DiveField EditWaveSize::fieldId() const
-{
- return DiveField::WAVESIZE;
-}
-
// ***** Current *****
void EditCurrent::set(struct dive *d, int value) const
{
@@ -272,11 +259,6 @@ QString EditCurrent::fieldName() const
return Command::Base::tr("current");
}
-DiveField EditCurrent::fieldId() const
-{
- return DiveField::CURRENT;
-}
-
// ***** Surge *****
void EditSurge::set(struct dive *d, int value) const
{
@@ -293,11 +275,6 @@ QString EditSurge::fieldName() const
return Command::Base::tr("surge");
}
-DiveField EditSurge::fieldId() const
-{
- return DiveField::SURGE;
-}
-
// ***** Chill *****
void EditChill::set(struct dive *d, int value) const
{
@@ -314,11 +291,6 @@ QString EditChill::fieldName() const
return Command::Base::tr("chill");
}
-DiveField EditChill::fieldId() const
-{
- return DiveField::CHILL;
-}
-
// ***** Air Temperature *****
void EditAirTemp::set(struct dive *d, int value) const
{
@@ -335,11 +307,6 @@ QString EditAirTemp::fieldName() const
return Command::Base::tr("air temperature");
}
-DiveField EditAirTemp::fieldId() const
-{
- return DiveField::AIR_TEMP;
-}
-
// ***** Water Temperature *****
void EditWaterTemp::set(struct dive *d, int value) const
{
@@ -359,11 +326,6 @@ QString EditWaterTemp::fieldName() const
return Command::Base::tr("water temperature");
}
-DiveField EditWaterTemp::fieldId() const
-{
- return DiveField::WATER_TEMP;
-}
-
// ***** Water Type *****
void EditWaterTypeUser::set(struct dive *d, int value) const
{
@@ -380,11 +342,6 @@ QString EditWaterTypeUser::fieldName() const
return Command::Base::tr("salinity");
}
-DiveField EditWaterTypeUser::fieldId() const
-{
- return DiveField::SALINITY;
-}
-
// ***** Atmospheric pressure *****
void EditAtmPress::set(struct dive *d, int value) const
{
@@ -401,11 +358,6 @@ QString EditAtmPress::fieldName() const
return Command::Base::tr("Atm. pressure");
}
-DiveField EditAtmPress::fieldId() const
-{
- return DiveField::ATM_PRESS;
-}
-
// ***** Duration *****
void EditDuration::set(struct dive *d, int value) const
{
@@ -425,11 +377,6 @@ QString EditDuration::fieldName() const
return Command::Base::tr("duration");
}
-DiveField EditDuration::fieldId() const
-{
- return DiveField::DURATION;
-}
-
// ***** Depth *****
void EditDepth::set(struct dive *d, int value) const
{
@@ -449,11 +396,6 @@ QString EditDepth::fieldName() const
return Command::Base::tr("depth");
}
-DiveField EditDepth::fieldId() const
-{
- return DiveField::DEPTH;
-}
-
// ***** DiveSite *****
void EditDiveSite::set(struct dive *d, struct dive_site *dive_site) const
{
@@ -471,11 +413,6 @@ QString EditDiveSite::fieldName() const
return Command::Base::tr("dive site");
}
-DiveField EditDiveSite::fieldId() const
-{
- return DiveField::DIVESITE;
-}
-
void EditDiveSite::undo()
{
// Do the normal undo thing, then send dive site changed signals
@@ -549,7 +486,7 @@ void EditDiveSiteNew::redo()
// - Change the semantics of the mode-editing.
// The future will tell.
EditMode::EditMode(int indexIn, int newValue, bool currentDiveOnly)
- : EditBase(newValue, currentDiveOnly), index(indexIn)
+ : EditTemplate(newValue, currentDiveOnly), index(indexIn)
{
}
@@ -569,11 +506,6 @@ QString EditMode::fieldName() const
return Command::Base::tr("dive mode");
}
-DiveField EditMode::fieldId() const
-{
- return DiveField::MODE;
-}
-
// ***** Invalid *****
void EditInvalid::set(struct dive *d, int invalid) const
{
@@ -590,11 +522,6 @@ QString EditInvalid::fieldName() const
return Command::Base::tr("invalid");
}
-DiveField EditInvalid::fieldId() const
-{
- return DiveField::INVALID;
-}
-
// ***** Tag based commands *****
EditTagsBase::EditTagsBase(const QStringList &newListIn, bool currentDiveOnly) :
EditDivesBase(currentDiveOnly),
@@ -725,11 +652,6 @@ QString EditTags::fieldName() const
return Command::Base::tr("tags");
}
-DiveField EditTags::fieldId() const
-{
- return DiveField::TAGS;
-}
-
// ***** Buddies *****
QStringList EditBuddies::data(struct dive *d) const
{
@@ -748,11 +670,6 @@ QString EditBuddies::fieldName() const
return Command::Base::tr("buddies");
}
-DiveField EditBuddies::fieldId() const
-{
- return DiveField::BUDDY;
-}
-
// ***** DiveMaster *****
QStringList EditDiveMaster::data(struct dive *d) const
{
@@ -771,11 +688,6 @@ QString EditDiveMaster::fieldName() const
return Command::Base::tr("dive master");
}
-DiveField EditDiveMaster::fieldId() const
-{
- return DiveField::DIVEMASTER;
-}
-
static void swapCandQString(QString &q, char *&c)
{
QString tmp(c);
diff --git a/commands/command_edit.h b/commands/command_edit.h
index cbbd0d968..8e9ca90e7 100644
--- a/commands/command_edit.h
+++ b/commands/command_edit.h
@@ -61,140 +61,138 @@ protected:
virtual DiveField fieldId() const = 0;
};
-class EditNotes : public EditBase<QString> {
+// The individual Edit-commands define a virtual function that return the field-id.
+// For reasons, which I don't fully understand, the C++ makers are strictly opposed
+// to "virtual member constants" so we have to define these functions. To make
+// things a bit more compact we do this automatically with the following template.
+// Of course, we could directly encode the value in the EditBase-template, but
+// that would lead to a multiplication of the created code.
+template <typename T, DiveField::Flags ID>
+class EditTemplate : public EditBase<T> {
+private:
+ using EditBase<T>::EditBase; // Use constructor of base class.
+ DiveField fieldId() const override final; // final prevents further overriding - then just don't use this template
+};
+
+class EditNotes : public EditTemplate<QString, DiveField::NOTES> {
public:
- using EditBase<QString>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, QString s) const override;
QString data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditSuit : public EditBase<QString> {
+class EditSuit : public EditTemplate<QString, DiveField::SUIT> {
public:
- using EditBase<QString>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, QString s) const override;
QString data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditRating : public EditBase<int> {
+class EditRating : public EditTemplate<int, DiveField::RATING> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditVisibility : public EditBase<int> {
+class EditVisibility : public EditTemplate<int, DiveField::VISIBILITY> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditWaveSize : public EditBase<int> {
+class EditWaveSize : public EditTemplate<int, DiveField::WAVESIZE> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditCurrent : public EditBase<int> {
+class EditCurrent : public EditTemplate<int, DiveField::CURRENT> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditSurge : public EditBase<int> {
+class EditSurge : public EditTemplate<int, DiveField::SURGE> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditChill : public EditBase<int> {
+class EditChill : public EditTemplate<int, DiveField::CHILL> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditAirTemp : public EditBase<int> {
+class EditAirTemp : public EditTemplate<int, DiveField::AIR_TEMP> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditWaterTemp : public EditBase<int> {
+class EditWaterTemp : public EditTemplate<int, DiveField::WATER_TEMP> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditAtmPress : public EditBase<int> {
+class EditAtmPress : public EditTemplate<int, DiveField::ATM_PRESS> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditWaterTypeUser : public EditBase<int> {
+class EditWaterTypeUser : public EditTemplate<int, DiveField::SALINITY> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditDuration : public EditBase<int> {
+class EditDuration : public EditTemplate<int, DiveField::DURATION> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditDepth : public EditBase<int> {
+class EditDepth : public EditTemplate<int, DiveField::DEPTH> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditDiveSite : public EditBase<struct dive_site *> {
+class EditDiveSite : public EditTemplate<struct dive_site *, DiveField::DIVESITE> {
public:
- using EditBase<struct dive_site *>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // Use constructor of base class.
void set(struct dive *d, struct dive_site *value) const override;
struct dive_site *data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
// We specialize these so that we can send dive-site changed signals.
void undo() override;
@@ -212,23 +210,21 @@ public:
void redo() override;
};
-class EditMode : public EditBase<int> {
+class EditMode : public EditTemplate<int, DiveField::MODE> {
int index;
public:
EditMode(int indexIn, int newValue, bool currentDiveOnly);
void set(struct dive *d, int i) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditInvalid : public EditBase<int> {
+class EditInvalid : public EditTemplate<int, DiveField::INVALID> {
public:
- using EditBase<int>::EditBase; // Use constructor of base class.
+ using EditTemplate::EditTemplate; // 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
@@ -254,31 +250,36 @@ protected:
virtual DiveField fieldId() const = 0;
};
-class EditTags : public EditTagsBase {
+// See comments for EditTemplate
+template <DiveField::Flags ID>
+class EditTagsTemplate : public EditTagsBase {
+private:
+ using EditTagsBase::EditTagsBase; // Use constructor of base class.
+ DiveField fieldId() const override final; // final prevents further overriding - then just don't use this template
+};
+
+class EditTags : public EditTagsTemplate<DiveField::TAGS> {
public:
- using EditTagsBase::EditTagsBase; // Use constructor of base class.
+ using EditTagsTemplate::EditTagsTemplate; // Use constructor of base class.
QStringList data(struct dive *d) const override;
void set(struct dive *d, const QStringList &v) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditBuddies : public EditTagsBase {
+class EditBuddies : public EditTagsTemplate<DiveField::BUDDY> {
public:
- using EditTagsBase::EditTagsBase; // Use constructor of base class.
+ using EditTagsTemplate::EditTagsTemplate; // Use constructor of base class.
QStringList data(struct dive *d) const override;
void set(struct dive *d, const QStringList &v) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
-class EditDiveMaster : public EditTagsBase {
+class EditDiveMaster : public EditTagsTemplate<DiveField::DIVEMASTER> {
public:
- using EditTagsBase::EditTagsBase; // Use constructor of base class.
+ using EditTagsTemplate::EditTagsTemplate; // Use constructor of base class.
QStringList data(struct dive *d) const override;
void set(struct dive *d, const QStringList &v) const override;
QString fieldName() const override;
- DiveField fieldId() const override;
};
// Fields we have to remember to undo paste