Version: 8.3.0
commands.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 
20 #include "commands.hxx"
21 #include "guiContext.hxx"
22 #include "Proc.hxx"
23 #include "Catalog.hxx"
24 #include "RuntimeSALOME.hxx"
25 
26 //#define _DEVDEBUG_
27 #include "YacsTrace.hxx"
28 #include <sstream>
29 
30 using namespace std;
31 
32 using namespace YACS;
33 using namespace YACS::HMI;
34 
35 int Invocator::_ctr = 0;
36 
37 Command::Command()
38 {
39  _subCommands.clear();
40  _normalReverse = true;
41 }
42 
44 
51 bool Command::execute()
52 {
53  if ( !GuiContext::getCurrent() || !GuiContext::getCurrent()->getInvoc() )
54  return false;
55 
56  bool commandInProgress = !GuiContext::getCurrent()->getInvoc()->isSpecialReverse();
57  if (commandInProgress)
58  GuiContext::getCurrent()->getInvoc()->_commandsInProgress.push_back(this);
59 
60  bool ret=true;
61  if (GuiContext::getCurrent()->getInvoc()->_isRedo && _normalReverse)
62  {
63  for (int i=0; i<_subCommands.size(); i++)
64  delete _subCommands[i];
65  _subCommands.clear();
66  }
67  ret = localExecute();
68  if (ret) GuiContext::getCurrent()->setNotSaved(true);
69 
70  if (commandInProgress)
71  GuiContext::getCurrent()->getInvoc()->_commandsInProgress.pop_back();
72  return ret;
73 }
74 
76 
79 bool Command::reverse(bool isNormal)
80 {
81  bool ret=true;
82  if (! _subCommands.empty())
83  {
84  for (int i=0; i<_subCommands.size(); i++)
85  {
86  ret =_subCommands[i]->reverse(isNormal);
87  if (!ret) break;
88  }
89  }
90  if (ret)
91  {
92  if (isNormal) // true for all commands but commandDestroy
93  ret = localReverse();
94  else
95  ret = localExecute(); // subCommand of command Destroy
96  }
97  return ret;
98 }
99 
101 
105 bool Command::executeSubOnly()
106 {
107  bool ret=true;
108  if (! _subCommands.empty())
109  {
110  for (int i=0; i<_subCommands.size(); i++)
111  {
112  ret =_subCommands[i]->reverse(false);
113  if (!ret) break;
114  }
115  }
116  return ret;
117 }
118 
119 std::string Command::dump()
120 {
121  return "=== generic command dump ===";
122 }
123 
124 std::string Command::recursiveDump(int level)
125 {
126  string prefix = "";
127  for (int i=0; i<level; i++) prefix += " ";
128  string ret = prefix + dump() + "\n";
129  for (int i=0; i<_subCommands.size(); i++)
130  ret += _subCommands[i]->recursiveDump(level+1);
131  return ret;
132 }
133 
134 void Command::addSubCommand(Command* command)
135 {
136  _subCommands.push_back(command);
137 }
138 
139 
140 
141 
142 
143 Invocator::Invocator()
144 {
145  _commandsDone.clear();
146  _commandsUndone.clear();
147  _commandsInProgress.clear();
148  _isRedo = false;
149  _isUndo = false;
150  _specialReverse = false;
151  _undoCata = new YACS::ENGINE::Catalog("undoCata");
153  _undoProc= runTime->createProc("undoProc");
154 }
155 
156 void Invocator::add(Command* command)
157 {
158  DEBTRACE("Invocator::add");
159  if(_isUndo)
160  return;
161  if (GuiContext::getCurrent()->getInvoc()->isSpecialReverse())
162  {
163  delete command;
164  return;
165  }
166  if (_commandsInProgress.empty())
167  {
168  _commandsDone.push_back(command); // --- to do after execute ok
169  _commandsUndone.clear(); // --- undone stack is no more relevant
170  }
171  else
172  {
173  DEBTRACE("addSubCommand");
174  _commandsInProgress.back()->addSubCommand(command);
175  }
176 }
177 
178 bool Invocator::undo()
179 {
180  DEBTRACE("Invocator::undo");
181  bool ret = true;
182 
183  {
184  stringstream ret1;
185  ret1 << "_commandsDone" << endl;
186  for (int i=0; i<_commandsDone.size(); i++)
187  ret1 << i << _commandsDone[i]->recursiveDump(2);
188  DEBTRACE(ret1.str());
189  stringstream ret2;
190  ret2 << "_commandsUndone" << endl;
191  for (int i=0; i<_commandsUndone.size(); i++)
192  ret2 << i << _commandsUndone[i]->recursiveDump(2);
193  DEBTRACE(ret2.str());
194  }
195 
196  if (! _commandsDone.empty())
197  {
198  bool isNormal = _commandsDone.back()->isNormalReverse();
199  _specialReverse = !isNormal;
200  _isUndo=true;
201  if (isNormal)
202  ret = _commandsDone.back()->reverse(isNormal);
203  else
204  ret = _commandsDone.back()->executeSubOnly();
205  _isUndo=false;
206  _commandsUndone.push_back(_commandsDone.back());
207  _commandsDone.pop_back();
208  _specialReverse = false;
209  }
210 
211  {
212  stringstream ret1;
213  ret1 << "_commandsDone" << endl;
214  for (int i=0; i<_commandsDone.size(); i++)
215  ret1 << i << _commandsDone[i]->recursiveDump(2);
216  DEBTRACE(ret1.str());
217  stringstream ret2;
218  ret2 << "_commandsUndone" << endl;
219  for (int i=0; i<_commandsUndone.size(); i++)
220  ret2 << i << _commandsUndone[i]->recursiveDump(2);
221  DEBTRACE(ret2.str());
222  }
223 
224  return ret;
225 }
226 
227 bool Invocator::redo()
228 {
229  DEBTRACE("Invocator::redo");
230  bool ret = true;
231 
232  {
233  stringstream ret1;
234  ret1 << "_commandsDone" << endl;
235  for (int i=0; i<_commandsDone.size(); i++)
236  ret1 << i << _commandsDone[i]->recursiveDump(2);
237  DEBTRACE(ret1.str());
238  stringstream ret2;
239  ret2 << "_commandsUndone" << endl;
240  for (int i=0; i<_commandsUndone.size(); i++)
241  ret2 << i << _commandsUndone[i]->recursiveDump(2);
242  DEBTRACE(ret2.str());
243  }
244 
245  if (! _commandsUndone.empty())
246  {
247  _isRedo=true;
248  ret = _commandsUndone.back()->execute();
249  _isRedo=false;
250  _commandsDone.push_back(_commandsUndone.back());
251  _commandsUndone.pop_back();
252  }
253 
254  {
255  stringstream ret1;
256  ret1 << "_commandsDone" << endl;
257  for (int i=0; i<_commandsDone.size(); i++)
258  ret1 << i << _commandsDone[i]->recursiveDump(2);
259  DEBTRACE(ret1.str());
260  stringstream ret2;
261  ret2 << "_commandsUndone" << endl;
262  for (int i=0; i<_commandsUndone.size(); i++)
263  ret2 << i << _commandsUndone[i]->recursiveDump(2);
264  DEBTRACE(ret2.str());
265  }
266 
267  return ret;
268 }
269 
270 std::list<std::string> Invocator::getDone()
271 {
272  list<string> listDone;
273  listDone.clear();
274  for (int i=0; i<_commandsDone.size(); i++)
275  listDone.push_back(_commandsDone[i]->recursiveDump());
276  return listDone;
277 }
278 
279 std::list<std::string> Invocator::getUndone()
280 {
281  list<string> listUndone;
282  listUndone.clear();
283  for (int i=0; i<_commandsUndone.size(); i++)
284  listUndone.push_back(_commandsUndone[i]->recursiveDump());
285  return listUndone;
286 }