mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-28 05:00:20 +00:00
be2bdb8650
The undo stack is only relevant to the dives that were loaded at the time the command was executed. If a file is closed, by specifically closing it or opening another file, then the undo commands will reference dives that aren't available anymore. Clearing the undo stack ensures that we don't crash or accidentally do some undefined modifications to the currently open file. Signed-off-by: Michael Andreen <michael@andreen.dev>
117 lines
2.5 KiB
C++
117 lines
2.5 KiB
C++
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
#include "command.h"
|
|
#include "command_base.h"
|
|
#include "core/globals.h"
|
|
#include "core/qthelper.h" // for updateWindowTitle()
|
|
#include "core/subsurface-qt/divelistnotifier.h"
|
|
#include <QVector>
|
|
|
|
namespace Command {
|
|
|
|
static QUndoStack *undoStack;
|
|
|
|
// forward declaration
|
|
QString changesMade();
|
|
|
|
// General commands
|
|
void init()
|
|
{
|
|
undoStack = make_global<QUndoStack>();
|
|
QObject::connect(undoStack, &QUndoStack::cleanChanged, &updateWindowTitle);
|
|
QObject::connect(&diveListNotifier, &DiveListNotifier::dataReset, &Command::clear);
|
|
changesCallback = &changesMade;
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
undoStack->clear();
|
|
}
|
|
|
|
void setClean()
|
|
{
|
|
undoStack->setClean();
|
|
}
|
|
|
|
bool isClean()
|
|
{
|
|
return undoStack->isClean();
|
|
}
|
|
|
|
// this can be used to get access to the signals emitted by the QUndoStack
|
|
QUndoStack *getUndoStack()
|
|
{
|
|
return undoStack;
|
|
}
|
|
|
|
QAction *undoAction(QObject *parent)
|
|
{
|
|
return undoStack->createUndoAction(parent, QCoreApplication::translate("Command", "&Undo"));
|
|
}
|
|
|
|
QAction *redoAction(QObject *parent)
|
|
{
|
|
return undoStack->createRedoAction(parent, QCoreApplication::translate("Command", "&Redo"));
|
|
}
|
|
|
|
QString diveNumberOrDate(struct dive *d)
|
|
{
|
|
if (d->number != 0)
|
|
return QStringLiteral("#%1").arg(d->number);
|
|
else
|
|
return QStringLiteral("@%1").arg(get_short_dive_date_string(d->when));
|
|
}
|
|
|
|
QString getListOfDives(const std::vector<struct dive*> &dives)
|
|
{
|
|
QString listOfDives;
|
|
if ((int)dives.size() == dive_table.nr)
|
|
return Base::tr("all dives");
|
|
int i = 0;
|
|
for (dive *d: dives) {
|
|
// we show a maximum of five dive numbers, or 4 plus ellipsis
|
|
if (++i == 4 && dives.size() >= 5)
|
|
return listOfDives + "...";
|
|
listOfDives += diveNumberOrDate(d) + ", ";
|
|
}
|
|
if (!listOfDives.isEmpty())
|
|
listOfDives.truncate(listOfDives.length() - 2);
|
|
return listOfDives;
|
|
}
|
|
|
|
QString getListOfDives(QVector<struct dive *> dives)
|
|
{
|
|
return getListOfDives(std::vector<struct dive *>(dives.begin(), dives.end()));
|
|
}
|
|
|
|
// return a string that can be used for the commit message and should list the changes that
|
|
// were made to the dive list
|
|
QString changesMade()
|
|
{
|
|
QString changeTexts;
|
|
for (int i = 0; i < undoStack->index(); i++)
|
|
changeTexts += undoStack->text(i) + "\n";
|
|
return changeTexts;
|
|
}
|
|
|
|
static bool executingCommand = false;
|
|
bool execute(Base *cmd)
|
|
{
|
|
if (cmd->workToBeDone()) {
|
|
executingCommand = true;
|
|
undoStack->push(cmd);
|
|
executingCommand = false;
|
|
emit diveListNotifier.commandExecuted();
|
|
return true;
|
|
} else {
|
|
delete cmd;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool placingCommand()
|
|
{
|
|
return executingCommand;
|
|
}
|
|
|
|
} // namespace Command
|