mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Cleanup: remove EDIT_TEXT and EDIT_VALUE macros in maintab.cpp
These functions are now performed by the edit commands and the macros have no users. Remove them. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
92e6e2bba1
commit
73a230b6e6
7 changed files with 215 additions and 62 deletions
|
@ -200,4 +200,9 @@ void editDiveMaster(const QStringList &newList, bool currentDiveOnly)
|
||||||
execute(new EditDiveMaster(newList, currentDiveOnly));
|
execute(new EditDiveMaster(newList, currentDiveOnly));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pasteDives(const dive *d, dive_components what)
|
||||||
|
{
|
||||||
|
execute(new PasteDives(d, what));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Command
|
} // namespace Command
|
||||||
|
|
|
@ -66,6 +66,7 @@ void editDiveSiteNew(const QString &newName, bool currentDiveOnly);
|
||||||
void editTags(const QStringList &newList, bool currentDiveOnly);
|
void editTags(const QStringList &newList, bool currentDiveOnly);
|
||||||
void editBuddies(const QStringList &newList, bool currentDiveOnly);
|
void editBuddies(const QStringList &newList, bool currentDiveOnly);
|
||||||
void editDiveMaster(const QStringList &newList, bool currentDiveOnly);
|
void editDiveMaster(const QStringList &newList, bool currentDiveOnly);
|
||||||
|
void pasteDives(const dive *d, dive_components what);
|
||||||
|
|
||||||
} // namespace Command
|
} // namespace Command
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "command_private.h"
|
#include "command_private.h"
|
||||||
#include "core/divelist.h"
|
#include "core/divelist.h"
|
||||||
#include "core/qthelper.h" // for copy_qstring
|
#include "core/qthelper.h" // for copy_qstring
|
||||||
|
#include "core/subsurface-string.h"
|
||||||
#include "desktop-widgets/mapwidget.h" // TODO: Replace desktop-dependency by signal
|
#include "desktop-widgets/mapwidget.h" // TODO: Replace desktop-dependency by signal
|
||||||
|
|
||||||
namespace Command {
|
namespace Command {
|
||||||
|
@ -598,4 +599,177 @@ DiveField EditDiveMaster::fieldId() const
|
||||||
return DiveField::DIVEMASTER;
|
return DiveField::DIVEMASTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to copy cylinders. This supposes that the destination
|
||||||
|
// cylinder is uninitialized. I.e. the old description is not freed!
|
||||||
|
static void copy_cylinder(const cylinder_t &s, cylinder_t &d)
|
||||||
|
{
|
||||||
|
d.type.description = copy_string(s.type.description);
|
||||||
|
d.type.size = s.type.size;
|
||||||
|
d.type.workingpressure = s.type.workingpressure;
|
||||||
|
d.gasmix = s.gasmix;
|
||||||
|
d.cylinder_use = s.cylinder_use;
|
||||||
|
d.depth = s.depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swapCandQString(QString &q, char *&c)
|
||||||
|
{
|
||||||
|
QString tmp(c);
|
||||||
|
free(c);
|
||||||
|
c = copy_qstring(q);
|
||||||
|
q = std::move(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
PasteState::PasteState(dive *dIn, const dive *data, dive_components what) : d(dIn),
|
||||||
|
tags(nullptr)
|
||||||
|
{
|
||||||
|
memset(&cylinders[0], 0, sizeof(cylinders));
|
||||||
|
memset(&weightsystems[0], 0, sizeof(weightsystems));
|
||||||
|
if (what.notes)
|
||||||
|
notes = data->notes;
|
||||||
|
if (what.divemaster)
|
||||||
|
divemaster = data->divemaster;
|
||||||
|
if (what.buddy)
|
||||||
|
buddy = data->buddy;
|
||||||
|
if (what.suit)
|
||||||
|
suit = data->suit;
|
||||||
|
if (what.rating)
|
||||||
|
rating = data->rating;
|
||||||
|
if (what.visibility)
|
||||||
|
visibility = data->visibility;
|
||||||
|
if (what.divesite)
|
||||||
|
divesite = data->dive_site;
|
||||||
|
if (what.tags)
|
||||||
|
tags = taglist_copy(data->tag_list);
|
||||||
|
if (what.cylinders) {
|
||||||
|
for (int i = 0; i < MAX_CYLINDERS; ++i)
|
||||||
|
copy_cylinder(data->cylinder[i], cylinders[i]);
|
||||||
|
}
|
||||||
|
if (what.weights) {
|
||||||
|
for (int i = 0; i < MAX_WEIGHTSYSTEMS; ++i) {
|
||||||
|
weightsystems[i] = data->weightsystem[i];
|
||||||
|
weightsystems[i].description = copy_string(data->weightsystem[i].description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PasteState::~PasteState()
|
||||||
|
{
|
||||||
|
taglist_free(tags);
|
||||||
|
for (cylinder_t &c: cylinders)
|
||||||
|
free((void *)c.type.description);
|
||||||
|
for (weightsystem_t &w: weightsystems)
|
||||||
|
free((void *)w.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasteState::swap(dive_components what)
|
||||||
|
{
|
||||||
|
if (what.notes)
|
||||||
|
swapCandQString(notes, d->notes);
|
||||||
|
if (what.divemaster)
|
||||||
|
swapCandQString(divemaster, d->divemaster);
|
||||||
|
if (what.buddy)
|
||||||
|
swapCandQString(buddy, d->buddy);
|
||||||
|
if (what.suit)
|
||||||
|
swapCandQString(suit, d->suit);
|
||||||
|
if (what.rating)
|
||||||
|
std::swap(rating, d->rating);
|
||||||
|
if (what.visibility)
|
||||||
|
std::swap(visibility, d->visibility);
|
||||||
|
if (what.divesite)
|
||||||
|
std::swap(divesite, d->dive_site);
|
||||||
|
if (what.tags)
|
||||||
|
std::swap(tags, d->tag_list);
|
||||||
|
if (what.cylinders)
|
||||||
|
std::swap(cylinders, d->cylinder);
|
||||||
|
if (what.weights)
|
||||||
|
std::swap(weightsystems, d->weightsystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***** Paste *****
|
||||||
|
PasteDives::PasteDives(const dive *data, dive_components whatIn) : what(whatIn),
|
||||||
|
current(current_dive)
|
||||||
|
{
|
||||||
|
std::vector<dive *> selection = getDiveSelection();
|
||||||
|
dives.reserve(selection.size());
|
||||||
|
for (dive *d: selection)
|
||||||
|
dives.emplace_back(d, data, what);
|
||||||
|
|
||||||
|
setText(tr("Paste onto %n dive(s)", "", dives.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PasteDives::workToBeDone()
|
||||||
|
{
|
||||||
|
return !dives.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasteDives::undo()
|
||||||
|
{
|
||||||
|
bool diveSiteListChanged = false;
|
||||||
|
|
||||||
|
// If we had taken ownership of dive sites, readd them to the system
|
||||||
|
for (OwningDiveSitePtr &ds: ownedDiveSites) {
|
||||||
|
register_dive_site(ds.release());
|
||||||
|
diveSiteListChanged = true;
|
||||||
|
}
|
||||||
|
ownedDiveSites.clear();
|
||||||
|
|
||||||
|
std::vector<dive *> divesToNotify; // Remember dives so that we can send signals later
|
||||||
|
divesToNotify.reserve(dives.size());
|
||||||
|
for (PasteState &state: dives) {
|
||||||
|
divesToNotify.push_back(state.d);
|
||||||
|
state.swap(what);
|
||||||
|
invalidate_dive_cache(state.d); // Ensure that dive is written in git_save()
|
||||||
|
}
|
||||||
|
|
||||||
|
// If dive sites were pasted, collect all overwritten dive sites
|
||||||
|
// and remove those which don't have users anymore from the core.
|
||||||
|
// But keep an owning pointer. Thus if this undo command is freed, the
|
||||||
|
// dive-site will be automatically deleted and on redo() it can be
|
||||||
|
// readded to the system
|
||||||
|
if (what.divesite) {
|
||||||
|
std::vector<dive_site *> divesites;
|
||||||
|
for (const PasteState &d: dives) {
|
||||||
|
if (std::find(divesites.begin(), divesites.end(), d.divesite) == divesites.end())
|
||||||
|
divesites.push_back(d.divesite);
|
||||||
|
}
|
||||||
|
for (dive_site *ds: divesites) {
|
||||||
|
unregister_dive_site(ds);
|
||||||
|
ownedDiveSites.emplace_back(ds);
|
||||||
|
diveSiteListChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send signals.
|
||||||
|
// TODO: We send one signal per changed field. This means that the dive list may
|
||||||
|
// update the entry numerous times. Perhaps change the field-id into flags?
|
||||||
|
// There seems to be a number of enums / flags describing dive fields. Perhaps unify them all?
|
||||||
|
processByTrip(divesToNotify, [&](dive_trip *trip, const QVector<dive *> &divesInTrip) {
|
||||||
|
if (what.notes)
|
||||||
|
emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::NOTES);
|
||||||
|
if (what.divemaster)
|
||||||
|
emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::DIVEMASTER);
|
||||||
|
if (what.buddy)
|
||||||
|
emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::BUDDY);
|
||||||
|
if (what.suit)
|
||||||
|
emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::SUIT);
|
||||||
|
if (what.rating)
|
||||||
|
emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::RATING);
|
||||||
|
if (what.visibility)
|
||||||
|
emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::VISIBILITY);
|
||||||
|
if (what.divesite)
|
||||||
|
emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::DIVESITE);
|
||||||
|
if (what.tags)
|
||||||
|
emit diveListNotifier.divesChanged(trip, divesInTrip, DiveField::TAGS);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (diveSiteListChanged)
|
||||||
|
MapWidget::instance()->reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redo and undo do the same
|
||||||
|
void PasteDives::redo()
|
||||||
|
{
|
||||||
|
undo();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Command
|
} // namespace Command
|
||||||
|
|
|
@ -211,6 +211,38 @@ public:
|
||||||
DiveField fieldId() const override;
|
DiveField fieldId() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Fields we have to remember to undo paste
|
||||||
|
struct PasteState {
|
||||||
|
dive *d;
|
||||||
|
dive_site *divesite;
|
||||||
|
QString notes;
|
||||||
|
QString divemaster;
|
||||||
|
QString buddy;
|
||||||
|
QString suit;
|
||||||
|
int rating;
|
||||||
|
int visibility;
|
||||||
|
tag_entry *tags;
|
||||||
|
cylinder_t cylinders[MAX_CYLINDERS];
|
||||||
|
weightsystem_t weightsystems[MAX_WEIGHTSYSTEMS];
|
||||||
|
|
||||||
|
PasteState(dive *d, const dive *data, dive_components what); // Read data from dive data for dive d
|
||||||
|
~PasteState();
|
||||||
|
void swap(dive_components what); // Exchange values here and in dive
|
||||||
|
};
|
||||||
|
|
||||||
|
class PasteDives : public Base {
|
||||||
|
dive_components what;
|
||||||
|
std::vector<PasteState> dives;
|
||||||
|
std::vector<OwningDiveSitePtr> ownedDiveSites;
|
||||||
|
dive *current;
|
||||||
|
public:
|
||||||
|
PasteDives(const dive *d, dive_components what);
|
||||||
|
private:
|
||||||
|
void undo() override;
|
||||||
|
void redo() override;
|
||||||
|
bool workToBeDone() override;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Command
|
} // namespace Command
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1802,9 +1802,7 @@ void MainWindow::on_copy_triggered()
|
||||||
|
|
||||||
void MainWindow::on_paste_triggered()
|
void MainWindow::on_paste_triggered()
|
||||||
{
|
{
|
||||||
// take the data in our copyPasteDive and apply it to selected dives
|
Command::pasteDives(©PasteDive, what);
|
||||||
selective_copy_dive(©PasteDive, &displayed_dive, what, false);
|
|
||||||
mainTab->showAndTriggerEditSelective(what);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionFilterTags_triggered()
|
void MainWindow::on_actionFilterTags_triggered()
|
||||||
|
|
|
@ -47,7 +47,6 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
|
||||||
weightModel(new WeightModel(this)),
|
weightModel(new WeightModel(this)),
|
||||||
cylindersModel(new CylindersModel(this)),
|
cylindersModel(new CylindersModel(this)),
|
||||||
editMode(NONE),
|
editMode(NONE),
|
||||||
copyPaste(false),
|
|
||||||
lastSelectedDive(true),
|
lastSelectedDive(true),
|
||||||
lastTabSelectedDive(0),
|
lastTabSelectedDive(0),
|
||||||
lastTabSelectedDiveTrip(0),
|
lastTabSelectedDiveTrip(0),
|
||||||
|
@ -288,7 +287,6 @@ void MainTab::enableEdition(EditMode newEditMode)
|
||||||
if (((newEditMode == DIVE || newEditMode == NONE) && current_dive == NULL) || editMode != NONE)
|
if (((newEditMode == DIVE || newEditMode == NONE) && current_dive == NULL) || editMode != NONE)
|
||||||
return;
|
return;
|
||||||
modified = false;
|
modified = false;
|
||||||
copyPaste = false;
|
|
||||||
if ((newEditMode == DIVE || newEditMode == NONE) &&
|
if ((newEditMode == DIVE || newEditMode == NONE) &&
|
||||||
!isTripEdit &&
|
!isTripEdit &&
|
||||||
current_dive->dc.model &&
|
current_dive->dc.model &&
|
||||||
|
@ -700,22 +698,11 @@ void MainTab::reload()
|
||||||
mark_divelist_changed(true); \
|
mark_divelist_changed(true); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define EDIT_TEXT(what) \
|
|
||||||
if (same_string(mydive->what, cd->what) || copyPaste) { \
|
|
||||||
free(mydive->what); \
|
|
||||||
mydive->what = copy_string(displayed_dive.what); \
|
|
||||||
}
|
|
||||||
|
|
||||||
MainTab::EditMode MainTab::getEditMode() const
|
MainTab::EditMode MainTab::getEditMode() const
|
||||||
{
|
{
|
||||||
return editMode;
|
return editMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EDIT_VALUE(what) \
|
|
||||||
if (mydive->what == cd->what || copyPaste) { \
|
|
||||||
mydive->what = displayed_dive.what; \
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainTab::refreshDisplayedDiveSite()
|
void MainTab::refreshDisplayedDiveSite()
|
||||||
{
|
{
|
||||||
struct dive_site *ds = get_dive_site_for_dive(&displayed_dive);
|
struct dive_site *ds = get_dive_site_for_dive(&displayed_dive);
|
||||||
|
@ -812,7 +799,7 @@ void MainTab::acceptChanges()
|
||||||
MODIFY_DIVES(selectedDives,
|
MODIFY_DIVES(selectedDives,
|
||||||
for (int i = 0; i < MAX_CYLINDERS; i++) {
|
for (int i = 0; i < MAX_CYLINDERS; i++) {
|
||||||
if (mydive != cd) {
|
if (mydive != cd) {
|
||||||
if (same_string(mydive->cylinder[i].type.description, cd->cylinder[i].type.description) || copyPaste) {
|
if (same_string(mydive->cylinder[i].type.description, cd->cylinder[i].type.description)) {
|
||||||
// if we started out with the same cylinder description (for multi-edit) or if we do copt & paste
|
// if we started out with the same cylinder description (for multi-edit) or if we do copt & paste
|
||||||
// make sure that we have the same cylinder type and copy the gasmix, but DON'T copy the start
|
// make sure that we have the same cylinder type and copy the gasmix, but DON'T copy the start
|
||||||
// and end pressures (those are per dive after all)
|
// and end pressures (those are per dive after all)
|
||||||
|
@ -855,7 +842,7 @@ void MainTab::acceptChanges()
|
||||||
mark_divelist_changed(true);
|
mark_divelist_changed(true);
|
||||||
MODIFY_DIVES(selectedDives,
|
MODIFY_DIVES(selectedDives,
|
||||||
for (int i = 0; i < MAX_WEIGHTSYSTEMS; i++) {
|
for (int i = 0; i < MAX_WEIGHTSYSTEMS; i++) {
|
||||||
if (mydive != cd && (copyPaste || same_string(mydive->weightsystem[i].description, cd->weightsystem[i].description))) {
|
if (mydive != cd && (same_string(mydive->weightsystem[i].description, cd->weightsystem[i].description))) {
|
||||||
mydive->weightsystem[i] = displayed_dive.weightsystem[i];
|
mydive->weightsystem[i] = displayed_dive.weightsystem[i];
|
||||||
mydive->weightsystem[i].description = copy_string(displayed_dive.weightsystem[i].description);
|
mydive->weightsystem[i].description = copy_string(displayed_dive.weightsystem[i].description);
|
||||||
}
|
}
|
||||||
|
@ -1173,8 +1160,6 @@ void MainTab::on_visibility_valueChanged(int value)
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MODIFY_DIVES
|
#undef MODIFY_DIVES
|
||||||
#undef EDIT_TEXT
|
|
||||||
#undef EDIT_VALUE
|
|
||||||
|
|
||||||
void MainTab::editCylinderWidget(const QModelIndex &index)
|
void MainTab::editCylinderWidget(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
|
@ -1216,43 +1201,3 @@ void MainTab::clearTabs() {
|
||||||
}
|
}
|
||||||
clearEquipment();
|
clearEquipment();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SHOW_SELECTIVE(_component) \
|
|
||||||
if (what._component) \
|
|
||||||
ui._component->setText(displayed_dive._component);
|
|
||||||
|
|
||||||
void MainTab::showAndTriggerEditSelective(struct dive_components what)
|
|
||||||
{
|
|
||||||
// take the data in our copyPasteDive and apply it to selected dives
|
|
||||||
enableEdition();
|
|
||||||
copyPaste = true;
|
|
||||||
SHOW_SELECTIVE(buddy);
|
|
||||||
SHOW_SELECTIVE(divemaster);
|
|
||||||
SHOW_SELECTIVE(suit);
|
|
||||||
if (what.notes) {
|
|
||||||
QString tmp(displayed_dive.notes);
|
|
||||||
if (tmp.contains("<div")) {
|
|
||||||
tmp.replace(QString("\n"), QString("<br>"));
|
|
||||||
ui.notes->setHtml(tmp);
|
|
||||||
} else {
|
|
||||||
ui.notes->setPlainText(tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (what.rating)
|
|
||||||
ui.rating->setCurrentStars(displayed_dive.rating);
|
|
||||||
if (what.visibility)
|
|
||||||
ui.visibility->setCurrentStars(displayed_dive.visibility);
|
|
||||||
if (what.divesite)
|
|
||||||
ui.location->setCurrentDiveSite(displayed_dive.dive_site);
|
|
||||||
if (what.tags) {
|
|
||||||
ui.tagWidget->setText(get_taglist_string(displayed_dive.tag_list));
|
|
||||||
}
|
|
||||||
if (what.cylinders) {
|
|
||||||
cylindersModel->updateDive();
|
|
||||||
cylindersModel->changed = true;
|
|
||||||
}
|
|
||||||
if (what.weights) {
|
|
||||||
weightModel->updateDive();
|
|
||||||
weightModel->changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -55,7 +55,6 @@ public:
|
||||||
void updateCoordinatesText(qreal lat, qreal lon);
|
void updateCoordinatesText(qreal lat, qreal lon);
|
||||||
void refreshDisplayedDiveSite();
|
void refreshDisplayedDiveSite();
|
||||||
void nextInputField(QKeyEvent *event);
|
void nextInputField(QKeyEvent *event);
|
||||||
void showAndTriggerEditSelective(struct dive_components what);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void addDiveFinished();
|
void addDiveFinished();
|
||||||
|
@ -113,7 +112,6 @@ private:
|
||||||
TagCompletionModel tagModel;
|
TagCompletionModel tagModel;
|
||||||
Completers completers;
|
Completers completers;
|
||||||
bool modified;
|
bool modified;
|
||||||
bool copyPaste;
|
|
||||||
bool lastSelectedDive;
|
bool lastSelectedDive;
|
||||||
int lastTabSelectedDive;
|
int lastTabSelectedDive;
|
||||||
int lastTabSelectedDiveTrip;
|
int lastTabSelectedDiveTrip;
|
||||||
|
|
Loading…
Add table
Reference in a new issue