/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GNEUndoList.h14/// @author Jakob Erdmann15/// @author Pablo Alvarez Lopez16/// @date Mar 201117///18/****************************************************************************/19#pragma once20#include <config.h>2122#include <stack>23#include <string>2425#include <netedit/changes/GNEChangeGroup.h>262728// ===========================================================================29// class declarations30// ===========================================================================31class GNEChange;32class GNEChange_Attribute;33class GNEApplicationWindow;3435// ===========================================================================36// class definitions37// ===========================================================================38/**39* @class GNEUndoList40*/41class GNEUndoList : public GNEChangeGroup {42/// @brief FOX declaration43FXDECLARE_ABSTRACT(GNEUndoList)4445public:46/// @brief iterator47class Iterator {4849public:50/// @brief destructor51~Iterator();5253/// @brief check if iterator is at the end54bool end() const;5556/// @brief get index57int getIndex() const;5859/// @brief get description60const std::string getDescription() const;6162/// @brief get timeStamp63const std::string getTimeStamp() const;6465/// @brief get icon66FXIcon* getIcon() const;6768/// @brief increment operator69Iterator& operator++(int);7071protected:72/// @brief constructor for GNEUndoList73Iterator(GNEChange* change);7475private:76/// @brief default constructor77Iterator();7879/// @brief current change80GNEChange* myCurrentChange;8182/// @brief counter83int myIndex;84};8586/// @brief undo iterator87class UndoIterator : public Iterator {8889public:90/// @brief constructor for GNEUndoList91UndoIterator(const GNEUndoList* undoList);92};9394/// @brief redo iterator95class RedoIterator : public Iterator {9697public:98/// @brief constructor for GNEUndoList99RedoIterator(const GNEUndoList* undoList);100};101102/// @brief constructor103GNEUndoList(GNEApplicationWindow* parent);104105/// @brief destructor106~GNEUndoList();107108/// @brief undo the last command group109void undo();110111/// @brief redo the last command group112void redo();113114/**@brief Return name of the first undo command available; if no115* undo command available this will return the empty string.116*/117std::string undoName() const;118119/**@brief Return name of the first redo command available; if no120* Redo command available this will return the empty string.121*/122std::string redoName() const;123124/**@brief Begin undo command sub-group with current supermode.125* This begins a new group of commands that126* are treated as a single command. Must eventually be followed by a127* matching end() after recording the sub-commands. The new sub-group128* will be appended to its parent group's undo list when end() is called.129*/130void begin(GUIIcon icon, const std::string& description);131132/**@brief Begin undo command sub-group with current supermode. (used for ACs133* This begins a new group of commands that134* are treated as a single command. Must eventually be followed by a135* matching end() after recording the sub-commands. The new sub-group136* will be appended to its parent group's undo list when end() is called.137*/138void begin(const GNEAttributeCarrier* AC, const std::string& description);139140/**@brief Begin undo command sub-group specifying supermode.141* This begins a new group of commands that142* are treated as a single command. Must eventually be followed by a143* matching end() after recording the sub-commands. The new sub-group144* will be appended to its parent group's undo list when end() is called.145*/146void begin(Supermode supermode, GUIIcon icon, const std::string& description);147148/**@brief End undo command sub-group. If the sub-group is still empty, it will149* be deleted; otherwise, the sub-group will be added as a new command150* into parent group.151* @note A matching begin() must have been called previously.152*/153void end();154155/**@brief Add new command, executing it if desired. The new command will be merged156* with the previous command if merge is TRUE and we're not at a marked position157* and the commands are mergeable. Otherwise the new command will be appended158* after the last undo command in the currently active undo group.159* If the new command is successfully merged, it will be deleted. Furthermore,160* all redo commands will be deleted since it is no longer possible to redo161* from this point.162*/163void add(GNEChange* command, bool doit = false, bool merge = true);164165/* @brief clears the undo list (implies abort)166* All undo and redo information will be destroyed.167*/168void clear();169170/// @brief reverts and discards ALL active chained change groups171void abortAllChangeGroups();172173/// @brief reverts last active chained change group174void abortLastChangeGroup();175176/// @brief get size of current CommandGroup177int currentCommandGroupSize() const;178179/// @brief get undo supermode180Supermode getUndoSupermode() const;181182/// @brief get redo supermode183Supermode getRedoSupermode() const;184185/// @brief Check if undoList has command group186bool hasCommandGroup() const;187188/**@brief Return TRUE if currently inside undo or redo operation; this189* is useful to avoid generating another undo command while inside190* an undo operation.191*/192bool busy() const;193194/// @name FOX-callbacks195/// @{196/// @brief undo change197long onCmdUndo(FXObject*, FXSelector, void*);198199/// @brief event after Undo200long onUpdUndo(FXObject*, FXSelector, void*);201202/// @brief redo change203long onCmdRedo(FXObject*, FXSelector, void*);204205/// @brief event after Redo206long onUpdRedo(FXObject*, FXSelector, void*);207/// @}208209protected:210/**@brief Cut the redo list.211* This is automatically invoked when a new undo command is added.212*/213void cut();214215/** @brief Abort the current command sub-group being compiled. All commands216* already added to the sub-groups undo list will be discarded.217* Intermediate command groups will be left intact.218*/219void abortCurrentSubGroup();220221///@brief Can we undo more commands222bool canUndo() const;223224///@brief Can we redo more commands225bool canRedo() const;226227private:228/// @brief Currently busy with undo or redo229bool myWorking;230231// @brief the stack of currently active change groups232std::stack<GNEChangeGroup*> myChangeGroups;233234// @brief the parent GNEApplicationWindow for this undolist235GNEApplicationWindow* const myGNEApplicationWindowParent;236};237238239