]> SALOME platform Git repositories - modules/hydro.git/commitdiff
Salome HOME
Ref #250 - Fatal error after Join all selections operation
authornds <nds@opencascade.com>
Thu, 19 Dec 2013 07:40:15 +0000 (07:40 +0000)
committernds <nds@opencascade.com>
Thu, 19 Dec 2013 07:40:15 +0000 (07:40 +0000)
src/HYDROCurveCreator/CurveCreator_Curve.cxx
src/HYDROCurveCreator/CurveCreator_Curve.hxx
src/HYDROCurveCreator/CurveCreator_Diff.cxx
src/HYDROCurveCreator/CurveCreator_Diff.hxx
src/HYDROCurveCreator/CurveCreator_ICurve.hxx
src/HYDROCurveCreator/CurveCreator_Operation.cxx
src/HYDROCurveCreator/CurveCreator_Operation.hxx
src/HYDROCurveCreator/CurveCreator_Profile.cxx
src/HYDROCurveCreator/CurveCreator_Profile.hxx
src/HYDROCurveCreator/CurveCreator_TreeView.cxx
src/HYDROCurveCreator/CurveCreator_Widget.cxx

index 69287f1fa6c241ba57907476c66676446e620252..53576dbc04a494505ea208a9a9f38f3ce500c2b3 100644 (file)
@@ -258,11 +258,13 @@ bool CurveCreator_Curve::moveSectionInternal(const int theISection,
                                              const int theNewIndex)
 {
   bool res = false;
-  if (theISection != theNewIndex) {
-    CurveCreator_Section *aSection = mySections.at(theISection);
+  int aMovedSectionId = theISection >= 0 ? theISection : mySections.size()-1;
+
+  if (aMovedSectionId != theNewIndex) {
+    CurveCreator_Section *aSection = mySections.at(aMovedSectionId);
 
     // Remove section
-    CurveCreator::Sections::iterator anIter = mySections.begin() + theISection;
+    CurveCreator::Sections::iterator anIter = mySections.begin() + aMovedSectionId;
 
     mySections.erase(anIter);
 
@@ -383,34 +385,46 @@ bool CurveCreator_Curve::clear()
 }
 
 //! For internal use only! Undo/Redo are not used here.
-bool CurveCreator_Curve::joinInternal( const int theISectionTo, 
-                                       const int theISectionFrom )
+bool CurveCreator_Curve::joinInternal( const std::list<int>& theSections )
 {
   bool res = false;
-  CurveCreator_Section *aSection1 = mySections.at(theISectionTo);
-  CurveCreator_Section *aSection2 = mySections.at(theISectionFrom);
-
-  aSection1->myPoints.insert(aSection1->myPoints.end(),
-                             aSection2->myPoints.begin(), 
-                             aSection2->myPoints.end());
+  if ( theSections.empty() )
+    return res;
+
+  int anISectionMain = theSections.front();
+  CurveCreator_Section* aSectionMain = mySections.at( anISectionMain );
+  std::list <int> aSectionsToJoin = theSections;
+  aSectionsToJoin.erase( aSectionsToJoin.begin() ); // skip the main section
+  // it is important to sort and reverse the section ids in order to correctly remove them
+  aSectionsToJoin.sort();
+  aSectionsToJoin.reverse();
+
+  std::list<int>::const_iterator anIt = aSectionsToJoin.begin(), aLast = aSectionsToJoin.end();
+  CurveCreator_Section* aSection;
+  for (; anIt != aLast; anIt++) {
+    aSection = mySections.at(*anIt);
+    aSectionMain->myPoints.insert(aSectionMain->myPoints.end(), aSection->myPoints.begin(),
+                                  aSection->myPoints.end());
+    res = removeSectionInternal(*anIt);
+    if ( !res )
+      break;
+  }
 
-  res = removeSectionInternal(theISectionFrom);
   redisplayCurve();
   return res;
 }
 
-//! Join range of sections to one section (join all sections if -1 is passed in theISectionFrom argument)
-bool CurveCreator_Curve::join( const int theISectionTo, 
-                               const int theISectionFrom )
+bool CurveCreator_Curve::join( const std::list<int>& theSections )
 {
-  //TODO
   bool res = false;
-  if ( theISectionTo != theISectionFrom ) {
+
+  if ( !theSections.empty() )
+  {
     startOperation();
     if (addEmptyDiff())
-      myListDiffs.back().init(this, CurveCreator_Operation::Join, theISectionTo, theISectionFrom);
+      myListDiffs.back().init(this, CurveCreator_Operation::Join, theSections);
 
-    res = joinInternal( theISectionTo, theISectionFrom );
+    res = joinInternal( theSections );
 
     finishOperation();
   }
index 34ff73f3ca1957caaff80311ccfca36782e231eb..209e6a7ca7354ff2b1d09089ca9d263bbcde3bc4 100644 (file)
@@ -140,11 +140,11 @@ public:
   virtual bool clear();
 
   //! For internal use only! Undo/Redo are not used here.
-  virtual bool joinInternal( const int theISectionTo = -1, 
-                             const int theISectionFrom = -1 );
-  //! Join range of sections to one section (join all sections if -1 is passed in one of arguments)
-  virtual bool join( const int theISectionTo = -1, 
-                     const int theISectionFrom = -1 );
+  virtual bool joinInternal( const std::list<int>& theSections );
+
+  //! Join list of sections to one section (join all if the list is empty)
+  // The first section in the list is a leader, another sections are joined to it
+  virtual bool join( const std::list<int>& theSections );
 
   //! Get number of sections
   virtual int getNbSections() const;
index dbc633428bdce57e697d56cfb63975ce0435cb14..d1a7dc3222e43426504b79b637fea80197b35ce0 100644 (file)
@@ -158,40 +158,81 @@ bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
           setNbUndos(1);
           isOK = myPUndo[0].init(theType, theIntParam2, theIntParam1);
           break;
+        default:
+          break;
+      }
+    }
+
+    if (!isOK) {
+      clear();
+    }
+  }
+
+  return isOK;
+}
+
+//=======================================================================
+// function: init
+// purpose:
+//=======================================================================
+bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
+                             const CurveCreator_Operation::Type theType,
+                             const std::list<int>& theParams)
+{
+  bool isOK = false;
+
+  if (theCurve != NULL || theParams.empty()) {
+    clear();
+
+    // Set redo.
+    myPRedo = new CurveCreator_Operation;
+
+    if (myPRedo->init(theType, theParams)) {
+      // Construct undo for different commands.
+      switch (theType) {
         case CurveCreator_Operation::Join:
           {
-            // If the last section is removed, one AddSection command is
-            // enough. If not last section is removed, two commands are
-            // requred: AddSection and MoveSection.
-            const int aLastIndex = theCurve->getNbSections() - 1;
-            const int aNbPoints  = theCurve->getNbPoints(theIntParam1);
-
-            if (theIntParam2 == aLastIndex) {
-              setNbUndos(2);
-            } else {
-              setNbUndos(3);
+            int aSectionMain = theParams.front();
+            const int aNbPointsMain  = theCurve->getNbPoints(aSectionMain);
+
+            std::list<int> aSectionsToJoin = theParams;
+            aSectionsToJoin.erase( aSectionsToJoin.begin() );
+            // it is important to sort the section indices in order to correct perform undo
+            // for the move sections to the previous positions
+            aSectionsToJoin.sort();
+            // 1rst undo for remove points from the main and n-1 undoes to contain joined sections
+            int aSectionsToJoinNb = aSectionsToJoin.size();
+            int aNbUndos = 2*aSectionsToJoinNb + 1;
+            setNbUndos( aNbUndos );
+
+            // Add joined sections to undo
+            std::list<int>::const_iterator anIt = aSectionsToJoin.begin(),
+                                           aLast = aSectionsToJoin.end();
+            anIt = aSectionsToJoin.begin();
+            int aLastSectionId = -1;
+            for (int i = 0; anIt != aLast && i < aSectionsToJoinNb; anIt++, i++) {
+              int anISection = *anIt;
+              isOK = addSectionToUndo( theCurve, anISection, myPUndo[i*2] );
+              if (isOK) {
+                isOK = myPUndo[i*2+1].init(CurveCreator_Operation::MoveSection,
+                                           aLastSectionId, anISection);
+                if (!isOK)
+                  break;
+              }
             }
-
             // Construct undo for RemovePoints command.
-            int anISection = theIntParam1;
-            const int aNbPoints2  = theCurve->getNbPoints(theIntParam2);
-            CurveCreator_ICurve::SectionToPointList aSectionToPointList;
-            int aJoinedSize = aNbPoints + aNbPoints2;
-            for (int anIPoint = aNbPoints; anIPoint < aJoinedSize; anIPoint++)
-              aSectionToPointList.push_back(std::make_pair( anISection, anIPoint ) );
-            isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
-                                   aSectionToPointList);
-
-            //isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
-            //                       theIntParam1, aNbPoints, -1);
-
             if (isOK) {
-              isOK = addSectionToUndo(theCurve, theIntParam2, myPUndo[1]);
+              int aNbPointsInJoined = 0;
+              anIt = aSectionsToJoin.begin();
+              for ( ; anIt != aLast; anIt++ )
+                aNbPointsInJoined += theCurve->getNbPoints( *anIt );
 
-              if (isOK && theIntParam2 != aLastIndex) {
-                isOK = myPUndo[2].init(CurveCreator_Operation::MoveSection,
-                                       aLastIndex, theIntParam2);
-              }
+              int aJoinedSize = aNbPointsMain + aNbPointsInJoined;
+              CurveCreator_ICurve::SectionToPointList aSectionToPointList;
+              for (int anIPoint = aNbPointsMain; anIPoint < aJoinedSize; anIPoint++)
+                aSectionToPointList.push_back(std::make_pair(aSectionMain, anIPoint));
+
+              isOK = myPUndo[aNbUndos-1].init(CurveCreator_Operation::RemovePoints, aSectionToPointList);
             }
           }
           break;
index 1a398d3b5f227bf49ff073fd9a26e34852cb2175..f55f5306ff18f9133319d6985cf110cad6687dcb 100644 (file)
@@ -78,7 +78,6 @@ public:
    *   <LI>SetType</LI>
    *   <LI>SetClosed</LI>
    *   <LI>MoveSection</LI>
-   *   <LI>Join (with 2 int arguments)</LI>
    * </UL>
    */
   bool init(const CurveCreator_Curve *theCurve,
@@ -86,6 +85,17 @@ public:
             const int theIntParam1,
             const int theIntParam2);
 
+    /**
+   * This method initializes the difference with an operation with two integer
+   * parameters. It is applicable to the following operations:
+   * <UL>
+   *   <LI>Join (with a list of int arguments)</LI>
+   * </UL>
+   */
+  bool init(const CurveCreator_Curve *theCurve,
+            const CurveCreator_Operation::Type theType,
+            const std::list<int>& theParams);
+
   /**
    * This method initializes the difference with an operation with one
    * Name, one CurveCreator::Coordinates parameter and two integer parameters.
index a535dc65a004086ba759689e4abedcb6a21b4583..9effa478a0db3ef2ae5107ac27d1a389a7d7e8c6 100644 (file)
@@ -27,6 +27,7 @@
 #include <deque>
 #include <vector>
 #include <string>
+#include <list>
 
 class Handle_AIS_InteractiveObject;
 
@@ -88,9 +89,9 @@ public:
   //! Clear the polyline (remove all sections)
   virtual bool clear() = 0;
 
-  //! Join range of sections to one section (join all sections if -1 is passed in one of arguments)
-  virtual bool join( const int theISectionTo = -1, 
-                     const int theISectionFrom = -1 ) = 0;
+  //! Join list of sections to one section (join all if the list is empty)
+  // The first section in the list is a leader, another sections are joined to it
+  virtual bool join( const std::list<int>& theSections ) = 0;
 
   //! Get number of sections
   virtual int getNbSections() const = 0;
index bd9cab5dcdea6a91a93e4b98ef6f8f760f525da2..173e1c8817fdcabd8c6ebf84940c751accafbd22 100644 (file)
@@ -114,6 +114,35 @@ bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
   return isOK;
 }
 
+//=======================================================================
+// function: Constructor
+// purpose:
+//=======================================================================
+bool CurveCreator_Operation::init(const Type theType, const std::list<int> theParamList)
+{
+  bool isOK = false;
+
+  if (theType == CurveCreator_Operation::Join)
+  {
+    const int aNbPoints = theParamList.size();
+
+    const size_t aSize =
+      sizeof(aNbPoints) +
+      aNbPoints * (sizeof(int));
+
+    int *pIntData = (int *)allocate(aSize);
+
+    *pIntData++ = aNbPoints;
+    std::list<int>::const_iterator anIt = theParamList.begin(), aLast = theParamList.end();
+    for ( ; anIt != aLast; anIt++ )
+      *pIntData++ = *anIt;
+
+    myType   = theType;
+    isOK   = true;
+  }
+  return isOK;
+}
+
 //=======================================================================
 // function: Constructor
 // purpose:
@@ -364,10 +393,14 @@ void CurveCreator_Operation::apply(CurveCreator_Curve *theCurve)
         theCurve->moveSectionInternal(pInt[0], pInt[1]);
         break;
       case CurveCreator_Operation::Join:
-        if (myPData == NULL) {
-          theCurve->joinInternal();
-        } else {
-          theCurve->joinInternal(pInt[0], pInt[1]);
+        if (myPData != NULL)
+        {
+          std::list<int> aListOfSections;
+          int nbSections = pInt[0];
+          for (int i = 1; i < nbSections+1; i++) {
+            aListOfSections.push_back(pInt[i]);
+          }
+          theCurve->joinInternal(aListOfSections);
         }
         break;
       case CurveCreator_Operation::AddSection:
index 7650cdf5ddafd7d8e1d1a52b183ee6ad18161cfc..855d0da2a33e0abec6e601c9de97c14a7f743bc5 100644 (file)
@@ -106,6 +106,16 @@ public:
   bool init(const Type theType, const int theIntParam1,
             const int theIntParam2);
 
+  /**
+   * This method initializes the object with an operation with two integer
+   * parameters. It is applicable to the following operations:
+   * <UL>
+   *   <LI>Join (with a list of int arguments)</LI>
+   * </UL>
+   * @return true in case of success; false otherwise.
+   */
+  bool init(const Type theType, const std::list<int> theParamList);
+
   /**
    * This method initializes the object with an operation with 
    * list of pairs of integer parameters. 
index 69e60486ed65e3cc66c7913f42db6a1be7b12c3c..08ad8a4bee793359d7efb28c615f6e03828af42b 100644 (file)
@@ -76,14 +76,12 @@ bool CurveCreator_Profile::clearInternal()
   return true;
 }
 
-bool CurveCreator_Profile::joinInternal( const int theISectionTo, 
-                                         const int theISectionFrom )
+bool CurveCreator_Profile::joinInternal( const std::list<int>& theSections )
 {
   return false;
 }
 
-bool CurveCreator_Profile::join( const int theISectionTo, 
-                                 const int theISectionFrom )
+bool CurveCreator_Profile::join( const std::list<int>& theSections )
 {
   return false;
 }
index 67461a42f78bb9c6bde32b24ee53797c027d1c8a..f426fba00e3de200949139c05db68f0694df0cbf 100644 (file)
@@ -50,8 +50,7 @@ public:
   virtual bool clearInternal();
 
   //! For internal use only! Undo/Redo are not used here.
-  virtual bool joinInternal( const int theISectionTo = -1, 
-                             const int theISectionFrom = -1 );
+  virtual bool joinInternal( const std::list<int>& theSections );
 
   //! For internal use only! Undo/Redo are not used here.
   virtual bool moveSectionInternal( const int theISection,
@@ -59,10 +58,9 @@ public:
   //! Move section to new position in list
   virtual bool moveSection( const int theISection,
                             const int theNewIndex );
-
-  //! Join range of sections to one section (join all sections if -1 is passed in one of arguments)
-  virtual bool join( const int theISectionTo = -1, 
-                     const int theISectionFrom = -1 );
+  //! Join list of sections to one section (join all if the list is empty)
+  // The first section in the list is a leader, another sections are joined to it
+  virtual bool join( const std::list<int>& theSections );
 
   //! For internal use only! Undo/Redo are not used here.
   virtual int addSectionInternal( const std::string &theName, 
index 9280713ac5b334ebba24ae907f16e99d036a89c1..ce580d5357ee720a045f3b2ceed086832bba7add 100755 (executable)
@@ -249,7 +249,6 @@ QList<int> CurveCreator_TreeView::getSelectedSections() const
       aSect << aModel->getSection( anIndxs[i] );
     }
   }
-  qSort(aSect.begin(), aSect.end());
   return aSect;
 }
 
index 42bbaf6cc909fe516c7a3a812c1ba1fa7df01f37..e997fe69fe3fc1e9bab18fbe1ee083c040a3e9c2 100644 (file)
@@ -665,13 +665,17 @@ void CurveCreator_Widget::onJoin()
   }
   stopActionMode();
 
-  int aMainSect = aSections[0];
-  int aMainSectSize = myCurve->getNbPoints(aMainSect);
-  for( int i = 1 ; i < aSections.size() ; i++ ){
-    int aSectNum = aSections[i] - (i-1);
-    myCurve->join( aMainSect, aSectNum );
-    mySectionView->sectionsRemoved( aSectNum );
+  std::list<int> aSectionsToJoin;
+  for( int i = 0; i < aSections.size() ; i++ ){
+    aSectionsToJoin.push_back( aSections[i] );
+  }
+
+  if ( myCurve->join( aSectionsToJoin ) )
+  {
+    for( int i = 0, aSectionsSize = aSectionsToJoin.size(); i < aSectionsSize; i++ )
+      mySectionView->sectionsRemoved( i );
   }
+
   updateUndoRedo();
 }
 
@@ -708,7 +712,13 @@ void CurveCreator_Widget::onJoinAll()
   if( !myCurve )
     return;
   stopActionMode();
-  myCurve->join( 0, myCurve->getNbSections()-1 );
+
+  std::list<int> aSectionsToJoin;
+  for( int i = 0, aNb = myCurve->getNbSections(); i < aNb ; i++ ){
+    aSectionsToJoin.push_back( i );
+  }
+  bool aRes = myCurve->join( aSectionsToJoin );
+
   mySectionView->reset();
   updateActionsStates();
   updateUndoRedo();