File indexing completed on 2024-05-19 05:42:24

0001 // ct_lvtqtc_undo_manager.cpp                                       -*-C++-*-
0002 
0003 /*
0004 // Copyright 2023 Codethink Ltd <codethink@codethink.co.uk>
0005 // SPDX-License-Identifier: Apache-2.0
0006 //
0007 // Licensed under the Apache License, Version 2.0 (the "License");
0008 // you may not use this file except in compliance with the License.
0009 // You may obtain a copy of the License at
0010 //
0011 //     http://www.apache.org/licenses/LICENSE-2.0
0012 //
0013 // Unless required by applicable law or agreed to in writing, software
0014 // distributed under the License is distributed on an "AS IS" BASIS,
0015 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0016 // See the License for the specific language governing permissions and
0017 // limitations under the License.
0018 */
0019 
0020 #include <ct_lvtqtc_undo_manager.h>
0021 
0022 #include <QDockWidget>
0023 #include <QMainWindow>
0024 #include <QUndoCommand>
0025 #include <QUndoView>
0026 
0027 #include <QDebug>
0028 #include <QGraphicsView>
0029 #include <QObject>
0030 
0031 #include <unordered_map>
0032 
0033 using namespace Codethink::lvtqtc;
0034 
0035 struct UndoManager::Private {
0036     QUndoStack undoStack;
0037     QWidget *debugWidget = nullptr;
0038     QDockWidget *dock = nullptr;
0039 };
0040 
0041 UndoManager::UndoManager(): d(std::make_unique<UndoManager::Private>())
0042 {
0043     d->undoStack.clear();
0044     d->undoStack.setUndoLimit(1000);
0045 }
0046 
0047 UndoManager::~UndoManager() = default;
0048 
0049 void UndoManager::undoGroupRequested(const QString& groupName)
0050 {
0051     d->undoStack.beginMacro(groupName);
0052 }
0053 
0054 void UndoManager::addUndoCommand(QUndoCommand *command)
0055 {
0056     qDebug() << "Registering command" << command->actionText() << "on the undo stack";
0057     d->undoStack.push(command);
0058 }
0059 
0060 void UndoManager::undoGroupFinished()
0061 {
0062     d->undoStack.endMacro();
0063 }
0064 
0065 void UndoManager::undo()
0066 {
0067     if (d->undoStack.canUndo()) {
0068         const auto *command = d->undoStack.command(d->undoStack.index() - 1);
0069         Q_EMIT onBeforeUndo(command);
0070         qDebug() << "Undoing" << command->actionText();
0071         d->undoStack.undo();
0072     }
0073 }
0074 
0075 void UndoManager::redo()
0076 {
0077     if (d->undoStack.canRedo()) {
0078         const auto *command = d->undoStack.command(d->undoStack.index());
0079         Q_EMIT onBeforeRedo(command);
0080         qDebug() << "Redoing" << command->actionText();
0081         d->undoStack.redo();
0082     }
0083 }
0084 
0085 void UndoManager::clear()
0086 {
0087     d->undoStack.clear();
0088 }
0089 
0090 void UndoManager::createDock(QMainWindow *mainWindow)
0091 {
0092     d->dock = new QDockWidget();
0093     d->dock->setWindowTitle("Undo Stack");
0094     d->dock->setObjectName("UndoStack");
0095     mainWindow->addDockWidget(Qt::DockWidgetArea::RightDockWidgetArea, d->dock);
0096     auto *stackView = new QUndoView(&d->undoStack);
0097     d->dock->setWidget(stackView);
0098     d->debugWidget = stackView;
0099     d->dock->setVisible(false);
0100 }