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-2018 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 // ===========================================================================
28 #include <config.h>
29 
30 #include <iostream>
34 
35 #include "GNEUndoList.h"
37 #include "GNEApplicationWindow.h"
38 
39 
40 // ===========================================================================
41 // FOX callback mapping
42 // ===========================================================================
43 FXDEFMAP(GNEUndoList) GNEUndoListMap[] = {
44  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_REVERT, FXUndoList::onCmdRevert),
45  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_UNDO, FXUndoList::onCmdUndo),
46  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_REDO, FXUndoList::onCmdRedo),
47  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_UNDO_ALL, FXUndoList::onCmdUndoAll),
48  //FXMAPFUNC(SEL_COMMAND, FXUndoList::ID_REDO_ALL, FXUndoList::onCmdRedoAll),
49  //
50  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_UNDO_COUNT, FXUndoList::onUpdUndoCount),
51  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REDO_COUNT, FXUndoList::onUpdRedoCount),
52  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_CLEAR, FXUndoList::onUpdClear),
53  //FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REVERT, FXUndoList::onUpdRevert),
54  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_UNDO_ALL, GNEUndoList::p_onUpdUndo),
55  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REDO_ALL, GNEUndoList::p_onUpdRedo),
56  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_UNDO, GNEUndoList::p_onUpdUndo),
57  FXMAPFUNC(SEL_UPDATE, FXUndoList::ID_REDO, GNEUndoList::p_onUpdRedo)
58 };
59 
60 
61 // ===========================================================================
62 // FOX-declarations
63 // ===========================================================================
64 FXIMPLEMENT_ABSTRACT(GNEUndoList, FXUndoList, GNEUndoListMap, ARRAYNUMBER(GNEUndoListMap))
65 
66 
67 // ===========================================================================
68 // member method definitions
69 // ===========================================================================
70 
72  FXUndoList(),
73  myParent(parent) {
74 }
75 
76 
77 void
78 GNEUndoList::p_begin(const std::string& description) {
79  myCommandGroups.push(new CommandGroup(description));
80  begin(myCommandGroups.top());
81 }
82 
83 
84 void
86  myCommandGroups.pop();
87  end();
88 }
89 
90 
91 void
93  p_abort();
94  clear();
95 }
96 
97 
98 void
100  while (hasCommandGroup()) {
101  myCommandGroups.top()->undo();
102  myCommandGroups.pop();
103  abort();
104  }
105 }
106 
107 
108 void
110  if (myCommandGroups.size() > 0) {
111  myCommandGroups.top()->undo();
112  myCommandGroups.pop();
113  abort();
114  }
115 }
116 
117 
118 void
120  //std::cout << undoName().text() << "\n";
121  WRITE_DEBUG("Keys Ctrl + Z (Undo) pressed");
122  FXUndoList::undo();
124 }
125 
126 
127 void
129  //std::cout << redoName().text() << "\n";
130  //std::cout << undoName().text() << "\n";
131  WRITE_DEBUG("Keys Ctrl + Y (Redo) pressed");
132  FXUndoList::redo();
134 }
135 
136 
137 void
139  if (cmd->trueChange()) {
140  add(cmd, true);
141  } else {
142  delete cmd;
143  }
144 }
145 
146 
147 int
149  if (myCommandGroups.size() > 0) {
150  return myCommandGroups.top()->size();
151  } else {
152  return 0;
153  }
154 }
155 
156 
157 long
158 GNEUndoList::p_onUpdUndo(FXObject* sender, FXSelector, void*) {
159  bool enable = canUndo() && !hasCommandGroup();
160  sender->handle(this, enable ? FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE) : FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), 0);
161  FXString caption = undoName();
162  if (hasCommandGroup()) {
163  caption = ("Cannot Undo in the middle of " + myCommandGroups.top()->getDescription()).c_str();
164  } else if (!canUndo()) {
165  caption = "Undo";
166  }
167  // only set caption on menu item
168  if (dynamic_cast<FXMenuCommand*>(sender)) {
169  sender->handle(this, FXSEL(SEL_COMMAND, FXMenuCaption::ID_SETSTRINGVALUE), (void*)&caption);
170  }
171  return 1;
172 }
173 
174 
175 long
176 GNEUndoList::p_onUpdRedo(FXObject* sender, FXSelector, void*) {
177  bool enable = canRedo() && !hasCommandGroup();
178  sender->handle(this, enable ? FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE) : FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), 0);
179  FXString caption = redoName();
180  if (hasCommandGroup()) {
181  caption = ("Cannot Redo in the middle of " + myCommandGroups.top()->getDescription()).c_str();
182  } else if (!canRedo()) {
183  caption = "Redo";
184  }
185  // only set caption on menu item
186  if (dynamic_cast<FXMenuCommand*>(sender)) {
187  sender->handle(this, FXSEL(SEL_COMMAND, FXMenuCaption::ID_SETSTRINGVALUE), (void*)&caption);
188  }
189  return 1;
190 }
191 
192 
193 bool
195  return myCommandGroups.size() != 0;
196 }
197 
198 
199 GNEUndoList::CommandGroup::CommandGroup(std::string description) :
200  myDescription(description) {
201 }
202 
203 
204 const std::string&
206  return myDescription;
207 }
208 
209 
210 FXString
212  return ("Undo " + myDescription).c_str();
213 }
214 
215 
216 FXString
218  return ("Redo " + myDescription).c_str();
219 }
FXDEFMAP(GNEUndoList) GNEUndoListMap[]
The main window of the Netedit.
const std::string myDescription
description of command
Definition: GNEUndoList.h:122
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:78
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:92
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:85
FXString redoName() const
get redo name
std::stack< CommandGroup * > myCommandGroups
Definition: GNEUndoList.h:126
GNEApplicationWindow *const myParent
Definition: GNEUndoList.h:129
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:249
int currentCommandGroupSize() const
get size of current CommandGroup
void p_abort()
reverts and discards ALL active command groups
Definition: GNEUndoList.cpp:99
void p_abortLastCommandGroup()
reverts last command group
long p_onUpdRedo(FXObject *, FXSelector, void *)
event after Redo
CommandGroup(std::string description)
Constructor.
FXString undoName() const
get undo Name
class CommandGroup
Definition: GNEUndoList.h:106
const std::string & getDescription()
get description
long p_onUpdUndo(FXObject *, FXSelector, void *)