Gui: Fix undo/redo behaviour in transformation tool

If the user clicks on undo while the transformation dialog is
open the currently active transaction will be closed.
From now on any change of the placement won't be recorded any
more so that e.g. canceling the dialog or an undo after
accepting the dialog leads to unexpected behaviour.

To fix the issue two new virtual methods onUndo() and onRedo()
are added to TaskDialog and reimplemented in TaskTransformDialog.
These functions make sure to open a new transaction.

This fixes issue 19152
This commit is contained in:
wmayer
2025-01-23 23:49:13 +01:00
committed by Ladislav Michl
parent 30ccf2ab26
commit c42dfe1ef3
6 changed files with 51 additions and 16 deletions

View File

@@ -728,16 +728,31 @@ void TaskTransformDialog::open()
Gui::TaskView::TaskDialog::open();
Gui::Application::Instance->activeDocument()->openCommand(
QT_TRANSLATE_NOOP("Command", "Transform"));
openCommand();
}
void TaskTransformDialog::openCommand()
{
if (auto document = vp->getDocument()) {
if (!document->hasPendingCommand()) {
document->openCommand(QT_TRANSLATE_NOOP("Command", "Transform"));
}
}
}
void TaskTransformDialog::onUndo()
{
openCommand();
}
void TaskTransformDialog::onRedo()
{
openCommand();
}
bool TaskTransformDialog::accept()
{
if (auto documentObject = vp->getObject()) {
Gui::Document* document =
Gui::Application::Instance->getDocument(documentObject->getDocument());
assert(document);
if (auto document = vp->getDocument()) {
document->commitCommand();
document->resetEdit();
document->getDocument()->recompute();
@@ -748,10 +763,7 @@ bool TaskTransformDialog::accept()
bool TaskTransformDialog::reject()
{
if (auto documentObject = vp->getObject()) {
Gui::Document* document =
Gui::Application::Instance->getDocument(documentObject->getDocument());
assert(document);
if (auto document = vp->getDocument()) {
document->abortCommand();
document->resetEdit();
document->getDocument()->recompute();

View File

@@ -166,6 +166,11 @@ public:
void open() override;
bool accept() override;
bool reject() override;
void onUndo() override;
void onRedo() override;
private:
void openCommand();
private:
ViewProviderDragger* vp;

View File

@@ -172,6 +172,16 @@ void TaskDialog::helpRequested()
}
void TaskDialog::onUndo()
{
}
void TaskDialog::onRedo()
{
}

View File

@@ -162,8 +162,12 @@ public:
virtual bool accept();
/// is called by the framework if the dialog is rejected (Cancel)
virtual bool reject();
/// is called by the framework if the user press the help button
/// is called by the framework if the user press the help button
virtual void helpRequested();
/// is called by the framework if the user press the undo button
virtual void onUndo();
/// is called by the framework if the user press the redo button
virtual void onRedo();
void emitDestructionSignal() {
Q_EMIT aboutToBeDestroyed();

View File

@@ -503,11 +503,15 @@ void TaskView::slotViewClosed(const Gui::MDIView* view)
}
}
void TaskView::transactionChangeOnDocument(const App::Document& doc)
void TaskView::transactionChangeOnDocument(const App::Document& doc, bool undo)
{
if (ActiveDialog) {
std::string name = ActiveDialog->getDocumentName();
if (name == doc.getName()) {
undo ? ActiveDialog->onUndo() : ActiveDialog->onRedo();
}
if (ActiveDialog->isAutoCloseOnTransactionChange()) {
std::string name = ActiveDialog->getDocumentName();
if (name.empty()) {
Base::Console().warning(std::string("TaskView::transactionChangeOnDocument"),
"No document name set\n");
@@ -527,12 +531,12 @@ void TaskView::transactionChangeOnDocument(const App::Document& doc)
void TaskView::slotUndoDocument(const App::Document& doc)
{
transactionChangeOnDocument(doc);
transactionChangeOnDocument(doc, true);
}
void TaskView::slotRedoDocument(const App::Document& doc)
{
transactionChangeOnDocument(doc);
transactionChangeOnDocument(doc, false);
}
/// @cond DOXERR

View File

@@ -187,7 +187,7 @@ private:
void slotViewClosed(const Gui::MDIView*);
void slotUndoDocument(const App::Document&);
void slotRedoDocument(const App::Document&);
void transactionChangeOnDocument(const App::Document&);
void transactionChangeOnDocument(const App::Document&, bool undo);
protected:
void keyPressEvent(QKeyEvent* event) override;