Salome HOME
b5293088470231c9f3262d2f5d48713148e69c64
[modules/geom.git] / src / CurveCreator / CurveCreator_CurveEditor.cxx
1 // Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
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.
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 // File:        CurveCreator_CurveEditor.cxx
21 // Author:      Sergey KHROMOV
22
23 #include "CurveCreator_CurveEditor.hxx"
24
25 //=======================================================================
26 // function: Constructor
27 // purpose:
28 //=======================================================================
29 CurveCreator_CurveEditor::CurveCreator_CurveEditor
30                                 (CurveCreator_Curve* thePCurve)
31  : myNbUndos   (0),
32    myNbRedos   (0),
33    myPCurve    (thePCurve),
34    myUndoDepth (-1),
35    myOpLevel(0)
36 {
37   if (myPCurve != NULL) {
38     if (myPCurve->isLocked()) {
39       // This curve is locked by another editor. Invalid case.
40       myPCurve = NULL;
41     } else {
42       // Lock the curve.
43       myPCurve->myIsLocked = true;
44       myCurrenPos = myListDiffs.end();
45     }
46   }
47 }
48
49 //=======================================================================
50 // function: Destructor
51 // purpose:
52 //=======================================================================
53 CurveCreator_CurveEditor::~CurveCreator_CurveEditor()
54 {
55   if (myPCurve != NULL) {
56     // Unlock the curve.
57     myPCurve->myIsLocked = false;
58   }
59 }
60
61 //=======================================================================
62 // function: getCurve
63 // purpose:
64 //=======================================================================
65 CurveCreator_Curve *CurveCreator_CurveEditor::getCurve() const
66 {
67   return myPCurve;
68 }
69
70 //=======================================================================
71 // function: isAttached
72 // purpose:
73 //=======================================================================
74 bool CurveCreator_CurveEditor::isAttached() const
75 {
76   return (myPCurve != NULL);
77 }
78
79 //=======================================================================
80 // function: undo
81 // purpose:
82 //=======================================================================
83 void CurveCreator_CurveEditor::undo()
84 {
85   if (myNbUndos > 0) {
86     myNbUndos--;
87     myNbRedos++;
88     myCurrenPos--;
89     myCurrenPos->applyUndo(myPCurve);
90   }
91 }
92
93 //=======================================================================
94 // function: redo
95 // purpose:
96 //=======================================================================
97 void CurveCreator_CurveEditor::redo()
98 {
99   if (myNbRedos > 0) {
100     myCurrenPos->applyRedo(myPCurve);
101     myCurrenPos++;
102     myNbRedos--;
103     myNbUndos++;
104   }
105 }
106
107 //=======================================================================
108 // function: getNbUndo
109 // purpose:
110 //=======================================================================
111 int CurveCreator_CurveEditor::getNbUndo() const
112 {
113   return myNbUndos;
114 }
115
116 //=======================================================================
117 // function: getNbRedo
118 // purpose:
119 //=======================================================================
120 int CurveCreator_CurveEditor::getNbRedo() const
121 {
122   return myNbRedos;
123 }
124
125 //=======================================================================
126 // function: setUndoDepth
127 // purpose:
128 //=======================================================================
129 void CurveCreator_CurveEditor::setUndoDepth(const int theDepth)
130 {
131   if (theDepth == 0) {
132     // Reset all undo/redo data.
133     myNbUndos = 0;
134     myNbRedos = 0;
135     myListDiffs.clear();
136     myCurrenPos = myListDiffs.end();
137     myUndoDepth = 0;
138   } else if (theDepth == -1) {
139     // There is nothing to do as the depth become unlimited.
140     myUndoDepth = -1;
141   } else if (theDepth > 0) {
142     // The new "real" depth is set.
143     if (theDepth < myNbRedos) {
144       // The new depth is less then number of redos. Remove the latest redos.
145       int aShift = (myNbRedos - theDepth);
146       ListDiff::iterator aFromPos = myListDiffs.end();
147
148       while (aShift--) {
149         aFromPos--;
150       }
151
152       myListDiffs.erase(aFromPos, myListDiffs.end());
153       myNbRedos = theDepth;
154     }
155
156     if (theDepth < myNbUndos + myNbRedos) {
157       // The new depth is less then the total number of differences.
158       // Remove the first undos.
159       int aShift = (myNbUndos + myNbRedos - theDepth);
160       ListDiff::iterator aToPos = myListDiffs.begin();
161
162       while (aShift--) {
163         aToPos++;
164       }
165
166       myListDiffs.erase(myListDiffs.begin(), aToPos);
167       myNbUndos = theDepth - myNbRedos;
168     }
169
170     myUndoDepth = theDepth;
171   }
172 }
173
174 //=======================================================================
175 // function: getUndoDepth
176 // purpose:
177 //=======================================================================
178 int CurveCreator_CurveEditor::getUndoDepth() const
179 {
180   return myUndoDepth;
181 }
182
183 //=======================================================================
184 // function: setType
185 // purpose:
186 //=======================================================================
187 void CurveCreator_CurveEditor::setType(const CurveCreator::Type theType,
188                                        const int theISection)
189 {
190   if (myPCurve != NULL) {
191     startOperation();
192     // Set the difference.
193     if (addEmptyDiff()) {
194       myListDiffs.back().init(myPCurve, CurveCreator_Operation::SetType,
195                               theType, theISection);
196     }
197
198     // Update the curve.
199     myPCurve->setType(theType, theISection);
200     finishOperation();
201   }
202 }
203
204 //=======================================================================
205 // function: addPoints
206 // purpose:
207 //=======================================================================
208 void CurveCreator_CurveEditor::addPoints
209                       (const CurveCreator::Coordinates &thePoints,
210                        const int theISection)
211 {
212   if (myPCurve != NULL) {
213     // Set the difference.
214     startOperation();
215     if (addEmptyDiff()) {
216       myListDiffs.back().init(myPCurve, CurveCreator_Operation::AddPoints,
217                               thePoints, theISection);
218     }
219
220     // Update the curve.
221     myPCurve->addPoints(thePoints, theISection);
222     finishOperation();
223   }
224 }
225
226 //=======================================================================
227 // function: addSection
228 // purpose:
229 //=======================================================================
230 void CurveCreator_CurveEditor::addSection
231         (const std::string& theName, const CurveCreator::Type theType,
232          const bool theIsClosed,
233          const CurveCreator::Coordinates &thePoints)
234 {
235   if (myPCurve != NULL) {
236     // Set the difference.
237     startOperation();
238     if (addEmptyDiff()) {
239       myListDiffs.back().init(myPCurve, CurveCreator_Operation::AddSection,
240                               theName, thePoints, theType, theIsClosed);
241     }
242
243     // Update the curve.
244     myPCurve->addSection(theName, theType, theIsClosed, thePoints);
245     finishOperation();
246   }
247 }
248
249 //=======================================================================
250 // function: removeSection
251 // purpose:
252 //=======================================================================
253 void CurveCreator_CurveEditor::removeSection(const int theISection)
254 {
255   if (myPCurve != NULL) {
256     // Set the difference.
257     startOperation();
258     if (addEmptyDiff()) {
259       myListDiffs.back().init(myPCurve, CurveCreator_Operation::RemoveSection,
260                               theISection);
261     }
262
263     // Update the curve.
264     myPCurve->removeSection(theISection);
265     finishOperation();
266   }
267 }
268
269 //=======================================================================
270 // function: insertPoints
271 // purpose:
272 //=======================================================================
273 void CurveCreator_CurveEditor::insertPoints
274         (const CurveCreator::Coordinates &thePoints,
275          const int theISection,
276          const int theIPnt)
277 {
278   if (myPCurve != NULL) {
279     // Set the difference.
280     startOperation();
281     if (addEmptyDiff()) {
282       myListDiffs.back().init(myPCurve, CurveCreator_Operation::InsertPoints,
283                               thePoints, theISection, theIPnt);
284     }
285
286     // Update the curve.
287     myPCurve->insertPoints(thePoints, theISection, theIPnt);
288     finishOperation();
289   }
290 }
291
292 //=======================================================================
293 // function: movePoints
294 // purpose:
295 //=======================================================================
296 void CurveCreator_CurveEditor::movePoint(const int theISection,
297                 const int theOrigIPnt,
298                 const int theNewIPnt )
299 {
300     startOperation();
301     myPCurve->movePoint(theISection, theOrigIPnt, theNewIPnt);
302     finishOperation();
303 }
304
305 //=======================================================================
306 // function: removePoints
307 // purpose:
308 //=======================================================================
309 void CurveCreator_CurveEditor::removePoints
310               (const int theISection,
311                const int theIPnt,
312                const int theNbPoints)
313 {
314   if (myPCurve != NULL) {
315     // Set the difference.
316     startOperation();
317     if (addEmptyDiff()) {
318       myListDiffs.back().init(myPCurve, CurveCreator_Operation::RemovePoints,
319                               theISection, theIPnt, theNbPoints);
320     }
321
322     // Update the curve.
323     myPCurve->removePoints(theISection, theIPnt, theNbPoints);
324     finishOperation();
325   }
326 }
327
328 //=======================================================================
329 // function: clear
330 // purpose:
331 //=======================================================================
332 void CurveCreator_CurveEditor::clear()
333 {
334   if (myPCurve != NULL) {
335     startOperation();
336     // Set the difference.
337     if (addEmptyDiff()) {
338       myListDiffs.back().init(myPCurve, CurveCreator_Operation::Clear);
339     }
340
341     // Update the curve.
342     myPCurve->clear();
343     finishOperation();
344   }
345 }
346
347 //=======================================================================
348 // function: setCoordinates
349 // purpose:
350 //=======================================================================
351 void CurveCreator_CurveEditor::setCoordinates
352                      (const CurveCreator::Coordinates &theCoords,
353                       const int theISection,
354                       const int theIPnt)
355 {
356   if (myPCurve != NULL) {
357     // Set the difference.
358     startOperation();
359     if (addEmptyDiff()) {
360       myListDiffs.back().init(myPCurve, CurveCreator_Operation::SetCoordinates,
361                               theCoords, theISection, theIPnt);
362     }
363
364     // Update the curve.
365     myPCurve->setCoordinates(theCoords, theISection, theIPnt);
366     finishOperation();
367   }
368 }
369
370 //=======================================================================
371 // function: setClosed
372 // purpose:
373 //=======================================================================
374 void CurveCreator_CurveEditor::setClosed(const bool theIsClosed,
375                                          const int theISection)
376 {
377   if (myPCurve != NULL) {
378     // Set the difference.
379     startOperation();
380     if (addEmptyDiff()) {
381       myListDiffs.back().init(myPCurve, CurveCreator_Operation::SetClosed,
382                               theIsClosed, theISection);
383     }
384
385     // Update the curve.
386     myPCurve->setClosed(theIsClosed, theISection);
387     finishOperation();
388   }
389 }
390
391 //=======================================================================
392 // function: setName
393 // purpose:
394 //=======================================================================
395 void CurveCreator_CurveEditor::setName(const std::string& theName,
396                                          const int theISection)
397 {
398     if (myPCurve != NULL) {
399       // Set the difference.
400       startOperation();
401       if (addEmptyDiff()) {
402         myListDiffs.back().init(myPCurve, CurveCreator_Operation::RenameSection,
403                                 theName, theISection);
404       }
405       myPCurve->setName( theName, theISection );
406       finishOperation();
407     }
408 }
409
410 //=======================================================================
411 // function: moveSection
412 // purpose:
413 //=======================================================================
414 void CurveCreator_CurveEditor::moveSection(const int theISection,
415                                            const int theNewIndex)
416 {
417   if (myPCurve != NULL) {
418     // Set the difference.
419     startOperation();
420     if (addEmptyDiff()) {
421       myListDiffs.back().init(myPCurve, CurveCreator_Operation::MoveSection,
422                               theISection, theNewIndex);
423     }
424
425     // Update the curve.
426     myPCurve->moveSection(theISection, theNewIndex);
427     finishOperation();
428   }
429 }
430
431 //=======================================================================
432 // function: join
433 // purpose:
434 //=======================================================================
435 void CurveCreator_CurveEditor::join(const int theISectionTo,
436                                     const int theISectionFrom)
437 {
438   if (myPCurve != NULL) {
439     // Set the difference.
440     startOperation();
441     if (addEmptyDiff()) {
442       myListDiffs.back().init(myPCurve, CurveCreator_Operation::Join,
443                               theISectionTo, theISectionFrom);
444     }
445
446     // Update the curve.
447     myPCurve->join(theISectionTo, theISectionFrom);
448     finishOperation();
449   }
450 }
451
452 //=======================================================================
453 // function: join
454 // purpose:
455 //=======================================================================
456 void CurveCreator_CurveEditor::join()
457 {
458   if (myPCurve != NULL) {
459     // Set the difference.
460     startOperation();
461     if (addEmptyDiff()) {
462       myListDiffs.back().init(myPCurve, CurveCreator_Operation::Join);
463     }
464
465     // Update the curve.
466     myPCurve->join();
467     finishOperation();
468   }
469 }
470
471 //=======================================================================
472 // function: addDiff
473 // purpose:
474 //=======================================================================
475 bool CurveCreator_CurveEditor::addEmptyDiff()
476 {
477   bool isEnabled = false;
478
479   if (myUndoDepth != 0) {
480     // Forget all Redos after the current one.
481     if (myNbRedos > 0) {
482       myNbRedos = 0;
483       myListDiffs.erase(myCurrenPos, myListDiffs.end());
484     }
485
486     if (myUndoDepth == -1 || myNbUndos < myUndoDepth) {
487       // Increase the number of undos.
488       myNbUndos++;
489     } else {
490       // If there are too many differences, remove the first one.
491       myListDiffs.pop_front();
492     }
493
494     // Add new difference.
495     myListDiffs.push_back(CurveCreator_Diff());
496     myCurrenPos = myListDiffs.end();
497     isEnabled = true;
498   }
499
500   return isEnabled;
501 }
502
503 void CurveCreator_CurveEditor::startOperation()
504 {
505     myOpLevel++;
506 }
507
508 void CurveCreator_CurveEditor::finishOperation()
509 {
510    myOpLevel--;
511 }