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);
}
//! 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();
}
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;
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;
* <LI>SetType</LI>
* <LI>SetClosed</LI>
* <LI>MoveSection</LI>
- * <LI>Join (with 2 int arguments)</LI>
* </UL>
*/
bool init(const CurveCreator_Curve *theCurve,
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.
#include <deque>
#include <vector>
#include <string>
+#include <list>
class Handle_AIS_InteractiveObject;
//! 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;
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:
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:
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.
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;
}
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,
//! 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,
aSect << aModel->getSection( anIndxs[i] );
}
}
- qSort(aSect.begin(), aSect.end());
return aSect;
}
}
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();
}
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();