Eclipse SUMO - Simulation of Urban MObility
GNEUndoList.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
15 // FXUndoList is pretty dandy but some features are missing:
16 // - we cannot find out wether we have currently begun an undo-group and
17 // thus abort() is hard to use.
18 // - onUpd-methods do not disable undo/redo while in an undo-group
19 //
20 // GNEUndoList inherits from FXUndoList and patches some methods. these are
21 // prefixed with p_
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
30 
31 #include "GNEApplicationWindow.h"
32 #include "GNEUndoList.h"
33 
34 
35 // ===========================================================================
36 // FOX callback mapping
37 // ===========================================================================
38 FXDEFMAP(GNEUndoList) GNEUndoListMap[] = {
39  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_REVERT, FXUndoList::onCmdRevert),
40  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_UNDO, FXUndoList::onCmdUndo),
41  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_REDO, FXUndoList::onCmdRedo),
42  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_UNDO_ALL, FXUndoList::onCmdUndoAll),
43  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_REDO_ALL, FXUndoList::onCmdRedoAll),
44  //
45  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_UNDO_COUNT, FXUndoList::onUpdUndoCount),
46  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REDO_COUNT, FXUndoList::onUpdRedoCount),
47  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_CLEAR, FXUndoList::onUpdClear),
48  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REVERT, FXUndoList::onUpdRevert),
49  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_UNDO_ALL, GNEUndoList::p_onUpdUndo),
50  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REDO_ALL, GNEUndoList::p_onUpdRedo),
51  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_UNDO, GNEUndoList::p_onUpdUndo),
52  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REDO, GNEUndoList::p_onUpdRedo)
53 };
54 
55 
56 // ===========================================================================
57 // FOX-declarations
58 // ===========================================================================
59 FXIMPLEMENT_ABSTRACT(GNEUndoList, FXUndoList, GNEUndoListMap, ARRAYNUMBER(GNEUndoListMap))
60 
61 
62 // ===========================================================================
63 // member method definitions
64 // ===========================================================================
65 
67  FXUndoList(),
68  myGNEApplicationWindowParent(parent) {
69 }
70 
71 
72 void
73 GNEUndoList::p_begin(const std::string& description) {
74  myCommandGroups.push(new CommandGroup(description));
75  begin(myCommandGroups.top());
76 }
77 
78 
79 void
81  myCommandGroups.pop();
82  end();
83 }
84 
85 
86 void
88  p_abort();
89  clear();
90 }
91 
92 
93 void
95  while (hasCommandGroup()) {
96  myCommandGroups.top()->undo();
97  myCommandGroups.pop();
98  abort();
99  }
100 }
101 
102 
103 void
105  if (myCommandGroups.size() > 0) {
106  myCommandGroups.top()->undo();
107  myCommandGroups.pop();
108  abort();
109  }
110 }
111 
112 
113 void
115  WRITE_DEBUG("Keys Ctrl + Z (Undo) pressed");
116  FXUndoList::undo();
117  // update specific controls
119 }
120 
121 
122 void
124  WRITE_DEBUG("Keys Ctrl + Y (Redo) pressed");
125  FXUndoList::redo();
126  // update specific controls
128 }
129 
130 
131 void
133  if (cmd->trueChange()) {
134  add(cmd, true);
135  } else {
136  delete cmd;
137  }
138 }
139 
140 
141 int
143  if (myCommandGroups.size() > 0) {
144  return myCommandGroups.top()->size();
145  } else {
146  return 0;
147  }
148 }
149 
150 
151 long
152 GNEUndoList::p_onUpdUndo(FXObject* sender, FXSelector, void*) {
153  // first check if Undo Menu command has to be disabled
154  bool enable = canUndo() && !hasCommandGroup() && myGNEApplicationWindowParent->isUndoRedoEnabled().empty();
155  sender->handle(this, enable ? FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE) : FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
156  // change caption of FXMenuCommand
157  FXString caption = undoName();
158  // set caption of FXmenuCommand edit/undo
160  caption = ("Cannot Undo in the middle of " + myGNEApplicationWindowParent->isUndoRedoEnabled()).c_str();
161  } else if (hasCommandGroup()) {
162  caption = ("Cannot Undo in the middle of " + myCommandGroups.top()->getDescription()).c_str();
163  } else if (!canUndo()) {
164  caption = "Undo";
165  }
166  // only set caption on menu item
167  if (dynamic_cast<FXMenuCommand*>(sender)) {
168  sender->handle(this, FXSEL(SEL_COMMAND, FXMenuCaption::ID_SETSTRINGVALUE), (void*)&caption);
169  }
170  return 1;
171 }
172 
173 
174 long
175 GNEUndoList::p_onUpdRedo(FXObject* sender, FXSelector, void*) {
176  // first check if Redo Menu command has to be disabled
177  bool enable = canRedo() && !hasCommandGroup() && myGNEApplicationWindowParent->isUndoRedoEnabled().empty();
178  // enable or disable depending of "enable" flag
179  sender->handle(this, enable ? FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE) : FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
180  // change caption of FXMenuCommand
181  FXString caption = redoName();
182  // set caption of FXmenuCommand edit/undo
184  caption = ("Cannot Redo in the middle of " + myGNEApplicationWindowParent->isUndoRedoEnabled()).c_str();
185  } else if (hasCommandGroup()) {
186  caption = ("Cannot Redo in the middle of " + myCommandGroups.top()->getDescription()).c_str();
187  } else if (!canRedo()) {
188  caption = "Redo";
189  }
190  // only set caption on menu item
191  if (dynamic_cast<FXMenuCommand*>(sender)) {
192  sender->handle(this, FXSEL(SEL_COMMAND, FXMenuCaption::ID_SETSTRINGVALUE), (void*)&caption);
193  }
194  return 1;
195 }
196 
197 
198 bool
200  return myCommandGroups.size() != 0;
201 }
202 
203 
204 GNEUndoList::CommandGroup::CommandGroup(std::string description) :
205  myDescription(description) {
206 }
207 
208 
209 const std::string&
211  return myDescription;
212 }
213 
214 
215 FXString
217  return ("Undo " + myDescription).c_str();
218 }
219 
220 
221 FXString
223  return ("Redo " + myDescription).c_str();
224 }
FXDEFMAP(GNEUndoList) GNEUndoListMap[]
const std::string & isUndoRedoEnabled() const
check if undo-redo is enabled
The main window of the Netedit.
const std::string myDescription
description of command
Definition: GNEUndoList.h:123
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:73
void redo()
redo the last command group
void updateControls()
update control contents after undo/redo or recompute
void undo()
undo the last command group
void p_clear()
clears the undo list (implies abort)
Definition: GNEUndoList.cpp:87
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
the function-object for an editing operation (abstract base)
bool trueChange()
wether original and new value differ
bool hasCommandGroup() const
Check if undoList has command group.
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise, the sub-group will be added as a new command into parent group. A matching begin() must have been called previously.
Definition: GNEUndoList.cpp:80
FXString redoName() const
get redo name
std::stack< CommandGroup * > myCommandGroups
Definition: GNEUndoList.h:127
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:246
int currentCommandGroupSize() const
get size of current CommandGroup
void p_abort()
reverts and discards ALL active command groups
Definition: GNEUndoList.cpp:94
void p_abortLastCommandGroup()
reverts last command group
long p_onUpdRedo(FXObject *, FXSelector, void *)
event after Redo
CommandGroup(std::string description)
Constructor.
GNEApplicationWindow *const myGNEApplicationWindowParent
Definition: GNEUndoList.h:130
FXString undoName() const
get undo Name
class CommandGroup
Definition: GNEUndoList.h:107
const std::string & getDescription()
get description
long p_onUpdUndo(FXObject *, FXSelector, void *)