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));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pasteDives(const dive *d, dive_components what)
 | 
			
		||||
{
 | 
			
		||||
	execute(new PasteDives(d, what));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Command
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,6 +66,7 @@ void editDiveSiteNew(const QString &newName, bool currentDiveOnly);
 | 
			
		|||
void editTags(const QStringList &newList, bool currentDiveOnly);
 | 
			
		||||
void editBuddies(const QStringList &newList, bool currentDiveOnly);
 | 
			
		||||
void editDiveMaster(const QStringList &newList, bool currentDiveOnly);
 | 
			
		||||
void pasteDives(const dive *d, dive_components what);
 | 
			
		||||
 | 
			
		||||
} // namespace Command
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@
 | 
			
		|||
#include "command_private.h"
 | 
			
		||||
#include "core/divelist.h"
 | 
			
		||||
#include "core/qthelper.h" // for copy_qstring
 | 
			
		||||
#include "core/subsurface-string.h"
 | 
			
		||||
#include "desktop-widgets/mapwidget.h" // TODO: Replace desktop-dependency by signal
 | 
			
		||||
 | 
			
		||||
namespace Command {
 | 
			
		||||
| 
						 | 
				
			
			@ -598,4 +599,177 @@ DiveField EditDiveMaster::fieldId() const
 | 
			
		|||
	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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -211,6 +211,38 @@ public:
 | 
			
		|||
	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
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1802,9 +1802,7 @@ void MainWindow::on_copy_triggered()
 | 
			
		|||
 | 
			
		||||
void MainWindow::on_paste_triggered()
 | 
			
		||||
{
 | 
			
		||||
	// take the data in our copyPasteDive and apply it to selected dives
 | 
			
		||||
	selective_copy_dive(©PasteDive, &displayed_dive, what, false);
 | 
			
		||||
	mainTab->showAndTriggerEditSelective(what);
 | 
			
		||||
	Command::pasteDives(©PasteDive, what);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::on_actionFilterTags_triggered()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,6 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
 | 
			
		|||
	weightModel(new WeightModel(this)),
 | 
			
		||||
	cylindersModel(new CylindersModel(this)),
 | 
			
		||||
	editMode(NONE),
 | 
			
		||||
	copyPaste(false),
 | 
			
		||||
	lastSelectedDive(true),
 | 
			
		||||
	lastTabSelectedDive(0),
 | 
			
		||||
	lastTabSelectedDiveTrip(0),
 | 
			
		||||
| 
						 | 
				
			
			@ -288,7 +287,6 @@ void MainTab::enableEdition(EditMode newEditMode)
 | 
			
		|||
	if (((newEditMode == DIVE || newEditMode == NONE) && current_dive == NULL) || editMode != NONE)
 | 
			
		||||
		return;
 | 
			
		||||
	modified = false;
 | 
			
		||||
	copyPaste = false;
 | 
			
		||||
	if ((newEditMode == DIVE || newEditMode == NONE) &&
 | 
			
		||||
	    !isTripEdit &&
 | 
			
		||||
	    current_dive->dc.model &&
 | 
			
		||||
| 
						 | 
				
			
			@ -700,22 +698,11 @@ void MainTab::reload()
 | 
			
		|||
		mark_divelist_changed(true);                 \
 | 
			
		||||
	} 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
 | 
			
		||||
{
 | 
			
		||||
	return editMode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define EDIT_VALUE(what)                             \
 | 
			
		||||
	if (mydive->what == cd->what || copyPaste) { \
 | 
			
		||||
		mydive->what = displayed_dive.what;  \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
void MainTab::refreshDisplayedDiveSite()
 | 
			
		||||
{
 | 
			
		||||
	struct dive_site *ds = get_dive_site_for_dive(&displayed_dive);
 | 
			
		||||
| 
						 | 
				
			
			@ -812,7 +799,7 @@ void MainTab::acceptChanges()
 | 
			
		|||
			MODIFY_DIVES(selectedDives,
 | 
			
		||||
				for (int i = 0; i < MAX_CYLINDERS; i++) {
 | 
			
		||||
					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
 | 
			
		||||
							// 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)
 | 
			
		||||
| 
						 | 
				
			
			@ -855,7 +842,7 @@ void MainTab::acceptChanges()
 | 
			
		|||
			mark_divelist_changed(true);
 | 
			
		||||
			MODIFY_DIVES(selectedDives,
 | 
			
		||||
				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].description = copy_string(displayed_dive.weightsystem[i].description);
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -1173,8 +1160,6 @@ void MainTab::on_visibility_valueChanged(int value)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
#undef MODIFY_DIVES
 | 
			
		||||
#undef EDIT_TEXT
 | 
			
		||||
#undef EDIT_VALUE
 | 
			
		||||
 | 
			
		||||
void MainTab::editCylinderWidget(const QModelIndex &index)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1216,43 +1201,3 @@ void MainTab::clearTabs() {
 | 
			
		|||
	}
 | 
			
		||||
	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 refreshDisplayedDiveSite();
 | 
			
		||||
	void nextInputField(QKeyEvent *event);
 | 
			
		||||
	void showAndTriggerEditSelective(struct dive_components what);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
	void addDiveFinished();
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +112,6 @@ private:
 | 
			
		|||
	TagCompletionModel tagModel;
 | 
			
		||||
	Completers completers;
 | 
			
		||||
	bool modified;
 | 
			
		||||
	bool copyPaste;
 | 
			
		||||
	bool lastSelectedDive;
 | 
			
		||||
	int lastTabSelectedDive;
 | 
			
		||||
	int lastTabSelectedDiveTrip;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue