From: nds Date: Thu, 19 Dec 2013 07:40:15 +0000 (+0000) Subject: Ref #250 - Fatal error after Join all selections operation X-Git-Tag: BR_hydro_v_0_6~27 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=a8fc21e48db08ba3de63519dcae1a8e3fe560ee4;p=modules%2Fhydro.git Ref #250 - Fatal error after Join all selections operation --- diff --git a/src/HYDROCurveCreator/CurveCreator_Curve.cxx b/src/HYDROCurveCreator/CurveCreator_Curve.cxx index 69287f1f..53576dbc 100644 --- a/src/HYDROCurveCreator/CurveCreator_Curve.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Curve.cxx @@ -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& 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 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::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& 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(); } diff --git a/src/HYDROCurveCreator/CurveCreator_Curve.hxx b/src/HYDROCurveCreator/CurveCreator_Curve.hxx index 34ff73f3..209e6a7c 100644 --- a/src/HYDROCurveCreator/CurveCreator_Curve.hxx +++ b/src/HYDROCurveCreator/CurveCreator_Curve.hxx @@ -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& 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& theSections ); //! Get number of sections virtual int getNbSections() const; diff --git a/src/HYDROCurveCreator/CurveCreator_Diff.cxx b/src/HYDROCurveCreator/CurveCreator_Diff.cxx index dbc63342..d1a7dc32 100644 --- a/src/HYDROCurveCreator/CurveCreator_Diff.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Diff.cxx @@ -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& 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 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::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; diff --git a/src/HYDROCurveCreator/CurveCreator_Diff.hxx b/src/HYDROCurveCreator/CurveCreator_Diff.hxx index 1a398d3b..f55f5306 100644 --- a/src/HYDROCurveCreator/CurveCreator_Diff.hxx +++ b/src/HYDROCurveCreator/CurveCreator_Diff.hxx @@ -78,7 +78,6 @@ public: *
  • SetType
  • *
  • SetClosed
  • *
  • MoveSection
  • - *
  • Join (with 2 int arguments)
  • * */ 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: + *
      + *
    • Join (with a list of int arguments)
    • + *
    + */ + bool init(const CurveCreator_Curve *theCurve, + const CurveCreator_Operation::Type theType, + const std::list& theParams); + /** * This method initializes the difference with an operation with one * Name, one CurveCreator::Coordinates parameter and two integer parameters. diff --git a/src/HYDROCurveCreator/CurveCreator_ICurve.hxx b/src/HYDROCurveCreator/CurveCreator_ICurve.hxx index a535dc65..9effa478 100644 --- a/src/HYDROCurveCreator/CurveCreator_ICurve.hxx +++ b/src/HYDROCurveCreator/CurveCreator_ICurve.hxx @@ -27,6 +27,7 @@ #include #include #include +#include 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& theSections ) = 0; //! Get number of sections virtual int getNbSections() const = 0; diff --git a/src/HYDROCurveCreator/CurveCreator_Operation.cxx b/src/HYDROCurveCreator/CurveCreator_Operation.cxx index bd9cab5d..173e1c88 100644 --- a/src/HYDROCurveCreator/CurveCreator_Operation.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Operation.cxx @@ -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 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::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 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: diff --git a/src/HYDROCurveCreator/CurveCreator_Operation.hxx b/src/HYDROCurveCreator/CurveCreator_Operation.hxx index 7650cdf5..855d0da2 100644 --- a/src/HYDROCurveCreator/CurveCreator_Operation.hxx +++ b/src/HYDROCurveCreator/CurveCreator_Operation.hxx @@ -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: + *
      + *
    • Join (with a list of int arguments)
    • + *
    + * @return true in case of success; false otherwise. + */ + bool init(const Type theType, const std::list theParamList); + /** * This method initializes the object with an operation with * list of pairs of integer parameters. diff --git a/src/HYDROCurveCreator/CurveCreator_Profile.cxx b/src/HYDROCurveCreator/CurveCreator_Profile.cxx index 69e60486..08ad8a4b 100644 --- a/src/HYDROCurveCreator/CurveCreator_Profile.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Profile.cxx @@ -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& theSections ) { return false; } -bool CurveCreator_Profile::join( const int theISectionTo, - const int theISectionFrom ) +bool CurveCreator_Profile::join( const std::list& theSections ) { return false; } diff --git a/src/HYDROCurveCreator/CurveCreator_Profile.hxx b/src/HYDROCurveCreator/CurveCreator_Profile.hxx index 67461a42..f426fba0 100644 --- a/src/HYDROCurveCreator/CurveCreator_Profile.hxx +++ b/src/HYDROCurveCreator/CurveCreator_Profile.hxx @@ -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& 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& theSections ); //! For internal use only! Undo/Redo are not used here. virtual int addSectionInternal( const std::string &theName, diff --git a/src/HYDROCurveCreator/CurveCreator_TreeView.cxx b/src/HYDROCurveCreator/CurveCreator_TreeView.cxx index 9280713a..ce580d53 100755 --- a/src/HYDROCurveCreator/CurveCreator_TreeView.cxx +++ b/src/HYDROCurveCreator/CurveCreator_TreeView.cxx @@ -249,7 +249,6 @@ QList CurveCreator_TreeView::getSelectedSections() const aSect << aModel->getSection( anIndxs[i] ); } } - qSort(aSect.begin(), aSect.end()); return aSect; } diff --git a/src/HYDROCurveCreator/CurveCreator_Widget.cxx b/src/HYDROCurveCreator/CurveCreator_Widget.cxx index 42bbaf6c..e997fe69 100644 --- a/src/HYDROCurveCreator/CurveCreator_Widget.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Widget.cxx @@ -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 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 aSectionsToJoin; + for( int i = 0, aNb = myCurve->getNbSections(); i < aNb ; i++ ){ + aSectionsToJoin.push_back( i ); + } + bool aRes = myCurve->join( aSectionsToJoin ); + mySectionView->reset(); updateActionsStates(); updateUndoRedo();