-// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// Copyright (C) 2007-2023 CEA, EDF, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
+//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
-//
-// This library is distributed in the hope that it will be useful
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// File : SALOMEDSImpl_UseCaseBuilder.cxx
// Author : Sergey RUIN
// Module : SALOME
-
#include "SALOMEDSImpl_UseCaseBuilder.hxx"
#include "SALOMEDSImpl_SObject.hxx"
#include "SALOMEDSImpl_SComponent.hxx"
#include "DF_ChildIterator.hxx"
-using namespace std;
+#include <list>
#define USE_CASE_LABEL_TAG 2
#define USE_CASE_GUID "AA43BB12-D9CD-11d6-945D-0050DA506788"
+namespace {
+ // comparator to sort use case nodes in ascending order
+ struct AscSortSOs {
+ bool operator()( SALOMEDSImpl_SObject firstSO, SALOMEDSImpl_SObject secondSO ) const {
+ std::string firstName, secondName;
+ SALOMEDSImpl_SObject refSO;
+ firstSO.ReferencedObject(refSO) ?
+ firstName = refSO.GetName() :
+ firstName = firstSO.GetName();
+ secondSO.ReferencedObject(refSO) ?
+ secondName = refSO.GetName() :
+ secondName = secondSO.GetName();
+ return firstName < secondName;
+ }
+ };
+
+ // comparator to sort use case nodes in descending order
+ struct DescSortSOs {
+ bool operator()( SALOMEDSImpl_SObject firstSO, SALOMEDSImpl_SObject secondSO ) const {
+ std::string firstName, secondName;
+ SALOMEDSImpl_SObject refSO;
+ firstSO.ReferencedObject(refSO) ?
+ firstName = refSO.GetName() :
+ firstName = firstSO.GetName();
+ secondSO.ReferencedObject(refSO) ?
+ secondName = refSO.GetName() :
+ secondName = secondSO.GetName();
+ return firstName > secondName;
+ }
+ };
+}
//============================================================================
/*! Function : constructor
*/
//============================================================================
SALOMEDSImpl_UseCaseBuilder::SALOMEDSImpl_UseCaseBuilder(DF_Document* theDocument)
-:_doc(theDocument)
+ :_doc(theDocument), _lastChild(0), _childIndex(-1)
{
if(!_doc) return;
}
DF_Label aCurrent = aRef->Get();
- if(aCurrent.IsNull() || !(aCurrentNode=(SALOMEDSImpl_AttributeTreeNode*)aCurrent.FindAttribute(_root->ID())))
+ if(aCurrent.IsNull() || !(aCurrentNode=(SALOMEDSImpl_AttributeTreeNode*)aCurrent.FindAttribute(_root->ID())))
aCurrentNode = _root;
- aCurrentNode->Append(aNode);
+ aCurrentNode->Append(aNode, &_childIndex);
+ _lastChild = aNode;
+
+ // Mantis issue 0020136: Drag&Drop in OB
+ SALOMEDSImpl_Study::GetStudyImpl(theObject.GetLabel())->addSO_Notification(theObject);
return true;
}
- //============================================================================
+//============================================================================
/*! Function : Remove
* Purpose :
*/
{
if(!_root || !theObject) return false;
- DF_Label aLabel = theObject.GetLabel();
+ DF_Label aLabel = theObject.GetLabel();
if(aLabel.IsNull()) return false;
SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
+ if ( _lastChild && aNode->GetFather() == _lastChild->GetFather() )
+ _lastChild = 0;
+
aNode->Remove();
- vector<DF_Attribute*> aList;
+ std::vector<DF_Attribute*> aList;
aList.push_back(aNode);
SALOMEDSImpl_AttributeReference* aRef = NULL;
if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
- aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());
- }
+ aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());
+ }
DF_Label aCurrent = aRef->Get();
SALOMEDSImpl_ChildNodeIterator aChildItr(aNode, true);
- for(; aChildItr.More(); aChildItr.Next())
+ for(; aChildItr.More(); aChildItr.Next())
aList.push_back(aChildItr.Value());
- for(int i = 0, len = aList.size(); i<len; i++) {
+ for(size_t i = 0, len = aList.size(); i<len; i++) {
if(aList[i]->Label() == aCurrent) { //The current node is removed
aRef->Set(_root->Label()); //Reset the current node to the root
}
*/
//============================================================================
bool SALOMEDSImpl_UseCaseBuilder::AppendTo(const SALOMEDSImpl_SObject& theFather,
- const SALOMEDSImpl_SObject& theObject)
+ const SALOMEDSImpl_SObject& theObject)
{
if(!_root || !theFather || !theObject) return false;
DF_Label aFatherLabel = theFather.GetLabel(), aLabel = theObject.GetLabel();
if(aFatherLabel == aLabel) return false;
- SALOMEDSImpl_AttributeTreeNode *aFather = false, *aNode = false;
+ SALOMEDSImpl_AttributeTreeNode *aFather = NULL, *aNode = NULL;
if(aFatherLabel.IsNull()) return false;
if(!(aFather=(SALOMEDSImpl_AttributeTreeNode*)aFatherLabel.FindAttribute(_root->ID()))) return false;
aNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, _root->ID());
}
+ if ( aNode == _lastChild && !_lastChild->HasNext() && _lastChild->GetFather() == aFather )
+ return true; // aNode is already the last child
+
aNode->Remove();
- return aFather->Append(aNode);
+ bool ret = true;
+ if ( _lastChild && _lastChild->GetFather() == aFather &&
+ !_lastChild->HasNext() ) // _lastChild is the last under aFather
+ {
+ _lastChild->InsertAfter( aNode );
+ _lastChild = aNode;
+ ++_childIndex;
+ }
+ else
+ {
+ ret = aFather->Append(aNode, &_childIndex);
+ _lastChild = aNode;
+ }
+
+ // Mantis issue 0020136: Drag&Drop in OB
+ SALOMEDSImpl_Study::GetStudyImpl(theObject.GetLabel())->addSO_Notification(theObject);
+
+ return ret;
+}
+
+//============================================================================
+/*! Function : GetIndexInFather
+ * Purpose :
+ */
+//============================================================================
+int SALOMEDSImpl_UseCaseBuilder::GetIndexInFather(const SALOMEDSImpl_SObject& theFather,
+ const SALOMEDSImpl_SObject& theObject)
+{
+ int index = -1;
+ if(!_root || !theFather || !theObject) return index;
+
+ DF_Label aFatherLabel = theFather.GetLabel(), aLabel = theObject.GetLabel();
+ if(aFatherLabel == aLabel) return index;
+
+ SALOMEDSImpl_AttributeTreeNode *aFather = NULL, *aNode = NULL;
+
+ if(aFatherLabel.IsNull()) return index;
+ if(!(aFather=(SALOMEDSImpl_AttributeTreeNode*)aFatherLabel.FindAttribute(_root->ID()))) return index;
+
+ if(aLabel.IsNull()) return index;
+ if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) {
+ aNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, _root->ID());
+ }
+
+ if ( _lastChild && _lastChild->GetFather() == aFather )
+ {
+ if ( aNode == _lastChild )
+ index = _childIndex;
+ else if ( aNode == _lastChild->GetPrevious())
+ index = _childIndex - 1;
+ else if ( aNode == _lastChild->GetNext())
+ {
+ index = ++_childIndex;
+ _lastChild = aNode;
+ }
+ }
+
+ if ( index < 0 )
+ {
+ SALOMEDSImpl_AttributeTreeNode* Last = aFather->GetFirst();
+ for ( index = 0; Last && aNode != Last && Last->HasNext(); ++index )
+ {
+ Last = Last->GetNext();
+ }
+ if ( Last != aNode )
+ index = -1;
+ else if ( !Last->HasNext() )
+ {
+ _lastChild = Last;
+ _childIndex = index;
+ }
+ }
+
+ return index;
}
//============================================================================
* Purpose :
*/
//============================================================================
-bool SALOMEDSImpl_UseCaseBuilder::InsertBefore(const SALOMEDSImpl_SObject& theFirst,
- const SALOMEDSImpl_SObject& theNext)
+bool SALOMEDSImpl_UseCaseBuilder::InsertBefore(const SALOMEDSImpl_SObject& theFirst,
+ const SALOMEDSImpl_SObject& theNext)
{
if(!_root || !theFirst || !theNext) return false;
if(aFirstLabel == aLabel) return false;
SALOMEDSImpl_AttributeTreeNode *aFirstNode = NULL, *aNode = NULL;
-
+
if(aFirstLabel.IsNull()) return false;
if((aFirstNode=(SALOMEDSImpl_AttributeTreeNode*)aFirstLabel.FindAttribute(_root->ID()))) {
aFirstNode->Remove();
}
aFirstNode = SALOMEDSImpl_AttributeTreeNode::Set(aFirstLabel, _root->ID());
-
+
if(aLabel.IsNull()) return false;
- if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
+ if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
aFirstNode->Remove();
- return aNode->InsertBefore(aFirstNode);
+ bool ret = aNode->InsertBefore(aFirstNode);
+
+ if ( _lastChild && _lastChild->GetFather() == aNode->GetFather() )
+ {
+ if ( aNode == _lastChild )
+ ++_childIndex;
+ else
+ _lastChild = 0;
+ }
+
+ // Mantis issue 0020136: Drag&Drop in OB
+ SALOMEDSImpl_Study::GetStudyImpl(theFirst.GetLabel())->addSO_Notification(theFirst);
+
+ return ret;
}
return (aNode->GetFirst());
}
+//============================================================================
+/*! Function : SortChildren
+ * Purpose :
+ */
+//============================================================================
+bool SALOMEDSImpl_UseCaseBuilder::SortChildren(const SALOMEDSImpl_SObject& theObject, bool theAscendingOrder)
+{
+ if(!_root) return false;
+
+ DF_Label aLabel;
+ if (!theObject) aLabel = _root->Label();
+ else
+ aLabel = theObject.GetLabel();
+ if(aLabel.IsNull()) return false;
+
+ SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
+ if (!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
+
+ std::list<SALOMEDSImpl_SObject> aRefSOs;
+ std::list<SALOMEDSImpl_SObject> aNodeSOs;
+ for ( SALOMEDSImpl_AttributeTreeNode* aChildNode=aNode->GetFirst(); aChildNode; aChildNode=aChildNode->GetNext() ) {
+ if ( SALOMEDSImpl_SObject aSO = SALOMEDSImpl_Study::SObject( aChildNode->Label() ) ) {
+ if ( aChildNode->FindAttribute( SALOMEDSImpl_AttributeReference::GetID() ) )
+ aRefSOs.push_back( aSO );
+ else
+ aNodeSOs.push_back( aSO );
+ }
+ }
+ if ( aRefSOs.empty() && aNodeSOs.empty() ) return false;
+
+ //sort items by names in ascending/descending order
+ _lastChild = 0;
+ std::list<SALOMEDSImpl_SObject>::iterator it;
+ if ( !aRefSOs.empty() ) {
+ theAscendingOrder ? aRefSOs.sort( AscSortSOs() ) : aRefSOs.sort( DescSortSOs() );
+ for ( it = aRefSOs.begin(); it != aRefSOs.end(); ++it ) {
+ AppendTo( theObject, *it );
+ }
+ }
+ if ( !aNodeSOs.empty() ) {
+ theAscendingOrder ? aNodeSOs.sort( AscSortSOs() ) : aNodeSOs.sort( DescSortSOs() );
+ for ( it = aNodeSOs.begin(); it != aNodeSOs.end(); ++it ) {
+ AppendTo( theObject, *it );
+ }
+ }
+
+ return true;
+}
+
+//============================================================================
+/*! Function : GetFather
+ * Purpose :
+ */
+//============================================================================
+SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::GetFather(const SALOMEDSImpl_SObject& theObject)
+{
+ SALOMEDSImpl_SObject so;
+ if (!_root || !theObject) return so;
+
+ DF_Label aLabel = theObject.GetLabel();
+ if (aLabel.IsNull()) return so;
+
+ SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
+ if (!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return so;
+
+ SALOMEDSImpl_AttributeTreeNode* aFatherNode = aNode->GetFather();
+ if (!aFatherNode) return so;
+
+ return aFatherNode->GetSObject();
+}
+
//============================================================================
/*! Function : SetName
* Purpose :
*/
//============================================================================
-bool SALOMEDSImpl_UseCaseBuilder::SetName(const string& theName) {
+bool SALOMEDSImpl_UseCaseBuilder::SetName(const std::string& theName) {
if(!_root) return false;
SALOMEDSImpl_AttributeName* aNameAttrib = NULL;
* Purpose :
*/
//============================================================================
-string SALOMEDSImpl_UseCaseBuilder::GetName()
+std::string SALOMEDSImpl_UseCaseBuilder::GetName()
{
- string aString;
+ std::string aString;
if(!_root) return aString;
SALOMEDSImpl_AttributeName* aName = NULL;
return false;
}
+//============================================================================
+/*! Function : IsUseCaseNode
+ * Purpose :
+ */
+//============================================================================
+bool SALOMEDSImpl_UseCaseBuilder::IsUseCaseNode(const SALOMEDSImpl_SObject& theObject)
+{
+ if(!_root) return false;
+
+ DF_Label aLabel;
+ if (!theObject) aLabel = _root->Label();
+ else
+ aLabel = theObject.GetLabel();
+ if(aLabel.IsNull()) return false;
+
+ SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
+ if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
+
+ return true;
+}
+
//============================================================================
/*! Function : NewUseCase
* Purpose :
*/
//============================================================================
-SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::AddUseCase(const string& theName)
+SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::AddUseCase(const std::string& theName)
{
- string aBasicGUID(USE_CASE_GUID);
+ std::string aBasicGUID(USE_CASE_GUID);
//Create a use cases structure if it not exists
}
-SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::GetSObject(const string& theEntry)
+SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::GetSObject(const std::string& theEntry)
{
DF_Label L = DF_Label::Label(_root->Label(), theEntry);
return SALOMEDSImpl_Study::SObject(L);