mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
Undo: Implement undo of dive site name editing
Implement an undo command that edits the name of a dive site. Connect it to the dive site table, so that names can be edited directly in the table. Send signals on undo / redo so that the dive site table and the dive site edit widget can be updated. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
8e1f736d2b
commit
0e1b0cf1da
9 changed files with 97 additions and 2 deletions
|
@ -48,6 +48,7 @@ signals:
|
||||||
void diveSiteAdded(dive_site *ds, int idx);
|
void diveSiteAdded(dive_site *ds, int idx);
|
||||||
void diveSiteDeleted(dive_site *ds, int idx);
|
void diveSiteDeleted(dive_site *ds, int idx);
|
||||||
void diveSiteDiveCountChanged(dive_site *ds);
|
void diveSiteDiveCountChanged(dive_site *ds);
|
||||||
|
void diveSiteChanged(dive_site *ds, int field); // field according to LocationInformationModel
|
||||||
public:
|
public:
|
||||||
// Desktop uses the QTreeView class to present the list of dives. The layout
|
// Desktop uses the QTreeView class to present the list of dives. The layout
|
||||||
// of this class gives us a very fundamental problem, as we can not easily
|
// of this class gives us a very fundamental problem, as we can not easily
|
||||||
|
|
|
@ -83,4 +83,9 @@ void deleteDiveSites(const QVector <dive_site *> &sites)
|
||||||
execute(new DeleteDiveSites(sites));
|
execute(new DeleteDiveSites(sites));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void editDiveSiteName(dive_site *ds, const QString &value)
|
||||||
|
{
|
||||||
|
execute(new EditDiveSiteName(ds, value));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Command
|
} // namespace Command
|
||||||
|
|
|
@ -41,6 +41,7 @@ void mergeDives(const QVector <dive *> &dives);
|
||||||
// 3) Dive-site related commands
|
// 3) Dive-site related commands
|
||||||
|
|
||||||
void deleteDiveSites(const QVector <dive_site *> &sites);
|
void deleteDiveSites(const QVector <dive_site *> &sites);
|
||||||
|
void editDiveSiteName(dive_site *ds, const QString &value);
|
||||||
|
|
||||||
} // namespace Command
|
} // namespace Command
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "command_divesite.h"
|
#include "command_divesite.h"
|
||||||
#include "core/divesite.h"
|
#include "core/divesite.h"
|
||||||
#include "core/subsurface-qt/DiveListNotifier.h"
|
#include "core/subsurface-qt/DiveListNotifier.h"
|
||||||
|
#include "core/qthelper.h"
|
||||||
|
#include "qt-models/divelocationmodel.h"
|
||||||
|
|
||||||
namespace Command {
|
namespace Command {
|
||||||
|
|
||||||
|
@ -80,4 +82,29 @@ void DeleteDiveSites::undo()
|
||||||
sitesToRemove = std::move(addDiveSites(sitesToAdd));
|
sitesToRemove = std::move(addDiveSites(sitesToAdd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditDiveSiteName::EditDiveSiteName(dive_site *dsIn, const QString &name) : ds(dsIn),
|
||||||
|
value(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditDiveSiteName::workToBeDone()
|
||||||
|
{
|
||||||
|
return value != QString(ds->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditDiveSiteName::redo()
|
||||||
|
{
|
||||||
|
QString s = ds->name;
|
||||||
|
free(ds->name);
|
||||||
|
ds->name = copy_qstring(value);
|
||||||
|
value = s;
|
||||||
|
emit diveListNotifier.diveSiteChanged(ds, LocationInformationModel::NAME); // Inform frontend of changed dive site.
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditDiveSiteName::undo()
|
||||||
|
{
|
||||||
|
// Undo and redo do the same
|
||||||
|
redo();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Command
|
} // namespace Command
|
||||||
|
|
|
@ -16,14 +16,26 @@ public:
|
||||||
DeleteDiveSites(const QVector<dive_site *> &sites);
|
DeleteDiveSites(const QVector<dive_site *> &sites);
|
||||||
private:
|
private:
|
||||||
bool workToBeDone() override;
|
bool workToBeDone() override;
|
||||||
|
void undo() override;
|
||||||
|
void redo() override;
|
||||||
|
|
||||||
// For redo
|
// For redo
|
||||||
std::vector<dive_site *> sitesToRemove;
|
std::vector<dive_site *> sitesToRemove;
|
||||||
|
|
||||||
// For undo
|
// For undo
|
||||||
std::vector<OwningDiveSitePtr> sitesToAdd;
|
std::vector<OwningDiveSitePtr> sitesToAdd;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EditDiveSiteName : public Base {
|
||||||
|
public:
|
||||||
|
EditDiveSiteName(dive_site *ds, const QString &name);
|
||||||
|
private:
|
||||||
|
bool workToBeDone() override;
|
||||||
void undo() override;
|
void undo() override;
|
||||||
void redo() override;
|
void redo() override;
|
||||||
|
|
||||||
|
dive_site *ds;
|
||||||
|
QString value; // Value to be set
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Command
|
} // namespace Command
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "qt-models/filtermodels.h"
|
#include "qt-models/filtermodels.h"
|
||||||
#include "core/divesitehelpers.h"
|
#include "core/divesitehelpers.h"
|
||||||
#include "desktop-widgets/modeldelegates.h"
|
#include "desktop-widgets/modeldelegates.h"
|
||||||
|
#include "core/subsurface-qt/DiveListNotifier.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QShowEvent>
|
#include <QShowEvent>
|
||||||
|
@ -38,6 +39,8 @@ LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBo
|
||||||
connect(ui.diveSiteCoordinates, SIGNAL(returnPressed()), this, SLOT(updateLocationOnMap()));
|
connect(ui.diveSiteCoordinates, SIGNAL(returnPressed()), this, SLOT(updateLocationOnMap()));
|
||||||
ui.diveSiteCoordinates->installEventFilter(this);
|
ui.diveSiteCoordinates->installEventFilter(this);
|
||||||
|
|
||||||
|
connect(&diveListNotifier, &DiveListNotifier::diveSiteChanged, this, &LocationInformationWidget::diveSiteChanged);
|
||||||
|
|
||||||
ui.diveSiteListView->setModel(&filter_model);
|
ui.diveSiteListView->setModel(&filter_model);
|
||||||
ui.diveSiteListView->setModelColumn(LocationInformationModel::NAME);
|
ui.diveSiteListView->setModelColumn(LocationInformationModel::NAME);
|
||||||
ui.diveSiteListView->installEventFilter(this);
|
ui.diveSiteListView->installEventFilter(this);
|
||||||
|
@ -121,6 +124,18 @@ void LocationInformationWidget::updateLabels()
|
||||||
ui.locationTags->setText(constructLocationTags(&taxonomy, false));
|
ui.locationTags->setText(constructLocationTags(&taxonomy, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocationInformationWidget::diveSiteChanged(struct dive_site *ds, int field)
|
||||||
|
{
|
||||||
|
if (diveSite != ds)
|
||||||
|
return; // A different dive site was changed -> do nothing.
|
||||||
|
switch (field) {
|
||||||
|
case LocationInformationModel::NAME:
|
||||||
|
ui.diveSiteName->setText(diveSite->name);
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LocationInformationWidget::clearLabels()
|
void LocationInformationWidget::clearLabels()
|
||||||
{
|
{
|
||||||
ui.diveSiteName->clear();
|
ui.diveSiteName->clear();
|
||||||
|
|
|
@ -39,6 +39,7 @@ public slots:
|
||||||
private slots:
|
private slots:
|
||||||
void updateLabels();
|
void updateLabels();
|
||||||
void updateLocationOnMap();
|
void updateLocationOnMap();
|
||||||
|
void diveSiteChanged(struct dive_site *ds, int field);
|
||||||
signals:
|
signals:
|
||||||
void endEditDiveSite();
|
void endEditDiveSite();
|
||||||
void nameChanged(const QString &oldName, const QString &newName);
|
void nameChanged(const QString &oldName, const QString &newName);
|
||||||
|
|
|
@ -26,6 +26,7 @@ LocationInformationModel::LocationInformationModel(QObject *obj) : QAbstractTabl
|
||||||
connect(&diveListNotifier, &DiveListNotifier::diveSiteDiveCountChanged, this, &LocationInformationModel::diveSiteDiveCountChanged);
|
connect(&diveListNotifier, &DiveListNotifier::diveSiteDiveCountChanged, this, &LocationInformationModel::diveSiteDiveCountChanged);
|
||||||
connect(&diveListNotifier, &DiveListNotifier::diveSiteAdded, this, &LocationInformationModel::diveSiteAdded);
|
connect(&diveListNotifier, &DiveListNotifier::diveSiteAdded, this, &LocationInformationModel::diveSiteAdded);
|
||||||
connect(&diveListNotifier, &DiveListNotifier::diveSiteDeleted, this, &LocationInformationModel::diveSiteDeleted);
|
connect(&diveListNotifier, &DiveListNotifier::diveSiteDeleted, this, &LocationInformationModel::diveSiteDeleted);
|
||||||
|
connect(&diveListNotifier, &DiveListNotifier::diveSiteChanged, this, &LocationInformationModel::diveSiteChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
int LocationInformationModel::columnCount(const QModelIndex &) const
|
int LocationInformationModel::columnCount(const QModelIndex &) const
|
||||||
|
@ -173,6 +174,14 @@ void LocationInformationModel::diveSiteDeleted(struct dive_site *, int idx)
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocationInformationModel::diveSiteChanged(struct dive_site *ds, int field)
|
||||||
|
{
|
||||||
|
int idx = get_divesite_idx(ds, &dive_site_table);
|
||||||
|
if (idx < 0)
|
||||||
|
return;
|
||||||
|
dataChanged(createIndex(idx, field), createIndex(idx, field));
|
||||||
|
}
|
||||||
|
|
||||||
bool DiveSiteSortedModel::filterAcceptsRow(int sourceRow, const QModelIndex &source_parent) const
|
bool DiveSiteSortedModel::filterAcceptsRow(int sourceRow, const QModelIndex &source_parent) const
|
||||||
{
|
{
|
||||||
// TODO: filtering
|
// TODO: filtering
|
||||||
|
@ -223,14 +232,33 @@ QStringList DiveSiteSortedModel::allSiteNames() const
|
||||||
return locationNames;
|
return locationNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct dive_site *DiveSiteSortedModel::getDiveSite(const QModelIndex &idx)
|
||||||
|
{
|
||||||
|
return get_dive_site(mapToSource(idx).row(), &dive_site_table);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef SUBSURFACE_MOBILE
|
#ifndef SUBSURFACE_MOBILE
|
||||||
|
bool DiveSiteSortedModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
struct dive_site *ds = getDiveSite(index);
|
||||||
|
if (!ds || value.isNull())
|
||||||
|
return false;
|
||||||
|
switch (index.column()) {
|
||||||
|
case LocationInformationModel::NAME:
|
||||||
|
Command::editDiveSiteName(ds, value.toString());
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Remove from model. It doesn't make sense to call the model here, which calls the undo command,
|
// TODO: Remove from model. It doesn't make sense to call the model here, which calls the undo command,
|
||||||
// which in turn calls the model.
|
// which in turn calls the model.
|
||||||
void DiveSiteSortedModel::remove(const QModelIndex &index)
|
void DiveSiteSortedModel::remove(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
if (index.column() != LocationInformationModel::REMOVE)
|
if (index.column() != LocationInformationModel::REMOVE)
|
||||||
return;
|
return;
|
||||||
struct dive_site *ds = get_dive_site(mapToSource(index).row(), &dive_site_table);
|
struct dive_site *ds = getDiveSite(index);
|
||||||
if (!ds)
|
if (!ds)
|
||||||
return;
|
return;
|
||||||
if (ds->dives.nr > 0 &&
|
if (ds->dives.nr > 0 &&
|
||||||
|
@ -240,7 +268,7 @@ void DiveSiteSortedModel::remove(const QModelIndex &index)
|
||||||
return;
|
return;
|
||||||
Command::deleteDiveSites(QVector<dive_site *>{ds});
|
Command::deleteDiveSites(QVector<dive_site *>{ds});
|
||||||
}
|
}
|
||||||
#endif
|
#endif // SUBSURFACE_MOBILE
|
||||||
|
|
||||||
GeoReferencingOptionsModel *GeoReferencingOptionsModel::instance()
|
GeoReferencingOptionsModel *GeoReferencingOptionsModel::instance()
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,15 +35,20 @@ public slots:
|
||||||
void diveSiteDiveCountChanged(struct dive_site *ds);
|
void diveSiteDiveCountChanged(struct dive_site *ds);
|
||||||
void diveSiteAdded(struct dive_site *ds, int idx);
|
void diveSiteAdded(struct dive_site *ds, int idx);
|
||||||
void diveSiteDeleted(struct dive_site *ds, int idx);
|
void diveSiteDeleted(struct dive_site *ds, int idx);
|
||||||
|
void diveSiteChanged(struct dive_site *ds, int field);
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiveSiteSortedModel : public QSortFilterProxyModel {
|
class DiveSiteSortedModel : public QSortFilterProxyModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
|
struct dive_site *getDiveSite(const QModelIndex &idx);
|
||||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &source_parent) const override;
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &source_parent) const override;
|
||||||
bool lessThan(const QModelIndex &i1, const QModelIndex &i2) const override;
|
bool lessThan(const QModelIndex &i1, const QModelIndex &i2) const override;
|
||||||
|
#ifndef SUBSURFACE_MOBILE
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||||
public slots:
|
public slots:
|
||||||
void remove(const QModelIndex &index);
|
void remove(const QModelIndex &index);
|
||||||
|
#endif // SUBSURFACE_MOBILE
|
||||||
public:
|
public:
|
||||||
DiveSiteSortedModel();
|
DiveSiteSortedModel();
|
||||||
QStringList allSiteNames() const;
|
QStringList allSiteNames() const;
|
||||||
|
|
Loading…
Reference in a new issue