From 254aba54a085eac64aa4ec13f1d46beac722a252 Mon Sep 17 00:00:00 2001 From: akl Date: Tue, 19 Nov 2013 13:08:30 +0000 Subject: [PATCH] Fix Undo/Redo of AddSection, RemoveSection, AddPoint, RemovePoint. --- src/HYDROCurveCreator/CurveCreator_Curve.cxx | 179 ++++++++++++------ src/HYDROCurveCreator/CurveCreator_Curve.hxx | 17 +- src/HYDROCurveCreator/CurveCreator_Diff.cxx | 42 ++-- .../CurveCreator_Operation.cxx | 24 +-- .../CurveCreator_TreeView.cxx | 9 +- src/HYDROCurveCreator/CurveCreator_TreeView.h | 2 + src/HYDROCurveCreator/CurveCreator_Widget.cxx | 48 +++-- 7 files changed, 206 insertions(+), 115 deletions(-) diff --git a/src/HYDROCurveCreator/CurveCreator_Curve.cxx b/src/HYDROCurveCreator/CurveCreator_Curve.cxx index 8f878e25..c1b66d58 100644 --- a/src/HYDROCurveCreator/CurveCreator_Curve.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Curve.cxx @@ -449,6 +449,26 @@ int CurveCreator_Curve::getNbSections() const return mySections.size(); } +//! For internal use only! Undo/Redo is not used here. +int CurveCreator_Curve::addSectionInternal + (const std::string& theName, const CurveCreator::SectionType theType, + const bool theIsClosed, const CurveCreator::Coordinates &thePoints) +{ + CurveCreator_Section *aSection = new CurveCreator_Section; + + std::string aName = theName; + if( aName.empty() ){ + aName = getUniqSectionName(); + } + aSection->myName = aName; + aSection->myType = theType; + aSection->myIsClosed = theIsClosed; + aSection->myPoints = thePoints; + mySections.push_back(aSection); + redisplayCurve(); + return mySections.size()-1; +} + //======================================================================= // function: addSection // purpose: adds an empty section @@ -460,25 +480,16 @@ int CurveCreator_Curve::addSection int resISection = -1; // Set the difference. startOperation(); + CurveCreator::Coordinates aCoords; //empty list if (addEmptyDiff()) { - CurveCreator::Coordinates aCoords; //empty list myListDiffs.back().init(this, CurveCreator_Operation::AddSection, theName, aCoords, theType, theIsClosed); } - CurveCreator_Section *aSection = new CurveCreator_Section; - std::string aName = theName; - if( aName.empty() ){ - aName = getUniqSectionName(); - } - aSection->myName = aName; - aSection->myType = theType; - aSection->myIsClosed = theIsClosed; - mySections.push_back(aSection); - redisplayCurve(); + resISection = addSectionInternal(theName, theType, theIsClosed, aCoords); finishOperation(); - return mySections.size()-1; + return resISection; } //======================================================================= // function: addSection @@ -489,33 +500,21 @@ int CurveCreator_Curve::addSection const bool theIsClosed, const CurveCreator::Coordinates &thePoints) { int resISection = -1; - //// Set the difference. - //startOperation(); - //if (addEmptyDiff()) { - // myListDiffs.back().init(this, CurveCreator_Operation::AddSection, - // theName, thePoints, theType, theIsClosed); - //} - - // create an empty section - resISection = addSection(theName, theType, theIsClosed); - if( resISection != -1 ) { - // attach the given points to created section - CurveCreator_Section *aSection = mySections.at(resISection); - aSection->myPoints = thePoints; + // Set the difference. + startOperation(); + if (addEmptyDiff()) { + myListDiffs.back().init(this, CurveCreator_Operation::AddSection, + theName, thePoints, theType, theIsClosed); } - - //finishOperation(); + + resISection = addSectionInternal(theName, theType, theIsClosed, thePoints); + + finishOperation(); return resISection; } -//! Removes the given sections. -bool CurveCreator_Curve::removeSection( const int theISection ) +bool CurveCreator_Curve::removeSectionInternal( const int theISection ) { - // Set the difference. - startOperation(); - if (addEmptyDiff()) - myListDiffs.back().init(this, CurveCreator_Operation::RemoveSection, theISection); - if (theISection == -1) { delete mySections.back(); mySections.pop_back(); @@ -526,9 +525,22 @@ bool CurveCreator_Curve::removeSection( const int theISection ) mySections.erase(anIterRm); } redisplayCurve(); + return true; +} + +//! Removes the given sections. +bool CurveCreator_Curve::removeSection( const int theISection ) +{ + bool res = false; + // Set the difference. + startOperation(); + if (addEmptyDiff()) + myListDiffs.back().init(this, CurveCreator_Operation::RemoveSection, theISection); + + res = removeSectionInternal( theISection ); finishOperation(); - return true; + return res; } /** @@ -581,7 +593,7 @@ bool CurveCreator_Curve::setClosed( const int theISection, return true; } -//! Returns specifyed section name +//! Returns specified section name std::string CurveCreator_Curve::getSectionName( const int theISection ) const { if( ( theISection >= 0 ) && ( theISection < mySections.size() )) @@ -636,6 +648,39 @@ bool CurveCreator_Curve::setSectionType( const int theISection, /*** Point methods ***/ /***********************************************/ +//! For internal use only! Undo/Redo is not used here. +bool CurveCreator_Curve::addPointsInternal( const CurveCreator::Coordinates& theCoords, + const std::vector &theISections, + const std::vector &theIPnts ) +{ + bool res = false; + if( (theCoords.size()/getDimension()) == theISections.size() == theIPnts.size() ) { + for( int ind = 0; ind < theISections.size(); ind++ ) { + int anISection = theISections.at(ind); + CurveCreator_Section *aSection = + (anISection == -1 ? mySections.back() : mySections.at(anISection)); + + if( aSection ) { + int anIPnt = theIPnts.at(ind); + CurveCreator::Coordinates::iterator anIterPosition; + if(anIPnt == -1) + anIterPosition = aSection->myPoints.end(); + else + anIterPosition = aSection->myPoints.begin() + toICoord(anIPnt); + CurveCreator::Coordinates::const_iterator aFirstPosition = + theCoords.begin() + toICoord(ind); + aSection->myPoints.insert(anIterPosition, + aFirstPosition, + aFirstPosition + getDimension()); + res = true; + } + } + if(res) + redisplayCurve(); + } + return res; +} + /** * Add one point to the specified section starting from the given theIPnt index * (or at the end of points if \a theIPnt is -1). @@ -649,27 +694,18 @@ bool CurveCreator_Curve::addPoints( const CurveCreator::Coordinates& theCoords, // Set the difference. startOperation(); if (addEmptyDiff()) { - myListDiffs.back().init(this, CurveCreator_Operation::AddPoints, - theCoords, theISection); - } - CurveCreator_Section *aSection = - (theISection == -1 ? mySections.back() : mySections.at(theISection)); - - if( aSection ) { - int anICoord = ( theIPnt == -1 ? 0 : toICoord(theIPnt) ); - CurveCreator::Coordinates::iterator anIterPosition = aSection->myPoints.end(); - if( theIPnt != -1 ) - anIterPosition = aSection->myPoints.begin() + toICoord(theIPnt); - aSection->myPoints.insert(anIterPosition, - theCoords.begin(), theCoords.end()); - redisplayCurve(); - res = true; + myListDiffs.back().init(this, CurveCreator_Operation::InsertPoints, + theCoords, theISection, theIPnt); } + std::vector anISections, anIPnts; + anISections.push_back( theISection ); + anIPnts.push_back( theIPnt ); + res = addPointsInternal( theCoords, anISections, anIPnts ); finishOperation(); return res; } - //! Set coordinates of specified point +//! Set coordinates of specified point bool CurveCreator_Curve::setPoint( const int theISection, const int theIPnt, const CurveCreator::Coordinates& theNewCoords ) @@ -700,6 +736,31 @@ bool CurveCreator_Curve::setPoint( const int theISection, return res; } +bool CurveCreator_Curve::removePointsInternal( const std::vector &theISections, + const std::vector &theIPnts ) +{ + bool res = false; + if( theISections.size() == theIPnts.size() ) { + for( int ind = 0; ind < theISections.size(); ind++ ) { + int anISection = theISections.at(ind); + CurveCreator_Section *aSection = mySections.at(anISection); + if( aSection ) { + int anIPnt = theIPnts.at(ind); + CurveCreator::Coordinates::iterator aFirstPosition; + if(anIPnt == -1) + aFirstPosition = aSection->myPoints.end(); + else + aFirstPosition = aSection->myPoints.begin() + toICoord(anIPnt); + aSection->myPoints.erase( aFirstPosition, aFirstPosition + getDimension() ); + res = true; + } + } + if(res) + redisplayCurve(); + } + return res; +} + //! Remove point with given id bool CurveCreator_Curve::removePoint( const int theISection, const int theIPnt ) { @@ -708,16 +769,12 @@ bool CurveCreator_Curve::removePoint( const int theISection, const int theIPnt ) startOperation(); if (addEmptyDiff()) { myListDiffs.back().init(this, CurveCreator_Operation::RemovePoints, - theISection, theIPnt, 0); - } - CurveCreator_Section *aSection = mySections.at(theISection); - if( aSection ) { - CurveCreator::Coordinates::iterator anIterPosition = - aSection->myPoints.begin() + toICoord(theIPnt); - aSection->myPoints.erase( anIterPosition ); - redisplayCurve(); - res = true; + theISection, theIPnt); } + std::vector anISections, anIPnts; + anISections.push_back( theISection ); + anIPnts.push_back( theIPnt ); + res = removePointsInternal( anISections, anIPnts ); finishOperation(); return res; } diff --git a/src/HYDROCurveCreator/CurveCreator_Curve.hxx b/src/HYDROCurveCreator/CurveCreator_Curve.hxx index d5428008..f1998051 100644 --- a/src/HYDROCurveCreator/CurveCreator_Curve.hxx +++ b/src/HYDROCurveCreator/CurveCreator_Curve.hxx @@ -138,17 +138,23 @@ public: //! Get number of sections virtual int getNbSections() const; + //! For internal use only! Undo/Redo is not used here. + virtual int addSectionInternal( const std::string &theName, + const CurveCreator::SectionType theType, + const bool theIsClosed, + const CurveCreator::Coordinates &thePoints); //! Add a new section. virtual int addSection( const std::string &theName, const CurveCreator::SectionType theType, const bool theIsClosed ); - //! Add a new section. virtual int addSection( const std::string &theName, const CurveCreator::SectionType theType, const bool theIsClosed, const CurveCreator::Coordinates &thePoints); - + + //! For internal use only! Undo/Redo is not used here. + virtual bool removeSectionInternal( const int theISection ); //! Removes the given sections. virtual bool removeSection( const int theISection ); @@ -184,6 +190,10 @@ public: /*** Point methods ***/ /***********************************************/ + //! For internal use only! Undo/Redo is not used here. + virtual bool addPointsInternal( const CurveCreator::Coordinates &theCoords, + const std::vector &theISections, + const std::vector &theIPnts ); /** * Add one point to the specified section starting from the given theIPnt index * (or at the end of points if \a theIPnt is -1). @@ -197,6 +207,9 @@ public: const int theIPnt, const CurveCreator::Coordinates& theNewCoords ); + //! For internal use only! Undo/Redo is not used here. + virtual bool removePointsInternal( const std::vector &theISections, + const std::vector &theIPnts ); /** Remove point with given id */ virtual bool removePoint( const int theISection, const int theIPnt = -1 ); diff --git a/src/HYDROCurveCreator/CurveCreator_Diff.cxx b/src/HYDROCurveCreator/CurveCreator_Diff.cxx index 97c1e6b4..3cd5ac3b 100644 --- a/src/HYDROCurveCreator/CurveCreator_Diff.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Diff.cxx @@ -203,6 +203,26 @@ bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve, } } break; + case CurveCreator_Operation::RemovePoints: + { + // Construct undo for RemovePoints command. + const CurveCreator::Dimension aDim = theCurve->getDimension(); + const CurveCreator::Coordinates &aPoints = + theCurve->getPoints(theIntParam1); + CurveCreator::Coordinates::const_iterator anIterBegin = + aPoints.begin() + (aDim*theIntParam2); + CurveCreator::Coordinates::const_iterator anIterEnd; + + anIterEnd = aPoints.end(); + + CurveCreator::Coordinates aPointsToAdd; + + setNbUndos(1); + aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd); + isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints, + aPointsToAdd, theIntParam1, theIntParam2); + } + break; default: break; } @@ -235,26 +255,6 @@ bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve, myPRedo = new CurveCreator_Operation; if (myPRedo->init(theType, theIntParam1, theIntParam2, theIntParam3)) { - // Construct undo for RemovePoints command. - const CurveCreator::Dimension aDim = theCurve->getDimension(); - const CurveCreator::Coordinates &aPoints = - theCurve->getPoints(theIntParam1); - CurveCreator::Coordinates::const_iterator anIterBegin = - aPoints.begin() + (aDim*theIntParam2); - CurveCreator::Coordinates::const_iterator anIterEnd; - - if (theIntParam3 == -1) { - anIterEnd = aPoints.end(); - } else { - anIterEnd = anIterBegin + (aDim*theIntParam3); - } - - CurveCreator::Coordinates aPointsToAdd; - - setNbUndos(1); - aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd); - isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints, - aPointsToAdd, theIntParam1, theIntParam2); } if (!isOK) { @@ -373,7 +373,7 @@ bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve, setNbUndos(1); isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints, - aSectionInd, aPointInd, aNbPoints); + aSectionInd, aPointInd); } break; case CurveCreator_Operation::SetCoordinates: diff --git a/src/HYDROCurveCreator/CurveCreator_Operation.cxx b/src/HYDROCurveCreator/CurveCreator_Operation.cxx index 073d8ec7..e24e2dca 100644 --- a/src/HYDROCurveCreator/CurveCreator_Operation.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Operation.cxx @@ -97,6 +97,7 @@ bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType, if (theType == CurveCreator_Operation::SetType || theType == CurveCreator_Operation::SetClosed || theType == CurveCreator_Operation::MoveSection || + theType == CurveCreator_Operation::RemovePoints || theType == CurveCreator_Operation::Join) { int *pData = (int *)allocate(2*sizeof(int)); @@ -280,22 +281,23 @@ void CurveCreator_Operation::apply(CurveCreator_Curve *theCurve) switch (myType) { case CurveCreator_Operation::AddPoints: + case CurveCreator_Operation::InsertPoints: { CurveCreator::Coordinates aCoords; - getCoords(&pInt[1], aCoords); - theCurve->addPoints(aCoords, pInt[0]); + getCoords(&pInt[2], aCoords); + std::vector anISections, anIPnts; + anISections.push_back( pInt[0] ); + anIPnts.push_back( pInt[1] ); + theCurve->addPointsInternal(aCoords, anISections, anIPnts); } break; case CurveCreator_Operation::RemovePoints: -//AKL: TODO Undo/Redo support theCurve->removePoints(pInt[0], pInt[1], pInt[2]); - break; - case CurveCreator_Operation::InsertPoints: { - CurveCreator::Coordinates aCoords; - - getCoords(&pInt[2], aCoords); - theCurve->addPoints(aCoords, pInt[0], pInt[1]); + std::vector anISections, anIPnts; + anISections.push_back( pInt[0] ); + anIPnts.push_back( pInt[1] ); + theCurve->removePointsInternal(anISections, anIPnts); } break; case CurveCreator_Operation::SetType: @@ -340,11 +342,11 @@ void CurveCreator_Operation::apply(CurveCreator_Curve *theCurve) char* aPtr = ((char*)&pInt[2]); aPtr += (aName.length()) + 1; getCoords((int*)aPtr, aCoords); - theCurve->addSection(aName, aType, (pInt[1] != 0), aCoords); + theCurve->addSectionInternal(aName, aType, (pInt[1] != 0), aCoords); } break; case CurveCreator_Operation::RemoveSection: - theCurve->removeSection(pInt[0]); + theCurve->removeSectionInternal(pInt[0]); break; case CurveCreator_Operation::RenameSection: { diff --git a/src/HYDROCurveCreator/CurveCreator_TreeView.cxx b/src/HYDROCurveCreator/CurveCreator_TreeView.cxx index 800546cf..c48eb510 100755 --- a/src/HYDROCurveCreator/CurveCreator_TreeView.cxx +++ b/src/HYDROCurveCreator/CurveCreator_TreeView.cxx @@ -382,7 +382,7 @@ void CurveCreator_TreeView::setSelectedSections( const QList& theList ) selectionModel()->clearSelection(); for( int i = 0 ; i < theList.size() ; i++ ){ QModelIndex aSectIndx = aModel->sectionIndex(theList[i]); - selectionModel()->select(aSectIndx, QItemSelectionModel::Select ); + selectionModel()->select(aSectIndx, QItemSelectionModel::Select | QItemSelectionModel::Rows ); } } } @@ -487,3 +487,10 @@ void CurveCreator_TreeView::setCurve( CurveCreator_ICurve* theCurve ) aModel->setCurve(theCurve); reset(); } + +void CurveCreator_TreeView::reset() +{ + QList aSelSections = getSelectedSections(); + QTreeView::reset(); + setSelectedSections(aSelSections); +} diff --git a/src/HYDROCurveCreator/CurveCreator_TreeView.h b/src/HYDROCurveCreator/CurveCreator_TreeView.h index 20f8a622..ee0260c7 100755 --- a/src/HYDROCurveCreator/CurveCreator_TreeView.h +++ b/src/HYDROCurveCreator/CurveCreator_TreeView.h @@ -79,6 +79,8 @@ public: void setCurve( CurveCreator_ICurve* theCurve ); + void reset(); + signals: void selectionChanged(); void sectionEntered(int); diff --git a/src/HYDROCurveCreator/CurveCreator_Widget.cxx b/src/HYDROCurveCreator/CurveCreator_Widget.cxx index 90a8ebd9..ac5b638f 100644 --- a/src/HYDROCurveCreator/CurveCreator_Widget.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Widget.cxx @@ -400,6 +400,7 @@ void CurveCreator_Widget::onSelectionChanged() } } } + updateUndoRedo(); emit selectionChanged(); } @@ -488,9 +489,16 @@ void CurveCreator_Widget::onAddNewPoint(const CurveCreator::Coordinates& theCoor { if( !myCurve ) return; - myCurve->addPoints(theCoords, mySection, myPointNum ); - mySectionView->pointsAdded( mySection, myPointNum ); - myPointNum++; + //myCurve->addPoints(theCoords, mySection, myPointNum ); + //mySectionView->pointsAdded( mySection, myPointNum ); + //myPointNum++; + QList aSections = mySectionView->getSelectedSections(); + if( aSections.size() == 0 ){ + return; + } + int aSection = aSections[0]; + myCurve->addPoints(theCoords, aSection); // add to the end of section + mySectionView->pointsAdded( aSection, myCurve->getNbPoints( aSection ) ); onSelectionChanged(); updateUndoRedo(); } @@ -757,24 +765,26 @@ void CurveCreator_Widget::onRedo() void CurveCreator_Widget::updateUndoRedo() { - QAction* anAct = myActionMap[UNDO_ID]; - if( anAct != 0 ){ - if( myCurve->getNbUndo() != 0 ){ - anAct->setEnabled(true); - } - else{ - anAct->setDisabled(true); - } + if( !myCurve ) + return; + QAction* anAct = myActionMap[UNDO_ID]; + if( anAct != 0 ){ + if( myCurve->getNbUndo() != 0 ){ + anAct->setEnabled(true); } - anAct = myActionMap[REDO_ID]; - if( anAct != 0 ){ - if( myCurve->getNbRedo() != 0 ){ - anAct->setEnabled(true); - } - else{ - anAct->setDisabled(true); - } + else{ + anAct->setDisabled(true); } + } + anAct = myActionMap[REDO_ID]; + if( anAct != 0 ){ + if( myCurve->getNbRedo() != 0 ){ + anAct->setEnabled(true); + } + else{ + anAct->setDisabled(true); + } + } } void CurveCreator_Widget::onContextMenu( QPoint thePoint ) -- 2.39.2