1 // Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: CurveCreator_Diff.cxx
21 // Author: Sergey KHROMOV
23 #include "CurveCreator_Diff.hxx"
24 #include "CurveCreator_Curve.hxx"
28 //=======================================================================
29 // function: Constructor
31 //=======================================================================
32 CurveCreator_Diff::CurveCreator_Diff()
39 //=======================================================================
40 // function: Destructor
42 //=======================================================================
43 CurveCreator_Diff::~CurveCreator_Diff()
48 //=======================================================================
51 //=======================================================================
52 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
53 const CurveCreator_Operation::Type theType)
57 if (theCurve != NULL) {
61 myPRedo = new CurveCreator_Operation;
63 if (myPRedo->init(theType)) {
66 const int aNbSections = theCurve->getNbSections();
68 if (theType == CurveCreator_Operation::Clear) {
69 // Construct undo for Clear command.
70 if (aNbSections > 0) {
71 setNbUndos(aNbSections);
73 for (int i = 0; i < aNbSections && isOK; i++) {
74 // Add AddSection command.
75 isOK = addSectionToUndo(theCurve, i, myPUndo[i]);
78 } else { // theType == CurveCreator_Operation::Join
79 // Construct undo for Join command.
80 if (aNbSections > 1) {
81 // Add the RemovePoints command to remove points of
82 // the second section fron the first one.
83 const int aNbPoints = theCurve->getNbPoints(0);
85 setNbUndos(aNbSections);
86 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
89 for (int i = 1; i < aNbSections && isOK; i++) {
90 // Add AddSection command.
91 isOK = addSectionToUndo(theCurve, i, myPUndo[i]);
105 //=======================================================================
108 //=======================================================================
109 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
110 const CurveCreator_Operation::Type theType,
111 const int theIntParam)
115 if (theCurve != NULL) {
119 myPRedo = new CurveCreator_Operation;
121 if (myPRedo->init(theType, theIntParam)) {
122 // Construct undo for RemoveSection command.
123 // If the last section is removed, one AddSection command is enough.
124 // If not last section is removed, two commands are requred: AddSection
126 const int aLastIndex = theCurve->getNbSections() - 1;
128 if (theIntParam == aLastIndex) {
134 isOK = addSectionToUndo(theCurve, theIntParam, myPUndo[0]);
136 if (isOK && theIntParam != aLastIndex) {
137 isOK = myPUndo[1].init(CurveCreator_Operation::MoveSection,
138 aLastIndex, theIntParam);
150 //=======================================================================
153 //=======================================================================
154 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
155 const CurveCreator_Operation::Type theType,
156 const int theIntParam1,
157 const int theIntParam2)
161 if (theCurve != NULL) {
165 myPRedo = new CurveCreator_Operation;
167 if (myPRedo->init(theType, theIntParam1, theIntParam2)) {
168 // Construct undo for different commands.
170 case CurveCreator_Operation::SetType:
171 case CurveCreator_Operation::SetClosed:
172 isOK = setTypeOrClosedToUndo
173 (theCurve, theType, theIntParam1, theIntParam2);
175 case CurveCreator_Operation::MoveSection:
177 isOK = myPUndo[0].init(theType, theIntParam2, theIntParam1);
179 case CurveCreator_Operation::Join:
181 // If the last section is removed, one AddSection command is
182 // enough. If not last section is removed, two commands are
183 // requred: AddSection and MoveSection.
184 const int aLastIndex = theCurve->getNbSections() - 1;
185 const int aNbPoints = theCurve->getNbPoints(theIntParam1);
187 if (theIntParam2 == aLastIndex) {
193 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
194 theIntParam1, aNbPoints, -1);
197 isOK = addSectionToUndo(theCurve, theIntParam2, myPUndo[1]);
199 if (isOK && theIntParam2 != aLastIndex) {
200 isOK = myPUndo[2].init(CurveCreator_Operation::MoveSection,
201 aLastIndex, theIntParam2);
206 case CurveCreator_Operation::RemovePoints:
208 // Construct undo for RemovePoints command.
209 const CurveCreator::Dimension aDim = theCurve->getDimension();
210 const CurveCreator::Coordinates &aPoints =
211 theCurve->getPoints(theIntParam1);
212 CurveCreator::Coordinates::const_iterator anIterBegin =
213 aPoints.begin() + (aDim*theIntParam2);
214 CurveCreator::Coordinates::const_iterator anIterEnd =
217 CurveCreator::Coordinates aPointsToAdd;
220 aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd);
221 isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints,
222 aPointsToAdd, theIntParam1, theIntParam2);
238 //=======================================================================
241 //=======================================================================
242 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
243 const CurveCreator_Operation::Type theType,
244 const int theIntParam1,
245 const int theIntParam2,
246 const int theIntParam3)
250 if (theCurve != NULL) {
254 myPRedo = new CurveCreator_Operation;
256 if (myPRedo->init(theType, theIntParam1, theIntParam2, theIntParam3)) {
267 //=======================================================================
270 //=======================================================================
271 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
272 const CurveCreator_Operation::Type theType,
273 const CurveCreator::Coordinates &theCoords,
274 const int theIntParam)
278 if (theCurve != NULL) {
282 myPRedo = new CurveCreator_Operation;
284 if (myPRedo->init(theType, theCoords, theIntParam)) {
285 // Construct undo for AddPoints command.
286 const int aSectionInd = getSectionIndex(theCurve, theIntParam);
287 const CurveCreator::Dimension aDim = theCurve->getDimension();
288 const CurveCreator::Coordinates &aPoints =
289 theCurve->getPoints(aSectionInd);
290 const int aNbPoints = (aPoints.size()/aDim);
293 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
294 aSectionInd, aNbPoints, -1);
305 //=======================================================================
308 //=======================================================================
309 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
310 const CurveCreator_Operation::Type theType,
311 const std::string& theName,
312 const CurveCreator::Coordinates &theCoords,
313 const int theIntParam1,
314 const int theIntParam2)
318 if (theCurve != NULL) {
322 myPRedo = new CurveCreator_Operation;
324 if (myPRedo->init(theType, theName, theCoords, theIntParam1, theIntParam2)) {
325 // Construct undo for different commands.
327 case CurveCreator_Operation::AddSection:
329 isOK = myPUndo[0].init(CurveCreator_Operation::RemoveSection, -1);
339 //=======================================================================
342 //=======================================================================
343 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
344 const CurveCreator_Operation::Type theType,
345 const CurveCreator::Coordinates &theCoords,
346 const int theIntParam1,
347 const int theIntParam2)
351 if (theCurve != NULL) {
355 myPRedo = new CurveCreator_Operation;
357 if (myPRedo->init(theType, theCoords, theIntParam1, theIntParam2)) {
358 // Construct undo for different commands.
360 case CurveCreator_Operation::InsertPoints:
362 const CurveCreator::Dimension aDim = theCurve->getDimension();
363 const int aNbPoints = (theCoords.size()/aDim);
364 const int aSectionInd = getSectionIndex(theCurve, theIntParam1);
367 if (theIntParam2 == -1) {
368 aPointInd = theCurve->getNbPoints(aSectionInd);
370 aPointInd = theIntParam2;
374 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
375 aSectionInd, aPointInd);
378 case CurveCreator_Operation::SetCoordinates:
380 const CurveCreator::Coordinates anOldCoords =
381 theCurve->getPoint(theIntParam1, theIntParam2);
384 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
385 anOldCoords, theIntParam1, theIntParam2);
401 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
402 const CurveCreator_Operation::Type theType,
403 const std::string &theName,
404 const int theIntParam1 )
407 myPRedo = new CurveCreator_Operation;
409 if (myPRedo->init(theType, theName, theIntParam1 )) {
410 // Construct undo for different commands.
412 case CurveCreator_Operation::RenameSection:
414 isOK = myPUndo[0].init(CurveCreator_Operation::RenameSection,
415 theCurve->getSectionName(theIntParam1), theIntParam1);
425 //=======================================================================
426 // function: applyUndo
428 //=======================================================================
429 void CurveCreator_Diff::applyUndo(CurveCreator_Curve *theCurve)
431 if (myNbUndos > 0 && myPUndo != NULL) {
432 for (int i = 0; i < myNbUndos; i++) {
433 myPUndo[i].apply(theCurve);
438 //=======================================================================
439 // function: applyRedo
441 //=======================================================================
442 void CurveCreator_Diff::applyRedo(CurveCreator_Curve *theCurve)
444 if (myPRedo != NULL) {
445 myPRedo->apply(theCurve);
449 //=======================================================================
452 //=======================================================================
453 void CurveCreator_Diff::clear()
455 if (myPUndo != NULL) {
462 if (myPRedo != NULL) {
468 //=======================================================================
469 // function: setNbUndos
471 //=======================================================================
472 void CurveCreator_Diff::setNbUndos(const int theNbUndos)
474 myNbUndos = theNbUndos;
475 myPUndo = new CurveCreator_Operation[myNbUndos];
478 //=======================================================================
479 // function: getSectionIndex
481 //=======================================================================
482 int CurveCreator_Diff::getSectionIndex(const CurveCreator_Curve *theCurve,
483 const int theIndex) const
485 return (theIndex == -1 ? theCurve->getNbSections() - 1 : theIndex);
488 //=======================================================================
489 // function: addSectionToUndo
491 //=======================================================================
492 bool CurveCreator_Diff::addSectionToUndo
493 (const CurveCreator_Curve *theCurve,
495 CurveCreator_Operation &theOperation) const
497 const CurveCreator::Coordinates &aPnts = theCurve->getPoints(theIndex);
498 const CurveCreator::SectionType aType = theCurve->getSectionType(theIndex);
499 const bool isClosed = theCurve->isClosed(theIndex);
501 bool isOK = theOperation.init(CurveCreator_Operation::AddSection,
502 aPnts, aType, isClosed);
507 //=======================================================================
508 // function: setTypeOrClosedToUndo
510 //=======================================================================
511 bool CurveCreator_Diff::setTypeOrClosedToUndo
512 (const CurveCreator_Curve *theCurve,
513 const CurveCreator_Operation::Type theType,
514 const int theIntParam1,
515 const int theIntParam2)
519 // Compute number of modified sections.
520 const bool isSetType = (theType == CurveCreator_Operation::SetType);
522 std::list<int> aListOfInd;
526 if (theIntParam2 == -1) {
527 // The operation is applied to all sections. We need to collect
528 // really modified sections for undo.
529 const int aNbSections = theCurve->getNbSections();
531 if (aNbSections > 0) {
532 // Get sections to be modified.
533 for (i = 0; i < aNbSections; i++) {
535 aValue = theCurve->getSectionType(i);
537 aValue = theCurve->isClosed(i);
540 if (theIntParam1 != aValue) {
542 aListOfInd.push_back(i);
546 if (aNbSections == aNbModif) {
547 // All sections are modified. We can use one single command
548 // with -1 section index.
551 aListOfInd.push_back(-1);
555 // There is only particular section modified.
556 // Check if there is a real modification required.
558 aValue = theCurve->getSectionType(theIntParam2);
560 aValue = theCurve->isClosed(theIntParam2);
563 if (theIntParam1 != aValue) {
565 aListOfInd.push_back(theIntParam2);
571 std::list<int>::iterator anIter = aListOfInd.begin();
574 aValue = theCurve->getSectionType(*anIter);
576 aValue = theCurve->isClosed(*anIter);
579 setNbUndos(aNbModif);
581 for (i = 0; anIter != aListOfInd.end() && isOK; i++, anIter++) {
582 isOK = myPUndo[i].init(theType, aValue, *anIter);