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 /****************************************************************************/
14 // FXUndoList is pretty dandy but some features are missing:
15 // - we cannot find out wether we have currently begun an undo-group and
16 // thus abort() is hard to use.
17 // - onUpd-methods do not disable undo/redo while in an undo-group
18 //
19 // GNEUndoList inherits from FXUndoList and patches some methods. these are
20 // prefixed with p_
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
29 
30 #include "GNEApplicationWindow.h"
31 #include "GNEUndoList.h"
32 
33 
34 // ===========================================================================
35 // FOX callback mapping
36 // ===========================================================================
37 FXDEFMAP(GNEUndoList) GNEUndoListMap[] = {
38  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_REVERT, FXUndoList::onCmdRevert),
39  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_UNDO, FXUndoList::onCmdUndo),
40  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_REDO, FXUndoList::onCmdRedo),
41  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_UNDO_ALL, FXUndoList::onCmdUndoAll),
42  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_REDO_ALL, FXUndoList::onCmdRedoAll),
43  //
44  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_UNDO_COUNT, FXUndoList::onUpdUndoCount),
45  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REDO_COUNT, FXUndoList::onUpdRedoCount),
46  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_CLEAR, FXUndoList::onUpdClear),
47  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REVERT, FXUndoList::onUpdRevert),
48  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_UNDO_ALL, GNEUndoList::p_onUpdUndo),
49  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REDO_ALL, GNEUndoList::p_onUpdRedo),
50  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_UNDO, GNEUndoList::p_onUpdUndo),
51  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REDO, GNEUndoList::p_onUpdRedo)
52 };
53 
54 
55 // ===========================================================================
56 // FOX-declarations
57 // ===========================================================================
58 FXIMPLEMENT_ABSTRACT(GNEUndoList, FXUndoList, GNEUndoListMap, ARRAYNUMBER(GNEUndoListMap))
59 
60 
61 // ===========================================================================
62 // member method definitions
63 // ===========================================================================
64 
66  FXUndoList(),
67  myGNEApplicationWindowParent(parent) {
68 }
69 
70 
71 void
72 GNEUndoList::p_begin(const std::string& description) {
73  myCommandGroups.push(new CommandGroup(description));
74  begin(myCommandGroups.top());
75 }
76 
77 
78 void
80  myCommandGroups.pop();
81  end();
82 }
83 
84 
85 void
87  p_abort();
88  clear();
89 }
90 
91 
92 void
94  while (hasCommandGroup()) {
95  myCommandGroups.top()->undo();
96  myCommandGroups.pop();
97  abort();
98  }
99 }
100 
101 
102 void
104  if (myCommandGroups.size() > 0) {
105  myCommandGroups.top()->undo();
106  myCommandGroups.pop();
107  abort();
108  }
109 }
110 
111 
112 void
114  WRITE_DEBUG("Calling GNEUndoList::undo()");
115  FXUndoList::undo();
116  // update specific controls
118 }
119 
120 
121 void
123  WRITE_DEBUG("Calling GNEUndoList::redo()");
124  FXUndoList::redo();
125  // update specific controls
127 }
128 
129 
130 void
132  if (cmd->trueChange()) {
133  add(cmd, true);
134  } else {
135  delete cmd;
136  }
137 }
138 
139 
140 int
142  if (myCommandGroups.size() > 0) {
143  return myCommandGroups.top()->size();
144  } else {
145  return 0;
146  }
147 }
148 
149 
150 long
151 GNEUndoList::p_onUpdUndo(FXObject* sender, FXSelector, void*) {
152  // first check if Undo Menu command or button has to be disabled
153  bool enable = canUndo() && !hasCommandGroup() && myGNEApplicationWindowParent->isUndoRedoEnabled().empty();
154  // cast button (see #6209)
155  FXButton* button = dynamic_cast<FXButton*>(sender);
156  // enable or disable depending of "enable" flag
157  if (button) {
158  // avoid unnnecesary enables/disables (due flickering)
159  if (enable && !button->isEnabled()) {
160  sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE), nullptr);
161  button->update();
162  } else if (!enable && button->isEnabled()) {
163  sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
164  button->update();
165  }
166  } else {
167  sender->handle(this, enable ? FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE) : FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
168  }
169  // cast menu command
170  FXMenuCommand* menuCommand = dynamic_cast<FXMenuCommand*>(sender);
171  // only set caption on menu command item
172  if (menuCommand) {
173  // change caption of FXMenuCommand
174  FXString caption = undoName();
175  // set caption of FXmenuCommand edit/undo
177  caption = ("Cannot Undo in the middle of " + myGNEApplicationWindowParent->isUndoRedoEnabled()).c_str();
178  } else if (hasCommandGroup()) {
179  caption = ("Cannot Undo in the middle of " + myCommandGroups.top()->getDescription()).c_str();
180  } else if (!canUndo()) {
181  caption = "Undo";
182  }
183  menuCommand->handle(this, FXSEL(SEL_COMMAND, FXMenuCaption::ID_SETSTRINGVALUE), (void*)&caption);
184  menuCommand->update();
185  }
186  return 1;
187 }
188 
189 
190 long
191 GNEUndoList::p_onUpdRedo(FXObject* sender, FXSelector, void*) {
192  // first check if Redo Menu command or button has to be disabled
193  bool enable = canRedo() && !hasCommandGroup() && myGNEApplicationWindowParent->isUndoRedoEnabled().empty();
194  // cast button (see #6209)
195  FXButton* button = dynamic_cast<FXButton*>(sender);
196  // enable or disable depending of "enable" flag
197  if (button) {
198  // avoid unnnecesary enables/disables (due flickering)
199  if (enable && !button->isEnabled()) {
200  sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE), nullptr);
201  button->update();
202  } else if (!enable && button->isEnabled()) {
203  sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
204  button->update();
205  }
206  } else {
207  sender->handle(this, enable ? FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE) : FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
208  }
209  // cast menu command
210  FXMenuCommand* menuCommand = dynamic_cast<FXMenuCommand*>(sender);
211  // only set caption on menu command item
212  if (menuCommand) {
213  // change caption of FXMenuCommand
214  FXString caption = redoName();
215  // set caption of FXmenuCommand edit/undo
217  caption = ("Cannot Redo in the middle of " + myGNEApplicationWindowParent->isUndoRedoEnabled()).c_str();
218  } else if (hasCommandGroup()) {
219  caption = ("Cannot Redo in the middle of " + myCommandGroups.top()->getDescription()).c_str();
220  } else if (!canRedo()) {
221  caption = "Redo";
222  }
223  menuCommand->handle(this, FXSEL(SEL_COMMAND, FXMenuCaption::ID_SETSTRINGVALUE), (void*)&caption);
224  menuCommand->update();
225  }
226  return 1;
227 }
228 
229 
230 bool
232  return myCommandGroups.size() != 0;
233 }
234 
235 
236 GNEUndoList::CommandGroup::CommandGroup(std::string description) :
237  myDescription(description) {
238 }
239 
240 
241 const std::string&
243  return myDescription;
244 }
245 
246 
247 FXString
249  return ("Undo " + myDescription).c_str();
250 }
251 
252 
253 FXString
255  return ("Redo " + myDescription).c_str();
256 }
GNEUndoList::p_clear
void p_clear()
clears the undo list (implies abort)
Definition: GNEUndoList.cpp:86
GNEUndoList::myGNEApplicationWindowParent
GNEApplicationWindow *const myGNEApplicationWindowParent
Definition: GNEUndoList.h:129
GNEUndoList::p_end
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
Definition: GNEUndoList.cpp:79
MsgHandler.h
GNEApplicationWindow::isUndoRedoEnabled
const std::string & isUndoRedoEnabled() const
check if undo-redo is enabled
Definition: GNEApplicationWindow.cpp:3219
GNEApplicationWindow
The main window of the Netedit.
Definition: GNEApplicationWindow.h:58
GNEUndoList::redo
void redo()
redo the last command group
Definition: GNEUndoList.cpp:122
GNEUndoList::CommandGroup::CommandGroup
CommandGroup(std::string description)
Constructor.
Definition: GNEUndoList.cpp:236
GNEUndoList::p_add
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
Definition: GNEUndoList.cpp:131
GNEUndoList::undo
void undo()
undo the last command group
Definition: GNEUndoList.cpp:113
GNEUndoList::myCommandGroups
std::stack< CommandGroup * > myCommandGroups
Definition: GNEUndoList.h:126
GNEUndoList::CommandGroup
class CommandGroup
Definition: GNEUndoList.h:106
GNEUndoList::CommandGroup::redoName
FXString redoName() const
get redo name
Definition: GNEUndoList.cpp:254
GNEChange_Attribute::trueChange
bool trueChange()
wether original and new value differ
Definition: GNEChange_Attribute.cpp:132
GNEApplicationWindow.h
FXDEFMAP
FXDEFMAP(GNEUndoList) GNEUndoListMap[]
GNEUndoList::p_abortLastCommandGroup
void p_abortLastCommandGroup()
reverts last command group
Definition: GNEUndoList.cpp:103
GNEUndoList::p_onUpdRedo
long p_onUpdRedo(FXObject *, FXSelector, void *)
event after Redo
Definition: GNEUndoList.cpp:191
GNEUndoList::p_abort
void p_abort()
reverts and discards ALL active command groups
Definition: GNEUndoList.cpp:93
GNEUndoList::currentCommandGroupSize
int currentCommandGroupSize() const
get size of current CommandGroup
Definition: GNEUndoList.cpp:141
GNEUndoList::hasCommandGroup
bool hasCommandGroup() const
Check if undoList has command group.
Definition: GNEUndoList.cpp:231
GNEUndoList::CommandGroup::getDescription
const std::string & getDescription()
get description
Definition: GNEUndoList.cpp:242
GNEUndoList::CommandGroup::undoName
FXString undoName() const
get undo Name
Definition: GNEUndoList.cpp:248
GNEApplicationWindow::updateControls
void updateControls()
update control contents after undo/redo or recompute
Definition: GNEApplicationWindow.cpp:3175
GNEChange_Attribute
the function-object for an editing operation (abstract base)
Definition: GNEChange_Attribute.h:47
GNEUndoList::p_onUpdUndo
long p_onUpdUndo(FXObject *, FXSelector, void *)
Definition: GNEUndoList.cpp:151
GNEUndoList
Definition: GNEUndoList.h:48
GNEUndoList::p_begin
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:72
WRITE_DEBUG
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:284
GNEChange_Attribute.h
GNEUndoList.h